Skip to content

Commit e46e60b

Browse files
committed
reformat to bytearray and padding fixes
1 parent a54b447 commit e46e60b

File tree

4 files changed

+105
-40
lines changed

4 files changed

+105
-40
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
/.vscode
2-
/__pycache__
2+
/__pycache__
3+
speedtests.py

constants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
HASH_VALUES = [
1+
INITIAL_HASH_VALUES = [
22
0x6a09e667,
33
0xbb67ae85,
44
0x3c6ef372,

main.py

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,74 @@
11
from sys import argv
2-
from constants import *
2+
from constants import INITIAL_HASH_VALUES, CONSTANTS
33

4-
def pad_message(byte_message: bytes):
4+
# Words = 32b
5+
def circular_shift(x: bytes, y: int):
6+
"""
7+
Word circular shift of bytes x by amount y
8+
"""
9+
x = int.from_bytes(x, "big")
10+
return NotImplementedError
11+
12+
13+
def xor(x: bytearray, y: bytearray):
14+
"""
15+
XOR for bytes type
16+
"""
17+
if len(x) != len(y):
18+
raise Exception("XOR arguments should be the same length")
19+
return bytes(int.from_bytes(x, "big") ^ int.from_bytes(y, "big"))
20+
21+
22+
def pad_message(byte_message: bytearray):
523
"""
624
Pads message to length divisible by 512
725
Appends binary 1 to the message and then appends number of zeros
826
Number of zeroes is chosen so that the final message is divisible by 512 in bits
927
"""
10-
number_of_zeros = 64 - ((len(byte_message) + 8) % 64)
11-
byte_message += b'\x80' + b'\x00' * (number_of_zeros - 1)
12-
return byte_message
28+
message_copy = byte_message[:] # Copy because bytearrays are done
29+
number_of_zeros = 64 - ((len(message_copy) + 8) % 64)
30+
message_copy += b"\x80" + bytearray(number_of_zeros - 1) + (len(message_copy)).to_bytes(8,"big")
31+
return message_copy
1332

1433

15-
def divide_message(byte_message: bytes):
34+
def divide_message(byte_message: bytearray):
1635
"""
1736
Divides messages into chunks of size 512
1837
"""
1938
L = len(byte_message)
2039
if L % 64 != 0:
2140
raise Exception("Message length should be divisible by 64")
22-
result_messages = [byte_message[64 * i : 64 * (i+1)] for i in range(L/64)]
41+
result_messages = [byte_message[64 * i : 64 * (i + 1)] for i in range(int(L / 64))]
2342
return result_messages
2443

2544

45+
def sha256(message: str, encoding:str = "utf-8"):
46+
message = bytearray(message, encoding)
47+
return sha256_bytes(message)
2648

27-
def encrypt(message: str):
28-
message = message.encode("utf-8")
29-
print(len(message))
30-
return message
3149

32-
def encrypt_bytes(message: bytes):
50+
def sha256_bytes(message: bytes):
51+
message = pad_message(message)
52+
messages = divide_message(message)
53+
hash_values = INITIAL_HASH_VALUES
54+
for m in messages:
55+
chunk = m
56+
for i in range(16,64):
57+
i
58+
print(len(message))
3359
return NotImplementedError
3460

35-
def encrypt_file(filename):
36-
return NotImplementedError
61+
62+
def sha256_from_file(filename):
63+
with open(filename, "rb") as f:
64+
message = f.read()
65+
return sha256_bytes(message)
66+
3767

3868
if __name__ == "__main__":
3969
while True:
4070
if len(argv) == 1:
4171
message = input("Input data: ")
4272
else:
4373
message = argv[1]
44-
print(encrypt(message))
45-
46-
47-
74+
print(sha256(message))

test_project.py

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,77 @@
11
import unittest
22

33

4-
class Test_Encryption(unittest.TestCase):
5-
4+
class Test_Hashing(unittest.TestCase):
65
def setUp(self):
7-
from main import encrypt
8-
self.encrypt = encrypt
6+
from main import sha256
7+
8+
self.hash = sha256
99

1010
def test_result_against_hashlib(self):
1111
from hashlib import sha256
12+
1213
message = "mzxkjcvnjkznxjkgvneqwiufhqwpqmajsdklfmaklsdmflkmklni2h543245njk"
13-
encrypted_test = self.encrypt(message)
14-
encrypted_known = sha256(message)
15-
self.assertEqual(
16-
encrypted_test, encrypted_known
17-
)
18-
class Test_Padding(unittest.TestCase):
14+
hash_test = self.hash(message)
15+
hash_known = sha256(message)
16+
self.assertEqual(hash_test, hash_known)
17+
1918

19+
class Test_Padding(unittest.TestCase):
2020
def setUp(self):
2121
from main import pad_message
22+
2223
self.pad_message = pad_message
2324

24-
def test_correct_padding(self):
25-
message = b'abcd'
25+
def test_padding(self):
26+
message = bytearray("abcd","utf-8")
27+
padded_message = self.pad_message(message)
28+
message += b"\x80" + b"\x00" * 58 + b"\x04"
29+
self.assertEqual(padded_message, message)
30+
31+
def test_padding_for_empty(self):
32+
message = bytearray()
2633
padded_message = self.pad_message(message)
27-
message += b'\x80' + b'\x00' * 51
34+
message += b"\x80" + b"\x00" * 63
2835
self.assertEqual(padded_message, message)
2936

30-
def test_correct_padding_for_empty(self):
31-
message = b""
37+
def test_padding_for_big(self):
38+
message = bytearray("a" * 534,"utf-8")
3239
padded_message = self.pad_message(message)
33-
message = b'\x80' + b'\x00' * 55
40+
message += b"\x80" + b"\x00" * 33 + b"\x00\x00\x00\x00\x00\x00\x02\x16"
41+
print(len(message))
42+
print(len(padded_message))
3443
self.assertEqual(padded_message, message)
3544

36-
def test_correct_padding_for_big(self):
37-
message = b"a" * 534
45+
def test_padding_for_length(self):
46+
message = bytearray("a" * 534,"utf-8")
3847
padded_message = self.pad_message(message)
39-
message += b'\x80' + b'\x00' * 33
40-
self.assertEqual(padded_message, message)
48+
self.assertEqual(len(padded_message), 576)
49+
50+
51+
52+
class Test_Message_Division(unittest.TestCase):
53+
def setUp(self):
54+
from main import divide_message
55+
56+
self.divide = divide_message
57+
58+
def test_exception(self):
59+
message = b"a" * 63
60+
self.assertRaises(Exception, self.divide, message)
61+
62+
def test_correct_number(self):
63+
message = b"a" * 64 * 5
64+
messages = self.divide(message)
65+
self.assertEqual(len(messages), 5)
66+
67+
def test_correct_lengths(self):
68+
message = b"a" * 64 * 5
69+
messages = self.divide(message)
70+
for m in messages:
71+
self.assertEquals(len(m), 64)
72+
73+
def test_correct_result(self):
74+
message = b"a" * 64 * 64
75+
messages = self.divide(message)
76+
res_message = b"".join(messages)
77+
self.assertEquals(res_message, message)

0 commit comments

Comments
 (0)