slide: https://drive.google.com/drive/folders/1odb_qi-nW0tpKfEDXpmCCox6zxVCEGMD?usp=sharing
lecture: https://drive.google.com/file/d/1cthYF5PcZYoGC0uRhlf8Ba-NbtSAvviX/view
首先來看看題目給的數據
可以看出有
我今天要取的是第一次 AddRoundKey
以及 SubBytes
的範圍
所以我們只需要橘色的部分
AddRoundKey
SubBytes
的原因我們知道第一次 AddRoundKey
的 key
就是輸入 AES
的 key
而且第一次 AddRoundKey
SubBytes
不會把不同的 bytes
混在一起
再加上 SubBytes
又是非線性的
所取的中間值
將使用的為 Hamming Weight Model
Why is the Hamming Weight model suitable?
- In software case, the intermediate value may be moved between register and memory several times
- Bus may be precharged before moving data
講師簡報
計算 Hamming Weight
來當成那點的功率消耗
共會有
所以得到 D x KEY_BYTE_SPACE
的矩陣 powerMatrix
AES/exp2.ipynb
# return Power Matrix (D * KEY_BYTE_SPACE)
def getPowerMatrix (key: bytearray, byte_index: int):
global PT
powerMatrix = []
# for i in range(D):
for pt in PT:
pt = bytearray(pt)
powerVector = []
# for k in KEY_SPACE
for k in range(K):
key[byte_index] = k
if not k in key_byte_space:
key[byte_index] = 0
intermediateState = CipherFirstAddKeyAndSubBytes(pt, key)
HW = getHammingWeight(intermediateState[byte_index])
powerVector.append(HW)
powerMatrix.append(powerVector)
return powerMatrix
接著將 powerMatrix (D x K)
與 PM (D x T)
的 column
進行計算 correlation
此步驟為比較我們猜的 key_byte
所模擬出來的功率消耗曲線與實際情況的相關性
AES/exp2.ipynb
# return correlation matrix of i th byte (K x T)
def getCorrBetweenPowerMatrixAndTraces2 (byte_index: int) -> list[list[int]]:
# PM (D x T)
global PM
PM_NP_T = np.array(PM).transpose()
# Power Matrix (D x KEY_BYTE_SPACE)
powerMatrix = getPowerMatrix(bytearray(b'0000000000000000'), byte_index)
powerMatrix_NP_T = np.array(powerMatrix).transpose()
# K * T
corrMatrix = [ ]
for k in range(K):
corrVector = []
for t in range(T):
corrVector.append(corr_calc(powerMatrix_NP_T[k], PM_NP_T[t]))
corrMatrix.append(corrVector)
assert(np.array(corrMatrix).shape == (K, T))
return np.array(corrMatrix)
接著我們只要取相關性最大的 key_byte
就會是答案
AES/exp2.ipynb
def getKeyByte2 (byte_index: int) -> int:
corrMatrix = getCorrBetweenPowerMatrixAndTraces2(byte_index)
# get max index of corrMatrix
maxIndex = np.argmax(corrMatrix)
I = maxIndex // T
J = maxIndex % T
return I
對於每個 key_byte
都作一次就有完整的 key
了
AES/exp2.ipynb
def getKey2 () -> bytearray:
key = bytearray(b'0000000000000000')
for i in range(16):
key[i] = getKeyByte2(i)
return key
# output: bytearray(b'18MbH9oEnbXHyHTR')