Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
L
LCB Cipher
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Neural-LCB
LCB Cipher
Commits
7c35642b
Commit
7c35642b
authored
1 year ago
by
Indrakanti Aishwarya
Browse files
Options
Downloads
Patches
Plain Diff
Delete LCB_Dynamic_Modified.ipynb
parent
8934c162
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
LCB/LCB_Dynamic_Modified.ipynb
+0
-749
0 additions, 749 deletions
LCB/LCB_Dynamic_Modified.ipynb
with
0 additions
and
749 deletions
LCB/LCB_Dynamic_Modified.ipynb
deleted
100644 → 0
+
0
−
749
View file @
8934c162
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"#1#Header\n",
"import csv\n",
"import numpy as np\n",
"import os \n",
"from os import urandom\n",
"from keras.models import model_from_json"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [],
"source": [
"#2#Defining Permutation Box and Substituition Box\n",
"num_rounds = 10\n",
"m = 0\n",
"o = 0"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"#3#WORDSIZE\n",
"def WORD_SIZE():\n",
" return(16);"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"\n",
"s_box_mapping_np = np.array([12, 5, 6, 11, 9, 0, 10, 13, 3, 14, 15, 8, 4, 7, 1, 2], dtype=np.uint8)\n",
"\n",
"def s_box(input_bits):\n",
" input_bits_int = int(input_bits)\n",
" #print(input_bits_int)\n",
" output_bits_int = s_box_mapping_np[input_bits_int]\n",
" return output_bits_int"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"\n",
"def decimal_to_binary_list(value, num_bits=4):\n",
" return np.array([int(x) for x in format(value, f'0{num_bits}b')], dtype=np.uint8)\n",
"\n",
"def p_box(c_decimal, d_decimal):\n",
" c = decimal_to_binary_list(c_decimal)\n",
" d = decimal_to_binary_list(d_decimal)\n",
"\n",
" e = np.zeros(8, dtype=np.uint8)\n",
"\n",
" e[0] = c[0]\n",
" e[1] = d[0]\n",
" e[2] = c[3]\n",
" e[3] = d[3]\n",
" e[4] = c[1]\n",
" e[5] = d[1]\n",
" e[6] = c[2]\n",
" e[7] = d[2]\n",
"\n",
" return e"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"#6#L box\n",
"def l_box(f, g):\n",
" if len(f) != 8 or len(g) != 8:\n",
" raise ValueError(\"Both input arrays f and g should have exactly 8 elements\")\n",
"\n",
" h = np.zeros(16, dtype=np.uint8)\n",
" h[0] = f[0]\n",
" h[1] = g[0]\n",
" h[2] = f[7]\n",
" h[3] = g[7]\n",
" h[4] = f[1]\n",
" h[5] = g[1]\n",
" h[6] = f[6]\n",
" h[7] = g[6]\n",
" h[8] = f[2]\n",
" h[9] = g[2]\n",
" h[10] = f[5]\n",
" h[11] = g[5]\n",
" h[12] = f[3]\n",
" h[13] = g[3]\n",
" h[14] = f[4]\n",
" h[15] = g[4]\n",
" #print(h)\n",
" return h"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [],
"source": [
"#7#F function\n",
"def binary_array_to_integer(output):\n",
" int_output = ''.join(map(str, output))\n",
" return int(int_output, 2)\n",
"\n",
"def f_function(x, key, d):\n",
" q=0\n",
" global m\n",
" if isinstance(x, int):\n",
" x = [x]\n",
" #print(x)\n",
" \n",
" input_parts = np.zeros((len(x), 4), dtype=np.uint16)\n",
" for i, val in enumerate(x):\n",
" input_parts[i] = np.array([val >> 12, (val >> 8) & 0xF, (val >> 4) & 0xF, val & 0xF])\n",
" #print(input_parts[0], input_parts[1], input_parts[2], input_parts[3])\n",
" #print(\"input parts:\", input_parts)\n",
" \n",
" s_box_outputs = np.array([[s_box(element) for element in part] for part in input_parts])\n",
" #print(\"s box:\", s_box_outputs)\n",
" \n",
" p_box_outputs = np.zeros((len(x), 2, 8), dtype=np.uint8)\n",
" for i in range(len(x)):\n",
" p_box_outputs[i] = np.array([p_box(s_box_outputs[i][0], s_box_outputs[i][1]), p_box(s_box_outputs[i][2], s_box_outputs[i][3])])\n",
" #print(\"p_box\")\n",
" #print(\"p box:\", p_box_outputs)\n",
" final_outputs = np.zeros(len(x), dtype=np.uint32)\n",
" for i in range(len(x)):\n",
" final_output = np.array(l_box(p_box_outputs[i][0], p_box_outputs[i][1]))\n",
" #print(\"final output:\", final_output)\n",
" k = key[q][(m+1) % 4]\n",
" output = final_output ^ k\n",
" #print(\"k:\", k)\n",
" #print(\"output before:\", output)\n",
" output = binary_array_to_integer(output)\n",
" #print(\"output after:\", output)\n",
" #print(\"________________________________________________________\")\n",
" final_outputs[i] = output\n",
" q +=1 \n",
" if (m < 2):\n",
" m +=2\n",
" else:\n",
" m = 0\n",
" return final_outputs\n",
" #return output"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [],
"source": [
"#7#F function\n",
"def binary_array_to_integer(output):\n",
" int_output = ''.join(map(str, output))\n",
" return int(int_output, 2)\n",
"\n",
"def ff_function(x, key, d):\n",
" q=0\n",
" global o\n",
" if isinstance(x, int):\n",
" x = [x]\n",
" #print(x)\n",
" \n",
" input_parts = np.zeros((len(x), 4), dtype=np.uint16)\n",
" for i, val in enumerate(x):\n",
" input_parts[i] = np.array([val >> 12, (val >> 8) & 0xF, (val >> 4) & 0xF, val & 0xF])\n",
" #print(input_parts[0], input_parts[1], input_parts[2], input_parts[3])\n",
" #print(\"input parts:\", input_parts)\n",
" \n",
" s_box_outputs = np.array([[s_box(element) for element in part] for part in input_parts])\n",
" #print(\"s box:\", s_box_outputs)\n",
" \n",
" p_box_outputs = np.zeros((len(x), 2, 8), dtype=np.uint8)\n",
" for i in range(len(x)):\n",
" p_box_outputs[i] = np.array([p_box(s_box_outputs[i][0], s_box_outputs[i][1]), p_box(s_box_outputs[i][2], s_box_outputs[i][3])])\n",
" #print(\"p_box\")\n",
" #print(\"p box:\", p_box_outputs)\n",
" final_outputs = np.zeros(len(x), dtype=np.uint32)\n",
" for i in range(len(x)):\n",
" final_output = np.array(l_box(p_box_outputs[i][0], p_box_outputs[i][1]))\n",
" #print(\"final output:\", final_output)\n",
" k = key[q][o % 4]\n",
" output = final_output ^ k\n",
" #print(\"k:\", k)\n",
" #print(\"output before:\", output)\n",
" output = binary_array_to_integer(output)\n",
" #print(\"output after:\", output)\n",
" #print(\"________________________________________________________\")\n",
" final_outputs[i] = output\n",
" q +=1 \n",
" if (o < 2):\n",
" o +=2\n",
" else:\n",
" o = 0\n",
" return final_outputs\n",
" #return output"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"\n",
"def convert_to_binary(row):\n",
" bin_array = np.zeros(64, dtype=np.uint8)\n",
" for i, num in enumerate(row):\n",
" binary_str = format(num, '016b')\n",
" for j, b in enumerate(binary_str):\n",
" bin_array[i * 16 + j] = int(b)\n",
" return bin_array"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [],
"source": [
"#9#Encrypt Function\n",
"def lcb_encrypt(plaintext, key, rounds, d):\n",
" print(plaintext)\n",
" left_plaintext = np.uint16(plaintext[0])\n",
" right_plaintext = np.uint16(plaintext[1])\n",
" L, R = left_plaintext, right_plaintext\n",
" #print(L)\n",
" #print(R)\n",
" #print(key)\n",
" n = 0\n",
" m = 0\n",
" q = 0\n",
" \n",
" while n < rounds:\n",
" #print(\"(m+1) % 4\", (m+1) % 4)\n",
" #print(\"m % 4\", m % 4)\n",
" #print(key[q])\n",
" L, R = f_function(R, key, d), ff_function(L, key, d)\n",
" #print(key[q][(m+1) % 4])\n",
" #print(key[q][m % 4])\n",
" n += 1\n",
" \n",
" return (L, R)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [],
"source": [
"import random\n",
"\n",
"def generate_hex_keys(num_keys, length=16):\n",
" hex_chars = \"0123456789ABCDEF\"\n",
" keys_str = [\"\".join(random.choices(hex_chars, k=length)) for _ in range(num_keys)]\n",
" #print(keys_str)\n",
" return keys_str\n",
"\n",
"\n",
"def to_binary(value, bits):\n",
" return format(value, f'0{bits}b')\n",
"\n",
"def generate_round_keys(num_keys):\n",
" random_keys_hex = generate_hex_keys(num_keys)\n",
" #random_keys_hex = ['D622529ECC92D353', '163A529ECC92D353', '967AD296CC92DB53', 'F4AB5DB7D4EBF352', '76BA569EDC93D353']\n",
" #random_keys_hex = ['163A529D687529EC', 'D622529ECC92D353']\n",
" #random_keys_hex = ['163A529D687529EC']\n",
" round_keys = []\n",
" \n",
" for random_key_hex in random_keys_hex:\n",
" random_key = int(random_key_hex, 16)\n",
"\n",
" K1 = (random_key >> 48) & 0xFFFF\n",
" K2 = (random_key >> 32) & 0xFFFF\n",
" K3 = (random_key >> 16) & 0xFFFF\n",
" K4 = random_key & 0xFFFF\n",
" #print(\"Key parts:\", K1, K2, K3, K4)\n",
" k1_bin = to_binary(K1, 16)\n",
" k2_bin = to_binary(K2, 16)\n",
" k3_bin = to_binary(K3, 16)\n",
" k4_bin = to_binary(K4, 16)\n",
"\n",
" k1_np_array = np.array([int(bit) for bit in k1_bin])\n",
" k2_np_array = np.array([int(bit) for bit in k2_bin])\n",
" k3_np_array = np.array([int(bit) for bit in k3_bin])\n",
" k4_np_array = np.array([int(bit) for bit in k4_bin])\n",
"\n",
" round_key = np.array([k1_np_array, k2_np_array, k3_np_array, k4_np_array])\n",
" round_keys.append(round_key)\n",
" round_key = np.array(round_keys)\n",
" #print(round_key)\n",
" return round_key"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"#9#Make dataset\n",
"\n",
"def make_train_data(n, nr, diff=(0x0040,0)):\n",
" Y = np.frombuffer(urandom(n), dtype=np.uint8); \n",
" Y = Y & 1;\n",
" plaintext = np.frombuffer(urandom(4*n), dtype=np.uint32);\n",
" #plaintext = [0xCED4B5C6, 0xEED4B555, 0xEFAAE23D, 0xDDAB43B, 0x6DAE4BB5]\n",
" #plaintext = [0xCED4B5C6, 0xEED4B555]\n",
" #plaintext = [0xEED4B555]\n",
" plain0l = np.empty(n, dtype=np.uint16)\n",
" plain0r = np.empty(n, dtype=np.uint16)\n",
" \n",
" for i in range(n):\n",
" plain0l[i] = (plaintext[i] >> 16) & 0xffff\n",
" plain0r[i] = plaintext[i] & 0xffff\n",
" \n",
" plain1l = plain0l ^ diff[0]; plain1r = plain0r ^ diff[1];\n",
" \n",
" num_rand_samples = np.sum(Y==0);\n",
" plain1l[Y==0] = np.frombuffer(urandom(2*num_rand_samples),dtype=np.uint16);\n",
" plain1r[Y==0] = np.frombuffer(urandom(2*num_rand_samples),dtype=np.uint16);\n",
" #print(\"PLAINTEXT\")\n",
" #print(plain0l)\n",
" #print(plain0r)\n",
" #print(plain1l)\n",
" #print(plain1r)\n",
" round_key = generate_round_keys(n)\n",
" #print(\"KEY IN BINARY\")\n",
" #print(round_key)\n",
" ctdata0l, ctdata0r = lcb_encrypt((plain0l, plain0r), round_key, nr, n)\n",
" ctdata1l, ctdata1r = lcb_encrypt((plain1l, plain1r), round_key, nr, n)\n",
" #print(\"CIPHERTEXT\")\n",
" #print(\"ctdata0l\",ctdata0l)\n",
" #print(\"ctdata0r\",ctdata0r)\n",
" #print(\"ctdata1l\",ctdata1l)\n",
" #print(\"ctdata1r\",ctdata1r)\n",
"\n",
" ctdata = np.vstack((ctdata0l, ctdata0r, ctdata1l, ctdata1r)).T\n",
" X = np.array([convert_to_binary(row) for row in ctdata])\n",
" #print(\"CIPHERTEXT IN BINARY\")\n",
" #print(X)\n",
" \"\"\"\n",
" with open(\"Dataset_NewP.csv\", \"w\", newline='') as f:\n",
" writer = csv.writer(f)\n",
" writer.writerow([\"plain0l\", \"plain0r\", \"plain1l\", \"plain1r\",\"Y\"])\n",
" for i in range(n):\n",
" writer.writerow([plain0l[i], plain0r[i], plain1l[i], plain1r[i],Y[i]])\n",
"\n",
" with open(\"Dataset_NewC.csv\", \"w\", newline='') as f:\n",
" writer = csv.writer(f)\n",
" writer.writerow([\"ctdata0l\", \"ctdata0r\", \"ctdata1l\", \"ctdata1r\",\"Y\"])\n",
" for i in range(n):\n",
" writer.writerow([ctdata0l[i], ctdata0r[i], ctdata1l[i], ctdata1r[i],Y[i]])\n",
" \"\"\"\n",
" return(X,Y);"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"scrolled": false
},
"outputs": [
{
"ename": "NameError",
"evalue": "name 'np' is not defined",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m~\\AppData\\Local\\Temp\\ipykernel_13352\\2995501280.py\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mX\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mY\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mmake_train_data\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m100\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m10\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[1;32m~\\AppData\\Local\\Temp\\ipykernel_13352\\1935914450.py\u001b[0m in \u001b[0;36mmake_train_data\u001b[1;34m(n, nr, diff)\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mmake_train_data\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mn\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mnr\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdiff\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m0x0040\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m \u001b[0mY\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfrombuffer\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0murandom\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mn\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0muint8\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m;\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 5\u001b[0m \u001b[0mY\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mY\u001b[0m \u001b[1;33m&\u001b[0m \u001b[1;36m1\u001b[0m\u001b[1;33m;\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 6\u001b[0m \u001b[0mplaintext\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfrombuffer\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0murandom\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m4\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0mn\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0muint32\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m;\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;31mNameError\u001b[0m: name 'np' is not defined"
]
}
],
"source": [
"X, Y = make_train_data(100, 10)"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [],
"source": [
"#10#Creating Model\n",
"\n",
"from pickle import dump\n",
"\n",
"from keras.callbacks import ModelCheckpoint, LearningRateScheduler\n",
"from keras.models import Model\n",
"from keras.optimizers import Adam\n",
"from keras.layers import Dense, Conv1D, Input, Reshape, Permute, Add, Flatten, BatchNormalization, Activation\n",
"from keras import backend as K\n",
"from keras.regularizers import l2\n",
"\n",
"bs = 5000;\n",
"wdir = './freshly_trained_nets/'\n",
"\n",
"def cyclic_lr(num_epochs, high_lr, low_lr):\n",
" res = lambda i: low_lr + ((num_epochs-1) - i % num_epochs)/(num_epochs-1) * (high_lr - low_lr);\n",
" return(res);\n",
"\n",
"def make_checkpoint(datei):\n",
" res = ModelCheckpoint(datei, monitor='val_loss', save_best_only = True);\n",
" return(res);\n",
"\n",
"#make residual tower of convolutional blocks\n",
"def make_resnet(num_blocks=2, num_filters=32, num_outputs=1, d1=64, d2=64, word_size=16, ks=3,depth=5, reg_param=0.0001, final_activation='sigmoid'):\n",
" #Input and preprocessing layers\n",
" inp = Input(shape=(num_blocks * word_size * 2,));\n",
" rs = Reshape((2 * num_blocks, word_size))(inp);\n",
" perm = Permute((2,1))(rs);\n",
" #add a single residual layer that will expand the data to num_filters channels\n",
" #this is a bit-sliced layer\n",
" conv0 = Conv1D(num_filters, kernel_size=1, padding='same', kernel_regularizer=l2(reg_param))(perm);\n",
" conv0 = BatchNormalization()(conv0);\n",
" conv0 = Activation('relu')(conv0);\n",
" #add residual blocks\n",
" shortcut = conv0;\n",
" for i in range(depth):\n",
" conv1 = Conv1D(num_filters, kernel_size=ks, padding='same', kernel_regularizer=l2(reg_param))(shortcut);\n",
" conv1 = BatchNormalization()(conv1);\n",
" conv1 = Activation('relu')(conv1);\n",
" conv2 = Conv1D(num_filters, kernel_size=ks, padding='same',kernel_regularizer=l2(reg_param))(conv1);\n",
" conv2 = BatchNormalization()(conv2);\n",
" conv2 = Activation('relu')(conv2);\n",
" shortcut = Add()([shortcut, conv2]);\n",
" #add prediction head\n",
" flat1 = Flatten()(shortcut);\n",
" dense1 = Dense(d1,kernel_regularizer=l2(reg_param))(flat1);\n",
" dense1 = BatchNormalization()(dense1);\n",
" dense1 = Activation('relu')(dense1);\n",
" dense2 = Dense(d2, kernel_regularizer=l2(reg_param))(dense1);\n",
" dense2 = BatchNormalization()(dense2);\n",
" dense2 = Activation('relu')(dense2);\n",
" out = Dense(num_outputs, activation=final_activation, kernel_regularizer=l2(reg_param))(dense2);\n",
" model = Model(inputs=inp, outputs=out);\n",
" return(model);\n",
"\n",
"def train_LCB_distinguisher(num_epochs, num_rounds, depth):\n",
" #create the network\n",
" print(num_rounds)\n",
" net = make_resnet(depth=depth, reg_param=10**-5);\n",
" net.compile(optimizer='adam',loss='mse',metrics=['acc']);\n",
" #generate training and validation data\n",
" X, Y = make_train_data(10**6,num_rounds);\n",
" X_eval, Y_eval = make_train_data(10**5, num_rounds);\n",
" #set up model checkpoint\n",
" check = make_checkpoint(wdir+'ghor_Rk_0000_0040_Round_'+str(num_rounds)+'_depth_'+str(depth)+'.h5');\n",
" #create learnrate schedule\n",
" lr = LearningRateScheduler(cyclic_lr(10,0.002, 0.0001));\n",
" #train and evaluate\n",
" #print(X_eval)\n",
" h = net.fit(X,Y,epochs=num_epochs,batch_size=bs,validation_data=(X_eval, Y_eval), callbacks=[lr,check]);\n",
" np.save(wdir+'h'+str(num_rounds)+'r_depth'+str(depth)+'.npy', h.history['val_acc']);\n",
" np.save(wdir+'h'+str(num_rounds)+'r_depth'+str(depth)+'.npy', h.history['val_loss']);\n",
" dump(h.history,open(wdir+'hist'+str(num_rounds)+'r_depth'+str(depth)+'.p','wb'));\n",
" print(\"Best validation accuracy: \", np.max(h.history['val_acc']));\n",
" return(net, h);\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"#15#Evaluate Function\n",
"def evaluate(net,X,Y):\n",
" Z = net.predict(X,batch_size=10000).flatten();\n",
" Zbin = (Z > 0.5);\n",
" diff = Y - Z; mse = np.mean(diff*diff);\n",
" n = len(Z); n0 = np.sum(Y==0); n1 = np.sum(Y==1);\n",
" acc = np.sum(Zbin == Y) / n;\n",
" tpr = np.sum(Zbin[Y==1]) / n1;\n",
" tnr = np.sum(Zbin[Y==0] == 0) / n0;\n",
" mreal = np.median(Z[Y==1]);\n",
" high_random = np.sum(Z[Y==0] > mreal) / n0;\n",
" print(\"Accuracy: \", acc, \"TPR: \", tpr, \"TNR: \", tnr, \"MSE:\", mse);\n",
" print(\"Percentage of random pairs with score higher than median of real pairs:\", 100*high_random);"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"10\n",
"(array([ 3684, 3926, 31667, ..., 5012, 2779, 18903], dtype=uint16), array([39851, 8825, 38120, ..., 55696, 1477, 8290], dtype=uint16))\n",
"(array([ 3620, 3862, 31731, ..., 5076, 4600, 38913], dtype=uint16), array([39851, 8825, 38120, ..., 55696, 22848, 49984], dtype=uint16))\n",
"(array([35000, 26136, 62397, ..., 11565, 35287, 56114], dtype=uint16), array([41966, 48941, 11161, ..., 39817, 62295, 23702], dtype=uint16))\n",
"(array([35064, 9050, 62461, ..., 24217, 35223, 56178], dtype=uint16), array([41966, 12977, 11161, ..., 63570, 62295, 23702], dtype=uint16))\n",
"Epoch 1/200\n",
"200/200 [==============================] - 195s 956ms/step - loss: 0.0102 - acc: 0.9969 - val_loss: 0.0580 - val_acc: 0.9276 - lr: 0.0020\n",
"Epoch 2/200\n",
"200/200 [==============================] - 186s 932ms/step - loss: 0.0061 - acc: 1.0000 - val_loss: 0.0056 - val_acc: 0.9997 - lr: 0.0018\n",
"Epoch 3/200\n",
"200/200 [==============================] - 185s 926ms/step - loss: 0.0046 - acc: 1.0000 - val_loss: 0.0041 - val_acc: 0.9999 - lr: 0.0016\n",
"Epoch 4/200\n",
"200/200 [==============================] - 191s 956ms/step - loss: 0.0036 - acc: 1.0000 - val_loss: 0.0032 - val_acc: 1.0000 - lr: 0.0014\n",
"Epoch 5/200\n",
"200/200 [==============================] - 191s 956ms/step - loss: 0.0028 - acc: 1.0000 - val_loss: 0.0026 - val_acc: 0.9999 - lr: 0.0012\n",
"Epoch 6/200\n",
"200/200 [==============================] - 191s 956ms/step - loss: 0.0023 - acc: 1.0000 - val_loss: 0.0021 - val_acc: 0.9999 - lr: 9.4444e-04\n",
"Epoch 7/200\n",
"200/200 [==============================] - 195s 977ms/step - loss: 0.0020 - acc: 1.0000 - val_loss: 0.0018 - val_acc: 1.0000 - lr: 7.3333e-04\n",
"Epoch 8/200\n",
"200/200 [==============================] - 194s 970ms/step - loss: 0.0017 - acc: 1.0000 - val_loss: 0.0016 - val_acc: 1.0000 - lr: 5.2222e-04\n",
"Epoch 9/200\n",
"200/200 [==============================] - 197s 984ms/step - loss: 0.0016 - acc: 1.0000 - val_loss: 0.0015 - val_acc: 1.0000 - lr: 3.1111e-04\n",
"Epoch 10/200\n",
"200/200 [==============================] - 194s 969ms/step - loss: 0.0015 - acc: 1.0000 - val_loss: 0.0015 - val_acc: 1.0000 - lr: 1.0000e-04\n",
"Epoch 11/200\n",
"200/200 [==============================] - 198s 990ms/step - loss: 0.0011 - acc: 1.0000 - val_loss: 0.0066 - val_acc: 0.9926 - lr: 0.0020\n",
"Epoch 12/200\n",
"200/200 [==============================] - 191s 953ms/step - loss: 7.2857e-04 - acc: 1.0000 - val_loss: 0.0040 - val_acc: 0.9959 - lr: 0.0018\n",
"Epoch 13/200\n",
"200/200 [==============================] - 186s 929ms/step - loss: 0.0013 - acc: 0.9996 - val_loss: 0.6060 - val_acc: 0.3055 - lr: 0.0016\n",
"Epoch 14/200\n",
"200/200 [==============================] - 186s 930ms/step - loss: 0.0016 - acc: 1.0000 - val_loss: 0.0014 - val_acc: 1.0000 - lr: 0.0014\n",
"Epoch 15/200\n",
"200/200 [==============================] - 186s 932ms/step - loss: 0.0013 - acc: 1.0000 - val_loss: 0.0012 - val_acc: 1.0000 - lr: 0.0012\n",
"Epoch 16/200\n",
"200/200 [==============================] - 188s 942ms/step - loss: 0.0010 - acc: 1.0000 - val_loss: 9.9471e-04 - val_acc: 1.0000 - lr: 9.4444e-04\n",
"Epoch 17/200\n",
"200/200 [==============================] - 185s 926ms/step - loss: 8.9938e-04 - acc: 1.0000 - val_loss: 8.5804e-04 - val_acc: 1.0000 - lr: 7.3333e-04\n",
"Epoch 18/200\n",
"200/200 [==============================] - 186s 928ms/step - loss: 8.0073e-04 - acc: 1.0000 - val_loss: 7.7093e-04 - val_acc: 1.0000 - lr: 5.2222e-04\n",
"Epoch 19/200\n",
"200/200 [==============================] - 183s 917ms/step - loss: 7.3898e-04 - acc: 1.0000 - val_loss: 7.1769e-04 - val_acc: 1.0000 - lr: 3.1111e-04\n",
"Epoch 20/200\n",
"200/200 [==============================] - 183s 914ms/step - loss: 7.0863e-04 - acc: 1.0000 - val_loss: 7.0042e-04 - val_acc: 1.0000 - lr: 1.0000e-04\n",
"Epoch 21/200\n",
"200/200 [==============================] - 183s 915ms/step - loss: 0.0017 - acc: 0.9997 - val_loss: 0.4867 - val_acc: 0.4988 - lr: 0.0020\n",
"Epoch 22/200\n",
"200/200 [==============================] - 183s 915ms/step - loss: 0.0024 - acc: 1.0000 - val_loss: 0.0021 - val_acc: 1.0000 - lr: 0.0018\n",
"Epoch 23/200\n",
"200/200 [==============================] - 185s 928ms/step - loss: 0.0018 - acc: 1.0000 - val_loss: 0.0017 - val_acc: 1.0000 - lr: 0.0016\n",
"Epoch 24/200\n",
"200/200 [==============================] - 192s 959ms/step - loss: 0.0015 - acc: 1.0000 - val_loss: 0.0014 - val_acc: 1.0000 - lr: 0.0014\n",
"Epoch 25/200\n",
"200/200 [==============================] - 199s 995ms/step - loss: 0.0013 - acc: 1.0000 - val_loss: 0.0012 - val_acc: 1.0000 - lr: 0.0012\n",
"Epoch 26/200\n",
"200/200 [==============================] - 194s 970ms/step - loss: 0.0011 - acc: 1.0000 - val_loss: 0.0011 - val_acc: 1.0000 - lr: 9.4444e-04\n",
"Epoch 27/200\n",
"200/200 [==============================] - 205s 1s/step - loss: 0.0010 - acc: 1.0000 - val_loss: 9.6308e-04 - val_acc: 1.0000 - lr: 7.3333e-04\n",
"Epoch 28/200\n",
"200/200 [==============================] - 208s 1s/step - loss: 9.1884e-04 - acc: 1.0000 - val_loss: 8.9257e-04 - val_acc: 1.0000 - lr: 5.2222e-04\n",
"Epoch 29/200\n",
"200/200 [==============================] - 201s 1s/step - loss: 8.6458e-04 - acc: 1.0000 - val_loss: 8.4878e-04 - val_acc: 1.0000 - lr: 3.1111e-04\n",
"Epoch 30/200\n",
"200/200 [==============================] - 199s 995ms/step - loss: 8.3732e-04 - acc: 1.0000 - val_loss: 8.3205e-04 - val_acc: 1.0000 - lr: 1.0000e-04\n",
"Epoch 31/200\n",
"200/200 [==============================] - 201s 1s/step - loss: 7.0763e-04 - acc: 1.0000 - val_loss: 6.7157e-04 - val_acc: 1.0000 - lr: 0.0020\n",
"Epoch 32/200\n",
"200/200 [==============================] - 205s 1s/step - loss: 5.2469e-04 - acc: 1.0000 - val_loss: 5.7112e-04 - val_acc: 0.9999 - lr: 0.0018\n",
"Epoch 33/200\n",
"200/200 [==============================] - 212s 1s/step - loss: 4.2094e-04 - acc: 1.0000 - val_loss: 8.2335e-04 - val_acc: 0.9994 - lr: 0.0016\n",
"Epoch 34/200\n",
"200/200 [==============================] - 215s 1s/step - loss: 3.4261e-04 - acc: 1.0000 - val_loss: 3.6864e-04 - val_acc: 1.0000 - lr: 0.0014\n",
"Epoch 35/200\n",
"200/200 [==============================] - 212s 1s/step - loss: 2.7878e-04 - acc: 1.0000 - val_loss: 2.9883e-04 - val_acc: 1.0000 - lr: 0.0012\n",
"Epoch 36/200\n",
"200/200 [==============================] - 205s 1s/step - loss: 2.3748e-04 - acc: 1.0000 - val_loss: 2.3104e-04 - val_acc: 1.0000 - lr: 9.4444e-04\n",
"Epoch 37/200\n",
"200/200 [==============================] - 212s 1s/step - loss: 2.0897e-04 - acc: 1.0000 - val_loss: 1.9908e-04 - val_acc: 1.0000 - lr: 7.3333e-04\n",
"Epoch 38/200\n",
"200/200 [==============================] - 212s 1s/step - loss: 1.8941e-04 - acc: 1.0000 - val_loss: 1.8138e-04 - val_acc: 1.0000 - lr: 5.2222e-04\n",
"Epoch 39/200\n",
"200/200 [==============================] - 204s 1s/step - loss: 1.7688e-04 - acc: 1.0000 - val_loss: 1.7202e-04 - val_acc: 1.0000 - lr: 3.1111e-04\n",
"Epoch 40/200\n",
"200/200 [==============================] - 203s 1s/step - loss: 1.7060e-04 - acc: 1.0000 - val_loss: 1.6865e-04 - val_acc: 1.0000 - lr: 1.0000e-04\n",
"Epoch 41/200\n",
"200/200 [==============================] - 202s 1s/step - loss: 0.0033 - acc: 0.9993 - val_loss: 0.0725 - val_acc: 0.9209 - lr: 0.0020\n",
"Epoch 42/200\n",
"200/200 [==============================] - 201s 1s/step - loss: 0.0026 - acc: 1.0000 - val_loss: 0.0024 - val_acc: 1.0000 - lr: 0.0018\n",
"Epoch 43/200\n",
"200/200 [==============================] - 202s 1s/step - loss: 0.0022 - acc: 1.0000 - val_loss: 0.0020 - val_acc: 1.0000 - lr: 0.0016\n",
"Epoch 44/200\n",
"200/200 [==============================] - 202s 1s/step - loss: 0.0018 - acc: 1.0000 - val_loss: 0.0017 - val_acc: 1.0000 - lr: 0.0014\n",
"Epoch 45/200\n",
"200/200 [==============================] - 200s 999ms/step - loss: 0.0016 - acc: 1.0000 - val_loss: 0.0015 - val_acc: 1.0000 - lr: 0.0012\n",
"Epoch 46/200\n",
"200/200 [==============================] - 195s 975ms/step - loss: 0.0014 - acc: 1.0000 - val_loss: 0.0014 - val_acc: 1.0000 - lr: 9.4444e-04\n",
"Epoch 47/200\n",
"200/200 [==============================] - 185s 926ms/step - loss: 0.0013 - acc: 1.0000 - val_loss: 0.0012 - val_acc: 1.0000 - lr: 7.3333e-04\n",
"Epoch 48/200\n",
"200/200 [==============================] - 185s 926ms/step - loss: 0.0012 - acc: 1.0000 - val_loss: 0.0012 - val_acc: 1.0000 - lr: 5.2222e-04\n",
"Epoch 49/200\n",
"200/200 [==============================] - 201s 1s/step - loss: 0.0011 - acc: 1.0000 - val_loss: 0.0011 - val_acc: 1.0000 - lr: 3.1111e-04\n",
"Epoch 50/200\n",
"200/200 [==============================] - 186s 929ms/step - loss: 0.0011 - acc: 1.0000 - val_loss: 0.0011 - val_acc: 1.0000 - lr: 1.0000e-04\n",
"Epoch 51/200\n",
"200/200 [==============================] - 184s 922ms/step - loss: 9.7489e-04 - acc: 1.0000 - val_loss: 8.5419e-04 - val_acc: 1.0000 - lr: 0.0020\n",
"Epoch 52/200\n",
"200/200 [==============================] - 186s 931ms/step - loss: 7.4921e-04 - acc: 1.0000 - val_loss: 6.7901e-04 - val_acc: 1.0000 - lr: 0.0018\n",
"Epoch 53/200\n",
" 60/200 [========>.....................] - ETA: 2:08 - loss: 6.4255e-04 - acc: 1.0000"
]
}
],
"source": [
"#13#Training the Model\n",
"num_epochs = 200\n",
"depth = 10\n",
"trained_net, history = train_LCB_distinguisher(num_epochs, num_rounds, depth)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"ghor_Rk_0020_0_Round_8_depth_10.json\n"
]
}
],
"source": [
"#14#Create JSON File \n",
"# Convert the model architecture to JSON format\n",
"\n",
"import json\n",
"from keras.models import model_from_json\n",
"model_json = trained_net.to_json()\n",
"\n",
" # Save the model architecture as a JSON file (optional)\n",
"filename = f'ghor_Rk_0000_0040_Round_{num_rounds}_depth_10.json'\n",
"print(filename)\n",
"with open(filename, \"w\") as json_file:\n",
" json.dump(json.loads(model_json), json_file, indent=4)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"10/10 [==============================] - 3s 252ms/step\n",
"Accuracy: 0.49913 TPR: 0.5458930457834207 TNR: 0.45204599731080297 MSE: 0.2507894\n",
"Percentage of random pairs with score higher than median of real pairs: 50.19366232515202\n"
]
}
],
"source": [
"#17#Evaluate Function Call\n",
"import numpy as np\n",
"\n",
"from keras.models import model_from_json\n",
"\n",
"#load distinguishers\n",
"json_file = open('ghor_Rk_0000_0040_Round_10_depth_10.json','r');\n",
"json_model = json_file.read();\n",
"\n",
"net5 = model_from_json(json_model);\n",
"\n",
"net5.load_weights('ghor_Rk_0000_0040_Round_10_depth_10.h5');\n",
"\n",
"evaluate(net5, X_test_stacked, Y_test_stacked);\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.13"
},
"vscode": {
"interpreter": {
"hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6"
}
}
},
"nbformat": 4,
"nbformat_minor": 2
}
%% Cell type:code id: tags:
```
python
#1#Header
import
csv
import
numpy
as
np
import
os
from
os
import
urandom
from
keras.models
import
model_from_json
```
%% Cell type:code id: tags:
```
python
#2#Defining Permutation Box and Substituition Box
num_rounds
=
10
m
=
0
o
=
0
```
%% Cell type:code id: tags:
```
python
#3#WORDSIZE
def
WORD_SIZE
():
return
(
16
);
```
%% Cell type:code id: tags:
```
python
import
numpy
as
np
s_box_mapping_np
=
np
.
array
([
12
,
5
,
6
,
11
,
9
,
0
,
10
,
13
,
3
,
14
,
15
,
8
,
4
,
7
,
1
,
2
],
dtype
=
np
.
uint8
)
def
s_box
(
input_bits
):
input_bits_int
=
int
(
input_bits
)
#print(input_bits_int)
output_bits_int
=
s_box_mapping_np
[
input_bits_int
]
return
output_bits_int
```
%% Cell type:code id: tags:
```
python
import
numpy
as
np
def
decimal_to_binary_list
(
value
,
num_bits
=
4
):
return
np
.
array
([
int
(
x
)
for
x
in
format
(
value
,
f
'
0
{
num_bits
}
b
'
)],
dtype
=
np
.
uint8
)
def
p_box
(
c_decimal
,
d_decimal
):
c
=
decimal_to_binary_list
(
c_decimal
)
d
=
decimal_to_binary_list
(
d_decimal
)
e
=
np
.
zeros
(
8
,
dtype
=
np
.
uint8
)
e
[
0
]
=
c
[
0
]
e
[
1
]
=
d
[
0
]
e
[
2
]
=
c
[
3
]
e
[
3
]
=
d
[
3
]
e
[
4
]
=
c
[
1
]
e
[
5
]
=
d
[
1
]
e
[
6
]
=
c
[
2
]
e
[
7
]
=
d
[
2
]
return
e
```
%% Cell type:code id: tags:
```
python
#6#L box
def
l_box
(
f
,
g
):
if
len
(
f
)
!=
8
or
len
(
g
)
!=
8
:
raise
ValueError
(
"
Both input arrays f and g should have exactly 8 elements
"
)
h
=
np
.
zeros
(
16
,
dtype
=
np
.
uint8
)
h
[
0
]
=
f
[
0
]
h
[
1
]
=
g
[
0
]
h
[
2
]
=
f
[
7
]
h
[
3
]
=
g
[
7
]
h
[
4
]
=
f
[
1
]
h
[
5
]
=
g
[
1
]
h
[
6
]
=
f
[
6
]
h
[
7
]
=
g
[
6
]
h
[
8
]
=
f
[
2
]
h
[
9
]
=
g
[
2
]
h
[
10
]
=
f
[
5
]
h
[
11
]
=
g
[
5
]
h
[
12
]
=
f
[
3
]
h
[
13
]
=
g
[
3
]
h
[
14
]
=
f
[
4
]
h
[
15
]
=
g
[
4
]
#print(h)
return
h
```
%% Cell type:code id: tags:
```
python
#7#F function
def
binary_array_to_integer
(
output
):
int_output
=
''
.
join
(
map
(
str
,
output
))
return
int
(
int_output
,
2
)
def
f_function
(
x
,
key
,
d
):
q
=
0
global
m
if
isinstance
(
x
,
int
):
x
=
[
x
]
#print(x)
input_parts
=
np
.
zeros
((
len
(
x
),
4
),
dtype
=
np
.
uint16
)
for
i
,
val
in
enumerate
(
x
):
input_parts
[
i
]
=
np
.
array
([
val
>>
12
,
(
val
>>
8
)
&
0xF
,
(
val
>>
4
)
&
0xF
,
val
&
0xF
])
#print(input_parts[0], input_parts[1], input_parts[2], input_parts[3])
#print("input parts:", input_parts)
s_box_outputs
=
np
.
array
([[
s_box
(
element
)
for
element
in
part
]
for
part
in
input_parts
])
#print("s box:", s_box_outputs)
p_box_outputs
=
np
.
zeros
((
len
(
x
),
2
,
8
),
dtype
=
np
.
uint8
)
for
i
in
range
(
len
(
x
)):
p_box_outputs
[
i
]
=
np
.
array
([
p_box
(
s_box_outputs
[
i
][
0
],
s_box_outputs
[
i
][
1
]),
p_box
(
s_box_outputs
[
i
][
2
],
s_box_outputs
[
i
][
3
])])
#print("p_box")
#print("p box:", p_box_outputs)
final_outputs
=
np
.
zeros
(
len
(
x
),
dtype
=
np
.
uint32
)
for
i
in
range
(
len
(
x
)):
final_output
=
np
.
array
(
l_box
(
p_box_outputs
[
i
][
0
],
p_box_outputs
[
i
][
1
]))
#print("final output:", final_output)
k
=
key
[
q
][(
m
+
1
)
%
4
]
output
=
final_output
^
k
#print("k:", k)
#print("output before:", output)
output
=
binary_array_to_integer
(
output
)
#print("output after:", output)
#print("________________________________________________________")
final_outputs
[
i
]
=
output
q
+=
1
if
(
m
<
2
):
m
+=
2
else
:
m
=
0
return
final_outputs
#return output
```
%% Cell type:code id: tags:
```
python
#7#F function
def
binary_array_to_integer
(
output
):
int_output
=
''
.
join
(
map
(
str
,
output
))
return
int
(
int_output
,
2
)
def
ff_function
(
x
,
key
,
d
):
q
=
0
global
o
if
isinstance
(
x
,
int
):
x
=
[
x
]
#print(x)
input_parts
=
np
.
zeros
((
len
(
x
),
4
),
dtype
=
np
.
uint16
)
for
i
,
val
in
enumerate
(
x
):
input_parts
[
i
]
=
np
.
array
([
val
>>
12
,
(
val
>>
8
)
&
0xF
,
(
val
>>
4
)
&
0xF
,
val
&
0xF
])
#print(input_parts[0], input_parts[1], input_parts[2], input_parts[3])
#print("input parts:", input_parts)
s_box_outputs
=
np
.
array
([[
s_box
(
element
)
for
element
in
part
]
for
part
in
input_parts
])
#print("s box:", s_box_outputs)
p_box_outputs
=
np
.
zeros
((
len
(
x
),
2
,
8
),
dtype
=
np
.
uint8
)
for
i
in
range
(
len
(
x
)):
p_box_outputs
[
i
]
=
np
.
array
([
p_box
(
s_box_outputs
[
i
][
0
],
s_box_outputs
[
i
][
1
]),
p_box
(
s_box_outputs
[
i
][
2
],
s_box_outputs
[
i
][
3
])])
#print("p_box")
#print("p box:", p_box_outputs)
final_outputs
=
np
.
zeros
(
len
(
x
),
dtype
=
np
.
uint32
)
for
i
in
range
(
len
(
x
)):
final_output
=
np
.
array
(
l_box
(
p_box_outputs
[
i
][
0
],
p_box_outputs
[
i
][
1
]))
#print("final output:", final_output)
k
=
key
[
q
][
o
%
4
]
output
=
final_output
^
k
#print("k:", k)
#print("output before:", output)
output
=
binary_array_to_integer
(
output
)
#print("output after:", output)
#print("________________________________________________________")
final_outputs
[
i
]
=
output
q
+=
1
if
(
o
<
2
):
o
+=
2
else
:
o
=
0
return
final_outputs
#return output
```
%% Cell type:code id: tags:
```
python
import
numpy
as
np
def
convert_to_binary
(
row
):
bin_array
=
np
.
zeros
(
64
,
dtype
=
np
.
uint8
)
for
i
,
num
in
enumerate
(
row
):
binary_str
=
format
(
num
,
'
016b
'
)
for
j
,
b
in
enumerate
(
binary_str
):
bin_array
[
i
*
16
+
j
]
=
int
(
b
)
return
bin_array
```
%% Cell type:code id: tags:
```
python
#9#Encrypt Function
def
lcb_encrypt
(
plaintext
,
key
,
rounds
,
d
):
print
(
plaintext
)
left_plaintext
=
np
.
uint16
(
plaintext
[
0
])
right_plaintext
=
np
.
uint16
(
plaintext
[
1
])
L
,
R
=
left_plaintext
,
right_plaintext
#print(L)
#print(R)
#print(key)
n
=
0
m
=
0
q
=
0
while
n
<
rounds
:
#print("(m+1) % 4", (m+1) % 4)
#print("m % 4", m % 4)
#print(key[q])
L
,
R
=
f_function
(
R
,
key
,
d
),
ff_function
(
L
,
key
,
d
)
#print(key[q][(m+1) % 4])
#print(key[q][m % 4])
n
+=
1
return
(
L
,
R
)
```
%% Cell type:code id: tags:
```
python
``
`
%%
Cell
type
:
code
id
:
tags
:
```
python
import random
def generate_hex_keys(num_keys, length=16):
hex_chars = "0123456789ABCDEF"
keys_str = ["".join(random.choices(hex_chars, k=length)) for _ in range(num_keys)]
#print(keys_str)
return keys_str
def to_binary(value, bits):
return format(value, f'0{bits}b')
def generate_round_keys(num_keys):
random_keys_hex = generate_hex_keys(num_keys)
#random_keys_hex = ['D622529ECC92D353', '163A529ECC92D353', '967AD296CC92DB53', 'F4AB5DB7D4EBF352', '76BA569EDC93D353']
#random_keys_hex = ['163A529D687529EC', 'D622529ECC92D353']
#random_keys_hex = ['163A529D687529EC']
round_keys = []
for random_key_hex in random_keys_hex:
random_key = int(random_key_hex, 16)
K1 = (random_key >> 48) & 0xFFFF
K2 = (random_key >> 32) & 0xFFFF
K3 = (random_key >> 16) & 0xFFFF
K4 = random_key & 0xFFFF
#print("Key parts:", K1, K2, K3, K4)
k1_bin = to_binary(K1, 16)
k2_bin = to_binary(K2, 16)
k3_bin = to_binary(K3, 16)
k4_bin = to_binary(K4, 16)
k1_np_array = np.array([int(bit) for bit in k1_bin])
k2_np_array = np.array([int(bit) for bit in k2_bin])
k3_np_array = np.array([int(bit) for bit in k3_bin])
k4_np_array = np.array([int(bit) for bit in k4_bin])
round_key = np.array([k1_np_array, k2_np_array, k3_np_array, k4_np_array])
round_keys.append(round_key)
round_key = np.array(round_keys)
#print(round_key)
return round_key
```
%% Cell type:code id: tags:
```
python
#9#Make dataset
def make_train_data(n, nr, diff=(0x0040,0)):
Y = np.frombuffer(urandom(n), dtype=np.uint8);
Y = Y & 1;
plaintext = np.frombuffer(urandom(4
*
n), dtype=np.uint32);
#plaintext = [0xCED4B5C6, 0xEED4B555, 0xEFAAE23D, 0xDDAB43B, 0x6DAE4BB5]
#plaintext = [0xCED4B5C6, 0xEED4B555]
#plaintext = [0xEED4B555]
plain0l = np.empty(n, dtype=np.uint16)
plain0r = np.empty(n, dtype=np.uint16)
for i in range(n):
plain0l[i] = (plaintext[i] >> 16) & 0xffff
plain0r[i] = plaintext[i] & 0xffff
plain1l = plain0l ^ diff[0]; plain1r = plain0r ^ diff[1];
num_rand_samples = np.sum(Y==0);
plain1l[Y==0] = np.frombuffer(urandom(2
*
num_rand_samples),dtype=np.uint16);
plain1r[Y==0] = np.frombuffer(urandom(2
*
num_rand_samples),dtype=np.uint16);
#print("PLAINTEXT")
#print(plain0l)
#print(plain0r)
#print(plain1l)
#print(plain1r)
round_key = generate_round_keys(n)
#print("KEY IN BINARY")
#print(round_key)
ctdata0l, ctdata0r = lcb_encrypt((plain0l, plain0r), round_key, nr, n)
ctdata1l, ctdata1r = lcb_encrypt((plain1l, plain1r), round_key, nr, n)
#print("CIPHERTEXT")
#print("ctdata0l",ctdata0l)
#print("ctdata0r",ctdata0r)
#print("ctdata1l",ctdata1l)
#print("ctdata1r",ctdata1r)
ctdata = np.vstack((ctdata0l, ctdata0r, ctdata1l, ctdata1r)).T
X = np.array([convert_to_binary(row) for row in ctdata])
#print("CIPHERTEXT IN BINARY")
#print(X)
"""
with open("Dataset_NewP.csv", "w", newline='') as f:
writer = csv.writer(f)
writer.writerow(["plain0l", "plain0r", "plain1l", "plain1r","Y"])
for i in range(n):
writer.writerow([plain0l[i], plain0r[i], plain1l[i], plain1r[i],Y[i]])
with open("Dataset_NewC.csv", "w", newline='') as f:
writer = csv.writer(f)
writer.writerow(["ctdata0l", "ctdata0r", "ctdata1l", "ctdata1r","Y"])
for i in range(n):
writer.writerow([ctdata0l[i], ctdata0r[i], ctdata1l[i], ctdata1r[i],Y[i]])
"""
return(X,Y);
```
%% Cell type:code id: tags:
```
python
X, Y = make_train_data(100, 10)
```
%% Output
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_13352\2995501280.py in <module>
----> 1 X, Y = make_train_data(100, 10)
~\AppData\Local\Temp\ipykernel_13352\1935914450.py in make_train_data(n, nr, diff)
2
3 def make_train_data(n, nr, diff=(0x0040,0)):
----> 4 Y = np.frombuffer(urandom(n), dtype=np.uint8);
5 Y = Y & 1;
6 plaintext = np.frombuffer(urandom(4*n), dtype=np.uint32);
NameError: name 'np' is not defined
%% Cell type:code id: tags:
```
python
#10#Creating Model
from pickle import dump
from keras.callbacks import ModelCheckpoint, LearningRateScheduler
from keras.models import Model
from keras.optimizers import Adam
from keras.layers import Dense, Conv1D, Input, Reshape, Permute, Add, Flatten, BatchNormalization, Activation
from keras import backend as K
from keras.regularizers import l2
bs = 5000;
wdir = './freshly_trained_nets/'
def cyclic_lr(num_epochs, high_lr, low_lr):
res = lambda i: low_lr + ((num_epochs-1) - i % num_epochs)/(num_epochs-1)
*
(high_lr - low_lr);
return(res);
def make_checkpoint(datei):
res = ModelCheckpoint(datei, monitor='val_loss', save_best_only = True);
return(res);
#make residual tower of convolutional blocks
def make_resnet(num_blocks=2, num_filters=32, num_outputs=1, d1=64, d2=64, word_size=16, ks=3,depth=5, reg_param=0.0001, final_activation='sigmoid'):
#Input and preprocessing layers
inp = Input(shape=(num_blocks
* word_size *
2,));
rs = Reshape((2
*
num_blocks, word_size))(inp);
perm = Permute((2,1))(rs);
#add a single residual layer that will expand the data to num_filters channels
#this is a bit-sliced layer
conv0 = Conv1D(num_filters, kernel_size=1, padding='same', kernel_regularizer=l2(reg_param))(perm);
conv0 = BatchNormalization()(conv0);
conv0 = Activation('relu')(conv0);
#add residual blocks
shortcut = conv0;
for i in range(depth):
conv1 = Conv1D(num_filters, kernel_size=ks, padding='same', kernel_regularizer=l2(reg_param))(shortcut);
conv1 = BatchNormalization()(conv1);
conv1 = Activation('relu')(conv1);
conv2 = Conv1D(num_filters, kernel_size=ks, padding='same',kernel_regularizer=l2(reg_param))(conv1);
conv2 = BatchNormalization()(conv2);
conv2 = Activation('relu')(conv2);
shortcut = Add()([shortcut, conv2]);
#add prediction head
flat1 = Flatten()(shortcut);
dense1 = Dense(d1,kernel_regularizer=l2(reg_param))(flat1);
dense1 = BatchNormalization()(dense1);
dense1 = Activation('relu')(dense1);
dense2 = Dense(d2, kernel_regularizer=l2(reg_param))(dense1);
dense2 = BatchNormalization()(dense2);
dense2 = Activation('relu')(dense2);
out = Dense(num_outputs, activation=final_activation, kernel_regularizer=l2(reg_param))(dense2);
model = Model(inputs=inp, outputs=out);
return(model);
def train_LCB_distinguisher(num_epochs, num_rounds, depth):
#create the network
print(num_rounds)
net = make_resnet(depth=depth, reg_param=10
**
-5);
net.compile(optimizer='adam',loss='mse',metrics=['acc']);
#generate training and validation data
X, Y = make_train_data(10
**
6,num_rounds);
X_eval, Y_eval = make_train_data(10
**
5, num_rounds);
#set up model checkpoint
check = make_checkpoint(wdir+'ghor_Rk_0000_0040_Round_'+str(num_rounds)+'_depth_'+str(depth)+'.h5');
#create learnrate schedule
lr = LearningRateScheduler(cyclic_lr(10,0.002, 0.0001));
#train and evaluate
#print(X_eval)
h = net.fit(X,Y,epochs=num_epochs,batch_size=bs,validation_data=(X_eval, Y_eval), callbacks=[lr,check]);
np.save(wdir+'h'+str(num_rounds)+'r_depth'+str(depth)+'.npy', h.history['val_acc']);
np.save(wdir+'h'+str(num_rounds)+'r_depth'+str(depth)+'.npy', h.history['val_loss']);
dump(h.history,open(wdir+'hist'+str(num_rounds)+'r_depth'+str(depth)+'.p','wb'));
print("Best validation accuracy: ", np.max(h.history['val_acc']));
return(net, h);
```
%% Cell type:code id: tags:
```
python
#15#Evaluate Function
def evaluate(net,X,Y):
Z = net.predict(X,batch_size=10000).flatten();
Zbin = (Z > 0.5);
diff = Y - Z; mse = np.mean(diff
*
diff);
n = len(Z); n0 = np.sum(Y==0); n1 = np.sum(Y==1);
acc = np.sum(Zbin == Y) / n;
tpr = np.sum(Zbin[Y==1]) / n1;
tnr = np.sum(Zbin[Y==0] == 0) / n0;
mreal = np.median(Z[Y==1]);
high_random = np.sum(Z[Y==0] > mreal) / n0;
print("Accuracy: ", acc, "TPR: ", tpr, "TNR: ", tnr, "MSE:", mse);
print("Percentage of random pairs with score higher than median of real pairs:", 100
*
high_random);
```
%% Cell type:code id: tags:
```
python
#13#Training the Model
num_epochs = 200
depth = 10
trained_net, history = train_LCB_distinguisher(num_epochs, num_rounds, depth)
```
%% Output
10
(array([ 3684, 3926, 31667, ..., 5012, 2779, 18903], dtype=uint16), array([39851, 8825, 38120, ..., 55696, 1477, 8290], dtype=uint16))
(array([ 3620, 3862, 31731, ..., 5076, 4600, 38913], dtype=uint16), array([39851, 8825, 38120, ..., 55696, 22848, 49984], dtype=uint16))
(array([35000, 26136, 62397, ..., 11565, 35287, 56114], dtype=uint16), array([41966, 48941, 11161, ..., 39817, 62295, 23702], dtype=uint16))
(array([35064, 9050, 62461, ..., 24217, 35223, 56178], dtype=uint16), array([41966, 12977, 11161, ..., 63570, 62295, 23702], dtype=uint16))
Epoch 1/200
200/200 [==============================] - 195s 956ms/step - loss: 0.0102 - acc: 0.9969 - val_loss: 0.0580 - val_acc: 0.9276 - lr: 0.0020
Epoch 2/200
200/200 [==============================] - 186s 932ms/step - loss: 0.0061 - acc: 1.0000 - val_loss: 0.0056 - val_acc: 0.9997 - lr: 0.0018
Epoch 3/200
200/200 [==============================] - 185s 926ms/step - loss: 0.0046 - acc: 1.0000 - val_loss: 0.0041 - val_acc: 0.9999 - lr: 0.0016
Epoch 4/200
200/200 [==============================] - 191s 956ms/step - loss: 0.0036 - acc: 1.0000 - val_loss: 0.0032 - val_acc: 1.0000 - lr: 0.0014
Epoch 5/200
200/200 [==============================] - 191s 956ms/step - loss: 0.0028 - acc: 1.0000 - val_loss: 0.0026 - val_acc: 0.9999 - lr: 0.0012
Epoch 6/200
200/200 [==============================] - 191s 956ms/step - loss: 0.0023 - acc: 1.0000 - val_loss: 0.0021 - val_acc: 0.9999 - lr: 9.4444e-04
Epoch 7/200
200/200 [==============================] - 195s 977ms/step - loss: 0.0020 - acc: 1.0000 - val_loss: 0.0018 - val_acc: 1.0000 - lr: 7.3333e-04
Epoch 8/200
200/200 [==============================] - 194s 970ms/step - loss: 0.0017 - acc: 1.0000 - val_loss: 0.0016 - val_acc: 1.0000 - lr: 5.2222e-04
Epoch 9/200
200/200 [==============================] - 197s 984ms/step - loss: 0.0016 - acc: 1.0000 - val_loss: 0.0015 - val_acc: 1.0000 - lr: 3.1111e-04
Epoch 10/200
200/200 [==============================] - 194s 969ms/step - loss: 0.0015 - acc: 1.0000 - val_loss: 0.0015 - val_acc: 1.0000 - lr: 1.0000e-04
Epoch 11/200
200/200 [==============================] - 198s 990ms/step - loss: 0.0011 - acc: 1.0000 - val_loss: 0.0066 - val_acc: 0.9926 - lr: 0.0020
Epoch 12/200
200/200 [==============================] - 191s 953ms/step - loss: 7.2857e-04 - acc: 1.0000 - val_loss: 0.0040 - val_acc: 0.9959 - lr: 0.0018
Epoch 13/200
200/200 [==============================] - 186s 929ms/step - loss: 0.0013 - acc: 0.9996 - val_loss: 0.6060 - val_acc: 0.3055 - lr: 0.0016
Epoch 14/200
200/200 [==============================] - 186s 930ms/step - loss: 0.0016 - acc: 1.0000 - val_loss: 0.0014 - val_acc: 1.0000 - lr: 0.0014
Epoch 15/200
200/200 [==============================] - 186s 932ms/step - loss: 0.0013 - acc: 1.0000 - val_loss: 0.0012 - val_acc: 1.0000 - lr: 0.0012
Epoch 16/200
200/200 [==============================] - 188s 942ms/step - loss: 0.0010 - acc: 1.0000 - val_loss: 9.9471e-04 - val_acc: 1.0000 - lr: 9.4444e-04
Epoch 17/200
200/200 [==============================] - 185s 926ms/step - loss: 8.9938e-04 - acc: 1.0000 - val_loss: 8.5804e-04 - val_acc: 1.0000 - lr: 7.3333e-04
Epoch 18/200
200/200 [==============================] - 186s 928ms/step - loss: 8.0073e-04 - acc: 1.0000 - val_loss: 7.7093e-04 - val_acc: 1.0000 - lr: 5.2222e-04
Epoch 19/200
200/200 [==============================] - 183s 917ms/step - loss: 7.3898e-04 - acc: 1.0000 - val_loss: 7.1769e-04 - val_acc: 1.0000 - lr: 3.1111e-04
Epoch 20/200
200/200 [==============================] - 183s 914ms/step - loss: 7.0863e-04 - acc: 1.0000 - val_loss: 7.0042e-04 - val_acc: 1.0000 - lr: 1.0000e-04
Epoch 21/200
200/200 [==============================] - 183s 915ms/step - loss: 0.0017 - acc: 0.9997 - val_loss: 0.4867 - val_acc: 0.4988 - lr: 0.0020
Epoch 22/200
200/200 [==============================] - 183s 915ms/step - loss: 0.0024 - acc: 1.0000 - val_loss: 0.0021 - val_acc: 1.0000 - lr: 0.0018
Epoch 23/200
200/200 [==============================] - 185s 928ms/step - loss: 0.0018 - acc: 1.0000 - val_loss: 0.0017 - val_acc: 1.0000 - lr: 0.0016
Epoch 24/200
200/200 [==============================] - 192s 959ms/step - loss: 0.0015 - acc: 1.0000 - val_loss: 0.0014 - val_acc: 1.0000 - lr: 0.0014
Epoch 25/200
200/200 [==============================] - 199s 995ms/step - loss: 0.0013 - acc: 1.0000 - val_loss: 0.0012 - val_acc: 1.0000 - lr: 0.0012
Epoch 26/200
200/200 [==============================] - 194s 970ms/step - loss: 0.0011 - acc: 1.0000 - val_loss: 0.0011 - val_acc: 1.0000 - lr: 9.4444e-04
Epoch 27/200
200/200 [==============================] - 205s 1s/step - loss: 0.0010 - acc: 1.0000 - val_loss: 9.6308e-04 - val_acc: 1.0000 - lr: 7.3333e-04
Epoch 28/200
200/200 [==============================] - 208s 1s/step - loss: 9.1884e-04 - acc: 1.0000 - val_loss: 8.9257e-04 - val_acc: 1.0000 - lr: 5.2222e-04
Epoch 29/200
200/200 [==============================] - 201s 1s/step - loss: 8.6458e-04 - acc: 1.0000 - val_loss: 8.4878e-04 - val_acc: 1.0000 - lr: 3.1111e-04
Epoch 30/200
200/200 [==============================] - 199s 995ms/step - loss: 8.3732e-04 - acc: 1.0000 - val_loss: 8.3205e-04 - val_acc: 1.0000 - lr: 1.0000e-04
Epoch 31/200
200/200 [==============================] - 201s 1s/step - loss: 7.0763e-04 - acc: 1.0000 - val_loss: 6.7157e-04 - val_acc: 1.0000 - lr: 0.0020
Epoch 32/200
200/200 [==============================] - 205s 1s/step - loss: 5.2469e-04 - acc: 1.0000 - val_loss: 5.7112e-04 - val_acc: 0.9999 - lr: 0.0018
Epoch 33/200
200/200 [==============================] - 212s 1s/step - loss: 4.2094e-04 - acc: 1.0000 - val_loss: 8.2335e-04 - val_acc: 0.9994 - lr: 0.0016
Epoch 34/200
200/200 [==============================] - 215s 1s/step - loss: 3.4261e-04 - acc: 1.0000 - val_loss: 3.6864e-04 - val_acc: 1.0000 - lr: 0.0014
Epoch 35/200
200/200 [==============================] - 212s 1s/step - loss: 2.7878e-04 - acc: 1.0000 - val_loss: 2.9883e-04 - val_acc: 1.0000 - lr: 0.0012
Epoch 36/200
200/200 [==============================] - 205s 1s/step - loss: 2.3748e-04 - acc: 1.0000 - val_loss: 2.3104e-04 - val_acc: 1.0000 - lr: 9.4444e-04
Epoch 37/200
200/200 [==============================] - 212s 1s/step - loss: 2.0897e-04 - acc: 1.0000 - val_loss: 1.9908e-04 - val_acc: 1.0000 - lr: 7.3333e-04
Epoch 38/200
200/200 [==============================] - 212s 1s/step - loss: 1.8941e-04 - acc: 1.0000 - val_loss: 1.8138e-04 - val_acc: 1.0000 - lr: 5.2222e-04
Epoch 39/200
200/200 [==============================] - 204s 1s/step - loss: 1.7688e-04 - acc: 1.0000 - val_loss: 1.7202e-04 - val_acc: 1.0000 - lr: 3.1111e-04
Epoch 40/200
200/200 [==============================] - 203s 1s/step - loss: 1.7060e-04 - acc: 1.0000 - val_loss: 1.6865e-04 - val_acc: 1.0000 - lr: 1.0000e-04
Epoch 41/200
200/200 [==============================] - 202s 1s/step - loss: 0.0033 - acc: 0.9993 - val_loss: 0.0725 - val_acc: 0.9209 - lr: 0.0020
Epoch 42/200
200/200 [==============================] - 201s 1s/step - loss: 0.0026 - acc: 1.0000 - val_loss: 0.0024 - val_acc: 1.0000 - lr: 0.0018
Epoch 43/200
200/200 [==============================] - 202s 1s/step - loss: 0.0022 - acc: 1.0000 - val_loss: 0.0020 - val_acc: 1.0000 - lr: 0.0016
Epoch 44/200
200/200 [==============================] - 202s 1s/step - loss: 0.0018 - acc: 1.0000 - val_loss: 0.0017 - val_acc: 1.0000 - lr: 0.0014
Epoch 45/200
200/200 [==============================] - 200s 999ms/step - loss: 0.0016 - acc: 1.0000 - val_loss: 0.0015 - val_acc: 1.0000 - lr: 0.0012
Epoch 46/200
200/200 [==============================] - 195s 975ms/step - loss: 0.0014 - acc: 1.0000 - val_loss: 0.0014 - val_acc: 1.0000 - lr: 9.4444e-04
Epoch 47/200
200/200 [==============================] - 185s 926ms/step - loss: 0.0013 - acc: 1.0000 - val_loss: 0.0012 - val_acc: 1.0000 - lr: 7.3333e-04
Epoch 48/200
200/200 [==============================] - 185s 926ms/step - loss: 0.0012 - acc: 1.0000 - val_loss: 0.0012 - val_acc: 1.0000 - lr: 5.2222e-04
Epoch 49/200
200/200 [==============================] - 201s 1s/step - loss: 0.0011 - acc: 1.0000 - val_loss: 0.0011 - val_acc: 1.0000 - lr: 3.1111e-04
Epoch 50/200
200/200 [==============================] - 186s 929ms/step - loss: 0.0011 - acc: 1.0000 - val_loss: 0.0011 - val_acc: 1.0000 - lr: 1.0000e-04
Epoch 51/200
200/200 [==============================] - 184s 922ms/step - loss: 9.7489e-04 - acc: 1.0000 - val_loss: 8.5419e-04 - val_acc: 1.0000 - lr: 0.0020
Epoch 52/200
200/200 [==============================] - 186s 931ms/step - loss: 7.4921e-04 - acc: 1.0000 - val_loss: 6.7901e-04 - val_acc: 1.0000 - lr: 0.0018
Epoch 53/200
60/200 [========>.....................] - ETA: 2:08 - loss: 6.4255e-04 - acc: 1.0000
%% Cell type:code id: tags:
```
python
#14#Create JSON File
# Convert the model architecture to JSON format
import json
from keras.models import model_from_json
model_json = trained_net.to_json()
# Save the model architecture as a JSON file (optional)
filename = f'ghor_Rk_0000_0040_Round_{num_rounds}_depth_10.json'
print(filename)
with open(filename, "w") as json_file:
json.dump(json.loads(model_json), json_file, indent=4)
```
%% Output
ghor_Rk_0020_0_Round_8_depth_10.json
%% Cell type:code id: tags:
```
python
#17#Evaluate Function Call
import numpy as np
from keras.models import model_from_json
#load distinguishers
json_file = open('ghor_Rk_0000_0040_Round_10_depth_10.json','r');
json_model = json_file.read();
net5 = model_from_json(json_model);
net5.load_weights('ghor_Rk_0000_0040_Round_10_depth_10.h5');
evaluate(net5, X_test_stacked, Y_test_stacked);
```
%% Output
10/10 [==============================] - 3s 252ms/step
Accuracy: 0.49913 TPR: 0.5458930457834207 TNR: 0.45204599731080297 MSE: 0.2507894
Percentage of random pairs with score higher than median of real pairs: 50.19366232515202
%% Cell type:code id: tags:
```
python
```
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment