ãã®èšäºã§ã¯ãã¢ã«ãŽãªãºã ã®ã³ã³ããŒãã³ãã«ã€ããŠè©³ãã説æãããããéšåãå°ãæãäžããŠãPythonã§ã®å®è£ äŸã瀺ããŸãã éçºã§ã¯ãæšæºã©ã€ãã©ãªã®äžéšã®ã¿ã«éå®ããŸããã
ã¡ãã£ãšãã玹ä»
Advanced Encryption Standardã¯ã2人ã®ãã«ã®ãŒã®æå·äœæè Joan DimenãšVincent Raymanã«ãã£ãŠéçºãããRijndaelã¢ã«ãŽãªãºã ïŒ[rÉindaËl]ïŒã®æåãªååã§ãã ã¢ã«ãŽãªãºã ã¯ãããã¯ç¶ã§å¯Ÿç§°çã§ãã ç±³åœæ¿åºæ©é¢ã®ããŒã¿æå·åæšæºãšããŠæ¡çšãããŸããã æè¿é«ãè©äŸ¡ãããŠããåœå®¶å®å šä¿éå±ã¯ææžãä¿åããããã«ããã䜿çšããŠããŸãïŒSECRETã¬ãã«ãŸã§ã128ãããã®ããŒã«ããæå·åã䜿çšãããTOP SECRETæ å ±ã«ã¯192ãŸãã¯256ãããã®ããŒãå¿ èŠã§ãã é«ãæå·åŒ·åºŠã«å ããŠãã¢ã«ãŽãªãºã ã¯æãè€éãªæ°åŠã§ã¯ãããŸããã
å€ãã®æå·å
åäœãããã«ã¯ãæå·åãªããžã§ã¯ããšããŠã®ãã€ãã»ãããšã埩å·åäžã«å¿ èŠãšãªãç§å¯ããŒãå¿ èŠã§ãã é·ãããŒãé ã«å ¥ããŠããã®ã¯äžäŸ¿ã§ãããããŒã®é·ãã¯128ãããã§ãã¢ã¯ã»ã¹ã§ããªãã»ã©ååã§ãããšèããããŠããããããªãã·ã§ã³192/256ãèŠãŠããŸããã ããã«ã ããã§è¿°ã¹ãããã« ãç¹å®ã®æ¡ä»¶äžã§ã¯ãé·ãããŒã¯å®å®æ§ã«é ããããšããããŸãã
ããã€ãã®è¡šèšæ³ã玹ä»ããŸãã
- ç¶æ ã¯æå·åã®äžéçµæã§ããã4è¡ãšNbåã®é·æ¹åœ¢ã®ãã€ãé åãšããŠè¡šãããšãã§ããŸãã åç¶æ ã»ã«ã«ã¯1ãã€ãã®å€ãå«ãŸããŸã
- Nbã¯ãStateãæ§æããåïŒ32ãããã¯ãŒãïŒã®æ°ã§ãã æšæºNb = 4ã«å¯ŸããŠèŠå¶
- Nkã¯32ãããã¯ãŒãã®ããŒã®é·ãã§ãã AESã®å ŽåãNk = 4ã6ã8ãNk = 4ã䜿çšããããšãæ¢ã«æ±ºå®ããŠããŸãã
- Nr-æå·åã®ã©ãŠã³ãæ°ã ããŒã®é·ãã«å¿ããŠãNr = 10ã12ããŸãã¯14
ã¢ã«ãŽãªãºã ã«ã¯4ã€ã®å€æããããããããç¬èªã®æ¹æ³ã§Stateã®ç¶æ ã«åœ±é¿ãäžããæçµçã«çµæãå°ããŸãïŒ SubBytesïŒïŒãShiftRowsïŒïŒãMixColumnsïŒïŒ ã AddRoundKeyïŒïŒ ã äžè¬çãªæå·åã¹ããŒã ã¯æ¬¡ã®ããã«è¡šãããšãã§ããŸãã

æåã«ãStateé åã«ã¯ãåŒState [r] [c] = input [r + 4c]ãr = 0.1 ... 4;ã«åŸã£ãŠå ¥åå€ãå ¥åãããŸãã c = 0.1..Nb ã€ãŸããåã§ã 16ãã€ãã®ãããã¯ã¯äžåºŠã«æå·åãããŸãã

ã¢ã«ãŽãªãºã ã¯ãã€ãã§åäœããããããæéäœãŸãã¯ã¬ãã¢äœGFïŒ2 8 ïŒã®èŠçŽ ãšèŠãªããŸãã æ¬åŒ§å ã®æ°åã¯ããã£ãŒã«ãèŠçŽ ã®æ°ãŸãã¯ãã®åã§ãã äœGFïŒ2 8 ïŒã®èŠçŽ ã¯æ倧7ã®æ¬¡æ°ã®å€é åŒã§ãããä¿æ°ã®è¡ã§æå®ã§ããŸãã ãã€ãã¯ãå€é åŒãšããŠéåžžã«ç°¡åã«è¡šçŸã§ããŸãã ããšãã°ããã€ã{1,1,1,0,0,0,1,1,1}ã¯ããã£ãŒã«ãèŠçŽ 1x 7 + 1x 6 + 1x 5 + 0x 4 + 0x 3 + 0x 2 + 1x 1 + 1x 0 = 1x 7 +ã«å¯Ÿå¿ããŸãã 1x 6 + 1x 5 + x +1ã ãã£ãŒã«ãèŠçŽ ãæäœãããšããäºå®ã¯ãå ç®ããã³ä¹ç®æŒç®ã®ã«ãŒã«ãå€æŽãããããéåžžã«éèŠã§ãã ããã«ã€ããŠã¯å°ãåŸã§è§ŠããŸãã
次ã«ãåå€æã«ã€ããŠè©³çŽ°ã«æ€èšããŸãã
SybButesïŒïŒ
å€æã¯ãStateã®åãã€ããSboxå®æ°ããŒãã«ã®å¯Ÿå¿ãããã€ãã«çœ®ãæããããšã§ãã SboxèŠçŽ ã®å€ã¯16é²è¡šèšã§è¡šãããŸãã ããŒãã«èªäœã¯ãæ¢ç¥ã®ãã£ãŒã«ãGFïŒ2 8 ïŒãå€æããããšã«ãã£ãŠååŸãããŸãã

Stateã®åãã€ãã¯ã16é²è¡šèšã§{xy}ãšããŠè¡šãããšãã§ããŸãã 次ã«ãè¡xãšåyã®äº€ç¹ã«ããèŠçŽ ã«çœ®ãæããŸãã ããšãã°ã{6e}ã¯{9f}ã«ã{15}ã¯{59}ã«çœ®ãæããããŸãã
ShiftRowsïŒïŒ
ç°¡åãªå€æã æåã®è¡ã«1èŠçŽ ã2çªç®ã«2ã3çªç®ã«3ã®åŸªç°å·Šã·ãããå®è¡ããŸãã ãŒãã©ã€ã³ã¯ã·ãããããŸããã

MixColumnsïŒïŒ
ãã®å€æã®äžéšãšããŠãStateã®ååã¯å€é åŒãšããŠè¡šããããã£ãŒã«ãGFïŒ2 8 ïŒã§x 4 + 1ãæ³ãšããåºå®å€é åŒ3x 3 + x 2 + x + 2ã§ä¹ç®ãããŸãã ã æšæºã®å ¬åŒããã¥ã¡ã³ãã§æäŸãããŠããåçã®ãããªãã¯ã¹ãšã³ããªãèŠããšãå³ã¯ããåçŽã«ãªããŸãã

è¡åãä¹ç®ããå Žåãa ijã®å€ã¯ãæåã®è¡åã®içªç®ã®è¡ãš2çªç®ã®è¡åã®jçªç®ã®åã®å¯Ÿå¿ããèŠçŽ ã®ç©ã®åèšãšããŠååŸãããŸãã

ããã§ãå ç®ãšä¹ç®ã®éåžžã®ã«ãŒã«ã®åäœäžèœãæãåºãå¿ èŠããããŸãã
æ°ããã«ãŒã«ïŒ
- ãã£ãŒã«ãGFïŒ2 8 ïŒã§ã®å ç®ã¯ãæŒç®XORãšåçã§ãã
- {01}ã«ããä¹ç®ã¯ãä¹ç®ãå€æŽããŸãã
- {02}ã«ããä¹ç®ã¯ã«ãŒã«ã«åŸã£ãŠå®è¡ãããŸããä¹ç®ãããå€ã{80}ããå°ããå Žåãå·Šã«1ãããã·ãããããŸãã ä¹ç®å€ã{80}以äžã®å Žåãæåã«å·Šã«1ãããã·ããããã次ã«å€{1b}ã®XORæŒç®ãã·ããã®çµæã«é©çšãããŸãã çµæã¯ãå€{ff}ãã¹ãããã§ããŸããã€ãŸãã1ãã€ãã®å¢çãè¶ ããŠããŸãã ãã®å Žåãçµæã{100}ã§å²ã£ãäœããè¿ãå¿ èŠããããŸãã
- ä»ã®å®æ°ã«ããä¹ç®ã¯ãåã®
åœç¶ããããã¯æçµãã£ãŒã«ãã®ç®è¡ã®äžè¬çãªèŠåã§ã¯ãããŸããããã¢ã«ãŽãªãºã ã®äžéšãšããŠãæå·åã®ããã«3ã€ã®å®æ°ãšåŸ©å·åã®ããã«4ã€ã®å®æ°ãæããå¿ èŠãããããããã®ãããªããŒã«ã«ã©ã€ãããã¯ã§ååã§ãã
MixColumnsïŒïŒãšShiftRowsïŒïŒã¯ãæå·ã«æ¡æ£ãè¿œå ããŸãã
AddRoundKeyïŒïŒ
å€æã«ãããStateã®åèŠçŽ ãšRoundKeyã®å¯Ÿå¿ããèŠçŽ ã®ãããåäœã®XORãçæãããŸãã RoundKeyã¯Stateãšåããµã€ãºã®é åã§ãããKeyExpansionïŒïŒé¢æ°ã䜿çšããŠç§å¯éµã«åºã¥ããŠã©ãŠã³ãããšã«æ§ç¯ãããŸããããã«ã€ããŠã¯åŸã§æ€èšããŸãã
KeyExpansionïŒïŒ
ãã®è£å©å€æã¯ãã©ãŠã³ãããŒã®ã»ãã-KeyScheduleã圢æããŸãã KeyScheduleã¯ãNb *ïŒNr + 1ïŒåãŸãã¯ïŒNr + 1ïŒãããã¯ã§æ§æãããé·ãããŒãã«ã§ãããããã®ãµã€ãºã¯Stateãšåãã§ãã æåã®ã©ãŠã³ãããŒã¯ãèšç®ããç§å¯éµã«åºã¥ããŠèšå ¥ãããŸãã
KeySchedule [r] [c] = SecretKey [r + 4c]ãr = 0.1 ... 4; c = 0,1..Nkã
KeyScheduleã§ã¯ããããªãæäœãå¯èœã«ãªãããã«ãã€ããå ¥åããå¿ èŠãããããšã¯æããã§ãã ãã®ã¢ã«ãŽãªãºã ãããŒã æå·åã«äœ¿çšããå Žåãæ°åã®ã·ãŒã±ã³ã¹ãé ã«ä¿åããããšã¯ãŸã£ãã䟿å©ã§ã¯ãªããããå®è£ ã§ã¯KeyExpansionïŒïŒã¯ãã¬ãŒã³ããã¹ãå ¥åãååŸããåæåã«
ord()
ã䜿çšããŠãçµæãKeyScheduleã»ã«ã«æžã蟌ã¿ãŸãã ããã¯å¶éãæå³ããŸãïŒé·ãã16æå以äžã§ããããã€ãã
ord()
æåã®
ord()
ãã€ããªã§255ãŸãã¯11111111ãè¶ ããå€ãè¿ãã¹ãã§ã¯ãããŸãããããã§ãªãå Žåãåºåã§äžæ£ãªæå·åãåãåããŸãã ãã·ã¢èªã®ããŒã䜿çšãããšãæå·åãæ©èœããªãããšãå€æããŸããã

å³ã¯ãAES-128ã®KeyScheduleã¬ã€ã¢ãŠãã瀺ããŠããŸãã4åã®11ãããã¯ã ã¢ã«ãŽãªãºã ã®ä»ã®ããªãšãŒã·ã§ã³ã§ã¯ãNbåã®ïŒNr + 1ïŒãããã¯ããããããããŸãã 次ã«ã空ã®ã¹ããŒã¹ãåããå¿ èŠããããŸãã å€æã®ããã«ãå®æ°ããŒãã«ãåã³å®çŸ©ãããŸã-Rcon-å€ã¯16é²æ°ã·ã¹ãã ã§ãã

KeyScheduleè£å ã¢ã«ãŽãªãºã ïŒ
- åå埩ã§ãããŒãã«åãæäœããŸãã å0ã..ãïŒNk-1ïŒã«ã¯ããã§ã«ç§å¯ã®åèªã®å€ãäºåã«å ¥åãããŠããŸãã åçªå·Nkããå§ããŸãïŒãã®å Žåã4çªç®ããïŒ
- åçªå·W iã Nkã®åæ°ã§ããå ŽåïŒãã®å Žåã4çªç®ããšïŒãåW i-1ãååŸãã1èŠçŽ ã ã埪ç°å·Šã·ãããå®è¡ãããã¹ãŠã®åãã€ããSubBytesïŒïŒã®ããã«SboxããŒãã«ã®å¯Ÿå¿ãããã®ã«çœ®ãæããŸãã 次ã«ãW i-1åãä¿®æ£ããW i- NkåãšRcon i / Nk-1åãXORæŒç®ããŸãã çµæã¯W iåã«æžã蟌ãŸããŸãã ããããããããããã«ãi = 4ã®å³ã瀺ããŸãã
- æ®ãã®åã§ã¯ãW i-NkãšW i-1ã®éã§XORãå®è¡ããŸãã çµæã¯W iã§æžã蟌ãŸããŸã
ãã®è£å©çãªå€æã¯ãã¢ã«ãŽãªãºã ã§ã¯MixColumnsïŒïŒã§æ°åŠãèªèãããåŸãæžé¢ã§æãããªã¥ãŒã ããããããããæãè€éã§ãã æå·åããŒã¯ã4 * Nkåã®èŠçŽ ã§æ§æããå¿ èŠããããŸãïŒãã®äŸã§ã¯16ïŒã ããããç§ãã¡ã¯ããããã¹ãŠå®¶åºã§äœ¿çšããããã«è¡ã£ãŠããã®ã§ã誰ãã16æåã®ããŒãæãã€ããŠãããèŠããŠãããšã¯éããŸããã ãããã£ãŠãé·ãã16æªæºã®è¡ãå ¥åã«å°çãããšãKeyScheduleã®Iã¯å€{01}ãæšæºã«è¿œå ããŸãã
KeyExpansionïŒïŒã³ãŒã
def key_expansion(key): key_symbols = [ord(symbol) for symbol in key] # ChipherKey shoul contain 16 symbols to fill 4*Nk table. If it's less # complement the key with "0x01" if len(key_symbols) < 4*nk: for i in range(4*nk - len(key_symbols)): key_symbols.append(0x01) # make ChipherKey(which is base of KeySchedule) key_schedule = [[] for i in range(4)] for r in range(4): for c in range(nk): key_schedule[r].append(key_symbols[r + 4*c]) # Comtinue to fill KeySchedule for col in range(nk, nb*(nr + 1)): # col - column number if col % nk == 0: # take shifted (col - 1)th column... tmp = [key_schedule[row][col-1] for row in range(1, 4)] tmp.append(key_schedule[0][col-1]) # change its elements using Sbox-table like in SubBytes... for j in range(len(tmp)): sbox_row = tmp[j] // 0x10 sbox_col = tmp[j] % 0x10 sbox_elem = sbox[16*sbox_row + sbox_col] tmp[j] = sbox_elem # and finally make XOR of 3 columns for row in range(4): s = key_schedule[row][col - 4]^tmp[row]^rcon[row][col/nk - 1] key_schedule[row].append(s) else: # just make XOR of 2 columns for row in range(4): s = key_schedule[row][col - 4]^key_schedule[row][col - 1] key_schedule[row].append(s) return key_schedule
åè¿°ã®ããã«ãKeyScheduleã¯AddRoundKeyïŒïŒã®å€æã«äœ¿çšãããŸãã åæåã©ãŠã³ãã§ã¯ãã©ãŠã³ãããŒã¯æåã«0ã..ã3ã®æ°åã®åã4ã..ã7ãªã©ã®æ°åã«ãªããŸãã AddRoundKeyïŒïŒã®å šäœçãªãã€ã³ãã¯ãXORç¶æ ãšã©ãŠã³ãããŒãçæããããšã§ãã
å®éãããã¯ãã¹ãŠæå·åããã»ã¹ã«é¢ãããã®ã§ãã æå·åããããã€ãã®åºåé åã¯ãåŒoutput [r + 4c] = State [r] [c]ãr = 0.1 ... 4;ã«åŸã£ãŠStateããã³ã³ãã€ã«ãããŸãã c = 0.1..Nb ãã®éãèšäºã¯é ããŠãããããããã§ããã«åŸ©å·åæé ã«ã€ããŠèª¬æããŸãã
ããã«è§£èªã«ã€ããŠ
ããã§ã®èãæ¹ã¯åçŽã§ããåãããŒã¯ãŒãã䜿çšããŠæå·åå€æãšéã®å€æã·ãŒã±ã³ã¹ãå®è¡ãããšãå ã®ã¡ãã»ãŒãžãååŸãããŸãã ãã®ãããªéå€æã¯ã InvSubBytesïŒïŒãInvShiftRowsïŒïŒãInvMixColumnsïŒïŒãããã³AddRoundKeyïŒïŒã§ãã 埩å·åã¢ã«ãŽãªãºã ã®äžè¬çãªã¹ããŒã ïŒ

ã©ãŠã³ãããŒãAddRoundKeyïŒïŒã«è¿œå ããé åºã¯ãNr + 1ãã0ã®éé ã§ããããšã«æ³šæããŠãã ãããæåã¯ãæå·åãšåæ§ã«ãç¶æ ããŒãã«ã¯å ¥åãã€ãã®é åãã圢æãããŸãã ãã®åŸãåã©ãŠã³ãã§å€æãå®è¡ããããã®æåŸã«åŸ©å·åããããã¡ã€ã«ãååŸããå¿ èŠããããŸãã å€æã®é åºãå°ãå€æŽãããŸããã æåã®InvSubBytesïŒïŒãŸãã¯InvShiftRowsïŒïŒã¯éèŠã§ã¯ãããŸããã1ã€ã¯ãã€ãå€ã§åäœãã2ã€ç®ã¯ãããã®å€ãå€æŽããã«ãã€ããåé 眮ããŸãããæšæºã®æ¬äŒŒã³ãŒãã§ã®å€æã·ãŒã±ã³ã¹ã«åŸããŸããã
InvSubBytesïŒïŒ
SubBytesïŒïŒãšãŸã£ããåãããã«æ©èœããŸããã眮ãæãã¯InvSboxå®æ°ããŒãã«ããè¡ãããŸãã

æ®ãã®éå€æããçŽæ¥å¯Ÿå¿ãããã®ãšéåžžã«ãã䌌ãŠãããããã³ãŒãã§ã¯ãããã«åå¥ã®é¢æ°ãéžæããŠããŸããã å€æãèšè¿°ããåé¢æ°ã«ã¯
inv
å€æ°ããããŸãã
False
å Žåãé¢æ°ã¯éåžžã¢ãŒããŸãã¯çŽæ¥ã¢ãŒãïŒæå·åïŒã§åäœãã
True
å Žå-éã¢ãŒãïŒåŸ©å·åïŒã§åäœããŸãã
ã³ãŒã
def sub_bytes(state, inv=False): if inv == False: # encrypt box = sbox else: # decrypt box = inv_sbox for i in range(len(state)): for j in range(len(state[i])): row = state[i][j] // 0x10 col = state[i][j] % 0x10 # Our Sbox is a flat array, not a bable. So, we use this trich to find elem: box_elem = box[16*row + col] state[i][j] = box_elem return state
InvShiftRowsïŒïŒ
å€æã¯ãç¶æ ã®æåã®è¡ã«1èŠçŽ ã2çªç®ã«2èŠçŽ ã3çªç®ã«3èŠçŽ ãã€å³ã«åŸªç°ããŸãã ãŒãç·ã¯å転ããŸããã

ã³ãŒãã®èª¬æïŒ
left_shift/right_shift(array, count)
å ¥å
array
ã察å¿ããæ¹åã«
count
åå転ãããŸã
ã³ãŒã
def shift_rows(state, inv=False): count = 1 if inv == False: # encrypting for i in range(1, nb): state[i] = left_shift(state[i], count) count += 1 else: # decryption for i in range(1, nb): state[i] = right_shift(state[i], count) count += 1 return state
InvMixColumnsïŒïŒ
æäœã¯åãã§ãããåStateåã«ã¯ç°ãªãå€é åŒ{0b} x 3 + {0d} x 2 + {09} x + {0e}ãä¹ç®ãããŸãã ãããªãã¯ã¹åœ¢åŒã§ã¯ã次ã®ããã«ãªããŸãã

ãŸãã¯æ¢è£œã®æ°åŒã ãã¡ããããã¹ãŠã®å€ã¯16é²è¡šèšã§ãã

ããã§ã¯ãæ°åŠã«åãã£ãŠè±ç·ãã{02}ãã倧ããå®æ°ã§ä¹ç®ããé¢æ°ãååŸããæ¹æ³ã説æããå¿ èŠããããŸãã ç§ãèšã£ãããã«ããããã¯{01}ãš{02}ãä»ããŠããããå解ããããšã«ãã£ãŠåŸãããŸããããªãã¡ïŒ
ã³ã³ããŒãžã§ã³æ°
n * {03} = n *ïŒ{02} + {01}ïŒ= n * {02} + n * {01}
n * {09} = n *ïŒ{08} + {01}ïŒ= n * {02} * {02} * {02} + n * {01}
n * {0b} = n *ïŒ{08} + {02} + {01}ïŒ= b * {02} * {02} * {02} + n * {02} + n * {01}
n * {0d} = n *ïŒ{08} + {04} + {01}ïŒ= n * {08} + n * {04} + n * {01} = n * {02} * {02} * {02} + n * {02} * {02} + n * {01}
n * {0} = n *ïŒ{08} + {04} + {02} = n * {08} + n * {04} + n * {02} = n * {02} * {02} * { 02} + n * {02} * {02} + b * {02}
n * {09} = n *ïŒ{08} + {01}ïŒ= n * {02} * {02} * {02} + n * {01}
n * {0b} = n *ïŒ{08} + {02} + {01}ïŒ= b * {02} * {02} * {02} + n * {02} + n * {01}
n * {0d} = n *ïŒ{08} + {04} + {01}ïŒ= n * {08} + n * {04} + n * {01} = n * {02} * {02} * {02} + n * {02} * {02} + n * {01}
n * {0} = n *ïŒ{08} + {04} + {02} = n * {08} + n * {04} + n * {02} = n * {02} * {02} * { 02} + n * {02} * {02} + b * {02}
ãã¡ãããå¥ã®æ¹æ³ã§æ°åãå解ããããšãã§ããŸãããå解ãå人çã«æ€èšŒãããŸã
n * {09} = n * {03} + n * {03} + n * {03}
察å¿ããé¢æ°ãåŒã³åºããšãééã£ãçµæãåŸãããŸãïŒçµæãå«ãåç §ããŒãã«ã¯ããœãŒã¹ãªã¹ãã®ãªã³ã¯ã®1ã€ã«ãããŸãïŒã 圌ã¯ã代æ¿ã®ïŒã³ã¡ã³ãä»ãïŒããŒãžã§ã³ã®èšç®ãç¹å¥ã«æ®ããŸãããããã¯ãããããããç解ããããããšã¬ã¬ã³ãã§ããããäœããã®çç±ã§æ£ããåäœããªãããã§ãã
è£å©ä¹ç®é¢æ°
def mul_by_02(num): if num < 0x80: res = (num << 1) else: res = (num << 1)^0x1b return res % 0x100 def mul_by_03(num): return mul_by_02(num)^num def mul_by_09(num): #return mul_by_03(num)^mul_by_03(num)^mul_by_03(num) - works wrong, I don't know why return mul_by_02(mul_by_02(mul_by_02(num)))^num def mul_by_0b(num): #return mul_by_09(num)^mul_by_02(num) return mul_by_02(mul_by_02(mul_by_02(num)))^mul_by_02(num)^num def mul_by_0d(num): #return mul_by_0b(num)^mul_by_02(num) return mul_by_02(mul_by_02(mul_by_02(num)))^mul_by_02(mul_by_02(num))^num def mul_by_0e(num): #return mul_by_0d(num)^num return mul_by_02(mul_by_02(mul_by_02(num)))^mul_by_02(mul_by_02(num))^mul_by_02(num)
ã³ãŒãã®èª¬æïŒ MixColumnsïŒïŒã«é¢ããã»ã¯ã·ã§ã³ã§èª¬æããèŠåã«åŸã£ãŠãé¢æ°
mul_by_<>
ã«GFïŒ2 8 ïŒã®å¯Ÿå¿ããå®æ°ãä¹ç®ããŸãã
ã³ãŒã
def mix_columns(state, inv=False): for i in range(nb): if inv == False: # encryption s0 = mul_by_02(state[0][i])^mul_by_03(state[1][i])^state[2][i]^state[3][i] s1 = state[0][i]^mul_by_02(state[1][i])^mul_by_03(state[2][i])^state[3][i] s2 = state[0][i]^state[1][i]^mul_by_02(state[2][i])^mul_by_03(state[3][i]) s3 = mul_by_03(state[0][i])^state[1][i]^state[2][i]^mul_by_02(state[3][i]) else: # decryption s0 = mul_by_0e(state[0][i])^mul_by_0b(state[1][i])^mul_by_0d(state[2][i])^mul_by_09(state[3][i]) s1 = mul_by_09(state[0][i])^mul_by_0e(state[1][i])^mul_by_0b(state[2][i])^mul_by_0d(state[3][i]) s2 = mul_by_0d(state[0][i])^mul_by_09(state[1][i])^mul_by_0e(state[2][i])^mul_by_0b(state[3][i]) s3 = mul_by_0b(state[0][i])^mul_by_0d(state[1][i])^mul_by_09(state[2][i])^mul_by_0e(state[3][i]) state[0][i] = s0 state[1][i] = s1 state[2][i] = s2 state[3][i] = s3 return state
AddRoundKeyïŒïŒ
XORæŒç®ã®ããããã£ã«ããããã®å€æã¯ããèªäœã«åæ¯äŸããŸãã
ïŒa XOR bïŒXOR b = a
ãããã£ãŠããããå€æŽããå¿ èŠã¯ãããŸããã ã©ãŠã³ãããŒã®ã»ããã¯ãKeyExpansionïŒïŒé¢æ°ã䜿çšããæå·åãšåãæ¹æ³ã§åœ¢æãããŸãããã©ãŠã³ãããŒã¯éã®é åºã§çœ®ãæããå¿ èŠããããŸãã
ã³ãŒã
def add_round_key(state, key_schedule, round=0): for col in range(nk): # nb*round is a shift which indicates start of a part of the KeySchedule s0 = state[0][col]^key_schedule[0][nb*round + col] s1 = state[1][col]^key_schedule[1][nb*round + col] s2 = state[2][col]^key_schedule[2][nb*round + col] s3 = state[3][col]^key_schedule[3][nb*round + col] state[0][col] = s0 state[1][col] = s1 state[2][col] = s2 state[3][col] = s3 return state
ããã§ãæžãããã®å æ¬çãªå€æé¢æ°ã®ã»ãããã§ããŸããã
æå·åæ©èœ
def encrypt(input_bytes, key): # let's prepare our input data: State array and KeySchedule state = [[] for j in range(4)] for r in range(4): for c in range(nb): state[r].append(input_bytes[r + 4*c]) key_schedule = key_expansion(key) state = add_round_key(state, key_schedule) for rnd in range(1, nr): state = sub_bytes(state) state = shift_rows(state) state = mix_columns(state) state = add_round_key(state, key_schedule, rnd) state = sub_bytes(state) state = shift_rows(state) state = add_round_key(state, key_schedule, rnd + 1) output = [None for i in range(4*nb)] for r in range(4): for c in range(nb): output[r + 4*c] = state[r][c] return output
埩å·åæ©èœ
def decrypt(cipher, key): # let's prepare our algorithm enter data: State array and KeySchedule state = [[] for i in range(nb)] for r in range(4): for c in range(nb): state[r].append(cipher[r + 4*c]) key_schedule = key_expansion(key) state = add_round_key(state, key_schedule, nr) rnd = nr - 1 while rnd >= 1: state = shift_rows(state, inv=True) state = sub_bytes(state, inv=True) state = add_round_key(state, key_schedule, rnd) state = mix_columns(state, inv=True) rnd -= 1 state = shift_rows(state, inv=True) state = sub_bytes(state, inv=True) state = add_round_key(state, key_schedule, rnd) output = [None for i in range(4*nb)] for r in range(4): for c in range(nb): output[r + 4*c] = state[r][c] return output
ãããã®2ã€ã®é¢æ°ã¯ãæå·åãŸãã¯æå·åãããŠããªããã€ãã®ãªã¹ããšãã·ãŒã¯ã¬ããããŒã¯ãŒããå«ããã¬ãŒã³ããã¹ãæååãåãåããŸãã
çµè«ãèå³æ·±ããªã³ã¯
èšäºã¯ããªãé·ãããšãå€æããŸããã ç§ã¯åçã§ããã¹ããåžéããããšããŸããããããã¯ããªãã«ãšã£ãŠèå³æ·±ããã®ã§ããã誰ãéå±ããªãã£ããšæããŸãã ãã®èšäºã«èšèŒãããŠããã³ãŒãã¯å®å šãªãã®ã§ã¯ãããŸããã å®æ°ããŒãã«ã®ã°ããŒãã«å®£èšãMixColumnsïŒïŒã®å°ããªé¢æ°ã¯æ¿å ¥ããŸããã§ãããããããã¯ã©ããã«ãããšèª¬æããèšèã§ã®ã¿æ¿å ¥ããŸããã ç§ãPRã§ãããšã¯èããªãã§ãã ãããããããå®å šã«çµåãããã³ãŒãã¯ãªããžããªã§ååŸã§ããŸã ã ãŸãããã¡ã€ã«ãžã®ãã¹ãæå®ããç§å¯éµãå ¥åãããœãŒã¹ãšåããã£ã¬ã¯ããªã«ããæå·åããããã¡ã€ã«ãååŸããããšãã§ããæ§ãããªCLIã€ã³ã¿ãŒãã§ã€ã¹ããããŸãïŒåŸ©å·åããããã¡ã€ã«ã¯åãæ¹æ³ã§ååŸã§ããŸãïŒã å¥åº·ã«æå·åããŠãã ããïŒ
ãããŠæåŸã«ã1ã€ã®éèŠãªãã¥ã¢ã³ã¹ã«ã€ããŠè©±ãå¿ èŠããããŸã-ããã£ã³ã°ãŸãã¯ãããã¯ãžã®è¿œå ã AESã¯ãããã¯æå·åã¢ã«ãŽãªãºã ã§ããã
encrypt()/decrypt()
é¢æ°ã¯å ¥åãã€ãã®æ£ç¢ºã«1ãããã¯ã䜿çšããŸãïŒ128ãããããŒã䜿çšããããŒãžã§ã³ã®å Žåãããã¯16ãã€ãã§ãïŒã ãã¡ã€ã«ã®æåŸã«ã¯ã1ã€ã®ãããã¯ã圢æããªã1ã15ãã€ããæ®ã£ãŠããŸãã æå·åããã«åçŽã«å®å ãã¡ã€ã«ã«éä¿¡ã§ããŸãããå Žåã«ãã£ãŠã¯ããã¡ã€ã«ã®æåŸã«éèŠãªãã®ãå«ãŸããŠããå¯èœæ§ãããããã®ãªãã·ã§ã³ã¯é©åã§ã¯ãããŸããã 2çªç®ã®ãªãã·ã§ã³ã¯ããããã¯æå·ã«é¢ãããŠã£ãããã£ã¢ã®èšäºã§ææ¡ãããŸããã
åä¿¡è ã¯ãã€ããŒãã®çµãããèŠã€ããããšãã§ããªãããããŒãããããåçŽã«è¿œå ããŠãåé¡ã¯è§£æ±ºããŸããã ããã«ããã®ãªãã·ã§ã³ã¯ãOracleã¢ããªã³ã«ããæ»æã«ã€ãªãããŸãã ãããã£ãŠãå®éã«ã¯ãISO / IEC 9797-1ã§ãè¿œå æ¹æ³2ããšããŠæšæºåããããœãªã¥ãŒã·ã§ã³ãé©çšå¯èœã§ãã¡ãã»ãŒãžã®æåŸã«1ããããè¿œå ããæ®ãã®ã¹ããŒã¹ããŒãã§åããŸãã ãã®å Žåããã®ãããªæ»æã«å¯Ÿããæµææ§ã蚌æãããŸããã
ããã§ç§ã¯ããŸããïŒæåã®ãªãã·ã§ã³ã¯æ®ã£ãŠããŸããããã³ã¡ã³ãã¢ãŠãããŸãããçªç¶ã䟿å©ã«ãªããŸããïŒã
ãœãŒã¹éžæïŒ
- å ¬åŒææž
- ã¢ã«ãŽãªãºã ã®æå·åéšåã®éåžžã«æ確ãªèŠèŠç解é ã èè ãç§ã蚎ããªãããã«ãç§ã¯ããããã¹ã¯ãªãŒã³ã·ã§ãããæ°ææ®ããŸããã
- ãŠã£ãããã£ã¢ãªãã§ã¯ã©ãã«ããããŸãã
- MixColumnsïŒïŒã«é¢ããå¥ã®èšäº ã 0ã255ã®æ°åã®ãªã¹ãã«GFãã£ãŒã«ãã®æå·ã§äœ¿çšãããå®æ°ïŒ2 8 ïŒãä¹ç®ããçµæã®ããŒãã«ãå«ãŸããŠããŸãã
- AESã®æŽå²ãšã¢ã«ãŽãªãºã èªäœã«ã€ããŠã®é¢çœãæŒ«ç» ã ãã§ã«èšäºãæžããŠãããšãã«åããŠèŠã€ããã®ã¯æ®å¿µã§ãã