Last active
May 6, 2024 07:14
-
-
Save Nikolaj-K/388e643d1f5e6989072a21e469d10a48 to your computer and use it in GitHub Desktop.
A python script to perform sha2 in terms of if-statements and for-loops.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Bit level SHA2. | |
Script to perform sha2 in terms of if-statements and for-loops. This runs 1 batch iteration | |
(i.e. about 50 bytes max input, but should be easy to extend to any size.) | |
No warranty. | |
Explanation video: | |
https://youtu.be/UziK-Hqzwi4 | |
2019 | |
Nikolaj Kuntner | |
""" | |
################################################## online hashing tool | |
### https://passwordsgenerator.net/sha256-hash-generator | |
HELLO_HASH = '2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824' ## hash of "hello" | |
HELLP_HASH = 'fdd7585e08c4e2afd71dcabdb4636c89d557a3f42db9e2040c8bbd1708aa4ce7' ## hash of "hellp" | |
## ouptut is base 16=2**4 and has 64 chars or 64 * 4 = 256 bits | |
def num2arr(n): | |
bs = [] | |
while n > 1: | |
bs = [n % 2] + bs ## [remaider] + [accumulation] | |
n = n // 2 ## integer division, i.e. quotient without remainder | |
return [1] + bs if n else bs | |
################################################ bit functions | |
F = 'some value' ## respresents False, 0, fNumber | |
T = 'a different value' ## respresents True, 1, tNumber | |
def TRUE(x): return x==T | |
def IF(x, a, b): return a if TRUE(x) else b | |
## return a if x else b # if Bool is {0, 1} | |
## return x * a + (1-x) * b | |
## return def IF(x,a,b): return ((x-F)*a + (T-x)*b) / (T-F) | |
def NOT(x): return IF(x, F, T) | |
def AND(x, y): return IF(x, y, F) | |
def XOR(x, y): return IF(x, NOT(y), y) | |
def MAJ(x, y, z): return IF(x, IF(y, T, z), IF(y, z, F)) | |
def XORXOR(x, y, z): return XOR(x, XOR(y, z)) | |
#IF(x, IF(y, z, NOT(z)), IF(y, NOT(z), z)) | |
## return x+y+z mod 2 | |
## return XOR(x, XOR(y, z)) | |
################################################ bit array functions | |
####################### component-wise functions | |
def if_(x, y, z): return [IF(xi, yi, zi) for xi, yi, zi in zip(x, y, z)] | |
def and_(x, y): return [AND(xi, yi) for xi, yi in zip(x, y)] | |
def xor(x, y): return [XOR(xi, yi) for xi, yi in zip(x, y)] | |
def maj(x, y, z): return [MAJ(xi, yi, zi) for xi, yi, zi in zip(x, y, z)] | |
def xorxor(x, y, z): return [XORXOR(xi, yi, zi) for xi, yi, zi in zip(x, y, z)] | |
####################### addition | |
N = 32 | |
def add(x, y): ## binary addition of N bit numbers (automatically mod 2**N) | |
res = list(range(N)) | |
ci = F ## carry bit | |
for i in range(N-1, -1, -1): | |
res[i] = XORXOR(x[i], y[i], ci) | |
ci = MAJ(x[i], y[i], ci) | |
return res | |
####################### utility functions | |
def rotr(x, n): return x[-n:] + x[:-n] | |
def cut(x, n): return n * [F] + x[:(len(x) - n)] | |
################################################## "random" numbers used in SHA256 | |
K = [ ## 64 * 32 = 2048 bits (256 bytes) | |
[F,T,F,F,F,F,T,F,T,F,F,F,T,F,T,F,F,F,T,F,T,T,T,T,T,F,F,T,T,F,F,F], ## 32 bits (4 bytes) | |
[F,T,T,T,F,F,F,T,F,F,T,T,F,T,T,T,F,T,F,F,F,T,F,F,T,F,F,T,F,F,F,T], | |
[T,F,T,T,F,T,F,T,T,T,F,F,F,F,F,F,T,T,T,T,T,F,T,T,T,T,F,F,T,T,T,T], | |
[T,T,T,F,T,F,F,T,T,F,T,T,F,T,F,T,T,T,F,T,T,F,T,T,T,F,T,F,F,T,F,T], | |
[F,F,T,T,T,F,F,T,F,T,F,T,F,T,T,F,T,T,F,F,F,F,T,F,F,T,F,T,T,F,T,T], | |
[F,T,F,T,T,F,F,T,T,T,T,T,F,F,F,T,F,F,F,T,F,F,F,T,T,T,T,T,F,F,F,T], | |
[T,F,F,T,F,F,T,F,F,F,T,T,T,T,T,T,T,F,F,F,F,F,T,F,T,F,T,F,F,T,F,F], | |
[T,F,T,F,T,F,T,T,F,F,F,T,T,T,F,F,F,T,F,T,T,T,T,F,T,T,F,T,F,T,F,T], | |
[T,T,F,T,T,F,F,F,F,F,F,F,F,T,T,T,T,F,T,F,T,F,T,F,T,F,F,T,T,F,F,F], | |
[F,F,F,T,F,F,T,F,T,F,F,F,F,F,T,T,F,T,F,T,T,F,T,T,F,F,F,F,F,F,F,T], | |
[F,F,T,F,F,T,F,F,F,F,T,T,F,F,F,T,T,F,F,F,F,T,F,T,T,F,T,T,T,T,T,F], | |
[F,T,F,T,F,T,F,T,F,F,F,F,T,T,F,F,F,T,T,T,T,T,F,T,T,T,F,F,F,F,T,T], | |
[F,T,T,T,F,F,T,F,T,F,T,T,T,T,T,F,F,T,F,T,T,T,F,T,F,T,T,T,F,T,F,F], | |
[T,F,F,F,F,F,F,F,T,T,F,T,T,T,T,F,T,F,T,T,F,F,F,T,T,T,T,T,T,T,T,F], | |
[T,F,F,T,T,F,T,T,T,T,F,T,T,T,F,F,F,F,F,F,F,T,T,F,T,F,T,F,F,T,T,T], | |
[T,T,F,F,F,F,F,T,T,F,F,T,T,F,T,T,T,T,T,T,F,F,F,T,F,T,T,T,F,T,F,F], | |
[T,T,T,F,F,T,F,F,T,F,F,T,T,F,T,T,F,T,T,F,T,F,F,T,T,T,F,F,F,F,F,T], | |
[T,T,T,F,T,T,T,T,T,F,T,T,T,T,T,F,F,T,F,F,F,T,T,T,T,F,F,F,F,T,T,F], | |
[F,F,F,F,T,T,T,T,T,T,F,F,F,F,F,T,T,F,F,T,T,T,F,T,T,T,F,F,F,T,T,F], | |
[F,F,T,F,F,T,F,F,F,F,F,F,T,T,F,F,T,F,T,F,F,F,F,T,T,T,F,F,T,T,F,F], | |
[F,F,T,F,T,T,F,T,T,T,T,F,T,F,F,T,F,F,T,F,T,T,F,F,F,T,T,F,T,T,T,T], | |
[F,T,F,F,T,F,T,F,F,T,T,T,F,T,F,F,T,F,F,F,F,T,F,F,T,F,T,F,T,F,T,F], | |
[F,T,F,T,T,T,F,F,T,F,T,T,F,F,F,F,T,F,T,F,T,F,F,T,T,T,F,T,T,T,F,F], | |
[F,T,T,T,F,T,T,F,T,T,T,T,T,F,F,T,T,F,F,F,T,F,F,F,T,T,F,T,T,F,T,F], | |
[T,F,F,T,T,F,F,F,F,F,T,T,T,T,T,F,F,T,F,T,F,F,F,T,F,T,F,T,F,F,T,F], | |
[T,F,T,F,T,F,F,F,F,F,T,T,F,F,F,T,T,T,F,F,F,T,T,F,F,T,T,F,T,T,F,T], | |
[T,F,T,T,F,F,F,F,F,F,F,F,F,F,T,T,F,F,T,F,F,T,T,T,T,T,F,F,T,F,F,F], | |
[T,F,T,T,T,T,T,T,F,T,F,T,T,F,F,T,F,T,T,T,T,T,T,T,T,T,F,F,F,T,T,T], | |
[T,T,F,F,F,T,T,F,T,T,T,F,F,F,F,F,F,F,F,F,T,F,T,T,T,T,T,T,F,F,T,T], | |
[T,T,F,T,F,T,F,T,T,F,T,F,F,T,T,T,T,F,F,T,F,F,F,T,F,T,F,F,F,T,T,T], | |
[F,F,F,F,F,T,T,F,T,T,F,F,T,F,T,F,F,T,T,F,F,F,T,T,F,T,F,T,F,F,F,T], | |
[F,F,F,T,F,T,F,F,F,F,T,F,T,F,F,T,F,F,T,F,T,F,F,T,F,T,T,F,F,T,T,T], | |
[F,F,T,F,F,T,T,T,T,F,T,T,F,T,T,T,F,F,F,F,T,F,T,F,T,F,F,F,F,T,F,T], | |
[F,F,T,F,T,T,T,F,F,F,F,T,T,F,T,T,F,F,T,F,F,F,F,T,F,F,T,T,T,F,F,F], | |
[F,T,F,F,T,T,F,T,F,F,T,F,T,T,F,F,F,T,T,F,T,T,F,T,T,T,T,T,T,T,F,F], | |
[F,T,F,T,F,F,T,T,F,F,T,T,T,F,F,F,F,F,F,F,T,T,F,T,F,F,F,T,F,F,T,T], | |
[F,T,T,F,F,T,F,T,F,F,F,F,T,F,T,F,F,T,T,T,F,F,T,T,F,T,F,T,F,T,F,F], | |
[F,T,T,T,F,T,T,F,F,T,T,F,T,F,T,F,F,F,F,F,T,F,T,F,T,F,T,T,T,F,T,T], | |
[T,F,F,F,F,F,F,T,T,T,F,F,F,F,T,F,T,T,F,F,T,F,F,T,F,F,T,F,T,T,T,F], | |
[T,F,F,T,F,F,T,F,F,T,T,T,F,F,T,F,F,F,T,F,T,T,F,F,T,F,F,F,F,T,F,T], | |
[T,F,T,F,F,F,T,F,T,F,T,T,T,T,T,T,T,T,T,F,T,F,F,F,T,F,T,F,F,F,F,T], | |
[T,F,T,F,T,F,F,F,F,F,F,T,T,F,T,F,F,T,T,F,F,T,T,F,F,T,F,F,T,F,T,T], | |
[T,T,F,F,F,F,T,F,F,T,F,F,T,F,T,T,T,F,F,F,T,F,T,T,F,T,T,T,F,F,F,F], | |
[T,T,F,F,F,T,T,T,F,T,T,F,T,T,F,F,F,T,F,T,F,F,F,T,T,F,T,F,F,F,T,T], | |
[T,T,F,T,F,F,F,T,T,F,F,T,F,F,T,F,T,T,T,F,T,F,F,F,F,F,F,T,T,F,F,T], | |
[T,T,F,T,F,T,T,F,T,F,F,T,T,F,F,T,F,F,F,F,F,T,T,F,F,F,T,F,F,T,F,F], | |
[T,T,T,T,F,T,F,F,F,F,F,F,T,T,T,F,F,F,T,T,F,T,F,T,T,F,F,F,F,T,F,T], | |
[F,F,F,T,F,F,F,F,F,T,T,F,T,F,T,F,T,F,T,F,F,F,F,F,F,T,T,T,F,F,F,F], | |
[F,F,F,T,T,F,F,T,T,F,T,F,F,T,F,F,T,T,F,F,F,F,F,T,F,F,F,T,F,T,T,F], | |
[F,F,F,T,T,T,T,F,F,F,T,T,F,T,T,T,F,T,T,F,T,T,F,F,F,F,F,F,T,F,F,F], | |
[F,F,T,F,F,T,T,T,F,T,F,F,T,F,F,F,F,T,T,T,F,T,T,T,F,T,F,F,T,T,F,F], | |
[F,F,T,T,F,T,F,F,T,F,T,T,F,F,F,F,T,F,T,T,T,T,F,F,T,F,T,T,F,T,F,T], | |
[F,F,T,T,T,F,F,T,F,F,F,T,T,T,F,F,F,F,F,F,T,T,F,F,T,F,T,T,F,F,T,T], | |
[F,T,F,F,T,T,T,F,T,T,F,T,T,F,F,F,T,F,T,F,T,F,T,F,F,T,F,F,T,F,T,F], | |
[F,T,F,T,T,F,T,T,T,F,F,T,T,T,F,F,T,T,F,F,T,F,T,F,F,T,F,F,T,T,T,T], | |
[F,T,T,F,T,F,F,F,F,F,T,F,T,T,T,F,F,T,T,F,T,T,T,T,T,T,T,T,F,F,T,T], | |
[F,T,T,T,F,T,F,F,T,F,F,F,T,T,T,T,T,F,F,F,F,F,T,F,T,T,T,F,T,T,T,F], | |
[F,T,T,T,T,F,F,F,T,F,T,F,F,T,F,T,F,T,T,F,F,F,T,T,F,T,T,F,T,T,T,T], | |
[T,F,F,F,F,T,F,F,T,T,F,F,T,F,F,F,F,T,T,T,T,F,F,F,F,F,F,T,F,T,F,F], | |
[T,F,F,F,T,T,F,F,T,T,F,F,F,T,T,T,F,F,F,F,F,F,T,F,F,F,F,F,T,F,F,F], | |
[T,F,F,T,F,F,F,F,T,F,T,T,T,T,T,F,T,T,T,T,T,T,T,T,T,T,T,T,T,F,T,F], | |
[T,F,T,F,F,T,F,F,F,T,F,T,F,F,F,F,F,T,T,F,T,T,F,F,T,T,T,F,T,F,T,T], | |
[T,F,T,T,T,T,T,F,T,T,T,T,T,F,F,T,T,F,T,F,F,F,T,T,T,T,T,T,F,T,T,T], | |
[T,T,F,F,F,T,T,F,F,T,T,T,F,F,F,T,F,T,T,T,T,F,F,F,T,T,T,T,F,F,T,F] | |
] | |
H = [ ## 64 * 32 = 256 bits (32 bytes), like the hash output (e.g. HELLO_HASH) | |
[F,T,T,F,T,F,T,F,F,F,F,F,T,F,F,T,T,T,T,F,F,T,T,F,F,T,T,F,F,T,T,T], | |
[T,F,T,T,T,F,T,T,F,T,T,F,F,T,T,T,T,F,T,F,T,T,T,F,T,F,F,F,F,T,F,T], | |
[F,F,T,T,T,T,F,F,F,T,T,F,T,T,T,F,T,T,T,T,F,F,T,T,F,T,T,T,F,F,T,F], | |
[T,F,T,F,F,T,F,T,F,T,F,F,T,T,T,T,T,T,T,T,F,T,F,T,F,F,T,T,T,F,T,F], | |
[F,T,F,T,F,F,F,T,F,F,F,F,T,T,T,F,F,T,F,T,F,F,T,F,F,T,T,T,T,T,T,T], | |
[T,F,F,T,T,F,T,T,F,F,F,F,F,T,F,T,F,T,T,F,T,F,F,F,T,F,F,F,T,T,F,F], | |
[F,F,F,T,T,T,T,T,T,F,F,F,F,F,T,T,T,T,F,T,T,F,F,T,T,F,T,F,T,F,T,T], | |
[F,T,F,T,T,F,T,T,T,T,T,F,F,F,F,F,T,T,F,F,T,T,F,T,F,F,F,T,T,F,F,T] | |
] | |
################################################## start SHA-256 | |
def sha(w): | |
for i in range(16, 64): ## fill rest of w | |
w[i] = add(add(add( | |
w[i-16], | |
w[i- 7]), | |
xorxor(rotr(w[i-15], 7), rotr(w[i-15], 18), cut(w[i-15], 3))), | |
xorxor(rotr(w[i-2] , 17), rotr(w[i-2] , 19), cut(w[i-2] , 10))) | |
a, b, c, d, e, f, g, h = H | |
for j in range(64): ## digest | |
temp1 = add(add(add(add( | |
w[j], | |
h), | |
if_(e, f, g)), | |
xorxor(rotr(e, 6), rotr(e, 11), rotr(e, 25))), | |
K[j]) | |
tempd = add( | |
maj(a, b, c), | |
xorxor(rotr(a, 2), rotr(a, 13), rotr(a, 22))) | |
h = g | |
g = f | |
f = e | |
e = add( | |
temp1, | |
d) | |
d = c | |
c = b | |
b = a | |
a = add( | |
temp1, | |
tempd) | |
return [add(x, y) for x, y in zip([a, b, c, d, e, f, g, h], H)] | |
################################################## utility funcitons for base conversion | |
def arrsToHex(arrs): | |
def arr2dec(arr): | |
return sum([b * 2**k for k, b in enumerate(arr[::-1])]) | |
def arr2hex(arr): | |
return '{:x}'.format(arr2dec(arr)) | |
return (arr2hex(arr) for arr in arrs) | |
def translateArrBits(arr, source, target): | |
for i, row in enumerate(arr): | |
for j, elem in enumerate(row): | |
if arr[i][j]==source: | |
arr[i][j] = target | |
################################################## initialize a message on w, run and print! | |
w = [32*[F] for _ in range(64)] | |
w[15] = [F,F,F,F,F,F,F,F, F,F,F,F,F,F,F,F, F,F,F,F,F,F,F,F, F,F,T,F,T,F,F,F] ## message length | |
w[0] = [F,T,T,F,T,F,F,F, F,T,T,F,F,T,F,T, F,T,T,F,T,T,F,F, F,T,T,F,T,T,F,F] ## "hell" | |
w[1] = [F,T,T,F,T,T,T,T, T,F,F,F,F,F,F,F, F,F,F,F,F,F,F,F, F,F,F,F,F,F,F,F] ## "o" and message end | |
#w[1] = [F,T,T,T,F,F,F,F, T,F,F,F,F,F,F,F, F,F,F,F,F,F,F,F, F,F,F,F,F,F,F,F] ## "p" and message end | |
digestBool = sha(w) # run! | |
translateArrBits(digestBool, F, 0) | |
translateArrBits(digestBool, T, 1) | |
for row in digestBool: | |
print("".join(map(str, row))) | |
for row in arrsToHex(digestBool): | |
print(row) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment