Skip to content

Instantly share code, notes, and snippets.

@M0nteCarl0
Created August 1, 2023 14:11
Show Gist options
  • Save M0nteCarl0/efc06c46c604ba28397c0e49bb86dc77 to your computer and use it in GitHub Desktop.
Save M0nteCarl0/efc06c46c604ba28397c0e49bb86dc77 to your computer and use it in GitHub Desktop.
SIMON Cipher CPA
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)
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)
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