Last active
March 11, 2019 19:07
-
-
Save nbulischeck/0906e7c75459ffad3141e5c224e383bc to your computer and use it in GitHub Desktop.
Revisions
-
nbulischeck revised this gist
Mar 11, 2019 . 1 changed file with 2 additions and 0 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -1,7 +1,9 @@ # Values from the white paper EXAMPLE_PHDR = 'L2 F\' B2 U D2 B U D\' F2 L\' F U2 R U\' L\' R\' U\' B F D U\''.split(" ") EXAMPLE_LHDR = 'B U2 D2 R\' F U2 B R L\' B L\' B L\' D F\' L U\' B2 R F2 L\' F2'.split(" ") EXAMPLE_MSG = 'F L U2 L2 F\' B D\' B2 L\' B\' U L2 F\' R2 D\' B\' U\' L\' B R D2 L2 R\' B F2 D\' U R B D2 U2 R2 U\' F2 R2 F D F2 B2 D\' R\' D R\' U\' F\' B2 U F2 D R U L F U2 L2 D R B D\' B\' U L U\''.split(" ") # Values from the challenge CHALL_PHDR = 'B2 R U F\' R\' L\' B B2 L F D D\' R\' F2 D\' R R D2 B\' L R'.split(" ") CHALL_LHDR = 'L\' L B F2 R2 F2 R\' L F\' B\' R D\' D\' F U2 B\' U U D\' U2 F\''.split(" ") CHALL_MSG = 'L F\' F2 R B R R F2 F\' R2 D F\' U L U\' U\' U F D F2 U R U\' F U B2 B U2 D B F2 D2 L2 L2 B\' F\' D\' L2 D U2 U2 D2 U B\' F D R2 U2 R\' B\' F2 D\' D B\' U B\' D B\' F\' U\' R U U\' L\' L\' U2 F2 R R F L2 B2 L2 B B\' D R R\' U L'.split(" ") -
nbulischeck created this gist
Mar 11, 2019 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,110 @@ EXAMPLE_PHDR = 'L2 F\' B2 U D2 B U D\' F2 L\' F U2 R U\' L\' R\' U\' B F D U\''.split(" ") EXAMPLE_LHDR = 'B U2 D2 R\' F U2 B R L\' B L\' B L\' D F\' L U\' B2 R F2 L\' F2'.split(" ") EXAMPLE_MSG = 'F L U2 L2 F\' B D\' B2 L\' B\' U L2 F\' R2 D\' B\' U\' L\' B R D2 L2 R\' B F2 D\' U R B D2 U2 R2 U\' F2 R2 F D F2 B2 D\' R\' D R\' U\' F\' B2 U F2 D R U L F U2 L2 D R B D\' B\' U L U\''.split(" ") CHALL_PHDR = 'B2 R U F\' R\' L\' B B2 L F D D\' R\' F2 D\' R R D2 B\' L R'.split(" ") CHALL_LHDR = 'L\' L B F2 R2 F2 R\' L F\' B\' R D\' D\' F U2 B\' U U D\' U2 F\''.split(" ") CHALL_MSG = 'L F\' F2 R B R R F2 F\' R2 D F\' U L U\' U\' U F D F2 U R U\' F U B2 B U2 D B F2 D2 L2 L2 B\' F\' D\' L2 D U2 U2 D2 U B\' F D R2 U2 R\' B\' F2 D\' D B\' U B\' D B\' F\' U\' R U U\' L\' L\' U2 F2 R R F L2 B2 L2 B B\' D R R\' U L'.split(" ") notation1 = ["D", "B'", "L", "R'", "R", "L'", "F2", "U", "B2"] notation2 = ["R2", "D'", "F", "U'", "B", "F'", "U2", "L2", "D2"] default_table = [ [0, "L", "F"], [1, "R", "B"], [2, "U", "L2"], [3, "D", "R2"], [4, "F2", "U2"], [5, "B2", "D2"], [6, "L'", "F'"], [7, "R'", "U'"], [8, "B'", "D'"], ] def find_encoded(i, seq): if i in notation1: f = lambda x: x[2] == i elif i in notation2: f = lambda x: x[3] == i else: quit(0) for item in seq: if f(item): return item[1] def find_default(i, seq): if i in notation1: f = lambda x: x[1] == i elif i in notation2: f = lambda x: x[2] == i else: quit(0) for item in seq: if f(item): return item[0] def get_enc_table(HEADER): # Step 1: Map header to default table in base-9 ENCODED_P = ''.join([str(find_default(i, default_table)) for i in HEADER]) # Step 2: Convert first scramble into decimal ENCODED_P = str(int(ENCODED_P, 9)) # Reverse engineering of 2.1.1 Embedding the permutation information i = int(ENCODED_P[0]) sub1 = ENCODED_P[1:i+1] P = ENCODED_P[i+1:i+10] sub2 = ENCODED_P[i+10:] # Use P to permute the default encoding table enc_table = [default_table[int(x)] for x in P] # Insert the "After" indexes for idx, item in enumerate(enc_table): item.insert(1, idx) return enc_table def get_length(enc_table, HEADER): # Step 1: Map header to encoded table in base-9 HEADER_LENGTH = ''.join([str(find_encoded(i, enc_table)) for i in HEADER]) # Step 2: Convert first scramble into decimal HEADER_LENGTH = str(int(HEADER_LENGTH, 9)) # Reverse engineering of 2.1.3 Embedding the length information j = int(HEADER_LENGTH[0]) k = int(HEADER_LENGTH[1]) sub3 = HEADER_LENGTH[2:j+2] length = int(HEADER_LENGTH[j+2:j+2+k]) sub4 = HEADER_LENGTH[j+2+k:] return length def decrypt_message(length, enc_table, MESSAGE): # Step 1: Get m by taking length notations starting from third scramble MESSAGE_PIECE = MESSAGE[0:length] # Step 2: Map header to encoded table in base-9 MAPPED_MESSAGE = ''.join([str(find_encoded(i, enc_table)) for i in MESSAGE_PIECE]) # Step 2: Convert first scramble into decimal, then binary MAPPED_MESSAGE = int(MAPPED_MESSAGE, 9) BINARY_MESSAGE = f"{MAPPED_MESSAGE:b}" # Step N: Pad PADDED_MESSAGE = '0' * (8 - (151 % 8)) + BINARY_MESSAGE # Step N: Chunk CHUNKED_MESSAGE = [PADDED_MESSAGE[i:i+8] for i in range(0, len(PADDED_MESSAGE), 8)] # Step N: Join DECRYPTED_MESSAGE = ''.join([chr(int(x, 2)) for x in CHUNKED_MESSAGE]) print(DECRYPTED_MESSAGE) enc_table = get_enc_table(CHALL_PHDR) length = get_length(enc_table, CHALL_LHDR) decrypt_message(length, enc_table, CHALL_MSG)