Skip to content

Commit 05035c4

Browse files
committed
Updated CBC mode for HIGHT
Variable name corrected. Added CBC mode.
1 parent de0346c commit 05035c4

File tree

4 files changed

+146
-30
lines changed

4 files changed

+146
-30
lines changed

README.md

+61-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
# HIGHT
22
### Introduction
33

4-
HIGHT is a lightweight block cipher that accepts a 64-bit plaintext and 128-bit master key. Through this Python3 implementation, we attempt to shed light on the complexities of this cipher (in ECB mode). Original paper with pseudocode and detailed explanation of the cipher can be found <a href = "https://iacr.org/archive/ches2006/04/04.pdf">here</a>.
4+
HIGHT is a lightweight block cipher that accepts a 64-bit plaintext and 128-bit master key. Through this Python3 implementation, we attempt to shed light on the complexities of this cipher (in ECB and CBC mode). Original paper with pseudocode and detailed explanation of the cipher can be found <a href = "https://iacr.org/archive/ches2006/04/04.pdf">here</a>. This work is done jointly with <a href = https://github.com/ph1nx>ph1nx</a>.
55

66
### How to use
77

8-
To encrypt and decrypt, use functions ```hight_encryption(P, MK)``` and ```hight_decryption(C, MK)``` respectively. Do import all functions found in <i>hight.py</i> to ensure that cipher is working well.
8+
For simple encryption and decryption of 64-bit plaintext, use naive functions ```hight_encryption(P, MK)``` and ```hight_decryption(C, MK)``` respectively. All functions in *hight.py* are implemented as what the original paper details.
99

10-
You would need to edit the values for the master key (MK) and plaintext (P) in the code. Here are some example values for MK, P and ciphertext (C):
10+
You would need to edit the values for the master key (MK) and plaintext (P) in the code. Here are some example values for MK, P and ciphertext (C) for ECB mode:
1111

1212
```python
1313
MK = [0x88, 0xE3, 0x4F, 0x8F, 0x08, 0x17, 0x79, 0xF1, 0xE9, 0xF3, 0x94, 0x37, 0x0A, 0xD4, 0x05, 0x89]
@@ -99,6 +99,64 @@ P = [0x32, 0x22, 0xF4, 0xCC, 0xCF, 0xD3, 0x90, 0x2D]
9999
expected_C = [0xBB, 0x80, 0xF5, 0x0B, 0x35, 0x11, 0x5B, 0xA8]
100100
```
101101

102+
You would need to also edit the initialization vector (IV) for CBC mode. Here are some example values for MK, IV, P, C for CBC mode:
103+
104+
```python
105+
MK = [0x88, 0xE3, 0x4F, 0x8F, 0x08, 0x17, 0x79, 0xF1, 0xE9, 0xF3, 0x94, 0x37, 0x0A, 0xD4, 0x05, 0x89]
106+
IV = [0x26, 0x8D, 0x66, 0xA7, 0x35, 0xA8, 0x1A, 0x81]
107+
P = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07]
108+
expected_C = [0xCE, 0x15, 0x95, 0x08, 0x5A, 0x18, 0x8C, 0x28]
109+
```
110+
111+
```python
112+
MK = [0x88, 0xE3, 0x4F, 0x8F, 0x08, 0x17, 0x79, 0xF1, 0xE9, 0xF3, 0x94, 0x37, 0x0A, 0xD4, 0x05, 0x89]
113+
IV = [0x26, 0x8D, 0x66, 0xA7, 0x35, 0xA8, 0x1A, 0x81]
114+
P = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F]
115+
expected_C = [0xCE, 0x15, 0x95, 0x08, 0x5A, 0x18, 0x8C, 0x28, 0xC1, 0x8D, 0x77, 0x08, 0xD9, 0xC1, 0x25, 0x86]
116+
```
117+
118+
```python
119+
MK = [0x88, 0xE3, 0x4F, 0x8F, 0x08, 0x17, 0x79, 0xF1, 0xE9, 0xF3, 0x94, 0x37, 0x0A, 0xD4, 0x05, 0x89]
120+
IV = [0x26, 0x8D, 0x66, 0xA7, 0x35, 0xA8, 0x1A, 0x81]
121+
P = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07]
122+
expected_C = [0xCE, 0x15, 0x95, 0x08, 0x5A, 0x18, 0x8C, 0x28, 0xC1, 0x8D, 0x77, 0x08, 0xD9, 0xC1, 0x25, 0x86, 0x4B, 0x3D, 0xAF, 0x2B, 0xF2, 0x0D, 0x52, 0x47]
123+
```
124+
125+
```python
126+
MK = [0x88, 0xE3, 0x4F, 0x8F, 0x08, 0x17, 0x79, 0xF1, 0xE9, 0xF3, 0x94, 0x37, 0x0A, 0xD4, 0x05, 0x89]
127+
IV = [0x26, 0x8D, 0x66, 0xA7, 0x35, 0xA8, 0x1A, 0x81]
128+
P = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F]
129+
expected_C = [0xCE, 0x15, 0x95, 0x08, 0x5A, 0x18, 0x8C, 0x28, 0xC1, 0x8D, 0x77, 0x08, 0xD9, 0xC1, 0x25, 0x86, 0x4B, 0x3D, 0xAF, 0x2B, 0xF2, 0x0D, 0x52, 0x47, 0x63, 0x4A, 0x00, 0x01, 0x2F, 0xA0, 0xE9, 0xF0]
130+
```
131+
132+
```python
133+
MK = [0x88, 0xE3, 0x4F, 0x8F, 0x08, 0x17, 0x79, 0xF1, 0xE9, 0xF3, 0x94, 0x37, 0x0A, 0xD4, 0x05, 0x89]
134+
IV = [0x26, 0x8D, 0x66, 0xA7, 0x35, 0xA8, 0x1A, 0x81]
135+
P = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07]
136+
expected_C = [0xCE, 0x15, 0x95, 0x08, 0x5A, 0x18, 0x8C, 0x28, 0xC1, 0x8D, 0x77, 0x08, 0xD9, 0xC1, 0x25, 0x86, 0x4B, 0x3D, 0xAF, 0x2B, 0xF2, 0x0D, 0x52, 0x47, 0x63, 0x4A, 0x00, 0x01, 0x2F, 0xA0, 0xE9, 0xF0, 0x44, 0x9D, 0xE2, 0xBC, 0xC1, 0x68, 0x51, 0x6C]
137+
```
138+
139+
```python
140+
MK = [0x88, 0xE3, 0x4F, 0x8F, 0x08, 0x17, 0x79, 0xF1, 0xE9, 0xF3, 0x94, 0x37, 0x0A, 0xD4, 0x05, 0x89]
141+
IV = [0x26, 0x8D, 0x66, 0xA7, 0x35, 0xA8, 0x1A, 0x81]
142+
P = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F]
143+
expected_C = [0xCE, 0x15, 0x95, 0x08, 0x5A, 0x18, 0x8C, 0x28, 0xC1, 0x8D, 0x77, 0x08, 0xD9, 0xC1, 0x25, 0x86, 0x4B, 0x3D, 0xAF, 0x2B, 0xF2, 0x0D, 0x52, 0x47, 0x63, 0x4A, 0x00, 0x01, 0x2F, 0xA0, 0xE9, 0xF0, 0x44, 0x9D, 0xE2, 0xBC, 0xC1, 0x68, 0x51, 0x6C, 0x0E, 0x27, 0x45, 0xAC, 0x37, 0xC1, 0xA6, 0x74]
144+
```
145+
146+
```python
147+
MK = [0x88, 0xE3, 0x4F, 0x8F, 0x08, 0x17, 0x79, 0xF1, 0xE9, 0xF3, 0x94, 0x37, 0x0A, 0xD4, 0x05, 0x89]
148+
IV = [0x26, 0x8D, 0x66, 0xA7, 0x35, 0xA8, 0x1A, 0x81]
149+
P = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07]
150+
expected_C = [0xCE, 0x15, 0x95, 0x08, 0x5A, 0x18, 0x8C, 0x28, 0xC1, 0x8D, 0x77, 0x08, 0xD9, 0xC1, 0x25, 0x86, 0x4B, 0x3D, 0xAF, 0x2B, 0xF2, 0x0D, 0x52, 0x47, 0x63, 0x4A, 0x00, 0x01, 0x2F, 0xA0, 0xE9, 0xF0, 0x44, 0x9D, 0xE2, 0xBC, 0xC1, 0x68, 0x51, 0x6C, 0x0E, 0x27, 0x45, 0xAC, 0x37, 0xC1, 0xA6, 0x74, 0x3A, 0x1E, 0xA5, 0x1E, 0xB4, 0x07, 0xD1, 0x4E]
151+
```
152+
153+
```python
154+
MK = [0x88, 0xE3, 0x4F, 0x8F, 0x08, 0x17, 0x79, 0xF1, 0xE9, 0xF3, 0x94, 0x37, 0x0A, 0xD4, 0x05, 0x89]
155+
IV = [0x26, 0x8D, 0x66, 0xA7, 0x35, 0xA8, 0x1A, 0x81]
156+
P = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F]
157+
expected_C = [0xCE, 0x15, 0x95, 0x08, 0x5A, 0x18, 0x8C, 0x28, 0xC1, 0x8D, 0x77, 0x08, 0xD9, 0xC1, 0x25, 0x86, 0x4B, 0x3D, 0xAF, 0x2B, 0xF2, 0x0D, 0x52, 0x47, 0x63, 0x4A, 0x00, 0x01, 0x2F, 0xA0, 0xE9, 0xF0, 0x44, 0x9D, 0xE2, 0xBC, 0xC1, 0x68, 0x51, 0x6C, 0x0E, 0x27, 0x45, 0xAC, 0x37, 0xC1, 0xA6, 0x74, 0x3A, 0x1E, 0xA5, 0x1E, 0xB4, 0x07, 0xD1, 0x4E, 0xC8, 0xC4, 0xB4, 0x35, 0xCA, 0x05, 0xCC, 0x62]
158+
```
159+
102160
### Citations
103161

104162
```latex

hight.py

+2-27
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,3 @@
1-
# TEST CASE
2-
MK = [0x88, 0xE3, 0x4F, 0x8F, 0x08, 0x17, 0x79, 0xF1, 0xE9, 0xF3, 0x94, 0x37, 0x0A, 0xD4, 0x05, 0x89]
3-
P = [0xD7, 0x6D, 0x0D, 0x18, 0x32, 0x7E, 0xC5, 0x62]
4-
expected_C = [0xE4, 0xBC, 0x2E, 0x31, 0x22, 0x77, 0xE4, 0xDD]
5-
6-
# MAIN CODE
7-
print("Plaintext:", [hex(byte)[2:].upper() for byte in P])
8-
9-
assert len(P) == 8
10-
assert all(0 <= byte <= 0xFF for byte in P)
11-
assert len(MK) == 16
12-
assert all(0 <= byte <= 0xFF for byte in MK)
13-
141
def list_to_byte(lst):
152
byte = 0
163
for bit in lst:
@@ -140,7 +127,7 @@ def decryption_final_transformation(X_32, WK):
140127
]
141128
return D
142129

143-
def encryption_tranformation(P, WK, SK):
130+
def encryption_transformation(P, WK, SK):
144131
X_i = encryption_initial_transformation(P, WK)
145132
for i in range(32):
146133
X_i = encryption_round_function(i, X_i, SK)
@@ -156,22 +143,10 @@ def decryption_transformation(C, WK, SK):
156143

157144
def hight_encryption(P, MK):
158145
WK, SK = encryption_key_schedule(MK)
159-
C = encryption_tranformation(P, WK, SK)
146+
C = encryption_transformation(P, WK, SK)
160147
return C
161148

162149
def hight_decryption(C, MK):
163150
WK, SK = decryption_key_schedule(MK)
164151
D = decryption_transformation(C, WK, SK)
165152
return D
166-
167-
C = hight_encryption(P, MK)
168-
169-
print("Encrypted bytes:", [hex(byte)[2:].upper() for byte in C])
170-
171-
assert C == expected_C
172-
173-
D = hight_decryption(C, MK)
174-
175-
print("Decrypted bytes:", [hex(byte)[2:].upper() for byte in D])
176-
177-
assert D == P

hight_CBC.py

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from hight import encryption_key_schedule, decryption_key_schedule, encryption_transformation, decryption_transformation
2+
3+
# TEST CASE
4+
MK = [0x88, 0xE3, 0x4F, 0x8F, 0x08, 0x17, 0x79, 0xF1, 0xE9, 0xF3, 0x94, 0x37, 0x0A, 0xD4, 0x05, 0x89]
5+
IV = [0x26, 0x8D, 0x66, 0xA7, 0x35, 0xA8, 0x1A, 0x81]
6+
P = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07]
7+
expected_C = [0xCE, 0x15, 0x95, 0x08, 0x5A, 0x18, 0x8C, 0x28]
8+
9+
# MAIN CODE
10+
print("Plaintext:", [hex(byte)[2:].upper() for byte in P])
11+
12+
assert not len(P) % 8 and P
13+
assert all(0 <= byte <= 0xFF for byte in P)
14+
assert len(IV) == 8
15+
assert all(0 <= byte <= 0xFF for byte in IV)
16+
assert len(MK) == 16
17+
assert all(0 <= byte <= 0xFF for byte in MK)
18+
19+
def cbc_hight_encryption(P, IV, MK):
20+
WK, SK = encryption_key_schedule(MK)
21+
C = encryption_transformation([P_i ^ IV_i for P_i, IV_i in zip(P[:8], IV)], WK, SK)
22+
for block in range(8, len(P), 8):
23+
C += encryption_transformation([P_i ^ C_i for P_i, C_i in zip(P[block:block + 8], C[block - 8:block])], WK, SK)
24+
return C
25+
26+
C = cbc_hight_encryption(P, IV, MK)
27+
28+
print("Encrypted bytes:", [hex(byte)[2:].upper() for byte in C])
29+
30+
assert C == expected_C
31+
32+
def cbc_hight_decryption(C, IV, MK):
33+
WK, SK = decryption_key_schedule(MK)
34+
D = [C_i ^ IV_i for C_i, IV_i in zip(decryption_transformation(C[:8], WK, SK), IV)]
35+
for block in range(8, len(C), 8):
36+
D += [C_i ^ D_i for C_i, D_i in zip(decryption_transformation(C[block:block + 8], WK, SK), C[block - 8:block])]
37+
return D
38+
39+
D = cbc_hight_decryption(C, IV, MK)
40+
41+
print("Decrypted bytes:", [hex(byte)[2:].upper() for byte in D])
42+
43+
assert D == P

hight_ECB.py

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from hight import encryption_key_schedule, decryption_key_schedule, encryption_transformation, decryption_transformation
2+
3+
# TEST CASE
4+
MK = [0x88, 0xE3, 0x4F, 0x8F, 0x08, 0x17, 0x79, 0xF1, 0xE9, 0xF3, 0x94, 0x37, 0x0A, 0xD4, 0x05, 0x89]
5+
P = [0xD7, 0x6D, 0x0D, 0x18, 0x32, 0x7E, 0xC5, 0x62]
6+
expected_C = [0xE4, 0xBC, 0x2E, 0x31, 0x22, 0x77, 0xE4, 0xDD]
7+
8+
# MAIN CODE
9+
print("Plaintext:", [hex(byte)[2:].upper() for byte in P])
10+
11+
assert not len(P) % 8 and P
12+
assert all(0 <= byte <= 0xFF for byte in P)
13+
assert len(MK) == 16
14+
assert all(0 <= byte <= 0xFF for byte in MK)
15+
16+
def ecb_hight_encryption(P, MK):
17+
WK, SK = encryption_key_schedule(MK)
18+
C = encryption_transformation(P, WK, SK)
19+
for block in range(8, len(P), 8):
20+
C += encryption_transformation(P[block:block + 8], WK, SK)
21+
return C
22+
23+
C = ecb_hight_encryption(P, MK)
24+
25+
print("Encrypted bytes:", [hex(byte)[2:].upper() for byte in C])
26+
27+
assert C == expected_C
28+
29+
def ecb_hight_decryption(C, MK):
30+
WK, SK = decryption_key_schedule(MK)
31+
D = decryption_transformation(C, WK, SK)
32+
for block in range(8, len(P), 8):
33+
D += decryption_transformation(C[block:block + 8], WK, SK)
34+
return D
35+
36+
D = ecb_hight_decryption(C, MK)
37+
38+
print("Decrypted bytes:", [hex(byte)[2:].upper() for byte in D])
39+
40+
assert D == P

0 commit comments

Comments
 (0)