M6R0 I%randR6#%"rG6%%"aG%"pG%"sG6#%aoCopyright~(c)~1991~by~the~University~of~Waterlo o.~All~rights~reserved.G6"C'>8%"-*)**********>8$"-"3p'>uU>8&".++++++"@$4-%)assi gnedG6#%&_seedG>F<"""@%/9#""!>F<-%%iremG6$*&F2F>FF/-%%subsG6$<&/%)_MODULUSGF //%,_MULTIPLIERGF2/%'_SHIFTGF5-%/rand/generatorG6$9$F/R6"6#%"tGFWFWC&>F<-FE6$*& FOF>FFM>8$FF>%)_CONCATSG%%trueGC$>FFjn,&*&FQF>FjnF>F>F,&-FE6$ Fjn%)_DIVISORGF>%(_OFFSETGF>FWF;FWF,F;F,%*protectedG, I+InvByteSubRFWFWFWFW>%&StateG-%$mapG6$%(InvSBoxGF\pFW6#F\pFWFW, I/I_RijndaelCBC0R6$%-CipherOutputG%*CipherKeyG6%%/NumberOfBlocksG%,CipherInputG %"iGFWFWC&>Fjn-%%nopsG6#9$>&8%6#F>-%%copyG6#-%+I_RijndaelG6$&F`qFdq9%?(8&""#F>F jnF]oC$-Fiq6$&F`q6#F^rF\r>&FcqFdr-%*AddStatesG6$F\p&F`q6#,&F^rF>!""F>-%$catG6#- %"$G6$.-%,StateToTextG6#Ffr/.F^r;F>FjnFWFapFWFW, I-InvMixColumnR6#%)RoundKeyG6'%+I_RoundKeyG%"jGF'%"bGFjpFWFWC%>Fjn-%&arrayG6$;F B,&%#NbGF>F]sF>;FB""$?(FcqFBF>FitF]oC&>F^r-&%'linalgG6#%$rowG6$-%'matrixGF_q,&F cqF>F>F>>F^r-%$sumG6$.*&-&%%F256G6#%+ConvertOutG6#&F^r6#8(F>)%"TG,&FgvF>F]sF>F> /.Fgv;F>""%>8'-%$modG6$-%$RemG6%*&F^rF>%7InvMixColumnPolynomialGF>,&*$FivF^wF>F >F>FivF_r?(FgvFBF>F\uF]o>&Fjn6$FcqFgv-&Fav6#%*ConvertInG6#-%&coeffG6%F`wFivFgv- %'RETURNG6#FjnFWFWFWFW, I2GenerateRandomKeyRFW6$%$KeyGFjpFWFWC%>Fjn-Fft6#;FB,&%#NkGF^wF]sF>?(FcqFBF>Fcy F]o>&Fjn6#Fcq-&Fav6#%&inputG6#-%3GenerateRandomByteGFWFgxFW6#FdyFWFW, I)HexToKeyR6#%'HexKeyGF\yFWFWC%>FjnF`y?(FcqFBF>FcyF]o>Fgy-Fjy6#-%(convertG6%&F` q6#;,&FcqF_rF>F>,&FcqF_rF_rF>%(decimalG%$hexGFgxFWF`zFWFW, I)RoundKeyR6$%,ExpandedKeyGFjpFWFWFW-Fhx6#-Fft6%FhtF[u7#-Fbs6$.&F`q6#,&*&FjtF>F \rF>F>FatF>/.FatFhtFW6#FjtFWFW, I,StateToTextRFap6%%)ByteListGFjpFatFWFWC%>Fjn-Fft6#;F>,$FjtF^w?(F^rFBF>FitF]o? (FcqFBF>F\uF]o>&Fjn6#,(F^rF^wFcqF>F>F>-&Fav6#%'outputG6#&F`q6$F^rFcq-Fhx6#-F\[l 6$-F\[l6$Fjn.%%listG%&bytesGFWFg\lFWFW, I,RijndaelECBR6$%%TextGFfp6&FipFhpFepFjpFWFWC&>Fjn-%4StringToCipherInputGF_q>Fc q-F^qFix?(F`wF>F>FcqF]oC$-%)RijndaelG6$&Fjn6#F`wF\r>&F^rFi_l-FfqFap-F\[l6$F^rFe ^lFWFapFWFW, I+ShiftRowByR6$Fjp%"CG6$%'NewRowGFatFWFWC$?(FcqFBF>FitF]o>Fgy&F\p6$-Fbw6$,&FcqF >F\rF>FjtF`q?(FcqFBF>FitF]o>&F\p6$FcqF`qFgyFW6$FjtF\pFWFW, I4StringToCipherInputR6#F[_l6'F[]l%/ByteListLengthGFhpFipFjpFWFWC(>Fjn-F\[l6$F` qFg^l>FcqFb_l>F^r-%%ceilG6#,$*&FcqF>FjtF]s#F>F^w>Fjn7$-%#opGFix-Fbs6$FB,&*&F^rF >FjtF>F^wFcqF]s?(FgvF>F>F^rF]o>&F`wFfv-%3BytesToCipherInputG6#7#-Fbs6$.&Fjn6#,( *&FjtF>FjvF>F^wF>F>FatF>/Ff\l;FB,&FjtF^wF]sF>-F\[l6$F`wFe^lFWFWFWFW, I)KeyToHexR6#F]yFWFWFW-&Fbu6#%*transposeG6#-Fgu6%FdyF^w-F^p6$R6#%"xGFW6$%)opera torG%&arrowGFW-F\[l6$-Fi]lF_qFd[lFWFWFWF`qFWFWFWFW, I*MixColumnRFW6&FatF'FbtFjpFWFW?(FjnFBF>FitF]oC&>Fcq-Fau6$-FguFap,&FjnF>F>F>>Fc q-F[v6$.*&-F`v6#&FcqFi_lF>)Fiv,&F`wF>F]sF>F>/.F`wF]w>F^r-Fbw6$-Few6%*&FcqF>%4Mi xColumnPolynomialGF>FiwFivF_r?(F`wFBF>F\uF]o>&F\p6$FjnF`w-F`x6#-Fex6%F^rFivF`wF W6$F\pFjtFWFW, I7InvMixColumnPolynomial,**&-F`v6#-Fjy6#"#6F>FivF\uF>*&-F`v6#-Fjy6#"#8F>FivF_rF >*&-F`v6#-Fjy6#""*F>FivF>F>-F`v6#-Fjy6#"#9F>FW, I,RijndaelOFBRFj^lF\_lFWFWC(>FjnF__l>FcqFb_l>&F^r6#FB-%6GenerateRandomMessageGF W>F\pFhil?(F`wF>F>FcqF]oC$-Ff_l6$F\pF\r>F[`l-Fhr6$F\pFh_lF]`lFWFapFWFW, I-I_FinalRoundR6#F`tFWFWFWC)-FioFW-%)userinfoG6&F^wFdjl%;State~after~InvByteSub ~~~:G-%6StateToHexForUserinfoGFap-%,InvShiftRowGFW-Fjjl6&F^wFdjl%;State~after~I nvShiftRow~~:GF][m-Fjjl6&F^wFdjl%;I_RoundKey~~~~~~~~~~~~~~~:G-F^[mF_q-%,AddRoun dKeyGF_q-Fjjl6&F^wFdjl%;State~after~AddRoundkey~~:GF][mFWFWFWFW, I#NbF^wFW, I#NkF^wFW, I#Nr"#5FW, I.I_RijndaelCFBRFdpFgpFWFWC'>FjnF]q>FbqF[r?(F^rF_rF>FjnF]oC$-Ff_l6$FjrF\r>Ffr-F hr6$F\pFcr-F\[l6$FcqFe^l-F_s6#-Fbs6$Fds/Fis;F_rFjnFWFapFWFW, I&_seedF>FW, I*AddStatesR6$%'State1G%'State2G6%%'ResultGFatFjpFWFWC%>FjnFet?(FcqFBF>FitF]o?( F^rFBF>F\uF]o>&Fjn6$FcqF^r-&Fav6#%"+G6$&F`qFc^m&F\rFc^mFgxFWFg\lFWFW, I&RoundRF]tFWFWFWC+-%(ByteSubGFW-Fjjl6&F^wF[_m%BState~after~ByteSub~~~~~~~~~~~~ ~:GF][m-%)ShiftRowGFW-Fjjl6&F^wF[_m%BState~after~ShiftRow~~~~~~~~~~~~:GF][m-Fce lFW-Fjjl6&F^wF[_m%BState~after~MixColumn~~~~~~~~~~~:GF][m-Fjjl6&F^wF[_m%BRoundK ey~~~~~~~~~~~~~~~~~~~~~~~~:GFg[mFh[m-Fjjl6&F^wF[_m%BState~after~AddRoundkey~~~~ ~~~~~:GF][mFWFWFWFW, I"i"#IFW, I4MixColumnPolynomial,**&-F`v6#-Fjy6#F\uF>FivF\uF>*&-F`v6#-FjyFdqF>FivF_rF>*&F\ amF>FivF>F>-F`v6#-Fjy6#F_rF>FW, I/I_KeyExpansionRF`dl6&%.I_ExpandedKeyGFjpF`tFatFWFWC%>Fjn-%-KeyExpansionGF_q?( FcqF>F>,&F_\mF>F]sF>F]oC$>F^r-F[t6#-F^t6$FjnFcq?(F`w*&FjtF>FcqF>F>,&*&FjtF>FhuF >F>F]sF>F]o>Fh_l-F\[l6$-Fau6$-FguFdr,&-Fbw6$F`wFjtF>F>F>Fe^lFgxFW6$F_\mFjtFWFW, I.I_RijndaelECBRFdpFgpFWFWC&>FjnF]q>Fcq-%'vectorGFix?(F^rF>F>FjnF]oC$Far>FfrF\` lF^sFWFapFWFW, I-ShiftOffsets=FW%&falseGE\[l$F^w7%F>F_rF\u""'F`dm"")7%F>F\uF^wFW, I6GenerateRandomMessageRFW6%F]yFjpFatFWFWC%>FjnFet?(F^rFBF>FitF]o?(FcqFBF>F\uF] o>&FjnF^^lFiyFgxFWFg\lFWFW, I3BytesToCipherInputR6#F[]l6%FipFjpFatFWFWC%>FjnFet?(F^rFBF>FitF]o?(FcqFBF>F\uF ]o>F\em-Fjy6#&F`qFf]lFgxFWFg\lFWFW, I/rand/generatorR6$F\zF(6&Fjp%"oGF%F\elF*F,C&@'-%%typeG6$FU%&rangeGC&>F/-Ffbl6$ F>FU>F5-Ffbl6$F_rFU@$543-Fafm6$F/%(integerG-Fafm6$F5Fagm2F5F/YQ.invalid~range6" >F5,(F5F>F/F]sF>F>3-Fafm6$FUFagm2FBFUC$>F/FB>F5FUYQ2invalid~argumentsFggm>8'9%? (F2F>F>F,2FdhmF5>Fdhm*&FehmF>FdhmF>6%/FgoF//FfoF5/F\o,&F2F>F]sF>F,F,F,Fggm, I-RijndaelCBC0RFj^lF\_lFWFWC'>FjnF__l>FcqFb_l>&F^rFdq-Ffq6#-Ff_l6$&FjnFdqF\r?(F `wF_rF>FcqF]oC$-Ff_l6$-Fhr6$&F^r6#FfflFh_lF\r>F[`lF\`lF]`lFWFapFWFW, I,RijndaelCBCRFj^lF\_lFWFWC'>FjnF__l>FcqFb_l>FhilFjil?(F`wF>F>FcqF]oC$F]jm>F[`l F\`lF]`lFWFapFWFW, I.I_RijndaelOFBRFdpFgpFWFWC(>FjnF]q>FbqF[r>F\pF[r?(F^rF_rF>FjnF]oC$F_jl>FfrF[]m F]]mF_]mFWFapFWFW, I(InvSBoxR6#Fbt6#F'FWFWC%>Fjn-F`x6#-Fbw6$-Few6%*&,,-F`vF_qF>*$F\elFadmF>*$F\el" "&F>F\elF>F>F>F>,(Fe\nF>*$F\elF\uF>F\elF>F>,&*$F\elFbdmF>F>F>F\elF_r@$0Fjn&Fav6 #%%zeroG>Fjn-&Fav6#%(inverseGFixFgxFWFWFWFW, I+FinalRoundRF]tFWFWFWC)F^_m-Fjjl6&F^wFf]n%=State~after~ByteSub~~~~~~~~:GF][mFc _m-Fjjl6&F^wFf]n%=State~after~ShiftRow~~~~~~~:GF][m-Fjjl6&F^wFf]n%=RoundKey~~~~ ~~~~~~~~~~~~~~~:GFg[mFh[m-Fjjl6&F^wFf]n%=State~after~AddRoundkey~~~~:GF][mFWFWF WFW, I3InitializeRijndaelR6$%&Nb_inG%&Nk_inGFWFWFWC&@&4-%'memberG6$F`q<%F^wFadmFbdm- %&ERRORG6#Q6Nb~must~be~4,~6~or~8.6"4-F^_n6$F\rF`_n-Fb_n6#Q6Nk~must~be~4,~6~or~8 .Fe_n>FjtF`q>FdyF\r>F_\m,&-%$maxG6$FjtFdyF>FadmF>FW6%FjtFdyF_\mFWFW, I-StateToBytesRFapFWFWFW-Fbdl6#-Fgu6#-F^p6$Fi]lF`qFWFWFWFW, I(I_RoundRFfjlFWFWFWC+Fhjl-Fjjl6&F^wF\an%@State~after~InvByteSub~~~~~~~~:GF][mF _[m-Fjjl6&F^wF\an%@State~after~InvShiftRow~~~~~~~:GF][m>F\p-F[tFap-Fjjl6&F^wF\a n%@State~after~InvMixColumn~~~~~~:GF][m-Fjjl6&F^wF\an%@I_RoundKey~~~~~~~~~~~~~~ ~~~~~~:GFg[mFh[m-Fjjl6&F^wF\an%@State~after~AddRoundkey~~~~~~~:GF][mFWFapFWFW, I+KeyToBytesRF`dlFWFWFW-Fbdl6#-Fgu6%FdyF^wFj`nFWFWFWFW, I)AddWordsR6$F'Fbt6$Fjp%"cGFWFWC$?(FjnF>F>F^wF]o>&FcqFix-Fe^m6$&F`qFix&F\rFix7# -Fbs6$.F^cn/.FjnF]wFWFWFWFW, I#RC=FW6#;F>"#HE\[l>F>F^amF_r-&Fav6#%"*G6$FbamF^amF\u-F`dn6$FbamF_dnF^w-F`dn6$F bamFddnFg\n-F`dn6$FbamFfdnFadm-F`dn6$FbamFhdn""(-F`dn6$FbamFjdnFbdm-F`dn6$FbamF ]enF\il-F`dn6$FbamF_enF`\m-F`dn6$FbamFaenF`hl-F`dn6$FbamFcen"#7-F`dn6$FbamFeenF fhl-F`dn6$FbamFhenFail-F`dn6$FbamFjen"#:-F`dn6$FbamF\fn"#;-F`dn6$FbamF_fn"#<-F` dn6$FbamFbfn"#=-F`dn6$FbamFefn"#>-F`dn6$FbamFhfn"#?-F`dn6$FbamF[gn"#@-F`dn6$Fba mF^gn"#A-F`dn6$FbamFagn"#B-F`dn6$FbamFdgn"#C-F`dn6$FbamFggn"#D-F`dn6$FbamFjgn"# E-F`dn6$FbamF]hn"#F-F`dn6$FbamF`hn"#G-F`dn6$FbamFchnF]dn-F`dn6$FbamFfhnFW, I,InvShiftRowRFW6#FjpFWFW?(FjnF>F>F\uF]o-F_`l6$Fjn,$&&F\dmFg\lFixF]sFWFg\lFWFW, I(RotByteR6#%(word_inG6$%)word_outGFjpFWFWC%>&Fjn6#F^wF[r?(FcqF>F>F\uF]o>Fgy&F` q6#Fhu-Fhx6#7#-Fbs6$.Fgy/.FcqF]wFWFWFWFW, I.I_RijndaelCBCRFdpFgpFWFWC'>FjnF]q>FbqF[r?(F^rF_rF>FjnF]oC$Far>FfrFgrF]]mF_]mF WFapFWFW, I+StateToHexRFapFWFWFW-Fbdl6#-Fgu6#-F^p6$RF[elFWF]elFWF`elFWFWFWF`qFWFWFWFW, I-KeyExpansionRF`dl6%%"WGFjp%%tempGFWFWC&>Fjn-Fft6#;FB,&*&FjtF>,&F_\mF>F>F>F>F> F]sF>?(FcqFBF>,&FdyF>F]sF>F]o>Fgy7&&F`q6#,$FcqF^w&F`q6#,&FcqF^wF>F>&F`q6#,&FcqF ^wF_rF>&F`q6#,&FcqF^wF\uF>?(FcqFdyF>Fd\oF]oC%>F^r&Fjn6#,&FcqF>F]sF>@&/-Fbw6$Fcq FdyFB>F^r-Ffbn6$-F^p6$%%SBoxG-FcinFdr-%%RconG6#-%%iquoGF`^o32FadmFdy/F_^oF^w>F^ r-F^p6$Ff^oF^r>Fgy-Ffbn6$&Fjn6#,&FcqF>FdyF]sF^rFgxFWFacmFWFW, I(ByteSubRFWFWFWFW>F\p-F^p6$Ff^oF\pFWFapFWFW, I,AddRoundKeyRF]t6$FjpFatFWFW?(FcqFBF>FitF]o?(FjnFBF>F\uF]o>&F\p6$FcqFjn-Fe^m6$ Fd`o&F`qFe`oFWFapFWFW, I*KeyToBitsRF`dlFWFWFW-Fbdl6#-Fgu6%FdyF^w-F^p6$RF[elFWF]elFW&-F_s6$Q(00000006"- F\[l6$Fbel%'binaryG6#;!")F]sFWFWFWF`qFWFWFWFW, I)ShiftRowRFWF\inFWFW?(FjnF>F>F\uF]o-F_`l6$FjnFainFWFg\lFWFW, I+BytesToKeyRF_emFWFWFW-Fft6$Fby-F^p6$Fjy&F`q6#;F>,$FdyF^wFWF`zFWFW, I,StateToBitsRFapFWFWFW-Fbdl6#-Fgu6#-F^p6$RF[elFWF]elFWFbaoFWFWFWF`qFWFWFWFW, I%RconRF\inFWFWFW7&&FicnF_q-FjyFiilFicoFicoFWFWFWFW, I/StateListToHexR6#%*StateListGFWFWFW-F^p6$Fa[oF`qFWFWFWFW, I)RijndaelR6$FipFfpFg[lFWFWC+>F\p-FfqF_q>Fjn-F[bm6#F\r-Fjjl6&F^wFf_l%?initial~S tate~~~~~~~~~~~~~~~~:GF][m-Fjjl6&F^wFf_l%?I_RoundKey~~~~~~~~~~~~~~~~~~~:G-F^[m6 #-F^t6$FjnFB-Fi[mF`eo-Fjjl6&F^wFf_l%?State~after~AddRoundkey~~~~~~:GF][m?(FcqF> F>F]bmF]o-F[_mFabm-Ff]n6#-F^t6$FjnF_\m-FhxFapFW6$F\pF_\mFWFW, I,RijndaelCFBRFj^lF\_lFWFWC'>FjnF__l>FcqFb_l>FhilFjil?(F`wF>F>FcqF]oC$-Ff_l6$Fa jmF\r>F[`lFbjlF]`lFWFapFWFW, I+I_RijndaelRFbdo6$FgamFjpFWFWC+>F\pFedo>Fjn-FdamFhdo-Fjjl6&F^wFiq%=initial~Sta te~~~~~~~~~~~~~~:GF][m-Fjjl6&F^wFiq%=I_RoundKey~~~~~~~~~~~~~~~~~:G-F^[mFjeo-Fi[ mFjeo-Fjjl6&F^wFiqFd^nF][m?(FcqF]bmF]sF>F]o-F\anFabm-FdjlF`eoF]foFWF^foFWFW, I3GenerateRandomByteRFWFXFWFWC%>F<-FE6$,$FFjnF<-FE6$Fjn"$c#FWF;FWFW, I6StateToHexForUserinfoRFapFWFWFW-F\[l6$-Fgu6#-F^p6$RF[elFWF]elFW&-F_s6$Q"06"-F \[l6$F`el%'stringG6#;!"#F]sFWFWFWF`q.%)listlistGFWFWFWFW, I%SBoxRFi[nFh[nFWFWC$@%/F`qF^]n>FjnF^]n>Fjn-Fc]nF_q-F`x6#-Fbw6$-Few6%,,*&-F`vFi xF>,,*$F\elF^wF>Fi\nF>*$F\elF_rF>F\elF>F>F>F>F>Fe\nF>Ff\nF>F\elF>F>F>Fj\nF\elF_ rFWFWFWFW