Created
August 1, 2023 14:11
-
-
Save M0nteCarl0/efc06c46c604ba28397c0e49bb86dc77 to your computer and use it in GitHub Desktop.
SIMON Cipher CPA
This file contains 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
import cupy as cp | |
from tqdm import tnrange | |
class SimonCipher: | |
def __init__(self, waves, textins): | |
self.waves = cp.array(waves) | |
self.textins = cp.array(textins) | |
@staticmethod | |
@cp.fuse() | |
def rol32(x, n): | |
return (x << n | x >> (32 - n)) | |
@staticmethod | |
@cp.fuse() | |
def simon_round_function(x): | |
return (SimonCipher.rol32(x, 1) & SimonCipher.rol32(x, 8)) ^ SimonCipher.rol32(x, 2) | |
@staticmethod | |
@cp.fuse() | |
def simon_internal(inputdata, key): | |
return (inputdata ^ key ^ SimonCipher.simon_round_function(inputdata)) & 0xff | |
@staticmethod | |
def get_hw_array(): | |
return cp.array([bin(n).count("1") for n in range(0, 256)]) | |
def get_simon_key(self): | |
maxcpa = cp.zeros(256) | |
t_bar = cp.mean(self.waves, axis=0) | |
o_t = cp.std(self.waves, axis=0) | |
HW = self.get_hw_array() | |
for kguess in tnrange(0, 256): | |
hws = cp.array([[HW[SimonCipher.simon_internal(textin[2],kguess)] for textin in self.textins]]).transpose() | |
hws_bar = cp.mean(hws, axis=0) | |
o_hws = cp.std(hws, axis=0) | |
correlation = cp.cov(self.waves.T, hws.T)[0, 1] | |
cpaoutput = correlation / (o_t * o_hws) | |
maxcpa[kguess] = cp.abs(cpaoutput).max() | |
guess = cp.argmax(maxcpa) | |
guess_corr = maxcpa[guess].item() | |
return guess, guess_corr | |
waves = [...] # Ваши данные для waves | |
textins = [...] # Ваши данные для textins | |
cipher = SimonCipher(waves, textins) | |
guess, guess_corr = cipher.get_simon_key() | |
print("Key guess:", hex(guess)) | |
print("Correlation:", guess_corr) |
This file contains 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
import cupy as cp | |
from tqdm import tnrange | |
@cp.fuse() | |
def rol32(x, n): | |
return (x << n | x >> (32 - n)) | |
@cp.fuse() | |
def simon_round_function(x): | |
return (rol32(x, 1) & rol32(x, 8)) ^ rol32(x, 2) | |
@cp.fuse() | |
def simon_internal(inputdata, key): | |
return (inputdata ^ key ^ simon_round_function(inputdata)) & 0xff | |
HW = cp.array([bin(n).count("1") for n in range(0, 256)]) | |
def get_simon_key(project): | |
maxcpa = cp.zeros(256) | |
t_bar = cp.mean(project.waves, axis=0) | |
o_t = cp.std(project.waves, axis=0) | |
for kguess in tnrange(0, 256): | |
hws = cp.array([[HW[simon_internal(textin[2],kguess)] for textin in project.textins]]).transpose() | |
hws_bar = cp.mean(hws, axis=0) | |
o_hws = cp.std(hws, axis=0) | |
correlation = cp.cov(project.waves.T, hws.T)[0, 1] | |
cpaoutput = correlation / (o_t * o_hws) | |
maxcpa[kguess] = cp.abs(cpaoutput).max() | |
guess = cp.argmax(maxcpa) | |
guess_corr = maxcpa[guess].item() | |
return guess, guess_corr | |
guess, guess_corr = get_simon_key(project) | |
print("Key guess:", hex(guess)) | |
print("Correlation:", guess_corr) |
This file contains 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
from numba import njit, prange | |
import numpy as np | |
from tqdm import tnrange | |
@njit(parallel=True) | |
def rol32(x, n): | |
return (x << n | x >> (32 - n)) | |
@njit(parallel=True) | |
def simon_round_function(x): | |
return (rol32(x, 1) & rol32(x, 8)) ^ rol32(x, 2) | |
@njit(parallel=True) | |
def simon_internal(inputdata, key): | |
return (inputdata ^ key ^ simon_round_function(inputdata)) & 0xff | |
HW = [bin(n).count("1") for n in prange(0, 256)] | |
def get_simon_key(project): | |
maxcpa = [0] * 256 | |
t_bar = np.mean(project.waves, axis=0) | |
o_t = np.std(project.waves, axis=0) | |
for kguess in tnrange(0, 256): | |
hws = np.array([[HW[simon_internal(textin[2],kguess)] for textin in project.textins]]).transpose() | |
hws_bar = np.mean(hws, axis=0) | |
o_hws = np.std(hws, axis=0) | |
correlation = np.cov(project.waves.T, hws.T)[0, 1] | |
cpaoutput = correlation / (o_t * o_hws) | |
maxcpa[kguess] = max(abs(cpaoutput)) | |
guess = np.argmax(maxcpa) | |
guess_corr = max(maxcpa) | |
return guess, guess_corr | |
guess, guess_corr = get_simon_key(project) | |
print("Key guess:", hex(guess)) | |
print("Correlation:", guess_corr) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment