libtomcrypt-1.17/0000755000175100001440000000000010621351501012523 5ustar tomuserslibtomcrypt-1.17/doc/0000755000175100001440000000000010621351501013270 5ustar tomuserslibtomcrypt-1.17/doc/footer.html0000644000175100001440000000050510621351501015454 0ustar tomusers
Code by Tom
Docs using doxygen libtomcrypt-1.17/doc/header.html0000644000175100001440000000064610621351501015414 0ustar tomusers LibTomCrypt: Main Page libtomcrypt-1.17/doc/crypt.pdf0000644000175100001440000311773610621351501015146 0ustar tomusers%PDF-1.4 %쏢 5 0 obj <> stream xmr1y R0uKJ90UQe` U=f (_s(sqaz/ ^oۅxAA Rrmy-dճ0iƜbu%3z2{KBr7g9+xH'5F_rԊj;/A`fYJX>i-[4IA|ѷW!(Y\s[fcU9.%jGRdVd}K`/Ğz XXRÕkh[RPحp|9'rɱ9F@"lC"5 y{5l*/N)O*/Q 5Ϯ#=~M%%=.rO|ϖ5?Yendstream endobj 6 0 obj 411 endobj 17 0 obj <> stream xTn1Wіµx;]X }8P@H)fO24q{z꽺`ocuM=ouwQ r xr?~/R6AXXߐdNSHGXW 8rDHgw㑹:Oqh]穻٥Ωy%+_)㲲؃@ 2#hjVvX9jh3N SRYKWcAmsendstream endobj 18 0 obj 659 endobj 22 0 obj <> stream xZr7}߯ǙT"u  `(!ܤٕƔ]ĦxuZ+o˻aݪ6sʌc :]U!9ŵZ_o^77NH>мnJƧԼj))64ksZZ?VME3[Y_':| Aw͓Ȍ /e\E(rYex~?J?aPpH%m/Vs.:Ğcvg'NBC7"}]5tC&m?Z dKYpjNĝӟ9yPgB߶#DMFb]pb<%0i!jiؿ␠"YMytM&btsNOfS4ObYq5pJǕdΛ-g3vQ3蝿 әv-ESIrm#Ń|-J*bw^iEoT'HFmC]*yOL# :ɘF>9/ʘINaŋ\ꧤȢY[T#K,$Q6ǙOot˙T=h"1O#4px;xݐ#Ę;beśj<cܹ$6}pUJ*x@MQ>292Y& (Sy_Wby9(\+nk0J$Df1o!,Šd)( NR E3tI؀-0jenqJ\] iW)jl?^?h}=s0 9"?{VRdq_Bh?BޫYM"!YUoS[ =A fBܪK5s[0> stream xے6)NuKeH $`JU!yt3쑽,Lv(e?w-f̵Y:ݸ͚s%8*:tv|6iaBgȓˑm3:jW0ehmk '̿g|yT>Y2bgZ!_lfdǝyډs~٬zͅ'-*c!ƜxS4nUP"}ϻN$zy)sW+&1}R]~;oܤVpJCrUL k N>rX}[Ҥ]ϹWE31'/O~@=`Mӕw-zX,zL^: y0\"DiB3^.Zց0*SaI7Rܢ86Ee„B{b̰2)+'ae k,yLn:>zb!0&>w\1c\幔تC7;zg^\"A:ńX=zYL?`4BDE&84 ѸaA♱lڅ@N>8կS7ѳ&R&^RjsɌkƣ;;-bFR`5,͚`--MޭI$u[䮇<^hOFq(G/z>'1 fMq/if*-=3ڕR}Rc'`/I23qf#k}vQ Ӱ>h{s7׈K@Nm#!$Ldb HlžF֬}؂Y`ƵԈ K  1I~-'FtoU$ &WuM|Owb6{~=߽Zd=BJ7jfUM#=K?t=s@oz'' we|KgOB[r\Ydzi˹]"g}Yje"po+Q|OR!&w: jYkWڲ+mNKg*^YV%ķHK2t-IJI {l1xRw[#48<ݓȦmb4hE5o/ 1iҚo M>h&0_"XC*o9é.O㤂0̸WBʏH|͡APZL+m[odFSڹ`m ЁcKB6Ni' ɺΨ-K>jApAd}}ZFQQG#14L7m!)-n aDqFOCݾr2։L"^#1EKlqx,|Ÿ.|Avsv{,\4_ֹPendstream endobj 32 0 obj 1983 endobj 36 0 obj <> stream xK6F?^b9CǤMv4=$d$gS4>3,R${^"UdR"^>̵gY}v ;G:;_A۞@ÜV拋_+hrHţ(l񩬬mu(si[5GxWV<A*rKSqހX\sʁ/Yuۋ7S!C?*1̝|1~6Gt1lﳆ:QkP /~e=4狳fIy " 橙⇲ Sۆ̒ $ :e/~*iӕ#xWU gfCūS_)Ȑ#c{q('}ڀҺ³NYtw|)-/8 uHSJܔinݝI1Z^dVu5{p.Am~dj$-Aѷ^|y/L6m oJ7_ß$}DTʒUH*$JJ0I{1gu+[39\8:41h칍nFR˹=X_*endstream endobj 37 0 obj 1854 endobj 41 0 obj <> stream xY6ߍR~&M+FQ"&A;w#e:FVD983~L,yW}z7|aQ.q{jn!v0j{!epXjbgK A^HleB3kz2^9\0z) d΂>nsɜdsře9&^gp{ _ L+꾀a_,}KÌ..DKl\c5K\=T3VWY"8\Jgw)$N*<`/{n\o/@Hn_t]W3ByR˅rkZw~`ֽ &A1eEP ٪1KrbK,2*?@dт(`FJ ǸР^9hqEd?'GJK}0(Aj~:*oU.JQ,WJ8:K~0߫.˔)j%8(:qۙ|_nQiN"T!;ø .F{/H(HmJQŸsLue8A,V;jCwP(u2ӎGGUD|(% %^iTcdcd3CaOH`6JH:*h7-\GjKԴD*DŽo9{^CmPʹX#C ĈkBh`sKt8E>R琔7&{Qv5s<8TROtcfTԍQg8zK`' 8lzaК"*VKGYI΄ >Րl8 kg -HAe?W! :ia?Ȇg+CBY6Wµ\g2#fFdwI&tx@)ƍnGe}݊].؍j$Dl[b$3 bZD~$Vo&zRD\TE3@5WiE IXHCwjҖ8(/{NcD7a a |ӄVTɡCX=al(֞[ؾX[np,~Fԝtp6]'Lv^vT&a1}r᪝cK:瘙$LN0?Ul3ᄿ's,}f7aP3Ƹ'uh](mJ ݺF6BڲVVsb42.ז&ƹwJ[5 *P) Ռ7^zf7쬼y8P`8]SByio6(#>kbpTRaN`eITyxA>Io"݁\'O$晪 qy"ZHS^6RgYn:ѵ*~U"kNXXeI/I:iTLïipVFmXpe;ERFŅsBRTdgM*`T+øv*в4&Y,S ipӉn*Σ3nMjY)LX'm|d0T8M-<j}x&RGƬHxq *HԴvkW ~~q >X-~-+Bendstream endobj 42 0 obj 1946 endobj 46 0 obj <> stream xK7e&UVuHBs M/}*.'dz[cbP6Tf1"@+ӡ|YtˡqXLJʔfvk]pI|oJXXzhݓɋY=ic̅^Zs)P}`,#[F1]aݚz-<0vJe!}`~`f'irpy+";8/U !"(^s$^lwyKN‘eJ}$o'fe2!0abd'[ /X}sb5ÐJnjm 14 '1^-ҁa^4o[%xV28b b^ UF\mT<-Q0'ɭ[I9&G"ݭSC6kHlQrwkHFJ/K j6=) ϒCI;sEGr=ZIW95VJI'5}`g)dCnˊC'>SG&t8^lH엥cA}Gi靤Sѧz>O;m pV>Mz~E4 K d:{w)6c4PRÛKU^g7<̱-)g]k-~WH7/$~ `A tQAlqYWx-Eⵧ>贍@B=21]DLkzrےGq`W+Yۿ/DѴba4p "#hxN1XQqM7Z!֡h]qGEsYN8/9p .*y+' O$3omߡhPG#(ʖ eb%҅ҺY*Ahjt֊/T|QۣпfW6iu}8Ҩ|8zv'f^jWU$]کLy$*4I %iFR9 ` |Ƒ=q{T/e;yU/(<5 &|*oԉX)QLzD9>&$Ù^U"h(56\X#M'61ݚ *)"*3׏!!_ nd5"e nͿkuG1}&RVvVam!5@4IM$WP/s^O{YT2c^fN$87{iendstream endobj 47 0 obj 1995 endobj 51 0 obj <> stream x\Ys?BJݏ2c舵.30,cͬCJUWLwSt}2S)}P>.n>ۯR~yխ~":pZ{{/PY'jqZ5K-5 f)A)[_6X$Am(}i&]kVx5ƈhkL,6,ZYk1*;n/VFS ֺ~X!#P~95<\Y 3j>};]VCHj%2V(qtbԵx8<|^!F*kq`uH0yA@6YS+ N0=+u\'bhS!D)%`'8*J+ 'ʘKq)ni0w { z851VG՟OF2ڏ-0&Dd`>z .HH c\bW2:&-\ר:0^΁ו)>rp1/XAI0ChCiD Vk^lEllE1h᱙\3D!exJD #%_q.}AOyoQ'E7D]Z<]|t͗ɢ5B* S փ߿YR~ܩz:kTNoHtwUe,GAd&֙.Hpj#QsBB¨Wa^6X }pckJDq)V̨)},!*8-Q+QE^Fԥ^C.B%{̴ɘƙA)L8Ǝ?Ll5Κ}-4.{J7ljՃUhf) }nlTQX؂ ۀ:[f-^*icxݳ l[Q;rBf%n44q5oIcCp.4F:;:88'~@mMq@-vk^#l=wpƜYﻓ.g({VŮo&.(]܃";db7'Gh JYp;B!wփ3K}wS~*V^3j9=yc|2YH5_o8~!fԵd*\J3K( IEqxpl  ˜/tMAJs\>O;uE`y IHJM`"c2K.ee8)y`&} N< ñL$XKTHl}>)b(aAsVs_ZH!]v+>e$9GfR[ m°B:u:󕃧z'Gīwq;{3loZiDyKK$'kNki$wKCZ;WXQ3;U,NRtЊc̸*@>/{à,8r%=.tJ_ ; %gS1@./S  LPKquZɏ'.@ X{J3|1=b%xZ3)_Vv,z7&f3p:,Zi$!&v :u|iU>ϋe_jaZXlq}aJN/*,NIK3xw(%4qՐKI|k)R&  . řN$%:ҙ Eg\l B垳:0:u(.Uî>];usendstream endobj 52 0 obj 2661 endobj 56 0 obj <> stream xKs6~hyL>$q궓_ ٔLiI_.s8W}|6쩟J8_ajk.y33lb[@lKBʚʬ.CTAmu2V^8ҠLt՛/.4*S(/8Js  1]ZeM\z]ߗ8tfwFڀ}Z@@u.1巳;brӳ~EFϚǯ]0g;3i R^| ֫|/|҃1?V ōђ6wBfA@(CRz.@qW lgT1zK l?4rm)*8w Cuf2?EkĄ4*mض3!u`1?VjBuߤQ䜳EuVD#H+|c"x6?")"ER6:ANqg~nWUG# V,ĭ=`1cH湄ୌKex7[ !L!iH&P/K21w~,rn;֟6&D>f8`o^Ef4e^Z)bCw?*UNQf?DC"yVUNzv 3?Kn#~G5ˢ?Ä5#wX]SmbېS4˦u]Lz2.3-XRv[Ҵ܁Ͽk8C?vCL', ("B(/Ad)<_KA{&J &gՍ^=A)"=*~E}\ӈ/g?A_*endstream endobj 57 0 obj 1420 endobj 62 0 obj <> stream xXɒ5wuTѲ2Zhf3}#88</c֟穪j=C5R*/Ki^vRg~lsQ.^okG݃y冦?4Ŧ۝ohflv6ߚF)-[ʎԼ.(\[լߔ$9/V)D1>0qbU$Wc"A-vU 9H8e9V["*ÀCȣg˩` Dw7GȞG-695IeHV?9Lǭopq7`ݝ}Њ<_h#!?ͣ O2! L}C^@4{/{Nc~砜[IXE A*FbC׾w|Z5(Hk!=Zbmz\’p7<5yoP`N$RYxV.eZreCɄR&m#jv3msTn= ZDS9-pX:iDtT)d%f2 | ț_J׳5L 4;FŌ'%J(I amєB`]_uF>yčM/ꛬS8tɜ?Fj$P2yFW.LT!tE 4E0^S Zl'\@j{vBGnTs)EiֹJ2ފ?-kx*&#UWW3=WȖ]u^.^^i ָ 'W8[n!k*W! QlHM飘B1Y-E?~;&*6_dendstream endobj 63 0 obj 982 endobj 67 0 obj <> stream x=K A S$mv[F+e;+k|W 2ż+L۳/W/ZHHk5[Nhwػg1Lf7&=dJ:>UM&endstream endobj 68 0 obj 116 endobj 72 0 obj <> stream xZَ}#C4"ر t"& g$h\A|7- #,,-^pgh ?ZjLɴa8MVP4ja[E|pt&XV*{տ VXgh/CdG纪 'EРz@JI [a}W?,n$Mrt`̫. bį.) @8 ¹ 4>B>'=G /:6c#N.Z/U%$GҚfqGM'6 KՇ4!V1> =0'^MF`[/}ثbth`@x] èczI_ca` 2x: #\mUi@xidk0|H4h6cݜ]I+P7lpovs2w  G4FxQUdꃩw!%e[2w'RuFc Jٹ4R∾ Q( C'Yɥ䍨=GǏ}; I[cWD⯪߽J QogXR1YJ"`սPW$r/?fQtRya+&A-o(#TٻΙK`qw k<`j;J&C|a!K?7:nQĊ'rE⇋]殑![wƄ4j@)d *` q+6 ̷By?uΣ<]TXQ-ğ6LD8?486GUU >hgvyB(J1KDSetq[A8yTpުM1jȗ2IA1`~uw'C;f7FRǍp!>)wԽ8f\wKD?MveE݆#9x2꟭a}X(7HO qjR'nң|gul3T W#>Ap'Ud{MG`޳:*M<P0{[~zRhTiԊ47 `z~ڟ8~>D$0>FR_k<ʼnkx+hLgu4Wzqx0fU t#I6'FFPr iZAݟj!R=Un8{H܆CNǑry(UWp$9QTߣf+z`-.{P?Fcdbmli n<31A6S]r~̕Z84qJ8=> #={lм\_* }YU*NbQ0]H=la 5eZv\ @:'S&jW3mpZ8UOV &XHQ=ee/:ޱּQy߻=D\'p;r}wc#u! c v]4gTe8(o4ϱQJ16t9Ϲ'cȣ@z×! =;)y1c8k\~ +ǔuK jq1(ԯҼ7k'Df3n`aCV Bh}xKʕ&<\$SxפP^*MMA_9s^SғbtCJߒʽɹzIo^-%YY;:|+[V2* \7v.ݨ"D@ CXE>gĩP+뺽؄3>pWaz6 хb% R7]k94S[yށΈRﴟn zͨw[~}g 1v@E Gʳh}`7dn=cMU}[mO;Տp|l=47 ~^/1q[vuQ(N)H+>2ӈt$cL=:@B0ri.M2{ G~| /qw`\mY-IHH3$_JpI[;R! cITyqȂ˿Zŵew*'U1oLˍO|G2\ߩFRa :=\v ̌: {tu/ 6k+xiwٻ, LGC|+:!JHZ4lPL;"4 Gb#;Nۿ56ŸD;16O<_eiB'I:i$!|!{iuO!=0WgFUDч߿\.] z?Y{|:هJQ_En?T\)}aUCyKVZ[t 0ckE| g]a)gǟendstream endobj 73 0 obj 3218 endobj 77 0 obj <> stream x\Yu~gy˽o%/A,ANC%Mm}SÄԼ]˩|g䍠_|7_W?0!'MKE\"Yw<'ytvla%2'Int~caܱɁ- h? .-XU yH1AnZtS\+Y]liM* %!3Evu{5m *&7; '@k"Hn"*b(TcCƚpW߸ф\H!9:JWGG)_;iz R3#v@KRuoNM»rYp[eZ%_\ftm9zΞ^GSJg5cv+p8-`nv|(LmAnKcNSe$R{ߧH;~kl$ogJڒ1K?c2Åʬx|$[P~O ^.nglhHbDzP|Bkwg3 b/_fS/%KǙMiL%Zub|] E`Le?;{&qɀf ܽ#Zqfw`iWCK1ʏ1dr@8ώ_r C-ˬDnL"4 YE6K 2nCJ>S`m&Nq"|`3 $g1FsdeG+ Zr"ۮM%Z]u3o9"Э zeLBoa4Q, !jcHy ɳPm#iXb=C@ B7KAo_l8-:5 dML>2<(1wB݊X `:;r_0h;l &;@NQ,5EA@.=H{r7(MiIqML4u{ x_!F6]5175R{(Ng D>e'`DH;9hES3h%LAbo-%K>Ggz^Gh bueIDKZXeAj RT!m!VBiQD[ޭX0؈,2|CyBW@\AT"P`B0fG j sӂZO"mSv}e~mYtͳp )͍厦h)nm"'dܝx$PPx}UȌn}]F@D-1_2vfޱ됾JjA"/cne带2$!I7<+{+v­dUJ1f.f0s*(dՔjw՞bd8UŽd%}&ˀ<o>VY08VwI}֧߃B&u|8 */SD娄tU\ [2)x={qyQ#2e%FIXgN~j8+f岵U$hDG*fJ?}j %'z nvZ2냫Q4+j';%$1(8UКs)w%W]`W|ҟA'룟qC/>teȠ(SRkZg 9ǚD窇 J `";ݵ-=NWҍ^=K[?9'ˮ9NO]PwN_nNkB\g[rNë!QGbѩ;wrVi#K 4>Hf4K'RjA .Tnze],:Gr'뜻c)ihc g4;lRQA1.OFS*n!מ"KK؍@IEa#oR/Fa2ԝD۪ >H" FvQN/5Xdܘ9;!;qԌ_zo•?J3j4Í,F#_ߖdy]ozzbD_U&I;d?U͠#cRDZz0yrƁƆ3؁,}IX ilMީ(j_d61 ur'sV4rb]ص t=hNr3Kl%K#˃XL*8>1z((Fߨ8rÓOrWzf4U}B*g/H_\8ˌ]v[C*^'8Nxx/r fr6Vt}@Orטm+TaV49Z}U۟/򐻗U <#T#A}fexd8L-yIZJZ;u mhZd* ^2!_z'5ՐZp濰ֈ5L#CfUM"Y+ѷsi4#rEc6u'j#%[F |δd/6p6FF^#fޱ)̐Zz3ZKoWy:{·ea0d8͹g%j+O+,|ˀ~ tSȪ;l5c bwًalHi2*&1h ofmj_7gvvI> z%b_tn// U`OOH~WVj!c"}-r굚S5@QX[>^X1 > stream x\ْGy{ V# ^&I3VˌedY3#!UwWuU̓KssA?j^^Y%;6􀢍Ok2Û4oU`_|y*= }x~a8~IIjѐLt-2~EVGk]{>N ^TUȂpxm lZY]hث9X/ N%OkqN֒OG(KTih exň\6Y] ; ZPeܴh K#Z2,EaԝS8uM AMA[W Lp;p %̔Y.P}wNW]RlGc|rƺ ,A{ux[FzPa[y>WȸoizZbΫ*=Uq }'@TXgXr ><[bYf> QW1/Gɔ: k>h;6=,]+Цkv*v$Y\$ cQ B+Kiٔ0UqX9KYҟ:nM}B");mEG|9S $[I'hl%10qϓRɣs%vo较4~sPAR8Jz0|9Х!q]Y7X<+Rb⫝JP\jҭ&k ̫طF8 8]ه=Kx3[ ~(|k',tU{4*]Bw O 2kZ7YPoIF޵γe`g r@xSDdK Q K0~qi>0nHjU` 2jhF~#fy^NmB)+ÓxӤsV@;BO4¶CT ݷK|~ḾRx*DfI@=LzbVىAqi3!~ J$:=2@iegp :kMaw3Z{NNz N.ڹ<]N6+2"r}7$ahK9mH7s):`Hz0x7G6ͤm:v9Yc[2 IKiP049ݻ-m^xauyO}֭K3ԊM`)wE R `^U*!lд}IO+y؞+E*\O\bD0-Z$Vj8 & Qө>hVPLvok%{ER8Mv< 5&s{: 󗼖ZX!)G3UC92*hB nj kZEV-u/]!F_ڞɴ |'p^ϳ=jwheSaK}3F4PDěL HD0 f L au[57zVbpx FNnwaW&Uf5x='sZƆkN#p cJc4K2)h?Ѫ 27ϴI)8n9@HV>s? LzۊD߽g_7lAf.Ńtu7s}KF1ۖ%e'P@JLKzusZ^% BcE@b^yE:M u$21|l%fifoݿ\'oوcwk2c<Ͻܱa݁1JbSX#SBsT12oS[utXq)K "8Φ23VZp9G,0j6$Wb0?6Z.Yh1Mܭ)nyEyƨ~Jk zYMt֊$ g^XiTqAg*d|n67Mǩ禶 j^c^?V6O= 5/DIX.L.抳"JVN=Fx[[yv6G.뱈M*nsA6z-W=MRSi),YX .>Om}|j(2SƕSrK* 'yRR,!jE)]KX?8Kzl8=˹N~rJ|N_֕ 19AS5LwC;k x0?.rm12JcH$I4~YX ~C?KQm~9;GüocuQɌio"Y7mZr,aZx8/aM XRt;я([JtA=\]c7y[7$?_za7]~$ 񺌿C"k# ʤlCv~iԄoH/no(rkǠ;`D#ia{zl@tͪUhUaqŰif=#Nx n(bDп!kޤʱNm1 U,D't$I0R\*jӧ*17DhHt }@51;;pDmnkJnE5;ɛ@Lf/0m~=E~tS;m~xJ`2-@4.:/.0Nendstream endobj 87 0 obj 4392 endobj 93 0 obj <> stream xZ]L< [ڱksZZ3(efӧ%9NB'gx׋Ûg>>>cT(S?»ImBͫ÷OV8YU+Xy‡?'-V*TFY5OJLh7'E1d5 k($0Lǟ^H3|5j%rkTe-qfRH9˓P6D~F`pIvc۬q^b{r6XJpZlMmC &LxpӷÙ óQ1N9`E[{ P~<BevnXIeSU* zЫa _ sq \޺Ȭ' d(Gz %X/KVfD;PwËhD\MPȾy}ŀa\ ?<{b Jӯj#,wC v$!D*B`suW$ 58G}1f)gg4T%\ "(30{|HfXc>RH8Rk膏6 Д >7ܮ,n J_:.54jr"R@rΩy֢a Њ@""j(#:CU!YO;++Vlm_$T^ SR-r VPOY :K} @}'#*Яf3"Q3%s><}x/U/fԱ!̟s1b6U[ xws<jO.' {wiV9j?¢yThϢJp^YrU{ *kM02MzlI"BJߑ"c\*h/)BQb;H.4*Z-SCJ# 4p4qPM=Gg_}?|r'ǧʲy:2Ym0SܖLQx7<g$䁠7 KJd`s%CmC(zhu, T ] 8? _3Mi"biRJ=n"Nën7ݩW~n'"Kl19NQn<+yU|X@^w55A/r}[ XքCk L =MKUUR r6C6HK )c6^ H?]i!c$6ko\RRʸ n[NC`vKm^JR#=NSWOn=EP΀4}ܩ 2錦sQϋQ)7 "R tM,:{6>0r t*j|T/~D])"6T@I?`O Fac%'v=܂zqleeMwˢCGH"EAZUgVA5V(TP? ZH=Q+*WQvUJVJma&͒=̇Ж(*=0؝t]^3FdQwetsixP=a7ªh}f 1xt6v ?Luխj<Иkn+NFFDJ.5LU͠QS9/PxʲcM0T⡡/Ȯ>ze+@.D tF馺UY]電Ytendstream endobj 94 0 obj 2679 endobj 98 0 obj <> stream xTMs1 أ}XaI?0 01MC[>>v0JOOOz~S8>nxq5z|ф 9Pf/s%% @N z2b l'͢gs1g2ufG3P*]4-!dWUA\ bAw|(7؉4kBuP͍)sh!6BߢSE)}AʈR'UWץ&tXP΁r"G%[v;bG58b:.sȾh0.R gJ(Ϣ9w EXQ.$EnQi"]}PfTcثɚ1¾,ɞ IvSnP]zT$[=mHk2&h w{~7njW@=w*AdWȑ^Cj#%'Uea#KI?S0endstream endobj 99 0 obj 634 endobj 103 0 obj <> stream xMNNC1 !v;YX`ʆXQUT*kT|>wq_w1vg֓Ch8oДU|w4f`Kc1 > stream xXn7|E?v,7O J6m , P$X3,ٛݟ)v3-Nd]xTo:)T'zuwoWIک2}fr=`p\9_iU":0zsdXKaÚҺ?NJUz;()ؿ ֪fXkDw {rll0ET1v6~7x j0A-6#鿄u0|ARA_),Vc6GCtnw졂ߎ Ql8EW6)JFj(1iM97S~(Mk:u#.N)OM| #RPu.cM$rVǙ5.u!;(Tqɖпrm[/6Y1h!+ *Bl+WVB"G2vt:2!kLmј:<mvJJ v!8mY3گ,%'LkNM@ 0L|FhLA" n Ll7i*RGa`bԌ\퐜2Z-`WH^oeT8-HI2|ްMk4ԿSА P8afH(uk6-[7& -*}1; ד>t8> JHO)FC "*_]Êц7,#L620dd;?r 00MQ)u 3CY'0 #ts,6U 68)lҷG_7jX .:!&:pm:)is kCsYDV $dbRZd;5QvN^( XPH-)b"F> L( &Gh)4rpnl'l{]~WzR-tXTP~dWY8& B BOE2ޡ|Ccc!$K>a>P`=ެtڈ55#7kWG?t7w/WG?uju-9lqm~,S &?c#'j8{P䲻hSAr4ֻW jнEVR\HbMAd(pUC.ɂy/Wƛ%>0nZz-bZq[6opQ^Rr?(QDUiCCˍb4kM5.LF>E^(j? 4.RZ7=8^?vH/$`h7j +a;&qg-zXud%팥嗓'艖>p;+cšQh]'C4:zLX f?^t35 "X6QjK6pP3_` 1Vs++:%nDfIeuVl|v#MPf݌ ZKZfhݑI7j{C#q`oX _tAp!bmC{XO$Vc7U[Zsҷs7m^T~@!{Vnjο2\nM/7$n.4un1- 9M-?c cXArjp{I?vXl\^G !9S-1}OVwyMF*1# . OU}5;S/5Q&<7?u.D|F"\1 ~y[d &\-CQ-Sv R1AjZ,Ǝ4endstream endobj 109 0 obj 2183 endobj 119 0 obj <> stream xYYo]~#nZ8/]$A_7/E]% Y2օDYY3~﯎tGqw#6_OG?O_o!7+ΎD9,=pruog|F{>Mܝ‡obRIR;Mwٖ3v tQ/`́.n0ni τWrjv:w B,d^ofX0/\lK7m齚M᫴4)Ǎ*[)7G'IO1>w?qmkK:qA4ɳGye:^u b-uR1s(84\ 'C&Q0%w,#װ,&ȗ˱=y;){BFS_*k! g``đFB,b,4^(gXs(n%s :)UF©fV$Iʋ Λ uy4 rJBT9( %:4sS.um  *!0ܨw(΂SE-DvRoA =E*59JXl;køeJ lxYawL87՚}#= (}*ǗǫH P}ҫrެl,iX0WVO  KıF. ԧ`)7Gfbx)rc.jRy _}UGidLljѪDy=-*ؑTbJ{fSfMÜ]PQ$}*N@O~O ^*0(@e%y:4D EXFI˔RAfeHl{F.+]D^W |4RFTH|IB+@InߣBun/i~I5 (qS4]z\{+}bqQk2 9. o՞ Xu(#"(4r}4dӗjϋSX%d{ %Bx3XҌȨm6дk8l{lpuP* >ݹG6qV_9IW4pp9h @j I18ˈ gy`a$}VV(Eo\Tne,xnfS@pyh̸ y\УP|ذ`u0.1y1xGrBR5.z=A^3:OCO"N-K-XOϬPgk| Q㹟$_b46 -~S{0TJ:3Œŀ@͡y#QzxU#ݏ˦zЫAc@ƒoxY@Ie}7)FQSfJhj˜J7$e=S#Jm锕穀Is㸶c+ DƳ;pendstream endobj 120 0 obj 2444 endobj 124 0 obj <> stream x][Dڗ҆ <ZFȍ߯v<9ɎHv+})ZJΣŵay"_]K EO/C$.O~YyD4).]BΣŏ+8tv%R^;/ҫ ^X+af8;Z[WFXZZ,ABҗ=tvGw-:%+iC'M] Ii'0: Ϥ1У,]4;7V a|GBk7Z>?}qoq퇥Z\wǍOY|zcIQx[HDPi7q(lFW(n8aԓ*IȼV7HaO@193G{"F[$:4ICO05mwHa&=0a+zg[)Oޣ4?洓tzBLDݥwzZp!mEũay`Pa9070Y'o00z R{ Va1ж&>܅gp|dcgvy h2qݓw(c_HvZˊc|v" خO! [0F4~Fqu rBe{eoE_],t_~4DO3uGE@4M E$ N'i]-C; I#(Al݂skmrҬE UO2'cmȺ%qsEL2 n=|L.ՠǝ9k1"' q5TzC:S/k/z+f*-f9?4?3] ~ޙA~q~f^?kc.bW?tEMB Qp=|LS0۶3a.;4NJ_K_iʺǗCM4&3wh6o=Gw8GK5{;d hOjZd(T=jh̘_!֭IܜQ1a^3ɼQ{l_ ִDRrL5zizf(뛣=5N!A9Т[]kVm֘=XNߔGǺp|{NItb4J994T ޣMدqT`4:zfj?Mȩ:pKjFP>F瘳G<>g}҄3_ZEk0dcX+$XMGWM[TTlxQ+?Sd" &anJ"45~ۖwݎ'ENvSBaI)Uhx^Ui'l\FKqJeJl2V2cT޳eX@ҧ3+!S%4}5Lg8xm0Y /A Y 𭥂mվ\/ižDZU#hPaA̽ޗ}ܲ)(^c1ufa8! 1;zs0H$N΃.l/Vn^(Jc&6nJJ+h^<{!XxȅIʸY(7Մqqa; FN}^=!s& 6[}ml,=❫˱mن@^ W*X ~OЩI2T |  ;?F5w+"8RF>7 tNmϳsGB:Z!%F Kw,qPb#_fcRZbv6O;ٲ3۷? 6e`lQϦl:ccl bSaT \*JϢseDj+z2e>ffV[JPZ:IGPb< '= 0 {Ȋl@lfW*OyOM ܣ NMs?뮃o5i%6ԫvC-bHƋ+>TkAvf2nrXo,0Kot.URQHN'>C!$l;TD]ٲ,jxe uWH籺wjwPaH/&u@xZ >Հg=MfD8dy*"s>٘ǴJo@~OGU-5[:zMÅT <;,~{0.4' )q X0++Z+dSd]'7Aaods6ZS#ByyC+9(0}TvPGxy:բ"+:!ь$YhXQM];D5n_\$^ -מk\{PZuwiąɿ\ZžH6Ȃ.9hV?ݢ)l-F r NgCk1{wW훐V+*>Ƿ%Sendstream endobj 125 0 obj 3413 endobj 137 0 obj <> stream x[mo럸hqgVw?ةIDQQq`ŒK w:Gp1]Ùg=]Xbg-Oqv)_ۅo/! VZ;^}:g{4w/~\t>F8!.D*B`ͻFuRIP;gu9-\7VvuJÃFtV7M˜EE:i#wb /w+ZNIRۻzAm<.7uNpV]ozVop꺌N`@v^G6zuX*d'Jex\K8~,OE˜,s~*/{R BX}{ X<(i YH?x1'`uﴡ `dU[WIN SwK"ݾ-le& O^1=~]=>džE{gK^5{7ܞ3c ˃2Gi;k?,rM#]ߗ/NEל!lCRa֎W]GuYe]֠ewt(s*-&x=u (&k"o2"w\R241ej{ߺ툙xuw)yz]A*x9m'R&8TDMȋm9c~t5ãU1/ݑ)ƽ)" 6T`?TLkHtڛK z4rn\agI΂uRHԧJ `{PUWW/0 DKCDMJcmZ&q_¬ʐLGܠ c[,42ғt?4żwEt ]&kvaRZ@c| s[FEHAu/5Qa vU@wk:ͯ&Y@#8⇸I[3gH8/+͕Y [# tp#To|dp}{dٖ$\`M-=~#ZSOy[L< Y2 %2|5auho4?zHNjtÆ[\7{,M31TO"y']yMB%ok eY&iԾՐ*ܭ_ŽVƜ v:sNEdr@wDؐ6b.†HtG Ǟ?HĆD.ŏCO3+A@v,/<ˆGEA~x]p`iǑ8 F@1o;9s om(a)vBQm!p_k \m5\b=!P"r"p 9&"5B f (1||EWB$8e 4$@^] &ˉ)/c,=u$k$e1&C 8; oUNهCw!@1)J{z"J,x@9<&"R?(f C'TҢ2$I0Ɍ# ngQ:RQ ;m8&dCrn*+h\ < bHHByKw #" .m4_:Ч5uU @O3o8*W+Ѝ@#,دrV"eůup;Sk9%=eR;SɎA̼e(U\Gӡ#|V)1wJ]c0ҁ{Wŝ]1lGh+ӏ|*J__q$;CE`r_KK6r:60ޑw*$#jB pYT'-⇞ h%EO3rqM})z=\CnYôȥBWg޸;t;G[ʼnfL fz|L!vUJDk"!!f|nLxL fkIArf2 ~Kž} sc:Ζ34zaщh+;B UY<~^&GjR J֭;@!x&1>--f䳑 qȍY~Zd4]WTgX(Y2t΋YGyR!QE1=5y >urŋYmd9L/1`zKO23/ ,M H>PWŚciJ(}H,0= ¤tɗ59TXn F^J7,#W}/xO[ÿ}?sendstream endobj 138 0 obj 3349 endobj 142 0 obj <> stream xZyo\)-ZMMMus;J". ɖ%ò%Rw 2-HxoNzr=O}>yJk^dg._? !N9>x{+E1mBlqfYxfZMp&eg3=lPnharz9O la朶%i|RqXǃ0QNJJLiO7jֳMKFHI 85}+*rhk"Y'_@RqQ;c`̻_Zږ϶ʋhAbScWDIR pPY hޫJ " t1i<@rڔ=QgMlM;YJ1`a2iӴ̭ ;* TVn]l,8z8,`H+p"3}fbGW/VO23{.Ww[?pG_W49R4*d={;5ҥ"M:",+SbϝYoY|zeU63:+uEk@70IJMG%i! 2H6$3U`eJ>.Id/3q>x7Xin Zs@ji!'QX9If 1ٯG? o5j2dh2y+{0xBrY鐘S ڂb$khzب^`ˀijjYk]BY+\0[U[漵hҩﲵnEj}֟(,Lgw_T;W=4%"l\ ?x:a  VImWҲ[3ں);)$7Sap^k|jՔ,~(n[m v98IĴū^ r. g4|چI;ftu~>~ СVw2g,@9hE=*r󷭓p1h-4:H93}v EQbTTvL۶R$o{$~&!KTi a n܎BgeLuZѐ$8Dnj}BkC$ kD8.IrA ~cygьg.YJw\we@E&Xfjjn2u2[t=z#ڇfS$ujs;[i=|k!pZNYhajjxlh|A[~ZW` / H: Dfk:vE~`'H֘&Rt8]h +1~?DfdխT?$-ORF!hxinDZNY")`DXiƵzTf)f<"QbXHQ2A)S9U @ B4q§(՞}#jBţQС-~|;jeT% 1S q.BtcaˠJKn㍝fXʥ8Q Q;g}RZ?B>+D~91NOC(Z4 مzT(HA*BQ鱘:Qࡲ0pSŤAuA*TmWQfۚo6Q [BT _,l=;Jr%*X+*[ju>\Nb>^2TV;)[øp"F̏ !67gt> )[QS\J=݂uivcH)jz<`vx ou|QEXʶ| ][>oٴ-xj`UE2P+>k?˿hys=NSeNvbLݽ9[fU+gVաe7X lf .>CiU FǢd` 䞰 t! ]Tz|-or$y07+nOttS8rADtkH Ȧ*<24Dm1Xhx$V"@*ptK#`Rxl?:i@j`&.׃4Nl'A5pr˭9?c .-@8cfyz0hzTw hV;R o|e/w\2=BX Kʮ}s =CBNսع[_:DY.{iIKoF fw?ll߸qEᣅc*PIuTG5}T0~Z{klYGzQ¼-%eq]I~wGppxHr+ǡ>eBSZT6o$zk" "$;C4䘿z7 wi(m xvh, X$3m*شm%|Hb$w>B3B%C=ŖH`x-dL>Õ`*54)<[?д| řEیg ^h%[2kd|̎??ڵ>a19s: SPeNLC^jH[MVU\ŲcN >|hzhK:ߔ`'deby%c#XA!fRg݂ 4z4:؝D ٗݗ_f.b8k!Â=t DG xm oԏ䦈,'8+IDa'xTi b[,EךMO:9^RNNDnZQ}iF0+aB)y~mRWME+5 R?t`2&*ͨ'(y-ϋrՂ #ccXG0X|ocDxϱx$;F&iT-~Fdnu&>cg"C(\[c/VKp^/#V#t< jĠp%h^wN2endstream endobj 143 0 obj 3363 endobj 147 0 obj <> stream xMNC1 Ţ<°䌇K*g-tK6॑%5mw~;Bendstream endobj 148 0 obj 205 endobj 152 0 obj <> stream xZn\1w O%o  Ā I%RE%T/n(0`zk9^K=kؿݽ3wvE'^K;U;%IqoNO~>pކQ 1ATqxw?H:4\gS/`R4!h?W&1(b&'NqmT G%V ohS-sx 0&|IyztWğRxQb4 u | `uUJ[u'b[MjfD]˾,Zk; , ^zMzqAR{@2X@J4(P:elƫ@Zx5F7jxӗgVj #= sT$ swRE(J[EW|UQ u$I`B-Lpru.N$Y+fq$"h/8 t0QrPXY(@_A ’vz8\Zd4X]HJ? m 64/c£?x^hJS"o :$PXDØr^w:rNHםڐlOi3H،CN Da?is38+# un-U|Mxyš*jY7%"pa=H3QwJ$۩9#zYt e)¸An,&- ǾXC~.]PNVS1P 6{PkF#h0=1LT36.goK؜Pś5gq:g YSz55 J"6_H0 H(M[=7qˀ  ,?(Q[#CgB ȓQhJ\937@ul pwEJZe6{hH+*>TAF8A&5Z'T|&*OO :];YuLT81/EARɔ̋QZFȸ+Ռvyb^YtQ@Q4 rb>&q$OZtd1?1Ͷ[0pILwV sn۸˴;+ M`Yf 5͵frceHn#ѡ013s"xR1mk@#a92*Yq:ưr;ZM,ҮsEs\ ΚjMq1&-! PhtF9!RA-C>8j#g:^u[Wmq~zEݬ}k, fMǂ'Ek,Y:u Pޠdp'7<c&z?f(p9Fg6!Uvҋt찇>cgf3j\L']d tJjQSS|LUV3yDdr:( ]L6W u2 v8(!8=$Nv/v%:OV}A~eGR>}{//vOW'=k=߿XNuVGDV^gIJǤ)J>lDR]Q2yMpOg99 ¡wq~l M~)a9 !KOWVѣ~"sĞG̦Aݨ؀qHf|1kLr19xv먮PUU4b|/ yȧD&q`."֬kw1nB49'R8xVtFy( 0hFw#M'ά֏q*|@O[M>DAtB)gzv sEXo(Wz)l6eUŊ5j=cc3$Y׍ bru)<r1J \ Y8мݫ#^E+ ۚYQѥYЄ9WXt`xZ_PBtVQ(EAjc"ifR>ٗR~*@3s+Q^bņfv9.^7DX)NMq0n&q _iЊ%\գS1auzE, Vo[yHYE;yZ5ecdӔyjWqxl>iyag|i2p}ҭV/,æv# E\*Tcכ3ry=ꆱ9d^7^&G:̴G}rz&,8zNDԬ` -5}ԇ1}w}ˋ ))Y߾˛~aTU}zRvGa}yZAR4e?p=>ݯ%YH!'?o&zT-B׫n Zsz$Gʑ 5GMxendstream endobj 153 0 obj 2715 endobj 157 0 obj <> stream x[[oeGg3?9gቄ40 KmE8@3u>mwP>uYU[݉E+^9~⻳v'wlO>L?D&HKtʙ7g~N aQ˛h5{C/Eίh_G(Tv9e!vW(墎 bviU.xYV3o2,2h?E&;L~ b}T~6|",G:M$b$ ^.?z]q ŽV-ZƸ;}<47z>wjy.X6vjqQ?b{Zyá?d8GE5&HAңqP%2Ia/Ͼ:va'3 ;!٧g٧g~}g?v_}@I\8u9Ab#k'kOطqN6!WB"L@_U]`\₅_wzbq$u'ī>>"@/("en5X@K\;@%oe$&Wd7q6.ּ$a9*9(\*!ۛo-Z:XNסlX[K>+~G%%]97+lJ8߱]>tb\v;" 2=Ժ + +/M83 r18*~HzsQB C]A v"1k`ʎF;l*kI(o<᲌.ȅ&{,%a.W#HT{*Xk$mi9",B Q.އfc';VN&em*" ;<7"pK:D9 k鐐 ns԰\mT1n!za*^;CYjԙ:+Wd<< U:J&CR}g\;p3:;K3|_hoCR"#{D亣a$]v治ꓘ鰜q`KHIoΰ-M\w@gh~>ٺ= Aڥ;0M XTD˃v" g"JA1L 3\ VPpUUJ;-E.K5hS ^X : IDĠG+x爽q!LkGǥ莈g, HA[9aBoK[$A LsW_ ٘CdWz6E 2En80DeqwvbʎJ}0!$CEVe gE2ض@fM>Okzh%-A.q%DrQUMY Y<AnXZ^DE Ug:@XTLI(#yO?ȸ#ҡ>B?a 9-o^cō 4#cf53W\+ TY ͐< MT(P&jib|@T}E4f ɭLAtxF \EeaeQBݎe>XҢN1jDm˄ȉZI:ɫ̛.ѝ{B]%6t`S%IcbDζYYj?mD C ks+1Q2TCւցml2mt(1цS0*>>Z$iNU..){܌(:T:i ⣂VR Ln+Lgn8ovྛyOLS"XG~'E ܨ39XgcӁ{DUјAR"p7Flm/5}ND7M:̄̂ LDu޵w[x}2 PPDkUJ B_?^`7HKɅ4K_zWt A m5]F{Ag(R0ij,xR2 *12fK-d$d2_)%Я#i9!CLކB+B򞳐RBCk>?R粥nWpUdƯ %T/J%yL6dۓRV=zBs|I7 Lv}p"p*-H-># ΋[uMX> ؚoHݫm 7́F=}4%kC 4҄2-\VQ=&o͌.ڎd;* ľ;%rū<!׽;޲=l,ͻo ww-kCvt-e<+RQp_ݴatuhDF[x/2?YbT'=2/v˧AUƓ4ysrTRiw^/]*{<;Stȿ57Qy҆rW 9"ÏΆJ%NۗyܫPxV@MԋA7w/eq-{c|Z} RЧ] suϝ&,\53!U9}=C+n$>O !y&DC^wx!;CF/.%.'\^c- m8)WӜ14݄X(a%yI_Y^oZza`Bvϫ͐еf:~y/4@uZJC?yV_ ]*̄mS37A^  y|XM}D{)CE/qlGM(?ش*Ou1<_ +Ԙ1ؓ>gh]u&lq^mhU~k3VO:(ER`K#g=}ώCbngK'G4aRnH9lrT{bH $;'$TC j#IK[QQ)oU4Q(& * h{2x-EzNVRO5;3?JɝEj't +/V,!evtQZ=^E |З|Qt 3uj6qVR1gh_a) C[@3a2+ZG^˛6OlyfFM_Pȅ"k+AQvNaGG6M7WWHeXH }^}ctzabDܴ_ekcB K$#oI0TG}M_uv֋Tܫ_wnp$с ُK=yR'ݰ?]YmM^S~/'RU :@endstream endobj 158 0 obj 4308 endobj 168 0 obj <> stream xZ{ߣDu#r! !7Rr c}BvOrrgM@'^]U˞KĒ7'nyxK|GNj i 6x ,Xirui̫{&⟝|Fwiid'˔~L{aZ>ġJteZO:/^.uwG `Rjn^ᆠ̔P/{.8ZK Th=8{יLB5et,8~\}V} p8E{29aV&SJ?x&HK?|D s$z 4"'ŋǚ`SV%ǣ[^~_});=zy/O._l,?frCBZ ^ NvPK~R4Q%ġAqM14V' *wIjXЦ;J Mo#Gy#LNB%fB3H;[2 %JRX˄]M#4 M'Y .LhVg LuJ8*aV+z]`]s#O:,xH+\ LW J70@_$ώA;11^oh;P ~%}˅B3 !D9$3B{Ү*ЃrѴO|2pV%aV@ &Tbe-. 8ޮXEܐp$6w"YqeAcN`u(X˕7` 0tSA.R؏T5d<]BdjD8Kr@XVd pSy;nUdHc<5|Lkf+]P@UļЈKC> [#J"Xiu[_"ѢH.g%BJyy,/K=xQfIxSf,?ʊӺXu{eIY7ev*fAyqXE/k]3b~=ԅPd:Io8۪}U,wl 2x4oIq:$P 5]FzQg2Ô1 5U!BӨ1cDy6j$xx["H?MjړhNBGMe*]`|kfJU|҈etFI4 %~%䊣IhA z'A}x n>k|}]y^7lP9jXL?,iEq< 2$*CNXʊĥx*H[Gkv0K^a>9&{C ȸNiuy'$j3KkOPm5OGmR:ew?_v8]aZzm !flj~w>wЩ_Ѥ63>_}.5wϸTFgG_wdI~E?{c@6\EV+a@Km:y~-)z@_T#s3ހBӽ)7uo}=I@9osF<[ROŠa9퓕>.; (C 'O>o>./UD{Bd87&*GQ> stream xZ[o\~#-v 1.P)&@D@[؁!ku.+K+;ޙCΐʮ7wJo OF.qڏCtʙ=~N} `jLvQX3s2Ĩ>+9=09X™V*NK s1x]jh7;BEgB0BZ;[%Y+$[傗\edjv;7ڹi;$5(&U(^( YZ)̂Rٷ8ڋ Aw6njp<N1nF A:8n M:P, n9n^Bx Ҁ9mP J:M 4ws p(i@n9`"`H`! ZfӠoa_[$Tb>xxW:sܡt]7[fAFUڲkP`O1X\(qRA#7墍+ 4yCIȹ^;?V$u=fMDv%QH&55^ppv;(zM0d9 %V6Nc,F6_i!r0!w\M6'6㙒rD!2)$atYMsZ/Z)7Wz>BdD]uEkՌwD~ U?8&ꚨsx+GH "fG/qOhIOy L9)*eSy0u,M\ܙ=0 {SNa^A޵C-DFI@@a=M5u{A?#{ƅ:TGH#AUq=cOFP4\ rWPKKe/]eSVe @O^)0'[iu>'&_MeUf#':tܗȸ$~IVF%ZʬՌ'2L۰ܿ3q`X`յn<%>,Ti%2GR$g>Zu<sJTv1MGn:ˢj<.Sτ_}|j:~{Nw"kTu\D^7Q"RG n1tHϪנBִƕ'eYݗeAv)f.۫B*B-{2YYaE%D7{ jWVM(tyY]k_ ]YyWb,F9!O`c'}ld~Z8,qT5n2t~Yh~.pT얭U}EtUinoZ leuZbƞG.:?D#Ƚ7dAok$ pVKvO94@n,]mJmB.uM`-;X,ɃÛN֬f [׊Kf8*3Jjsfl b^'s><.q}Ho2yE> >|A$ϭXL`4'6 ]Z]'}PVIjqh&Zew<dy:( 6{]hwM fӔO:I %ѡ0}M"ԉ8+J 9 `Q2 :o;^t|~\_D._;ţLdΉ6tk _#+2Tk/4+6sG-WM2~شCUurzW C&6g 5Pe`/:"a^TS'G53@ MC y> stream x[[oN_pq=iΚK4uӦI* %r-Kdq:ru|I`Zq;|fe/݄-~^nox`s[?{#=泓ms76Lr׳Liޱ*$v{,>\Y5|B*5j׎)%'eOKdnabqXy/0_35"Q9[!/vr 5,rdpb6sJ˙y3]U`T 5PF+yG~Bgo T.PR ףS#4l(:j`^Yo{aӇ0+ɃW *" ^Oe촌&*N>חu].cׄJ2xyILqzr Ox8ù0=ÕC8-gi! `Շ(Nzpݞ5s/Z4أ<ݖgZ~ьU*o4@SR3ZNLtX;)X)cow p\y&+_qPV:bfl{af(@v@yڽ̛ai&M(w[*p>`J~"?ԠߖWD [Z~+0VU|ILfA R DDKI9R[nEZwv\v.gª?C(?TC u=`r6+GE'#$8"iixxQp@t҆u77}TryVV9p'pJ^5`MqVV_<8mQ1xjxz:5fu5$HGEGx%rPjőlIHR*N*#0Зҍʖ܉Y0͂Y i^A%f͌HdXd9ќ$kJJ C4jp71N_9V9ȱ rIx &Yvʭ$KBô12n6eB$,)eﯯ xZo!mTrYVvQv!|`J6K˒)bH !CXy@6}KiuQ3dY‚X4& 8гv,Y,H:aƀIU$G%+W8^2&f q5vf 鬦qZy*DHtzZGr CZOEy WO s~Ͳ<@pA|"ᕵȹ)~SpA#=O벗'0sաd8ƝEpFaYs2J0jng)TYU |9A ]Ž /,QDWfuk^ 5{,_/9bAar6"W;!J3tjWch>(Ƶ&VlrUT`72Si@ zY,JT_{uwzHCNe]2:'8{a2 J98i K5Q٬=0z˸^d՝R0 #*)]5泶'<:СγY\5ጻ*8m@Pp]q-58Y)ijq$a^+?(N#2NQ<nA#@.v P%CRx[ot]^" (?]la Z(^?DH [łk$/8?`+@$(`/=~n!Hʗ4j Ih a;Ǹ2̗nsdn ;G$bnX)c3@LMbAhS2$t ~hLAhVgUI /[9E+A ` p|z ~Fmj0:QnkH`e^m3#N!F@,!o)r 7j ef ҷ<"c LĴٲ$[ryj%/hVB;sfn ে?y`s?/n^m{7cOlZv|)&@_Ωa%8_$:]ȜCr_Wѭ1Futȷp@wE`;nvף6! q9+NP)ʗa:lޗvrB%A.}kBӓ_ULq>8`eN0dSy '.0W읊zL@p֢]cu@,$)L npL5(Z )oCjO@GtĵvBTfuGLQ fNNm]+gظYI-v i;+B/M텣v"K-+X6^!Jtɰ!w\FI2޶q{wXh=[0wl~YN p?3HiG O bXj%I<,=H', Ш+N79f)ff̋$"H-jljRh2wnYȻߤ͎[pn9._Ӹ R踷3j=^:lo)" _ HtKg /́scՒTUj;TJ皤Xێ1DtZRI_ yY^bNHNq\ HC|LW#+b-Tt߱¿0|jSM5#dɼtS=X_ ٲdөiR-lLAPҊv$V ; m:wZh 1ƍYZ}*~́r0ZuCf:`%B] qPU. *N\ֻrPRO'DȶZj+Z5yg{E_0AjzUR4 p|4WH6|y@$SKCPja݉C@ܶR9S%[kŸʵw}xS汔J: ςs*ь^Ó/u ΜDXrn9F{h[L*B<.Ec llcqDyB1Hs |Xء)N Ym2\nx5nxqqU"?>ܒ׮0 rvAxĻq^OҵbWCҬendstream endobj 179 0 obj 4122 endobj 187 0 obj <> stream xZY]G*?>k{_BIaE"Yms̘86 Kv9յW}3'{xz>]ݵX^^DoB VZ?^sY.{&껍 qCP=(?o~JPi˶9-ܜowqݜN0i 3\Ja6mNdj:j+<^V3͕Ķw^|xU3D>/rG8^e@r+`Sy<(%7[Ŵu|lnRr8设HLY@^ sO^l%Ҫzw V^FsH.ύjbMؿg^♊9%n&Fm$-DYf `W|FX>KJ\ivFfP_̏]׽ӺnFng4uݻ+84X1Gh&пwB0?>!Q!7z1}U7aBƒ>@7MOb *Fm:\f/|AC: #j[w 4$B(6ǾہaN4N/ͪMSˋ3by?^ l_ ~$jMY7&Mg`2.Xco Jd/{?Խ iNNlaooMˠ wՖQ2jWF{ bHKD k]f6֙aLhh*ϻ,Pint_?hb !}ŏZ9PY0fC0AZ R^Wv1낛x6"_ս֣6mz_׽Fe@iRW=ዲa"a?z]ķv0YIϯ&^P`/3LD6äqKD*،xB! *-5BԱ [;5q1*\~")JnQqdt8^ . R`/N{w5SJ1cЕ,"\&rsƃ#XpLPLvZy*)! sAqf4sx5F )Nd,*o*>GRXK1r)} :?C _ﯞ^8iBrk-s{<[=kz;ٟZb℥gLXxL*n>pV, "S>6-`ȰG8U샇*|R7֠ǀGW^|LrrO"GaR+Z($iMǢf5IkoMatS4 >ȧ;M t&R t) <{]m /4)4ą&8m xS횚9 0/ŴPoVIA%\* -ƤM8 !YZLJЩkyu*ɭavkװ)$QI٦ukFp(9]HHb!њ[AĦ;Edꎙ{/qEEn %.:Ǎz~=IHzuMKPN}.U{ʨE-^$$w73Wly:iajG!-M&-аB!(ɠ B*x w gA7 6k7B$Vx'W,^1Otw[ 66uOɲ dןR~/#K7r\UmQlЀ@-Zk|4(-*<Of)̸3!2l24oQVې!nh )IGӢl,.@S"굀Hϡuˆ+n c6-+UW>Nq`>\OPpNVelaӤG}pT=W85+v fkq a_MCHi"׼;"\|]jʚ =,:EJN_+E9Nhz|U[TQkԯqfo2\qG :1d/1OQ9OcUʥ+iDϑV:3dLhu>`H2`̈́߶9ٝ0錚'] p819 _WsK l0>0s4%ot =ej>̭gEBkS8N,׸ gR~}&NZ9-UN9ڻ ^LŋF8=AB5i0mN 8X ÷}4cslAMo?C#⫯S*5w*"ї]h 8o`ŃTt7d]i[~@I7:= 83 2?z ?RZ(J.@Jq}M _Ē^G\1qsQ#qrpptȮxrP7t?J°880"z-Aq59 v>2 .Z#?R=:տv#endstream endobj 188 0 obj 3104 endobj 192 0 obj <> stream x՝[ݶ|quЮ_nA 4}pq_cm3CQ$Y(kDgH4z /}rwgru>z{"]s7x}`N ~oyGA; 5WÅ赗FCUB)kgs oCM7@ ۽e/dL/ZM(?^kt:^CP=)MFI}ntR 4tݷ{emѡ^[ w~]m/w]suo=EDŽD?bR ӔL](ȣV2xk ڸ23!tX7RP|P / Yp Yki}%^n0!o V {)u!V'+XL/5HMл ZS=傚(G{ yP؏MAPSȰjw/nM-rگѧ"g2Za#EY5S{@bB*[,W%*J56|%{!1X'\i%a-d iފFGoh;IMr%ɩ%|BI!iz)2 >"fdX~Op0\U38\Tn5X@m?̓qdWjqGLӢLVMd62Vʸ'mJԷ0 c/;/ajJcvfȪs8\.3C]>^`v9UG~W7:8Xo2ed03)<3"W4 ],rUp3ŤYLJZ@&ajAv_ BMgr\`F=B*Xj }hh( }*ؾY2ɤc sb#Ll${y$W@]?/#Vtcz.Ue|sd%6®60< &+WQ0k6w̱՛mOHui Ete©`aCʮ:B̉hSbcY .dwJ4rxN&+ I9 edC}\sy`6Ij.?5^y7V[4*ęihcaŨZv+H"~ U`< \i ͆V0)ސ  3:~UA۽δ%&ꝭ-zu+ +ɧYt&VShڠ {ܥ1µ_Wn#\Ϩd+}RȌlW9HӾj$/#ðSiG35j^k}$|o\Zt_Mvx/g M2%:U] C#Aezh:C8 =ʌ ]#9+-.1Y3P{Gq:^*l>n#h[{ݎn-{lg}Cs/G ̣у9{ݺS$C]gƝ/T,f?/a:R擆~>Q2 +`mSTBMxṵIqyfc䢏Mڐ2!,1ĭ(L50ӭ]<ݜjޝMtO;eyg6 /<^QtK/G8>EO zh|m6W6>o|T۠o5xiȈ,'vq;|@u%ϟZPߒUܳ_ i MBUh5i>x 5P&j?}#e xy"%'O:u\m endstream endobj 193 0 obj 3020 endobj 197 0 obj <> stream x\[q?<y>ű({D pX$Hx|K>gf4OO,U;1ɝG/.>=}s/^_Q} ): Y~N aR7{u8)Da^?ШwG'χV*G ;䍲jpTFQNEoGbv2"ݿVeD<<0ɠfTcbRNZETxC^;7=I w{ *ғ/in L%4B(v3I+Go%x(39R]i)eȃt`˄x9 ;Lr' ' МF??/DJxӸ ˹>B<^l/$6bdWՍ5'*m^(So?:2L]ѓT"QLcdbtP W>\mߤm<7/& wm0YI^D&!c ]ª)'g=s~u1)ذfѼj¨;(-/xd2 d?wVCT 郋O|{ӻ.>z'/>=?|v_>+G+9esi"LFU~V){vrꠅv5&ex܄IMX*e$JjbT*7bTYe62,fݦX; (#XI !zs#D+nbtI-yhnل"ó%aݛZuYF4%!ckjY֬y`94~Uɉk xa~Վ gf&IOQYNb-2F)&K n7-eه4Ϭ"ٕޡw K6J p>vG+:`"ܞ)851Xט b !٩7I-TC<3-ʵ"%Th|87 ŤMl@!ҳY7 [Ac&DP̕I3\#6p@4 6 )5:Ea[2Mwf=$cYuxbډф3 34RmؒtN~3 Xb>Zb%w\K-p{ɹ[Lh?)%7]`y u+HwJx3C{ƒUxf,n柍Ұ3 p0G54XaffQgS6l Z}}X`hW2mv+!"ꇼcBT1$Δ!N[4p %W 0: !}52Mon+ 9|bN;mF3}#hL)@[Wpfn&^۸ɺ5% yQm IZb'FY뻖 [-l%4xT8ںNF Zu=@pa>-Bk 1=eLI`xo5XVXomSl0C$_;*LFQč-Wued؍)(ua8lU5\Jrށ3f.ցWKo9{{ VE:]H몭f}f!!$S!s)8-\P~)9tGR 8p*XR;IpI .P7?pŽ\MM-~k1pyloBiϓcjڱ~M;\1nr>00fh4\.]qυkbLKy͖;hBnrFhm iDtR[= 0b\ rXp9 vM!O{aVA-0Y\C^2t>'[zC[9cK>qRjR\ =ȍxt "IY޳'Du^zϔJ2jLAvO,l7(sOg2_疱#9@HpPÔ&gHg!D7 ?U QhU>Ǐyz̝hOs_`vRKG֨mH+R(_tb\\^78זa2& [r7 #nuMN)mbBpg;UI&ɚlf#eҬ75S7eyTG NdrGHƷIZ*!p.*%0dO[N]\a f&?Fި{v R0m]LdJh&OǮf'(!#1Aʋ&=ai=J)QB=3ըV:XV2x0 zŔ>>a9R1e34P kUφ#.'՘9\cjP{M#HӱJ5{6$-rT 6A0@INlK(Ƴ\efWWZ|Ѷf+Y6Jcap9=Wr3t=mdi_@u۷l#^T911ZiyUR!)&?2cikD%tj@ܠNz8ǖFv $LxPr Nϣ 29.*"Zxai2l =gss_ހ HRQ7qK=;L ĪR9 }[I'},!8A%Qt֍NWYGs:Wa8or!["bu+"I{1* |%zwd:B~;RT_=;Zzd촫Ep2TSj2H=ZZk ߥYNq|5SuOI̜vl]"K~6=EY6 g->sosyEoKꅏJ-mlrm%Rp9-)72rot`d{&s7'TRE$\K. dW8޲N\t~726Vb6,F;W6"O^U\N>JXӮ[2 <^43UG,By|"nq.U)g CAcl͚-Q#w>U**L yG3cmbTTLB'[;mgͮQ+«_2a5X,NmI-sQQd-j+] ܥ?ors49uԫp ؉ߍO0JEP &̡tLǕ]:`'}iheg*Z|8OEͥMP3ak[|@pm:c3ܴ),qb><ͭ܇,$@x^]K$ ڰY!#uۙwoʹ Ӧh6pï1w]ɝf,,nD@FcdÑjM>̘+/Ɣ1,3Фa1k2\ZojaNWQJ.+,X srHH5 *Caa-rnl92ƚg/W[$)IwG-rWGZ]`'9ʒ[^Yv]h@pquۃ$o)Ly<̜IJ.-mmKZa\'AP/Bt[*#9@xfc{rl'o4klf=ޮFa|r*3'Շ]ƴzU\L'$vf5䍞~L1bABxm}-4=0[ {\uۧtVB[&+9sd79:* a?jG xqP44a:,AC=6묡*(gG4F?n,2˹fy›rŁr~O8arrnbrf2B:ͬUY+eL#RGQ!&7O G~R5?[/i&Q-i(D\TF~,GiIy9=h/w@>jooo_۟[]Hӿn\.-9ȜG ܯ$Y,h8a":VEzq* [Ί~94.y(IT̷aFPֹҡz8}Ј}|Ć[f"w/;7!J"m?^NxM%,w# pU*2΄<`w-9sPѪw3%mTݭ2)ի*SDz$H̆l$o5:;{A&}w06i-h;$|mDv 8Y{< [(.nYgO(h˂{Lpw nk5tL)&Auh@@<J)OișLJC>7pt4%! Vee|u/-욆endstream endobj 198 0 obj 5719 endobj 204 0 obj <> stream xio\-'އq GmnDZ)woj @L=ÙoSwO'[?rf|<~sS{#nLxܯywS\/`t򢓳gZuV -phK.ٜq-uw40TJvWt y*4SxB(f <{}LLs'%LIVUk^t9R֫n6:ey&TN;G 8 lùSO'?LNws@N(ơ=l=vzyq?i'[_}y'ϦK%@`*Y٭@.FJlT{`EP鍔Zv?digL4ig3?sA&[})*3/(ٻ9!fIۀ(Ӧv6)1t%T$+Ac$%5ۼ8R`ZBRB$! dKR`PIJ`7 mXJb_,)q6{qYH "eĭ0ay [?:tҢphxWƀvgF3f:*19/@c `| r{u_u/;]xN\aLp}W)p{9 b*( wnkݭ\ncP398 (42RYknu:tiZj ꌆ{4\%޺JodY[f *Pg]  XdZIlC $>H0D6rdV Qq36+kxdkO&|@op.dVAB"(H鐜ۘų%KrEle |T%/IMf_zxMVLۉyow͹|SE۳w yD~ >…Jf jsiD}D\l:9UW ܖ('T v DNA{0R=TZ  Z_Qd5ck1ZG @lZ{W~8%(ARNJAAĘz",hƦG|.Cd;仃E lzA6*tY4l;"6| ɑ0^ǮWUXt/?9 RJ3Ahq;ɣ<#,* Tu͓"NU[y"Lj(i U45VBR$G&VM&ǰ:<&ϝ4x.\+GƤR|#.dNs=߾Hҙ)^Nd*<`z~K)-R1?˓s2we/j6cT$qޣ֭m, ?"  ,uF*5u˙"!hRըಝP57//-Θ5˚#Q(Wx56.t\~]Y?Enq2Ӯgi\"j h *꾁2|-ŁT L%/ޖ ^`ZT\{uKcWzKpzCjB6 ;yik|H7xBK|1ӈJ_+SҌf$ 42k*zK>͒/!݌CWupEߣۍ\otCp1ӥɎ[BZi J{%n˸)|,|MṧJO] Mض,ᥭ-GJ'Pa'(7Qˀ1i@J4v36ivmJȈkldPahbpo]c{} X ?jYt).8IJ0 ~G=Bרk2LE,CC=T_ab080dqv4, ,+0^|,̾]=s}]f{f K3tgmh`(Yg# [!Mkr^s@(.yo<\lѵnYgͩ0a?LvԖendstream endobj 205 0 obj 3335 endobj 209 0 obj <> stream xZyG"gez>b K`(k=L SgL?{,tW3/v*QmY]ϣvaVw_Ds˵Ir 7a>psӇg\5P"R9 {sJPi69-N6d\hea3 &mPaތ˜<"NHtFx&F3͕QbۻTcn/)j#Z+0y%|w3Uwd)[E$5, zBRqi`kY)D<.X9HÌ.S%L%LAp])ŸFmȉN.&1eZ[4ps :$QP ׈IzcsQ#)P(bs !rڃxȤQ 1#QsϜK!ι, ]& haҊ|ޛs,85<$QʀQKia/7?Hs! ! D7[B B|4%=F?װ|-Gl?st T]E8Kzqs쀬$@AlM԰ o("Q+Ҭ%~lw~x>T7fq W&65&gm.aQ7۠[pK).>6]"}ä{bRȣIdjDȽ3]]67h&}I0B Ku8AIy BVYb>RNv!*ZVwEVHKUH50\֭]%چP=,># 4X_Q3 ՙ8 "~US 0x 0 :Bz,LG _@)yY!$%'a1 (@ĘvLu;םwi:ך^&R~UZ?Pa,F,9b2MУ{ 8:`"`{z[Unh]bbې 1<&̎8Wq|e3\r}z'c ^^t7 w!|5B;_P '5v$,jv&|i09GІ7~K(7YԚ-cN0KCqk(~ jD5DAn @vWOWoJ] _Pkxpj˛wkw}y/Vn=V2^D@%X1J %9BlV" 1,9ܒhC2=^{ ݖйT>?}|K-%IKKgn';wdq'Z,)a#X؅vlYrJD":@ >T_qTPTV;PVrGS=ľ!f3.ݯ֩nоNib&.;T> &'egg"/*}/a•Vb0~Hc7I%ENj J6NSf*& Egƙu%&SCj'4M_s=v>EkqҊE.VYgYckY;54 S>dO M̛gMāwfhS@ `s×jYľ_O0`k snG|GU6ϸ.$f$`| rMgdGff Gg@0Y,,p8g"&8:q(Α&cL¶KH_3_)>}=NPrjQMG:?A= <|6~U5wH7|a+Ȯ'_睯3n;T; %2xR4p2 M9|?>䪟}iam}lO>@J~*QgM[wضA5/vf;lH/LpaoR7d_/N;&''"fF8:9 hGGm:9 ͧx%鞴Lo=G!ۻI Z`nu펤w?A!l#/Gi+>i@i B0h*cP 5΄R>Cy42iFI93V'7e}[fEee<ҎGAG߰EYǀLk/ 3x褣q. aڲ :̬jFqtBU|#-h.ZP AWy!@Ng42k`j6)'0rxPD]*dZ=ZMxOJA8XԡaԽ{t'))N'w+|%H|\!pzC{$u9)=Uys!;Oy)<8":7.0cwB(]qk?{4ZO3m(1/7yzK,a2MiáL{IOWEendstream endobj 210 0 obj 3009 endobj 214 0 obj <> stream x[[%7x l!#;Fk_W]v9g6+!3=U_}U弽B]Kկ>_o^~r 1^'+wJDⵋQh89t R>FߎJh9?NZh=<'c?}u~~8a]^]Ko1Qß6kC(.o+~)BGCdL4t3}T6JLm~ ,UvϠ\ruX:u(V)GeؤHwG[d"GkAs_'0F6ᡊoih;rM*E(. O6ȋ%ќp*%]'RA J'W 5:j,pئw&xLH WƱ{o7{Uk~Y* Qtd6Z ?' ivHuFw#Ʉi:Q~AS'~Vˍ@e?RYGφ6ieȲ'&ݙov듁#˛ 7Ι al5 X+lzw]IL8<YB g=E"<3 /VI>P^֡vLHjlvrl iᨃeiJ052tȋRVڋLt48dְ 1Ȋt3<|h yq_E©a0?NL*A\j|c6)S%k4z"Eܱ /9asv:}93bQ#v6rk\ЍG؉s\5ɠ a@"ʍ}I<mH'~<ڃT'hFbveڳ=9?!vlۮa4&}c^[2E&gL V 3dSgqd)|BƎ`O9` PvR%h$PD#>BkE'Ic?^-=s΁K}3a 3$lǞ5c#W]FsbрTw[l4'\|2^oK.q߬iEiuX8h3W&!||q 9B fKa S"$z%rT/Iۡ@a%WDrc9sThA6:(Ó,(0x^mg,.>v#nvFXz6QpQz›"v0lE\v$oeo%9+4[Ռfb2A[N4N&\B= , dt#)'F9a*J'MϳJ4+dܘJ G&׊em1rZ^4u͑@Ğ  ˽.jpAFQQԜh A09qtPS\rPdK&PLFD_hTVb\ *d*QgƩbUrH[M^I[@ <(ۅB)N qUdv.SkuX$ -奿F׸ʭpy>f萨aPv4UIJ <@h+WҹOuR~9VSWz&52?HCBKQxk֥Z<$~FH?M鬧ǭ+М}wUUQ@7Q9.IZ"&IOZ;ShӴcԈmI^AC>:f ZX7I - yOy Ư귧](,VP]hh%s' Br3,]i֬4;>ըy@>?ZHDotkk:8A|H_,ϙVfS ,Z[0}4`=8|uzy#YFSXv PUݺvڌnt"ޗh{Hw)ڌ:{GzQS|vJ:)ɾn{Wxő½Vu%5HҾh#~%& xdw؎O߄ZKd~k;o.{gەFtYd&+d]= Y|`vrj57ϛH^?7Y5VggR߿z'v[|J%rbE)q]UZp|(;7`Ə~fe$Te|]蟡QȝrOtxe[t;gHX|T9h6[T9[ګ$qB1q.j&gJBs d}n@jmnΛG7-5ƩJm$W9l.UtZS@\MqX}.ks\{*= [MQ{"\$&% C x^|nŵC_FfPj wp=7YxZԉtM%-Q $u;~?<,}\,j7>H_iendstream endobj 215 0 obj 3341 endobj 223 0 obj <> stream xZK9H #XMBJKec"8c{c{ׯ'SRJ'‡)WWR_~P=BKW>}}wg:zu}L(g/; 6-[f12ĨsZ5r!= w~ ;) ˫TFe|+.긼%*#ME)\H3/ov*4,avny>k k'E1dD@ EG˗~p8mGZ: tZ.Y+A; -9s5f8m}6D\h{ LDZa2>7 , 5>7½ﴣjaNC7hI#\0+̷K"kbe,ԀWΔ|5(-m߬myReQȐP4^ֽ>`f ВޘonOk a#HpWvh4!MB'K~,/8Mfo$Cb~ p=UXVbL];zq[ KXbm EqVihO\=Z&AXhmьqsEw˃pyNpY/h"P\z[:=,tg2!:ASdHV3ގKZ9YCcst˯dUA$3yڰ5㚕8Ky]ϒR f@+a imz$,#v q>i i&%@|GF;ʀAp@-d8 ~^, %X;orj:ґ?f}_;-"){*Ɍ;r3Gԡk=Ёz~*l [Gp& aVJ 諚ÝH ik?xma(.wy .1_NlSw[t,zRN{:1v+Bqb0A24 G' >F, G wt]Y]1(UePqL 0%G9N6KΡ *G!_bUsK JElncn1M6}y#!F/H[݁Ruq*aUj:d@dx0jͲ!sϩd47<{Dڨ N:lj(:UK+y=ks(lلL7vNn)6nժ=*=XݚjkX<KtڇH컫[2˵ ؑTN :8V2 y]xR}x@u&i#Aofy*JJ`fy "юfwjdG+_|#3@9nRtmm$ٖ3|)t8Ls߲Q 4Pn(0쉟vǏY|uq?͵endstream endobj 224 0 obj 3076 endobj 228 0 obj <> stream xZ]oퟸo7]}u#P$G bK%%q~}pp+Ii ^C̙3CيAn=}yoo6Vn:=}y[oqN9=z#s{+c_^o! kv^ (vfp Z{9`޽Ԡ2fz'eO/G#vcw%D}3~?h}wWvgi@+ (-5E!F:RoRovI NIɿgv﫝ո}}F+_\:a9VJK_rC؃xCZmwBne }X;#46M?a_qFRo6-z?d~nt6n꩷8: u3Uvsj. w#䴰Ke#վ[j2_;X2 [! -WU&ԸfɞM';`x==մ]Thw ;8vN2bk`o&U[h6 |T^{1YtRZןZ{ (` 4'e ^S~txI=b{Ou ;L7w5a&@極*A8.F_#=3\]M2rB2\Vչq尮V4% D6``s@z` __M( @ mΜ7s,pS #㑣'#! 7mդG6DPWyJ Դ;MoC.:;1 ^4Sy|##{j鑠w`}@R*٦E%&N$e\\O*tʾ$#BduH7d4q\((|~ThA#1TѮs(*֙1he՗6.W9``0be'OC>O^*2AܲN(ȸ,QiQZ $*O;|AH{ZQԜ3R6rTܠ^k2/m8Vwz䨛*md Osg}n $,5hio'U>k\! Q1m1kO KFGLܣl YL)퓦?xGOW̔C_ti@'*Vǂ^iI`j|/-ߍim QHh6[ZmO0IT=ҐZ@9B2b`B|l};20ffL eUydCUO+.C6yJh':F3P._G5FĴ3(&!~wװyEzpV?F9H:0 g yxC6к8~b.O` \lX{Y>=T| _Fl9'hvsggF?TR \}}bt. Tl^kxINt3S)j7̼\}D&#?C!]PBqbO&HYq$K8-sq<5Yc0"x( 2Bx™gKy#qh^$F|Һ ԗ|'VU|\ SB<~h0V@0'lB$h1=Bҥa3/ v ]Mzd}}K֪9OrIyzёϭ5ui$5&⣊WNGTִmHXy ^A:Jpp\*Rhz<mG,'+c훲y{;N޲ u %oש''@a.Tk/x̢`0rͣ{d\1I`fu}C@j (dWN"8Ì.є eES#SOdKLT ֍Z^(s6Z}Dʞ) {ɢo?; \'wL~x"ͣ1AŷR~Mcj-1\Q-TL9sN$2ͣhYe|a3p)I:r|>NPY~|lfSjdea+!ej-Ag'>޾{yϭ<3??gVg9Z> " C3*nY/wq[`B'C Y1:LEC&?c* hVFg GxM[[$HTlL Ti;@@/ d'\"SM4wk`sY9mMs^8vPTV:րX^tD62#r6MkjRjBgcڢ$98UsaF+B(soT\[V=XDKR5EеX/sh5;-Q\vzt 3յ5UXvuͲ6 VYK +ECu6ꦷ+HUdkkWQh̵2t`bbB2f[\&`i\OC6xr>R T 9+T2I!K>\(K"`CV0}9"MMhH=O"lyʃ=و4 ĬצJtj.]@h'} [W>(VJ^W 7@Ar?d̲:[!if# "t-a I:O'WRj|,b{z~/LSRt+*wo\V&xw=5#YuDOِ,!;!de@W!JC.\Ҍ-x(XR[R 57YLWrޡHXERF$s􆴒wm y:׷~pg)A_vk$hJWap[X2rks@W*'5xmޑ{eo5ºd%$c9 S]EOLsNC>~ʹMI& m>3peyi.zGM[<-ǻ לocSYI2=ul=PΌܚuwo6ΑZ} ^~hzPZ;+'<ȓ>:xRQF)l&$endstream endobj 229 0 obj 3558 endobj 233 0 obj <> stream x\[sq3J?jI1 c9dDJ@x@2L,@T%.t򧝘NoN^?IwwrzO'r=< RrfwD{?y'Ά0)o{u8)Daޥ]#_DiEN_G=)T,~w:e&!vW('墎Gbv."ݿV弚|waALFh/2ge1I0}T~61Slm F)8~C|/kw/k,[Y|.g ppoo@ywwAЂ7C2g/V:Z5i(%D-dbf ۤlNje2ڳtjrQ;\;w=94Uv>te0f>mwLdL gt3R^ܫY/NnIN,I =v(F! R,R Ӓ~\a֌'OHy#'ހ.?^xu nN p۳݇CwqZ^{zw'IKl+O] '-u^)J@4 }OVP8eK=(7$ɐbjRQ ab#Mc>uEE?\ɕ_U*UTTtz2!4P%(,QNAihDČ.YPQG "&xTnzJ&,QNC2jȔW  ;8!F^/`quNp6VMhDeYV5;WwX 4yZP`a@0swmq p$V@*+{Yurm.) <_@܆&| !5Qs4^Es ]n 6Brct޹I’-W =Lz'߾4tGO8y^ db Lȩye&D;%=.(l35`H%9%\jlҲsd @[ѱ.Z4KʚXdd]*ZD6W ?vg)ݜ0=i"IPA>NByT)>هIY'^dc ,H8hς "&*⃓ 8Jcy҇[-2ApҿOtN+lRwy0aRvQR ߓn: Cij&{}P|.CHݢc֋MxUD3b*< P]G=WNzNP)4r`<5Fݸr5[͊/Qhm ;؅fW:Ctj$#+GJsX9yް#kDP5-KɤG&Nɩt[t @/zHnLUxr2d.g%ޚ fQ28g|'/U8ʂ_f  'v:0^"H X2S4Q5 :Iqi!Rޛ&%[6)ĘrO`޳L [\dTulL J,V+}9kqﶕ89jV!EݘQqQ";GBm$Z SU/k2T;Oq.KDIއg(7 S5rH!] QlqpDJwd"c<v1N1^ !n_4TC7aP?seMk8F'0 \+q]@-,(:$ubn*/cd.p~u\UdK=8s R5"MFsC[YbX&cǎNAҖ'Tb4wyqWܽRWG£֢瑧òxH͢Xhg?Lokf%˶eM"Rs}h5A*1o$rY!e7u-LTi=֤|OA/idrU̜43f7: f3,o (zpW^9ʋ[?"T$G/o-Dx̜l׀ף>ò *Ȇޏ6ƤfZ_Q4|l"hrWgTn5vxDj #@[Aեm&F`.++ 1^+Np#^@{j^tLhR.dtR)FĩwlLD-ĚUG6r*Jֵ+tEi$">}mVnAkn ,NF}G 4X4Mz㑦<.AnX Ic<Ψ1.%n;,^ WolpegU&lU4jp QZ4.~҃(&0Aޞ(T̽v WMXW”&̴$ZSdn{i0 m'c wjji5g囗&jt8OyZw}m:m ȽY.j~^ n#XAJޭI #J̃^xDdp 2v% TXlFҶ7XCm*4}n۶@>6n*C nڦ><%Jny]srzn͐npᓦqͲ'3@dImtܐG,}n?;89h=mwo )SE9OD;-:OP;ӑSP$DA}dnrf J{*.+S$6൭2}c'kR(ꃯ꽷fȹU\2dD6 80b;_3.[ǐfeD*4jhh.OꜢoNG:ɩF\Z4,o_YBI%dRF\{Pvވ H&-f-* yeghڼ_tjKC$0 c.ŃTrmĸ5T57'oendstream endobj 234 0 obj 4652 endobj 238 0 obj <> stream xZ[oI~7y:}f``۱e wZ=@btWWW}U]U3ns&9[_H_oDVoy̫෍L“7Z͆؊3^XL{t%\j=`$m0dt 5J1U.9i~L·x0nha҇wH™($BDل콛. ;Zov *W L@NYX! Y: IU,PvCi/uSta?UYx4[*Xf$Mm^aZG獌h%M]qE!4Vi5QIɦTe+p`D[aݶ}Mx5`{v OPy@F^ds#, Whc)P-XJa!Dؐ J JXHyI2uҬ8j)`(Mm @(b470Arm\҅ H5!BMK-P Iab`Uy"Y עsvi< BC Ȝ6?mNC|r n5|&)fW" svQq6ӐDBޭ<(^e=xU>^ )^n>z.0(si (Ҏ覎贮8:zV&W U7U=)4<[!OD8I!vNo{505IeOd BBfT}Sil}SG;y?Jnd A1k󾪣?֧py^i ~qEv1zYG늽GME]7тެ_Z wR(ȦU TЎTe]8`SgCwRy\I昸zrTG%WT}b 0<,2Ta3RVX7"əKYI M2lQ^ki$&t}-era cR%1!m{˯4H'K}~^RvUbu(ɇCzt'+<ZB5:$X6~eS G)۷flg4D eh+@ N=o|SAoR,Yf}_zǂ0̲җ7`K֘Ҵ1s7H'D+B4fQkJȵ-)[ +Uهܤ2"hU:rC#eYnr4!𝂰6Mw:Y\W #FOB)FgzOȂe!/pP9Uc JQ?l)A nŞiJ=O\6SnxOHJ\ (lQd|Ӻ{\GloFy} =7_g95w!pMަESTcd)xH ` iAD7 l*9⬙2ؿ^>h*q"NXp2v |:OpXȼ/a?͹4>]/BilqwR A3#ΣeS}]+*xQ@ς$Iz4{5#./<[D$B[]rS7O]`*Y .6tcX?Iȃm];SY}KdlWI݋эZIxjw pIaq[ͱPSDwX!h np \HTuRwQon:>h3.qݨc[>0Qs;*ICje9ܝJ#as_O D^4^ѹGùK#k][}ިCYojxZǽ6|ݤzSmZ<~ҝq.HWHp A?HQ gp83@gJ;[5m$y!W/ ,FZ6(jFTҹ$J6-/].l[̋X,/}9:(ThU#ِQvҸZ*TYew$ck@HtdPIPcz ue,\`Va\&3|RJ xeSo'Hӧ=r@yK,LBn~] L4gG5ԕ\vo)kϰa,DfJ9xVo75zw@9FjlUш>H7"5/2`)*@>v5bMc95jGTMj`7<EM`]h,|譚+"3&!uE^e/ɇ[S5L͵V }S> stream x\kog5?~7]@?NIIQز#%rw9%dYBdû̙zgˣ{Qj7G?b|{sHCtʙoGr|;66AᗗGlno5ېC_'Q#DiNNzPZ8=ox7ʪ^ B^Ev{i"EJ}IV؛x0Ƞ FhgyYKӴƐg|noDqN&Xa0uۧi˜G#уSh\?=hA5SrR5(&H g>$n쐤omc}c; /iԝ_AAj_Ԡ9Bqbr#`Jc V{QFC]I=i%vtkVNsHkY&#h^yBqdbkV   BkT&T9hfQRWcV4FDj˰5m=&mSRO>zL^bJ9\%ː>s:(QϥhG5D\Jh9#z74*)@_303ڂk쵃+ށW0We&,r*ur2F|ı:[ @fj4"@AL 3^0dk76f^T@ nDVPPv6y$' [5A!0m&2\\A@tf)ofmCHT;50k.?11 G$]/FXҼpմLLNSc/VL,5I Qy_fTpUjbZ$ycee [%{TLAvux`FSM>O82|eBZBU'|V]f CͲѻd$-8xe!l®G~G5PGB$O ۓxfr9=~ʟI6De3Ë] ̔ cZN:]󐼾hE&? 4bss;fT\OawGZ XI*4´Qy*3ZZqKL*#嚹WOM%k{؀wm5$.YH- >OR3kb[.Zct>hLǣ>Jgjun5ɬUyeRe* X } PRr9{,6 z Ϗ>mYKYi}ZZߕ}i27_𼴞s>#:{+LգHI7J|^^8.?w[I^jkzx۔YݧV#SrifgUXe 38،?_֗+okfгvQ%ߥ%VT_A)~:E-`R0]\wY@^hmk2?%0"(/֗Ż%LSa`JFZ)Mz\+4sq~'9PcepSL |(ޚ1`PtoF!%P:&i͠a(Nj'?K;'K IlG7\ԽHnM)({j6Ik(cU l3\ۻ38ǧ*#] 7w@Y*b) k$q19PjG$QJU[R5X"TfM#CO}}OyJ&?Hi\9O*YvKAwI),_-Β~E~^'%r tv>vR$H֖4x'g$ Z`"#!y*.UU6VM:ތ ;pġwGўa2E7OZ JJC;$4Hz O}[T5 -sQO,&S"~[&z)꛹RPUz?+?dP^crKS).eYU:fP3||>հU)dV} YClg ݦYcoJ^MUn BOi1,킉I1~t,+CmRN-En)l^8Kb'Wp^Lk:Q%);bLa#a~%M"JFܵK]pxzuL9wnggT ?^ ?vX f#" =jb;IGf. ?3iU@_j' - }JksFIw-boz ^[ jMI>*1SWsTUuC+id5!ݶ ѨO|caL;-=PZ]uNtdr xoTAUYCAm%`/yn]teK᪯)2}2 :S8HȭzBMMȽ{qc.o21"YFS^]4^hީM_J: !v'X%n)4\{m<\{xתvj_յń\;2R6y_T?;C9`OB}I)Ƭ2@#hvajl]W3ה17SSXU(駚[@% Z9׫lTN՛U`SYx,}c耰/J\K :*3w$k_s<`ZecVV3b. a7gu.Uw0 (T;l=Z`DݨRGUm!zɼfz&22V_Ah$r؝WQ@uW0QŜjލɜerӅyG\d뛖9̙+k՟+Tt-#^_`AH疒m?9^n "ol4hRLw &>,Sb3VUkԡtsυ7'W 7 E`A@V:T2%Auv3ݼiOpro32WJ[ŭ>⊒ XKM᮳m0Tg:j_ 91ge6uv.[U3S9S !> stream xWYoGyAvWw!LV Qƶm| \)䭩cnZ57]6{c{zܖ3u44>tƅڬsdžtr9>%mGnuƳҝёUA;ꏎ4'fv+eCuҭ$;C$uK$u>K?V% Ȇ5dd:zõ;\0:z9 )g> KaGV!`bg1n ڰ CpB>F8|=%rk5[٨GKg٦ !)!#l%QO*O)i%h_\'|: 3BΚmvLЙ} UHE^ "l&g6wURv6Iǃ1x,v8b҂H!y߁Vl hՁ 'bȄ8Vؗ>@FcU RLp7[Sꇵ*J[qhb>'K*AǢâXó(hXɕ Şn5'SZyuD^G璮3tMΑƊgmNl@ެH5x 0cf *@dt`D!2`z$pENQc dbDzRɤ\uW Y9T_"R<R{Dq}kNd9Dn)yB9 nr85N Z`[ؒ2!%CU&P9 uu6h,4U"F7h\i[7@GHpw<.uOyVRoUa½|LN po T9ٜL M.7:xA>f\ ͝J By>ڨ5*S&( cQ1$T~>ESM|÷z*$s<P>;w!| RAgKêgL=tP^2$0tp},UbN gh2`#%(,ok: (F!q}n{K?kVB`TªԊa򋯦fE{pR???4Ý_PO_PXhP \?3üW8ZܩVPeO/Jqo4>O dendstream endobj 249 0 obj 1267 endobj 253 0 obj <> stream xZmo6_ +Iغ|Z[ "HWԉi #)鎤ON6]|(}=7J};.wz2z.F^:0z3z;ݏ{z.blDƓkVWaΜ635*+1Fv5!kdg׼ ɄCUPJhB+Ye8 DeɖyQZ0%:X8ىkQ55)c77RdbUEm C]8؅4-ziIcjX͜IpTXWYcQr!YmPLjNkY2۱]Ee>x VN˾a ZعҲ[qcd fv?ԥ-oԍ$l keF 4}KdS f- dG0unLoZbY7RXz(Vat ne |9LtlrX78M챳RrA]ȼ4OLXyC&8*ه3#Q#$VGZs F&4 6~ F''HSm)&02a#08HiDJ޺-[_`:,E_BE/^p=OQ<^ennU5\\2B3Udp-%L Q OCl>NtHuE!@,YRq`X/ :{OI b Eg6"*\^.t$ غ ckT,8I)8R9%<ҏb ~,[[wA֭fP^肰'gv(> UaC,d@~?夵f9@j ;WA^/Cy|`B"Ub}>àmaо|%<0].^_S 2漣igKɔG~g%x$Pu,2[7*{n蝖Jm{e'puZB:- nH[XF ɫ)yR!F7A:\VP @lЈ$/mpwAKm(1l AFBNj!|GU mwU@o sWiw?A+ངqjt@I.}ط'O%7莩 $KwSjE_ }5U?bRbjؾă 4_@AEMYYb8'Lzgz~}=%xYUMf&-}kV }a~#t]6>^1=X(! SG}*8Ekqo^4QY(dn=VtKЏObJKi,u}o׺kҒUM?_>cq@~>.|qo_kcTendstream endobj 254 0 obj 1797 endobj 258 0 obj <> stream xZ[o~WMwzy'%ER;H)d],AWKG3\pGQ_BrÙ j1/?z/oRB.QtՖ?iJ32Ǘɋo|-+-HX0$AekRwCݤs 5(}`a,!~Oԍv%"7$CZQ;k|`ިзW\P`""z'!EWć)foIhØDK^. '-dZ2^y4eYͨ2x`:oeA=(RTmߴOwr~Ѽ JIh\#&B* <9J| BǤ9^fa`R$ $8OU7 5_$3/]c/f^F9̳*StܤxG[TL>eoZIrM"e; /pq̼| 縕{Q֮t6A:'8h|3kYsPwM6KޕЦr 0*b)7 §jHN? FxDk nc( n m=[@qP*șVt=Fs4]?F߰[endstream endobj 259 0 obj 2439 endobj 263 0 obj <> stream x[[o\6?bw/MSbGe6,[HQsxQi.9|CYK֒\}O߭ZG/VoV*E{uс3ßV*^x'amC\c;+Bl Cҩo&ON 7|Vl,lN;R6v|HTnZ4mn&lPA#sTWz^D@!mmnm4#[ڼ؂QjEH'R6W{DJ-^NF t8 FuX_~~(tTBF,Xq,#|1x:j%{Z+T9x5MչDF4D1>*uyDdANo6h"c*턜4uxLœd^!Sw j%&eHU#NOʊCm*U:{^g;YHvA;WJ )BY02RSfOꐝ|g\K<Vu\:Rf5D%&^`>^ >24}i@|Yuq=&+W_~.j&Q7j^ճN ^(ڷye]{2a"97>=ef/e%y,fZٓ)_{(O&)5ieWcg45L0>ڇuqӣ2:qYg.?43JcdFPM a(49%[SYR@1" K5"NHWg)aI>}l{Ua" T_A*m.U^瑓RRGq sRŞ>*j~-S;G_5{B-˅ֲ)-oSinNn;'jKNTeSlV殼P{M雎HZڦ^&OG%~B>&2'B > fX.-T˸| ˆc06^&zZr"1!|dE^>BD 0\1JNl(pb0@ec&4ڒǗ E_tJ2*C-5^RRmn0Wܾ C{[ѣ=+%^u%U]\ qCH&(3Յ?U*}"G׃K,c=Z.,cFۂ9 ['$JV ,ah'8TڌBԃR2(1Fٱ"EۺCs2uF \0e1F,b+MHdY/m={]xCѳYL==^8geP[UT1^9vB KՏRŀa5KbAMcDGMjP cjQoّK5]T3fG{WDUC%" #P Ee|szzLҳ,"&ڠ[^%;X=Z3߿?ꛃ : t T ۭ uRt(ѝHۜqtFj^̬;+KMI3ilȬ ޶~&o0X!&hM8L`I+g QOOYE4`U<0 @ mJ5܍Uy 7Ak/˰* 0KثCg uJF-2u a`2ΚKS톱J$,V?tɩiڽ.yξBhcpvvhJ[ X݈_`ݳ [ 5m>ҥgP tOkxY_ω'ÀOHP'udzlM~nT~>:̺AJwyF74ާ+dVUF7,\ J;+:=k|t$ʸk&F,3^dƯZ䨓W{)7 ʃo>7Xz1tG9xB/Fwxk{b֧cɂpzhrAygO`C.yy4QӬK/볥Wt2ub~Fvk#vരP۾w9*_zPN. ^Q\q8O'41rᶦK=W1> S:,o@|,X<b ( ݎ" HpWn0caj3ޥ t˙?XS:1V2.Xd"a&"8Y֋͝Q 5S$T5Gw=vNȕk#stB'0& {<J4|u۷9 .dm5,JDBp 6UzTq^Ow)A'^~eQR Li a `?'endstream endobj 264 0 obj 3317 endobj 268 0 obj <> stream x[Y?b{ pb@ۉ--v`v]i->Ul6r,.GrlP[O.6&nzyQYFo?> 1nH^{=zQeS".FN$N`Ӄ(=<)afxkvAKXninvFXZ8D/`mX.5 GӼx S4%cJfx i8wT6Vk|F1':| ëJ.5_G*͙EG80V)Wfe^%O[dr}mRJpNWQr3$M {o꾥WԼ/zg dH>`IM@ O8C}Dc16LÃڋFx?O;*}=YunY+o{o8h^tɾޫ4ϩ15Jj\Wt؜q? 77kjR`y}.݌ 7KNhp2b8JZдJ'XO $bhfcgM{=ޅ_a/s䦥(6tC;*gh例7430y:yn$GӋJH]D! c/' N8euY&0=2\EfU/4熑9@#{rXէUC"-.MF*]a$i=ME6hh1qSoʰP}tr0qVH̅˰GPf9p !A}UEOƃxH}! `$^֋I6U#O7.{d )Cܒ^Ng' A&;Ѡe6IdD8r18?i7m#;3)-\Э\Ԩ1|BfE{B|g5[f 'oy&PxK??ɴ~3ҚdLJ$TGMJ|5kPs[U(p4Zb/U&2iܓ[йΐ YU$N#j]88ݡБՐ_`ǝ6%H&G 'op9$ %lϐ[a"s.g:B\_I)ރh M3gdEgj7;o4q܂.u= >K~ҔrfLO15ɚ/#hfPoiIwUڕZH}MOHQ% q0:I +`gEtO(#$'Qj蔤]3;騃϶{#(.fU㈏v F\h"AbXFGJPc7V*p> wJ|_G5*.Eɺev:QO;ZWs,+=D*1[G%xXjTy<9TiR  , 5ªНli 9s d|cR D@;Rq%Ah+yA[sc ~-B/@hq@:Infro$(G{721,We,p%~Z{DO `?aY!w>.R%2 d]΃'6Q"2q,#x&>P6v ʸf8zu/w5v4%҅q t +LDzRu.exRCOz/L9ʖNO>>m Յ#Cy]z.V6[Ha Db"zv_C|$UqneVcV|Jp|?}ևE>߆mq6Ҿc񴪝'|:#-[6%IK;ؑ\PWb Vq.:Ę <@ShTHݛd!5m-u<Wbӿjc tv|IIRBK ]>l$57^'$a*՜Nazț1,rQg]azrr-*`7GQB WMaBT O:j=m4[ V,%wNZ1e]CYiNg@4bsXQML{A~>\z^-l*ӎ )'F5'W\;xZS4W Wbe+^V{Sxy$ZCnSZb tZxNX-ج^ZTRMBZ7gNn< 㵩j})Wz4 n2G"$qgTqw.Yl!˥FDŽ `B<2ۜ{MEsy:p|&bZ 1xת 6\p?XםѲ] C aba %& |D򺣇G.,N5T'OC-6AOj#KIe;K n Dc _3^ d)rr hwUm!MyzG`-Z\[Scrn.@Ul`XW Slx(=ZK!M̿3;hJhk7V(*"Tc5 M'ԃ+t7r^OT5鹛J;9eKa)2)"U͡Ǔ)1 dוf33%x1 |Xש,mz;oX1}"yф߈oZ'+_"1be:x?5[_7eN9~8=*R j5Oxxh^ely#c|v},"d)pHY-5/ {[;Ch5Y;{Kߴ._̽]Ǝ.~3}8a 7I(qY!|+>/RJ/*04+W({w}HFzN@) o.'ZU-1 eS3 OXB/t9WcJc"Y Q;tlZ1O}4G >&95a[&&k 5E\&u90`۫;,^-MM+=>ՓXL9 S'/xz{qhE8J2JT ,\78&iڜ/20p#L(y͛ҐW*7q5[pG_lonm~U}'ϣ?on)[i)@-)Sf`TjğU r͙ HijhlӏW`Q6;HmfNdԼ-!{N949~Nr|Q"Ib>dtcMjk endstream endobj 269 0 obj 3491 endobj 273 0 obj <> stream xZn}'|WН$o6YD!Q`P$%"ksgz,0@:ujX Xѿѯg>#]PuW'xA<`;>yz9) \kg?۹r>"F,rrwv0֘<=WCtƛ` K~|?l nGYk&j.vӠ5W{78eC=NqZHC9C7-w7AVCicF35~ǣcBϽnp~$Z=р*=Zf-sEɽ0iOʘZP=tͣ]u0" bBRz߶pqP F`dzΣ]J_0t{̨Idd 79cF]a+;P٢ |*ڴU,his;(ʳI"Yd^R"QwF_9yTxnT"c(Mhا P`VJZi 2)}3rJ-Z`C oee\uK|<Kh "[ _It?W"l @kBb(W!0Dw߈,X&, \/4u[а;23/>߿d&!8!FIR$$|H Iz[fPpv5EΘFx}{FQ$ R<Ú1V.HNPW-ͤl^X92Zv%lB0dɩKfC՝ @5=fZ ʳm ~obqytOqfvff,q\K%x]t޳OdzlI^GVH(h-8s?C kV,: >r4Rv)1i%" YcJj,%i,BlʙYRIHޅs_>Ə9n2cRB× "Bm gPvcI"(K4VW2} LLXd_ YnYjhNd|c2Z}?ļh#An"kL%u$^׶% 7z6c]4hk {EXS@mEkqxԙn5d3ƾ|V8h,SL e<;s_ċ~CWtE=Osr1Yr?A~ѸQ`{Ϡ콩u\9eN#sXTWRJa=]@ (BݟDNEbsjZBOX-Ti"u(vruWvJ_wKi3,Kz/j#QbK$i1OջGt@j!W+2wh%&(JJ]Lu\W/bIA31<~:#6辙^ҫEؒ K*G5; ?+(OBBT۬]1eJ@= ?rk{22&Q '{-:(PٍLOVJSgrUC)n?r8) lzi89VΣq)䄳L#"3g뜬4"&M!GC: ـZD[zEUG_OGkۄv-r_!%1W)%ЂD +l:)tϿj"FVKӚC!rsn_!Tf!;趙h{JCMXn&A{EZl&e,,jy%a>`ҹMxW}ca{Ѭ,h#,X\t= 뷫% _U|>Xu5pQFU+oHm-M[EE.V5!"эFeS> stream x[Yo?bg oy Lbr! (IקgzzgA jQWU_ެPk_}g7ܻV뿌_VoVj9^??b\'v}rNhR\_^љ։Hvw^mZ}lR[۽@KXtUдw6FXٵ;g?lu0]L Rw'yA'->Ѱp(LS2KHÙoS`kI ߳}O0} \]Hk? U W' |OFqRnlbqA$:_BJ!9zOs=ޟ}3Ehzs𒚑ߏ͖hJZͭJBFCnqݫѺH(uҀR yc#HGLL@Z.-[A@Z㛐zxc&j5v][βdH膓#{.ugzGU9|&P A+)NEқ—F.z1jzHvnh?ꘚ23|Ł7H(MBIb :԰ ~mY/Uj)=z?hKG^rC nG˿h'X[@ .1`JNr3FDecGujiNF%aQI`g2kHnFՋ՛s,Ԉk BP1=?X=;fjO}aaOžyatK$)]BڐU17.2Mr+lCSG,~kF9a\~L-&t _))]61A¦}fVNл؞49W Ez!JA݃<bO/^ÍZ2/I! d/2ܤk#=P_.]s9ezyȭλL9UfR3r7[,C%YNPд ϙ-&̈́ߐh21aȖ4hWUM3]bZNSє GIE*!ӵA|S?7J"4ΚsǁrV F`ͣ1Cz)8H8#KOJdᴘ2<ĪuB~2c‘ccgzBR`X/py:GQz%Θ;?Qy_ȏMu"CI++[V,S;'yqߔf'ɏj:ٴ>h)+MF$+t 0·q*ࡩn'v8bozsendstream endobj 279 0 obj 3011 endobj 283 0 obj <> stream x\kyE~s1SҸ.ծ5Z]y3$g8+m `y8{y+9z}<)_[x"_/dQf Rrp,󽟼`C~yqG}:)Daѥr."7xOg=)T7t7ʪ&!vYNENgb2"=U.xYV3/O2L2hu|s2ڹLvj0&ͤSLOƐ'0XX -%~Fx'($8x,6&eN|Zl𤽞 +l!=xjW<(4g;ϿKg,fm|Jb?i9I4iƴ֭ħ.kl;!*-oV K& +/)]1t¢NBA2\OXtD)Ikb$UEЯ%HUS.74U1` 4JF+`>^/`5jR[w5n:IH)`\ P`0fy)ch87+OD , sq4SlC0B:Jʙ罕Օ#-'jkl(?bJ!+!LmaP)q\Uf|NU? @Ii p*%jV7E0^VA@ez=!5fj{~RtO7I8a(3(I;V6@۸"|U1Ihy#DSѦTdax6**!41l&L4!v,DX;* P6Xv>ʕeq] RU+`qQCڜ uV XhHgGVQh)x2 ^9E fL1v%,2/ l^DqR@THy:pZ~gdT5aOaI[+\0ŕG=Wc3\pзCL8mQkDU=Feރ| :~&ԣJe6r)9,&& #6QV]\Z8f O Ь VI " HD{x5j~<Ў2u{B%ns6.o?'`K!-fVm7qXJ&R5F6%>W'@@5%6[MbӉO,G"B^UFp2AlcqdfQv~Վxy(fsV(!Tfb%c^fFa$<'/c,J4ܽ[w >n:ܛ7JPĵs^fʚsʺTR jD9~Ѐ.+d\[eUX gXi𪠀/˲md0 zeFB xFbPGQv- U*~?qk0~6Lg)ur,>EKVb8C7QTً^ZҰt;iwTpI^"w6]ZΖҴPfb 60uПޱ2>o˅F;ژ%eva߽vWz/AQqR=O#U=n]K3}CIKdX$\ v Ex द{{vd丈d.f#r f &ї*Ɲz9̌k,>"]a{׸OwInÙKm&*2O׶P000;T4."ir)wV=؟-_WusN}*tq6]HVΣbrlETɷ >UX2)@RC&nQdZǶZ+b]ǓeG1ʨt`;J}_ !WX$.Z5r#؀q{w);-AfD|p,mnQZ 3AFzP;Kzߡ<bbkVٲkQ;^ !'ouE FS d%V 7tVX]U,^a!\*΢`6G1sSPmddPR_,gz?* Q137B8TW؞ULmQ2 ɜs Ux u'9T O.{Sωla}_[wl[aT*eKYv#A ٯƁa[/'9 ]m=`g 3SE9 7FAg¯yfmD9$O8l 8@pL,me4TUj妝Qu/yl3#,fr ]¢֩CZ*,\bGom %KS\>۬6y̻EuHGZQ>uL?n5o\[WM Iw΅ xgK:WE>,?pGMq06Rg> 7& ԌKdg.gsu騕1g+Js͉'߹)Y V#\ÞTM2qTӏ.ĆRݻ1vߜ5:σ44@Bc#nNܺ>U{Q%; %R. O)w~y^{qD ʱ)׀]ܔѪԖĜOVZ]x`OLFf[iMXawz-?ĝ:]0H {=JޫN;7{504ڧr x Br蚺;+ey9-`m6#ł m2ae"h| z(n 40>DiXBfÓU/0C;׺T4b߻Up->ӂjYzTT]w2ʩA<2akwj~?HS'⽖dYzWr10 ʹ[yd*OhhGdp]=p̓{x/bجvU6\~tڇ:Dd[K;Z0Y7ֳ_խn˂\W\FWa 2V@GohCܧ"`g[o~S0 5x>\2x΋6Z 馹f|X 'o^SFی^Ko[VsǜmHo :Ẹ7yM -duwu؟|wYκtPE R/iD#JB˱AT}H+yij W&CtxURsq/fیFn~.²͵Չɠ6gmra*k (M^3:d7AN6ump} /3, /ҴZo1IF cS/h?&oeC!ox^C7R8i*\n8xy I,^ŗ>{ŗ<ȋ/_sG o`)3"o-!eA[ۿS߂dWѫ=~EU{dhAG>^xcD$vs ݼ,D'v VRw:ygI$N/e>y7\1J|x˴1 E5*+6*]ypP-t"]O9Xv%l䓏 qw'8 ҧIvJR ;&҇<)̘ p\;bmN%뼺Ͳə)G-D:N\:_qRO>搯D *ݵ\WCy-@eX.T9- ͦL]dt|KĶ}]>LPEXJ~Jt^Ͳ3谫̏u'y?QnVSL>u_hxxmBaz[tz'B43(UgIgAMV[g<2pB[ 8ȅ{TC<ט"IK5d ;I N.g>nz})> stream x\[\$?bg(<!'@BjS )x]/ϧ[̱wI kttiuu_n9[?>v[bˍ3xm`Jg_oDo*I;?7z9-ܙ˔q]p{?&vwߗ^I.]M={{~W9{oy[1S:^flY"8t!gfƆU-I{sICw/΋9i柵.gW,Pcv q)7{xdn_/["7Ge7{P#[a)OC巤d;9Ih _~{)Ѐ03 \2˝N?n(##POݗы9SWjt[UZV9BvSnNSW2`r ?vEh+9{j< KZa5(7*u]q˂DP2`͙EKi..@>)8ɂ_낃Jm_MmU%[=ǹ h!H s#fYF4FBhZ֚2zǃoHkz7"<⎝ =<=cx ½ @1!*L*V13ɐ\`3&p[Gw_/(4Mu&d?踂a!h2A^4*IT-`.A9op6yF}Z_An8H`C0{ s+=ͬS8(U!bVOZ6r73szU[S"e.¹~Y[G5mqe;mzozDAF >.e}颶K6&RNl}V[ 1Y;<:[*٩ľK%G?ݼ܂:X[! 3鱾>~wg[x6>~\k F2aal*5ИD隕 a00Lr^}/=AbDS%S~ёbM02ؔ:A~C>LrOҦЌl)Dz1Tmn=8XfiK6\ פ륃w{$LҶ = _,]4*X=7>bdzN4j$bL/κXqs,YM+޼,6Lk4X oթPED5I8V2uk:bA.%sv1XVm!@c|)⵵O|~eP|Nn%*%n^@06P LXpKeyG0Զ,'àjݳ->Zu5?._oYJ]R/N.^up=gd?z.4'2.TP-`-yZCVV񮷥j"%^Q#7.BXnB;QM蔳UX}MCt`% - qSXT3"4S[Eچ&Z&M!2?. WI:R%$EBR B $'}[`-(Q*&Z&e>{qxE 5՞35FϲM.4|HW̹{X'OC t:|*:Z>j rMɖ,Xr])k]n)ڮȡu/@&e^T0_XJ*f]pWbS+v$4?8լuO[)SJj~+**y\@tqTX-X%Blt#M_`MQϩ[(,EPo[\6J-RA8q'dD:ï0]TMJWX+Be,ԛ#ͱ8gX;<.+\W;;Ku.se%1 :*}iN>h`;Ht$ IW[)kf[@'Gh)Ơ9GPBYi`J-VS+tyn޴r`ҮX*;\LY71̉}bPG[9MNs)k↸á;ir 1Xk塂f$rV9'j*ȇݟO:Vry/!\B ;۸e!P<%~˕ވt8 9Z1.!"}IR<*Xo߬BB'%H:x`J`Ro_3;wv|+)*iʕM|~$\.i3WcKĘy7Njh/~pJFɒ8+ {O%"މbIƑ(? XYc٭bUV>[Z<4 זH90}oZ4u w2amߌSn>عUr^1Bto#endstream endobj 291 0 obj 3844 endobj 295 0 obj <> stream xYoχ( 7MSnUTI֮p@>=mGbrg˵$CF%y|ߐ~)ZJ9[l ˣE.an~~.,PzEBCKtm+4|9[njDMmoqȕh@>u6Bc`TV;ݜZHeoNhfVBhbsZK0F*皋\sb}TF^T+TktsJ}sԙ݆k4{. ->_)a[kMI9lsLjځmFXa4j-B`5$!.׭i V!wo,Y6jނk`UZ8aN*64JghhL>PR) =s`4̚.3o>xVA5%ǂmm̘>cZCLtAu.vfkʭ#ԭLm%`}gI&LO_#PXA@0XMaCiXY0 I&>I/HzNB~jA{\{U)ꅪOKi,($}6 у@ Jur6<wBң\vN0Yz<W}hZ4qE:ܙBs~"9i547!S/8􄮆BMX)k@Z%ۨg#L xo\R :=JGח4M8N )϶jh40&r#{qv2g&/f9X9pD]G>C$2܌r# U/%w3޵ d/{EN#!{Q4V :G֜`7,쵿Yi'4r j0H7p doFۢ6K=z G *"}BZQ lfsTH "h#[+܆O ʏ;{Y %]]Łƌe窟\#³[*pK^pĭ"u-DCpv(@jU)<-耵]r6&tȀ&%֏1y@f/p ^7f/$_@E^"|8ǼGoo5f!9Qh}}joU4kH8=4c?'5A,h!zf!(k(4m{wr~ik(vrZЦŋߖ7W/b7>+Dkqȼ5|ԾVzo_k]gl4)2[ZP__ոЋyh(<ⷄuАV;w(銤IzYtAcqLw2YYGAQC;S̻.x-9j}HcujWwsԪIsfv[~5I=I-I*9c Wʜ7N8Q#exX<[N3QfUunmbũ`S87Jėak3_?;>Ɯ썙I:yXupз8EC>pg/ 񮫸˲! أc?\\b'9X50=͋-*. y+N}6ߐp߬):= ̹k Bs6c1B⢜wXڞp |ro26XjSߒ.j.\w50lg;$I9HB$!$I_t{r^$x[,O Ym1qWWgF%mqUЕ}_(m2U-gY . t;/[EpٯuIoRv.\Sf;V-PrbOR{jhf>}[ i;@􃞑fn\p =wc~%5ܑB i@ռ}4tX͏z1T4i^qxTLf|i M -<8Θ0c.ɘS&`Kbnf`?a}e`ȴc̅)g|Wy'-:cK^S$Jo oQ>6-&ox),w'Dy5Y=yQ/!Ad7"F͔SVoY̦NzH|?X endstream endobj 296 0 obj 2595 endobj 300 0 obj <> stream xZ[oT7~ϯFj{nSVTPE[VQlB.Pό/%@ۀBٱ=wIw6<֓FN8zb{M0fbUL|F~IL1_6v|:^L{әpʺnHz+-#{Lg0&z՝ty>qFZVusI꾞r¨]ٜ4F콜2IElFhS۰ nm'ݱS Vl($ J)ff3|w1aZ>of9ɌibsP3A3M dnouiO>#uP'qaa +,zÃ$$*5Qňyռ>1bE o}ԟ:P܎(59Pt2$1==LTS3.K-і7|;"8gpTF6LlPM*]@=&qHʇɰUjʀxOKpbI/b10Wjqc|8-qBDWY4 ~1 axt2%a+>4J~ԯ Pmk7# ר R@=88FNi&PO`F"2)Λq51J+2OA4a\2H<bB((GQ))|+mpdྱf92 /'4kթ eRDq/ zQP(p l2Wϊ5sH 6Q6ha4ZPc0gm:"Ǘ{'+ۙMC810w T3B}<[Uy45+dUOkU[aRlH?:ݬYSיx b`q/\ ]T!:ZwFǃ@pKB />!yM*!*ro s,E6Pb[PRinQ.^d )Gg]SSj]`\ $z<"v 6}czZ)W:9(ToU* ]KC%.#/9Arϩ4@MAm}vPLP},.@MLp=eۧ݌QPcyJ g-㺫- U蓊o\܅Bj53xqꇌ,S>=xtUr 9o?rqCPA4윚|y\3mڭ ؄zːU?;Kޗ3(\Pd ó-( Pl|Um"9t "g"ˎ*>?P-]qM݉jVt}=i/1pǶ.D\i?\T(F)8nw "I&hؔrZejeE}Z{(CccZ֗8{B5 zcGzI.wY#Lz RwE-.nRC Vx"s"ྦྷhœZdf8"œ6<}Z{ h Zx9%tY#*hgy0EsxLfs3~hh98 ׎Sг*"9w[D/#U%wxGBTinZgX1,{Dscewi l*EXMO`Bynˬ& -ڝfj~j^㖘C$ sgyYs Gz [0ޕ&ԜjzD">)~KAv&p=5 Kogk%Rb O7&/:|=jHh>o{ʿ (V^EF fw~KNWkܵ_éҠk{e(y~.<Ք2`۝:B]CA&;|GD9_??Wendstream endobj 301 0 obj 2057 endobj 305 0 obj <> stream x[Yo 7ܷ |ܗv IZ)m\˒#[v_3 v /~g!Fr#G/7Fn'̓},j3{r}PBˋmM}šH!F/7QccytRq4Ѿ7ʪySFyd\q #Lvra7yˠ3ڹi&;Ly)z !spLŧE}UFA L(^ge938hrr܃2z52eE$}z g'\@/ћ.=)s`$iu_{Z]IeI{'UXL c8ZAJrwB8NXՇP~8x]sU1>L6g QsVʶџqe1 ^wetRli$lgei{h0@4/HkLWij( }@|np$S]̴^ &'G2W뭙1R%[)N&rq]5ax^./;A2dzhyPh󒔫(RF8@'|)[XGNCrIJKhFJR[uɛI)*+Q %SKGݎ\ҁڰPU6|DEא|T"ٖs[fnE `T:M}J?!(@^J7YR ;#Uj!"Rԉ`KiH3"gFKJgOX4=[+TI$V$:FoȲð|H@z5nŘ >LOH5 2IGTH(kOY1|BlՊBS1߇}MkÄ4N̓.(oCY,FB/Diy6S΍o7'}b$ENID[)w5DK;OY%MĚ̄Hp8ft^Z`|練J(qr"mu1 12'`j-Hi u=1 WWjt*3ߤ0Ʒ򎡷YqVig.xԌvjZ`Ies,*„\,M8_j= -PRN э6zu~0hO>_IDIRDyBҪJ*&f|53,YrXVݤ׀uJX$[h4I24hW.f$8gCԸ#TZHǶ %~G1Wjy|ѵq*?^)-6aBEʮ_1aOk-𠩷%r/8<m^nDAN%PMv%#*y$NcFzx\:֞K?*1" 5 D~>'!o!˱K=)P_T"jz,֟M_'eU)B䓨xX3\\G.ċ0"4M7:VEq\/I!Y> stream x[[o~W#s )+F@ $E`KĖN~%]Α8F ?hͳ f͹\ҿoί_suoT,ob^FX=۞o k_[`KdOo1& v:w/IHş!fušQ_\Av6d18M{ IhRYR$QB)3[KO&jj tW{Ի/v5<۞':A݊ pop6M6Gh(gXeSdne{E3JUĂɲEG6KI@3EYqAmE ^Zl CŀIV )CHQ8XLFRRޅYr~:tifλXaI&T/x2t7sP". 6#e ;7,XX.MqXBI<4)әv3pEߖcmў ZF ta'tQCL=gԝ蠵Aj: n.ag1S"WyWPy4@ph(Tt~%A ufmAYzv`ɸ7l$(z/`!9;w iwUk"g[/ˏ[뗭rhz 2loA>n˵n[oG14[획wZufq;" 7=֯Z'l;.gC|[=hY?=\@!@m]#jC Ӧީ\-uLQ#F|`+,)AI9)N1'$9BB0={3TIR 酓dJqYAdf;e㏡IJxAK#1y|4/v6kKoѰ?/ShN0)Jb.QIFfjKJuMA!βF2Ю`XW fSf YM` o[,1}^LŪQJ'WIC?9NadSU>긙:˵"?-qS_]n% EYis1.#G )uq!dDx@O=lrզjAa1+"@zJw@"LL(=>KliHZZƅUzǁϚY +Xb L4$eS!|xrn0J1}2o/SLy f7}eQ2r{sMkɑT>˧Q.˯bN\V %csp"pv"}X*  ArhiM  d Wzk{N$#-VF't$xFۋP-Z4V+̂% pkrlM|j5S5Êgł&nQ- ORi J͡}I 󿙫wCէT4q[Kcv3UE݀x0ѩmRɽamu\A5oQ-s/ؒ4&g YbiSkKqJ5K)KN(+>Hl+GG1a7Nq GK_U%O 4YADZhoh<̈́ap+ӛ̬_"Ŷ7Lծ!Va aUQh sR79oԈz) GI YׇJne@1vzǹI{@N{/s7Ve׺]dY!HXf/ݟT0yw_ r,(3 *eWW%?覽Dl ^x$b~wѹ[رRʙib^r'q fW/}H >Eۇ׭#iav]ـ5GAq}̓'U1lTauhu C.Cy_A`v':lN9A-"g k@rUcU|Gy)ӽ.0_]5֮aTHő9ǮS2E5FD1jxBұXEtvۑ7i(w*l9Et̍úvpo>R}} 9HKʹg,Xy9EQzFP KzΜbTT+:Zjǧr9|v#rN:JBH:FJdzhϫ0}e-Y#.Hۮvm }E}g%?8*j8 [M J$1 ƛ 3$aXQ{ݜ h*م&ȳv_f<3+Ѯ/Nw}~雭Q>ߨm?^ێ?M|V{%ho_ɷbe?L#0nW=׏ 7іl|掱e>TEquQ$e9͇aMėyTY7 G޺}zX*B>˲qQ NYJ1+&.?C,K&t5|bFmqAN"`b贲68٢\wg=N(am :B/6ǫ3/#k G%ԎϋgIì]7_endstream endobj 311 0 obj 3413 endobj 315 0 obj <> stream xZYo ?byANa,dI K#[6ThaQۜ&Y﷜-?ߣͳM݊ퟦ0Am`J7"s˭Ibǝa>p}]]D*Ü;Ť2G4e#gNK#q'ZM}|560\;papd 8lNtQx&ը4]=Iǂ >I7-E\j=܌ioF@z%a/@NŴQR4~ztv L6ybbW;BT : G[+cZ jqtZy wap7uI}8: R-h G0t/u]XLp 'QCʻ'ݍgv%mұͮ~HW\ty{ح.r0MwT^uOF;F 0%b* [,oZ+RRaC)I) Dqh}/aLyڸ]]oH` Mk1}b؈f^GBo*>:{(0{?56]}=A fMK$z-㙲"_K`O@:7vAnuԼL@0\7ѿJu*Ɖ8Uqg4KRx@18"k=9e\48^֐N[kVQÞ:?BYEe*hNyY5h;97纎F "ϥxᶲNz}́B弊AkǛMu8g- JfP0xZu&{F'SOJȋphbDwIP"8$q uCA1т"WgÒGtWts [ =Qc(w* bq«E˰H .8ϯq]@Brm`jy n͝"{N,xOk:/jD)-y̓jˌ+4i^a)B Vf֎VK>D!3/Qk曘<_^_p؍}!QauzpJLH"jU /Z Ӯa,?8Q+hޚ>3ӫu1QӬ&甃)sL\*)^r,O3xS1Z59%Vcwiƒ5IvƬo }&m ʗ N(G'M% Y=`ݰDOsv͸B^~4iqc i iPwd{WI$[K SrQ\Yqtk%j肫-~jvYF gd$V-ɗy#;9UæBQ3l3WL3RꅌBK${)#>EL,qkKK\{dNp '4"G'[&u^3!M?깛#O4G\zSH3,?޵[_]Jԩ_Vpf>,i]|8nl?s3J,h>>ZuFbE^+X>x)_fՃ`O*#D ,>ʘE3#~wěV:%' 7e&QRxå)@kӲc Rn'zBt~/^L@T۫ vkid z}Jׯ }? Wkendstream endobj 316 0 obj 2761 endobj 320 0 obj <> stream x[n}zez_`! Ab`,ɣhkCT&<΃2KvWW>tc5cEӿ/~xQ{ZpNBJyw|zH6c`ˋwvCʻݰWCtƛf9.Uл{=۝z0Ʃ)w2^'!z;+O[?İF; QKgس!x|22ip S޽ [LMڽKrZjFd38 h֍Ӧ8_k;1.a>VHI%_Kk5$nӳ1öo3%߅y\ 0?{wo&R}wٷ|* !MVƨZ峗,ɛӐ]VѳOYޕ򚟽N|R/ɮq`bGf[k8"ŷg*b(PWF^fvs2` ,w5͞oڀjɓk) :gåtOg3v^}2V6"RMSxBbxAw\+ ~o4v(^&-fM/u(V7Q|FiLZ7'j| :i,Amr@Fbth]_/ʔWu"&`F(grڴvvb,1O.UK1> @NoGm:@n:Bi&ZuY/c"xJk%4"86 i#P>)A'Ek -+KY#q'D0<7{mKV]Vȯ:PSGXo(tF'}Y;$-U"jw8ˬŶ/$Tkl)|0%:q؜Kx[7"zDhGv6*L9]'"Xp*Dލ+F0 0I&vy@'_7T&i2ؚ2d ֕ m=.૪S<h^` Ζ,gt Al-kw*,_!Zm.qGrM O@¥Uc brIĢG\w0ns0hץjg<颜h%4zmwq˕.\X]e =8/f,,ɖt 4ج!'Sn @"ސ~BD*:Y,%PAǶ{˟ +/!jLi#c{] Pɓ}δk(Q MV,L:U=>ec8 A{4:R @:ѷ7Ap,LqUh%q%A?srADŽxz[=Aab ]s"M)bR\-Uë>3PFZK-Ps.u6O9W[)84pewS0sKfϝ$9sF*"Xkd M[o1ɢ|vJ b ߽]Mk=ԄI\YJRN@l#d>{1U2Wdꚤ svBl&anwd$mn[N,q@V{|YZiWX>{M$-d`JM G%hf" po|ŶR%R6p\-_hNxilf+*\%Z'7B,UB=bˁWİJ;s+P^"{Khr!!um$=!)alHd kՏ7yX=7XS5($KE I㼷{~; ths8+H(0ݟK%S0lswNF[&ARz8vcE1r8{6 {覭l>[a*/g8s:46~0aa2K0E[FG?.;j|:G|m*]p[0N+GjKـ{z獣:Q(OUt" aƔ/``ytr01YZm/ϠzEޞ%O#QwBtx#);W> stream xZko\(v5)P'UQN`(lÖe'n|^ûܕ03%99sK1ȥ?GOśE]7rz!ˇ 2)gr;6Aabte;(!F_iQccuуJ4a-oUF BVgz#墎F!]]HiWm ^NZAVk3[~=F)(?Dh-mڮNM+0VJyYhWy#r`m8q$ rJ\:VrVoiĠtU"iQ=xݘDFg@A|vP2z2bseσIq|+"sǸ1٣-Sh&pp*pӫۛ[ Xϱ֜5uc-4aM'ev=(*@:'Jq8Fxh%-bTPRP_=b{CAxwJ=@ NQipRqyl겘=LeƼSm`U~l `T@Yx 9OjPtu紡DW:wa, mM&;M=iUi8C ){^;%=6*-╽jF rwk(sOdXwZ1:N[u嘺v7sO 9uxHrՉtX!tXVg دޏ<8ɘ tZ 1aiU"i@~rcQ_$ig˦Bj v`xzI $.}@G-oߞ,s)< '-ʭY(+0veTWIےZrTe~d%򕳫G2"ZW?{j"B?!t}t– kBȚV5lNSW:a><.ϪglF\S5 Ex;$0gixJF@}I)O"#cDB4 P' >K'V޶Kk6J5,ܞ'aL4e41!"ʕj$k&7CvqV Ǥ6[a\ukO;"BE%Ю򌗻E|^ŅBUKJEŚ2a;NfkJ#O,s5~#kC .y܈w]I\nNu;U*2{:)zԍe-Rg  mcM^Ne6Si*`G1zpw4r*IUDA`MHPSR;^a4evG|ˏ9sFAFRޒبE>TG,`U4,Ƚ%͏OG36HT&4+ǥr]q}Ds~ JPݜQU9[7@K1l#ʣNeEZVhU[p2#H|8)TL$?5C(;BfMAgY'MPx]gyk-崻^3+2= x\rR 7OSf,+5B{iG}͔}H{&T؈*rTD+"dWGD] BP/qLЯWUSD zezY'ͬfA- ʟ噭4&%S@Ⱥr) YC?l͜#gԭ$תAjG!W'ұfE4j'kT1_{z*Hh% AEEkiV"_d꙽?D3C.)yWTk@_D@罦|[㺬{_J[>j6czuZuMgu/zߧ_Ɏ ˝u9Ii}͹Y+u*{Wa\tz7*{!qV8_t;mK_+)=xF]^c,(^ ڴ纮cfaٓ3M'ǜj sʭm;x8\>5{d%kw97 g9zۤOc%~/ʿ jLO Bfp~{^t|ѻgf2bǝ>I&)J1R2]Q> stream xZmoU_qչ">$)ҐԊ d| XMEٷ=gqP˜3<3s^q&VǯLgpmh.aZ`f![3 VL}괭whN1MzaUmz̉Hǂk+qÃnJ l-8㌷ӍцY_yc.W3ϪxSUٳ*{9~eSWٽ*`ƃ*Wu} rpx~댸]t5IVjuK@GӒ'!*<2᫁Iv2،OpCs,Kz}}|I◎r;[Һa\g䥫b8@*)F2 A N4{30.9DQ(_v(>)[ NU{UPVtus^ehjZv U;Φ ZLeu{Qֵʶ_סof֐ؓ 4v1b B e4!sas7 |L%X6W?NZX)km~».ux%BZHOI 08B{aռ´V 3]wtpx@WZC%A5eބiOߡ`#aLlA/ SE9 7|EȀ`3p RPV6Sa)RҔ@[%^5yqqo(}kް, ,ƁL͢.Ҩram6[;D1e%  f.Q!FQu{`(YEB^4HZ*/{x8ӝoYjmPr5:e{\Fp" m7C(} (}!rB ZhSme,rF 8җ}iM!YܕbXDopem{^ a.7xm !iՕ?qtT%m99E(Hj9 Q5Ax=9}A&E?R/|l+MsPPqK봌Ycnߦ\iL):n#pAp]f)T!k+D2-JCV3f> stream x[[o~#xN,d6Aހj") G\[k~Cr.W 5/73 O'!O'S~t}ٟ嫓z*OW|"?Wg i)gN{ݤNmBowf"ɚK!FҪO$gGy?hRq4V7ʪݳAIvO?):^Y)r2|AȠ3ivY$Aym Y{-qIyf/ yS ^ҚI]d؜W"m[sSYapG:l IuPZP޲Y^Q#tE2 WjZEAY4Md'NuB)lSZ*ւ/ +b0_TIn[Jhxn䖆Gbں_X\6|OpQvf\7%Ѱ MPV,G'nW2 NSePdVQ!8DSRj~Z 5 ]c׹kt3 Fc?nMa+[VuӦnf03Z` w UMU5e\֬pag?9{E`$7 7E'QA %gWlͲΎ\<&/^$>:`h,{yZ6rC@H'Hougorkr&H  7>9'4N]^Zn4Λ ¼{%EEﷴrg+B[[>,RSӓaT-H$ kt6ܢUߔTTxuH%/0E#[U3QR`drX,ޓ a>i7׭N`1w=<>[Ud5*'}>jî['jud-uKX>_@߄!B#Yiϗ"օ @^'KM-^廾˂)hἷ[TX/@mgl2NBEҝ1o|5veeTiE "fLO1ŞܻwDD[=,.T}%Xxb: 42y&˒VTA׮?m94vxn %$x%,@⏋X&:f?QGXokϑ)bR4r0!}bQW3H ILzirgӵYAhj lA0R6 !,?ZsFbs) &פ~/c8F^8՘R{+r(*&O:<,!%XHbc;a 8ɛrԍ`Bz3 7,qp1jd)"AS]l. ~aF26&Xpv{ȮZ<(k>Lj(69M6b(GA&D"$6OOnxf}J%Uiz30) lfRfg7S=+1OiEJRlT'G!qR5! gi nPMQ% Wd|c̫x6HI ܗ1SALJEC)ԕ-0z]$4qYÎmv^PysMsfDDns̕μRF[E)3;nK!5/mRaFZ!O\]N5.Db-$,bOzQW=^$dˎàd)tdC83vüQ;p"5DQZ}3LwMMuo.83,16lPCc-JY6xΕ갽W:rVr*SaZpXJdƘyk=}%b'~FkCTHZXR ~`)M|MîW{`UJSK*q(tE}ej8v3nE''9>է/[fE.~*ࣨn\/wp|ZH^Xe7y L{~f}_IUҁ5;OR{&Ef̴dyf-ݥ7ϔ#itJH4ƉŐmwSur/LjSκQ9w&W*[գOJ75虴X<y&/ڒN ۶mq. :↾N*1 Yg&;6^}ۆfDǁsF`9jxEv|r,/&KP.;Pv2_ĖG ĜV ,ͥ.tE1*гͰb!qa?2s<Rw>nGYЁJ2ԃR]d+o:g9%ޙX`Ѓmi \w i.J̳x B'`C*aH-2"{slnFisU\B W<\1}5b0?[2!̛oK=WO$Fcm#qVZ=#,ޤ\rJ)G;=)?4 f eq܍ߖ̗@tUFs^༐ﺄPzEJh㛉Kڭ=ۜW\HCTuz;_l%a2wR9pv_R uc4m\Nq-bfiއD}{qƁ(k3 -îMjJ?N7npw*p59:r& =򬻻Y=^RM -(weEGH鑇_ <nKz_-cGcI?f? i}SyϺ +[5^绩7ŜsYTʾV Za ,YpgIbYJDzv^/?uA&i%iP#FZD ح\?[n"? E2;P/N'[o=QJP 6ec:j gE苻^T?'8rendstream endobj 336 0 obj 3331 endobj 340 0 obj <> stream xZ[o\OYK~iHA (TVX-[:geV`$pf|Cr&O.6Os۳ػ?ϛ#6`ۣ7 ~kg~00q4r25)!d\p+˝`^0)5u/K&zzWG~5Ǒ>EV:ߕaN)&LnlŴNL?վۗ;i dy|8t!.g}` 7%~B ,$U i@GY>䒎}&@ ?i@Y)f*)Kr9ЭP-$3^YM_iKNv wK z9Z-|{!ẑ{?{ 'pŸI a/;u5L7W^"+% [8sA삳tN(s', єdBi I_9({U\Lp%-R#>D쐬l~'f̟V "n۫sV&i͂ tUPP<٥!6)7v>vn~f g(P`Tŝ 3DD??8si4\CN_C W=q/[r`BmPԦ-+T;H:Lk,^w79* 10͟fJ0 rcaS~|!9x)G19dR;`HN R ^Ev;?&q~).TSp!@^clh1\Ek5[46!p${zcP O¹,D|1\Ck~\~ιÌ́޳J aju7!c.ecd?Z3?Yf88G)S:f\3aCnt% #.8yErg%~9gއT24ei+'y1coWZq3~Fl8iZq^W)(+6ߠـWCB,ۘ%mhp;Y mJ@>/-WY}F|3V´xV^ ϥxN\)qen1pZZq z pbExv[\i· \= S)t_P>PYbU9 BJ]Md}yWI0dVw>=Dފr'e5(9΋!˶mE @㘟Akq"(ίE Ңqyv6rV@23؀WbliN]x'ay6W94-||g&壣r#i޳]:yRa ;_XiQdf5 ϰ[b~HՍܨ^~[ J-oHWoiJڎE/4LdVV3mR/5Ev+§vhV=ؘ^êq{h`UBwӿ۹%' Qŝ*z,9]!(̊:{ȏHIfARfT W2 qn$JRjIf\Ga=R ΰ(|Үw#íN07)x"LOZXR_zbBiio+{VN:sydbs$ BB钝]]̟l{7@-XYC̞=JrۊR!jME_3WJ?vXl~Jgyȵ6۳ZCxendstream endobj 341 0 obj 3266 endobj 345 0 obj <> stream xn澠Ovbnm4N!)Y%ZlyI|!9 ǒܸ1!Ͼ͖3_ls{=~[[YڼوOoBn VZ{sY.{&ᗳ͏w|\ԿzT.;o~wI%eiFΜFN2.˺|>60w˜""pHȷˋQx&娙8]ZZ Iǂ >Apw`F}.P!2N ܔ,vx n>3ㄇ5p`f=R{aN{U riH( 'Q)ye+xW1m$` 7䦳Q><ۼ٪$?5Z8EO.mk+6{o HE)5p` Jda b]Eb"-2{!&x)fq*܂@~)o.R.802$)=ҋpxtBq8>&գ<$%5=dأpi!l(_ ;\A Sxk-CYL - JW` 2W*A*iXTˆU@Dj/Pџ7:GĊg7|S+&,OArdsd1 L,/^T.͉Ȝ}j_TëjOQV4g NR [)o; B;}.*x0VH*_C'cp;ׂ415{{f܌"b .WLҫa;уmi%{W̋0$#2[!>,B7wE*+*ӷ"SH)׫>` " <$4 e V#`TsE.1אGe˙Z&#Lx2SnCNΌt= =ž@lfP\jg n7ť/}0JѕOK gGw]TmX\w/Q}}Ww!p(ۋ޶?:]nÆC jé "?.no @9rRyOK(02C0on+ 41(R 9 g|T!?$ (z꘳}~pAPZhDe ɂex,2ᆲXDx8f D!Z .h=lK%m6veԽ1 o5",ҙ!"JEh-IM7<.&`"AXȫY"܈F ]W#])T~CڐFHR7 c` xA#s8 R PIF$`)*V(ū6wܳnVAOJw 6rc^&27 i :!?DmQA-߯I^ /Dx rq~%9DNRn֘rDr OT(?#\/GNóKC> stream xko6XH..&x(\y:ζn߉HA\`\xH2ƣuGW*:ilģ[}3ե(hpzəkIU$ΓT2UgYR2IKY@4P2+Qr&D\󋬊?$`"Ep"IsY%xWέ@%x?əZ9+9&${dm-@,-ʪbH>AkU`MeJ`bY|=̅fQ V5z0XUucbEU×TT 9LT` T.Ehh/ JU_!r\#tRknqs> uP!279 tJe Tf~r B34kUq$bNe1jSd;sih1Ei6Jrkid?$>dmVV 6 ^ n;6g,D'D)S*侁)lb58Zj;Em)օ,$M[htcvo1NÀc\x"b)975EڎСW{sXS!d/QJYd_+oNwɪCg9gjyfn6R,4+K{/&_^".x"pȫ;r-:AG\k>qwCTk.b,7!w' r_Lx37  u;]?6V%ff.4d^_U>w}uIV`B*oyn< 쵞㧈:F%7p Џ=G-Nm#x~mXM ­hv2M&%4.pR{ߪG2<ݐ#WUijN-HSĆJ@ 8~z)I ΐ{QtQvV+T0 kjM=`V>@=#yJXiz۾}IGM3v)Z"AC}OMgD[BYj'+.D; 6oG xw[N4M_3W# Q/(A7t$zSyrN8}3?,j+ם4pkBN_t JvJ]Fp C"z\-IzFxЋ1rD\ь l:-J2|(\@=q`Fbè Qž5[>i8 JqEM7#$d44Wg,!BKg,=Con} +XzkٖɆRW7B "ܧc@WV/H tQ_moHxW7<0[rw1n׉~2 mcvԆ6uŻ\s/[rh4)+U`MyJ ݋؛.E;˜\ϝȁg +>endstream endobj 351 0 obj 1570 endobj 355 0 obj <> stream xXmO7~b:] UI&J)A\ wǛ7GժcxO~Y.5T6 xY]"0aW\ LSj4M#FݭMx=dtdendB UeÒJh_ Jd!y8,8U#|1,JLɵ/[]8ԱLͻTc!7)P1UʪOZMj͹ʌUƩ]'QeYZae,Tv)?v."x3c٣uʪy [,)|(VhY[%[Za#ylUZHutJ+hg'ˀR2 `)Bʔ ^Z؛üL=Ж@1u s#hϋ7 jbe3?tpn#fhg0mo. :Uhi`=+Z8-; MhSmY/vC_3X"Ez,3YޢXʇr +¤ Wo4WqcUZ}"WWosw r ΂{!T~;xo7>PD·W;M}l_n,vigA&M+s<-~ z$x*'Hl n*0]M0ѱ߄ 6%49A"l3# uWLPO`XD'gjNRb'hTzKRQ"$.}{+FRYPWW]OUM2jnޏ$#KA"&6ve/#- [ [P2{܍ >.*TmSZ8lIٿaSPF-YCHcFō~$%ԣ!eb8M@D潯/^ rzO0p8s.`a=6-|^yY#%6#dNZԣ>H<܅CT*Bפv'ܪ1Q"F` X$ᱨ,g!X`pwL~ ?!;M_VͺO}:-yl r{GM<؊†E4',"ILs^ݡЯ-ngX)6ƎK2Ql֪pendstream endobj 356 0 obj 1479 endobj 360 0 obj <> stream xTn@ }W4AČ=}\ BuA8YORaslgK Xœݦ<-Zb%yq]`{veAe۲=.;`b(]@(j!jgTKj<$54jjQ!UF ګ'ݨUM@UW¼jC3 1CfPAճ!r6`oP v{/*rv&G8hb611&;\Q]طQP,mݧ%ی4"5nYj+ mXMt5OLjeM D?wQCD>9zEhsw`GڇNGG\7ukxJa#a.;`WHv. wS#^ {s5}ID28gĆ6ʩ~-_+I-GP=Րz(DssM&W䁰7rMw,_kn YFc4rw(Nr-C_Rˉ| ?v9OL?/ΘX$ʛ,ygB|/ho)wbSلbOnX@v8- Ǽoendstream endobj 361 0 obj 615 endobj 365 0 obj <> stream xMNC1 E|Ed'J,eeC,} H}\7Z,A˝UO>|>U Z}i xLJLaglfo_ڄ:nN1el(**D.11 Ic"jwL8 ,D%,\6&63 ZQ??RBendstream endobj 366 0 obj 205 endobj 370 0 obj <> stream xYko~sj#N.@R-[e%M~}p%wv"K΋ssR Ch2zyx{WΰAAIrD1 &XaW/x9P')N$&洵4;FÒ^}m0OlBog_|?j2(ڨwST RA3( A<1*\,\:>2jVZux擏~| jiE_[EE!=O;uk@Om̢&nG<@S<<*\z#(&-$#a?)/ ҄@/ԎYG.]e0 eتe `REE1~Jg]!5DaWR#@Pa|9) WjJ Юx)lۜTH%)rޣ=P!$`KFd2N,zv ClQo,1#n_h}zF"ۓj|2h 7(K8i4K7[޳K8@峲q|tH-]UˇX7g, ]JD($gHxU5C t#RZc/;s2&eN7Wd@6^>Bctu0SJ`flI0Zo Ktd9_ӹPz^Y6Lf=<;<94$z;@ Ց=<>pp=ǗON2̤qd=LVƓf2' ) .x6-BJ3nlsD_f@uJ^r.`gտUn<:nE:7HN0.XO@VۏHSw*J%'dlPGp6l`*%Na=8+.ǟ(]S*}DD|exUH\҆.{ 0}8eN?n6>V@ 2J(`6;~Q?۟Y~2]* 8b3sL3P؞uN ڬ?mMǵf]XixxΓ @'pDP)tE֢.S|HHrowWp-^Es,TnI&ࢺT= |~N a=}mnw`iŒ]|6ѱl^X%!\ҰMfyySj~]:{%4834 2ä!?w`$fw$$[ T*voH:oU}]ĔŻQ}ɝw\h\ښqd~/Ga$ 7:𺮽.X+źx8Qat6kYw;]z樠fT89+QljS6I HZ%WxY>Ҷk[2}h_罴Ã7P3u^kRZv7>`SDԀ0#I(,0c·%xpٷdM?֥ *N-$Rd&Km+@ō#)R5NvM.;\ܹiP=F~Vo`!+b.?ӳiZ3e (! k0KEZK9+yJ{Y/ҝ*F\LEsS2d@hW:5=EL[6=P2&%ݕYP"9%;֝S5. eV&\ЕbX:}j0v.YTr=7 z_kfcNXI,BN#5%[n!Gєm`Qs< ;C+qCcq0uQ[$_bs_W%%pk=oφ2Q,?@1dNwzĽfbRI[vkiy@E澚RO̴YS^>_81sӏGWT9Oy+N@_P7M"E \PUԗ)-FG~f2#X ^cLzZjA 9lg]X2ҝu#/vU[\GJo]X> stream xYko\E"]CKunZ$ąVHZ[5𒜹w@[p8s0s5{p˕1Ig61%џqĕh@ּ_FTE,K)N/.+-/.H|\)}2iq\I0F* 1&7KF/nVXi_ f0Xg_+Dr)n+R-k/I|S`GCOmhFOiFoiɟW4|}pF/iLQD튆i- O?,I~iCvanO[et9nT/ffo6t~: Ε )A+G'OgO:ٞ'~M,l 2 9 kZBce& *Z+P+|+ntH]:&$ooH%9DdX%13_oygU.g釕d4MT8PV(_yS`=JI_ɐ{=l=NggăKCi]NqA!0XPa!%ľTC0XĻyטR]tor EOXD~1m-k.Y:>mwwwiyG">E%dS D -m^.`p>ASn ՞ szoa+OpmG x4٫1u1cillxMcZ $ќžA@yRƖelrktxþدBW;Z7"stǦ WٛA4}L{%w"׋w( 0pRJԢB8jv'ƨ"f%Th/ߤ ,DZ2_534xipX~A{.?h em"dw3茔6`Zm%-H_ڻ} p;9 FO>NPB֑ԗR>kB4j 'bB}.H냒 DN밷 :E4-8N;T~]ǟ yHË^1Mv]!-ߠ|~NjLUF&]6ifywmMoU;ic7Mft6vޤ?\հ4mr,aIWS4hUE۶׆a]6m. nğTiuw9+ٙ%'w@һXxj춃۱³tfׄ1Лr'r>rMW{,(*,>㎾5hI1kN;hߚ~)Rurx3#har$pX 3aeO㜻~>}qVG= +2hcs?&.A1SUB솝h7.?ґƞ;KcKi!cz19zUV<ϺUkfendstream endobj 376 0 obj 2694 endobj 380 0 obj <> stream x[Yo?bgm~,v& I\)OUO3=$EAgꫳk߮9koVϾwU]ӫەHC:`ßW"}o*Ixfà7[|FlÙAnX(&z8_^oqpO0gbc7«dLJ-^ŕ$~8/{^n^y9Z}Ї蜴aAl8gKOA3͔gmӴt,Q7q9B uLh#x-qE8Ϝ 80&X`dM_oə9v^l%$uHfs"q6]6É]>aU !> \ bc 0%9{T?()&@ $Ң %ȦOaMzH(HB:HBRG=.jdd%\55\6 na!fF,)Ο*DG h">k?6R14a}bVW!Q{<[3@ݶi;*P]D;\BI"[ 1rUU "[0*2(ay"i<) ,a^4FNl[)V|y|unv`5 @HAk9 nWRO|#>F"' ψݠj.}r %1g!+A0ˣ3N lW?OzA d3h:^b[xtݩsx|!ҷ8~Bi%B3x_ s7!x9xN|`Yq&fX-C>VHtIKz)1mDȞUO`K' yϻ%#"g Yz/c/m&f\iZ*oLohHfqxb} n}MrLuȥMKoUM )FQI!h ?Xt%!_a ْFCGrK2,iI uRbΐᢐ+m'&Ųe=$bFD$.Y9ZS Rُ% c2R<8ÑJ 9R*} 2$,(u22cx]F ̡U.`riЫ[Au:+ ,.Wy p*T?-Puopus[V;-HB.٧). \ ݩO*Q7R=m-@dR}ˀ0@!X+ Z? 5~Xw_u,']B2/ˢ# 1@ZO-`^Uy}qXOr;]:'tmiCѵR_4;$8B;ړIkA1@?UÑ"Lol![cQ(W '/FmX/@Nƃ`v{Z#Fn^d-j `6gx_U@:( -801kFn5'q7=w}-za\ HYHܨV;f賋74e#ī@hᎭKя/` *`}Yz|@TeN4rUȒeQSA8=1kb+7 gun/$B<>biӫIx&)'<23$1ܑtf]d,SDj$ױ횷%)]Nb7$#JԻ5̱FcMc45 O+<5qu7n}_ngy#,jƔؚ]՟Mr`B-L@$(d1,>[c\]I۝ĜWvY ǡx)HG 36۴JywMu M*D%˙pI3V8ΓC}l B9F3 V' o2Ba69ΔT bAߟ Em9pCO1:slc>gE ѪNAԅn7YlJ`MG;IӒYI( 1PWTHT`Aǔl[ja3n y<*;Frq{VcPk };˸Z$t8a-%bUf (-M[v3Ū}:RӨ X IzT{Xv34<~tǜmCW#_09TE GX_8*Ta|Nիi94&Jd#LI;g~xbK"; w$/S+1{\dLʆI?1;}߮w?#imdpЭL ֍Mj߈KC7)=UËԬ;pc/n?YTƑZO'cr_PnoS P1k"IMo6 pO`'~"@aqBmSFmS OIw tׇF =Gw 1 ;zM%T STI D^QE+,`2cu0joOyR8Ɓ?" Iy ğj9V _mX_TbY1B<1nI1 6ywͻ lMo',;̃:: EӢi47  7/>IOVq-HroDS.vVYЋu)8iC^w jQp7d@wH#kgb#;*z&mzE~YL?~gwv"%?+c"%bD ؃[v[\7C5OF1nendstream endobj 381 0 obj 3689 endobj 385 0 obj <> stream xYmo6_u g#R$.̀u뇮نm0 $v~I:쿏Il%Maȇ"y|.bW?~̓uX_l9acB] }љ9} !TfY@L75'nB'˅7FYB`Cc-va $mu/sq|RڋNhZcͼ̸&F=>Td:ۯ|+W(iQķ/@^N|_p.EWo{!0x̷p}ސV` KgV6G`jrE / rendstream endobj 386 0 obj 1597 endobj 390 0 obj <> stream x[rͳGT2<رUes*%Kh$Ϣx  Z!*Cbnو^n7=}}y(ӫ7GrZoCG?;C{+cz/ٙ! k~+zoUul{%2Iinӽ0u/m]>^XttRF8|FRB4[ٛcJc|4ejbԼ0 _bUQ7{|1z%`LQ12@@,iQC#Љq}QCa2`@Z]kl jdnm8{7PJyLXeuFǔZY4PAGL r/e @mrG_ *cI i2M= 8>hlnq*k8+뫭!vijTʸ+RtVwgS,TX\扽˲wY:O&-凹^,6 k^it-eCcWuA$T@JeP% U)xLݫl`4Cr㲫P.&p1#4fZkIae atr+Pw)-ϸdKAš[}P6mS+כk?) - sEeB׋t{D[(@1,qp5d/G$0c'uܨKi{P @kogv^rVéFwt }mƀ=%ٰ,`WSR'ingCJW(!a3Sm;[rl kxe~°܋:6FSh‚i7N9G^r76Ft6܄䂗zڰ{[)1]LzJHQdNSޙ%Ij,7*_6z <ӦIa#B, ˖E:uD&[`zYWkZB>q&2Wf?-(aތZDdut XY"33ss1ϋ 3b73g^*{kGcJ H#k$yV @ߞw5wy|}Dn ɌtEy#4"=)YJE >i9:ksZ东ϝ޾H4޲Y|n?TgQJ1JⰃp\Vzs$H1:k TbR plo5y7UC\0v/ O +L]rstBT #<6R[UNa.Rw Z'y/Ϟj0~{*LJ(Uȟ@*Z%}2PSIt}֔X`#|x#T3xۜl@?4PVV-:j"IPq_tDT{2>tIQ,CdoK.bρ[[iᱳgx?nFklbvS%w&g8n@}}dTe>D0`N(WJ,d^6 wM$w8xqF$1- 1 r9Bs!1a0%NlJ(0xc/ԩp D^ 0F̝VxHk DF_ 1 r-应-Ud&>W&7Ÿ ŎcɗbHE3͘ C:o=ԫ8te aKM3cUh{Lio1p!$mLcm"~` #?ft@w׈x66|9]T j֪"y4/m~v/wlTeGL,U딼q%%ʡ~eoH7!l B |$-[Ânk@ˉ[M~/79E^|:2/*C/7or+ZגD .5ɒ, fY .dnrƜxLbZ'E.day9+W}[ڐxoYTQ?tC@d_L\Of{z{}V'Cu# eAtn)"j+-Ԯ J2SRx䩭Zgy=TATi߄#Y"VZRvחC[z!gw@[pnE< Tу_l޿zzy3ï>Ɵǟl~wJY5P+ag"NTfX溜APeI)7 b7 OWH/&4;S/z U-Uu6kJ^=9S;^WƠ #VGiYko%N:c FTEf1SMZ~%w35MTE`yFc?TEX"܃Az/hbn?,DdVd]哵 Ð+5Z),\ s\R}0B`M g dWhK,3\PVQ=m.xK}<-sDS}qcQj~'ry>ѭѐG2]["JG/jfsU6m9-vSR߳mBqBgs'eHEm PkVκJ|aӀ*Z*p6sv7 0ޒRe]{Vˇ<Lendstream endobj 391 0 obj 3534 endobj 395 0 obj <> stream xZ{o߇~k{E\;#4 E'KF$-K߽3%gv+i|Ԑg~XoRbYX]dR-w7 5!{0Aeko/j^ꥋQh9[|ݹډ]͘fjL ds~XFT6XN+)NwRYWvVBdRwZKF*m/R;C>5p ەBEV^z[_kDr)ҿ9Z n-J/{9+#.ѶUIJ m $49hoVk0^$P3q= %|%KD-e쎲>A~(u{!$wkMN)$\ufW`т }` R:QvQQ$z^NL$-IᣣX"4|Ajk74B%C C%!v9RҦ-cu m&W:\j_z,c, M h*'̗ ka[>q&Ы6W{g7"{JJximJ%HXJoY-!b S; ^B@K2% ֛ǩa9&[a8┊QLybHސ8g3^ I1CFieіFwAࠐQS=0'PP@d`l.4{v*U*fJLpyhmlDJHri{]2԰@wH+4L3B1[JHwa#Ɵ+J s""P)ؚ;{N0'ֿEbqT[mV0W_B LF]ur>,dvB L?Rb`9~c^c/*ĜlD d= # 'w)ӬF#C(G |F'}o`LD1Nl:/k{&܄E7;XldEkQ@;c@%lPǑ z\`E@QB_ QQ^I029bF=Z=(U:ìαq 6ShuU{7= <⬃Jvݗ{[igvXinpvR[.ٳ$fT6Pna62(@<^y]yWֶvjQ,_e,'7e!<=f4`Jcp[51Iƌ ReCGb܃Jܻ=1`2w]w iD?6\cX$j%>V^[WO&q}h* BSH uCPIIKu1v'Z[ֻvAC²?RgB} Nc/61R >qE9OsBkG$UCsob7 Ty&8?Z,Au[u*h׷o -YC-Dq޷Dpm 9ziX0*tӱ ǹ= eA5(UjY:8CJNn~Ww)Q`aW|& ܖXYxpyz/qT$;*cg, B-S7vbA+sZO?q.KJ{퉌@yTˮi9;m>;rs9+QhO=v/G#QkU:Woh^D7#[ڪ޷91gC?$O=? ") ~-$ 85Yso~ʢCh7vW98-AHkyX$iPo==9/fswZkz7{ٸuV!> stream xݓ4yyE .VBQaR$ ײ%gޱ Vݭu4߫כ{߻6]y?2޿o^@o@xx/zF;#|F7i4` |* Q7JڝR+Г2Y'L?wM0i]ShH_ڝK0͛)͇<,.Zz[Z*7d7iSZ' E7p(j3!miPZcI woCZL}7=>ILbv>qwL 8;(HҘ;(r8y7MFR(ـzD_՝Pưs3Ãth_5-4NƗg |gv Ա1{^C$ m>^sߺlɳh6L-`/-uͧQeG . T Uy)^f ]~xnn7FQ^#!m {o?\o=_Ix6wJƻ'"M4ю%dҴc>%o(׳GC2hd^G 2C adƒ`O.֠SYJ 5=^QbJ#_jc|HT6 |tF%+F@ XOaP}@JbgÐY C":Y5Q3,s1l(]I@K"ގ"eZY6-JRLIK٧ؠ}Xă](Tp[J"dC [w}lKgYe; eI^2C. _'IÛ]t3(.')!jcR.ı>8ɨtY[Ȩ:gx{er1z\Z 5c[ UQ_|ZfnQ݌ı>35vBnF>1Zy/2LOg1\iF\:8\lLRɨi{ەƩnZuDr.Mxڃ9W9=כFiˬHouV`:[y#2EBOr)U!aU5a@/̰X29n92ΰ,3#*[է Y{eFY.sQtf DQ[a۪USpd=WV=Xx n͟r,g=+oE&~Ŝ&k %wM eY<:ȲuY6;3#J[OY"3d/~9vӌJ#QՌ͖xYV?!\P~ȴ,3rY2 'nUѭ2.q!oH,_@63T-]Zy\낻bNJsU~Q054Պ$,""h+qw:խ̉:QW智"znuRNCV4խL`&aEr1 6Jr .gYK;Ut2?FeyA$uŅGu.kfFa]Du+r/UMbEr1 WQZ. Ɛ:IOUeq3UL1Nߪf֭{QUԙ*&YT-s*vKKA9*= ·"SߊL[LiC3REZ.4Q`U*聹K?~݌QZ#}1Ύ+;My?~P;xG')d9!0aa޷!9? `Ωqq;ك|?endstream endobj 401 0 obj 2326 endobj 405 0 obj <> stream xZko+.R7]@ jSIU@R$Kd%McIr-Y|(DKr8߼a\Uԅs YfSW[lՠ4fsv6jq5Hei#w^{W[aSXB!%x-FAaY@vMK%ߜch#`+åb-pNY..-0UHXs^ z5 ,F g7wC ZL/W΄aJbW#^4Y^ s27DMw%u%<g?&=`y6F` ?K':2pkߛ~ivz7nЌ~ONé8KiJeԌ:b<o0 ,mFM%:7n.s4;X,+r̶ >L8rqﶤ:샂G:`e =r4]vEj#AYC?O,w-!KM ZrAx]&u*! !xO@୰ 6_n<>rLr2Wն遏[=7kzﳿ>ş?zj1Q18J5Z QV8+TY(}? Jl{v^ J; ^Qv~q`tH`",lltrC$;Pt;T$ӈS/ HH隀rARc#.b6n!?exaN.^J<S@fͤNJ\1Z;d c>>?Fjx֡zU%b#"{M YVI86"ƽvY4[uT,'49AH%#<7? .+-%`uqB!=}#wK 7 DE ;> mi=& SZg안gbH" p>4ס]h&v˝I&fnSbcjw"jqKM\wE9uhUފP ɫW{ޞ ԑs&LuH!Ulld!I"." cBX(!y'_$(zz5ikaKe_i5#l1I鎁z5>R& wBxZ}qY"=.j2t|㬈/mkժ宻8IϖoGq/零KP}Jw",)J*Gx 3)ݑ ʶCr]RCrtrM b1v(I^Mƙ awDr/;gy}Tni7V[K 5riz \Cp=T;-`(] Tɂtȭd[EAEc2P;@{$ǪTk5'&/T.jR;{9Ԧ]\[ pW U p2%6хt$|6^I0W -gup%MK[1%%2{X+7]~~t1,|-;@oJr'e.ݨ~<]i(g]tU.WHTEzZc|pqp_,u\Lu [^5;QşG(1 $`՛v .^IcIטquiz2G S%C4d“zzQS#ᦫIL]HlS8'CWx!uoxj5>\ ^ZA't"'ʆR6a;㩍SGN}UiŜŭ#*rUݙU/{=˕*TTy/3i2t?+wt(H?-ҽ"H^_پv3OK-"d :Tq䴖hB2>hC{'.h!Qrt]l endstream endobj 406 0 obj 3530 endobj 410 0 obj <> stream xYYoG~ EAl#Q!@.HA񭘵dEꙞ hjB g{NX_meB-M>lr^| 1.H^{=RS".FWN$D/EizQ7B+mwN ՝N6R 4־Q{cphyCrUm^-: l{/HQ*G5-o2$pЭ`uI>%.IߒG>$S>'$!);I^*'JisMwm [R-vomS!Z$cw-/ɩ1*b S'R!vIށ̲n<1IoQخRѝG|}،ncsE C73qEkm6z5hy!Cg(]$Ɉ;po+[#+:)W$.~x4o|9,L$]kt-THUыto_:; .K?V #vGb$3PZk}Yz@S2/ pW+f` &eKσ8 Oķ7ͥ &M]FWM˻wޤ.CGFs|9FjaЀFh@ֈ*CyV,)N4B*an{2lɚM<ZyJ>%4lϛ 5s$*.):&d@kχYl遵f!Fw+t\FD&z8r$hnl?GR-u Xo.=:v^E@QhicDj@@jc;${'^L;<;kSBV2voQ3-| ^ $; \ C{G5Jp%_oGj,d"(;HQ-|GSK9.oOQTG(::h݈UIsL>W(ayҦ'ct'gF)t>gNHJ'gqf?+tL5|(7^4Qic9Q(? 8e B1aWȗ}7Il9LH rHGU8Fei'#iY8Z.:if)R%\wGs14ՋIY?uԔ ?Z9+q0r60@V0: <;]=@Q5I`ń'Ӿ 3qIN3diS; HW Sz FF=SnCm򁤼sOq2n_t^;U5&vVtnK1-_"dR5fŠ> stream xMNC1 E|Ed'J,eeC,} H}\7Z,A˝UO>|>U Z}i xLjLaglfo_ڄ:nN1el(**D.11 Ic"jwL8 ,D%,\6&63 ZQ?@(Bendstream endobj 416 0 obj 205 endobj 420 0 obj <> stream xZ[o~ׯ8{K^ -$E 9!Yr, ]wSir83pA u}~s񫿇E=ßŏCՇ^b-.PuS"6:ao.~wJ'Nd )Lgg|* Αe!=Ffs#nn LrY8RYaّ"gɎ8!iRtN$KlJ?%ԃI/.LЩR[]C[Z8# LiW ƻZ?gME :koI _ApCoN#ɻ Cҏ5W81(dT449KzV謵>2^ h?1۞eĶ+qzC7B{>^Zd\!E8R`@lʗ*Sg1gdY y<G0T0rP[x.ka!N%42a e%L|u"GºFzO+V`ue^^?1DVUjr}vi5X6'ͻf`Rojq k; TKlY-cʐ,[A_8(mDy/dd5 tHJFh@ID^g9ͯ ރ b`g}S]`ʫN_yZm6 Y1&,,8i$[ # h\b= oD*5[.=d&F_B ECt1pʇ7C]y;ǒ s->J|U`RqT34Y3FjŠY$ 0k"<5 ̇::BGMςqĝRAyR_taQk@`5 uA.n g#bݗٗ .+ "i+ieRCGTEIO>C4$uwc>=-2]{+%zǖm EP9JFblΔ@SʔB + B+^or9s@sZu2jq린z"!~x.%[1 Jom#F0>qW]џF'ҵFD%GU%׌4mjXМM49!>s/j6|W\'DPqN(ߧ(B"ť/؞aφ B,ܜԄ;Bi(m_4Ȝr(}47 +|UDNSKIv=lR} B D?V_T13'549N] i5GakH!j_"P޽#42"^n9Ԯ4eGfv;D$Y|5R QB//,xLvX7㬋鈖%(?^z׊v|RO"!]Ξ Wv~qkϦ1EFCr _,,A:vl([Ǐgdf !lu>+hgCi[slAP+K7q=FS)Z6XOތh=uUM(CZCԫp<#fDyZZ9ݼg ۙ90$m's!s&Ѩ@YB O 1,dɩu^W ddrf Ay>,MaM"w}d0Ie݂>~ cƣ밫-a߮8ONG囂t"*1 *R17 )iq(8mrh`kOL>ù *v$m.-òڹn=s3E0iƦ'p,VoEx.>^%~nUzŖ5Ї$A=E4zӗD>ݽt q#{ξië6_IQLS;v.waǡ{:˂ @ ׾j՟q'm$Uܼy କzŨ_6ݷg=oК!4|nk tVaӡʇ&"nf")UJȨJbҶ$5ٸ> stream x[Yo~g#kx;}S$9Q#St1#F=u}U5ߝr&N9/^I=\^|w"x}3xAV}{"|瘳\_^|a>pw:>?T9;;I%e(i:9-]qݽ *˜mE{FZD^Mx τWrfU"ۻDu{}|M/۝׳K&"EhSLk Ax] Ô2pr̷0(5Bpk) sV^tb?b5HL {,Ǵ+<;lbG9~QG '{^O![bja~^~,w"$@drHg\^ d{S!Trx97x(o@ͥ(% *Lݽ{0^>nQ2]idB kğ*Z#'W'<(3tr̤^4y\K 6@ $8^̌_95K\г4$:`:3$lh ܉Өm +XV7GQ2PT,L^+WJf\#A ni9ʭUD{#_f$SLkdf:ZU%(*ɠD^``ެ^NJDsBn%P Z0#RXdL)w:ݠཞI>Z%O-`ɸ'Ӑ[V\rǨ̼ZZ(_}ś;ȧyg?^rV=J,`슨o(Պ8]^d!hv@OH5w E;z{c'@b[Wf$!˫,b6 (2/| ݗ%T܃K,qgZf{ę9./|`&D AL;J|V([Abj:Y~?K ~V/I]5\2A/sj^ۜ$h49; RպO 4CS )$l̑E_xUn}94.+uL^ e9;. }ur5H>+,{jB=ϣ9>`+u_uu}SGoEo(yqUer܁x!wu0Hwqn# B\pIr/L鏿<7.LNWc^ËI [d@b1WbOu:a`i MNN(~qqOZ2J1-2aY[oíqQd(jlB&.&KzD9@AS 08#O.qe4".aDWl# G~}3~6Opj5 ?ihBg>}Au+4QrN"#qF_ƭpZH4A Ac év.:E,! jņ*T5+} >5FުPS140cΖ637*q5O[Rw8G0r7ׯAI]dwuU~ԓRROu) %<ijEޭP/? 쬐 R-ReW* ’49@ j1dHkRŽW5*ּ#_1Nr@9 IӪޗ CYE {lïm }v܎pi`dCqt@P!uGKɚOu{9?@=krFl;]Óq "w)yZx4P64t%T "|YyRˎvj@+Oֵ< d!Yp,w;\K @TK{$F.=^%JJRY[țOm1V9Wb{xIe$% bM&3EcC4aDFVl"ߕ`9ޤ֛\8n}AylP 63yj=Emsh:nxMδVk8S")v'0, ڮdPԆLoũZ/UqԬM\(!Ы(8p .@\q\^q1\gDYHʴO<}Hn΍-!U)[d|lhLY LQĶ]89.!~E^7jԔ-x]5!}X|[uH>̽$l\:GI]s=Ouǯ┖L(M;mw Yn局$-ֆt(nv P7e')K]{cլZi+<`/(;j"ImOa +$zpk5g.,n=ry0cͶe@x-bNb-BUME&om ~~G43)玪U,rF1ҁ*Կ #s_\qӸg^;cZvz^jJb#].5n_uaEh^ I3;T` ٭N#~~H42ľL-Ε)OCǙ<&inz^FS74ZtW[Qpq巽D fo8}ܲAl4,m,Ȇ, ƚvGA UC]Ə,c.y#.xVlN=g4 JډbvbNO:1"r 4ϕUgAX0fQENƪU =v@CxuCI+Sa FB^fG=܀Ds)UA GLC$lX5Y6-fJ7cgN6vZhQٶMXuva ^}:$ "l^f۰/n;rpt.cϫ}*Qo.e#wHmW](0D$%6E߅|2r:Jѻ= ?ABO> stream xZyo~E wh I( K-iE{|$#Rbwr_ >?_=ڮVav?X\~[azhzG'[kF_W zգLaܰ*7[(>Qp&.iFQQÓVJ;Zm/ap" rc2ڼrY"ㇽ+\/f7.gkܵ˶@qXٲQ9N唒i (3ndJ ?KiDbLQu4|85S.%x?O2xjf P'( FJFx妸>pQx%xWњ+U>m&2-ȯвon`#Ob6.NZK瓨%B3/f02 2=jЁEKs4+蒞AZ3g\ NV@-tn3:'Lk y]{4,22>j@phI[)-Ѯ#_@Iy`Yb0+䓁ϰxʈ*-\閈Wy;iT{O+8H F  i( c$ Wa )Hvm̄/vN`r]CHQK8S5@'B/ $MI ITnAA=aI6N rirRAm4.0Bf'bh16LOTۡ|Z+JMH]9Tϥ :2`rgJ=6?ϊ/\ "/ %P7ASMe $AwJD6$.3Ԟm1&_q )(xlvr.IiYl!&]%Gσiu=> GZ+, 1CFʽ/mMp ʙBJ3F‚+=هy6ا4e\Ж4{Uuif;~x@G+ i l )T0j.zuu!S=-{U}%{M%]+͂tkޮ=H:3L rNoڙ4>/M -HEzǨ 1ZR%l~ nB+-~&Iم& 5Bc,g9/l8N5_KrݖBKuՖ}žYGҩ.l[CTo@WI Fdb6QBhSռSg~B`2_o<আBlހ| rkA{rx'{V:\-\[խ%W?uztѷkz)O[nW?{ O?{=}J (?CqyP7308vdh,'?ˡt_,=_J] ۮk(f"{+]_3@R)ȸ(^ ꫟^(z9U Nގ{I1l u{?H,\yW'K! @ 6( UᶸfF-Ezv"UWG:E;7S<@]NbgeR\Vgq+|C=cځ0ECћe $<^j,QY  ,5%O^c.|tṭUsc;ɣ!+S;0ij *7&"Jd-`MG S 5N 'Ʌoq$rɓJiGo3_8Fٝ151j7;H *j$X.o#Z9ac/C% E< owy9G?*y8G:Շy$7y<<&@_E g|[:&-.ve [7E(Sy^Y&+>I)Kb-0A,#"d 'Qs7p҈ʏ߼^_'9?ut;,;E1cc8Cr(~#&aI^mvvBUMpۯ:E]5d?m4(nP3nJ%}wh40yO I~߱JA=G(h&sYܐk:'[Re Tӱu ]*]8-:G'xZI&坖Mz&n"yЎ4IYOyYADx%qAendstream endobj 431 0 obj 3381 endobj 435 0 obj <> stream xZ[oTHYͬ{F<,! R {01ceTT3=h}z=i-t@J)LT^DC:BϏ3Ao`fն׵]jf;?TiS[ƌW҈PlۗzoBಲ*7]ukim; | g"[6Cu&W>Ui*-֫*]Ui=8U=6Mϋm蓹ʤ*ܳ2;Tޛx6hD ݌1X`]sf7v?׶Ek3RB+"-iB"Ymפ7 VYԇ`^.' 1;ii  F:Q~Go18M9GX_ 6ҿgmJdx_ᘕ&y){T/myItBqd.Xo6,RVv5HŌcf&Xdh}GDqH|Uоt{OdB+c2 mnVnn1tz(-1&S{6߲6:p'aLR⿅ 5[n "U"7Qs$n-~u6TMEg,'N$OkIvp,Z?}%:HE ? „?*TK [}Բq!NS!/ݹN"}A67shE^=5NW6l6γM46bŬ igoD.wN>t:HK't&:A4RŪobEg!>o׺XMlG\6/}PqSNON􆕲\as_Шml猚&F;R'™Q6%m gvH0Ktv ^_Qқx,tT%(rx>Y]М  A3@d´1@FZ-03!O,O{={|+땔?J*SveZ,^B{p SMiY;ݪ/c@b*96F }PLHȔI+";t2ۈG9 (\``yX:! ʆbcE`a7B,DfL+bٗAh=É\" ,Z 5\D?~ Mj 8ؓR ;쐻IdGJ˞Gw0T~hߛZl$,2ƾ$/^5H Y:o iQ>S Pfo@cwz;CవN\!VYS"!'냐$JS+ȟ )OGWH"Y {tX0.\="gwCqfCc2`Ю*2{ǻ@r&RcY>RDkyѰ6SMòf )aYA\{IY\zqP%, 5";̈́=-$\q8 70սCl1o 9afvGm/h h>iZ0v[c&+FUy*cjUZ!>Ju9M3u Bu]b#H@WmdOJU/Lɻ !, j -;ҫtBp ue ."yۖ#A% %֨a$ՕTrX{-h|xq<:=Cllj}׃g'~7{{NvR :?' h1_IN:7K~|UJCo,CHUi!Vi]OUheј{RMcAc_j.)g,@#sľcendstream endobj 436 0 obj 2760 endobj 442 0 obj <> stream x[YE?êyB,Hh+d{1"ʨi`?!Kv:+8y#Iͧc맓Od(7N1!MSlN8eC1ll—'nno5a'oU[;-s.7vsۏvZ}kok|6 I-jlq{H;:5ajc=' ? q3o}&^J[fM˼=ȍOv{ٚCEk>nͧ}ku}'W-·q;thާr06}fpAAh(7efw}A*M%TYF8 .Ejeٸ`e-'=t czl c%Q*nؙ[ِ)[*ۖztq#&FPBX@Jx0|ƄZ 7F[%DV CTb8!㲋ڪA&>{\lC7ZRVvM4ulm^S=2)!|zJiؘ<:ͫg'ȓ_x}󗓏m\^Ӌ {;f$Z r"/I@i'9\8p"D΄`ٙV1$[d>#A~Ā)PN_E<)bO5 k.^$1b{.VWŃoO b;{=P~~(^. B[Gq_jv8{ݽ5֧x j)`57;heRc%G2' )OVf9єd]$[k')="゙CL+3Xmƽ?M&_^6=I.ݰŊo lЎZ:Y%Z20U(gK+7j>)A^:pOϫ*QR zpasHP4ZbYdcH9q-gfɼs|G&;,`Hm\,Z\+uS XW3 t} VO(U z(Tfd׺ ף-bAWKfWc䞻5tVɥPn X$EsL"rʣ;$Mywg!9.i|8P}O۷;dv[[{Ɠ+H2a(Mm}Ђ85/mMuoCYjK%kR\5T!g2+Y~<C ]&ϩ=W3j-y>DEeR>zɰJ+NlPv>$ZtNF%L*+ir HF:DsMJ ex1/cBϡ֠9)oЁu0OFjgWYN(IV5w>LZ:i0a*aC)20]++- o##odUЖnIz씔#kg-s&;cTyL;z4uuG$貙[SNbW#xFCqت хb :b ] {ȹ%kAD|Uw{GIn_v_w 2<ڝe7[m3̃42q_ir8nCt$,+4.KSS=qź&1MKj+,1S ږ_R aB{DSҨIY݇ͯХm1R0_W:u|6-n~ޙ8$GAX.7!S3pLY3NM*Zn $c| #CoُMYs`*uF i#Ž)^$ n2(Cay/\zu2W.,'#hIJ| GYot$eĹUqYZz8M== z"T{?W*(֊VRo&V^:W^]&dWVRuz1Kp47؛ !衮/XQAҳ;7z8z 0Sh59 LEEt:+t~":M ;Mo9ڢ(](}#ВTpuNChV; mΓqrH"4&|9V>n$_bhCe$92?;~O> stream x[ko ;7 ) E%#=3^pVkF"䐗}?E'ׂ\קVw-ןVrf?:Rcrf}|%w !t #nvg5!FҮ/"GO۝V*v[yڼT'ns^mwS.긹UOvsAV尚h^medjs5ڹiOv=wDN.zo3aLl .q;ڭ5{ y%~m׏:N(ʘ7ق>-||L{. 9I,c"6*:KZDž#^T9luycJF>5SDZRGqhǭӰ#e;뜧Tvf:Uav v'>E' Yis-deNIlyGjE"N OtvС2`LKD2/_Oâ >,4Mj*s6i\GRG2uB% 68USVOEyRB']B>?PQ x\0D$"TM\`qm[ZiHy2K #b:wPwgRq8&ӴdH:wìQJUi蹈D+/GVN H UKVGP&37ieiRHzK#crIws^M}]z݌3Sw^f^A8&圮ҼMILMḞ$:cyR*^WuHE*\V^ ;a;hnAb =f >>˶`*Is_6'\Vb% CM~CBI͗e^ɡICeLJ}o8+n[zZv[XnXkz7F)Qjvu">"*G4u S8$YQ2chܱM`&'CYn`M^ *dTG0֤,fSu"ϋBZڛE⬯eȑ= ꇵ/CZj|Elݧ|dۛWY}1{ !`d&{oDKkɁK6šMcF~x; bIݗW%i*S$7V7=J66IQu E5uTLҍ' CrE8$ʸ4K<ڏhz @/7̥;L8HoR1*TRm.a]nþ~5_Hv) ڋc4vO KĐ<)wv2yu4U%EJc/dgF*CSA: Hc;RpPErfN|XLLdA?YA32pIZ׃1%0&e`LOa~Xq5r/f*a煚PEwU*$i@Gwɘv$ x>E3C`b?.//8̀-[QЋ:)MK7ܻOA&"a2>mLfLҢڌvO1ЛVBj!'L-.s ~D> stream xZKo6h ,R |HH졭~naE{)RRu rd!͐O$ä}|9|W 'pO#iiVq<N^Lr2zr0RqY%* 0L*0UBouY -y"E&ElQq^JdRSMHXUE\˪J!e"L, aZ $5@VR/jF'ZnPAeB5R"Z,OZ,j"nFO}RY2"Ea$Ue?9o? ZRKm?.uWS>%h>.sf? y3Պ F{IƗ@1M 8Tb/as=oyFQVUs=5a?Zkf܏Ç<'̆{/@4Tomvz?7^Ju@H.@i$ZޕgFSRaU(=aDQL˿ZylxSnѠh~\-uysg8oC g!  Pf "cbS+h~ەݥPplA,WeqRwȨS&0羍-)5n5YT[Xe̻Nk}ߕp˺ j|"AZK366D9mgN۶dƇ%4atGޒq@B>>`;^3a3&3tE;;Y-q9D$h\@f:$3 [6(lsHeew]~r4~9ZnI!؄Jabhshz,&w?#4sw+! O^9V{j|~O<Ӛ#"?(IWw(endstream endobj 453 0 obj 1639 endobj 457 0 obj <> stream xZ[o<y]uڠv"IQKdHJHk% Q\^f8oLt~÷߻&v:Gw0A.`crė{7l !|Kz98œ [Ť2MtΜFV2.|5l6paL."R;WwLx%A3͕I"ۻD5)m%Q%ұ`Oԛd85V H`F ?'ڸGFiG ''tI#Ui5hF򸫶XJz%3jsI\t|c@Fthjcl<l>RI2,8 e8`ȘSRXr;2JtiH^FqHD|*ޣVҲ?Zq$T4FICaF->͙ߕӞ :F+N)W1)n1)MVF |cRZU3ÜxKIN D*F\ߍyѽk0\t jY͹$}|7RPDjkIђܲJۓ ig+[Z=Hҟ RMW"b`~fԐL݌`᭕X *NS^.j [UD ZNjZSu `@49b>źJ -U;g<me"VHyiPv9을Tt0J`'Q3Ry-U( cEha9I  #lOZHP`[9 pHGnX1R-'l{).L-\)Dr*-}M! W-z/_iϿ+5WD@l5a1п& -2t6.8ApKf` 7«'<{ 5]Dv)ޏmp6a]l~X.VԄ Su|_o T>&IlCsWz"v=Ӛ+06z$8pX]S㊢ÿ*.GIQ>ekj+*^fp8HΚ^ RTy/ˀDZ'Uj^ ? e7306ehF+<+K` A I^INk6Qb֋ـF9s`V}2@-?׎Ca<=NjMU~0&TAձؑ4#lA8F]bWC#qfѢJdyٴi>y2EksuCH2J|p㱻DJC"&}gɍ_M(9%J*{\ 7NUiCA*8]1Q̋R.R $̣dNRB kfUI3JÅm*z;iΝHЋ\Nx^L:%kXwT:K(IdٍZVCY({gJl )zkRPz3#LiE4&d:ߓ񝗡7zj3K-Rvq}^+1T#@C4 TrU|*?SaJiՂ2d2ETAxBa\?`PuYg(sa8_(50q'%m>:l9irԝS/ /U(!/.^>?E˔Tc^P̮͒c2YߚGA S n_LJJfK^ (j;vM9P1•ȐEJ˽_KSk_MWG8=Ӄ oِ ݱ+ҼWG 5t^*4N*YW] {H¾*EE nR]Q4+zGHf?kdx+=0R>r^Ԕ"s`|.UxԾ.D1^_nyӅM?ӗ/c iUYh[IL@lOYG{ޏ 94_V~aT^h|W㺔&X_kn> Rϥei#i<-P J:)\j}+=D +wrA#o.|M5Qutzܛ [b GZN1yNCZ]D/Cҭu*\W1vRb ah;!yW9_\'>gu/7_vbo'/ݟ6Ou/3DcaOO|z)OB>U,.Ҥr"[2eFN!x l[yn[) p{>qM=92Eϻ q`*(JW>(9GʸMZ1#fYVW0cz NB5 -d}V,4u8=h;@QtjdZ\&ϛӷzʒ:q> q|+589j3:UG*|DaƧX Ӗ4J2J#˪7tFǷB kEV߈((U :|>L{ᓴV1@FPӵa46˛Wt"8̼b](qwӚy:Aendstream endobj 458 0 obj 3178 endobj 462 0 obj <> stream x[Yo?b2kh[}ɓ8A iS(EgY:%h3=u5/-fn|lb#?4z&x ,Xi臍 ~kgOo:0q4rл5)!/w3Rs;\<>kp+S;<ڇᣝtLqOv{δFt Y-dZSPUHq~Ǫ`{qQYzxWkȽa`rZ{{\UI1^jv_K1 RN3poJݹ# ۿ&EpX S SAd%+d=1W =iaZ7ctAŸ8gt _M.M,X+iZ%M'qw~9Dڃׅjb i6h$8IS̼j5iBed}]5*>p/=4oxCPv'zF"asL @ .3e7fC q 1o] ۳ovܵr2JcP/DW,Ou\F*5J#K3q]Wj\285E$Kl׫Z<@kDGT+q$ojj{=hDƻH Lށj$IIĿz:P~_mDJ.by$},n8r^VND, >C_kQ B-7ŔVE*-\vz-'P؈պN) dC*Ͳشƚ,E>3—M"5Fn)9UŴ\櫓bE Tfєqݴ3ɟ%|ŸΊTa-|@dyJX-9h?L"Jso .`'P 40m2װ@EJ0$7,W h:+\` C ׎(jB N![mĝm\ǭ;5G>,wuaCKz $}>2"b4{Fr#Kr+C/.Tb%kt%{ߐ|d}xyQ.IzYZ6 bBE٫θZco؊Fcەۿk6OF"M rtUp29gF{!S ,YN$39W*ESkpT:b,wkAdp(`R]M^PS p?"p.Ɠn)%PV (&e>exBM+MZ1!e8X7!hVH% 77%J-I/,)s+=µyx4KiT-\qOGI>Jo!$s*A%ĪQNIeyd3' QuILRJfmjݪFZӂv5,Q0պe+e>d?Gg8{!~yo>5S%2'^oюXҽPn}C|ݸH`cEX)R> )Q.!%ĊEP F IP P~xtd+{YtԪ2ڳ޿5O43O<%KYЌnhxmͱwOԘV;$LfH-&ވ~ql<.t^L:#:TexAMz(ևlu> #fRiǁhׅd$IԿeH.Z Ң42iU,϶$KsBiO( _ aoӌ  ǀ,_!k7bx)%El[QF)H^x"QiʽzC#<ڷgxRT1 AӪEFP,Ϫ1P0޶ 30VNL?s2֎H}q]Ue`x颢kE*wH(>&3%y3#=0CdHf|6ki8SnZ\HL/9rg#!ߣOjDNvMAQKD._i|Vڡ ;[9`&zD;]-Pۼ#M[>&m(m_KB؁k)mE0zs?k^* #蓞 P*9x'/WNTQ!>5̻CWٻ/꺅yM>0shI?jtL*~`"NuSjn' GIVWmȅ~7G@ߴQ!Hj '.ⱵE[w"q)K^L*jPT "B5P0#bG|o뢓QkI,jBu8T@C?ω?g\"W.ץHkҪ$>:nʭm]ւ7PO eQ0}蠤唈׽ϼƳ ԡ(͒c# >-L*-Gicbf]KĢDpchcXōA~g;y9!ydgccBSU#^:Iaݔ(Nrpޫxw 5*ͨN'oQz/-_M6] ǫendstream endobj 463 0 obj 3509 endobj 467 0 obj <> stream xZyoE? <@6h ( '(dI[#/.WS%ÙkĚjn}|k8z?<^?߃ B VZ{ysY.{&6[|F2}۽⩁CqUL*)Cj,p4rxJƅVv8כ`͖3\3\$^0Ni0τWrhv8Nl{nE"[X0'/zݰ_e(Sj81fV*dxA1\P J860D@$ Q::ti*/QeQd㙇+'ۑ$)򶕒Y)e> gA!鑤48-AEp.ŝm`vV4*.upPDpo҄/K`[3 jI$?I`ͨ*FtbDY JK=6TÿeD;.JV2]MK@R]x=N[ {*$\86 $U "Ϫjs $Oƅ7,X+FH|U97ǃҤY3Q{.'&L1^勽ՇJv1$kAc~j}}ysZv= gV/v/?1rx >nriU=fo6UKfe~= ~tj}1 VNV8ㅡ9 R1s%2 JgM$&zPi z2A9(d0h'vP0XUe_@P"W{$ ѧd63zq(ۻ:{Zg~=u;{]`[8Ü8~z גY<RξomYq xSc'w"C 髮ƎgjsB'=j2[TMotol%Z!5n\ aqGv/ȲY# p dI>k`(Cn"B^?8d]4 U?V {n?+H6=oHRb ~L\iBnʍOD;WHwqA"p/I&6aMǙ2MQ:9[ jRn̈́FGTR',4"fIL j9eL̦$ h@RZZH*։A"y&?Cz b&|Hwڹ5ߝ4g_uZX@N}`lF 8r=? <q- NgG_/'9;ٸ!Y_dk>%)R8=Yr0*Sݜ#tV0in?dCVz3p5t1PʞBK8.fqa/t,nh `s5b x(.;a;;s |ԥWh_TtĊI߬pQmE4"tjn0Ҵ[nrwhKcVF I WZR^g|?Y9iBXdb!fuvJ :P_a8P\2ͪÊEK$䀵{}>YJ۪K6-\on*{ =˝Piތ~@T,cB6kڪܙ!B)C-GbtȷLE cf*icubz6Ah0NMbխi$1ǫSS!unJOIкTض[MpdzJK75o%i˛T]8ЍF(奭I؍[X8߃rXzr: ;TFkYfTG6x:SJ y0?V!L<=lBc;kx*jHTK8H0&,0sEK #gC> y҂\ȑ -Mv"KLŇ#aԘs1+}\%pcTQFb - аR|L(9H 8M+(_ 2R-6,q2Qir&>tIY0Nަt.YA"nŠt&Tsڌqƪͦ%'0:S[TNc=z: It Wl@WPP)-=Sh|jq`LA: `1W~[w?!$ܐ|T5 4M{suDJǦ)iƞ|Y7sn'iWA$!w׏#3_ ཯ ?j:%YqIzfYru³rn೬6{SV$Jeb%JUUuVo,.͘$ ]QvJv׵xu!^wYg[A&wک!HɁ;z3u5x]1+(כOg2<`4| wEI> stream xZkTb4~9 QBv,0E~J6.VpLr^^reE2'OK Gxov8a"Z5&=q+D@bbL:2lf~GWsoށ`nq@ OcPbeI%(el=ᆆgq,` ~Nֿ֭u Yx?TADQϵ)Dxlx@ޯAu 5NIC,enlm:k{GMF,cUlzڤlrp8#3/ fVP2>jq=)\rɋ4!usx fLĥ'\[Buk-3 uB3. \vx3MG[[PR]ivt9`%ܩ";ӵhMaA wx|]3ayBq|C1)Ը_c; vwazOublJ{ؤ[#ݻmRr["eM~ݩj<6uG^`{D;z,0 .&@:2紘L}`>M`}IQ['>^ewF|ݣ\Ӵ5e}=7,6R.Bߡ3 /,ҧy(~M.`|W6 6j%[{"53Kw%xwvߨskXGYCoRx4|FNIDU}sdԈ9W(#()&wsBʛm={Ұ'H+$Wd}+[tZ]=냧8e=Ʒuyn%NH;em$ `P&x/#Fh|`# #pƺ0w2f>ѪbJB8%ߵWsV/sXJ"^l@.A_@Z׽`aVF oGK 0r2>aHUpaR2)NV S~m2R[^$RICTc| AC*S u2pڣѓ| :BW$h&HA~!kU2t:b iejA];RQ(@;&զ4W3vQ3DJb0A;e[h_7\Qx,s'p^DzXa}Zhr/[d}R~hWĮrD> L:]u).RcA^;+T LDati"Q ' ې ) 5's<)JZ*2R \8m%Bdi\; LD> lM(ә&@{J}Pݠ .FptD =^ qyr5i4ցۧEg׃ l/vuW{w" Q\k"jrZ|ÄrQҰ40s|/ 3(jylG3$府O+q +7 S'Ī΋N_2Ξ4Q t} CʡZ!킡>rl\ih\4G;=|[qκ]jvг2QAϴ}sl,?hs6dxh8֏FnsN?vFG|Zg⮼C'6϶bu֬SpgŸ_endstream endobj 473 0 obj 2179 endobj 477 0 obj <> stream x[iun#[fO#,A۰lvXe?WlvfήV],^F'ߟdzv݉y)j3G'2~N aP[!Da֤魑O$̏V*N~w؉en!vۧn/墎׻0BZvEJ}Ar~^+?D(#zRѻ/vr0=OWV$rM8i@{3HJ頶֛EePKR'~Mz0C X1f/+|zOGO7[\;{K߷w XۻOA.]7_uf/%vBq[˟@Oƾ,~R /_-Xbɪ$ƒoQ,7 8o*"fU;̖v}erؾ޳x( 9KYcDSzSnySRD ټ=Lz*\T0z-LLEk5OB?X\vJ)k"0 H)5SŚRRXykN|y:m Z;bgIdg; †(˪Hnp18+FZRP\{L?J`]0M俞' !`C'lQP N[Eֳdv3o:aaG+د J폒P{9lY"EvM2& H(;Xw䵃z396r>-L=avاrd2_ͣ^a "X J9V!*{NC b&%9rA"8=I^Lol6ܴ{q|u40)+`u&֫qAƑ|r~c)Ko]GCkΩu")!9F*eNBe7j?/K"D ʫյ/fe!H ꀜ򥵁~w)#¸ |{ @S|zwmޞ. 6ȳ/;'lȓFGs/wN>rKO\R*-z RH%?Х@sM*oTj1 Bw1ܗQtY*Wf{Ja;zGgLlL4t@Y{gy,|̔ 9 "B@D 9 K9ؼꀯkɭ#;nbbH)3vAj @Du<<>&BZrCzsz=.! u(t>8kOBʣ4ni :gQBߡOgt')ZΊwuŖBQf].̮N= i[*@Fz]~o"?Z `\wy8, X͒7CZz  W*pL]Fp*q6 1.KmzIJg&wF<h wX|1 `9GēI͠4XQSܟ7G"cNVNjHCZST>ʰj>{RsU zV/u.^,D6XW\D&%?Dyve_]@q<`Bk@ =DTOIagZ߀,m9k:V}4%x`x@HH59I "sXK"DZKG!06j#BIki8&ަ'-cPI ^jqGd]ȄRl_\%8ɪ3fTL81Mz'N1w7&x:Ll8Y"DR~s2ιumU*Q^+VRaQC%Ճ*+.ՙ=N f p-U_k8-Ǫs<7m8?Bh(Ljg*򶯺OcK}\ml"Η +*Lot]F`k"{[ {xfB}l[U3e$8W%i$YȮ2RtB˦fJp2ko>X:&E4EC܄Zw;NQwRQBI`lwR)a<|w(BkgP oKx^M}T^r7" miz4 64",1//ŝDY%l~=h553ޭo֮س ?KH ΍-iYYͧ JNwF#5 zj(iP{^̨Ez雭Z冉_g?P\ƈգeUUBcqYe?mChA0zMDR\cR2][2 L3ԍmj0Ͼfi?QWtRz5@E¸h;mv]HTUvnDU&ZĻQܔ`ZpGH4ȣOwptDGƯ|`[%°V: qb<.pޠ3W>"%o6TTˑD*~b{Ѹf6Jcxi/sdYNՐ88K]N›Xd+RqۮT[ 'NXCP/7mu&Xש64[l}k_}-zz5B\> stream x[r>eK9vJ0TJ"0HmL4fA(*).W ^mOmn}뷏_mݭޝn^l~}BFrf{h#Vc“g:[boM'vFYչY'T;%t1%]uwo'1vNyg}/LVHQQ c \OH+ih!uN %{e=LﺓY绽R6/qcHݣFEsnMwtP {;0yEMw??.U'As4-ě9>ZbV;@z[ͣ#1L3D(gR޺I"(N^t *gX)<u{ =yFZQ z|.1ߩ=*8kTص@mj=F wf2ݻY{hxYZr&eO', n 1ɴ ЍxSsrLeЏ3f*ai٥ x*^v--ir= 5 X ؑ!dz8"!QKʘ֊5=I⧴H4X'x#V\n,4ƼR_vm:q~m 5Ùȟ&U-E]e͜h%6l'r6-ZctO{R7,uz&Ш芆0FC( }e-+%T`Bg#V\ WK+mӖkmY::12?ii瑬QµPB0YT`H úU.,q6l^lB䅭(Q*lFFw6۾~ypsw|~g*UHj!MNəd;,Ig/:+mGe`E! 4}w86!khys#O.)Nr"Um ɵa&ı \SH.kVif)+gs.uX>=eNLbxi3sp?9a0Wn]rf@\JaJd|"#}4"inykkA#aEz{F,zMO5@0\/Bs EK{݄plҀeȗWӡWAlmⴞ7w6ٕ?B!"{T d BA5x;Xjoì]1ԵOБ,q M]Qi&Mh=&2AX5\*="ᱼo }b )6M]3]>"|#+G|۲O5K G6/ÅMEtlHi!>ڈ}D6A\MrڷָU4OgoY+J Vq3v+Dҫ7tqWig H\#wü}VA4*%2ʚڪ^ (|jJ&9⻐6D6E͸䒵!U+l-SOI4(+M5gळWlPE9)%(BvVhyDrHS{!`qА~FZ`B:47 XӒK_xblWM,Q6%+06#oЊ*/51*UZ3Xب/9򒶉RVTa)h:XTD][bG>ףPnKsM7⪨WsZ_VgSKr^5w1k/=V&o52l~2ImQ6 &=xuX=]x(> uoڢ9i+[38b-8"pl`>{c^vV<6Y_ۇ-ed#\U)6 *? { Ƨ0vߋ'6=ЧqMy<9!"~γĪ"YnIY<)" :b&LZM߃ɹ6f_ xx!^ЬЎ=|wGtGWKsOo*M)\yS{wPL5:eoئK:#P2MCƙyYm-B) ^+7Ǵ [^cѻTs6+x81Ω#$GзF^;y8ebُb%tʉuN!':\ 98}5+FDCфWVnHw)-%EP 9gf=XQP|l%@q*-mӮVޱSMOU| ᯇ#m0Yte5) # `nAڻ&C0~CQH+ `f*Ъ} 2W_P刋Ia#Bg^C &C"m@"O|- Fz~P0<7jfٙ""=ThfW(~f]`>_x Pz'@9ZDpUh>iS([#t䶁6AL,SX7Z!/:JVji(ٸ&s͔MzTAieGmwo(Q:7' vzX(ѯb"{iWiϗ/:E.h[4Byk0!ΟO_8hSpۓj +:tiGF2#f f$~+AYޑfeKF$:.҇Pf_LZ쓙<(Eh&2O;N N8mxc*D{^_r>- E5 TP\!΢-j\71Yut8OV]QS4Quy 2VJ _> stream x[ko۠~~$4A$*") Y%òe[Vǟrw9Z Pּ| g W[˭ o෧ԺۯgW9C `TG<ȡwBmm/7?v~}šΥ_h'Qccy^iiN(^Bn/{墎ݛ^@!.,R95[傗l&b'C/VuYPL>ZH=W 1d-1z0RBYwRof}w 0~RDb&+y\w#5XcXlqY&^|9 HcXvio02&WQ3e"11~6 +UwQ"T04ͩ$txg I<4IwSh7aː_0h= UaE!€s{H1Y),1X;w&IZ3<4^XK 5hhS4ϋ(hU`=T,!̐㋬`!S 4ezx%MI"Yq޶"CQ"^yܰiy2Zbrjl8^B"ASWR5\Q-xp5C %N CQ#NK]4XS .-w=vB1֜Xp3nyaTP}Q;QS)d ǭ23mZ.mÀZgH=JH{ K?1g C2_]XH@V/C !vsB u77%_eOHcdv9Z s>K!)UXzߔyi||K,siuښ@6wcأB7c{#:Īg*[q*RYiUQ[Ը^ѹSg#&% V"0U iAʟ쀾nePCN,uu0'0DYy#+6 [=h=iJ.LU4uOh[맒٢#YVP\<&iqF(L(ftkrc5Qz󺰪N@Urv}KKJ*UO; YmHKQJ"Ы2"m'gotU`3+zԈ$gJQY=g7g$DڊHǓf+f |3iD\JGɩ` j%*cu&lĞ eɝReHGs}Sgb~MQQTa){Zpp&zQ-@ފisKnRldhělH\~\xiBo#;0_҂?R'bʼ&\)qWz@AnV ȉx76jM!M@,v'2|zo.T)j4d:ߠ. p1w̓-3Ul`fl\R5kKAϿ, (oµJ2k~D{/*T taqJl*P L YjEWi}ZZ_4[ߔV$'dTΉǑO>ԗJD|X:<)}0DL}ShAKl9*ֹhN-KԁI~ܗf_&.Bgg _28l-楾,0%SY}s^ZM"^#1 ف@J߹ S Ç XN{R5Lt+/wT}Wq8cZTTJL_ AV';$$ۃ> N«DcjI*,*ijS`T <ɕT ΁bLیV<2 d'3^,7%'n5hWNJθrs aZ:}eՑ /RuXфV 'L'*oy^OUՃ>P']>v{4XZ^̻^|fQ՚ٻCL{@cdzG5$]|!-t`qtj` #g|0E]uF?\N 0 =zoo^_l}+7|g?l>~IY-L*:[LU~Q-.PRx̯b^-}?W"zQ|hEY]Ϫ{H6{pC*OTRWKWfuЇeqoZ.ɦw,dVx8ӕO{r 焏@F.b40kq {z9]0#F5Tμ7%✥1~z\#]s%K[0v:ͥM^WTMg)WnJsr|!w-Uև RU~X= fF_krt뻍qzMnFG.ۦ uft+Ab %N<(D&Si..u nW͞\#YN0R:`3U*kד՗hM-4BrU^9"cXOWv1ь]vȻMF4+'JWN5Cy&$?3ޒ(a@y;O0Ϡx0њ\CuJ=uEx:bIhADbz~kU*kbnV8Ql5[Ɣ;. fPin z ݩ#bB_h͗pn6X̳s%qY d{90&˻ ^=^i&+vGyr/GPU{ͼȲ=,1gvT_J{dB*c33+)_t&1~6͟'1֫B½y:lgnq%BP/GzHp]{¡c@iMo|e r'^Ժ`3.;D;LXMmUB}z8pz7=yK}xP:7Leuendstream endobj 488 0 obj 3669 endobj 492 0 obj <> stream x[[T1oq1BdL'l+eR),,kB-H-aYC\{r͙Xs/=<_{'Wv-ߔ竗+:`냧+ ~mg~9_1۝a>p7l˙ȍL V2՛PG'>ۭ/1D|q0@$(:8\Z˻v9Y0@u}P!QUL[O8v^~W硍QVR^D7<K U?nܠrq"fH ̛EIeV}L@Xyq@mX0{xgOp:rp=ofIL]UX 9mEuwv|:w(":PASݲr0f5 Pa7uNE+y\ֳLѳ67*@&O--*SRphAWph"XwcTQ_^w  '31߿`uׯW_սF4xQ>o#!nzt@1VCsRlBnx!i+y7\єq(]ZcʷYz|>aY$!bΐlцg̉ڒ3ňNv xD̡!PLkT3xnf@X[#Oh."#i:۟y9Ĥ^eNZlND Kx;. 8BҀ#Ϧ(^gP( rUY 둜T ]L뿬5`\Aht;}Q:,TB_KrcQ_ot%T1b[{Ap+a.D2Æl+Ga\N` K?)۟G_/>ϔfH0.>krh"ٲ~S"q<ͷft7e w6 eM.Sr<5' b7] 9`W {rn(,} S@>$f<*endstream endobj 493 0 obj 3541 endobj 497 0 obj <> stream xMNC1 mʃ'Z,A˝UO>|>5n7Gs_! <&{ S5%,?]pa_) k"11 ?>DͲpA5.YjXVrSVl!i ̭%ʚQ?EBendstream endobj 498 0 obj 205 endobj 502 0 obj <> stream xYr~žeFp$O$rSvŐŒDQQ>̠gK\eBX\Oc>lP[Iտ'6O Mݪ틹fa?d}v nk=zQuS"6:q'6D?wZhG)RގJ$lFp=L"V&qj!EF$ϛ'? ߌ;%fВ8zCFinJ,RF=hsoaV'U gOixLIZ2Sì(dW N+nƻQa?y7k/>0PW߫Iުګ4 :Zg-Urf4[}feafDP)Mp VAFH, RW&xhlrߏ1c.[󄬊XZ8t"oմ~q1QQfQS[m;rsltbYCcl;CZyf˧1a4=!0ȕ96~a[Azgt 8S+Kτ98R7K@cmIKB{>ty3AnDkuuޟtZ3'# #cY&҂lZk{۰* %Cl􆇖>.i0og4buqaPl!uȰJmI\0IǍ~M`XuT\_# t5"DDg)sLIHK}yy5'ז;NG*]=<}w[yG߳ob˃eZ`nl#l)bo-n$YASHA;ޙ+W\-9!35!kTbKsir8ZdYg?rmȵX.@\+ 6B+H'%G:GPD^x_zjUO-]zת xK$rySwĈ߷~ּYfHFνܼl[OގHT!7ΝQ\L}pÓU[]szj4L=T*^VKQ@,r*ȹ@&(|GZH5*p K㢡7%3&sͨI.薸vfgP'a!vvh,'~6"h~YyrKQs]PpYʨ9Es |\Cy!m(yYOP#ѓUK؇]*X}(:IkJ'nU@Ӣ:yNK,jN*%)ήd&=smhP}F;])Gwyp0&t;4U(ʓeCgz֝S2zPVDګyȁ4P32kM0>V&i)3֤վ_׹X5M pX\]t䍝G&5|]$x_k-+1-nh1p( ' ) ]ɠ}5M3s59KR ,6_"7BH &~]P홠*m|y*^S7_h0akc88}n{,J5O9j ]%uJ=ߢ*$YGJ?^tE8y#UicX4{[_ͽM0$b9޶ﻶa1;Lг\4=)1` Yy^trԂ.< )WB;\衹'ç#_ ]"Z1gs,u#lHGR'R`246Tern8>BYz*)\l3N gBM [^QΉa׷*5OpbWo/eqhlWi̳/7R3endstream endobj 503 0 obj 2706 endobj 507 0 obj <> stream x[i~|14#&Id簄ywuC]>UG trt|lJPӴm8sZ9l%B+;lIT7[papl glNtNjLx%f+klբJǂ >h< 9G0μÿrspiOmym=jCmͤj1utyvYɬ3WQwgǟ7mV0aF0 װ%<7R2o[i,@s`A%M@0Ŵ7cGبD(!̒}Rfmˑu 3óMr79| <6q%oVOWoJ37D`_-D#OV}}}uszZ?O'맋{5aZ8଴3V&89| $z#U:;0XxK"pwx_UIz#D>.4߃GҰ{. ^%?!h2 p892\ f' ,q} ::&d ?aVh &`?F>إ'\Bհ]*Ѱcx>%Aܔ:'G/tBхcE}0ٌfj xyFp1 gV[\«=ݫ:O'7p|U"<,E r:QM$!Pˌ9d-^"'>b}J ,p[?+YٲHBC.R w^Ld+/Hl]#ao sgD;fC`EƓO d(K,;] ^Wcj$J,ŽX:&#Cآ$)ߦy!k !&6KߐLکkn&ՔRSg^Jų.k])6[g**[*mutr o^vax9*݉fDR7ve)%D10K90W}r "u>}H/"%۽C@:/~AjcM=H%jĊJБ BD^Nx (${39TcJ|b5q+t1.$BE:1[<@h-ȉMSis:,?Kv C2^w w,°Z&$p[E9Z> -G1\UX"J >'KǹI1=ye?)nr ZĹR'ՙhuNi[1OK/LAKwxH#i $cj1`L X(CaT@_AYv3Dͩ!NNCH=DjK ⮄wyC iN4 n L,1/D`yɘpװ@Ry$`/Eڂ 6tywGC ;Ѥ!v ,8 S*'>$ SUH1(B%]*""Vp%`~DžnAϕf=*Ji*]` s(= 2% heՂXgi;i3y l O4wJ*MD{b d+ =q:좇ME.{ǣnOx4aμ+k(H:z򊱵|XXTj^*s0ݳAhs{ {ng4 7 [J挦^ߏ3x &esYTc\$% D 8P1ʣ`&Rֹ"]"g`X C1ߔ!G<^$7;(}X{# 1G;aG7J$,9ѱͿ ,1Tw.A7lu ?P;xS%&%g1f^ž%UXN7XO2b8MI#<0d 7cUjThc\ܓ.6& |[ϺnF^xƻ)>S tv@ ٺrЪW{o1v@I`m6۶5҂%ÕKnkQGYH<>}8 ,G8 EoLB EŅr<!w\ug-d[ܨֳES J<` PU\!gCt_1_endstream endobj 508 0 obj 3534 endobj 512 0 obj <> stream x[ێ7cOi5$&lj',qAҮdI9Eb7{g,){xbթS}F߇/ww7v/_;cʣw/0}V/DoU{(ݿ{8чa5Pbxt8*iG烷u^̤(F)dEMu,>NZ\%$.$V]\K|ICOtc08Z>ɌB/pYOksio(4ҲYhǾ*#Jb4R z21%j7Ncp*xXss$$JMF8ɖk؋ IOYGU\nt>CxG)G+E3I*+>xvǴ]{yX}HW aVI #2Lm$ⰡI{fQbDA'i!%]tq1xb!%1:u`s ([:VI)?e\y׻0bTf1ɳit/'/jɊ|jӓl\fJQ"΁`Htأ7P\2L1)ؾ,QV7I bhG0jÃt/Y*e/TPYгiX'{慜BE?)P6afoeea.*-Y`zuͯe?ŔO(Ueֈe$Rb C0|58T܅d@.\>&9ܟTzUHD)\)ug&f"yLھIf /(Adat0E:|a04p&9|YW dД:/P= yhjDhVoQ2%̶?lIy.e.=[JULi\n$E >3/p9-sec93Jq03gM2@_13!P3 8^v-p2w) =Iuf簤rWlޡcy+.ɐxZJ@ eP8B;bJ1:"3rUFJ'YbIY Gb~q0uQTh^ py)]jՔmF] Tv_ETQE zsNI, jI ]vq^y8Cz${wT@s*ʴ$#{bYj:(*'S erTBRx'tLSo"V9 IVv~ndj2V~Rf# ѷbrb k\,w'l$٨N (yW;ؘQ6/Ӟ"ũ&ggZ/$Z\*v w M݄XGe0fk^(g2M֧ϻZ9O'6X98ϖJBnaMƤUgܼkȭ>&t})9xO5QjKF":&A9d6E:O k@ iRr}W& h(* ±19~[o;]BZTΫ4vd$ij-Xj6-#%,([73zl1#;nc)&aA,im]e-mKm rhu{/ 5j2xwF.@̠RjpZ:PDc.g=$wRZ (h2,NJ\RպUwQ>-/6.RA wZ-SOc0w V7 J~+0mUs"DגꨙCEGW)9O%sշ KD #ZrDz J,:}$הt> &Nbdogg>J Ne+Ɲ݀hF !V}4owjs5, E-+|RA!6nZz+&5O!lH9ӭ61:pVHJ}ƶ.to lK>MLZf$_$O@'_p?Tf1M > stream xZ{-V# NкiPv`\tg鷺߽3\r9˥b%m) X9oCtyz8~꺋Evduf!<a]`JB1gL7Wg_ 8!/]e"&3XvRL*)Cj)-9sZ_.Wq_W˕`rA.oY0މM,g+.5\Y_ b{7H-Pt,\izG;`gg$PqR8*B}ߚjr$G,?F◆9BBULׅE(ԻNTtqSڻ}q]JMCo e{28jP(T^_²u36Mc/ՄqaSPGϼP,Ƶ*'Mې$~7hT/l\wN^ 9:տWfG,Lsy"+* *K4D|kbI7$T2KC6%+PjU- >= cS}ybC!UrphP7LDvxU}-d9u {eFڤY>qT#U_ClV'N<\(E()Pv э@qWK0QE&5^`?)P]J\l 2C=|:&4Aq5V`Gᴝ,J\NMl,na(b[ | JK@LΤ pwL{1'i`{jmbAj:aocArτm39߂@f@nC^# p{ d&27VW -׻%iQtxTBBH!IS%HK[bfkAE=%ϱ㢸[^dLL&r%٣Kx!2S+li +\i}$ W !D?r4JQ@2!ى ;ˉ"#ƴP0=`;P^ePqf(X}7 Y7 XC LrcLvdP2:hdL5]ẁzz*`DL)5(o&[F9(T#{jwa)ЋiO2mF: #p4:/0 yDœśC.&t A2}㇏Ǐmow;8=GgwO2b |6E[OP25l@lfTpN˱+ѥ=8hpHuhs݆ad= maPag{7%?^*Mӷ 瘩 vH&lڄ8㌥y`R)(9 2.+E϶ I)Dژ-EKg%Z} }Nr[W6jnL Pݴ!1M{$KP?:ARFDd-א&I2dMׄmt%fG̝^qYrĹte=*kϷez;}|5\Cj0> stream x[[oAy |h/ɛu!(P$Y,[%%C{gxYґ-6C3\yLl9>zymO/7qv+?LWw6`ۃ ~kg~yy09sZ9qgeJ'2.óQ0euG$_ƝRi/Fø^ 'N0)5%θVv8㙒s?Mg+ tԵvAqA=&B a7.*ɻvI&;X0 ,xC@Noi}^g/U6gAV[Ueo|BpdTHÅ!cdAᗡNWO:" Lam:{Zg:f'/~"C"h"b8=AYv&OBjRP篛&=[j~5g%NՖ_T2$`Hn #yecl-d+ǵD+bY v'1zQb<~|As ~ؽhV<{+<)< (u&& gV':O?4HyvAΨB ]gbqn3\]p6Lg[""FqJgyOIg %"U1O2˵mLeh]BtR'@4N1'B^aS"-ohorWM_v=8V IHZ_ $OAn7ӰU5Ҁ:F` sA5 $#ãӅTVR6-k&5H+ZdN1SNpeZ*8Lޭ2\hzT&- ڐB|b~oy %,4S /F4ЗʬҩQx&LZ,s 0HOx<#v&'B_̑b".ñR(:5PUcUIcf uZ>W7}E(~Qgkyޥƴ@K֒NX{I@D|(2ۨŊ `o`6.=[5JPL -c=,4x/5!$9>nKR3X'>Iz֥zG(lGH2F,d9,U^sQxLpbBdA zJ8p4pR`KA&20`N'(P2IoF,L?+§Ln"Qs ]BNK~D$ܞ{W9͗W2!'B8,ocze0t(5'Ph5SAVq(SS䨊,,@dd).y^,$”YZ=e#0<'H{^(%]rM1U i;n9cE bG8+Ռc嘶P>(A5G+рtFd4@Ȣ_N5l`MJ=kM%0jQF_.b\Y/<# \ TqlAJ`_4m)͕!*Kh.1S8B.$AdJy*XN_+n\GcpHsJ0,G 㬣xiJ'j3'Ur7YCŖ gF Bj@ Ďv"2JJGKhgb Y܃w)Q*)` ԏiP?\BJ!*;B$S.c%u8>C3߹ȅ Wu:a'8K= nqwh{IiUoߔ!& qFmqbѬ]hHќ|MZȌ=ukp90/Ԗmt C7HqVׄFSNLG(&gݽuS{zZz:\ೈhQ|ݧ?+b;Ou %8n">V\ZHb >e0II6Fdbbol5s*湷iS ȫRqz^EQ2YBY(MEʭk]uJ<G?nx1F22hK\&-e ?bǣ|s˧B^ZMȂ~@)s:Y7|QL 4E/%~O*vB^EN |E\2`Piޖ4XQކ tzω@ 5hmQV!ӓޗ0THJ9vxg酂[3AbF%0Ԁi0 $gt㌗~/ Uػendstream endobj 523 0 obj 3018 endobj 527 0 obj <> stream x\ےq>bgf/z3%R,  K ɺteuWc/q0tUee7>N}5o?q/g_>\4>M$ R~g] {TƂPӁ[ ӫ $‚X MDIoHHY2))Û"bHJ81|$#]`"88yИ' 77i!(uQ 5(j#DԘ[-_&@,/7kI2V`&ȭl 2ړh OZƈ$H*7C:P \\a_zKB(w 7H%ڛ1&X뉼`D; *+$"?)/ =\֨.܄ױH8T_2VѬF@D? t鈍zGKҰPӈ:!Ol#6oG iyvMaV;;Ô#+QmUXqF9(=A7CG}.37rjTvY.vyKj(ȏ&݃MZIJnߦef]3KI1b_8o:]{,=ݦ777M[Z w>*K&-%5U@v-:Ȗ%fq倰N9ZpDwlOHP%5$_&vyIeL-Pms=̏>Mɣ+眦ќes[sSe^t "t5U6H_=gbP Mګ,ZMHkB: 8ODd( P:Δ }O ]L P%QV3d/4 CkM_$UJVTH٪ ~7AZ HhJ":&gn+- 'vp2@-t;Hc@+iR#M!qXd1%"LB+ED“0+*gSR8i!$!"2cOJ/k^[<$ Gewߝ_҂n&UFD#00bا.A@ yyRQ8M:|Ty5t vQta[$YO-AЭrp  <hEL(ḶۆطfBe@Pں<|E )bWq8|'Y9d{ₐnl4E٫6UδflбmrַˡglI ء8L1UEkOԒ(ΈD^S89(l_ 0,%u'b3 40i4H<[*W 6L m<R'В>qAګLiT*d.2az4X"9Od:l3xEEh ͼޑ6Z1cLo|*yu㻑fyg>E -/Bg:/i2]3p}mA-$A09BE KDB^4I1&|QEJ~-8ŽL`]fIhA%'fh[hɜv{dM MuC_#QvCnb$V3=oά+(PڗhRڏtʮFXыHLIͽWe𠝯TzTrlo`k~^jE5l=2MULuU3Q6Rg>_&O۱&jN%*}BlszD 񦬢.8Y7iQ=S\x\˧!GΪr_ʁoZ0|N "2X>.牆cF #F,0e!iU j`F΁2 y™8|Xzm1TG-frЀPl)gg}0& 2*DgU"֗{tme]u#uՕ3|,Q;HہJV ljZ!A0_Wy1XJR6R[QtXMܬ0;GUTDNOư5;tM|pI:}ܕޤdUAe_::Q9 QG8yQ!ETo"Id\\|{T K;6 ].@IM`jghT|Y)lC>Ҍ$F`k˰?9l )(4 %șjKo}NnG59zEQ$Zj Qh$bHeDٽIy*\atڱ naB2SdNI+ؾBU@ߠQsQ A:!CǸ9YJrMXE,.l! cha.G5\.J"9WGM ~Ǫ 4 tg9,+jFu2+x@M@w[]P^]:>)\$.ߎ"@ZRлG!Uj|@f* -Gqq2QnjwbdEk{[ea%V2~$Zkimmw1o$t_™?˼jP:,"(x3k&IVflAsE˾ ThLۀ3E;vץ*w0N,M[G)Av+x˅jzx~78vsA}3fv;fչ*gie7y-];ire; f-V7y ~(Gk*D߷M:o_46 þ(KJǾPXjsE]HRI&"X)ҧ)򤚲rBh6+| 5ӯMW{LwuźeC]5(e1ٲb:+ja <2_1.L|VMCm102 J9(r3/~*endstream endobj 528 0 obj 4636 endobj 532 0 obj <> stream x\Y]Go;>}6b YԄnH~5:ݷ "Yj2ȃ_Kxt nBÓgx!C\Sy+c8;o/rtK(9.'x:ӥnR?EH˓\3%0Kb:daeǯOrQw;/hw|/~TBڜ0 h711<6+߬ oc^b{!JiإKIzNoNqRrBK$^WA-㫓Y:1ob R,[w0}񤈋H27m_5iBeÔ*@'edGV 1+l}8W/*~2HαWY=49蔥[$2-CX~/i83bH˸ū6t,:X,R)IR%( r /z <%Pɧhp萵^<ρn")O;]h-)0-Sh$ 6&a|H~&tZ_M=Lr0h~ϴZJr^((Ǎ ~s?Kaʂ7ǟ.bBid+Ԩ`5F> 9 >ƕR``4-JͦwNۗH p<}06$&sGƞc܀=Xlm)D+oݔ9C`8u|~ .iRm`JO:z!AC̮OSVf'2-0\5ףx^w n^`jזӥ1fʟOS&r*񛙛"HhorZH;!UlzkbxM`=?}vŷͥY^ UHA뭬kG9pY9]|T$JtSCRcCnhkMyU= K}Fwx 鱘XQ> +r)]UA8ʋB)<ʜ&,nMԩ >q[M}K-<”TTIs{B~QF` ӈ.ʹ&]?']̼U@Ck`Y <~C߷DjHkXhX<ى~ ek .gTBۼ*[B1:71{%Co5K# NQRQ;{%=H7:,⭧gWGzqn?:DZ>(]pDеrHj8 čih8kfџ]ɿ'X1a59jJ<5V;()2{5neUQy(Q2ƂX3 "w6mq$q3>'([q\!3Սm;Y]>,Κ ByPB[` rYi  xQplk+@`:$A3ӌǮHRh}j~!=1jTmQը 0٬a F\.tXeJ~4SMrm.Eh{%3sB1y ؎G͵K ٤iEd6]{\9ru,̀YW}&KeR:**>UfAw/LpYg56a=-&{^,Q'.!R1rR84l1)>B%Mq#C#.T!g-Iɜp A$H~z7LJ~PISI2r@l np^ôbj}n`Z?m"Y-p{XG>@j *۴!/9~THCf0 W}ʅXsAmL9l̮;Cm@$Ϣjfz`tS'W-eFJ_ӊJ4F[K'>,- ,Dk]=FQ<W V@. -֛h~rvZO حBW83=E8M틢h $bqk ʱ>QOt?w*֠*%QWQvá<0cMj[yfKN[ 'أq1b jggǘNB<1ayk/S卍d /27nлSt][F_MWMi(^5J'uڝH~FZ#IIfC"pkŬr1SU4ǽ[iL:űa-N(~{nfױ4$ /ktڈq9Ofa;iLrY_ 7nTtU xn/u/'&G<ko^dpcߠ(;|zMyJ+'eZV@j6Հf2Y}t:I7bU&JMf+> stream xY[o7~ϯ8j J-BHj)=}xw' A9x.|83{lt%jgb+oVO~!g+ͷWsY.g{&a`E0эA܈T7aλSL*)(js-k9sZ췝d\he$j; *4gm.iz_0މ 3lNZ4W6;^K{ݡ۝t,{G?=yF` %HAIoaaÅaIllg5LÓ9m;6 K1aqd`oC|,c+/o[ŸAF%,4'F7{]04|FG; NHF]~G1PY!M( ɶ+\=iٵoI:J:Q C n3Ǡ|Gk':;kQэ2>K yPR2N(mfBOBn%zHyNn$I/VlUҗ ǥ+䂩m0Q֋CjP p&:&@Ң@L$WLbg7}gT5H*ePQ4#.wUYUjdZ3 %--ם2Ki!ίQEwۺ ?QR߫ANΜG,E&V*LdV2SBh̜$Wcc&{EtDGI]^NPEl=GTq7QyGR-_Wx$mw,222+nm"HwiT,ޚKxl_G&*3}wܒgo t¬i a8q_Gx's^?N9!kߵ)R:&rO{L{-3r =8%n+iۯ)v-gmoEU6"l܌N3j4tDqMR.IGUbʄ,S\8 qOJ5Ԥ[/wd[=v'(^MGTVaz9爞'2%EU[>}*APݨ|.ܘ^HD+J & A0)QFc^k9GYk$SDBq_/l NAz,4i%;׼9x!-b+mVGq6*5ݵ̞LѐL0$m'6g#=/Y5Pvx{0]:cQ{G\}dヸ$]A BzUJ`f@(wBH|‡UoBxJ hR kb)`4|oP_+yg CrOC̚bxmOa-xGYgrn%pӣn._zzvr=lMn37ФPsJÌE N 3LV*o .)!r /ColP Hw ϬRl _4{^N ^Y9{t쵳CNvҤ H$8:(dJ|և}9"[Q*( P6>Q0,9:If0wS-6\x'nW9ȡ @ԅF:?Nb&*ݻ4\-h4&5^Kt`~Y5>xa"endstream endobj 538 0 obj 1863 endobj 542 0 obj <> stream x\Yo3w<Ŋ( VI`"-TTU3=\ZV֨:1ɍʟWGoRFnҾ.~>/| StʙͳGr : aR߷nSš7ʪujl j}iޞZx7I)m4ᶷw+MZJI-x&~kg~ӓBG?v#ߍj26 iHiqԾt+?E NOf8/ow{c䅄N9ۛ^))^qe[odTq{QE^qڰ_7X,'as$3z[$:(vƼfMd]__jF8q-U eƒɅSXaLA;&%DWMwybE,{41ee!Ӡㅄ^1` 9\gQjA`WE6HnI\&rU=sZA( Rp7YPBȯ38A޻O$GNd:`X. 7В^L.rDpT I$wz%J1ʂ%,̾BHi[Е) ֔Ϸ>_,9VTUϏQt9 Lv̗.-l? |Ee@͋%Z% B`V,ʸ{t^1?uf>a?Q@p86Sy֗+@g3bR3ۋ羀<3LѓԶujϳB:n~"@r9 *BhdgN6ΰlR.je1J& ջb~ JXz%g%`;P"JzQ撠*dDPWvs#ip0x$2'+  mK݄'9,v)c TM5Wa&nIZgבm\iɗ80 x*LX:!h]Z5AYubdnue'XʝLU.$4! }qY (IyҺmy}Xgz蜌DdKT0AG K+Z]0<.L42ޫV%1Z\pwD{)7˳5-+9tۯK(drC$-F@O!en gXܸqQ(WHfuBmnx@-DXC%5y!K0EDRuǔ䥋s_5wWy8JΊԇY5x+U)xꎏ_fJ>ER@rt,@][bWBgsy+R|Xfw%bvәAnˊg\{\X=sKU+C`}:<+߸s9&(3 ‡י\A IjFe [q![V> M-䁍 3__tV /9+xWrtЁDWɮ/?Q .BjԀ)};20H7um.6BGf59.ی^ rRT‘6>DKE3约 |p?0Mz݈{$;Xz";9ؼq$@AB1y~~^f?Γr'MBՇo,޳˖r O<IWhKBaǞFėm6ϛhTNi wEƨCּ 'CTVxPb;8#`v"[*v`> stream xZmoIfOvpa$!tAN%;9 ߩꙮsEdnwOuWW=Tuϼ[Jƿݧay~{jZojGO/타$.j|>K0rމc3d'\5Փh` q֩4muXIv{교߽UɤrKPF*A\wN8M<_(T4[xߝ j0h]FPۛjwH.A_N*,<R[j]ˡ/Nh% S)RߚZ4zјEP+j~Ir ,s ttuF>iuV3 HWY7Y=N9"sZ U6\ܰÙag"=5n f{N}N!>یKz og6Fћz+;mCkj֚ZZ;uZK*(;园48hj8'iBwH vM(SGt7–Bxa7j=Y"vZ2Z,ń3twk&Էp_h]1ފy76s.t"!~=T.NVjzLG5v;o>nJlCgn»MTϲ(S:3g̔-iƽA#LdT{{`K><$r3ܶXږ5~l^k﹌6ɇád8};;FOȎBqVoʌi- ifcF2IߔR/e8ږW*?~fj2K] f pzzt}s:_q~P˯0);R˜TgV5(kea MZ@S> H)P}Kaep˸Ҡ%J)|~1ox L z$3GO0O{wx '"4JհoxOpU_*6-*Zա ;4hKSC]pĽ-$jWyu'x0tQs,s&ZʘM{p)XJ-+s-Cy0*L_WMTa":NY轀C5ڒFJ;ŽZD:`[#3P|ޒ iwWc}yh/2BT5{!RKVeͳQj|t0X @bjz.|*Dۨq6k _JC `h30 Vv$=oMwȖgo焩2V[Uચ. ÔUAi;m5X=x@@۫^É1C(~A kMTNB5-(S |\&l4V:s4UOȐm^<ʨXs lt:c&d4&3 èT" R1NE+){mP6rB!#_ LB0^Y&G `#I^>HH45}cbf Ù4FﱤQUtP cU{(jT˲RaP'sBWQG()ZpnbC0A5Z.ISG-c"ΈFK+TW*.,R1JU@|[`ضJ\MՌ+y|&dSS `dniDW%@hdp;{{ݽ?//WGݿ/bg˟--|oN2b⤲wI*4K/*6S4xݖa$]Ko|?V0PLs PV;dMdW Ery ': `m":NRF|]oXuVNb;NUpl/:ʹhLS,m=ɓq16R0Ye$z'UӶ?WMCWMb,"Zendstream endobj 548 0 obj 2414 endobj 552 0 obj <> stream xVKOAI4i9ӭ"!$BPq<0aABx,bVT?QL1jU_Q^17\MnъW;(]NM^w``LemDl‡5FZSic4ZScVNmЂiJ.H7Uk)Q)IfZJCUې1ȩR)rҋ55SdC . UuQ!{SIgBmZ+ ܽjVP7ީ1-}%ʀY#3E U ~o>L3Bʉr%J*MV+4yV&!ثQrrF-v'(- T4MGw!;C3Pbۃ6Ψ^/g!CRh #vXVO&X;B춠c'i8~x@{ZhuH$rAUdc(9~4̣E9n~ܮꈝPS]Ap+1^If*R~, kң.[e%?Z! =L;4wiC]fKJ"PǭrctTB8eǡ}FʂXF#g19Xؗ\CBpM6/ c"q2 m×acn_#(](*Xd5gWPDGv?"J^YG7r7ɧi6%,žFy6KxMF_+o6> stream xMNC1 E|Ed'J,eeC,} H}\7Z,A˝UO>|>U Z}i xL,ͰH36ԷvmYI72pf_k" $1pl;&aJ KU.\txԀZsawtM}ABendstream endobj 558 0 obj 205 endobj 562 0 obj <> stream xYoy+p485Pij!")Qd;]Y.T#@#|3}iEߋͳbw림{9=k~C1h T9u.9Mi僋)7۝QƐVԿko&f-YT#[J6FkTL2snӏ03\"oؖW&vG8}\ueX4m{` %㱔8?ePȌd0qDULH!ưIq<1aagĔ),uy.izv3%GppڴU\GNYLq]RϭN^mDp"gX z?l-)2d( 6a8o,aB/V6xamYa{ƚ3Z9TI]ODFF*uP(]Ofmf]CSMR4 S4<d4.ɵdqgO{;Z(\Y|cǐA=fIHʀ0pӁE$XvOH9ͽw b8g,9yǚE\37HElK/1ͩʱqVsр6<ƴƩW>DTHL-5I<<{__HwEE1 *Tnpc iNy3H&!!$ 7^L\&tf)W6Z)'K،b*nC%M"wHhOWA<(d7ncVt"GrёD$Ɵ?N ';U!@B%bCT"y2#A.QZ020)-?gήBDU&=L9J[MF^H}9|4١(?BX9hA>G)v5AYVcZY@g" @2<Կ]*_ޱq'ϔY)fM}^,(aP/jŏ5kl{UW}* \&2qc2c*6u˭ mCi @\ADd#YLKxޫ5e0pS(*z1Q`N2:ÚsT>ѿXW3K*Vcp =\-rq*G=, p@h}W?Qa6aFR10*~3"Mȹ[YJA [c3`wZW` .I/7US/dyj" g .?-99x{U@gWm5̕lHz8e-|yd D_@k4dp=C+xEjfD5hHU a_p*dE h`zJOSwBC$δÚ'Հ~Է`Nsvws"N!w3/ܣ_rmy x_8ج3D?~2 =& D .}MC zi2,|4kcoFkPwD=pjyg2\ܵv\![7x[]P{_zs3IXsm2KHMZN65B<|Q=)ĝ^$桕!:d= N5jȶM+y[*Uo ƌߋ\H.7}Y~/w(lPWYK_o%笧6)ú߶[uQ4ܴǯgѵH֥]YW!ul]"4ދ|N8 |jeQM-C\("TvM2JKeendstream endobj 563 0 obj 2374 endobj 567 0 obj <> stream x[[o8@^ rhlj'h'm CS8m79~.\Xq[0`\rf8ok)h-_y|u{~zF״7<=]\QEG:3룟V{/jmC o۝!Jk6*=]c_;-V*ƛzTlFYy)!h9+;E7o; b$Yh!4f˂QZ( $^lpFey𺌞'͹kw&8(=.2 m>/Oi^Ƽqb$MX+IDq(OXSH-l[X)2V M1>kQ^J*x8Z[}$|LnFؙTsO M]NMs+9U>kJo߳ZMVNxVW^ zJQ=n2qްsm:Wet}742%*N㊎RԛEY}5N?nGLOqNd@u{@V["FQhY8~U?I1=:Ap@\b?,~q(80&THc[5`dJ 2":$= F_08/ƀPI-mw8F5Az<$C0,U| x7/Qit:Jn|Ynhm-jI7gC|V!Z(~W@:er f}Dm/߷"GEI̘-ahur tR kb$ ݾuWW~X_bV4Q)+lc|RNpJI3!akg:lcp/!J\%eG41|X6#'޲ߩd cިUSG{by c ΆqH2eo$A%(is's6xc~Av7xyk);ImAT8 +vvzeG i'>BؖR˴YύZm$5"T7r$6Z:}M{sPJcGJF1roa=g%7Dὁʲ %HVN J4"@m.[G,6wIoW `f+ B:rZxPՅcUF}c`>S:슺[(mQ4{ fL 2bOj+mxbyq%Gs!}2`9c96\]*z1SȞjGp U]x񔃁pȇxn% iP Z7vRR+ME8$xbZdcdQ'X1Zax60ϣz!|EWsrHH {ƀcb)PGE0a8(2\ (}粋&dVNj啙fR jy~"+zGzGq$뀅GdӲzKHsTP;jۭ֜ ѵ3MRhU^Xy"0J#U.5H07_"c.i pQAD戡CdJoU _!" KJť)G d*;<(`I>Chs` 0!#_)(OㅬX 4,0 ^$| 扶Pj<3f!5)!4jēr_ ڐ *ZsxPnb1р;?(X{?)ih ĿOΏBm^Octw_t6->u~ p+a>5yޢl*SM'ϝ7Fc.鬊 Sxv:➠v:a"u^toB@ȩs[J]5 ;!CWUhrek܉kΞhpJvYhU_MDű5+&ꕑrP楳_.)!谻yEHETw؃y5QPKUB9%Oh}iM7xqr*e/c7ϣRnEr;D*_WzGr+, GbxasAݎ{T0ѕ/Zeʴ4SJ+<)7/ *L}ڹ+`D縂R ko1i4m :DcU(FP!n0= Wo3е탮.sً;T$Ѥ۪qېLEG= %E׳Z!-7\)`XV&5LD$SϥHk}%uÒgR{Ɉ+tQpSZ~!OQEݿMN'y8qON?++Y#P$\UzPjB.hLФ@L7"-+#;Y.!6wj=w ضt>:_џ'Z!ހF0ӄ0mN'gӉyҧ8(ѶݍR%2ӀscAގdһFRrmvޑt4Ł|!׊i5Sj^_.endstream endobj 568 0 obj 3597 endobj 572 0 obj <> stream x[Y&?b<Ŏ(vQ;0ݵV_d֮$ 6IXr#Hg{|qa(n#5|b$v#5&ōQh8fv{'bnN`[{Qz%Tҫ;E:n?Q96跿i7v0hw{ J#Vb l~6) Zy2n+(}^־K5o`Ҝ=:i!Pi&(Y`Xi~A$,JiN,qS qf} f^( ǐBQ'G܄bb;V{݊> QZ/cJ״F?OZk-Vp*_=ul!KG?aJ0J'J#L4ۯ"m$ ~l9 {VBړ:z O m;siY= ^!p6m̜.dFh%]K# ֧zʙg-C'ڠvOiRu\u6z(Һu(">b"iMy Ϫ,-a<`;+N&q9gUϙH^?\ Orpya4 l#ZrVHt)$xQ\аdDՌJ;TTkX8ljV'{e"%M̚GWA>g~kvUթJW=eyCGW",#=_(A>5JF ^3]bL[;3<[~pcтx&u#%&U垖/gڔQQ/4XH#(xQ0OSU=XkMA')4\!}D6ʌ 8Ug`* 9ZH4W#|3V؎X֬8, tI٦5Vt Xj& .&U1 ˹iR>~0aAAt@* 6/|; 3 䮦Df5>xO(DNn4YG-/gJ]B31g<5=[8=-_d C\%H}[CY'xYK cL`}mI_ +`i&ckBU*0p*%ɑZ-U*I>ʏ!,!''u ?up̐2+~-fhGYv!CnypYᷧ3rgC]4 }TG/4<(軥dp}| JZI梎 w;wcC 'DUO& Γ:z=(Z5kiG!*3s(?\ =wǻ̃Nq[}-CR!q'Wa6JtK Sfp&V&;)iofy?+oYu +]d)]j.ymbg5[(Ydt36lҘ6+zCY*VTU/_2?ZtF;<4awi|b<ӊ嵅hOn,ҕUh6< wP7w8ݰS7de:9H8Gۙ\rF[=TQEDZ4Yuqq)Gn9mK1F(c8vb}|;v1]΃J+{xJl{|4Q`b"6.쀛d:KK =N PF:M获i♯ |SgBd 8 <ɔZ8~59ksJDo"Z@Z>CI>܅YLJ^dN<ˢ+]df\y&lqi,徢ْZh5dg.eL,'wWG/7p:8ԓf#u~G^ߝ}:OemZ6TnCx7O݆OO& I?Dr$rÜMIa/zR~,wgK-q]e&7 ]6N̛Lfl&G'VP"4, Q:45eIuº##h&t*=#d}Átu%y#Rj;HӇwmUJU>m%mC9clR;+[V9`|&}#;Z&RF%a2&2^1;L t.tnfU._K-L qؚ2xM;g״܌7D7͊2ޔe+P/6Ëq!+r~ `'44lb~8g ye Ҽ}_EtpK/框kƺyFq^5U+g&Qe삨'̵_*i|io0.ϢQZ*J c܎k3scVŮBwTt+!KeL&G5u*ϱK*|Z_=<S$^;edj<7"2?5dGm]⨭ܿu˻+گJu^@[<̦;+:'Ewa^u1}%{r>g+&V:eﲋݨ$6 R0os֝S5qɌ5o6F3JA1F(A@Gʪ&˿C*+.7N4ys:kP61\{CŰ=B)e"/:{ ./F~y([ʛFXNHiT61i csxKy@˄J8j|P. gw7")po:<&x(^:lZ]/xPDڣYPv[$4Y|@W?ݬko',qpp}cү{VN{+5>,M.`m,k7b8J;!ZB kOF38!~_:ѯ+_ pv:?#h]yΑ:Cendstream endobj 573 0 obj 3962 endobj 577 0 obj <> stream x[Yo~roKs_Чf)⦋ (dIVؒ#K~3p+ј!,<Ǎj#ˣG_PzD#5A/(4޼7?Fhu*6X>*vR޾v{%O&mow{ brn{=Т۾a} j\&<^T*Ya~{1@u KqwQ*'KLH7Dp{2 aP{cvJcXh&HLU8̽accBZG;)V魪 LcgU|I65^o>&aHҨ‰?{%x>vʟkl/x2񤤶H|F&a u4jLH))Idck+bptof+˒iF-'fzan"6 )f'd$!ccr=1 4$mَĝSoc1j)@ }S((~:Yn'Y!Ӥ3v( "on $Ëy+2P'Rtˆ6 td e1ۘ@":̄ P4>?g#i~"R"d9 Zȋt^M M{ca^ N,hpK϶ AiTW97(,POm1[V 7ĸ.x=dÚ&>xv$2k{fJU5i&dV-P[-6MR[cTx~Ӡֹ.H]V ,T>3  ,a^;|\iX_JE}(>?>ǍBq,BǍ6 )zѣܝ=F=ɓOg_}x#c "0~s{s6چ޷iⷻ"|lEj#=2rdb)%4pkp894&R(%K(4tL  s9"" ӉyrsZ*)P86#W6yUF.@R8n3eÄ CDG82q9%g Q1$E_F_^ѓ:z^Gn쳳:Ἆk>7|*%hb-vrZ Wu:zYG/s[Nᎃwbi~:圆d7Σ7iZe:~o.SX4nbISS8ū*:z3_ %^&h&3J. 3>ܳ]gqq6JiQ) 6eW*IfDf}[;dڻ?i|%54=QtؐvahtzM& w!T:R'd7r)-gȟ@ƥ 2+J1Hj4S,1tFv՚z!) YsD~-_1#eYS[;R;%%!"Tf-ɔn[^NJǼ*Wl H 8V~E t'@D%hJ"t@}`|j+?h$1B0\`EHnY9K"jxWHfxemPt5 k? +eQ76'E@ڍyRC.5mHdS'[,Ua>yf\p ``~cSCj`03Tc>8a.*aLUq+k;v7U&VyHI䷳ltziՋ^}¹JC/v@ԗ! cv &SN{9#L@z"MKwIաJ{csw `Dfҹ:ı^\̑@_JjnRw.ҍhRWzX^M8ԉ٨g^PФ~YsFDiՇ!6Rub*b9af1ٲe/Q-?x3jB5:!n̲#Dtxn۲sye |U6P@8k YkonGIs"pބXoB8KJ^k567 StfWu)/jYrL/'i#CN+L/39f%Y0ef03юQҼH`buK09DAOq0B8^$h`$o?( ёD : T2vnDJ]m^ySͿft[֠HN5԰ s$?]H'ӎWFSE|[۝3,\#lǢq -Ld1p|7T'ٝrtԃ.Nh)V _ƻcJcJWO^!XujK9uу,H-E8YlT_36E*3"s:cE(+X 0Jc]i [ kj_]i0}kʶ7$&VJ kNG5Ť ƇOgASE$4$MV-bf3%ll_.2ҍ=xK@eCzS+UDQjIP&S׳d-@mtb6 B i87ZNʚz}u9I3k8_=wXoTC/]Ω}!װ|b<-jeZo٬Zf鲛ګ2x\w_X7endstream endobj 578 0 obj 3615 endobj 582 0 obj <> stream xZ[odǼ_Ч:P7)lٲ]l]R'$6ji~swk1ȵO~}|Jk~zen%?"~| !rf}z%VAǰ! oV! k6V (6fs Z͏xNn0DN &HvDV J9m6ZdkaeЛig^o`rsX_:nHhS,^G}˨y4zUG߾ui~>:y3@iĒXg<\tp].I=~8#ƒ7:zinu=p\Gދwfz$a >]͞7)58ʮk0戥 ۈЧ8-{&Fl-LqE-j,DŽp{FQ]0}jjq %, ];OT6`bwm,UʹYb Qʭ5?j,=I˹3y3 chW%pX|jƩ]r).qx=:fMh*>KGi11آZvP2ЃWӇ.0dC/ NNN)04Ly %U璏?2 $`_Y2Sihlךb.OZ}oՙSXuȺ<Ԃ$'5E$FW%߅a;vP:iN ! ) (xIlLۈJyE?ᵒBw#('ppj7̓naz`D| ^CBѩXh +{GEebJ)|¨YѴ[ /rH:1"KQ.|DPS3 )|)k&.s~ v&:V%1: 30^`Tׇ j$n<ީig*Ed+7ByJ?I:su[  7Ոv( hqavzQv\SvDcPJ[ շ܉5Z&c\j0{T}WЫdzCOuO(4*M`n)EeϻQwZ^IU{*~_䜨{IJڢo wlԮPty8e qpR_\s %3rmZP wr i.MB.7V}IbͿUhX>;QMGr mTrMB'GFxU'GתC[l$j&1l @fqZ)<۞lĘ.:9涎O-ޛ O1wvSYtl.͖NYF;|DI~zvukeoj߾O&MזհOZ"O!vSakVWA5M=iwZ1WהR^VAr y3CYL zD|ߴ-*m:{/_TK6)֪! *T{L+y0ЫzG^JEB >Â`}Ba7Q'Gs2x "y9p|lڏkinN#*Y*jJ8}wW1&Cy`o-CĎ vnpK4_St~e Gzm{Tzn~¦uVJA-z]%]MН7#lg;Dy%!>osGw}/yywU,WĄs5;wr~Z/~~ڒYdJŋ|m6 fSAloJendstream endobj 583 0 obj 2990 endobj 587 0 obj <> stream x\II,0ԍ0^bcit6TZq%##_t|~D~}#6y#_׏~yQz#o~׏dQcx@Ey#Y~N¦׏xB֜\3ĨHQ"39_RiWؼQV<_&E"7墎btiҞ^e\f"ywaA۳ٌΝ^dT[ hc?ƥMV˳?@]%C-~ADvYZ sz6[rO؛nm&Ao8gO{8`\ponݪ=zJ\v_T8 \ %tۄK Q,Q0k) (Nʹj;d3. <DE'a ۲N@I쪱EJH Z{ W&ZxYT(!wV66QܦIO/v]뀐vͿm?MHBdIO$ j3^9ۀ&袍8yk͂U1_ OTuZ* 0_q)=Єxe;y՟9)Jҝ٩Ou&`z4`!v(+!"Ϯ0f *sTy ΔƳ♢p_pN^a6kQ%^LM &E .|lq.oN[+iS&roo wI% |"3¸҃ :_1}yF-Q!B(Ecǁ]  ѓ"H쉨*Z\\qV[ms)oۢd}`ǫAB#B -)S?h?tj(2 @m}~8ܾlEn]=jلluU]m+foGqZSpצgY( D {Upp-Kör`}EqWa4S-I ]Zd2kM)68m.B(@6Oj};d!6LK#oj@%YR Frvqyalb'bg, 'x+(3j1ӷғ,6%%=B I0-e>wے?%_4yJr!b-|y-{;9b`5Yp[c0.>[FX}gö-@`6N% p` GǓn)0,T*ާR(` 4ow+lιGÖ`%"H`ȅPַ@cx54zeH!s"`!"!:)mHX6 NRl:Fd;' hNje:A*ꥍ0ǤߗRMG`3ea%Ϧ#2{As=di!+FfNsS zfNS֡>"Pg4t0VA/=dO_L$~w~dk0tucFdoaNՓ2^)nս\ Aom F`9o<_!e_i/eIJZouj֜*ި5AP'N\abԴqi:G~&Ӯw Tӿn ŏiߥ 5YSnhD $ȞKcM3 FeH+SZtː#C}/;FެDʝ@gWCBړCS 6;A[l7ݢQLy$@լk̦8H:`qw[L2|JY5+q+=z!j?`΃STE"NNUbFޒ7Y c9{#Ŕvf!  َsa =mvCNhrS3sAȹO)uށx73L\xvf:7e ͭr>홒G؍K7f-wmp};祣Z@\;mkBUBz @f8ʻNH IqAM*Iب]*^LjI$٪Tm@Q7{P0\E4}Ƌ.!,1B|@ݸ9y?"W {LեǫƶG }ln¢Nyu8hO5Qȩ,MMW S݃ѐ#~a)_&/+,v 7;Wb }&pR &Z?Ka)GI.Iyt, uE: ԕ6ݺ>DE՞~j)fљ$6&,Dތ݅pt#*m)(7J<؀Msߧ#RT0Ǫ.4$|(.%Ke4xM+Fʫץ#1l2=l>i3"bGMC㧽8GzlUFv-Zv[oVxǻ&j+tucd< mr A!CW'?;dCq#&,U%IG=fEF>]̾c匦9C Tٮ\Kb!,U+̓Qmprwu9`Oʰ!_sonQ'Di!K8y^q~F0)y8Cq? %ح0zGr+ѰܥYG=΢apw;㡾y"yO5t6}S0)t{+4,&]5eٓR~hN Z1+=j'weH9z&+Vɝ_pPK*ǭՐ r(1ѓ -G଎xdLR>[h9Vf&OYbOڠ7Q?YN,^⇑Ơ8sMs2:(/tmE£1[|qZ&Yznօ0fT.FX!{`b8\JNAl\ : ,->oFLkafִXY;e C4:?s`k8T].f+ Nq>yg 𦝆V_#hd:I:((gCOӤo:JfSEAgGY< 6;كq~8 i2vj$売;d>~K}&yTPnZ![_v-#/ӑ~:9BKAw8HrZ A2{@[jxOXh#ǂx\=M.$ݓs oPD7OBx;W47KqцK|S6FWO \msm ׎G客1Zi"CKg\,‘sy<:qpȔOC{@[4əVTv*>Nܕ#y-/q~(DHcՉM֖ZKMJZoI$ K&'v.}p}O\祥ۘvχ*pFe d}ĸ8XÐ?7H#S <\ LZ`x_?>*-@âC]ub-~׏{m3_3+q@Jl?g\яvLS/ߜ1;[CAd!d;H bx6W)j[HΗOk<.#xvӺtvw $_erM1)rήYԿ?SR {%p ]UgHĥ}H0{I/K9,?ܗ Gendstream endobj 588 0 obj 5170 endobj 592 0 obj <> stream x\YGr?t/إ5AkZ+D-CHH)ZqEUY3C45YWd_?"+>xv=x" Y'!.)g_K1l›g}]BXQV[T{'hg=~'0ǏOgm"<~NݥtRF[W~1Z޿8ZB'4">>Ƕuǫ&Z. ZEAˇglˎ\>;cт8k_E eIdjtaN.9?fĝz9ؔ?ʠoNDAn(Ze\ZZ2>mMgyȞƔ+hN]<ׇNђb:>;Akي3i}4l=/&&2e찲'b鱪>_ߜک.mm(g R`wOgAz0Te<}_ytdYԂ]c/θ = LYkͬ0TiO2Î~GP j6e{gW)hSӃf}=SB]ݰ}З Z]t9{bd#Tlqke2y1A eE(`M%azq{\U:Ù,h%TtEІN`^ RU 6/E12NV)S٦{d^-0B -!1P͔O.7ϓ63s-0 T)&m~u8:!fx8oF*.ΰ o!9}POIG6N6}S: M;E ,LK:d_T1ƅ'KEwlJj,%k-ܬU-;"51&32o&f+\=)k] s+ױ$X)鋡2ngM/n([)y =$[c8KeK-?7vvO=>JXhɸMYT`KK}h|,PY B3tǬ d(ZP_xbȄ[E0Ry )q8ů' 'S3aE3B o ISR42Z8wwW6I^=#Oz`чS(&]TwXiV6C10I(¬IZZm۠#4)VwVٍ LڟM3|]8(O!0Mbq!z%0׋6\(>w&ن7p KRdO2u DzYb8ܳ $fT-0|N-bbɇMsc+Cox&1R'wR HmhL) `c$S<#"tf{jH!&F,61LUv`Xz[\H(@*h{=̻$ G}Y= &=,q{*7.>A^|O.>{j?G(g9BIY'#|BrTV0=ﰸ;8lU]#`hOnY@yxy z 2y: _|kCT'v^|z}G{UN) };T&׌ ļ8[ۛxX 䇻a㷽Sa I(L>G;BE٦! ̌It\=~37u!`1cxZ@·2XR;RMr 6jkSJ;\4 ֚|f^x 3e=hǢ aw{<챟>Bꗜ))jYaUЬ)Vi@4>8嬢Ogyxcڦ`Uxgum5BSR54xĊasDߛ9 }(J`jLRz!FSJbBc6ѳz[[c t{᳂@pLvs+CrKCɽ4H nH= Z[yeA|r"0e$utNfۭ.Y92) R4a!9JF 5wz\BI֏RPEc]$R )й4K)6?1H2Q^x^ⲫz-2bg 6wͣuuz]"jB+UIGM2!$WIerv+aLF2^C >opV0âNAƓE\+a<,2 Bڳ |ژìGEeLˆ gxڱ94D蟯yaLy8ƦQUB$$bjM7٘e+p(sjn`vO8)촢+g&s 7/3@N8sd_S#^ΊދTNArNxbX'Cw m<7|Js4ܹy27ƕ g ;O\ۚ`vȫRHc]Z{oWGp[RىfWgC\? ,4 )!C[tTwqRej˓|V,{2&թdֵؒ4۾6lJx jWC55f;/BERct])Td9ٱ7Lp A3-% FTI`V)&_HqvLc${µAtޣaӴ]'7./pzwW;jZ 9#ۜЌ6(&3> <9U`B<V7ӠUŢrSdMa P{qRwO('L"7GyrGW}F&9in5z~5Faw&*ؕweEVU }(y%U%=U]'qG' q'cS4 M >0yzDj{.ѫBb%ZMT گB4{RĨ9ؤj'WLD^[E&J-Ǟt{_MSqx:Z&Ԩ|!E6lm/)7^f5I5T5׉~HL zꃶ܅~^瘩\_\Le.hhwiKx6{,ray'SjޮlSendstream endobj 593 0 obj 5269 endobj 597 0 obj <> stream xZYo\ ?b 2%}]uqIQ,Gl7vޅr$ŵќK,Yk)ZW*Ϯ4zzR?!(N"yJ ߇ zbZإ։]Ø7&`y5B8Y"Xtwj!5{Ql>Խl%ʹE)׽i} j& /7* 7VXizc詮Y[Dr)Կhqx>OUwQFkM.}̽ ʏ&qu4/7Q/1mnϧYBޓܴrAV٪F;ֆd!ȭں ;T`<̲o.^nq RH Lv4^ L4e#1@{44ILsZE0A&l-CHwRn7AFGSD^ F:Zl. =! mT85ڀ}Na(2F 2 "( I!~LB{7P :M= i']~cI)؈ePJun>|g@"tBxp ·ZLg XL=Klo.wtN0h@?aB[wa ehع8RepFDk#C}=#7K2`%} З4EEDGjy$ua6҄u60,fS<ʀGrɖ%_at G r;cyF-/;P6m(ó29 ALZH'|. 軯ʷ_O/X \sB@ޒn^oO8q+S ۽.>.GȯQ}6 ގZxQNi>{Y&w.+sC/<"W)ϊ l-m";ƿ[5ʢAYs)3B+)('f\TEr{m3eG$j_`fp,OTK(]4 Np5 ,J2sG!!K16P$aY[HHy$0sHdgï*Jb7B#W,Gّ ԘNJB%I+e=!S;M#y/T ocmS;ٔ Y&baC$X#Y8FVH> d/,׾* ѪN&9:Irq'վ5P?1~X$߄:,܏=%AfvKͭu6ƹnKQnYVZlzpuQ #筞lR hIf ~8~ًGR'/}Ntq lb-ܔZKM]e !r2- }>\=[^+bnoi`KS|ԇ~duNW]{?O~=隶'mSrKgH<$%@o1)a{q#́ùtlw١ge1cR}%\nҵ}WY˰tΙm *4=6j7_*.z84lt4YN?}xP&ѷۨ$U|\r D9RH,{jܙ; 8QFe4;x/F&5XF4bVWonow @ncu'QRWEC37»Ն]ŵ.efɑT@: 꽇 qL;BB]Ur翧]gt?u] 3rżF^GnpaJpzͩ)X;(=#7&7-w2g|">̬A( Uyy.*;B&TBr{ rztp{ٓ [t:8JOG 2ME%T@*LAܶ)5y>-C !l0HqbDVd˂i3+cnZTs>"5c QS >u>_"D[$8ՖZ&ʠ E{ߝt9!rCjaZ"a~1"jG| poIJmڡU~YDV<"Y?28Tnb ˾>+!{5Ze&5c a{u J=yza.t~:q 촬)QAz} 0ߝ$2CIq5c18bނu&"niU=-mQט7~4 ښD fx2lɦ1u~8T'h. 65tW'U#J#3z5h~P҆J0"?޿ j嶞[wmYb8'lpLܓZ>#sdh }'-oSY> stream x[[TG~I*;6 KeQkF;b]Z|ݭyB%>n= oWw՛#LqDѳ;%Iqbߜ9։Hv:(=<(a5nxNX/R}lfV=AXc;'Se^KiZ؋zx1ZbuS2V['8 Y1LfӶ*[ 9p+~Z {R3$p"X~k|Q'c34R{?D,(=juu{vmZo*J5r:lBlU;|VNkv!rW0oCF6[ QR~ZÄg> ilcɤy,\^ȘΩg{0 FEOPC#wB[ b&4/f'DX E]^@qI6KJzTv 2qL #;dt,{>+IJt ZZWu)FM&Mq +gQ:u ꓍ƲއbNGqX--+-rS[ө(cvHuNQ;SH]#{n3}^F- MZz wmDۖ.j'ҔɧHi,:]YQ bz6=F{~mv²(Kv]94-i]8 bA#D#.TvQk4SY~b9`N{LXWivdcRY]}χ8#Lʆm:Iv絓wPC}xky C_ձ%>U6q)(/{ĠL>AD 7dov+*ﺗz.!@y/e<߹NOQg9R+IU~Ei'Swa=;ks,h.`+sGo\C>R[#l?N/EdDnmbv HFΰH*vy^Pb Ϛr[JY@JOn2Fmi]D6%ԖNɦ}E9ߜntMay)/H")Pʧ5VeMsi,b?^\Dl9NfC2sުjB 94T(D'MCˤuoة$-& Z ]+/@V4#ˈcO,1&O!_͠R%iDW4ڷ0䫍 )r'Hs&Ϲd[MRʚW&gפ;$@u Z[R+1:N6-SOUw:F=A2u.7L'12Ade7NfU:]CT1:5*g9 gѨ~.&o+$wQ.;Z;^Ewcm& b;ܔxf;׹1ЕQ$S&'?o?@Muu#Pcf ]XGe*~5'q$&ع An)hzCf<Qs"FjRZ}<5ojU&DʶQ`tWԯ_VTTVL&d~ИI, U*F õ)gBudcm><ŭp)!ܛ/HIKr~cL~TE{Ӥ򺦁uElj^,\Uޔg>@_*Q:c7O+'M\ĚcM\n A+]EyIl9AR:)!=c;hGcMT_DHޏ?~% w{}==| hMLzOmK<ړP2zfNIK)>q`Ж{k)ƞ&9~bTl-UZl]vfl`(8endstream endobj 603 0 obj 3105 endobj 607 0 obj <> stream x[[o\d)/SkCS؆-K87<Hu`\rf͝yB-%}x{-R-W Cw$.^~}"x.F+8tv%0d!kD@i>i`XKvzzB*ke>[o>Xo$ʹiGRnuBNTMU*:_[a~ jUa>.7:R8\oHQz!A2a=a}SfVhlndꏘ.z`vbݱtXf_eW(Wect1ˇR횙0zz05Z[s1JX  #]i|fpVx?(dNN[bvIp%N R%!Qlw1ٸ8&|6[S2 ^of @ Fs(bDM%aXe̽*L0Lwk9thPf\+"xgP''gr2h-y;?0/B' 042QŸj t^ tW}N!=9l溭OBŸ?IWO3@qG~|!i%&GڥzEU1փ!xv 1X!Ʀv:#FEzoFNXd$ܢBWщ&!@E9IS حuJ "y`f⤤]5[%]]oIE60z4}M4#2ȊnpYwK0eKz=v \;`I)'`Lh!,x"ǭLg+'= $(D2A"mDRadՎNg'!JBS0HF3ލ9r= # wd͐a MLC̗\Y[$jgU܊oq:H;*f <@6ZvNR@Fx\;ZC ;#aBehzHeM&Pe(Lt?M 6-S28s\tVƼYæ4w,iRj%*zLYm ŕ>HUGĚ$oMFƮe[(B TpFr 8͹.sWY8m(MXsGF;Sf;\ԿjK+nG\k[T`mSsACoT;In,d87eɿ{Ԭ.(17jyՈgɇ'1iAHao4_Hv;:Q6jwϪQ{ev e[D폮!dki#S(OF)O98yR'l$Wc@ת*cOIBءm(>uI1 %jHqIg{"҈+9gf.tZA}ƪ05i;24o6Kv>)ӷ%u4cxdg-f~Zw|trBgs9-p1XoP |]6 nrv2)fu?i-uX,C"ώT84gd= kvrfW ՓMhhYjc^ |ׂmb'W KU5KN~|+80tz:67ȇYӉ]ȱޒc: PN2ƻyC$cG\SE<ybT9eIJiAfSKO9Z&":[c_w [tVWedj<@WI0.+U;عЮ\M;A 7" leĆhz0dAR"+wvi3ڭU+bΩ7I]Q.I;'&Qp(!xdߌn?"Eܛv\oȼ  n]Q )3߾o `֡kjj@7$5JEt.C+e1ZAznk`Nmۏ@kDo:q;;:] >=W,Զ˛}U^A-B5- 0s;(V[U kMߓ4', ܩzJ^:,k(;M̯g]%ߵJD$]MHg @m&|QF3%{Y;xJZϞM/ACA^ӵ)gL.o*0 f`EWF0{Njendstream endobj 608 0 obj 3092 endobj 612 0 obj <> stream x[[o894)iiZ"I(l%GSp;.WRH >73 ?oP[I?O^o}/o6yt~y_dy{>qDы*;%IqbO^oۅ;"X.ya}Wxk[It0 T^M_Svzw<{;=OqwV!hL eF>/dX+~Y'*z<ƨ_gi)IAƒڥ2MAMZ𺲩bsڙ"%>Ҳy|͓J* 'yC^u,2dB6I8Fk#VEFW˰}. m]8)6=uMd'Dv*~_ ?BDXVSKFgZ2~1‘.%?큔'VR z;8^"Ek ü! GC(KxGyx>z |3-yHr9wĩ޽Wg^ji^F_Vw?F Bba2%-`:r ~lc T:xޮnF}<|wn7}:^rKNy3n`($vGyYm6yOwkWC%+O! ']+~n mE)}}TIz&{ϣ?52IAYP z$3b-M\H#ʯIinl#)*d*ܽ^11U|*%5{.2L2&VJ0}{K4EblcY3U އssKӦ9ӄq8}p74Art_cfbBEaFwAbYp$SJ K:,` Bvu#mO)CI^]-)M'edN2p>8< 2d(3:sVR7p*UOkA߯`H5&L6mf7źD\$8ZP49#J]*#x/J`QPw묟j$=(L7N~ n%wǮ]X3ljrMe]ݳMȱ@7jS?,כΗ- 8qqk||?o6Ug}՟l?||( [cZgpCTj2r 3?0E9Abd&uTfQ #*r+򤝣Yp ŘcSz#p x)KEؼ}V̞Y[dԠ.hxaM4E~gj2Er[x|`3>/`UI Y^T M-9d\TEAf(=E%=:uUXʙ1[WĹW8he )o3IV9^V |I׽m5)x \+9sD5 _[gDv#/~F vZ&]MnHAak^:K|8`(*U^]_9Boz ,S'+S`mulGcbC3Ð{(AArӐͯ%,&*6ldMhj h,qa]UITU |]}Dz|橦Lh[`HL%ʖ.xf#`!.@u\j jq"p+NZ?K7fSؒS&>MDUC۵K>ɚǠ:T a=m3C\3 jJq9X[~WD.Z5ş;jQJ՗c&k|mNy*P}uiElJ?Іϩ)*=JӪd$k+{2 GoCILؖUݝvx"/. :}\!Al B'kR DP8 HR"8B;<1fUN|`p?2DcW{ ExO>P95@p׿^i^=ģO')ݜq/iIŐRa^Wz5T`ABM ~KbqԿxfj}&5&`|No&]tܚjr&8IkwGƆtg"uCa.F=pbbIP9\Q"jfr NUrrSk=\ 9v+LaYj^dmj:ny) MY/$R'P7V{aKs֨DEcyX2l=֫S=v곪~ֱɉ**f tytNy..yt{E[]{EY]fxPw>ѱ,Cf4[vs>̝H:vSgf{avveR\Yz?kendstream endobj 613 0 obj 3580 endobj 617 0 obj <> stream x[Ys?bg?-0fw!>VI"@/ Ȭ*/YN?^=듷ԻcJ_D Rcrf}|%x;Z://Wv! k6"5Cz|==;8nwSZ847ۊeNuB6gv';墎w۝]BZy ݼn\2f"2t2hؚ jYNӹ)ECt15}Yޓ+g`WX9S.ͼ1ozw&qqyEFt7*LmgLYi/=:-ޖNo7 {[zϦ0 A,IjIz5w޲j{E%C'4c݆K]Ḑmiq Q;3f!"HMV[D BMx( tƱg uk';<$ FlS -0ḇJ'-`Ngx#aם1>L1}J ^21  V`@9{aH[0$ sx|P'%eF^UV:*Y+)/IV1 fQ'.Ȭ\Y^i~%b F S&yhD,P A/2*쥝Awt@ؔ 1q&'I$ʲ|æZC ݐ)  -ݠ."?~/s^}WOXwL Ej*9q(`IyT>NoG.d4/&Mxxw\\Q>VIz>_ ǾeqENL3+H2PG_]s+]:+8) @je~_ !#oA Ր:UC2}u!0_Ol<"6s&r%78h֞ Wݝ.XX5j jbdV`hpǭ}#|N*VWoKXZ2U ս?]Z{xV?NУPB16\gaN@G&\ʨ#QNʦ(4HR궥ƌ:mV}GE@{ONTs wi{?4Sav~YȐ$*yȵ 㔌I_`5ϖN _ȳj^EzКRj002~YHP?Z-ǯX(ZrZfXlR4AQ#;V6tF{A42K1YScqE,Yi"X>6=`.݁!"]h9/yseӠy(kit9^ڦK<*c$C9́SCs:3^*BqSt_O~SġŔ`"bA ltC H2vkBTV͋-'Kmrcd4gcf1;y'b'AY`(Pa qeȁn;T[+d" ] xTǨ8y)impg@{"bt0 1*\j >@%Z&3*'j'.YSp8gwt<G9DBHB "e6O(zW)d , {6?4ѫH:)"Vd:TH/[BX()o䪑˜͟RIy s67(IOtiRlfS NNfMQx‡k%>4}l}^zYeOi}bpS'ݐ4͹Vt|K\dgX5-;8䳤4TRRZlnaއT%pϺdOXm0F#zd( 7(vo!ӫtL!oQqL\j*WU-^+>FGxݼP@$gQx1Y^4c .հ\#b:Ǽ~+yCP]D#C@8,SSFdpZɸG)ltk<>DvMAB`8KIE]m5~Up3\*Y)g#ս/G#2|9}ˆ`@I[8@ :,V.eo*+%OI,,…jNDEIA ayQ;M"˺E2^.e Pw_8^̽~^X_%џ;6>Tv[CIg<5q*u޼:C959y.ODpoXqZw-OA\lvJSΈY:CWia-5ܒ3/wT̖FmTd"YxvPĦ ھ8yꧦr;S&y#wS ?\e<ӷX{_8+JJʛefX ~J9?^9endstream endobj 618 0 obj 3375 endobj 622 0 obj <> stream x[[oA~rN4@ݤml Ƀ$K/RtqlʒkAÙǙ!Ztr-C>\޵\[ZWFDŽֱN9x+cX://W7~]šM7ʪL!F۝mnev-0/;M' FvBn^۝2m.E%DؼTvs^^mugrpqVxeF+˼Ƞ7u-:ӆ~Q(~;$W 3P2 xiHJѹJEkMwʣ ZNd<1z^O)7q'%IBi );P:@ ̉EuCܨߎ2:mpҳI}K<| vnMsPfA#Ҭ 0-}1FwJ e6`AhN97]V ;Ҵi쁀 ui1cZUusۨvKVlll^eNtOjQ&' tiMDbPYOTr,ѴQV8XNH5J ܫD0RAbK&\YYC )Q*)پ}VH$ʻ63Xb@ɺ4@+fi޺щwi ^ak3'*iEB+VE@smOA~Mѓ%ۡ,-b)#BGR9OZ]" NxoI+U~uawUBl,́2?BO? z:z~F`H~\8pq{/k6׵y>ZS(x?z޷{ZuttwGsMKl.2gM\d-,'9 plag,AxnycޓڻWzIh͏%΋{VǾ(<ݫƈ1!19Lne|hoU!~{ )ؒ1V+x֔*3 `yOj \ U.̜d`hW{˦O`@lcUE;Q>M̭>LF:Fc ys#ؑd[19v.t.Uר H.Ɔ>kWyQwR\n(BP Y};1Dw@P$.ֻHfkNEd(OK-{+tb*Bi턓Oӥq/m# ~*gq"}'CERMKR H_Ү: Z"%KTD,Kn7PPX=8r%{ iqQa܇s!@7*B߮/AB1 yFZVg5?K=] 'F"L.8P0#dȒy;:[JՔbߛ-*;)'qh(H R (}]sG9mn32;TA(gVG(?XB9]Fy\vŻ&u~`60rg:?[=xjʓqp _|e4b3%>%ËJgh>{&X;f3fca4M0.7ES1ZSaw _5P*&ĦtK+TM-?~X5R%2t2.݈fs$]̥7 g?˛(O 53fUAULfR/`O\w!exbxB qV~7Up3̟)ŶNwn*zy" )_omB(jaQAG$م)ukx5>`zs/s8,~aG5ƴ6nV{m4]J2u1|v 2`S]Jއ[nҖSNB6Pid%،9 L+4&;n*{>% Bbk`^;eLfFf,V4T/߹:<::/ MD@hU T5*(Nqn@!dzfqs!U1>ep76Ǩs;) U ~!imZYF;/^<t{Vq]vhQrHmkԬ[A^LR:)&e b8D'X\F4+EP1Xn+AQ"]k~]#mΎH4{rսX_]\{ko,>8<RqH?+!D*hzb,#T@S("Zo¡s==J'J[}șV-#|VljԶFӎ W/Qo-8Ν\_Ѣv{>o(.E'ގNkvendstream endobj 623 0 obj 3435 endobj 627 0 obj <> stream xZo6 ~ŭ _+䇄 v]݀ iդ%ޥhad["%/~(KYIc>8mQsNGF#_ \5ӥ(݈響Ue&ƅRLN'iΊ<Ri-o? h_7=4?MRɄB;2r&rQd6Ix.=3QjI2^ɼU"9م(Uŭ\r>q%E,dY&ǭj<+v)Uv*`*R1U骵`c"YVdJn#S)iDf ˺0=$v,`ʓ X^9NBvL\ϹeO_k;Ngc;4MBuDx UMy, ;! ԛ$-`pD ) tygLs[QڣSρ0zG%<j`,:؁{h!opbb+]Gn-sO[PS Qg>xSMx߀M-)k ]Δy֞&w3>?#'G ]vx` ӧBO\zI>Pg."^BwD|Gim (hswdR=(0D~Ms|Uf\:@YX[ qB㇇-*_X}.Wc$QQLsQ;7^!^aּ 8'v+{#9 [PTy|tQ$o}j,@:@(Tq[ܿsL_a6R"[g@ XKe*P+U\U( 'TS]ݎ(L=/jݼJ{O׵֋2yEsTzd__^]So(x v;5e4}TpO˻2_/fiǪ'wNo0JF+ *(7^#@a+NՀV`gW‡ɓA0!`GMg1X6x*[3}"!Q k eY~;se L֘%q> }EGEo- IBp|!eGDcve4G9g8v9SLqm! {qCQx7~\yM7pQLEMl1 ?КO)My1zMg9o& 47V,۴{Fa+7|8D_xF˂86x3|egbXlϝP_PL6[P~<~;T=2_Kaz># "5՜FԜLvO|G7o3/n w(VH>Iɳ!endstream endobj 628 0 obj 1737 endobj 632 0 obj <> stream xZo]GnG\sܓ}?TC@Tђ^E;v}3gf=nb!!^Ͼ=a%FS~|{_$J!ﶰ!USάdYot +¨`_ofbFY5D 1j:Fb-G팶702 3uo4Bǐb2Oh ސ2D+-hێѓΎD3^)6mdȁBe$Q ЏH zrD ^}չaV~ƎΆḳeQ'Zf]qZEt-KppaS%T755!tXՏمv-?:z"Pb,t'Wt P< 3Q*pvY;~ EDG\MDc3I9> +u;Һ#F%7r0a21bǰl,c buGSgygJyK00-dcF@`1tQf]W|J0M,078,<8KfJOSitK;HSKB,M{'i?:*C8e|ՓGYeEݖDԇ3gM%|<1{" yF%{W4 * {kk-Gt?l?c?׷]ƤS^"s߷HZq&]",tkqC1Pw>lSt@%fNcPfq 'hWVF+-Ra6р)'Nx02 絗j†7`@oa!B:8!bNrp:'_q8itVLV[($l7d,>291 DGfiGmѡuG捊X+"t12z^CcVnNP ImO+˥>XR *J%Of.Ի>/w g{f&R9X.uD)2Ѫ!L+OI >tjiFzq$x:ڨ;FÌ~}Gyua*,DԡVX5p F%4 [STrz;2h)P?tB%J&\V$T.~@f ǒd* +OFNqbv wEpKLAɢW'}I[e!1߸~.i,/ۓ}"OݭI\[P*B=BS,pyCKlG0WN^w]Ǻ#E*?Pr)1#hp4@[ qj-[}6MHE! dL^". zvi)Th=%D.;Ԓq(P(+ ` 7dcrU Yn&9dwXSu*o w@";frV P&gh؀JClvxxަ6Y;Q=~%5S1zp"WzZ(I}t" >8bu>)-Xόy/bC}@K3q}S_Oչim+U"YW@BC:Β.8YFYJi׵!S0eIJ@*v)p09GKxsSGNt'i yRxkUmueНfS-$ [b:LХ(<wGԴ( h^^ᬢC]tbGץpofg\u-WXW=AXֱ۫/wlAȭykh#:= Gr/u3Іذ%)T.kc-@Ժ' Ӥԗ9oZVSrv4[lu A6YY+0dtLJM( ^b717(U9!/|ŧӹb=S_l2n?Tendstream endobj 633 0 obj 2752 endobj 637 0 obj <> stream xY[sݶiJzr`,>ʼngmcLv:$[˖|m-@ Ċ^v|IA٫g{nf;꾟G/wov4!ݣ^ Er;<Ѹ{T A(n[u{x+9榄}>k=Șm$;Hj[lDZ98$Vao5v_ V굽u` ΞI'2n48g?n)>eaDTHl ~bZ_~= x Lw™F29wBGX;:6؄UBRގ t $h !@<~lDH ( $)MDthG Jj4xV' IɧԚ`!]Y5ǜfciUE34(EUxv1A{z>|&aPMJJcQX"_0]DڻYC2jǛU++\ol'WyN;C#KYtz8-*WeU-7e}G_Ϛn[X)HCY,xWfix^2_ R]kCoG?Xۤ>~5ϲH"N 4. b3,nH`Bϊ")kvڎ^ûQ%փO*l eGE!!a,s]xUaMD2$z$O&2[eQ=6D]Y6U)1j[hEpPgP3Zx7>b xfK#Uly Nk܁'QlfreE“:#qg>ȌQҗ,@)Ma+o)P3 G[d욼 H0{ I h %ENE*&]"NUeT9JE TU;-ZjDJecuRѡuV>Ltz#GJ"8rj[d6Pv(XQ!ƈSu ,ej{Tbf|R]93'f |INN [gknKJv99aQWw+P_ߚ Z D_T]p[}! PJ[o<5_֊UE9n.*WmqD>oU67|,y],9jY=Lendstream endobj 638 0 obj 2357 endobj 642 0 obj <> stream xZKsΙol[U9Ċ+$$9DDDZֿ 3c0x4?|~iev꿗gwןJZ>]G;r;* gF%%#w;Jλ=Eee%Wu9YzYd}ߛW9 kh *yQC2zנ霅.{a}ciߖ:Me!E5E4SVBu.BYw{ վ{^)DNLNb8 q'#8~ץ{ͳrqRD–/GPZ crk@"֪;yJ*bvuwOsf\t᝛>4M70 t&&ŊBI/sj2WA<ҺfGF,:qTݘr)2<W܋Arhlc5Y)inn0p}!6^'{!.ܠ5\ @$k qZM4_ڄk=\8.Aް !8=xehf( w`;g3UA77/mn5x K[Ա!nRs*Y*Y;.ry<7! yLfA)م'DpuR C2۵e=9{0$A4@!C~ QA98!@ءKX)axkcrlo`J_,O{2<,zeEFhJn[l91?h,(0FS,3h,{A9C |ݰ_9^vģ9IXumː_:/}1g޻r2!ġ믈 ^ȒoVBwFbݦaQ+qc-\rQyٵ~Wn~$`3 JƐ8K2Pb+#9icvm3஛cAtd2Y` aoE8>T$";jt@I`Hty+бYePPm6@N2,O@up }.FWDde^nT h2mW[ms*b2/wpgz}o>gYO4c 4՛S}#s;k\L:M?.}_zf:/9739We[ !\:l7IsȜ˗ 6_aw2K%ђ^\~R`3 1'ܘS#DNCxu֚b-~6OL▷r|tgI߶}-x;3LFeW:r k#Y 5.'JQ 8o_F|;ꁅU.=]~'Q"HɝrKU!h6g"!}.Ef?sB7ﴉ9SCy+8Ps IlMO mR?Gh-}J'S߂%$!LU:>׍qE[&oK >Hh^8q|G pZ0&Qaàqҹ*KY-aYljB8>VߨT %δ jN>XKIs,-#.ucO纂W}AIlˠFpe)УP~a]z:G\S FWD by&|H~kD'ߗTn~5fx,VqqEeTju2;iWOmjQ?zKc¹BOk1P k'd.]vW.~"Бs(U;Y#Wl6i'dy;m ڼ^ϛ5`OZF \7bVo&i853T"WV'0.Xvsj_^9p)q\c؍8f~Lȴ:7iݖsrQN.Ա@> stream x\[qN^7Fx ~"c&B+$e\R4e[U%y 9uv'Wg۝k{,!׻0@]\Sο?{:^v QX1ĨA"Oi_?zQZX7r7ʪQ-B?Q.E<%Lv _[傗e6 "Vf1B;w|Q);*DC6AZm?HxN-6>؀tOQ `usmi7W( X?unQ|'AvNVMUQȹ^XP~gr0&$+U/عU(*DGE,ZHdm+ &U€dJܯ̛%qCT.NG$`wָXL2AF Xvh:ژ4ՋD6zN"}tf Er:~wWͽYv`?ӡl4 7y!SONdJDk݂ۆ Y}SWfV\ߡlE:gyAV(<:˙1X`tQh=rhToLx a. `*F9PHquCulK DX4 PgeH$z} o畴@"$U . "r<ٿ%~ 2hl{HE_ ʕGcvb J셍Dʌzd`j<[-!ƀVjfg;3yS-":tܟ_ղW8'꿜BkgVEB !UgNB$dJB0 ͈Z" ACt~ DAQ f@ĪyC@hCA-i>R˼6}4u,QҚ}ɤ_G{3P9ƜR9TJsIg w=M1@"vD@LozPzn0a!hȱ,aл\WGfI9=( b: 6Ũ+,):\(+7<L.+Vprw&LV:)5ǩd~\ZT1vrf85 h ꚦ|ϧt̠q㙕cn.A1 $S")]sLHh74` [g}'n;vuvrJOr-FˀŔ{^lRoH/Q^0KFn`fbH脿e7#jf@yC%ekzqz+oDoWޣLJM=xؐ?ߑr 8؍ۻN?C"G[ /4v$Law\lIiLfOH&t8 [i3i`+>Sz! x|:<kbbM"ޯ`UOG}^qZHE9!DC:|D쯤#l!k7KJ0 /y2K lzH1ٰ]D;|a{d`뽲"d/EF<~TZ^lIe~ b[%d,ոOƏ5HPmx3X;#ge6G8Y2I$bSNO-rQYC87I Xp>?p9ǨVy=V츕rl?NKc>潘+2 J[_2d4` ?({ث0'(vo[uȑ OX9X,q~ <(6n?Jّ.oaځ̉,90+4 WU p1 'qo ڏIc j1ZTO}NIJU125.PwSvV SJ}頰DكIp~ذ0/&Te!Itc`g}?u99gzE c3~}a)*:o:~3*aP`5c&&,|ϫPJy "~U4ڍyScT9߃[ 6(λ҇d*.\ G2"N$=eNx|p&a؍8wc =]Rl6u& M]K[> ; e#}?jI-g<&gsJԎ 6-@|TxaҲ5uF=F%!XM T`rbaR.2Y'م.sz F-XH$/\u59k֤祥6f&\T{SÍЧ\Vxs`4.+Ԟ mcK(Q?p?lϹM w>? ,EZ( t>]Hz FnŽ/ 7i.'54&{`{bk.KXS,`SQO ۡbR{79D Q>+~L}ꂗaMn{l&e0d&z8kr,N$ o$lfrH0sݗjVKTZc.*rk}|@)t et -%`_`G@;kyPF|ŋRAAkRBOrԁg f"Am*F9_ԜG{ԑ4)d/XoxP73p sZI\GCkX' w'9:b ƫڥf2o{nO- ( eT6ԛWrT`֢5vZEERy6YM {wFOtŧW4jd(GhR'#iG 3Eu.upnZ=QBtcJ i [)xw7cz3S֬oi1?<kHLEk3h̝I BsC\bWx9^n0j$ `e!mX6rJ/&,L E2,浉m]jxQ|b6L''wj@N&y-gǭmuUOUplƠbA4~:/xt87CI_ְ.~^EEl _X3f"  ֧K Ě lȅ0M8B{s]f2^hm@9U) (6v9@%o=njgX=~9)5Nv&gA)zvKL1]:p%ps/‘5dy$U 2dI^ݩ`4iTR r@l ?S9Ap-acš;my~`FJ k}$BE>$] /5oZ0ŋxᮈ_wbz؅$.X؈*$LfZV$@Wż'q"1\k"#8v *BGc&Zj`eӺKGH_D?9dFT7$ "g..{rF(0_v{ MYdI#À~upJU6.W=vמ{z3!;N2 _l|L#n*{J SI$0s ^5eR2y6Sr'];$xTWL9e Ui6zبή޼M\ei`Iࢃ] _dT_+":80k,H2p&V02CVsI1e#EfQKn^gvIld7 R_quy_㣞t3UikhJ_5Uo<NnX(nZ&1-BhYCDzlA\7DH(ij>?]؛ù.~:-qXiV|{_cO֓l$+84qσy‚`E;_-C+BLAH߼ˈRiAk9sϋo PJsJ*iLLu=Ծ:Fr; }z7D$+ ?cv!ds oyUHohأd5}{Noa1M)bPwSj.@lox;f]2ߜ{Rendstream endobj 648 0 obj 5145 endobj 652 0 obj <> stream x[moUKs+/+mBl.%nCHB@yU{g|\"T6B"}lgyfRr)_yjq_/RR.RB_D~zyk&ctʙӅ[9҆0*yyC J(Z;F-pǥf8Z娔6fZfv|PiZ)ĨTBJ$OO+=ޟAX* !H'itĉΖ[)=ڨB*r%G0tPAC<&I>u_LZQJ {I49ҠCt%AB9ZɵU`iq͊  W:IJӣpJ&zc_=KK*I 1_tRp [r$iF#[7ңͅz⣺ d4lRƘFFa\#Pe{/~pQҙO7}9꯶VA":=@EiRkX)NPAUNIw'7anC o}TYJǐZ2L .RqKfq| x;3n'LD: :Xp%CLY9BOhP{go`f'V\1@p F@bhqǥ\u67僭$V!Y-l>Czox`, eg:ax<OI Zr-⃐ VæTԱ1Ggǫiwaxm P.AWT֝ͩw"hSIQ >%q+[Fe"5hOha7]BaMf%4< <  UƝBӤ5rx CQA,Gc)~LSHS!bCW!ͤdexȮYn&Q|34E;6\- 51-ޘ^W+0D9h-9hXlfbbRjnu y6JwPAU9X*4R@A(Y5(Wr:3YDRb &4t{i~7FOT9 A L/k*n Fn{\ ьE:qCgD=85<kRfLȤƒ&?B ۞t<"mb9,PPYbrFil]WX>"Vd.N-}f t|^l TĭUa]0ĠJɞ`-X5u*m(K`_sĂiJ0l Zjh@㡎jؼCj&6?1X0vcIQ|RE` 9OYgRn}C m=ckw̲ȭpy^UH!rMo\[cQvWj3 |VQ[/dEU9dz&Ggz/8eDx 3Qijo:!S=ɧ}Q%{ǃ:@nDJ0PX{=!Z3Kפ|/x}'͝ 3mmzvX3.PaZ!SplR67Y /#J+kvS'Wԗ$ tJf(GCֵ! bE }'̃o([OX.ͧ3ٸ#-tXk W `+2>*>@@r*k )2%)ݦ$v3g+ ݶLUܧKj=Kj=wZG4  bίӿa u:exP_oQ6][h Ty8( 1icK:[4KNG;SwwsE7l4;LCui;agwEUΙjHKÊZ uHrIc@Ȥ9.[)Ǒ_q3fOЄpg yʖd Ohƌ5i!O[dx?' Aɫם?gDPh(j 6U2 yrEhh1S 㧒r~e{FRkŴ9agƾ|V|v6gD4Y,GE)ndV }~|2ӓd0=,wt^KZ%FkFZByGEՇLpޮ8KfIX ĉy~L1(6,XeП%uKbbdAQ.i(Zi<<>}E?s|6nE'է{g\+F?-77.e ]u۾$EUv)'^QFBo{a{ISd*MOOux$K/"}4b| mn[[endstream endobj 653 0 obj 3034 endobj 657 0 obj <> stream xZ[o\}<'R o IE CJK.Ԣ3<ó(€Mϒofr9a)ZJX/]/t G@ei÷ ^x'҆ 4~rQʊ~b4?~G"קG}Ǹve6Z<\*Z)ÃTlBRм H[%p2 o"!Nm[cQ9E[h4TmkI/V%DZx,c/%C5 0?,?959ES EPn",lIM 1a{dFΠhE?_3$*8I:$uD0â>N-Z[esƱ<Ő`;i:zeEr3{7b b0dEr̭$Vؿ.RdSJĆ8>屳H2ߗbYIu=Al~^c(*o3LӴ8|V]Qb|V9622+@:nfP~0ۀ&:|Aа &A(GeT['ٯdMO'蠦¼!623+,tswQH>/&}LJ5ubiT*+On$rpq;d,CgTQwV|=ȸu,+<r,u&(qhr0ۥCFjeW"R2,{LJgؓ p:{1GL&jۃ{Y(&UϹ}7kW b{Ey5J ߟ{)& }gm'U"tNxLpR&-ҳ"LE!Lj2^F*o˄oM|mpɼ}-&NҽaHRC`nJ4 OpށS_DҠmA`b^!taKIaQ}Z%O`8Y^c-ҷ}̥6zو@v(;ّrjgq8tS)z*XjkLQp<$J0T%0**;S{Q_U[GyYaPu3dg*l7Vd"8 r3zOJbqvޔu,Ͷ=t}җP}tra(s/$";[X:0u''r|$~>&m 6솊sWTj?me''sIU1ώ UaڎmHҝ*1(颉n䎟 ٹ0}Ԇz~󥜸1ތr!`l;ƛט6]=dH.S/$-rW'9?__H'|+>ɒ̜8=}掉Lܸ6lUd|2ڿRzқߑ&!H_ c3#1N+5l ?NZ!{OKb[M#&[%1(B~s1a]ƥC`iGFnFKR~r[P"Zt?5L!- +znB[d. BXL uw oqhKGh3K8Uq΀O*mf) dq ¸'tsBQ;䨽gqAJ],zN(MdtN3ҙif̝aPOZ>KaAdJN?nXaHb;dZkwgG3BHp \3Q0Has2nԢ *uYw eIB6ZiRsQ~Q{uTV~%a&UQw)e؏D} bs>fendstream endobj 658 0 obj 2427 endobj 662 0 obj <> stream x[nsc>n2yę  Z%_sY /Xjˑ`Qs/KoRU.]՛}4qDӕ;%IqboWΉ"XmwyaQ96nLlG<ڰe!ͻB+'搟 ۝Z[7W[C ݼe6\HkNu)ץc+;9BT<))Ja߼n: ]r?/;+Rh}(WHICx^OcH0˾4\,OJx]ߖC)} B LM*F 8) Kץj?h@_R<iv[Q;%-|aԯ6O~[v ?~*^խӲh>:^H&ATJߖ?V]L[IEP)u3?a<Zk FؾS+srNR:4SLcDpE23g}vrLLQ۵i16 v"T"-4ޙP\j(*r|Je#/[̵7j̚v6+jѴs =PK[:gg8Hh"h NH=Ky^kxH2vfCKMء)(!Oو0 m'ӏf7sE2@MZ jIZ[ }%ԛ[T [;ϚӔ&Vjfk5B# =Q֯sfs3׭vyt|iR1n‚'ɑ  ڱ0tT uI-m .9Ķ̚0aD cH̼C LOF/\- NZ(D-HpACU#Na"^_WV5jR9nnJMjfy'?mM~c;v=犨וMHxəS99uJ j1qn@J8 )TTe%ܥC j轁q?lM&3Ϗ''G@'Q F\8H Deǭ+yEDmx,US5R!'z[ye:UMsW;3bmj6?C] BL-K_Q]TyI#lbUVx^K‚8E?#l9#MRB55&=& 'hފs(TA.FVӭ EJe9- FK_Gaϥ )+ap 7Mmdž9L ~5naٛboNKi:2+%6ꂄz7釚+/T"Vc#~ t4 dJ\A8#=Wx97=]6PڮaA8Z0\iR Y6Jьg}kPwhtU-G?wY">~%p@IG]f1^b-dEsž!]O~c0,B tC@ ZYKVs~RlQ9S^Gq;"㚔ic*R MNkڳA '4tq:I<hx. Gb,QJqL:^.{1tQ0kF:jR˖#6R7 جi@U54"_L;f&^ԖmQ^Z<#% N ejɱ Au\ 9+Sf`{ Ab-κԖ6=NsTN{ob_O4h2Mpn1bW-ƣf,?i >Zcۏji\,'r܀];L&b1^4q|YA&hKa Ws_6~5;u=pNKdg&zRg:X*1yx8dyKGL!h)"hMSCHPF&#.OՐvN(c{ߪI>=hh/os8O_YFYC+qKu).*k({=j.)J˥ؓڰ!XD)(Pj[&_" # HtTf"\ mD'vv~z $Ns!PvVX)Eu V猲,ϙu\l`#hKF3I01 MkiA;}{qUvr S5}ʣIn ,c6J曮*)Pz㌋/Po\7z#F;>f|˨r}Gkcm&4D,yɋӗyR \? cH6 Gk,h c NvdBb13}XRei2 k`:\:ń%@Hr>,7$GoG;;)Czs(J/˱oɱ̊{/xendstream endobj 663 0 obj 3222 endobj 667 0 obj <> stream xZێ 13F"wIRd#'Mb v%/,c}N/fov6+9 QnX,:oZ?^m}/mJl7o6>8 Y@mOoL|*M["jϝJY{7SvGcNd9وN颓jUtir awYO(dw ~3{ݞBe4_MR&Yڽ; a[Af}ϩ38]& Fq4ckxS}]{]PWwFcQs*8/WCmuͨ3[V0C}VɾIm@qW./'IJjxUM|q弜O<w^OʒXTor`R~GLb2չͅ9dYIXݾ?oAXrVifOPdCsAo&㣗M$&'iHcS+ޖ&ixXeE*vZ2*kILp]U Su"dbfgﱚaMiaGI0DGA0LI# 3u?7{|"rϚlwΑ tdfkԁ\T[mR!q{pw.65{|aͣ\8mȅX)BQ}&fm<{kCЩxBboSrV9~x=i{m} }aCUq}0D)s9}o`iH~wK)!?*aZ0!|8. `TaR0#wXBe86 ~)pONZ:BLK@\3OcDEd m6w\Eคw6Ї ɼ%NYo1]ۨhۈbq d%X 6[p82GlRk}.'7ݐW/oevϙٗ,IoXٲxa ೊ5@.ŌAWlW1+c LO_$!pL@k2e׵h>q' =Kw*njy@|$"V\\cu&ƟC 20p1=M-1{Cʗӳ|WϚ]wYX c xޓEgn&xI{8!ԟj7QJNIӵX:3/H6y8 E]nFT6Hw 3J1!O񫨂#&u501/[27cJ9X:Qt:{<'7Ha'ܦ84I G_Q/.KISPW-+>aym,dj9܉gжg|$UXtsAǘ'3r3+Bc MZJ$Bt|}E.GuKӒگlrBXjs^7dqX,0M 2ؒX zR #vH% -!f@i@<eA *bIs%Aja_,q )&rDո2AJU6jT`-`LloMr|e+>%e𸱢 ME ~; ADawU0|hM`\X+a_"LiLV OK)Z` n)؃UFȝX 7:t)Pr͡cbcu[A[%4_[I%Nr *r3ta<ΡQ)+HuΚtBJx̝/G_7{㼪|ɥgPR".b1TG'\.fb]J ZSbU_ ~Il(xvW A `뎬ÔWa.ַN5_{|KaR7YR\(Ec 6nT?TJsXW,ᐵ @/ >"F׃ޯ 2YY$퉺)tw#6u.ED5,w^45|򦚑\3ǖ: b `uMt(oԋ-[g\0b.$fP$a_Ήara+}pѢ5C7fQ`L fև( 0qwa̝/iH;bh0zyA##Pւo1` Ya9h|ogŀnvXC8X;T3]=ec$-HY`^hĺ`XߕKcpc=dz!'E]1"\B4:+6%xL -(Ō0l85N|+B/C"[<$zE}>Ԣ\={endstream endobj 668 0 obj 2901 endobj 672 0 obj <> stream x[n}|<,vxwrq'!@ci}ʒWOl٣,qix7clEZjQw}Wk^H.TdxPg~/jȺ}b 85|u- ~=ʔ3|8_ews,"\|ojq_^U-~moW7P؜Ϸ/kbٸϷ熻*|i$0F'v!Rqfx$NV4hJDIp K;-1h ;@)6.`uh*oF:hud_Q@0˩; 6o?pB-\(řJ#wx*W:ץQ"۲^H`\EٹҡopѠ$Tc3jhSÿO cϢb5^a  xnwY²=޿oM-*:69"VjDiWuǗe1gz1+UN1h|EA9Uש@d O"*2zMuEvEWXM˴epڋ.$ s(W05xaKMSY΂Xb&vb^};>Z깯7ց^'($˗3҂o:W&d=iW.k\Yq64y?!lkQCUkilC3g/jL n*=E6$ ItMh.K'opfʽfMͲ)v:dsVIѝų<.e֮,{i!}^wTD*[qCP=|x㟰b&Ub+mԙͺHMl!F4BuxI7uVOQ&y*wT<.%%FQ E,o'Ω.. `8cS}xy~PML46JYt0sHPyr<I2p*$:R$Idj.jPg}MLFG$SBGUʄ*庸eJ#*t>:D{6.'B}]s%65D>x, W ̏s*yLC{endstream endobj 673 0 obj 2857 endobj 677 0 obj <> stream x[Yo$γ7[f i7BS`Ivz{k!5~{чOv{%O&m_|I0>i} R 띊BE/wVXiߞPVk{Dr))bU!nlۓ< 7ug볯>{g_YF~gcbwAȐ|~d5> 2So0LQD}?.!_g־鳿$ieqB{g/7kG%T@T7]WK .8ëpVPk_V^ǟ|s\ykt420AdlT8H@ah`,ac+ffY Ii~sBD?D<t&B')ZZKvJ}ˣ@PgOčґ8i`#9O=x7gGQG}/>Ӛ9-m-v~8tqtŪ=ٌ~sIt9tv8g P7H'tҲON_^2/FD($FXᵞN$!K.Rkd_H>Ș{ڙg?\R}̇$>vWDpN%;{E-*lR1BWysH*#D* opްl`+D&[<BcpHAhLZC0] eTQ WuNH${@qJ8x#L2y7`6D>w2IF(Yƒ6+ LC ++:t 0B!&+XJj#~s|!9Ө'r5vF'z'y|R 뷜dB>4Iߺ^C0ގ78y]vG!?Cc!,`S~^w?C_ 2F\h{2X(7j"E!xR#`gIU9Kha$R >4,ّYfh9nPgf2;=ɌJ?cL"äY;}#E~3}:*X`*|6Wۇ% ! ,-"ntrH n9'\]?-E,@7GF+¾"Jo֟ Sِ1tMϴY9Lh}q"@&.CieKx²KvܵHr-a;d#sN q5I 7nn!vv 3 {yOWkZw ,C&wR - љp6ӥzf!兂b82)d00\,B3˟& Ahd '+#O|3^Uˠ,_tW5 zjFl Ck$TLf.VQO?L*`[Ϻ:.Us!mLԋ~7CC]':6Y'X~{Xh+#`]\OLqNxáV+Izj$_VXZ| QQ{%Pv%:O2.1 F XIߊ~:doj&"*:Tasj9,؀_9sĂAOGɦ].A-Y`{Dp1r\;u"5WDS|ۙZⷨWT gs@(JV LuGBn,2JD1v7(J{K9 asآ}}5s][fJڬz,`5'%Ihʹ4j iC\Cgj6|^iؗh6p{%G4qE%nY&(*"0y^YBXeK1Ec:3b;(5!T hjY|eeYj;w.[3I$M{9 '<ݽW:ǵNͼC Xm*䇝t4awֺ\4ق{7o9}]ֆ0ȶNƀ/z:)G+Xo"r5nFBxM`'9}=e5Jyz^˂V^;r ~C=S6S '0,nnj=O$+Sp])%lX˙)lS0/= y 6tJsb 5/MuM7Xug|N7B!.飄;5F* G}n;vמ1ɘ*m̚"E𞳰u.oO[qnBZ~u=ˊQTKTrj藰*H7QŨ4Ooǽ|V_ 4> stream xZ[o ~#> zs#;֩(mٲ`YP셜Y˵q! CCE!>(C}Ix#@TBSV।+@KLnz0ڐn9Y9Oπ3O:Tvٍv $L6&FdxT%#g3|~"#0Ax2vZ\٭OA IGti+}nS_`D3 ʒtɽbud{ıuA i'뒋`p1*F)R8Ccڃ-Њ%*YcwF6#DSO!$Cg2kL%F){M֌^NA<[N1D*G'46spvs_TJ9@O@bs̱x.X57Di|s3'^*.{ģcd@D|(7jVWE+gMGFb@UT.@  hGdkծ]/ G+P7[p/]gܤH 3Ɨ'윔 `'*DE:|p29GļMZwaI3I0 z gQ-{>hS&j "?9_ zR0HI`X +v!r>c ګ@xe; Ea,g!I3}A8tUOPxpx-ff8z^3oϙ SɏwW1XvH bRlFsyOAHpRSOyx\WD'9=^!y1VSf*yU[.93\6aZ07Nsf}dX(73BfK_Shp8Ok L]9> 10 vC-8`( ^us`Ś^zd|ӱ/KZ.lUoCB={a g-6>/p8z~^̌dgiVMm0(˘.miޗbS%¨LsI?gi30(jpxتiPy4yޱ!NҐm"t,?jLݦ]?s]?edU$1cN navVu~adɨ77p#q^73u4nG:9{T‹8g25CD U+]6:d :ɬRz T1Vm e8> jg":bwxز"y6=1NN=q-2w~{umϤ{f&5)f7>H7QeB5 C_ڥfҘno,PB/R6 !=SF58" RBسcJKG gv0%tP"2D7xtDreuCfSbcQ-:985SK$yy.oSڬmSUfX.oRw57.%u q?:{ Y|ں=Dzg.`hEkvV {G<|CqptQӴwj*I' i?!!#̕rڰW4cESiD`=ozͦP\xx(:g+-h -պ/6gA}޳6x$bӼi+]L(h_x=K@Q1 !d~x6h:NV;|;Ldq74_H֍´b%i)ThM_-=3kB%FPX*f%~#{ : PkQvNrݹ`\.߮!5lz:(+u !($WJܜ*{=!I!^o~F̎J}y^( rRȗn㓊w8*#DAA";"3Nr,P<躋3-jŇ8ωn9P9W3iBvXGQv Vo rUwc9&W=xɃQY]*LJ>63Wf}2k=Y}IJj* laUbM{߭ Űu_ 4}xtLX9~,/0GC|j,;<2etl hIPDnU[fو#W\CxY7;w?D1endstream endobj 683 0 obj 3045 endobj 687 0 obj <> stream x[[o~#ayOmM@R/`Yr| T~.\X~%ofRK%+}߇GX7z2'@$<;Re|"x]BG? jw"&liƔH|>m;yF45mWV;=\ZHek^ IÛ^B.Fr vǠl6ySQhjglA أR"9I=)GLgR 6bf%J a`_A# j4RjS):)i e+ҟ6^)M,avGz1w8yž.3 v(7jv( oG'~NvшBS4F !ç3TIq kD>zLLꭓ֙fd(†`O;:v$Mogs!L& ?8^k=p<[~TqG&:^X M<$[.M6H,3U,y?\FϗgX4X=td"&i'_N,70" jBNI!%^ qnliޟj{^{jeR{Ok'_#of rRx˥!;D_}Z>A3zqiVc_F?<WK/^:D4x=N2OBba2%-`:rS}ؘ: :f!s}\N8eՖps籧I`ɹ.*n7bժ~3A>_s娴y]2m=uBÃd̗jOKvW$t&v28c1wL a$G9Ms J-Q~& olN,La #[,~-t `p215)s߳ʎI&-&j*\*8Rf=4iRbqɥh+*EI\P]K&+x[p9]F8?!h$8NI2hIӰNk TVNK =5NW+E}`bNR IuB⦑2sӎ%g@1 ]Uȇ`8 @~ J/4FFac*-)5){{^4~Yp*`&C$:2E=nD!fDd9.t1B(BO`\ ]%ݖW`7~Dy"cmF#7l cNQ ϒNYؗC :eo`Yĵ bF5h\cVշ'P| ]=p7ȬG/h0rH-yJji]T ۹(6nr*öG@Rw`U\ mDc_w,=V>_f!U:ݬooխUN}0ײE *ƕ5. d!;Fdpa>9M:4yz]Q7>4X)I6A>t,Uj3b NjIx-x6l7Yt#%Iu6"`\pc9 m74ƼQ8uYd.ZZޛSfv]KU(\rCnLkrzHLnORxhb>Bc} MYG\BwcCQߵ| _Wn5omolr܄,zP ڗִK-tjdkyveIJUߩ&:N/Qbꪍ…A9`ʻꅜDe$r/c, y=t[PM腍̡}"[ڴ`W-^"v,]b D]O߃"`=sm3p0Yx~[v\Amn?Vsjendstream endobj 688 0 obj 3150 endobj 692 0 obj <> stream xWɒ57?*Rj?;CxoJUʪv@a%)ח/SoZaq{nSnٴzy1?q!mV9PpިdsaaKΫw굊 9gm&;mU^}\&+XM8J7ݡ^BTnq5T28*țh:" C`cV4ReǤ.#~5{U z4UD]z !Ӆe\ҎMʯύ,xܛI6̑PJ)$I\.ύ9&h2bst"y)}K߮4ˊL!8h߬e/ @!m^]mfIG#~D5g\dg&:A6.6[Z ^_S__1 '[}*= h :!2`?8]DuVL˧DZqc/+ȋ7Ine@@0]LkW.Lvjz+s`ӡD3]Z3>9C}d*--]֨u$fUh0nWۂxiA&rdK#l| 3wyPqbm=X.!^k"FHC^Xֵ>c.0[Zcq^ry$^(VCS4SN cAn JmP}ecKBz&ń+0 F$Nw3h:V̼ח*1,LL_1$xj+Of{bjpsEq/?P;{}j X%; CLϩ~}$endstream endobj 693 0 obj 1562 endobj 697 0 obj <> stream xMNC1 E|Ed'J,eeC,} H}h(\W7G@ךeq7w_W.ᎎq@ r}UЊKkc@1hE&6E}5]q_) EZ…>&$5sL\-[ G.Re צ4"59|F\k؝tM}IEendstream endobj 698 0 obj 207 endobj 702 0 obj <> stream xYKs#8@,V)J"i]9X>%JeKQ8,|1MG)aFWRWQ]Ջ2yȬH ȭT^o: VXZm~7RXg|pz8]K* uZHr9mCdIA{O߳Fa*Gۿ0| n T*WVy,!*C`Ϭ؈hLgY.&}V vFa_CXCbj>E`toM$4:wIL"2z__7J->TFh}hlB iB*EqP ech%)R֐U֑wp:=\+"RlVF‡i7ݔ=V;ph~²ƅ䘠KpNoVH.Ũ(|DgcOQ"`DX&v<:-sH<1}K_IBd'a$Rk殈ەV ^Y/F^po}WeBQD!EoX pO,?i<d!R*/dfi88H%$Dd<&٘| oudla^;m:F5y;y^$"__,` 77ŏ *ewp.n_5 A %%"#]>Ӧ/n Y(ń~$Sp GJM\V/f2?@ey5ڗR(8q`t6cƳn*sS^]j!nQ(eKrnw2= _xNCb1}N8X?)KXP6ۏGR5؍6l"(  d&ADوSXLOv᭷08*bDA剰@"vxqYSWZc C7֤ˍ=KҎt/`4nij)AzӁ:b¢H:7N %&wP1} ήq--^s("/MyI 6+)p5#r2hk6S1ubȕNDT=ͮwAK#8`FPhW֫?ѩ~˟e IS'-g \RL <-- ;Ȝ`Hna U#0hUSA̤w zD @UڢS{̂}Jn{Ieq߯urtoY,&hxr=k(?WªrXzst(ykA٘p| B ھtƕ)_5X c# АgMcը |։zgLTSn;|A(Z#|Y˷Xl ZMs5W5 rajڛmf44Y2,>S1,G,f%)rͣ xֻ/IVo$JoN$iNNSj4204K2Td^  >;Q<mSG5Eטox4YVdw>|G BT ުK":6&?nt*.9:t _ (jnG9|X\Ӱ ZhV8؊(~-6=1Ap]^@%3qY řzK[ktT6hc:ySCwIwsW:{Ugh@Ouv+ۺ⶗uY};Աlu|rF1JPf1xeLl0rY4*^0&d"*-ξNm`l.둮#MÛn4{(s][ZT;+|b̌<Ҩʂq"9r=zPendstream endobj 703 0 obj 2436 endobj 707 0 obj <> stream xnG}bg]} BlB|XSsTB@\[]]s257f=YqNf[%n00*n|53-}* s\9VzUڻ r/"<l[m ,@@ĪZC_/@ilvܨFA6WB#_x_5 B{)4+C/ sjDX r̨=:T:K=sRDab:oCo42Y`%$G nL[7`ʩwX cI#ϳd^g𾖡#a޾gpgK9 _Ж1x6pgsգBtfn}8}nkڀ ]3]VkZԤݶ׌gP`zZ KhRB!Av6)&xؙhRlE_t%҂/+͵?VYdͱ|'){^m&-hED{صk8tw_@AۮbPŰ K6ea9wSio+rXzW$P!6co eB06<У9`8K^||I.o= u"!Pvo\+Vi<,8Ƭ 9nHxY $ۙC"DAx: 0u;Rt}*(6d7H9gu,nFA&V+^MF WmR1ҩ[5mZNJF*O(BoV j1l9{KDJo%\H=C_fh҂C A)Wh3E'pA,6hJ|Y7һ,O򀊊}c$ᄈ'|݅gXMkqvu=i3^JF&aTw!{;5>z^aN'D5}> O@tVK_*!l{hedhvdpsu([^+,c *C`XO$#.`R|X2yʐe% {NWuDYÑУ(t7j_@Ł"UM~2#M<AYRMkY2x%SK-Nc,.LgTȅ2,dOV;{ETd;ô bb~ +L~F;w}_I-nV}:t1V4\/;x!cw>CW25ek9Zt[#)wYc^yfwWy:UVQxgu8j}=OHӋQq^{mk2EjY=ӎo`9{-i6endstream endobj 708 0 obj 1807 endobj 712 0 obj <> stream x\YoC;ǃۉ$!v`VZi}+dgw; H>Ū*~B$W~W~u$]]'oNT,O? !Y=|vVcX˓q"DiZl,fZs7맛Dژ&/6o6 K&t4(I?~Qh8?IAOӓ!F~UE*nb0'/<9lX^Uw-f-Tz~6j:WW_ԫOU('|/Y/cz\~SyٛVI#.KpДڮ'ӇԪ B*FG@6ϢՊf `+HA@~D=ې ]a*"E޴Pa1R{qhƚ (Z DU+@Y믠Lt]R3^&|h!n>q$ V73F nBQGq+U,U(^F?eDvcXEn k& [}\Ȓlr6vH X˕(DTnH J߯Mм2`^M@=`:d=xL֍&?}xɛOa+YKY{zwy޷+ur/|/#Ee%hR%l@} #`>_uѰ3sLFu_5h2Y1JbL5 ' ܶX&cL &"]դ%bOIYׁ|G :uEgA턁-ܭ:^7Y %q'ϳWo J޺VwD6R<%g*p1rBMQ6h|^-Ds]gU!m$@醬Deu #P.o$4i꽥-*ׅxӝyr\}4oEK}$b(̩[8@O8G*<[ߗZGnh&CN"!6xw6^|a1.^DrQSeBg"Zu5:Crn6Eveq&cэHcwE anB4RNj9bh` `9kO8Kɖ mF+22Y,-B9uYs7vI79Iʑ$ig9^|\/V.@i_Q ɍܯGxY6<Ջl1<x)m xjuG{-IiOsxYĺckyl1 6OjWzzR>PI-Zs< **F`anڥS3#U/ʹΛީl6)fn=y [8s~6KgW~[=ׂtzV^ՈNC؞ì(C44ߙg)-2lsgku ǡ1*ʇ59!s3N~ҷRnlT>֟?ԟj?rF^~R/Wm>(Xk_Sf۔.ϛ2ɀ})̉#'U (nC<< $#\jل 4w/2aj61܉pɥ`tz4\ f y.~镘v%ta)5BjJ#Oe_d9BWOFRh:`CiƌD֐jONzaF5i>xBġʁItŗ}^3uGS`)ʁGD^}"Z)v"#Y#=}s8G a1l")śZs)&6SJ]H:&xܪY=НEJw^lӤCv< JTӾ?s};R4dj*?wv$U5mVHhS{br̬UiKsMӷd.nV9sIosD)]cJՄ˴M Z~Pfc5Pfk˾g--.'"1 @a"PnYv}C,:MQ;U^ŔgV)Xe?gc]{GnVז6-L[vLI 6qnL߫Ts|/nS<"n<)OMtۺ~38NI1Y΂T@@v&8, LK&/eDڤv{_G&皋i $@Zhބѽfwf qIM,Hƨ*FjZ#m^O+[r2Um"4f{(FC 7fΈ຅t>B{e@Y쿚LŶ@=]D,̚[_8Aw#(7tGP _x܍?O&2lץ"cIO!w3KuP8ɨ2ƤjѲobt~pa+?VMg;·~PP@IN#{8ΘG#'Qq7_p'S6zt.PA=TuS!N?uL Yrn+U>f%Kk a OVw>fUT](V0xF3+Vw}dxpp#/|sh2Cys&ݻyÁwW7G wXk8yw4ɑ!Ҍ)  ,)Jޛ2:|}u'*ker̲\V|y?<endstream endobj 713 0 obj 4075 endobj 717 0 obj <> stream x[n%Z&FnG/$@ZƣfFd>df_=<dhINwb~7'_~O/?SyɻߟTqN9szD⦅Ԇ0)ysNv QXS1Ĩ#/$@)1st'x[QV^jh?rR.iKHkw7Rj/h&f/$V{3]+~A)hcֿ{(QMAW^E\a֔앛Vvw Vґ0&(Zz䔔1c{tzURK(OJy v1%i$!g;kx*w.')c֮v@ (&n}*y5e9馾&m@Lo:nFC{((߿ P0,lm/QŒG !;kUg[+s30dߊ5p/<6Q/X^Oh( ]PvU;xzu\g|PZxQm?T}1k~Hn8rhd8N㝚DL7}bV2~P:[2u=- g QH=,?F3)Qvt"6R9,RS5vXW*zkCHfĤe&]Kv[`DV{$EFhG9ec'M ;b31J\C-_2Ik>Ajnx뚨&U 9 zUK73;jq**Rof i_u:¼TI 50Xr^Zf}/.b^L}KjBh6A_ -8IǝoWsܾYɉ!5Z]Ao&h>[cbCs7l:P}Ь XO#Yo4` v,,¾+]wQ8`y\Qr8pހ2[bc }p&p` aLo4  lpH^C}Gň Wx:KDUr轣L('Xb;p0|AU9fkܸ(ȃ}N /|_RfM)-3҂XBdb:@fd> ec  L6?` Ϡ(Ȑ}8J]֝^ ^LRΉ{r1D~;`,?`躘b`#>-(xnnBlPTϽIɢm ~;䰸1[TѮBVj|}Ik:[>Evd^ ˄z : y/WA =uzK-o8 dl V29p.ȭ D`4oCf=X=v~VP]e:֋'}@6pLKrkہgR-<.f) Fa'S<'O ѮjNݜ5$8)RE֕h xTp"ų)]N8cN$7l$ͣ$:Ƈqu_ V>5#V$}U&-fKpSngSqGrN><76J^ӔjAHnQliHR/s֑q[/Zei)LHso2\I k O|iQHlDZs5o#jgʶ;Sʕfw읒Bu'|5}^TC@W]fۓXٮs24/O/#]/J>Y.ܙnx}*t<~T`_/ubR˖rU* ma#udSM?\N Uپ|TkA`]yĢC5r3כy-=o3ևVC)ԳJ;#W41} xލhq$XiT>|]'ǔRw悎4nMcLSAˌ/ssλɹK0z@9D_NZSR]Fqa?RIU"J7Vؙ~k]mWEmX[}vOG[!yY<2E "Em}U#0iMU@R|eHc~h>(㞯Zپ>|<<ᛷ61]V 9`z('qA6m" r[> 5ɱJ*RٰT$ܑ"@8X͕3 rw h$E陗6MH+hAtzgvs1z'P,箖? ?Дy^zu:]G.|M,Z;xty Vb.wZ 4,83k j # h[IJFqn$=2PkS2*36E̗]Rن4)譻fVwںIW8XOvQBs2"5T:vƤIh#7t£ 'Ƌx+cnhK16wbXͅ.V4gyÊsdE,MMХlEv YQ4mV1FS$t#sv`ʬ l9##yˁe#`xa'-bqa2|M6inzzиtRvSǟ $Lā,a?4Kn|tM6q|Hmݸ`ݔr4mP!*ZoI/@endstream endobj 718 0 obj 3237 endobj 724 0 obj <> stream x[[o?b:kdi/Sm!)*r`Yuq~3]ECi͙Xs~}X=}֧W8oƧO+~i>~XەH`^637Vfkm8sZ˔Wø^uo6ilӽL; f+2./9f+䊛8KIQaCPR^1'UAI^V4Jy:񯃯"!KIS]'{a:5 [X0`q\V9>Ϗ8ytU~<̏?4'Qq<.ѫvy(_{8] 86Ym&9ܽ􏎇ofv821IPv~1(4B{#M:% qՠܓ`P_VO\MeSS/^с.'/ 3(,0_vSүOV~ϑ{MY}SRIE.3KtT9 =[~C0̎ *)Ȫ6R2o`sz b1X1Segzz^(Ƶ2"-*f2N,8X!m)Y%ECHE@jCTp]2E-QT@H_9 n d^X'r I!p!C3X> P!H2(&4lAwRpa :@l+Χ.n m}ezpp\pY\8d *D8JB!F]|ؐJY "8߆)mL@־l0BKy+bтpg3Z@GZhq|P2Tp,0qzq7$ {jA/IFaLdrf҄1kX L)ge J"h^,ԋJUJ% RFݵ_Ar\M7D`6퓪Vhhph 'rY|~Fd1 J!`瓠YΑ!ƨ=*ӤA›HP.(;N@Oz{/4Ґ=U \R/p2pQ!+ @:a6ahp9,3AeAA6C8{dy qZvTTSX)CVw)6b-ՅEBL]bud74j%M7E򰙺29wө #WL$ \!;iІ?ؙOX wOfգߟ~oh0Xbw{ { d2Nk'ӍKp VNSUH6˰j$mDŬQ5ֲiSIj$ MHT/HP\1.\51%fFu.z;#Ilݝ(*6`+*@6UN3>:sFSt6[ M~IS .{Wͩ-]T8"jeqyalF9M({ 5}!P>mK0+b^x 6_ZD/tZT]ahT[ ^^Qbh/8;Uh딃N;Y#Vf0 GXA.p0H<0 _aX {C`AèņQ4:OЈaxyKB)CDl5LJr )ZDvȵ66Sһa3`;bנh-.Tє SG UU-ȧ&86uPnU,%F;%Aۧ7# *K _\ :,HCjmwPɭ{7O yY/lnӵ@9/\^h(۸|QDbc&ޱ 4t(JTƧulOYjn%kW~sF6 GO)l2~ڐ=9mn }@=~Pk+1;uq0Y@/rž,9M@S}"yk)UP{xQEJ΃]JضiQoN¥/_Bk0%lY3h"/y[|n~({.;W~j$FK T{MЪҫwgyԅk#UGOTAwLU٥ ]DmFuW.t6#>):Sodhf-ڝںAūERZtVz&eS60p-ޝyLި1> stream xZr +?qݮ d5){8w7IMi$YVYYNFʏ$Bm6 ۿ2;-g7'{]~8ɣ;{=>?ݟX`hTywx{b!5\ƴ{bҎʏ1%8_DT# pnV%J#GUU`r\{RڰUyE><{ q0572`zixךLܷX[΂:a1*9G^S@ lJ#$em4KƐU!5/EbԼiI۾) ^{Vh5gbe #P 6?dq3o~Xkr訳ovI^DIY׼m8`BVGyӌm^q"5U&9w2+oݯ*p/:}lVuqjw S_SQ*/Y\7Zk#/<] P<`(t[sIpr4Xmy!1cCNceqy"hZƪ5S. `(C1ORmo٥#} /LUWԻ/CZ4j91II8"  kWW}o@>5wo;3'`eQ۞P%h>'Ŧ5')zd(vٯفz'I~Gގu4B-JEȋYǠ=Tbּ&ZoC#ȑb&  ef 05!X|X3/zȎ0+!Va &fDSdR;)MRxX+d X,mO5 ۑ&BV=>ȁߢ' (8u2;!7B)qzȃ6a^Ozprr=>u:>J5EɩL3}ڕ3 nBO5 ԄL^(ez6ho^c0!X4;gY57x+IyZנؼ=;G/ X)d{\\3}ZX 6;Dxcs [傷+Py_@KzE!KwįilH*R07>~>c%XJÑ8"H7՟"5 D,~;^\ž` ki03(q[5;/%Qɇ>ۗhlŊվ _9kTҲ6|hM;Wn'cC~um0٫?^ endstream endobj 730 0 obj 2314 endobj 734 0 obj <> stream xY]oط4?ڧ:6P)'J$-߱{K.]^9eh;Μ9sˁ31p/= wqvãelr'?xz{+NDzUI<{ 0#8sZ9ioeJd7«I0V_Җ`G\hNji/KǴRɴƌW VŴxPr7`P^s%^eŞ.pGў9_W H`]sf}" JfvlWy UL |x/<39YGn|qpXXF!aK.d4sx'_3]FgoI8C;%7A0ekGpSn  _/VϷ(\|-tG:Р BuYz#pf$!Ȼ d p%}"b!LJbƠث/ݜYdD|:!Tdgs M5y(1RmZv_3lȷ ,U"^N [9cxs>AIs?%tº),k\a;gSʍVڐ *ǬOؚu3kP1y8G㮂. ]٪"#V 6@H R`npO#3 #r m]F9V6Oww/ ؉i ƒѹwͫ{N =<mzVGq}_[b% *Q!G|E2G8GK+xBSߒǂ_<0PRTO;xἓsk4)Xq-@ڛ=һ_*1.YCN5!Q ;E.A޾ ӻU^V+cUfpSTbI,ȱNyhwۢP EEk^hB滯.E yPF`xB 1MIn"#E`bQQRX(+_8Sɸ Wy[O:K`U?sf6wqGFhOJ0â12J mF;$D?3s)4"˸=Nu:yżp1龅+Z/]2T+B}zo<X4[I(3C; H5vWN{Zd1У;Yzl:o?.6܄aq"X`guSoȅvji#Z$s ,j#}􎂔/TơѪKR$^X] c+qz=\o+mUnV V߭Xɀ#oRGIi8-ѫd@[Ѳ)4pVq nƞ$WT˼Ұ e(F$IfC{Y&-׌֖j;ъ[lM u ]i؆&g+V֑(~rY)>hR͉37)p4[ȟ/rzˈL%IYW(FYEtE_IYQPrk!BgEAi9S[qi 8JvĦT`,I4ZOmi9=I o(@]iZk_$@qbYt:U gvT ̿j]@!#A(ű m< Ju`+>GZ6ֲ+DWWιiƠM+܅j "%ߑ$DE7$F;>4Yxd91endstream endobj 735 0 obj 2345 endobj 739 0 obj <> stream xMNC1 pCnI+(*R`{AkMw~Eendstream endobj 740 0 obj 209 endobj 744 0 obj <> stream xYYsV~>κ#~lB9do*vJEɘxN*=_c0ӘlHɕRaF__K֒.W/ ӻU]O+U#6hRxznzD4)mrCf+6DߝmZh7R$/ oH:ԝl0gSfkS$)$(dEAB?ֻoW~a6*tBIyh*ZŮxqJ+niluL֗%y)v7>_vFBW>Qu}MRVu6)8أCA)1B* U'ݗPOx'zJ*NxavtPs~GQ[ E>y!#k %dPPf(N%31J5X-t9[( Y6 eDL~$lh\.G*b%Js$9wk'QЄ$S&j!I *gƔ(h$(d쎊boA@ik A87) p| ;R A_t(tlQ[uW()!ZZ v!E]ԦWWJG< 344)ƅÆ0:Qv v|6ȡ۲/آmPj NA w _<>y!9Ug@lIUD#^[V Ltwަ-V Rc7h&cE]0ݻEr6U6#ߎ '*ɯ9moLqVϔUD~O8xX=1ShK.H-/tʌTQ͈qVDᓭ1 DڣwN*3i$I&g2IAbErAg砪pUۯ7 G>"NGƪh24eKhD2+?tEmgoo[]D 0=z#r`=iK*0Q$XC;&Tۗ~dCU=8+u# ,q]1]fԺ@Gۤ(}*]"]) |ʨ'&İW$p_H',Gf;E<2ZwZe >hsklj*WE@^}EA򕖇3g:;˨`U[FSU U3CCczSBlNjϨ\k6sfRћX9ldG{АJf\:hܩ&}ZiAҾ;gkxᴩ~&x06N$pII1lSpe$"l{'ckvPdObX 1]N 9اP޾昿&-D4h4 x[^_+b4>_u~'_Ջ?_/9zի_A&Z_APS HN. fqIoNj]~|Gi*hzs3O5H6_?Y.Bׅr@4G QcDTfDKϟ26rG'XDC|Z\F!wï%xhhF CUJ kHdS/?kxg}ۆ4\Yc*GsB(nxgS,g$>c,pjdu~hytvj$)=kiYp m$,rj<-rZ^g,x2L,4 SuwN7<_LxoQJq5#!gS7ȚoZ'endstream endobj 745 0 obj 2500 endobj 749 0 obj <> stream x[YoE~E{1EDHܺN+CBR;<3%q)HgHY3bkA?g۟U]?k뿫W+9#Ʒw1@uSά[}Z'V_nvg5!F ϧ|0NJ+Kx{QVmnwjh9mo;9(uܜowt iE&@JyFV8h0Ƞlk#sAvJN!24 jyhZa6I i0/1(sZRcV 6/V$o1T(Rrpe:CdEx Q`!ԠMŕTO-D=z TaNN ӛN3ZkԄuwВ: |l@#,} YF* lA, y_㺍 C‚S`DlKP G6G O.@K.58%%;Wu30Н3y7AJ~|#]j$  MS/Fl:T8dx8jf a u'^U*-GkNLX _r#Piݖ@+(I YW|Gy%]^욝D8XA8@{\@_-c,XM[{ڹOEX-0FW ; wNzNzG@*L>a,w&}1".tdIe ̟4>ZonpN6KqQalܠԳ͇8j55A7U!dMբa;hA]Ҕvp!1?9:3MF%)O^Ǹu)i#h Ѥ5Du-L㭡m?!j' ӽjxvە;QxZYHq&C&)u] 0Z)ڨ RDR1EHI3Bl>bq5jswhO3hUދhn2[LIn330agY>a&ixɛSde&5iJ δ,E5HYrʓU(8e<+5(& <]hh#X,, R,VSSA3Xx s/]r lRщ:n z^gXAzܙ0 ϱ2dkBe ~\}sWyuE6WQZS;m~g\(-U[=8ky0BO\ NHilГ&#B8%)C10sI&\uo)#MЖ &Z^CU:FZ!kUܹ}_ǫYOם?w?^iupw`fFxb`2U!5z%\Si/S0߀blPp?$d@|X=`Ov5؋%Z`V}21?{qJ/K2T ?hiY ~0R /" rS !K]: zv'/yvE"@1ѵ7vO'gө'{1>ٱpB0&'5b[x-h KK!FL"G Y2՟ڒlÍIK;Cc1ԨJ{޹H$qDưEH,l,BQ39(ꜥtDw _i؋鐀HD/_B& `o2dXZ:wT[SimOB@;6^q}]ԾӅSڧk׵7. Eyw2}oF0hMacE}܆,;jSYgkKקxFޫ4G>M=}kK֧ɰUظvSTaN.3OİU3FRk鈻v&JCYp6rpn *+oz?'P.Pd<[Ql)4w6yS`_LOk)\҈nM Vә9Q۟k фgLְlq_(y`\X0[=M[iDIdHz^Z\JvZ/{'/}TIqڝSiƲ*ZC) 'DU{Aׂ2dϧJeWzC \h4{lsՒ4;SeLOləC'.۪\2JM>҈T5q,P)\G0Ry=A 'zYR-S$ק^Tȩgai/RPn?ʲQDU)E5\ 6-kH|I fGݸʹ_22~D{T)¤_piQk|Q&W u,':o I_މ]NIĆVh6]҄?)wǖћ}3SP4d9Y\Zu/}g4+#_^7 -d`KaKoyR>ՒҌ醔{пN-L"Gendstream endobj 750 0 obj 3679 endobj 754 0 obj <> stream x]Yoq *z}'q#MȲuF?sf=$(snPY 9zc1_ד;ٻ0㻿9?X{w pnoQ'<ݯw; _OS=8ϴڳp鼗f??Ap&SJc V?"1/ ZU'.cnA BwgaJw04:2%upOz >~䇓7;,Lǩ@DaN/Pwy'w'w=?ù0 HVr~`Z"nc#H6dJ)nٶʂz2^I*܀XxI7T֝gbȲBu@)#<{0>XӃTzvZRoׇS0Z5lV\/[)\i HN8\=3 a+"J2H5Hf+ \5%sT5X`@@Р=XP?M9&o9 #=, ^P6~YeJeOaH#p>t]R#3Rc +ޖ oy3_LI nN2N2_IQpR'a&ݕ䌓 q; ')$;-nfzq[̆bpvF ;ὂ<,^X~<ǎȥ[rlQAAXYH@vAV9ɰ0Z-Aq\g u-A7d Gl뱨d,`tca\`a[]h.8?Z$o᏶s`*HH{ӟOZ|"{$6R+1üԿRѝR%_ M8Mg]Cel:j3%QuEIv kCQvTfkeW@qAU(cosx,{0N'Xp  ߣ(w/{ M+:Q$[WsWQw E-֫ %Z|x-Su1+[bfo3fVEk宧]]1Rgo9SGIp@̥S) Rn9-&lv7rF q*p 88o8_Qyz3`YR64teËxY6*YzMWIQɫ1*ㄕm[zû kP%r@T&$oݽMo&]nGr9e@6xnUy`3}1"糊!H 'm£@FB"INi~KZw-{Xכ2 0+V9)JHX{ӟORĺCT#['U ^m+QTΌQn"[TrE5yG^vysqOwjd2pI_6:g|[Oo3ڞ_‘fqdNؑKv[O[!cxl?EQ7'_qmrv Fn?F0xsނetv3`㜝!qNstg$\)m*nFOG.^4ؠ><$: )~|FpAg^/ߕ@JzY}e^\cSLnb Y5ャCS _Qa{a2C?z>^6o2;~,]~޷HWeqLtlofn0bd^lῌ8lRa'v!HjA 1|C"#B?bΈu7a=Ѐ<$9f.65 tT~ M‹f +* [ S)|IJC, o{cgI?*Q-&Kx۽8UODٕUE6 qLTԙ__V'Xӓ$qꛦ/R}HA2iΕ'ana>5a[  H]U^šd Kl2C~0m}0mͽ)_wf#C D!#2R_YE@ @l:>5F`ulnlzcDwk3IHDqjħ礌 ^Q}R pxy0 nuN\{J5r g5)BP%d3+WݾO;٥` mj\ pL];,LM:14B^QcW~ SY 2+fXG# eL $6e2‡Nx$X!ۗ܏ VסKyq-tR/ZbPyoF:y\QT&Bi}6XXJRANq<*XB+~{x(7f.Pp@+N㟿be6fh%5R@|а(|C]$3Az dUy;)KDfԞW0ɄPvop;+8SX@l)T\kPk$[RMOP0$'XٜJ6 ~-d%$ YwqdڑWMiLj3m آ)Z7VˊwZ4ܼUDuF3`xp_^0HƵ.csvsP=;e)4#&P@J$۩B7*b.j@xEՄ6mIM1 1;tjna6նɴ @>_`А+ ^mU46yGafq Q )I=.2?PeVD*GQK$':endstream endobj 755 0 obj 4709 endobj 759 0 obj <> stream xZ[s&?bw)fK)C `"*%vE$_tOOdJ@JUҨ~7[1ʭї~zFr͛lj3ۓ7rZP[¨0zN;(b;1 89R|o7ʪ~PFݫ~rQ~KHkw)5 [傗i&r/(V^d P+ǡA12qVH$pq>(}zyjAz+tZ(>ܫY8I 3GM=O+,QĎk@rQG_Uel< ڞ|9ykiGaA?qnn V\JԔ ^̃tmwOkAdJy;_A)T*lHm{t_7Wo6G_~vndpc#~lNYkb4Y5W]Csϫe`Fb¸XpLƷ:eID$dQEeG_H⭂dL_'rLu_JZU&c$0Ƃ5!@WEY(UTJZt2R0r|!4qD ㏡IU3kokcޛ\F(U|i[eʀkD@E#؆*Ʊr/7U.*s\Nk챲4_p-Hh{wIW4>ogƐL-XhCԜ״I]Z|cO@~䦚v83]`>$_bJ]?9T}}yu1ᤕuN8Z+K;$oB3:G@BCv L 35lK8QFlTcTk2fas f9ƽmD?,A Yt2EkK͓QHY&+CkuM}[GޏG؃?dC6}N$ RKWuEwY]K4@0`^Ӻjb {uy@Z#,P8쁅 #MuYwnY]:I (R9ld;nc/(0Ϳ]!@KW-@,c20$2ZE7tG=J攧T(-V_j9a4QO~5E,'hY1Fh7Yb\b=9Tu}%"*(y}䏨 "!}~MB_i:o~*I<)]O^'Ⱥ$뼪4(yC )x GZ2' I[su J؉{8ho@DBI:S/e݂vYLe5*ED/*F"0BQS A04QQͽ9% E m[=';l"YĴ+(u@1ɚѤ\gI13%p굶~ bWt%dVYc"J[#* {5OPDdqx"T8:$+: t,dZ hK'uN%;ʠƨ}rXA5ᰨ$UC%B>JJm)K<&}R0v%攙ELv&5m m񰘕 9Ju*}.rPs>V}kj! ̑zLjc /{Ky\:,enPAۇj0n%MuW !u AmdJ m[uoQ$'b -)X\hl^T U/ Kʂ@YT\Kfx}ꬺ?쌆qU(>k$-sv#H8=0l9߫ODUWRmw^QV+k6Bi8,ItP6ަu`> stream xi\1G7!L lX ƃH׫=H OUoa"!Kv^WuwUu=lKҿOE.2݂4{x-0jyi棓-s/'Zyy/qFh3JiOWr 5<_Q9a VjQ#7f|h5Y%~17(j؋ߝRLIp(.衄cm)[p+0 C-5$ygЌ[8\[8f 0Wz3w8jVka, 7׫d밂FǸ=k%,v{7UywP5j(1roC4gf8ĭpE cCt1zƕNWv$.Hp@Qi'[A Sg5h8 ((Ko(;[m4!tTp*(H @9@ lr@Rw/$ЌO $ߑKB{zx(N&ZBL pR|EHӏZSa#iI g~߅R>˧vxDhp /`‡de01 e ެ^ /}Ǽpɳ𣜳Hn^W帖0U-#ҍ~} )-ީ .k;ݸ oxX$8 ܏̦5cԎTݪ(D'(Lla"#4!ޱ3ilr=Ë:|ٝYizP/+;]^WA,pK=@c?GhsTa/) Ke@\$<ӂtвBʼ зu6s$QpFU^U2DMxS5 9K4w\< 8}fguxk ݇uc=Ĺ/Vqæu_Zޘ( \VUnM;Z"^;^[ow3͓ۄsoS6ށ?];ߦixV6GR%S!mIqR UqtJ;s 7Lv2\BX)4vv;CJ 7'~&o"~^ Oũ!/5FJ{뾇L',323$iBjg$i9SƘZcIdԜ0IJW1Tu&.{4>ZVY !RG+Q˕ F"ٌf) j с[3FDK]7a0d-Dr0U:퍙QUtP)ɪ50|`ן[J=&tIsTZ(^7!nDјM"S Viw΍Nv)̻=2Xe9* 1& BTcOZqcDŽ0g%;nU;ZmϜNWsB''·4AS6CYBJd.b@-ÞhiHL;k{gp~"jGcoxT MokvU-UazjRFrpɝ?}|kvdme'XRSWzdݺJbwV&Hp܄5PekX>]s"Ta*$Ig{bIY$n mCڪ*7FV4c=wŰ0դ48QꓩSOpL1`.P&;zO B$Ekiօvn$F1rHBt,ҡH5)>(&a*m,5xo(IHǚ 8m,t5Ag{wMVG/x,@z^QU; L5y ^';63 ժ~c#7,Rk[/Iɸm2\ 1!l2!J>N8Üǩ0  WF@Ԅ" G7QQ M\|W:JG*񆞆g48Dcֻxqꌗ O_E[z' zTnߝ6&j@*FT*oWXdG8R^c9%;TG+4V2m!WFU=x|a?i|}\`vؓ>ΣP&XTg-9 9-û:d>_ÉCVlM:08EYbXBnk wNӡ>-.F~-lg|3u2 v'Y(*9 e5{9hP7\(uK,n~~e]v+uuGIvU`GYTVBr"Vßr> stream xZYsγq纸CK/$F<) |g{] o/glz#F'{~h_^go>>6qN99~v$|GF_^k۝C z 1Aͣ> ~J{w|?mwzTZX>7|t܊epݩQH~~QvKHkDvxIVeD|^neejx5ڹy Du+S~6DۭqM g۝8ũbhû[F-'ʕր @ vDVіQc϶b&)eT_tZf&(טv21FV(D(qgG5N{NN*wQFC/.e >oF8QTMZ퇟<^MR.b I$)+>'Fmw"WfxFfS~1$a[>U-\;>N\17`'/'alB>Q7tE2כun6R"ijqsGb1zA Bـ䨵wy !c0Ó-S2(8x< iOgW+_aak|=qT' Ɩm/1dṽ_bIYZ!;Ollfi(f[t"t!HbIpz+ K˿q%="ܿx%(R/to$4;B&pR(<fIeI-iU;} ϴ5hŁdc@䃧IËNX\r1쐕DioQY>$0/&b^r&NUNRO$uad]bɛ%ihbVI18>5ftoWg[ Tq3?QQ~bWQ+B*oqCŽR`adEL(x! J P$Li*c[q+i4,cBaV2! Ec67~v^Yk ѳЖ YI[:;\2]:%*ִ}k]Xv1I# =8quYW=èup?v|a c5GVG0?QIsNSsH 2CxҏIx2 #8؎nfW'~ANoOoM8Z (2}[ҽJ%cK̨݂;*6wV>ZɋҴ*)k(QPa 7i`,|͍ÞbJ};=g[|섿$$5; 0,۩)uϺ9Sɯl)„ʈ=坦r[~+#0-Ңd_^lL&[^ęp ͛&i*IH6(a"Hk +jE'\ (zxBX$пN\Rt Hn f NRW/:wHlEl00mFɉ̥(^&䭀c'SBS &< d)Є)ϋGsR 0;4KK *ѬWTwՋ,囒Eu^8|F5?½TWAB1bXK ~u;r]Szjup,*LYAQaraYM =^fZ"э3 &hQ3;?E. y6"\ZE/(p(?aח,4IW1=e:zVG/I}W o(yz? 'AL=`Z~11ZʻO/ռ~:GK*]-y>͟M=eޓ.ywY%BP"b30͏u'*bN~>sdU5}Hn|ž?5+f v,!T1uꤢ I_tU`vS|j{N<04rY$AEhgMj1: 3Y!NVM.SO  LpC&o„T~V"}^vUӣE7TJ7%*2:T!,s6Y%E1Psu&%\Z0W@zgH?wg%+j5TSj8UohTBwtvr gIZ$v35 )fn++jJ)fWMؠP[SS8M@ٔYPb2k`gLKo5ayՏY&7%-^:RqJ!zm@ϵHnfkR)*z~B>GgX_VMqN`^#CXsJ, z/Z@U+T QJZ8eoɈj ncuնTB+z΃%IMjIdTi/q:Wsde̋3lԸ,,nU5S#NG >e#hCiK@c:,^Ǭ>>ki*yf"W0{X H}lRZ,r9T3{us<*ؤV ݁.r]كZpGBMYX RCd'QMOitMߦ`kY4mSLoYLendstream endobj 770 0 obj 3426 endobj 774 0 obj <> stream x[kog?~~iݦimhlK~j3\.9J"@.̃s(w:}8I;syzyDSta3ӧ'2ot ;¨ɿ?1Da cQ^(轳n QIp/Gw&0SE=Jo{7OJ0ګQ)hzC>`Q}'(%WJ?uzVzGJH+|?cXtPDZmEE@QGe}d&T830 nxR oODpb2EƼ摔m{}1`# < Iecz 17ec*2VVG*nb:˽ R ɩP6DU})_gmuS8Tq~(s(uPXDFU~iAլ?˞{N#ͦrn${V׏"7>7(i˽I;e%C j vv-~.aba8 P ߇c. p1aH[Id"yC6zF$-66DKd!ߝ~{rŖJ3C:Q5q冉/̦QՁ 9>*xl fvc-|(/uJN+H`\E ,xX)k_6kֺX$1>颞i'zF#Ǩ6w;=k#$P当;?v_+W'woF i).tGԸmu4|puftz. { yS` Me\PU56+ʎY_~"wo^K67鞇4j h=ME2f]Ϛ+KZQʎ9k%[tOR+B;K +ߦvuxJc;, {ft $kɮtCkq6sG. 5Բq`QtE@̖:\m*cO$PL XȜ &d,쀕Ppp sE7ƄeDMf; vbHD4S 2QBMpzq"ZEA\M$ >#h+5GdZb\u8%hS MM߅osMKKVrt72:cu4ynENoz@+\C&5GrA"TEvaSNeɞf*x\;$Q6L6oqWfg@[A8^NLvTNv ݘExgSƾ*fo$6ŏK =X_nUlteD&JcTrL9t4um\m''Sm+3^Iw?XVѓsEb_o765ΞDq)8ר4͇H #o"E*ۭ9S"Sd99dS{M,Պ[yrMHm-@Fr3grmUn%nP6~2VViR&a> lfC"8_&ױH 326.aY#E,\UdEui֡r7CTq© Gȟ_Ep]m ɡm ס_sQj ]i2'|*5yr!@>nl[Pr^{ m* -foh-A"DM eY%[cX1o, zrE?gمﺌb2ەhկ,1JL)EW\kZUIGF5N-HTEg'sa]odP=`WXQZ "aw˧R[3]]4r^%Oo')LPFaQJdO =$5#W*citC_ 27ֈ3*ikDi hÎ5s,_7hʝ>xn:j͝M\Z>-`UfVOpoAԡ奜iNNeYȪZ .^ΕۼN,#jr^b$5./elȹT.Qi}MuʛBYoep% LMSV빀pZ`(~j F gQvE!xc} 8ꆿ Ү O-Ñ ]R4q,D7!G~nQ4p#W{#⩐0Py8B ^IC V.k>أd)zܯcwӳ63}:E`t.$, ]NIorJoc Qr?rZ/4UUqf'^Mb`>Ss5m3^TlG+yUܷ1Vf!̗d[~lwSN2`a?B__qP Ynx3)sv{Dye 5k>1[G IlTpu=Ji$vXP .g5JV9` ^! %rZorFG/,?s/ºe #wendstream endobj 775 0 obj 3677 endobj 779 0 obj <> stream xZK#y~-#~'p 'ofh2# WlvZ=,M+ğO_".??_O_^bV/.isY.{&N,WTT_%=]˕bRIveKΜFvw˕d\hem\ &mP{Z8˜n iHHtp dLsem5: 1^+0|/9ӾjΥ`"RΖ9I5Zk)uP88PY)Y7AU5J3eW`ΕhȕIɉ=s"?/.?=DΓA9DжAF u t=~ \az@xv .]Fe{5HBhil WEO q$`O~\qӽ>P/"aGڤXк{? 9xФbtJgOUŭ#0J6b#lo igK^1 m,<ȵk(0*'ZEfK Ӏ8Dytf8tC}go.^}m}gMbOmr1u?t[foVss,*$/(dxk_!_H >v~nj)mLTqΉdܸ6ڇ66O @鏮]S]^9M yJH_<`k#`0a0Icfe8zsԚSᾝ㊲;`=q PD5/0Mk瘞G4@PB aR_4kwyQ~3{~$ڂaMjhcP& J7dtq׶Al4T]םTzRnMιwSFIi72zkO oOX -Ž>"e?y~ns%xRADBIUMKÌC dq2z9::3RK7 $-vM6A@^PaBQsQ j7(h r22SF)!]}'VQyQX~ +١ˈ(xgDt{ xj<{[=A8Zp->4sc[˩x<,c"푸uc\gKP:lZ}ku7Ha?ÿ{'9>ץ(î 5.be'unrT׈ٗ.sI/4S,CPcI<{2eM2CONh!n~D>[J7i}ok D4Q|&ӴmԊ#V/dʎ3o!Ç3å"whsg )˵`!V5<6(\~ڵw%f=-]3#OB.&6 nd䀉VX¤kt(֥45uv㛱cZءzY#IG[} 0ɖ+Q1M[`]#hNhB:`$jC H{L1mw]8y(@ױdѓjXWj&'LXXgZL$9 l\Az)ȎE%'( q_٭RtÃ6##/  Mn֍Fj}Bkk:0QvQ&E:겘cDzEWf[Bǽl2?!숹#ߟƺXD^/ w~S̖YKę7:%y%[a~1]=S> stream xZKs7 *jU9ATH *1`C|yH3; ;NrowK~[KAs?o,Q4_>{?r.!<3D1mBᓷ_*V(dZu%j)QV:Z(TOk&GLi(\uN8]u2Tok%rT{W+4yΠHHݯˇ0Ti ^|[ҺV#C)9_(/ŕ$-ˆ#8/Ϛz%0;[e512F;ޣ{0p_tlyL r/ Wݚ4<6ځ .ۘm1Gk>3ہ r NS2܅mr՞ˇdNK=Ӽ|k-ҲZ>yY\*S] .8 G>jxuIuKTgQ4a'M)S2u4YKCQo Ge<3wBg'9L2&1`E*ݛShikugEE蚚/kPk]4#kh+/WƓt!Ն^`jzclDn1]'k1UÓ6C!oXttphbwD\׽F8GVCN6ZـuT#[J~` Nh+x+hoKjn ˓p|4YV5z}'JI-mt[T1ga < |IeA٢U7NJ+Dz8X.{EEK!a42nyxWn9^++GBmqn7Ɖ 8lqg.<`a hTn0:nۯA o`qW#$ᇊ'gH(2Ru q 28PXu6'׏͖V)e5kBAH2s8_$t6FE!턕⊴+˥!GQ[[9?t(wakHTp"1R)IR&;[eM]zEcv[6J`:ymKk3Z O1v-WM$皔h@iʏZ@XO ,%0^yhOUO,<4!c EQZmht[M,"DOUj6iR{`LɓUYj{0V%#I^jRlwͤ4aiYhڀםӍnVskߙѯfAk93?P^7kVYTu%8^ zDŽ3HWPvC YqDRZF#wʇ Wh$<%`d;]nF#`d&Eqw02yPѫL%8݌ W} Ȍ$at~wxn/VP~#Z9{.izL`Q6Bd)qɐ΅C? B$xdCJ;~De$m *Z>+a/#"- !_#0 '!EU?]\2qWq2# Q $@!+#: v+p)Kbe|hcI_6)Vl,t_uN[Մ̫ɶ@N3m[n߷KaMXጲhfB *}u<]|uo9?endstream endobj 785 0 obj 1813 endobj 789 0 obj <> stream xZ[sͻa`ICr !]@HvRzfwg D0a\zw^PkIVU]?W/WjFc$ޮ0>klN'bv&7cJS?&_ObOmNc{E/Eh!5;'F IUK*纋"R;n} jX&4/zFwVrԪUc7:R,G7V|UA&v=^{T>E3E.XVI^ױWtkٺwSTQA m* (ݰJn^ ҅E!/kwyam- dH>N3&ڞ~<{,s3?NuӬg[=qiA{ȓ#å~B,'ݍ yR%6*gUd ,RXO1BRKXO5Yeuc"[ԉ/u>X; )cp'ߺ(CyڡRêqU;yUJ om&JLݗ#WtQBkP蝐Nz5LDMvT;McWmz ƨQ11'.?HG28-CHgJ> 6.5YZ1hřԐKcI~H7#Fn0J3biE'.[992rm Ss#yW]OzM<ŋoʌ5ڔRYJmd.C39Ǥ|Ip%QuE;mح,bK<QDJsC+Cڕ ޠqv-h'B,N0xBqXpm"8v :6j`cIi.@kH c"B c0 4ql2cWюk'QV:9+DCuFeJAPyi2?*)M+n&yBAh0Yp4&`"|Wbp6O&]KM*ڳhg%toIT"v1)&`#t K]BS_v t{J`or_@Ǘ٘=),vhz plR9dG=.`a+lP|Z, (L%yiQeyVBNjpZJ/ZCڿ|)zNƛB2P߻R8A?ŻԿenM!-hB*y#OO}-9CGz.qlv~5/ TmTpvk1(\xb%- Y6TckuOUO;'xZB}US0R%XL> T^_Ye* ɵ`zTlYT++a+Ufn4TiQeEW󚦉&M 9n" űs[tk+:`TIqp*׭>bp۶UE&=BϦ}-;nr[J`k|Lh*)摒*{A/}!@b66֎++(|{Ň67xͬQ3Ł.1چAxLb(9 #8ˑd}^?ZDYU +P9)ǵ@E\RV3rhÏ Vx՞.?4g:(gvk)3x:(Jσ /&6[ -HE2`0̡ 5A$# }.DC?9 k0*bb DmE0JrprmO$^q(Z!!pxju+OV_Ǥ>.#WH3 Mt›A}:*5uk@~$%lJ;Œ@j+`?֪*E9s_(FkybܿI,1;9)nKj=pprjeg8[["Ld:Xm""W?85h{u5]t@t[Y ǜ̿)~C 4|&LxK<ϓ",ߢ6M&{ &9wٲ&$wa!mCi#3Z1➣H{+].6 ;~:[$N( H6F.C<_\3ܚ+5pkCzu=`eVjkl$I6Gao7|8gSr,+;/Y{1r-WV~ "蹓fGf|2={ta^(D-5j+=]a6 afy-H/h+kL6;'X ę"3Qe ER\ݲ%EaFXY|bkZu.F9]ѨFl> stream xZ[oE+3E݀`"Ǘ؉c:&F,㞾TUUu]K֒~WwܺVOޮT{w0 uko{+wJD(4޼^بvDLFǘiD+Eiz6ZkMbcP7_ oQK׭Z{c} ռDBZR+cjZh飔kBiCcDrNM7~`~)LJFC +v)-*v1"Zza0w-`<H5Oڍ&hg(n% $CXLvSֺm^*^i/+Se)0TP* %x+.E X_IClkQ}<;th!Jam=kx^;lں!CyQO14Huڨq@h;`-%4T ,h5R lث4qž6Fiau,sY!7-dhj=-ROJFzk*fR)ЬOڍR>r8T9drf9JnC}2cXi}. )74_&?_|o>$U#0QdVk~ݰц7]\͙kJ e% ʊ9 zBQc93p0pvt?T˥0B&M×y#D0TFۭj%wbSP}̏*?aH!\bSJ`N*Rb)jHT:棬+KDVJJ 2cnc$o~L14pg,5#^Wf>*uȨ K0$!_xDaI'PD e; 7KE*22A'T0)Y+#6 YCX2#kQ hy SfRi`/Cj6SJx`BXrsneSF4Xc5V{5V5wf.h:s.M*z0@,5"&*68zCI-Wx3Rcxľ|X)Ւ/I`KGUlA-w"1;隆s;[C`D0. ƈ1 ƀ F;!p<[=]] ]\gwjgw`jkCjգӭ7Y& Y]aA>y*zSl({Jjv'EYX"JP˙/h %ň3"KYvlrHcE5Zo qdDB*$F $Ed.cˑd-;0.: !ID0 -N>IK)ͯ$ Y85>rGxN;@;>$GadG:?7P֩F%Z`Y0Mgl,.\ /SHq0&I2WaLh< 7@֓ʔz nHADh#n: iƒL6j KGj[<^ ir9t]M(1hƣDxO!e|?p*> ^e5Yi)'Qe{df3;U\Z_ ikV!J;U} &B ՓGo'c%crԺEܲ#A5u l\KI^9Do&Nw>WZlit%"qqkÖ/B)U qj !=er=F)kBzyrxO5< (v\ 7rPKi0%WFO}eP>2VXG &AE[\e}dn>fn :[x1*P~O.(_v*pf.W)xwś ۹ɾyr^x*r uJbg@bo::zOW"޵pKvYmLi񿜉z4K& ~#xj;Tendstream endobj 795 0 obj 2489 endobj 799 0 obj <> stream x[[s!?YQsJk-dIT03w_mR(">ި Ycoe辜`_`R;]gTxOGH`Ӈ8bP 81ʪwMKv%M!8(&1|?(u4-qIրK振H"x?'_:(&*WKʽV(ACRi ;~ch$2uL `>_}aMNjKe!u"$>^=~8|z-W{}V?g~QYcL/k-kpQL"t(R:.6E`N=ɀMtML͟OS.tah{9HAI7[)r5INIɥHD_QwWL7ؤ'1i-fgzҞ )b@LPTl',#jk.L.7~O@@GsU7d,1ņ žv0 I5&S&@u39k3$T ){ppx4+SXoӨJ[.kCU*&5"Eh.6ѭO[ Ɔ Kr@Vrq WE4ܐP]OEer>:,fUh{ȖLu<4'Fmp2tB|Hk(8<|qb hdSjTj3LMv,]-R]Eإ:y۶CЦankU.Is>&:E<'9;MsĖPnu؃S PYJf!ymJ [!$T侄)mi0oi(z,Ȣ] Fi{~;Fd(EwB6Qv&];2v\j נ4;0{H#'iP- A0g\F~(($h3~)$5(!ݻ!y0m bm\$% w1Khϥ.$l|ujWFcM)dV̬AlBQ8:m:i,mӁSɺ(D b=*;ph'c(7E$n`HCMgX8](8 9ԀNF7D/D~H_HD-?RLJ[9Zq[^-mfsa ^"%i5 lpS% ~դhй*C#dׅP0=uws57 Aj;3gM`V >Ks^xw > |EsШ̫acEy>`|#"Ɇ|iw!%˩Iw-r-*aiC6?8 ɣ.n(|.:&Egl6WUj͠yQJ;Y2,-WR(HUJ`Ϧ4 AA|K˗ejܮۺCKY&vv(<2϶kppQX^j?34s˹C΢Kdlʍ~쪖qte3c7k nLKژYCy9eHtcq^fY^KV2&R!+eAfѬI͚4h֤Y֬~S;4>t{e=*ı!e+ynKf[fc=L1KWu`=y:exRxr No5YD /ruCQ[l)C@ y]yB| 7qYfRTM̵;|L>NN2b̒Mp.ynC c-{Sa0qmU:mVa wei5f  I2l̟!e7{0먉yùpmv/!$! Xx,x?suelm\:¦Lwg+\2f\q4̾I9 ?-? 3 ,Xnn)ʦF0ů`!t؜}ټ-2>ʹڦ4)d%Gm%MV\܎~V{K&I+̐Im]gQ. u<G>J MV]PKL-cUrMj1IE;F[  PHk4$F.#QӸ!zp'7?,5NUT+Tѷ\ +þd`M@UdΛ A9f.; W?৤^?nm~J*:f`fHL^dn:}hw|d 6{3pBI{dTVUL@VfBnKԈMefMl9H2^]lLS.h4SKi$qb 3g JupS^@H$_a,^=,rYFaz-Ѧ*b+huOZE+4z { Ҹw/ݘ xYeH=]#w}I"LXY}<::r]R\^SXy"L|ȻR2CSqRbjl{W51kΐbN 0A7`C5bdqZ /Z'7_A36$]7x B]-PsO(mEf;PzYŠ]!ujU$̛lE\R?׶^Js ݇:o,y?m&҆]}ZDG96wNkTUY3X{e5{ܻ ,&5H27+[ YV;j}o󋫫9vt9w43.wE3ŝdtҬ;[{l[x)|/tendstream endobj 800 0 obj 3537 endobj 804 0 obj <> stream x[Y]SF^z_'0NL0#EI1Ɗ1 [|t9}f{VU_-]NGϏ>zwO^ޝun#YeLa3dot ;¤ѿpl5{!FbFYEߝunAOJ e_d1zvh'O&۟_"Ԥf8/$v>  :9:#Y󏥶WchLGEkM/i}2=C{gڀ4Ŭ8<}mqD:5FR0 _棶7>-'|bǹIK&I.!3Myoi #RpՇtqkjoZr,cph߷oZek8}z$|t~>.:њ!7}^z4l,eea,+L+\e[,0#T1+un 鎥7NP HY3IdFYpؓ[v [MzEKVOgZ8\3>@lC*@Gd_P'fHlw4GL}4sƺK0V{1ݵ2qoV&>:cR%& :_y΃ oWARz"w.}<??ݗ.r"#m6M.5B)dd}tqtmtgo~z?en9Th Uo/樔\-Ӈ${.BLKPQ--V>#}6 F-pe*`JV`oY*A(eG1 G"/vKޯRk[&#,a'Zl_%G7;Y&*0lFb S) )<3@8SӞnrGsn}P$L/]$QI8^N w^);M}JͤYD)!k3}wҦJ2{\c&c(&m/0@/r- a|4rnW)-9U{8/jRe3Zą2LI}[s2s>pNEdUt** *Fﴞh5vYIZ/4Vpt>yDTDOkh*X*vJrQ2δ\tBc^{[yE%Ug"YJJ5ga V+9ersI -f3+,qZ^D5ӡ:!9[:<׬°R3*a b=ӅBo(R[j%YTLS_S/I OD$P't+##iBzxȤ/_z+0cZq^열Fء̇2&Wϲ<&Cne!=99%lŐTGQKKCfMG$DcA^㱎&E܅œ/OR$j(<ޫ$b:Hw턎F%NV>tA8 "t}XĞDZlXH>x4_g7˔3z^/?R#;Ca~脮AqEIЃ|j3+Vv0V5xK#|eWfiA8zHy<[ bZ=!D{r]cjQ;$ADg,X1U~Ab͟?ko-:~W;/5NV-JPv:,LZJlf]UэҜ1jw:YٳT"N=[cwR[4<⦝(2 `4rmc}xwz1QHI yj)}.)T;\v!P7|Rzv~dHt.TNN"Ti u>K*rӃ&4Մ:^##xJ' EOwZPMCeY0͑|\"`hbIVHpu:>7C\wXjG$A$J·)Bt!ݠAsY&|!U~ݑKy,Q.^m6Y0QxNz<#\'r+!A.W/|aнhzr*.?)ud!ӡ;q] %n9Y9&xTZJ?Ȍ u 1hCⶴ""_LЃTLfy?E|endstream endobj 805 0 obj 4088 endobj 809 0 obj <> stream x\Yq?bgf݇~0E: Ei `%s .꙽`GUVQ\L\7g_ޟpW?;Q>Hu3?wB&'oBL 1Ꝙx/=)T~wڋezPFv|rQA.!ݽHiwoU.xYF3o2L2h{7ڹ˼3XSV"#} #ȸ^@q?k*)*  SYBg)!j>;m&|-հT-I>NBO!:Mm}ܓ|(h6jz[pۄɁF&Ѫ΢U4HIY9B_7I:Q`_I '[}W3)o}bK"e)A2[eN!ܰᓬ-:(r&hLM>uTY5=fAN!#覚WNqqMJ'Y&dϋ&!mւB}GD0fZ!xo ha4C8nWu/nW}NzK[l$Mil:\#HNՃ2[Gޣ =Th9Mѿ)-:L@@X~K?Zb+&1DEnpb6HøRC@K&a>Wߎ0eC-n$vJ FRv;ҋm9DĉrAK;}h5gՆh!UŮ)# $ dp3 ]FlCYαG^cAcqʊ:x(=8dě TC~MgG UN9 _Ec0cp-Q"f 1c!q"gՁ:mၠ f&}9-/ot.j<ژPYѣeiۛ|(~wv,ܕ40m49m+yځ9{)p >tƓ tyad:,"#sSϣWe9 fe|ցT:I' '[bεXΩh|Fތ'NLle\ң#fwbh[GofdQ!`圂{)Zqk35aӅ!t0uKYأ/J S@Y\|wy>hI(k\Wy'\;J;=[@~xĄ2%';0?΢p{N"#-##|#>OɓY{?h2? 0ߌ/Cd('``? OD & f90>/&#e@J^Gc7VU nɠ0\D !xsM}u _g^!KP03hl;Ww(TnrĬ%-\">*1 MoV*49^媍4s6Yor-1*al h(rv4"W.eM;Tm$ԡԕ*?t?MOS/ ~}Q̆ zx0NEq{ bKƀ Rn}d|D*9ޤLV冑x#(ZO {dИqw( K q;*^qnooN8ڴh&0`Td/%)E`U1S~~^=᚜J/f?ck&((Cv Ulw_ݴG׭D"^߽jxxFͫvKDr/Ki>&D5%gp7tD;,z5ۂ'`-R4߯zzF\y^]=fg_-{fkd8V5LnKS{jVΠF)6p(DհT5iu6oBdB?c( ܶy%%r`EІX;ve? YhƑrںTP/:өz7Sri6;V|"v"7\ 7e "q%@⏲#$ZZOG9lBܴu~j~ 2J,-2JBX Q1Z>%@@[ZAӌUGYmƀn͢I8Y?g:q9%eCvURZZ²q9896R +FM5W67UKýjS$DcG);@my̦-)$B%[\쬛4uXymݔƞ &k%6)H.x+JBQ:%t'-Z x'Fsv+{|y0 kVvQ2 *&o?Ɉ`PpU5LNhq+ M6l``fɴP}KId0k!i`-ﳗRNuঙmddbP GdZ*-~8j/xF-כ8>r&mJ&0c2E5פУq~"oD< _Un̖nF*[jJC7%5 ۡjd61T-5 bfޏ']AB\8 ss>"<ƫaA,WɏEEC'wBzXo* "`5,fr羅%.` X}]rBnb9;>L_D,Z)BrX6g$3kqێ1Kc(etM8f~ERq,i"yD'GRэCy:U&m*ٵixr[F{xq &t:K(@rc>+I&W4ڎ f7Kp ::Vޗ$??Zcƚx7"Mo+^y9n }f'] ֎M7u[6c*Z:۱ڏv$k]G(dN[܆<%әd%w0 udvcnւI=.}Aycd3Q*p|aꜥf ZTݑR(:ƍr’%k%@M[o:$[. FAx3 3ޅQ4ml5/nSwiy^e tujVn \s}z21 }Ok,{ۘ%Z+؈DEm;hz*֚=7}zG0՚%SAe$~xM"F/EQ*멊v_0ƃʑvGH(/pFvaJt\bcfr\ ^*7ku 8ȯ3GVpbGoendstream endobj 810 0 obj 4901 endobj 814 0 obj <> stream x[kʏDJ<~`%#&u81ZeD署sw6@=:UuӾ?OnzzӞ )>鞞O6}Ro`lN־OYyשr]R}t>ֆF+oWw9=>;SdBb /rhRw21`O{K:~zlq6R&6t hs~&XgBV^{|308 ý{4kjMd/FPc1!_eWV}9g@{PV=Z|[}Nwi+?;0osZNC>Z4SkӘ\ܣhFŭljqhgZy0}'p1P/qM㲛>G-_S1|0_hC_ ͧK3{B}_x6FkVZ#*M ϖ_Qߗk5Ǎ>6n뮜ai`؏+[[ch,>ڄƋN :RN N tyHXWaӵY[_}P ~l)v“ʁ2҂ܺXk,c\[ڔ8tRں;B.G )F^kml;n|wDCJOa"9M5=jw{c GÿH}.7.:vHJGҜg! |fՍ2߇wU9ЂZQ75T,-)pb#M}8*-|lbLЈRTB,ۍqiCGbQq! ݞ+(,rxf# f"5a㦏џR*O'}$k񝱺{[nhuӔM0tC3-!mȊpE84/3nA )@t7%zF3f\fJ6@~K 3 NkE}LIYL]8L"fngU;|q̭ 1JeOS$7ac6_?lٱhEcUjv1w/ 3d\mX^`iAG ~q6GŴ9jqj3S36 FFC_#=~}we"w^; goR\4}jm ZK.-ăÌJZ MP/+XS*6;0b*syԇ)xRLG׺Ld1;"Z+'X>\[:ǽ:Jk|-K&b*4b,xIXS90"EߴҔ"Ѧ\r*:P54 b:1a.+R*y9RtmZ'> ! J {~(JsѝYqѷ\a"}<|hSi[sIO0Q_/L) HJ"%qv1PHG`x7qO iAP䕼ؒO)E #`p)o8&0?9U!JAvi>BVX(b1jE̋z&|}mBu(~%vwdL.,f,XP noCWvUM,;Hۋ -8Bb2;ťK-|Et\uk[qIS9=`y lX!+ ΦjQ Mҗ=;|Im+Е(׺V+wo1 Lby[YEzٜB'jqŵV~Fgc3හ7q~Z1,İKH٥°8 owbk' "Xiйt;XNccr B`gEA3`aI]_t^3v`PZEh]DyrNH{/^Z}63}PgkړԠƸւf%NX|ʞqL+ݪ= BiWi݉"DVr a!Hʏ+S) L%BQ_@jVm|a#A$&1]SsPZ$rDFR80+l'MZb De, S SQBdƇ,m+IQzzٌ'M.f,S!mo۾1c_]}7lo `cC.pV5yXI`df-^J[s+ }FghG=#pz5>1U(98h۱po|P{A [1`€Op61!af^q"fɱK}4CV>N25d:^!*Vl?nNL[ H)Gr!KK' c`6fٺ%Z>'Sgá WM;B/4: 7TJF˟8_3 kQtU!/Fu;*8-ˡ#/제&{41f|;9O~Lp.+h<uuC?J-kj|83sWu}8ۆfsgoj' ϲߕ4_&1T&$Hx{hi; ݩHo$Vŧ0tvlI;NVOQ 3yȘT+)TNlis u?mSҜ5B3&7%K2CUcW.{yOO+%+곐y,IsfJ@@VM&mZ%RI ~9=o,ĹIpq8E~'ifP1WAnS"1K.6TS3tu}3v6h)aƗ/s9wul#XLkwS]api!cRMGԆ#y#rP4yё7( p_SX0Gs K9* T_iePJ5WxK>hprLJicJXKs|VN1':ʤ[c#v/7J$ fe'H34,#Ŋ '>߬ 7׸ &P?J N4{?ݚ.~.k ͟ M_R+/l+*0~gv5X d/[ x{]endstream endobj 815 0 obj 3361 endobj 819 0 obj <> stream x[[o~s5-)&mFm"PdY,˶.~]]8P(./3ù|3m 7M_<ߜ^ލ|YZ1<;6qN99|y  ! _^|BlMjV|==;|w{=(TM vbFY n{^?rP.긽훑)5u[傗j&f' V۫mOGlv:{{m #;=+IuM-1DjPS3qN>͉w|=*}W]޿^M4MiC Z~upwv1i)c~ Vz7R RSRNGԩ);X<[ f0xP~4Q`otQRS 1np^}Ԧkfу.}4F$Leyţ$:4ylCpAY8/`IghNy5NG=N{m"#:*)Jf{&cw:&O]+4F1 E0}ӋJִ"Ŷ8x۞^p ]a//ݠeG2N :.vUie%(?VRMVƣr"8g+DY61楖vfmaL2P-B3 UR4I2F><E\fUsIt/9ܖKD@K*6ZAYUM&+v*iidr=.r](4IգЍsw l=ٸNh+ pLDoٖx̚oEx:L nYU,bL"ny#l6M6F-ZWB]w)P̾H0^}o ڴv%6ڕga*y&ADE6Z(q{4/P'߈`Z On%Oc~:t8i8H|/hq|`M5&]g' &Kx Lf {~˄#>ۅyXPRahMwoS}ӏ5%mVl6qq-zju\Z"rCSf'ghL>ӡ›ȔSym™YXN> juw{[{Oje=0eyՏ|Q;o^MQc'#P&]Isa&mj> ݟf,7b򥇣I"#I8ȣ&8"]Kmq @:հE%Ն[lA2,R-7U9V=q AK@!UQb]%G'76zOFE1mc$`GTx?onnOs#~JYaO $r:r0ݠoILNl@km!Aڱ[KաCOɞCrorGܑm4a[qÒ7vUvf9[X乴Ҕ7ʑwʭPk4%(!pZ]sIڷ'PA9+TǬhZA*0pTs B|;L5dHeǔP$fVRC4LcQבUwoJa.{뀨HzIC|j[$JGUהSMQ]W@bhtjYI*l΅+M +N%NXlW}/R9-wSKê&Eo'o]7>,eNd*l.l;=AY2("9kqP Y,̠/O4]ٽQ;AL7Cx }+ -q6:%3I_ h9'SRQKn*<HmiNnuEߡZs3}ۇL;eO a BKPؠEK3U$#lcGh.J|d3¥z~O a[} p-V!V)S7 ӗ&^ewTV-Oy{N bೌ\YUpqE[oC?"R54Y) >S&e-+^%i'IwhK@T^71AFBQHG N=N$J$ /:+]l0t5]PT=!58( ,P:Sk]U4w<:tl|CF2yZ녭;]SC)8@89.WP SjVG]޸ %cz~ȥzG9|ߞ7ytCQ݉wq銑Ҿ 2 2]ehݚJqB-@.>G"Q[R^$Mo`l`ee:}.񴕷 Q}Sd`*S%Lj\K$]ӭa4mzBq:zwsua.ͫzH1Y5؏0>Pl# Cx+6P֯B\SgZDyxž\&=)&>jRUU{UC#BHioj/{޹M[c>lI}B2 T,'?T)cv{^;K9y64R`M]뱄ppnIa}msFLKBCZL^IiO%j̘^/k{6k;!/oXz٣&n\-=c4;" XT1࿜#endstream endobj 820 0 obj 3515 endobj 824 0 obj <> stream x[n"o5_-@ĀC)HQ2I_ϩ隞-2 =l_N._Nyrz_ݬ׵\clY_/~~!crf}z%VvAǰ!t \۝BlDjۊeFmwκNkf+C'|t2fӝ0~*9LSj*!tS1vli ^mwSGcjv':Ֆͥvn+ '[9K-yjsUy6K D|t:J&2YLRڍ>çwRN.Z\Ob3]"~[0 {MnzyK{ZZ~>6i;1ż{ݔlfW+m!;9)G=]Igt.ͻvI Jt f1l-k&`9yi]H. A~q/*yȏw71Qkg7l:\3'̢cZwVAPl[xd5֭lM Dbt}ea'[ y%{GWQv>"Ӏ6t}z$VUgvԫ iwCֵod,cMdPly7 J2a+9]C5?/kD$]]g Hݣk4:Y[yA~#/ 9ziѽ }/pL?[R*99QM& EM?I+LEI Jj(&QŘxHOfR'#󈝧D脊܏9 gƌ2'f(-Mh4c>ʁF<òSQs5O%v *xGClךtwUnFsx8#%yŃZ* e4S)8 zDơ߼ u} GkO;K|x{[i ){S -*3 PJСy` &^3'Vkm'n*sHLRp{>! ˇ}׻oXWe$4peB LSStH0)QX;6g-$㣯|*H8aq!7jjI9Fl&0=yc^UOs.è+BLyOS#Q% k*D;+ -v3EDF\a*:pxK iF=SQv m1kV3vI5xj,dbw2m9HCC8΋џg)^*e`lVBn!ruM蟲3Nk*?ofq`8 Jǜ1JRSPu\Ά" NC~ 136HS,;eҥlX.OI wd=]Ek0\9æ$!™p-ڨ\lmgJjIXVarڴf35yR@s\6BG 9'mxS~)bn0^O24d0\#03i\5BPe68ʘ>-씓T = ĐL)-u(܄=Q ti0Dt[}_-V!ϊX:3cU(RT~N3i:ƺ&qv:=/O8*\,udi:^l:hZZrqS6\1hpP'avYsZsiKa[/$\X;Lr N+MhF!s5ozUyF9،:W8.NRy9-i"RVڟa"(imaQ|M;p &K;u.Q9Ȕ*7IbL"-7Cƶ#lvVZ;n{ށ)S:U^Fw4;sͷmL_Vw#\kP90U8#Ru*@h9HigQf ? qivTuvTE_%m_=PU)}S'yS?Re+л,_WU)mVwR_>w;7Ej2+筊[}Sڗk4uUO3 }Y="]nћz˓r١WHrXT>!]xUzF_{ˏ/R}5Yߋw.L';w <@j O驶OeHm5 ~Vu0PMGҳ~Hi0$M{T1RrArx%]i' ߜA9A87)D_mv%|xh8|ä u/Q粃{Q˾Oje-ĿKevb)K%-6!R5eT]FM/ꢔ">ZZ>S5/iV*eН}őӄcI{`-3U:Wu.ڥdžUқ, %ea^ծ5UjdZR5'GW5('hp)b ׅsXx3Sq'\* qO*jF> stream xY_o60`)uVeH hӴGʤHM yr>~?,,'p!w(Cʹ/+Ŕ,İn&ӌ5jFґv>Q*o<5%ړ0 *Qz VȋQΙvƮuv3:[Zv-dViCގxxSl=XURf 0\(k?Ӎ92;2ɦ*Z sF\my n{ ^Y{N@ƜçHUhk?a:Eܖ1nXSr,mZ:,5i:Z?L(-07n=]פҹЊDytx6i/= ܘR-@9t߁Ss'E~*eeEcG[[g:nCpo&z 7'֮;c,GX[tG!O0XlU yO<Y@} !I d5Y+4p*Y)JybE; ܳFuSrk- iޭ@Ybd3E>C[vKV: ^]+yjZ%M#U;K.HKQp;ٶX'!F![X]j.;OӹB:iާ]}R4F8͉;[5yh `R Yg SĜV62dž>rDOQzs FEW<#D}!K,Ma֝$6Ym_ZМVeG oI`/zevP2;eO/(W+<*5^Gy>;l;#݆ENԘvht.IsrKD$ʮdbޅufǧx%`=^zCa sҊȞ~gt0Hڒ7q m ;޷vt^|5zA,hRFi2 5M"O + {T ogzF4؛>\Д VT㷱=`8|jEY?2q b *mtd^)r^TLV|Rg]w "kZc{ F?E9c.ozMZLcpkZo ԇBrKI(>`[!4ACCmc$OU|w>hqg{ڦ |Ym4_C4yZ6Ow K[@s8:Hb~`B4?h f \``i]L?t{7I"~OU_FonuzPDk҃G<8 t]×Q}xwXwendstream endobj 830 0 obj 1501 endobj 834 0 obj <> stream xZv}Gcic_'KcymY;'")ZEj!(yBQːAU(̋F_GAŁQu!Շ`i>;ݩS~Lo;ڪ>tsVd-{iҔl&?> 9It&Iܽtծ;Ɯ֛d1'6:BwCEfi]R)wI%]:8fK]o]0dîU{5rc jV,\k]l Hlc4f5) |]hm&NTXʎ~LhRv;Nxb6M FIX"G E}!MM;aaRÚLJ2@MLp 20F9:q8[K sQKgGeIO& r5Tp-"uթא]YL4I90Ʃ@! |u8 ;ȋҲ CFᘣ/`!e.i?Bsv\)D4۝e?ݸI)Vis9ObgtC}5(G_ CtW־3[‹aO0su>#zEWM9j ='QH,J +׎=杭ˌmG|pl-tk`1 3<#5N:YH +Q.AJ%+VǸ:WV\D5/O}"3tYL1j)m\Hu'"aɗyt&4ŊꂌߎfVnF[<8]aܼOyf3n>3}ͯxkfq.-߿XC:ݟc_{צ爿?eeNCc<+2F|[n =&;/Z%w>拦%wjBWy͟/&z`qRjhnrkB;7cJܙo\CUy To3'"CBdrk8ْ']7)cGh-W%4-L!ܗF2F^F..6ّm`p\򊦉}~ F+CWuTyo8]x@^ M{go;dEQO+fTW'g%;zܢ9\UH1Z̤_"HG .ħJqWگ8q;MQa"6ʶ;Ţ 5f0)k*':)D0h^!]󙔖E&?_ u) 0pΞmI-% X ۊӞsJG}.!V4BIqlYFJKȆwzC\7b^1|Ox̫5>|W> (`_ps/E|> lZV~6fH'Bp Y yRih'x|I/AֱI4ޅup@CF]ϷQLW5.9s1-0vO2. EPO12leIo[qfg _K/}("B Aι?C / "ka؊71% Da,ƌWbqHITb̆ӻ\Zz%u kaHץWSlE-!_8ooV^),\4/PV"yxКTD puD2y|AO 4h~ x?Ո @V`'KǺ 8By4q~^Q3j=jh5zd+ Pi&F!RN+L+5e'Ybp)ςլقWǜ5QK`|B}knQռ^ER3 v WK-4,^gn_PCsVDN'_Ɛ nzC|;q7O:x*Z1^_bȕwClFRqu^!WFDU~=R{ix\}w&zڔn{p>йYPn^+ g V{c<:$eZjn|Y&K;Ӵ&~4r[ ኜendstream endobj 835 0 obj 2836 endobj 839 0 obj <> stream x\[G+^ buxHB& d{޵M6!zSUuzf7!qwu];7;1ɝ>yuS{ϋt'w]~xs!?DHStʙ~N aRx/{y8)Daޤ!Fwӿ]6|J{wyϿ>RqiOQV_jh^>>\q(/! HiU.xYf3?o2L2h{0ڹ|[*iGhcȻA_J9`?M9 &r~Sɧj23Edu4qMTBv~6 q8kޝc0+UXs~rC{l0$u!6n(ϩ"('<}嵲q5/>{*)$[lz9W& $t ыfUg#*79g}E16~>^+).l@觎Phs|Tylv%}l&¶g=DJAD׋Ⱦ\>yTIB#\eTh CKBƀϓP@&!rueo8[ڻH%齈(nJ&q`EB+FhPLw>&'<-@TVC0#I+);XŶ%ڸ)("'}:WO>髌ħ=Ut$#yIU:e]3 @x#IBz%^VRL\ Wt| OŦ%2 !c`k#ȴnJ;ўMnB>QTsz U|YͪZ&["#w)9s&{Flg+y!hR 6I" 2EU!$rjTPzg|2mT0$QJMhoN=mgY~,UlIwqrGD'Ɍ<.OGi}SS>O֧Oӛ~l_羻>x;:7(3y/b!Izl8iKn/GuB??]d'h-L&6h>靎0KAo/?| 'ar|8NR|6K5gє,0{'OHx+$6ENPR f!dxkNe 9S)V D/@ 'SbK8Ky1Ҳծ)F:m\y7@ΑbնI50Njg;^Û/kPy˰YF#RaRI+Ks]ۀ+HHA{k`[xG)-,PW*HfIb (5?戸f%wQʦ 1j;#GQrur$(BTqh %Sqz'9]9Y^x @QD2x #KY3f|q6$2HQ$iY< vv8Y<" )A,{G2´+ f"foV<2wA[7ZBWjюZTzKC-~8Dʢj?Ru g 9Ȩ|6 XI DM rC%N ?)?dH1Al h K-|T&c$l 'e& ?>n&W(3q;Ч;zL nex5qlp8$ٳ4,zՓيgmom5FjΨ!}Z"LJJ]H8KF?4uWOZc0rŌgLMҜuSx8մխH)wۛRNXAJIͳ^eDQaTAC{i^h vcM bq 4i>"'3ug E7Ӵ TI0P1ȳVrÑ,mK鈸.˗c LaᕣdFbrn ā7&sjj6vDq5*%'3z̋ 0_2=QO$8(.ח|`$'FdSw2FPT--wn^+~j)%ݜғZ./>xpR9( jŃ}Ń?Ń_}񟇿ܽw' 1ݶJG wr!ٺ09y4MIQ Pp&K0:[ :'bRvrekac[ZϊqwP4i)/iUE4\u&ǣ͚sS({Ub_)~ea0$q*Q [P٨hNZRwV5DR5ޱ #q:NSH(8)X/H jo)W 0u&;ڒXwwW !#u8¨&L73>r%n z`ፍy Y/ٛޢ́܉*m{ܟR@ l:JgԨ*EK[I5Xјq>61/\†qgַMBJ05rLI>f%/VBjO+W9aTJ*We&P~ciZ%3 5ʨs/JL3Nq  8xXmjKl1ttnEK>wur% =.3lCTfRiCT UTJzn-W&s |\}XsA;uliE!CanYik<(cT szI|L9gajP/v(iY FA|MN[w(PY0?.%9g24gIEٙY(,eܺQ ,f>j r6`L RtL*OX! JKt)] Nft-eM?ByӺ HK`0<KSf+E,#ڞSaOZɹ*ݔF,E!HbhCQҷCPHP;deأYɮ|δz3,@h~g"e0f2u1!-(qp?L%eɕ51ڱ7\:75~V"K!{@TxP՛ HZ;Iqnx:[U1Ե\:٪I3f] 3A"@:idElP\4zaO|בUUx~X+['_[Y5 xV 8Sؚ?۵?!ERnٮ5Vݘ\3b:(!Ch fTm ; z]773qpC^QZMᾟ15ҷ@*~~~+3DS}3PWNCfxW&L2%̍tp9kțƜ˂1ku AMq};k?#ܸ* ߠa& q,g013]g=Пtފ8i֫CgW_%nv ៃɯKĥ+[姂PTC EpFXxi9ݹ+&gc$UlɛL)!m\Zj]TLJwCv$b[(X{u{Bryoxi&e41ٙ](aGnZN-&MpzK)eg ;[L3w7;ڶV),džiI:dEef۬175-CxhֳMr?z=znF>fѝc|ֺsWh CmSag0weeXۤPrTKM+JRVُNlH!_D}ưCqg3UkawjJp䏭# ­͔ĚÆ*zӄ {? [ֈU,7;:wt#uڌG}.` @ V:WHW7i^Zn\i> stream xZY /-3}$C#aāZ]+i+d7ݜVrGU/R߳a&nˍu,qD㍪Ѥu1 _7ܩ3dvb/EB*2O2~g';-{*vī™e0 d*ݣAa+~諽6{%lt̄o^iνAXpf7ư0 CAXyi҃›J2m[FJ#KڢF6xz#jM0=Oe9kB- EH#żP"AUOfJG3hf6Rr['xaw:)Y!fK!ݷ3W]Cx/.y? ;6*UQvRȐ&Dyd+C7{ eйp#nv&:8ͣt138+wȀ“V^8Ji{8AGnB[7ˍ^sI!ߧ :.~=Y>ޓRY\m H1-4{ J&1`zEp.v+̗G;>/;& k>åp0:N:%8+'QRD^&4ZN> 0'rYI\5[yOBVM$h ꀇ؃R^]Fc cQHH%aJCPmΒL-o5z^z QTJpc[N$mumw0%vZǍyq0-~x. ?=ÝM;vA/CR=(SGm96ȚF:*u:F8]F?6rc8+/f@XNS s ZS^ռ ̷,- )mTB!i!h(j"}>_YȔhȭim>o/vFAȁWm5!'M*y}>6⚆8fRޚ!妨D?:6>0}!]ua#gFC2 vX2\&~`.I YXPV&GReHkNXSK.Lqi;jb PYggvRry# A 1[63l\2vP"˪>;-G%A㗲F*hAbfة#rn 1t`AJa! Ȧo%`Iu qɴԚO$Dt餡_֦[r2|Fۡ<-5-23i(hiдzԪEV E~3pd7k(=jR{zpS39^o&%z ZtuKĐpQC4s!M>N(EUd'بT].;CjxGm$)>RJ>z-fuWʕ3q>f|@uI-|1ooj#ZyfKLu,1HcvxqAb:Fx0_%;;:"?j\ |Q}0ۄsk]g6Y{>[`oڛVwtEz+)i"slFh{KzaW RY]AdX_i}vq)pf-;][SB&dX,RCMPDt44Lx{Fǃ5^:[7aCa\kַ#5sî;l `nJ# b:EMKz )NzD8IE :/)¿5R2FAyS/$i:FI%`IJ _Æ?G.vUWtuH*^*>;)WLϗD[-6?eOu^91|!-gevR^ϩdb]dZwquV_.]yendstream endobj 845 0 obj 3051 endobj 849 0 obj <> stream xMNC1 pCnI+(*R`{AkMw~Eendstream endobj 850 0 obj 209 endobj 854 0 obj <> stream xYێ}_#'0, pn0e We-sd7=bǁMSNq_=wW\zsEF~} V!pxO*ٜ.ze7ǓV>x2vz~*)M#l4=l *MĖф^9TLءQ·?]])ecZ9Py+O%|.C4s̎|^' ^s{G}b컲6/CNYL94GC8eb U4v'^!e3/|!L7R6xlf8nk!ƹ'<.s|K @>!.VQLpe$7OLJe'Ik/,벧y%y8fzyݥ8>>/s?O7}|Ր(؟r>}+Ǟp_gVJ搑?&8iYQ/3P3qO)g]g#ڻftu~r:VHy-|6.*Ӎ78*h_w}gmrf`fZ,rzǣ] m5cot\C#r:C`LN@!.ɭG݋q_<5/wuF"WD.Ndg' C㲟z1'|D(&P?. XQ7@.k޳#F,ƳVVgf YLgӧf|!0//8 "H̘R|Ny!'{m;CŝET||nH#9C^!bΊ]Ȓ s~SX$|ʟn܈'ĚrFUPDPeN-]GrGFH~9T|!a1bM[ B/(fFWk+GaR*G-= d2]jZd 2Q=ZdAf=Ώ N% SsCy6=M'V@$9 ~6Ni*.lKG~Q~h(~udQ~(݃1s-%@vi4xٷKx3\E3Rz(yx)KmA"׻A'I2mTpkk?Zd!I⨛ZܷMZ0uG B7zܩ?={y!f~Z - j :VR,-2,˾fd֝:V3E(G4$O1ػpLa^psA2Ԕ>^ԪgѲU[cd zRKUݤYdb@atE)!i\dn>!$X tQw*|ub ;ԹJݪm-ǯ/4_v UP ~z;E/1`sp\뭦7ZESA{sS#7{տI|7ʨ1^w'~]0R^w\O*LpK4?{t?J n">±Gdy[Ac㳵mZJz[\n15mk4v`kYoڡwZrK2niu _M(eP/x}] {]'?)̑" a-ԏȳI뫿߿G_sendstream endobj 855 0 obj 2337 endobj 859 0 obj <> stream x[W?bchãEˁ0tGcѢ]ձLL0=?߳.݋WNxA}`J'?D~9,{=w }0҇_p'NYI%e(iz-9-A)9.Sџ-To<\6~6(@k@҂F9.K|_1bA7y`Nhjs1H&2 q- bNBqLWEŠvQ CpB;xqm\T|Gš*WlS)iW6oCxy -<=xo=^|}Sg>z3үd^4~K 9|GĴnEMgT"vvsCT뢚 ὆e@}Dnߏo)0:۰z.L.ThY$yMF̘_AnJ8Zh""H2#b/ˑ%O3 e-6 vr&ְEg BO7+G$M%ZY̩M#.43 $ޜsEr14O &6&Ȓ9Z1l-we -7rp$uXߠU>u`9\~De>eB8kM Y }V5Y*W3iZ`_6.;¥LcnRq$ u5ĺV̢I}W[Av͑l 'Zd8{HK{$U9?5˅ |W\FspgeFdNQ(}DEM˃X"R!~ [C*xBPVu'd'EWd\D-|rr`2|[{N;k78kpl*xc-@$Ec*[x9 I낈Kh++fAp)yO3s(>߉*6|O zd:WSJw Ǟ;s<<} 99.BJ'G`回d#kL8OtZrxXY?2L l#5]AT]gwbk>42 s;GC4Uy@FLhXY3^$nAl=2'ɖM#&CQnShWh0Zl]zEFny[^'ˣ毋`@4[0-1@3=TF&yaO\*ԩ[q2v C@'< GJ>0|Һ -b )Y)FkJφX9;bAE,-2K/-#p̮N}M1Ze&Y_YiEi¯u@#ݪG_acւg8 'iV]#)KGc-WJ-,,C4X{ehg`bX]q "X} iضB^ %C،}RSr܋8eoaVN/Yj+m]7ɕy.s9mau1mKm~Z5 xO S _up-XXln%PxQ:kcɠJyS5ۢ_NfLo Hyjy3:Ey4o3eC.zb+9vN W<[o2 wYmdJ|R\=UYMRz{g@~Y̋ f6ZCMьm`–KL 7v ^3b)fiHn>l ݙ%"ڍ&۠Al1`gL 6A5uh8Qނ|pwo>!HM*FF.+=ER[X3w&6asۑ$i-~֯?zEj @onڃ0[)a94Ɛ~k4Y0 Lr2 7`OC8_mpVه}mQ|{>ÖS81quGfxc+5?;8Mg2I(Rs6D-NIH U;A$P!ʛ胐տ+1 XRߖ9~.ws7EmsوxCse:ȩ 8.4[weݭ };HZendstream endobj 860 0 obj 4135 endobj 864 0 obj <> stream x[ےܶM^+HVe]Uyd9]qYʦAѽtק$ gTU^C}nc#4>yx?ƫ׻;!&` o闷Ab!VtR8[B)~ǿv}A *_B'_;W9`0oUjmVBjeq-,ᢧ5=Ror}PC>wJhmi(B# I#m`P>ơ )oK-0AaQ^6 6(TIhI-y}x/v?6w{Wv4WZ4;FuJt Z,Y; ԄIZ'2$87ںԮG tu˂9*m=VȢ^j؎VY"P_Ui,tWgj m]͗d5l81VPqjX?e5Xm+L] VNfŭц_\]T ';+u1wɲX?eYp_p^ղВ6D(Y$]l HU%dT@^Qβ@57WVnB;M;K8hQ@6?QϦs@OgY f6ܶ^ )<͓1A ,s<, >oÃH,25f?I R`QW U<*Y au_UPGp DruU-{}ЫZ#,3f,eQƏkVC+9:M$/\F)<>;)-줶BNS QOȋgn3fc¸lR p#$ ),@^ӣ.0QǞ<]\`C,UEbi : y&-ipr=譮WvH+CqB/'(gJBֻbıXFkHfw,t% z,gՠsc]kjWׯFJ0oAz"*|3kW^[#qKCoPԻ9E]-,t?S.(_WSÐa8sꊖNE8BD9KnZMt=:|Z={Tid,00S.ylWE+s(5I(vm7b ć$Ƴ1]mXZsORq:WhV-jK1~eϟ^Uw\[;zajN@rX.kfŵA#2WAetF!_,z[6LoՄӓw& B܋qJOL6Q:ڶSH-{Enڑ'vEv|6 rxoU}78+!ΠkyyXW}k80T&o "6Q\f}ٶ[fzm4S&7F.̇>06vu_uum}PU돖G7F.4<0ZuR#zI϶:(<u|cĉ<{a.`u_u=}yۘXd7FK%j z˼Caّwk;Ձ#ѣo 8rFzxY K9CȟEںվ1q}yzC^whQxlӷʇSy1R'(Sp$๨! LF2ۻYR$-i ayސreWShhK!ΟM̱($SꚰXj0_~Uf!cO3̹5[Gk@8HO( E Ô{UH0-WU> stream xZےsя.~y\.^bz"0-XfXdIJK3^:A4yɔ>nP[IOm>mխ0zQ (M"yFχ zbwm~Ts"&lϘt' $>6aomN _j~TM)}2wʹ\.;cPl6^EݯVW b]?Y&\GNvf :%7ػ60&Sn=σ n,農OxXqRf5/h iU 4H4ʈ̷M'i Oruʹ:5r )c} B%tlDEg#/[g xMN8x"92c5%(!u-a{(x9 rr1;$k"E;]<tG޻Qbw_. oxyruꖹv@7F~%_O$dK+? ijVԸӀAyͽFD7x2MOv9ⶈ&w¬E~cຓ>bB^؃@?1 )u Aq~׭hu0~ae6Y eX[M % \oѓ/2$WMȻ}&n*+^Sy9#⤺3 R@yT_BIBrL$o V۰C;(%Q'O6'6HR!2bzKR-ԭT0{VkvA pajK'6TO:ols_)a^/kGHNGaq yFz=Y& 4{۴aOTx洛W;k&bĔ Ð5.1㇥ h)7Rd-~R}7ךۍHҔ{R|~A@( %oP[٨dϘ܌i*ZqH* `lhEEsmB{vRqBfu@<ƜzBz2Z?G8T@61WT3ԉ23TX ڳjJP[ wH1!yNGpJW-nUr5(%^Q%&R ^ksɟz= ;>*c FɯrNL7$6cs`k$8߈5j ѕ*J6HȨ"r:e@,8\털!Θ)G,[M/G㛴B%]7b8G)ؕTC@p[Yw;F5YٞLzoZYy5yWoxmke~3?(mMѬ: @4JتIY-otAƇۀRb2:B"IX͘=wal^B3\ٜp!% jW9HрFhPook& {SB1Ƕ[2ڇe%;c,҈5GO2=O3 w*/?5v I6ݓ>j3XPZF / zO: f,E# )@6w'lZ̃y9C )w^N{ka \-fjQt ū=:92Qzz;0Вutr{(v/;إf@mRfhmxɆ\x̑5E)嶆4[z'IYf^ E7 ʭԒwS;P;Bjb'ӋxKU/"w飧s欻kyF0Bp8puo>ZGoS] $roA z;:n. |o· 1wOa`x,_EF}+.)w"=9s/endstream endobj 872 0 obj 2919 endobj 876 0 obj <> stream xZr}g#q6~yUNʉrRfRIS}N2hby4ӧy#f}򛫏gFnzSRR|+脐aoo9ht;m;&I3rn?Z1^=`0{C!(habnC%V{?4Q!7'se*[IcĎb9_%w(=_-u=~o,\k2MIPhaT6SgD]G W஽F I˻ X7 HVcBR*hRLDȒi}%%hd͒6 [IhlT:u|.ta$}ll#]~Wy_ײ6./iX⮬Tβ ?#$dptX~OPI sae3w+Wܰ6:Bd%Q׶vXrE*>PR$"yF9G%&ԲCn<J/0|q >uz(PeUTźce5;3$ӂ ᒜh݆vnTqFAСz"T48fg:E吝":(|py9${Ĵ 1J>BN ¿fCdzm4@$TK+T+L[$_<|8 \[a2 :LL,IP9ǏYӛ̥Sny[^PU;- ́,4$#!qOwx.hB[N␦چ x21gL0!v̤eue~vʫxR&b"5F%_=$jц.eϤFdڟv(blŀfY&(8LGgm.OrĔKƃk>*߹G1sllEwRAK;kht}R Vv{BqѱN)LgQRE㇓a4'I |8Bt i8I]˃ XCA5ӻP-vh/F)$/6׉ÎWW kCԊ/c~#z? wpcǦ-v9X)!2#izt1%2I8QU)!V$RmjإG6KḂ ;fw] өHDfV6N7d;T# LfX[#ͻoBfD"SWN>V{]S04%I,'07Y|=W䙜 >+N]48]>^m̕gz9_sjt<&߰DUb(:tPRjnNaK2'((?9hPt%Y&O _CW%-7D밓Hᇥ_%_(Xxϗ0D 6Oy, ^f:n%q2 m1T\'eE af!>ߙv iH;W'a:1 }Lt(l qLǯ >_{u (qh3~EEJ% ͺ2Հ_ ("RyKU!v=h*˓< ֮f<DI}t#2,V+6١xrp\ {!KN0ۜ7*߅WFXhb` Jҭ2mGFTZzD4/D#1jzUr.U_v_/kzܣc]n>)Y(Z9:í}c`:^qzaOk ;Ya8ԡx./Pjd[ku:aR* Lt{ {=e_kw=v &'Zg; 92[3oiOnk%oRpYqF4-uF n !ǑMxџ0*⺼|ÁɊJף׭<π/PCҡ.n.Z`W27wpЂ.I]DvV17YZMU> stream xZIsy1a&e/ #ɋĔv*%Z\In*X"FH_ Y%#qt%ƃiaR]/$X>o8&kpnvnjD,?J;})ctj3DhK:lB+~\d!_{R*W1I$޺j/tj0ii6 ,Y'E茑,tlB] vX ,t:xƞ$|063w]ppULN16 5]"D"(<0]ƓdK|&FBZs,$ւv4e`6VC@Oi;0k2an9C6;p5[*j uT bp!~d  5P"gx+ 7&$YEH 0B*"& L7v]@nq13Ϭ$d(WcuIq1n@t"?:iriG"?"> EnJA;/KeMu$jz[$>1 g ߪTp1nY} JL?u&("kH^d Q,M!Q(:B1aM h!פe[c ҡ>}/f>K%[ Utp[[$AXJKX3t.,gc# 4y<`)bٲ ;$ P9 9^@>ɞj5g7AU ښx!Vxґ|dn]]vBy53tzA*LUTM6{w|Dz@$~RgOQ߮_tafr7Ø<ۓ7?f%>N ku5 F%/."Xjk'[ NT1cWHv+&cdgi^W z;1Ud7;^lӆS!"iÍUa}ek2SdP&e{Z+FLo[*$urQQ\s*3hy*+^ IVAJb5x vH-J29y:wV.zZn]stonh˄Tf Tj>KE$2RWP"G Sz6|m{M툤z+>1eR@>@c=v{|5IwLz¸M}k2])w^R L΂9-$=VoƑO̧@2Y2ipefT{,xTn^;ӫNԲ}[쭾sZDtS$g)ˊ|DRtYENjƻB/wFnZG㷷Zx~B{Q.ya^ޤe{ڑE+fDݨ1}u%5;j`,ro™[WP"WL]$Ы9P88O#Vӎm>_XUB4OXre>TdI7KuٗnK(3JeQ_~]g::dw7pʽ9vKʒD=d_a if o;.$T?pyB5naE3P7> #`ZDӃn^WkƕݼwK'ݢ ԻXȚų5e^~@:C?4ͫQ7۔HB;XMM芶:IJ8=P⭰Դ-k>t=΁*VCYxlke9w:9UC,zJRuw,D G? H;p?(}\>>T(0_oϙoӣ੨C, bhQN͟*_4T}w4BЄxE=' ǡ_Z&'s|z>/u#G(γNdyJ^I7sm %j|Xᣌ> stream x[[o"?bߺ[`(/`$,ɖlKrd)}2ÕI@L<}L9/{xޭ_[޵X[W?D~XH`^63Տ QCPiiFnk,Sn )k7eĪvn>L כ7y! +iVaxƅnMɹߜfjyiwXq_BB 1 3]$a?HǂX`sOJNjʛCmi3b:> ]狌W.w:iG%1ha=y81jJgezOgrL8*u"]ittxk@0c|Vy[L \ P̈́<.$"MBNW8[m%茍a6o".& Cb+sRŖ0Bb>c<=j@(Uh#ƥ`8.^ta(SfVh4jӇ\-bpd-ikni9)a<gC ܧa|Av1\*kq%z *g 7chOkvh(?|{xX=<|9yhOt泫$g.G_^NS" gJZ$;8SBT?(^4Lq!m'֌ b% K[Һ,4֊q,VxIEAvay}eEA9Q@T u>{٧V.o?R00]S^eZ﮼e~Ĩz݉WdmNWh9yoAD peҡaR8Ic9.5ŜpB"MװTl"H:VIds^n5%dAbʤ[*)N`ViX`(WgtH0:(P܏ڣ,蒈ՅD<sSYiDW#*Tpd!sT ډ hQV1ǡBH,t9$rkԘ8a 0"/g"T&iI6V1OD.B11hX~4{JCpڣ\Z K*,<'HvV:Sܶe/8Uy_,/{>jYX*G:,:('ehKnsFMHSeVXF~Z~.TÄ6$4FokGSIHV ^07jDyMW/FW%H1w,nC`6x1\C<3*XLv9R-DeA.,- ʨu|5y",2Oqho)K]K /-R 1 ąePn`aáO'KRI7%$X{p6hdAyjNsn'ô<kOGhLt< {R?3 թ.dCkRΰ0Ά[6:"uiҺGq"{E-U"o!xv(֛@0ɖ m6Q^ e"똋rȸwRH7s.]*VJyRʶZh&hq|G[httdCB`L >-\uWU={ٮn2z-C~}9oE ~C*)o۲BX92M}qGEˉ,tЂДըIO<=$V,γra>/E.QRܽB$4Ճ~_ϓdr$|-$!P]_ blcʔVRop"*$x۠j^0E5%b,tFC@Lץn XйIi>,ͧ 5h?.޽{Rz/JYiwŮj1Ѓ^%GU8US9tsi> cJߖcaAi.. Źgwؼ"I:Rw,̼*_ejٞQhЛ,t]:-xY0!#3pw56_X'>.ՐY'.@]Yg.vH%TV_\ɼd}nHQE" }ͽ턄Ê5MMe1d:AȆϣ@ !5it7$ˮQz#agB4< E(o:կd9ᑔ6Nj6|cXe2>TK\\!:9U}\JR|g|^CwUQT }YOiJ(F߭s-YoAgyPas+ ֆYq0~^ g(Ki;Hɣ3g=uQ%&CN܌4)|moXDvjF,QHurv4>0ucktɾlGV޼8 <\GN"ca@ Y)}.䷹O,ڑ8ǝ=jwG/ &PlK:f}o꿝endstream endobj 887 0 obj 3457 endobj 891 0 obj <> stream x[Yo~'#~ 2yʰ#L@XH]>U=]5=WuWGW^P+?G{^r՞*䵷{j^ꕋQhWֽ1Ig;1%JO@i`cn֩4m*R׽RY3j{%O&u^_R9] ( $;cPj6AjP +pl{uɥ8߯N;lYӽoL+=KF)R"^ p2򪎄9A{SojIqJxVLieau»Tyaϖ1j Q04m3;kn])Gcևں:YT`ԛg ZQ)iW1*-E3W7qͿ3$\a]v3\LKz0Z!%5.%痵;50KN/}S]I mE*#;njh&u磺)f}=zIu:n:+>vXTL JDW9H;P[3vq׍iw^i NϘ[$M@D͘f=?-["[(>3,y=(Es8˟6eP(0?op{ǻSR@rm-Y-[+IGJV7Tݿ\kPNћaǸ2 ={5h[ kE@|24x/e3*VVIڙ H1 e^oVttqU# B0}˺K[6E9A7LuGsF(/H5:/lm EjNIc1_,l} PR`Cp.–p#2ݩ-b.4Eό{n!aȒk c !2wgGYu?mcyB174xG*C=v. $cy9@b0=|ќM.V'\Y47' q~6?LTb\q E<4Cu%O_(@8qPr<>ևuYXr ovfrq 0ǁqaȲ1p$0s=cj>c3 LD=QF>4Ys:ԏ;)u dw挅Qcx}"\ QP15%R&<|N͋Q":HP%-v-xˀKjtc,V=6>}ZɃ+L,1;¶E6lzql )N qՃIhSOd}ccW+A뽬Lvp=>('˘'fk#^;SdY q\򕘖" V&NTՓ 8Wb.)gC[H[8}&Cx_y&I8.Kx!ϭxHΙ%%qjrT&ݠ2zb+v`&,V.+G'5ďB@KUe=kd˯FޘI D =fC>Wv>2VVC甴#-) ,7'\0 gi,;#@=ޕ?XvcH# VXb~-[̥U_(@b6W6 v1.k/L "x.$H U;T5膮xFUKnɄo0'~02c<^Ȃ`\A¹nC[/bhܵ<ـf>rXȧ]|$M.y9XU 4jBzz[ _OF#],?'[1, ΃^YKfPV/y>7&f<4_]E+&7 calpm8N̒;돋]Ł]uϱ%$3ў .2Iǫ2lFJ\>| Fpg0m/t0+[닛rX0<\(okM[^CXFڦ,4Ks8v׹yeFb"1 $b> stream x[[oqЧs5<ķ֭]4Hl9-۲ȟ7\r9Jǎ @Lqwy~ Fgon7RFn1^?9!lrfsHacC9~+w{;( 17ʪun{gWVZN&?MoN-E؞Vl;vMiN_҂ߞZnrPJiX>^mqlʧӘ{=dioJha{wP*.@` Ib*;Nbt{?CwxX-j.v{c"w[{D/'>õ: X}[f)o.[SKZMC-iaӃ1>m٨UB^^-Ѣ1)Ĝe7I^a&X65ֽ}A a}Zx9QUx7 ; *6a4F։p,tiAh:v/H ҫgL{]hm.ʢYA" lƞ&Cdwj: FEv|VKz'ב`Y'"k6Enj)U}r1a5&kb,fTֳ/u}u]PktN^aҴS B Hi.3X!Y~*,ӎ P`Vgns\'#i6#tEĠFN 5E0dg 4:9FVꌣ3bm4ܠZOYDX!C,&.z>Buw F?p& ƵIk N6p&*hByWv}^6Iq Bqa\e`mݲbWb_=@壌&z*Fbޙk13B.f|AQSв`x%W#nɄ^E)ThB{8w=[ɾZWUGr썊8gc#F խ(&\|SS+ǧ7;{l_b'/JĊeiU1y q1WR]OMT[-?Cņ\ee@jum[dc)IUXD+6CmNjq!RF;iG>\_>?<7ߝ?mtt{%{ Rp4 kvӕDVj8%1F@f(YBб nSA58FnyT^dCVݑaʤoc[imTshs쌐mjkE&19x#LFe yv=ͱg.jDGb;,YM?Ȓ;f?{/$$5f4uD]2d툳E9? bYT]Jf̹YcUO٫o9A:[<"n՘53Ohr.0o<[G!^FjS [BIBy޳847THf28J S6BBǖ1M$)5F--ౖnLAP/ (㳱Sb00tO ̖2֯^ %;0lbX\yQH}Aŕ~cͳӨHm Z0; Di`$I{mﶓk\{Lcɪ-0z_= r: O(ɔdbq"NhQ(7Q$)qYR bs^N`{-d<'(V0ٲm ҕ.!EРpҏ_Jj It/˄yfr쨒iaS~3n*^˄kz/%" SSTM#Yt#s^_S9MV[F._H{d\ ٝыRY„K aϾj$-?tÒ93ê&ӘzԋvŊ5MHS۴BiG bXU2#g̀yᣔ}gk-WGl0Tl@;حT,7;k'_p!Ex1Ή" 35ȅTO=9Vbi?uZ)36RVMfv=Z,^ lnQm~UMU6==k/~慅9(~}ޯjgzZ<`;_ٻh6_NQ2,Gly,KϸVjܛ729}~g/x@Xft!i5ۏ^R*.Sr}H<^3 J\ c{tٗIEC+PZzEim, vC 3LX`4E7WY)?ȍs[roqk `s6&X ozJG$,w~}:="iY7ZrUg78ƁK:쫯) )DУ# +)vw@_ZhrL?E8rAe8IWwMڭrHiUS9nE+ŬұoJ~G$cZE \+"dwKWIlWa7I(_lIF{xм8J)^IA"EL-2e~I)75B|tO0ŒmKaWl{VnNhHfkk)?Zl9g#$|/\l߃-Y{Z3O*$&aᔒ_N MX +ʎNMЁMendstream endobj 897 0 obj 4171 endobj 901 0 obj <> stream x[[?<t<K0r9y,^S1kB~}4RkFbH;Z緝Ng'7'ם}Qv"?Dyzw/HStʙ'㝞7V*Ηt7ʪ4ퟴ˟G9)uܿ>,v~/h&AIf2B;?+>KkHb!K-*$ #_dKT}JJej:y92etf j_Ә0tPjJXL.&wx-Vذ9ơ?;=䷝0 GQ&v ,7n=yWOn~'7N}t`2leR!ïN$]ə K dKMohpxv v)@pi'] `PҮ  ^oF̢l$d8Sj i~i4W aqBrj2#]FHGi=. e)l0RsK~ DU Cz4\_IxVIo:o?)K~YtC3¥r0˯T1ǘp'q z@5Xh%A=D*aŽy gi-қmHzT(OHX %Hu?'0ˣ:`66&|n"0'+R{"i;V&mCPSnI|^rs*XLj0]' rQ./h-V)FzvOԕW_L`PrSRrvLsTx'>bWQ (F0ޢTSK^YB}a5A#t{%0&`K1}i8+BHvy ڏ+W2RU +?D:ˎe1[>1(nz?f]* a1H!G#a9U /gf?Y*M"@@fx4Z!rrn^2tZx()HLil*6K|XiwfMݰ QJH+dlG.Yd )>!X ADmSJ^I4v0kyA2ލTLBd2&m!QF54zvlNfUa+|\:4"!-?B ʙVUcjTA$J{%Pٍ΃WMPJJd䛛"嚜s0RIZ7`ҖZH7NY BMHqu@ZN#z%>o/&kv{%ɚȼ* H$d#u !w -=nM- ;=>hϊ;qK&ۦ禊*x4J rP#iYH19뺣PyDM@> wSk{4k(YWrC^[f[r"jtl; )c~ႍR]0LVip:.d9̡ MolUwid edRTf,}B"!H"7P ƛLڍ&-l+؞݄cȟEXЪQKnK#yf Gg7jl%eƋJDY-KO>(*ZVmbir2=m3 EU iJQ 83*ˮ8LYÎ2vf"qnKJb}E` 8[hh?Hfҍj#Gd8&0ǟ~2'ZD ˗hAP~\ƫJ[՝w]|ꙗNqNtLBtc`ܻ:>%&V s#/ۏ#h&Ή~-+g>CiK}ڝE{s|7ߡ+h]S|ZJyɐkcsl_ ġk`ǟyfɬ b968~}aG^v£/+򆴶)qLӡ8@hlOO!e_I=k !!q{5I0M'= uS+nv$Os@ۃ7%)Ӫs#n5D~o^g_c Ɇ-H3lER?t>̮otg{SWy6?͛3ҵѹ .f!}PXFgyL'59+|K(ENn)M1+L8O)uȟBIHZ)GBj;ŋID}վNS MT>i)GqccuοVs?Bendstream endobj 902 0 obj 4259 endobj 906 0 obj <> stream x[ێ13%AX(c[^xvr=~uYCw7O1 ]SNS1l›g'?h5{~~:eκIk?=d?a2?e\ɞo0P9=TB44o2/JJEq^PT\*@!gu!͚0xmiĤc&@PQBsЌo %--S0]o'LB*|7jCjRIC#$VE^Tiy4s4hHq׃B ^%ahl00=jV{oN: K tvx5Sl^b $msX8> s>Y |Sϗњd9%sy)C67;6Oh6y5NplX0TD3K`B)P2 CuL.d,3d́=Ybh3i3k`4TԑΨlT<ČTj@-fS=\Z:)#dEr .6b'3Aoޖڳ׋_܆i4kNNoOv-xjPj7# tK )Z))LmcLZkU!lݓ^Y-MأFPR vx y_c4*UY?Zm~eI&Đsi4ӃR^ K|7!nA3["p>g_hQ :35"OdzRA!xȡu;DF-KyO$0 䉓Cna;iKjMV v63x$cdN,l[rw;7EME5:%NZ?? Fe^aRBdcCT?]*3ʂjvƴh9?hHԤdEAО-t]>JyݸX8:a,ݨbA/J3nRQ4.5Ǚ9fq%S [l!V{>0ȩ~9@c}*jXiOzZ+M8NY%"\2Ssa}E0xp\]q1â{U:dOI>~xp|3q!$kIٍ˦׃r5a7inwǐc!m|C):hP`{^@uߕbeaOQۊFí0"&e6*p\`K}i +ˬi:C7ZAl[Rl'5{UMk$B][q%y$4SYѹ̆PX%˧b̜W"YCaVUPz<(fK)97I'92W" Cm^.>7 $!YM6jk?NJ~r lbki_ bVJ{M:Oۆr 䊕!f>Q7xrNf@0P[,  GQ&ӮE!tiy YJ-rpr.feA%35sÄ6LX@Ny%Y*]0_'$ن||+  5Oj(S޵l5W]\!N*…-lYs(ˆIBE9l`$GBAU-*#GhF-!=嵉qB Lreyϖ~nw)-A_f)ux;*DT-goK s-s鍢LJҞH"{0@') lN|N|'AzbT/Rj iQJgA38jƽ(ZM5Ĭ?v\^qRK;3j+ˬm->NYߦj(՜P1PͲ::)GW}‚j+%Af͕f:b!T*H!Śqᐚ>x) =fY\L !$DbL4}d}MQar/a[*g2]6QəV6#2+-7Ǎq 1Ks+Y@Lq󤦍ԯ+Ͻ?[Ţp9Vei2KCv%R\RY҇6v qqp#Ϝ^3+Tz@<&a"1׃XLXוb\_Dw_oA]5 Q yTHJQ2KT 0]4QHGAaL&+̃Bo,}d(XCL\/vWK5:EWVz~i[@-|w-W{Sw72Fy?&줽A$ .ϑٴFo.yHL1eJJױt)'brBYg(D:.O"]1Fendstream endobj 907 0 obj 4145 endobj 911 0 obj <> stream x\W?b< hã%6mY:H6l?<L)_T=ӳ$o ܄U_}zىY}C{OW\o>9:+~N aV&?9Da2Ĩ'Q8SC{7=+T,~wދelPFvxrQ `\BZ;HNU.x[3._eejz7ڹiAi*phcH %mn*G񛽞q0^Ƿ zpNF;K/Aћ0] &HYi|~}/;6`氓NYuÛ(#>ϻ7puߧ_%f{|޼]>Ɔ7hG9,^><8|  ${̺y& >=&f$U-=Ŗl/­.|}摆l$$Ȧ` @Խa^JP:NORWF8g nz릗Uyon@Jnrn+^6>V'_gaG=nBA -`gZ$t]=!3ᢺ6Ba>ZFfD*h AD _H0tSYk&{`ɤzbqyLfAf@h--v Ed+Y{T%" Jqzsg{R92FlXoA3 /#Rr]L >[pV'mGta`!k| DyRf|3 n ;"eZ<>Whl`fmp2`@0}\dӠ0R E,Y.\ H:ˆ87^( f3Z8šzÂ0sG0qld{)Xxu+l^8u!ygĎ_&)%EWPDvcm#:L"7 i?BhI_{+DCK_-Y,·†2sE8&lNy5x0/AqvI]' A;Fm6)S$I-@|%O˨0y!QӘ1Y[26GQXT(XC'KbO9h:ҽ\"j ɛfL?z lmoG8>W:zH|ByYmDl9klBJmiKE]Iiu}F~#wI`q\^~A7@epx ]2MWt7L9^ rj%Kv @:3 J(@S`i^CܟA;#\-FK|ufO l!p:JfVI ]5MaOYd|BuhA ΃t0I+[dDD A͸|!|w.P#b,6})Fx ꬂH-H"o?WZfaŎSK3c8 YNJ[C= }ؚ:`m[J1HY%t ms X%7f0"K$Xxn,6NV\xdy/LYBIiF}GIdЇ@rp߃/Ȅ=o3m}σCH_Clρ(rƈh.Z2XVG<gE:r۰π~ԋ~^,pktZH<Eo_@hB \?nIĀ ;e+^Pۅ&Y`eŬے$1Zr5 {?(!Jӛ/f ڇs H9khլm+Ƀ1s+]zsZ.@$H%<ߋn@6"i*z%t& 5!x4R6%рEu A62=i4Y#`'j@!CܻF`SGf3'# R>f8{i7oss8QHZm0wh6J ix4%M#ƀkXZr+#C7g$?5V9#l+#QX6NOFتfJrrPCc:P.!"~%N:Ѝms Bt#$D<W+k:C^䰩C?s"q$3Z~ZkrN!Q=lD+tF[f$,ۂed*غ\$_.c.BmE&XʇЦagS2|-N f0_;ADlndnBw+_9\j*48xwވUDa/ť 7۪ר7348jR+[PCz5)2@e.RĂLYrhAQ40QqȟaCKE걲\Y;$ }#C4Nk bZ(6*;ӎLUOԧV2 A|dmv_ $B"zH=sJZ0 Pي( |Ƕ{ϧLѻ֕¸:lŢ-mqd9ɤmFfBm:!a`u5X4U (y-ִ_=ugQ(kI#G>gX3^-yg*ML z+hElps?86M k 24b@A1]90wF@.ƼnhdqEńY,׸:θDq"amePq/ig:(j< * _rM]C(I9WcIWJ 3>|[!H@6HyPqf"6&柔: )Z-0c37SLN XnǿS^Q(l,t3cHjIx6N!(,06&WH..F[¿&j7қ(14,ZN,gZ`XǦ9 Fa jёj`z6f)*籂 1x pѷlCjlvUcT݄݊Z &թ3dCfQ)V=qM };Վ*d69U<)Ǡ!/Cf8ǂ,sFxJ:‹YN{O$u*7Y~>z} ؘ<|-{>gL5g_Tq*xKm =ƺ,9\Gx" A /&VG%W)w1i[ϭQ-Q-|f""1TH%O^cGwZL4jn}9N S[6lJnkF+Xe@kw؎"  }ʉb|%4)pFNo8e2Χ=V\~WIՁ~0b[10g.pvn0_RE2=BF`MJx{;cQ1meiU&K~c[\X[)ن.I M#MY966zTXA/55I:n`6R6놭CHeA/Y Qgz6JRޚ$(ɭ܌&0L$p4jS& 0reFJ󴆟e \2()%;Y8+~ꐱ 1 ww'\Wu}dU"eK>@on8e^&c_"<1R%?i0gTJ^~S7SVw0@_/ɫq'3CЗPۢt|g#@XwnhJo2`&R.$?ġ!B;W>.Dkӳ1 >P|E%zkX-r_O_2=LF|(uč3{.\OJA;pj>?v!C[F30Qg0RALu:jxfP#+zg/("ٷ%#}l}Y\J{rthPXl'ANc Z``PjI R30VeOEnqI,m_!Zԧތx@~"-3FVNj%}S5&+;;gbIyzn8c"C06-׸O͖w٣[ ?s5QԹѦ_)W!ץddlזk蛫endstream endobj 912 0 obj 4966 endobj 916 0 obj <> stream x[ْ󘏸omj_##l Ҍ`'k-v(B*+++ɥ"x xEzOگ._Q>|pB8%: Yr : aQߏtKšN?C⍲Oggݢ;^b1AZmN?a1x{i7CiTi#_wNg(eO~D*O'埡:TB.CG5!s~-^nWfykq/Z/Ng(gB~ۀ\В+_|v%8[uJJvoNP:d"V''ei:3Q6E<5Ha:I GX,d#uHyY0x^ڲtHgU`"=nC>"ujƔd*ʹXm'XPIE.HMie,#ai^I4[MtЋVv%(BP.-EQsĵLli~7L!Ҫ'`N$K7+ TdN`ypzPEԺw`FOÎ}}qqxMfT6NntW7ϪEbdohYo}K:lle`!U3` 5BثS"-cϳ6У`A>|2Lj D_JUsI}%ӏ'S|!1P@Wx4:7faC o{xA='E#'1Ka`/+ %$_&fdhמM^UeàTW '( 8_-YC#:F<UojE0I"_-gF2]w)?kJI۰3gI\712G8~L9je}`S^@0̾lf4 o><ɤ:k~'J0hhʤV|y)qc&SP$8P]js{z񸚝łC!W?>$vƹ=HhW(x{w>=̓:ȋ>>@b\d $(0/:XJ}19~*#!5ցY  !c6Nt$4cDIl .f<2tfJN/=Sf~Ywz2}BkB' WYua;3rn@i;~x7Y|eHL5@ݮJN*ڥ.Ù~ >(=\ k݈fgtkXwCGf`v.Ǐ9>5 GУpFQ1GX%nq}F>S j0WѰl7.?E -"Q]-HOK[dȤqS-ߛ+VTSZ[m:dxRd㜅G*G+Y0˨!p?O"zdcG@r+f3cN) p`ٞm) CESj0)( yߒW݂3{2#ZNuk X߄6N]'a|,<ލ !%>)hQ:'|W4gU4wYQ*K82b襄ZEФΒ0]3@>"EjjK+L'ӧȍ\%'`FǞH#*>_OR}`AE:;JM[9Kv2"/#\ k(6|̷Ha>!ZiBdkJ4x|tPC?iZH6}7h`6X*$,~c{쐩L?D+Om W[_j TE(\b.m$MS+y*`nPmÔ2,Vt| 5qO%4"&M}]ɪm猢o7m2n+P (HE[egjhs;jHm^NqG}$T_!,/9 霜V*w֑?ţέ(ضǑ1*N=!w!^_R47Љ M/hL^^brǷ4>Ѓ$ǝgor RYMsoM)zD]6f/g貎dһWd imڿ0& {TbArKghɞ oŒT mRI#E)+RaV 0 :Vj\YC(jtc2BeܐN,4(Wn‚kV3$3o _!5i}Rc,8ok!_k#@y>RT}Yv, F>I+GlQډI׷ ؁ rj7vo57S3^9Uvi~a֣ox?q!\k|s|텍aU["n$}֑J#7`E2LYoqc $'=YqtD2qRnovS *1lubֲN<>g*ȗX;;GKnmoAqՂ*jIPcmVJtKnbu6j\ϔFYT(ʯY[@--1 ںJyo/;Rr*R ?q`݆73{h+$A (u0eRa ^b0GT34w' r!ʵaT;$ocUr5j̘eY. ^V+e]`SֳdMot)mMaӊ'Bni?M2nV  t=~,C#<=N6Ր̊mee p m;e3Rl #S3fO[6paLhcѼYPg{κxW=_=Ӑ"j(OLHI9 (A1{DI=+פ EOZ6Ҫ1Jiwp9EٹKnОb/WtNՎ&ۚI*uٌ(.Ek(ӍWm׹{CZS TOL`D{ ղ~!Q솕OYNȴ+ϻtaӖ*V?w&WNł{nJ 7fLL @8tbι0KGvKh l鳕ȳ؃ӁJoSQ+Ej1qS˝䘚-',9kmP:d(Rtw] ˋg~m-;IdF~ū9- AamΤүbդ Qɷ)9nTr_D+`v5ϏMT)`pWfy;8V-/Mm۵Sfu//{_(7I$L>ɤx*Z}Hc.7/wPendstream endobj 917 0 obj 4549 endobj 921 0 obj <> stream x[YB&XN|lSAZGi!f]I.Wyjt1ɍ߇|7_~,s j3GgP¤ͳmno5[>Vէ>m IixßN;1ywWF^NEw{} i2o@J}Fr2xaALFh綏 ϻm!i+XIư} 貉$ME?9{+Ǵwm?HuPe ^N8cBNJO6N@I -'g$ɶʄĬ &}QgJ++vOcueN (,S)o꤯wz2tR-ԤM`!4}-Cm܍Re GgZIC)69\ٚ zQ.i ݗ{h^\Cv冄_wAMRR oNmp:Lƻ@SO2^p ᘓJ M&䔔u`TnZ{!wx1彆{u6MilE@{)KYZ’5 ݧtQ;-nY!i'XvئPXY\Ȟ%:mϱB%볗!~o.JHa={ν/7xv绍<9WϽ7:z 顪ʤU绠 {$ir{=;Tt0hbJw`QF/ʔ֭AR 놱Xf늷vtt[݈<ㅒK8nb*/&xdy45)[@>~VB pqU`d . r'ύ;LT ^0h+ZU+~NvͰPEDM f_no`V#fF ҭ'}sC@ͧl@A#@r6\ b._vq$22;g!)ɯB#A42ތwV|Op6 2GBWƂqƂػI=܍,|˟wf؊7#7d.{cy)$oy [L1,v# |U!//`^Ĵ~x_We!@EZpeM/jЫf=~kf=AV0_hV3eL֗ a;e'a%LM7\ I7݊C!_zjT;LpEnrU*mDр@{;0ʭ%ca#Ez=wnЄɃܒe=5 cvNJ3bٛxl!1wؓ1Ww xEˬbv'8N v9㘈V ==z LoEz'DF)tmimH9N0)KՁіI(gԅ!P N7He ?9/^M款oP ruMw ܯ ;5!:^T)|k` LF*"(}f?tLGp-/t2RVkbA&l5>!703ho_gO\iځ2:Hz0@yN(%$-C9' ;ȥlYI'-AH_{@0Wd6{/rf3IoMhx%L "/PetëQd$6Eb ' ](}ꑘMfx7а4(C,![%9"(Us&N|qu6A挡 }qsKzH]iLB5|F|,U7TR<}o-d):?,XyrUր}v."!cϙjfTh%d%!o%d_-pa2gkioI2N&}̃V`ko_vs4|#W3=EBX9B(΢`+8E!#2RLs ^ת׍@mJU 7:yJtYmN1m[Iƥ—e2&[h.]U8axCW}qEPĵD"(~|Gek)IIގ DlDӝ' P7w ٜ42ϩ3>ґU֔9˥S8]pnQկGlɯkONh" Q`Wɞ7 h۱ɍI6qJ 37! KM> MS㼐njTŷ[VpQ$.n`y/Nqf%67~b{;•=5K}/UtPF9EY{;ʋaOU|^s$] h&wz(J1(~`2}` {:>g,WiRvӈ&LLe*^mǀ)16Ͳ,pNq ?[K::0BQ@Ҥbe):S uDTwNa ׸n$e񆋼rpӡVhgոRwQ*uCڍ]B:5z^e;o)ۯHDvᡣOK!4jrհRt2k|Q=2KGFǩF;!LbWu5Qa֯RJu`hj=l]wGGҴ]>sǷMw9ϽC^'6**#ᆡ*"(Hi 8t*xsl) MϠE^*x<,$?Ե1GQ4Q* ]<[7{l Z>ALQ =`koElgY ~Z- k6Oh*L)1)MgW]Rp<jv;jc6JJ2,1%Z [%X'r{<=ջT k%&.ӠkYCfS֬n:r1_؃AM)`ԋÜ2ŘUM{ygIyE 9sLÎm).{{-x!J1,PC,Dr߇%ydt"sO5-Rm"3ܖ>ERvXxYձ?wL73X2g_% oNfXwL_Z8z`;Bݮ`v@( =W|Aoݫ}BD&=0*VCƹ:l_b49QDww0=OPMvض{P ˰XfG .Z8@٣L [Ǹ {QB˽i0gTWݬ SE.COFyzA4Hao8ls Yi^+ !@4Rs5IA2Hky# >TTPoV|ͨsm^R E=5]YkR)(RoX.р5-%[0YP{V6~ gsy󋊯M u; . ][ZbHZt8P9MԤc3ZZ>qßuRQk؏T겺s~KS/g#'%6qIWlT]CwŬ㶉N~}$Nendstream endobj 922 0 obj 3861 endobj 926 0 obj <> stream x[[oqs5>Ķ[VuQR,E|!.ג+.əoԛF9{wZ7ŕ,#ta3|ot  _[!DaV;1xY7hGLV˝ģ1znuw{샫6e >Rj65*!BUdRF8ITݾ忏 sH͡ rtZo]vD}R0:HEQq3yo{/TF&~3Dbs@rђ 3&+;ؠ\&ء9-|4;G Zbhhm ~Rн}Q6b#-{:*Dq"&U]:Ir4W|Ok,q` GE}m7\ᘩs[Nw;'C>vPva zB/;%(t[ ٮ_"yRSRh5K}GcAJ7ڐ|Vlf>{[?dsFr!z7d" Mɽu T&[UEH+2rRR1E)u`g @zRM9x{%B%[ͺ>EfS9UԱ@b2DC`-vA4 <><8#4'Fo&4D\Bun O.%vs0ۇ]M\bB \B4G>B{FO""0}pp~:F {ypWT1HK}5hȧGIy]jLvXܾ@'c\MZ`'a-òE:ضvJp~yÁFen8|tLIE栝zŖqk]Y 'eFul(U{JG#1Ҍq:ţ+*B!znfd+=U}X)N#&.62V 8UcQPhR*I84\Kە:;mӭ/t9>HPGg& D" y}P;:fIizRK r#'ի< Ѵ)x3RfR %XwhR>" ܡ: % O3RV ݋?ZlO=E!k*p',kJDVVn(onPjοPp#C WO6hoDDj?ַm?hc>ie1&#uZ#E:sէ7#w Խ<20^؉(3@3oʦ]M”ǰq=Rt]-+g6I)2ϣR!WK@THqyL/[;G vÿª{EϰgKۄ]G))!]8Y+ɐ2.)U$OylydKS"vHNy4K˱1Ҁ_;Ax/;3! J ,sK?S"SZW,,MpJ 񄓉MGhJJRӅ[D|/Mz?Tf/gUzʡVT Ŏv )ob@u" m@$O׿Zb~/QM.װWv/Kìs_2]H&-OF#p 1Iǻ(?7l>+"d S~.:2h~Kڒ<9ϮNY ޼+x$Z.S>Ynmjtv&fԫUkG.cne$SCtΫȸuIl&DT'2,TcrĢe6V̭ڈJh^l4KTa,Ldf&RNK 1MI|LZ[Iab4xbZA>WH~Oc6?hwqV]1 ='mLe]}zZ\=oz(ag=mmka}zZރtMh:ɬ$6$G۩NI&Vi'Im4 \g|Cag0Gɳgc+9#.?SImk>=Ow{+cYmmbekUs{:xYo5C u|.v/rDTS1ԶwLočpѧetӡSSl^azqW]*%ytVVog .){lU엣ZX؈\hiC,>Vd .$9}R`#\ սr2ۗfJ]XֹLyz*,;[/W ZkU ߧYݿZJ&R3TNŷGﯓaJeY^+ޖ薞nLl\cY-11^BOsܔ}qRendstream endobj 927 0 obj 3698 endobj 931 0 obj <> stream xMNC1 pCnI+(*R`{AkMw~KEendstream endobj 932 0 obj 209 endobj 936 0 obj <> stream x[ɒO#@ؗ̐^蹉>3")sK,DjI/_&RSIO~N_?ߞӿ.^=Q>}s{OϟS"Omt'Ϥpކ/gZh9<=J*nJ$l:pw9uxw<3xP4R4!hR "Ġ DR)wr2c2)lT Sd!&?*JgJ~a7&V*,Q٣״0lԇ7e.aq1WYad o\`a-?RI 7(e`u3&NePZiX:^[a0ɚeHYcU+%owR>KKъU 3‚`L􀏥 o% ɱF`@;Z4-Ɖeo+RoVR?g%{F#mލ)B5 ~ {߅$Nlw 6cv X4VnDǛew$lY_f.)tGr9o6zZl>٭@_b6*$[7iwAG |)U_QY4Rgl>u_', A chx24h^躿uѧgi{2? 3. چ6O8ĤBc_IG5Eh"p-S&\[}쿳JCUz v*0ݑBsxٍ1GE(3EV(W@K+ՀNXo:} cxA"VF!<̙w?J~`H} t|)!9Z/]OG45hgEosF:-yMbO/x g1ƕ*3kOYsV5fKu #Q}KTo `AOzB+5wQ9?5dxrϖ{ Y1^x(~-)=Qqѿ==9b0'3@{Ssg!wBg1 &.Fi?E9MzT` @ven:N;/uT2f ,᱑C}99HiDI ^s3O[&ERM||Yi7"?6UHoB_F7FI;ɬѿ2űȤ~P4kJLns\]Qɰf!]˯Tg [.8,#S$igޞo"'P{C>ZuBQBji4`U9<H-{4{Aa-:Zec`^\T/ТVXh ͊t5K-ɥ,3/7Ltde旮FΠD^J4Cf~нHvhaՓCSUUcZJc@ltNvzW[5Ch@Rz䑦-u;!ԥ ,&⾐Zx:PNJ)Ycw{AD-c#CviS%ȔMlA&1M6 @P,9kñ*`vOWGhpޚU=] T0_p]z7@p, ӟmqP|H2~_+#/wz2xA`m~g=rJ3ps?n)+rI2.b b]:]YZ,E2,(bovNT42vF,2)] *ufy/3Tѯ=xv5466X%*xen9rn~Ml *;g̍6n\=IiMY: Q~nuUw]Uy3Y{)c@yRoj."I.CYg$7x:cefߜolvlQ=P˩ÓwYcvIDΐ6+aJG/L)鮜lCĤPyt M*6{OԊB|u:-@NDj%{ivwR24o{sPI철)Dj;Tmed4QX^r-(9KG9.ؚ-雐>L4 X?+$,-ɓLdN>w *:F CH_ &cBNX8B v(h(ՎS敺t}rMhgٷqפQ0fSwt\;*uy4k˝9hLvpE~[2t\hޢM' ,=T^Ǎd:mvQ7Ě8(i;tz?E8Z k<ӹԙ[⸚Mªȳekt}Cˑt#΍~|#rö^ZaU#+^KKiW/~U =A#n{w"s='f|^DFƳ zw5Y)<  u~ZO@^24rzB[te-cʎ%W);{-!c95iթTpmڋX!:oz><;e #67P}sfDn'lٺW꾈,LzDH bfe17 jLZJ1`UN/icKO-v*kOn> stream xYYo7~>.{I@ݦh h$(lI>K#v\9}sqU7muيU?ч͈~utWX͵&#֯o[j+e bfFcCcn{M㢅&3cvVdLI+2)t}GjPЋ2NT}צenj aFz1DRu}Y`NƩXeM¯紭^ 8|#r_:Sx5DJ $2FԸ_LFG78i$1c%TJw@Ӄjq;Rwы)fLVM0g~ĤNwc0R:t@aEWCT=K"BS Kƭ|9A)$̵@AD7ϩ"֦[ξy%gfnW-cQL!pAj!vbȅ̝u )Av%3 E A r ZˇL1;P#{CU,եXnC'aFK)qfRvY @|)Re''tI(p07M5 -8[~G:<= s0wYx:sKE~zhzH4B <Qb{d( e0u-ler1LB&7[?E XD>ЛC~(Ta]`2^ |Yߴu 9l30{0-y~;U_!%j:DVO$Sk&P//wHlEn,Yth7wDcy>W9KgK n}=9 ]x9bHqןBQ<6j{T#D짉9e5\m}i)i /v2CB\^>TGI}+/bgm]<-*-k ew? [ Gk0DZ3b !:WcZ ht/x6, !aW{#[!~L,UhUvTε"U+, % ":EmlKݰiRnP#6P=G I,,Vۏ{8aDz$mB GPAR"ͩ3oqC A8Yº"Ď[q:FODz_ږ(=|m8G'VN3H$]m[w0ȎXhXy3DCwS`kY%SLN;~>E#E)ڒEU0&^]d~ O]Y%FLS%2:FHGC$X7 'QœF*b/lcqHs"-%>J=Wt"'+:i/\v`yr‚7|kl!Hyl>v{q)zw,%tqML鵮#9GG692 e)S\$=~b!O^ N^.uqc{NnTX3-SHQVfu^'~ FYoLendstream endobj 942 0 obj 1902 endobj 946 0 obj <> stream xY_o6УlLHlkWeh±H⤶S,(ꎤαc@~s~>'9I]\5˱a:Y]R&wguf ާ|)\Tڡ"eÜUR(aVEIU,rCH/a4f QH즂<](?02r(tŤr<ҲsVѱsh_τH2QZ>́*M4kh}ڍ9D*VU:ΕbF@mk{ ;GO!2%LtYz,`J+.6pr۟m sVNƣ#-╧QG{fsTKug ӑ–68yDT\:YspCE<4NXS+e2#[]> ̾v8oVxF)aHM!^"vqXd9MF'݈Zh~uDu8#a$8-Q65/@l}^sdL*|KF3/vb\]x2`*L[+Qͺ_+#o=%wJ(t~W>x(]-Z“8.|͆Q_IzBpIA"y0d=;*ZD5hL~r K-IWA1yz#Y!!fʣׇx n/w,jF!`˟?= 0@aFhs > t$aC١a&=eۅ&ZzROa UuV][F~Q1DEQ/}qdJ,7-=Tq؋#uZF$\d`I#{mo He82U2-N?yWB"ŲD!6RCAj% k2 y(]E^S~BVhH YDikI5%DPB߫J+dPIF-NFm*&+0 Ԑ+Լ5q&b.|endstream endobj 947 0 obj 1436 endobj 951 0 obj <> stream xYYO1~ϯGo5>ֻk%C-*UmH8@!c6NmV<03o WL|~$8{|:xQ/> stream xXmo6_R01")J$ۊ}Z`]`(!p'1j'_ߗ;gsx&ENӳ:^6K>>hON~R&Ue2nDr%!%azd9z,DBiiDOIVd,+QΫETpa}F,yz,)ae22irNW6RdMJmNeI`nAvɅR*d& ;udr7,$w|iU {&~gu&zoŒR+X`yM&(07^{o>a`~2ҿ7+H!- ; -a2b&r#͜r!^$,bsw}5`k OR@A+]?UˉUaZka݁E Cԏ}c.;9:Rpo^羋T~Ә/"7@"Ϡ۸x,)I49 0EHv4J+.w3$䷐8qc͜zZs.C2M([jxl4'}rFA4zl] ,B   ݝޝ6"]|dhlqBsYHF؇v *>>`칠P]=va;\]b3兩H{>Ґ&Xv`[нoa-Whh|v}~Zв<7jov?ߠmsAiah Se1ica=IvFri$ğ^~C >E\ 9{'i >Cz}sE哏Ї1X>O>4g)#`XncK< w상X/:eUp?Nٍӳm;_> stream x]o6ݿrP$ {akuaH"a$vZY#O8u<>Nfՠ>x#kW \ +VPɀ˒E&L`?4grPWL2=b B|BxbߌRɄrCUF+Er1J˸E2Qʙ(*Y%Q2eCy2\-6UkƵbdQ$ l\ !ڒL SQ*tC#2e~'(Ϫ<93R0QfK 4KC5S2y̓ntG_uBr,U׃HzaGvaWFUYQB&c< [Fupc#lV9+2  =5)ܜ%fPḈ}G2R3-w;uFK O]s lDT?CsĞU>! %n 9!uj]/zѶPpH=Q{Rz^w~`|5@yټ"6oVxBK=` .'6р B0K׵NEz@7?yAܳw!ѣud]^IcI-yRͅ#&N-xGG+6(&q=;3`ﭟ s'r 휐CU1 D ͠Sb]x|Dw1p]@Y4bGd}f`ty.PUӡZ E?6˕ɭJ`hl!0Y! ͤQ kD|'p{G&& pO_Wf8Ĺ@!Ѻ#ΆRˢ Aj7_èۀ[*޼ " jP)pΟlؓ"?d(~PxN\ vO®@ fG{vMϧIiqDفD ;2ea3 ,~lX>nHT 0 nM>Id8Q^SB d"R>i8bb`XimG^xDnky,rTPr ]Ç`RI(:m@ Ft׎i?ّrj׼=!-X8!仸w9#d 7|B.B2 *,o6mi#Ȫ1gҹ k[4`8f)ǰuZV #9 q|2 _ONԶ1^d իxWm]* k"JiT%+a{5BB4/SJ6m܄ TDܡ7 w{IȌ;_:qܪ'B3kYtM{B Ie=(.E*j׾UQj,l=]A≪9vi\g< 7H8'vPmQAY xtq.PqΚq\2wke@z'Xoq.r3Яxvߨ:q*uzx:ŮSQ1eZocrM]P=yvI>ZaA'=&?yRiWů󸲶9}Gހlbuv: WX`}~7jrendstream endobj 962 0 obj 1849 endobj 966 0 obj <> stream xZoG_3-{_{K!BJ, PeِDĉI ݻٝ!Nsgi9LO{:<|U:084Izxl6h=DU"? d>BZ ef7ŹUgQ憺HQf*WE^4-QL<ͣSXIC̲4:Q,RiEP%S]T$YZjxQRd Һʚ=)s$6e6fj?Vej2E!AGy7T U# NQf0R8ZGg!͍.av%p|.EQ/@e D~EJPv*xOj$NeEӾ- >-؀XaIcJg 2Z!. v y߇Γ FR [R67Cz!aH:cVgL[C"+DjR;X4/B\ZP׮lm.,f2pB:AH>vhu5kw*IwשM,[lc,ߐhoiw͉:P;#4xj;+]9,/|7ڰ?BFx4t>lōBIM ]K"-RBTmMaPGOl]|Ԗ~YUAR9{:W_c޳Gؕh  hw͗Awyڃ҆Zm#F`K; {q{۸-Ty+ en 9ژ%>o9 ^?39eUwp&O -:vZ"NaFKLVۄa4HDH:7;#4r#TEZb&Cp*Xt#( 8Vkv7t$)e֓*zmBQl &zje?A.G5 4eCLߢHs:NXQLs4:EQښtw/ЬBhZ0j G"k;R) uCcx:pXwEf$%79fem4Eۉ X'.^ѴڎƾV?V<`~*u \S?@~ܥi7w_?=endstream endobj 967 0 obj 1645 endobj 971 0 obj <> stream xZ[o7?bgPDZR5V*@(l D$H6s<3gֻZFH{Ɨsw8l瑭fAZ^l{W8@@7`T59}k5*|r<{\yUmCy/kҧI|}i% *3@C}ԴPԇi㥯WMQ/.O:15gE?7DCM8+Xa)-H TLntzCG2VCXMN[71M$,9"y_eJ7GܮlG-=c)pNMN2vC]ǨMMI6wQ/ڪM+>q{ɩTO OW% Ix[Ҳc~ظ% eCZM'PܔYR\?V']z/g˭>ބz=h@o >,LF%en:h)<ޏJ*w)-|=G`{ K~}ps}ِ F)If;@U^IhJ g{w s@F0)HL t>14{bNsn,كC< /těӧZ儖Q - RS81G _^Ohp"ږrX\a7ayɨY44sKiZ0R "Bb*nhĺmP Z}UH ˨T֓fŐuZzAS+c6Q{yPTaJB9K[M.^nƠwqr㫩\P;0zvGQi` B t{`}xf }Ww @L  ֿ6@},8ڜ$tt5$Fw5ڣ7QQ4)X4]Dgń`xҭ`!B:Dy|pݥzHJnvvV/f;?Wbwm{bvwzGJ0c B D^@95̚kE~wi'6*D_FiE1&Ha˧@X_=RR ܉X/#ed(%m rep|^:+> Rڥ{C+-2D ͍J*Di*ȪĤX\xMΤ*R73 n6&2P ~V3 y%3A ( q?H)t&su:)l Se P+֜#ZcDh;$vLc._=Qx*E(-vu>p~Ҹ$r.-cNdjnHܬtȭ {(.Zrw&KtGncrtq "0EC`Α򒀬L kzN0JPeendstream endobj 972 0 obj 1939 endobj 976 0 obj <> stream x[r&qs]uGx?QUd;U$ + 2E_ӘИ)T%ݧO7b{Ag/v~ow^/WwwrEoqN9?9}+ǠcF'/v pcšƃQV pt֍ZQ&H q=\z8Q)m& QhFU*OE?-OJ;|sH9Fk}~?*[qF:Fod҅P6@6 qht/HIHF+Mϣf!\=˃Z fV8͏B MWP7 'LP_`0\"X i7&RH=\/0c??`(WHbKPoe:j@H7ycx ,,!Z³l /DQ(hu4S(Hd^dv(jغvݽۿ{s޿rw>%{>%jhZtrXG[悕_I|U XoZ/\LM1|/M9v7VW>-<ىqxBGg&!&VI@0[]V+qFYͿ*3)62]1x;Տ&۵&M6}IQ ?BI򟋫֩Z괂,1+m4)dp T g )`43{j\6`E1paZˍLD&aFYd#a ڀ!iMS1H<7<%CgG+"N35n#X?Bb%qkdkcN1s";![t3唌ٽ6+R YxK8X2'CgM:RF]HGt$L Р{W!FܦʏD4TΌ!cJSYc19SLmC&4ʈkjB7-(-VH,/3nMVЗF^TlOK-O1dǺzu ivBdYo!H#Szt&M|`  Gr}\G6;J֌VG+hZZ$U_ Y+ &5%O,-J,dӶo2eBV&/(nc.C% 2##/>>΄#nCV|#LU:4b= yFZsslhƳEG3 @#t!%-B; S1Ѳвt&eRD㛃FShX0WD:UdθhB>F %#5 )X"Mƍs8d6^} Z}FQ7fX:T5t81]LYL7}o eQ;Y+(J="2 W-΄+ @_![M_:@ug,xV&6&Xp='B`L-8M:P̎ɟTPaJy_+F<^Mi7 s .iԻ%C 0dþ*TD 2DW.KMi!6 tI}KΆVֻUEWVTH<y]'b+RZz\Y(\-O7فO3j&PSb^#bt[U D֪(6[( &a pH6,t!FN]U'Me!9~=-C~T'e쌞#m^EHP ji1 buT!}]Ň-tIԻA,V;G! z 0Yj-P1{Rbx\ V4OU (CڥQ$lTV= q3wrO&M:5O*w:2GuT6fd_aY͚+sQPEu@%lW-EP;Td?;PƊʨj\9ÍMfBZ/RJE&gg#ԙT2 QȞ"V'ZFb ݼHɩ'UW8| VYǐ[sVC1xgϹ8HmuvuruEluM@NeqU֎%Q \ZaKV L[y*ZRgI7b>Z7٦y{=ԇVafT ~]& hZIf:Jj_Zᝉn3 Q2_U1͆)EVTL=w2kq09噖kZ|13 ݬfu2tڅ~SBĐ#lؙ(Ѥ!QD^WhS'*/ejN$Sf[ź^tiThc t@N]E&zкUnBMլI0[E&l2oh"ހى/뙷YO )ٞ)C|WT VfWE,GCM>R~]YXɮNGDa0:Y|(ð'|ckuvFRT\;!PZW7wJOw)8bq1E 2-*>= /ՠzJ[ĭ 1yg|xv["[2v O J4fWg?%TBau8Gmb!Amp[U|ZUTrf%@Ww JnKЏDWuXKk˙l))- }!)n/kKk&[3' $TAi*+ gMo&nsnUaN}ngwE/WmO(i ii!!^S :Q`0ՈiҼ4MKW=::Mz.ۦiѹb7zS7-2@X5W^սDGKtBĦ7lқq3SD) VJT`L\ˏ]VlXDUubB" hfMW~&c8:oϜ8˨nM&{E>܈g?QnW|Acc:Rbcendstream endobj 977 0 obj 3693 endobj 981 0 obj <> stream x\َ q |[ܗGKqNd idYƎ).b7{f4 XdTթ"[?$w8=ysO'(OvqN9;D罟jgC~yq^v QX2ĨfӿxgxQOJ+ߝbFY~8IHi|x8I( _et*,W&ڟdvn$ ,5(U$>*1d%1zbAIk< Wj=?=8Ǩ7 3Ia/œy,^q2v:a(iL0FcңaxA)6CQ`A*n?O>($\@ Td4ҕj(f#=%oohO{6r`mn'Wž>Oo5Y^*qSoi63 ٣YF6O6Oypv%5)̮?WO=hɈζFWX@y:XgQeׁ˳7.˒%f><]AcSHJGTaw"/hmfˑC f]ǪI[WEm,dC v UR)0 ifC0В듟v$ݑ. KM"P{ޞ_<>)Rd &;33/Q> "G܁FBeS#X [[>+|U\,pva~o/#ިӴS**ٔ ŭRm!7U+I DXcA)CETS4)V/kcãU3czDzGA8JrB`a'&m Zt5Q]5eg^F=%ء/ GEUn`tӀrWCQ>_"hsRN% $k%a7 l(Lِh--*L\Z;ifӾPA\`+Bl:RR‹BvF,D99_16 d.3ByEPP7ȗSA|hӣÌ^^^⋖ImGݒ؁ K߲p`aj- Z!\_ڸnha BKzL7 z4kV8ul ~#f \1%6D\RtU(q@QAmxujctrϙMpv| }eX'.QM~W)qHZ]sC)jt[QTKp_ŀK }S}nO݇ T0֏Q%$]Cmϐnu$zP&hZ ڠ}7fw\ g)?3#P9#.`QD}[L7L?]7^}A ;F'\)8etis}*4eϱqr\w8lkTYm5ꨛhIx_u#Z[_/J{a`:'D7cendstream endobj 982 0 obj 4108 endobj 986 0 obj <> stream x\[sq3Rpr Vs %; )&TiST%q]lg iSc@CEf|цYn#/n3AcVMl_K%.6Yeg{LWIAC,''M+fyEx)jX-:dmGwp.2*LF(C^@Ӡa'vvm.4$3vMEo7_a$%Ҋg#aNRZg_?a Ȼ~g}˳O>ȳOg?;|i.VeFw hFtyo.zO+|ϗIuY{GI4jqJJfMͳqomԘ}59ZnÝҔ /5F(=moɵa* J X!?@WQf{M9ki俜[T Z'8nW;ǫ4/- ljM)x}w5WwzcF#$]u6eJ<аq. {Ib?9[$h^uCmnA^/>hdՇgX+w?qB)DMC'Y)| uM)lYHBB-.( l;={0a{ "=[rl-Fz޻^2ZA#,]lLUӦ'7[]d7@5׳e7+hW4htC-#N75b"mWZ8Ñ mЧ 6aC]0{hTѹh a]Uk&իuHL4]gB|~qzV@5<&NәkTsnɦ;Z֒ "܏~SW6=%hI=@Lrf¦DWYH߸b2hۅ5J >xO%Z^TY װD3:HsD -bsN[(,x.DqIJ;=s4񿐄BJx|x`}88e"Ó/{(/SNU~s }Fg {+´7{ 㝧_!|}A0]Q~\G8:YIaR,vXc2 vx1'b_,^5[ X#~SYrL4x%\x FE% zo66?wk h0& M4^r7-+{ $<\,;z/AͰ۳W̷A?)X$#E }3>ՐN)үLT;&\cKɃ=GH-}<#uU \ +N6Lą2)T .h&FӴfhM{[NNm-1HR)&;jM*w63<" ޤcEnɠy6a=/R[ t8gZ``fC)DIBU\Yb>T".NqTO1ik1fhkrE]1۔k3Z$8-ĝZŰTw,4kWc-1E!VT/GXW4 xRUM769p͓}aqmJ*f _/^mӋ!$4ypV1:Y4^uy2̪pw@23W3Xy.jTߨMͣ5/j̵\ŌQp6s +t`bg$x& ^]~#YW;iXjRFУ!^jdT2|@3Hb%>>~୩nm8^p( D5eVO[z>0AO;BS=e7WO4> 5KPd,\V)Brѻx)e[<=B,SP̼Kt$c::a{1$<$y7PKE\-\ `QftnQLșHsLbքp V<`,CXmKp店*'iTQq1gX}'ZC|*;5T 5!lВ6ɥ|sVg#JORE6C o Y~qzz=4)|=ٷi+U5[,i 64 J--%Rf؛~FS:{I<iKme DVGU6T8QU:vd}<rKe˯鼎;vz-lF!CvVxҲ\Sk[n;`״mmWD$Ó0t Jw Wv%Vvt٢Gj?3t]8ݶ|  ' OwEsv =DwXG:}dC=5>Is,q 9?A2Xjv9kxL ,<&Xc҃{;~eX]^7Mj7P~y݀^t}@X}Kq'bC~ ~);=zNeӡ~KI~Z#5]"ҫLL;GTQrK =Ȅ9+~E{9oagV2> stream x\[V~<Τ2]z 8`S$</)_:V{gUӒ;7/6 6#|WnE|NOO.^\1{BnzsBx?HۭhG!O*.0n Q;qpZ0 n/i ׻Fa& >FZDM<Wrr=*k%[)tC0' v{N k@y_8zH/`b8MnF U۫%[ghT:R0G'xQ'֩ Sl'` |+mwj+=jj'08 xEIR&X[^,m$ZP~Oۥi4i.v31HaX 3\iB(8C\fk>V~=IR9M/38C¯$ (jr\KxTa! rP40,T,t*%:˴".0}P QLTJul3R8$5Z2,Z)a.C^;P|IE{26Pp2yTMw:1qI078/"#SIZೈ;;pvU|< rdr ni½(yׇSz@2?@}^+ǀ0Б!OFpeI9Ii-0ʅ =Hn!@""T€ÄN|jD x;WəN!T:Q$ٺi2@[ z`~DSBTnr`X)ZxMhO//xQ)oo<;>߼~Nj;lŝ?q\|zo9Fk 9]F 2"r+ۍ e7|跓nyEFFI,+&ތ~'s tc}m9T镧Ҧ:hy?o_{Zɥ|U 'vW{g6Fb &#+ (iK4>XAHZ [Ӎ> )nIKtZVYRU"*&3!.3A<^"HLTeKuRШwF@@B3~K,,%?;sEGRF-$ǓA4 JXγ:R83 EVk:R ubYJ[ofw:q/rRjI$^ڃED%@2ı2st0}'tZbA.@.I{RQkm{/&8cn 樮[7!+f5%vo*Zeʢvu]2)!lOd* ]~!kY7dlVk!B_;B GkLJ9\QF4p5\ti5M0>1D~zw+E#gRЈ}:y/C*5&7xOÍuUk4кg6YJʃeuym搹*1%#PE|CDBRi|OVvʁ l*S.* Qs@/oJH>?NR4M̮HC2#c9@Db9eN@Hؼ;mi™xOCa>'v%Zdž<Eɟ#jaMF M8ixcNř麊I;_ t!s( `+dyvL,#: b#Or2$ c7=̠~_rF oQ\)A tJ~<=>S+Ae^AԔIq_&s/u[sҜ53grZZ'9kJJEm/_AM-vɸ=]bL7b XP Ht1'б#*0 T Tq;#>m]VGQRHGigگc_` |r,מQ~k<-'k<; gpm1\mll08{5+ cNi1^bpbS4iŠc]FSy#Y7v M~nn3N_R+ xŮj9Q# 2T.7'=/g&ܟM-aTηd|=:C+5sAM-(+mGv<'agl;Rȡ9/;ֿDlTdCfz65|? P2oFb3Sdu1-6PTgG[Yv|jΡ g 6ľͱYl"Jd`;h|>[#$yCةɆ-dm YDS)XŰ&䑱|A'bsfrF6]ZPX4(18w[řjD [fÅwT2;.-=D#Q_B/7ŽW0f3U=Ok5 @2N<(vPJnTn(M<+ MzrMˬJemb}Z%knKPZ… wSS78f Ӵw?eXFů׫`v^C}٧oc<`;mm?Uz-U+yeZ_86iS[=ײTMk>Rq=_hAI2JIX4^֕͋,7R!r5y -O5П6GyC>obe"ɢhk4֦+#\UyR ۵) 8ïBX]:45F݌W!Nt8Of9|W®JGXo(+ng\Y?zGBP F& d&4.>m s\pC&0CDgXσ3%Guo7;4Q'KI9M"*.d9FxEa?F?c$!074\t3i#ԨaI֢1u~mۇE(hP$.gL(JAܲq4SpX <T7.z>cje$v'E2+Xn~8$(A<0$z-赏z;v@\4=vkhr^+"? )R- Ei%@p$2rhendstream endobj 992 0 obj 3783 endobj 996 0 obj <> stream xZmo q8vk5n,;IK'YҡK{s1|H>B5?WWw9eioL6$Y~~S"0s5{ߪ‰Øi\`ӭ/߾yems%lִZk_xӪ=+Ii_ 0Fh%r i|v8JO?- * 1 &.OE16t)!nBzJY0"Ie}{'`+&MрNʴ`삣 &TUTIfz|]`Rθ1EqεAI,\W=hmsM.ZÑр:r6@7q:k'\kn3hF ޿͇@Ef ӌ_Y  NT› &!q1FJ2W]K n$zX ~QzL{VԄMkč01PD[ Zxa.EuT @`q|;d2Na0!րS Mc8 MNzJsjL `O, #x$YU@KdNFH1Ĉ^.gogՁJB䅏XJnNg?4jv z~ 8|eyLب/+:Ja4^E$V\`^<ڄH}Gi1 bv#x"\wM J0Ѓ}P9ÓBȐ3'Ð, q!! ,vU#e~&Pp&X䎥(4t }2adat*2^mE`B,,_N۔q!#虄T J?DMi Td2{ k)p2 F=8gh}hʑeU* )Ws/C9|Mz-ԈNpUp~Be&ܛRjaWFZ 2qYx &NKE%h֥FMʠh_yS)밅M?]6z#UQ+%GnJFj:ΩxXDaw_~Ha4@V:vW`q`?Cu`yw?nK ?jjop)c;ept꺄ڣm˰9jL8PBv*Dd0V)bz<xvuU:1Xp5*6. k\k:2KuTݞ\uwo(7]K4de"ixQގqScfB p&D4҇ no|iÄd+nͫC'K츌*N+;"(2/lAO$l ([Jߋb3671uS[,c'4SPwEvN{0+,G$*V▫ 7EXm|e+|ܺer@e~l*ܤYeAqBEs[!)eϘ;\g}^,ytŪ쭹dwDvYE? 3ݖB_vd+m02}YaArקajd#3꧉b 9V r/*.B\(*ޔ2NE7dŃ̗O_ ѳJVYu^Ud!GϳL7)';K*ѿ6";IO!LѯmˮcUX IpJk*uOb| c©`G N}CfqhQp7E";*2BC)RbJ+Rsǎl×_aTa%e`,YoK:ot1yw9;{Z3a<;!zuBquk,*Q%:kE%:9o |.s_j {Oj 1l R974{;/3endstream endobj 997 0 obj 2242 endobj 1001 0 obj <> stream xYYoG(?bgL#D8E]D<俧zc{8E VSV/L}xYԚՏpt\3x\zvPq1hke-0sZlX)bU1:'׳=.> ϶ 4FTRb$W9i;N(B7Gavpkڎ_),Sͩ'+aip2Kh%ThX3p͘-lwZb┳?P s?Rԩfi"Zc"-vBRm Na@5'!c%(8ɺpr?ɵjHMV\0 n^58+R3/qx 1Js=f[*."hR<:]7?`T/pH{78z hи,pG8 9"4e*no[4jNEȍNԸpϔYd&LOT;hi;~Ffmr-2b<ٻbiRP!Y2+[. />.vh ARԘ/|;:, 2LOD<c_H-^ԦC$3_(Fv/u2X1mVg7vbEZ W橂̵&uX:As#߯C>@ZW*B4uW}:5J=q&>E'841-B/Rv{$༥}- g/pYXX6𕽂V!Ħ|DZ#kSҚ('k>ꃅ}<=иJma R||sH*Iql-F{ I?:F#~Om3N)ASS*E WfIjzt<1 0ͱ*Dl>Q*mlZ:C@՗}GwOQNː=!d֖% ºEJw, F)zecȸr&x1/F+Kv>ꀗ(R `eתW`˸1:.D1CL9 6ZDJK1W7>o#ŗ͍[H=@=OJF E6-"GWNO:4a9h'!r?Hauks`蜜B&oq>04z{8Wj1we;֌;8T;W׋jU??{v~o.Y>c_֋aK)Г@| ǘ ~tK,''t{P$%?s vr9,#ϫ8hendstream endobj 1002 0 obj 1738 endobj 1006 0 obj <> stream xZ˒ݶO#fI@㽔+ʫ$,,FsF=9M@BW4tnͥVRW3^>{w1=4^^0?wWeV9PpWO/7*ٜ.}J0R nr< v<aǍnhKx0:7wdve@ 7)Gax<-Bd,e+^n5 P7X`[(ȯZ8̉w|bcvb,S˰8|&U}>+u<9HNAqV*'定jdPXm8nk+"e7Ӱ#cN=Z=Ǯ6v nJIf@ b/ʎRtA8G-K$vɹ\#mp+S52߆xĆקOp,Z6+#yIi&n[A^?Ìs ʁ2#MÏX| $ٍc6)gwULaO!k)-0ߘAC"^pa)!f00R~7I#*4ȈXLjyxCƔ!߹iS ;l; ySG_򯔝wDw?k<xGRE\mbaXSCtfDBgmDî6QtD~D9=8'rsV7?ˈz=7j;>Ű f]l!g^G:v7mU֜B~񦑪OԖepawTeyg! ֫2ù0֦E-V{h_oiHITv|}$McaeV-XOG|[뷭*ժ9-wJ91nLdS`17cT>YІ)p;.9i@[mՍ;5f8)B`/YnU;U.pReM!tn`E=dy'nM!\3+*u?m]hE*:,ÕfoXN*4A7D-0^rd_6hvgwu?>q-^ttw?sd%u{y=5ʥWyCBsn[87Pywj> stream xZnF|5R/؞؎ "]ZQ9${!ZRbM^6Nao?[l"66>l<.y#jv|omg vxsxJw3Zeqǝ>OHvpJvB GeU-YgТ=]DǸ=I{ҷ^kݞ p3Z8ˇ۔;)˥ƴǽZF; WJX,xkq**<*Ƅv;)iezx'q.eT l,-eǵb}S9^9~vjt?$/t.qB:]X:8v8rTwvPM'd9ƛ'rr\K~U)%!~%_L!*PDHM0C }x5\5ZqG~9\lይog6[|ݼy ҹS$=C\2^y.D |S1L?R֫%y#|ffni)I-D4$J2I BZ=8j@)n N{.A;A2Xr>FJ1_߄,ɴzOA$|kl"r}tl2y>!`qؑ|tg.q#8\qt4w4>~,H 7v P{9شf|BPߍُ6ЉV| i Y{BfZ,r<' ש%4pD^I]Ԅ w'0N1B!EDKG5Zu^&&:J"یrhϢTA@P)owV/'e&/SgT%J*L+Rc)s =w!Ҍģù(5蝙= b9dә"5 ;!fID chelWj2v(fUG,[zY)‰n5JlB uDj<0voR3& J;O{u"s<#Jc-)\J;AL?*#NNr‡\{43v=S`,vD!h'%m0+k[8@Qi̡BfZپ1Kyhtv-a*=FA/ODÿ0Lg;{XtmCcsw|!}=r Bc@f= ͮcx33C"ɤ*}șw=Mɞx,uUV"= UL٬i4'Mm{Q-Z0dXKolҸ-+z?mP<@h ?x:27}2|xl32ū5!fLZ#7icve"lH;ojR|7'҇x0]:~_'q/IžьZ}(uN]"6ekAw*.ċ$j^\gpF!@Zc܉t0D0߸/u&p 215dwqfYHsz_IC,vG/W WI 26iIT1Uk;mw`T1eWF?^E*`'+QsRJ O@UUqܔ"IEVcqu\K|~;&xNEGEIhUvxf &Č+31&c 3|;fN=1L#?5LJN44#QbD1I&VaCxz=JyQM4|PsքBs O3$7}Yu㸴mpGl/븈D_'X bqgchw= *`-`9l(`!Sr{*y6fRx)h̀PҏDJkG7(ocIa2 LݔiΊI(:L@ڦƍ5,Q=Js60%/uH{lUmysȢ eĽ GȝǍgϫXĻZuUJЗ~؅Ooc,endstream endobj 1012 0 obj 2598 endobj 1016 0 obj <> stream xZKo7W2\.z)ZA q]E[QKvl H?_rw9CR#i-u:fyS<,4WAC+=W7#/ҭk}B0-8̩Bgv:{i7U4NH^/D)=JU+ 6ǿYUpB))`4x\ ݯqs +0KKRQbѽ=G &,"2֍= i0 F@'Z 9̞v |e%,֢e!GQ-_'!"w 3 +Mcf6Å(,< `9Ii9w^5cdn\->Ik&;k^lh퉪d4ٟ!0!B-QӲ $tҴ.$m-+Fkc@;'Gu`!u /Iu&>"kF{b}|[nKzN!6pfSx7P:;ž"Mx)qJh ho㈘xaޱ_0õ6qSԐLC[FNZLFQv XUXc܆+" G ,pX7w$~fOAƜ UrW?Ư1B> stream xYnF13 dł`)`&-0xIB,4@4:uNU硫3q=}pݏwiݟϛO ;isY.;=xshO>2?O*Nα_èTRnGr%B+_Q0i 0rŅ1u4@_Ѱ;v׃Lx%A3͕EНVy2{vt, >KѓZ-8 "/Ͼy6"{0e4 ]:?}7>,e<%C<F+r)LN䊛˘+O A0M(F5J8?R(n|5FX@˴4+k5LaA59xFjpVsQsZ8^$fmޓ^iI#|R?=-k-ɠ:UYW>T T#`SB:uض34Oj<37ߗ=/& ٣*'HL(g"+tzo=D;S}٥kG(M+TꖫAJͳ#/(U%~CZ&i4̷фt^2a`M(/@P4)z6JiX扩xh>*/t7e%~hӫbX2WJHlH4;3y/`2<0lI2lMKP/ K>JQ2 `Ȗq)3q2i3: tܳ)L`xkԒSNj6!D\ڎ5о2b!yB՝ح Z.6B{3VV? >ͪ5{ޑQ5kʾM!5Y2WVFJ2:m2dUcY]ìR[)Zm#5:4VY5?<,p"eEC$HT^l2e-Ó𢉨86[$wE"(tҢ4bx1\ DqfguxL_szJ0QRC,_Uͫ.j@XuMOdLUy[k[=ˁ䞕 ] @JmVV倶I;r0ٹ@F="k TBrA~zro[kŶ(6K{Lhrnunvx y^|v8Ug_~0 6ִ5U~@#N7tJ$mJ5^;MwhW 3īaAɽ]L+ @r]2k?4ȢaOxK)3[[]:M-h+ ^-R~ ERIwXEs#SG=WI< FZMWyvjV %B#7_IQeB7.S\|{[E. oth.U*(~?&~h?owk{޶E fV9,2s^x8h|*J=QJ+,XrqށYrTH՘@YW {V;zs%u5%Rzٮ{1\f$:eS4&߹Ж"J 's̓_%2jrvT\vEO~T@jZѿVD!w*m#5*/mM!CVѢ}xJrj mLı)6;w.2>?6d"Pxw)vendstream endobj 1022 0 obj 2322 endobj 1026 0 obj <> stream xYn}g~o_D$e[ v P\"ċ,R|Nt6MEB8ЃFu9uzá?˃A/t@Jywx@^tS V.fǔw+)g;5Fgf| Ó֌Xm~nh2nxѣK6r֏+s)|-8^a78ufCƩ0`z` MF$LznkR:]28 ¦ IqtѮ)8c`gt1z:oMQjhs.!jtJnPduy%BlhEh~º1ZKw8ͦ-eب€S1D_mb0%61G̸1yXrBlgu&zڹ>h=[@Q%zp bWbH$?[YC[S_0:'?ذ *a7>< |id(w}JTA1"ZJb1]GaQ33Fm$O FsP뾓 `w`]4!5X9 AE!5i*3mq1F 7\:ZΫ"&@^&rNv}Z c@]3jXs"' Vy!ݠXsUBeљ?!쬬 :p( >yI71=&X w Sv⴨M(k: etsӈN|V)R -5gne֑%tSxJ5 ,:Ou[e<Ð`1}NkKa>A[&%'VLCECfT̸_W;4f<4e;Ej;v] 8 ܜspiޑ8B/|BRFL^TSGG ۢy@-~4f%$h!/WCZ4bmA]dx.Cr=^lu@L^*H߾Yk (#Bjtw[81ČLYT3e#O4ٛDXS.WT1Ϛ7A-\>@dE{_dA=g^<X*uG) Zぱ7}zuZ'zI#iQpG.G-!\wIn1eme9>. t2;pȀlq4|,h䙟QRV#>W1cUeK Yn[S'b0q[nqd-ƹgzioQYg:Y8Xw}3aj&|{}dS曯3eQt#I'7_y7H"Zn=;C"M[u*ɱQ;rS?ri/ٍ,۫6~\V2s[qF#xճKv< ݽ6ЃyYo,ɾ)3?]])iD߅ {/{Hv$>u/[}CG3: ݧY&]; uyƓ3:BL@NKbp+-/gyZXk6{-Rf{hዣo_%uendstream endobj 1027 0 obj 2612 endobj 1031 0 obj <> stream xZY6~[Ŋ+RD/E@SHR4bN|"&E0Cr4q!QxUڿG2zXjiģ70{adۡEd)D!˒E&"5vf:3I6ژ< kceqc%Is&r!L7t,X)S qIʙ(LnUf֮+8W+Q蒷ڤy5:"LfyQl\Fښ]2;B0-T(e*؍&H5j֩w1H/FNv2=fW { 9GecD-A= )W.[@l Ծ_yV" c€#S¥g/C[թZztӤU7py ..׈=>p[ 7Z7=(قJt$"#LߡkGyP`ELmX8NU>vP|©w(3ܘh`xq"ZK7~>Z/зr5ZlW,; dk⫳6J· 2FLʹ%@.0 c1O!w;&05 $=2|qBDO8dAQ"hv|japB(j^ dt <'yhxPO%׌y[V POiW֑5~Gz bU/)ɄrX}o ? lG1LvFY H_Tôxq{ -NԃG|ڥwWVWcb@@M luMs =He>UW.ICwض]-l; e"ř|n:y)X.FbprE؏+M[hl/#/8o| JdSG Ū1촵(c> C ]!w1?`8I9yK* wǝa?Ugs.6]-{o+H/ͳƽ_^U*vR~htN /*T̊T䆆ۧ9~#(1n{J]4(_éapendstream endobj 1032 0 obj 1543 endobj 1036 0 obj <> stream xZYs6~ׯ#1a N8t9z4mFlSApזdvZg`xq~v"O vUl>҄'/bե(U2:p7LZ'L)fu^T٦ka*% ì,J&e3\G? .)-HOO_PJ74s*+BUǡQp-af& u~+<מJ{zU 5~6q&tŔn4RZyр tmR73QJӛdbuap `tʋ\TFϮ5nZʌ122`eY{*9lGEW!e.d{FLtS2hLA֭] Oui0;̛شxj^`C0G;4E8i҂TKg W {CKڳC`%:ja Vl Ѱsӝ6$6O+0H]kڹft~Yr30 %+C_;'f0s|rmNߧ}3}  QXdP;?4Xxǧ -8;].#vNuѢb^dEdg{4E^h'+X+[umQO ً#-\tl ydբ"ag@D2bhi5e˖FrxtLA`sm3RhI䲟h" f u uF >dqSbYHVȡOڀCZmt3֭6,5.6xE.bd SB-@!QTP4u8[ %麶z3b!CYe#Y2 §{ [ H%J,Qc[x0H a/8G z+ϊ cm͌ݠȃy+dQBQЉ˺?4,AѢ h.e ?æ4<w^\kF0LJkq<]r _~:W-@ Վb]_`|>,BcIr}x`\OQET]憤?7eEJ^ Cs10wx\ >] VK$u+~-(z\p黀>'@ftH=#09 z(4zDŒka( >]u%0t# L7"YA{e2iΤO=w|gL@6#\ހ >qü>OPc^&aQߤoaQëp͏ArI;]ٖv!X.Ro>c}~m> $]5v> stream xZo6~_!I"FH^ {Yl+2C؉vVY$GRg[Ê<>;ww>DQVMףZm90GfFGߏ"ET FԌ/KRmLT2cY7Ry\X*KxLҜ16y])I2Rr&X>I(ϋ7IJ +TMfZ ?6 P*E%%5q ʜūEϛȲњRIvJќp$J($'׿:%2%[+Xٓ?n- E)jec+_lkzSrFxmE̴rڴj*hRE"EҌ(TE+㫶UTfh|VM"6xg^}|jf>&d{%VPKGY1%#<獲unK8躆i[$a}j , :0U:B:,;.:z d޷Qaȼ`8q`OY@'۽'WlV4VI&)YD8swi/Ԝh+XF2}Zw&yå.yCvba顱 pT}1ǘ|V(wH k+k+[N`{g-n#V܃`-F]dˬۓMCypzk_ 38RNd&5*MM ƮCPV5i;c3.`kdۺIs@ ths6/TnN(;O HńY۽F!1]L@,<[B8Guf-S=4~34:)俗`36Gr:Ir/R!(o=h<g 4\RYBlYzG`[\Vv݅lٟrlm96ЎW&U;]~7?C Ď1TS/3 ZvE@ #>99p8Q-k/3M&="BCȁw!;KGۮ˾HvlrbWnX mJКd  qW?Oȏ)B/vU9[wYu`]}cY'^[ρkYd魓w vX@9_ r\TE/xrϖp__8zB5{Y {O)/KNW =/=NGAXL}ݡv =Ëyu'8ayH8mi>Lmre7{i<*qjA^5&y-|Lہ`̫v`m.Nhu|-os?8ױݠ(m:Fgf&ml*Ŧ;Ĕ@^.ԚqAmZh4;Y88(xiB@yR AL{7c}L}8m\~~Ͻ~Lendstream endobj 1042 0 obj 1534 endobj 1046 0 obj <> stream xYKo7W,r:^z\i{i t %1jَ%/˝!,D Lp3עO=[L5rR V? SXj5ײMXد5šBC,&++E$]keM'TM^ &QRPj.ɺdTa8Y֒7ȥ4A+'#nvrjk$3dNcVktw+5OlǰqP逛'cb:SA8y-[TV9[E/My W~%ݞ⎶N+wTT7wF{ )>/ G(>Ev5H̀6LW롩,fXM-\O^Ж_ Z-Yh+?X32ֆYf?@;LDj,21N%p'8ZNq"'5V| 0M'o0(hendstream endobj 1047 0 obj 1072 endobj 1051 0 obj <> stream xZo6_!er0({km0ÐZk,?JH h0G$c<{|S$ͨ&3V(z<,Jtw gBixY2U<]\N2vRt=VLeRtZP֜jkYjOLDl-v,Y(L^mMЬBʙE}^hƋt Үš L_ h+rFx+!ycCy@D[`<ͯGCsJi63ܘoSX+o64im؎ ]y⪓ cr-ꬣDw #4"$G4!a.g9C<A`Ը|zg}Lo"Ҍ.`vKt8)F O#ف /^N?M|g=#؅<oO 4)/0 ,U6t.*3ęM1Lhz"}ٍu:ln`Ŭ ZFVp`n=9w@\2&݁>x=鐣>:i| Ǣqq7XE0`a9 )OλH5mh?1@*yeW]NVBݻ+QT[UT?>²Z*U> ]F0:s=pEŕ>"WDjh[Ez! }jȄzG<:ꣂQ:]㓹m87|G_+cO#g\o=}> stream xYKo8WHͷ(Rdw/mm _mQ8v7;n>d28<>Sh,iox{=ÚXU2¨lp~ͩʹTIyVDE[UМR - ҐT % K*8*+ RS89qJ4s6JonΫ!Bs+Y^8#!SsPy7$nR4>_l\ [R'kKb9פj9WuFZo_]QvrGb^Rn;ۢAș)>raɐm*r1,t3];HCX]vܞ'=RPa4L!sފRhū* B8( UR?@"tAoX}8*$bQV7]<W-8wZ&2:`w{.a;HkbE'Ik ʻMeor朼;WG{\CVÍjk|ԐB=-zSK')rذף 쵗@,?a+4Ăz >X<|D9v Cybz퉁[:l7a Q?EpqYy~(e$x䨈ͺׅuEvc z? .7 ܗ4,Mc:$έ+wh; AQendstream endobj 1057 0 obj 1111 endobj 1061 0 obj <> stream xZKs6Wpr"=!L/`rɴvtL&zTGvǯ/@hIvCV v(c<̟w<Ax臡^EDUDóU&RJ&|&IZ2U#J8>O~pNҜ\ՉE]Zd.D)Y " GIʙT$ʹ]/xyύ}ZLd\"^%+YVs^DR]ҘRQ3U*ٚmfY[i&f ط]t€ b\̭!r"O<2kX'^a}o0R?(Y%o1u 5y;iu|IY qc'uX(?'@A{W h_mJb_@'gh=9fb]9Ai[#3M5vo~@K6v7g {.n}p.)_Bv`{|S aρRf Gʳ=j HIgUͪ;O;TIO< )=3<{qC'99GN@<ź@J1;dffd;J;qAVo7&| 0jNie&ygh@+Zo_=6{$U>o qJi?tV Sp[*``ŠeuE&p{L HB7MqWtk .ṇmdw5Зd=)\|$>oFihOn|` 2ͨK{]*&F70'fS'Ċܝ&Lyz.ug<)!5ޮ| SVIأ;r˯Kp9{atq'F}o]e*hRNEK 94| [O(P?٢VEeq#M#/J'Fm)zXfU 0aWn1œQ/m[΅t -I2DJ34!{i> stream xYYS7~_'kFp*q Se`.f˚ x@RsO{E) n-0*6d$u^= ǘM2m ^^:ɀS[7M6iKqdXCĆ]BYϟIL')7,Av5+ g* @.qu)0{}diH"ݷp67HB1H#+K&lvȹ@Dڕ?-p?7|ڞ:էZDY=C*wQIywH"+3'd\Zj{ۯHv;ЋHJ ~\Y& M !^ T!(H~J'T!4Q"!6eݤ$br6]Z%.|-J^밼+m`_5t"0LzzK i;y]Ԁ Iz N;f(%rhwv)=,d>:_s1LO3Ww*|E99i,x/ M`04hR-Y4Xۑ]&0IɌ%}qWuWVm**$uˀZ# G6][W蚞I"w0%fzl& $G-nwP@t_XټF( 穹z.h'-QSƒE*n0OF>F1|ɦ!ud[JrISE^}y|3({e{zf]Y(׵씯ͨjq7Ȋnoc(2^g,EyC=lsakC=x"-u`0!=SPߋ'}/hh"xcs2>ݷK4u_==GeU] *}O_;>^7lgKKQI]W6dXKdq8G> stream xZYo7~ׯҕe܋"E-5 HE,˶jr$ى=83FIa  َʿe>*j[%Dn,]"SYd}w5zC>H5\RbKcgi)UIp Mq YtʄPeq,,1{/Ul*FTE9?z!C!caV S=+ {ƸUr[`P96WOz݋^ʙ`F w "xΙ&dgcndqڽ>uBbt[0` @37ıiǜQw +*7` wSiI9C h:ra@֘GŵNw,PK Bׄ1# [\e?B~,[L2D1/Tx/\/T|%xku9ㅙ#Cu GD;6Xhb 摇O{6g`u[".l u^f"/s+ӯW4~çۃ0͕HL/71L?t }o-o1[@7BTKH:CB^2'k̚.y!˙t5Kye@_RWN1pb8 ?qn Z]K.0-nJ豫wvM\ z'Qq"΃?\@xw`:FaO\{rӟ`.Bf5Dc@$W =""1;0y@K-F]dyّ3Xבn Xl$$5k /#;W+RkҨwY,uTL2wuYk3 5GY y.P/74!_k0F4~,ix'D׆2lH}NکyhFįW^ta]0 ݽЭGt7V{PHC֑\} H$ިOhS mgǁ1ר 0 K7p^͡=sشL,e`[WYrb\s垗YQ>Qam<ٟ: ʴPջo]@^Kqrz/MϘk6[1. ة^{ Uz^>7u/^zs7Zϫǝ"i:}E;[_yox>bhq܃ٽzj9뤑+l߅baP~۵k-V8>S5]h~8{FoA)77'$`5orK. <*~+ `Lh8߳P9FG腹W~ZEjnZ zO߿endstream endobj 1072 0 obj 1961 endobj 1076 0 obj <> stream x[Yyˌj$vEr,˛m=!aYSEYE{weIa"WW_ywl[_-bR,W7 1淗va0+^-D~߈AB⇕XohJGZ qpZ25vPʮ7rPR zYijbzuzF-V_Aڇ-t cNNM`Vb #ju G~Oq&9muY=^]ВlLS{@lBrI =(rޭB:f<\襇VyF`@qÖF3JۜI; k%Ui<,/3cV?}SڮKO065D=U=$>,Oi޻`#rֱƣt* @j±2ii{G߯ENC:'4$]4Ӽ,2wɫ,(QbPY_7'Z]F/+m~^ߗgm\.Of/%(ݔF<Ё ; bzQKgzS|񂵥!pҧ~tYpTֳ-EI@ΒxnWn5n s2GyPpz— ..vaoIJv㪴|lG{Ձ˻vܱ4N{}?ܸWzkRaA6$r;\BɆ^v b3&%ޙN#Ћu0V-уoDvCދo޶)F oi6C['|G"ݨ"KdTŔ9< sy^-OQ7m{RFz/g^OvFFY >C:aPpa2os{P/ <.;2}]zf#n'rRMC/:jQ_hM;TO;Ib]돮\p>1'lRc<~}ɐ6}NWB;uБWbۇ9JᅋI=IAYRf`JxS^`ѱxl\,}>QG<97q9C#kQ}cjj;e@bƇg0f_w{˂/:ݔMgɢ-6fu w1vP@3T+'7JQ=DSXz3: B&iEoKwdu^gl; Dmd8$ڡEmA6>F霐}Vnʦ(Oi{Tǥf:DPN4~[>[wU6O?V7 :\ǽϫIIQLR>2;!wGGl9vefݲD6ޫLmse,^(cW(% 7g3dڌU}Z&ĠUs` e"hJ:MN}XQ큼^!K9Uŝ)rxnr^fcb/$#EyC Ma 63ꝩv$@-wQ{j&'#Edɸ5t+kF2}BYy8s2EsdP~Qf tbgNRA@Zq1Sݶ5l u`Gk=hT}^.S֖n]َhN.!җ[ _JAÑacQӜm]cZLIF;-]]K5;67[8B9 OBT0C;(† w̍opSQr#*ScXi;ui"r~j pF6wSy񎁡{-dN!!IWrK0RuZuʞ(Rob t 5GUMθ93;bM{[V,~c-7,$֖f2 5Wx@!sR8(!bʐx %۟A,HK= B]GQ+~V"aS:Oal[su<G30ut^ESڠ> fs¢?Z "zC:W8 CݩJN(55A?p]bv P l, t. hy <R )r00rZċj†HgaW# CG7X2~$pD0V۠}ozFDymH^}Ij.'>ű 0>? +*H2y]^|,ZNHx:R]߀tG;@-0 M=E 4Db{#Q:¬Ϧ} dW߃Œg~0@"旻oo X?w0Ƽz)'MţNjZ^_.~=z9y///em闵>[X#jF9*ӞҷjZ$N v,<sX]zA|)Ee!e sGש_^RĘVNDᝯ;mPzHRG _H'F RH2ҁ1|c|ku7<pdT,>\endstream endobj 1077 0 obj 3819 endobj 1081 0 obj <> stream x[Yoo;lrv!N\Y(ET>gzxXqoOOuW_]|e2'v&nOՆaixFmnxod [$|yã^+1󸓓B&ɸJy}|2$~x3ŸYs=a-<<5C8t= ˂>ؑpJ?s}5ӲP2lrc?i g$)@.I_G(zau(݉R-M 3I)7?,EOqyظ|8=>cZyʘĝ;u;pW; WgYppT'u$רM9IaKv~1"8Ѱ u;;6^`PC|2.]waW$gPJ zE=JB8ebKLAi;1Ezb;&`9Il@k~U[GEN5'DU#L]Bf2T %;]X="-8\osK%u/l4aMwbh8\AnkAsg Qh2Sy م]DH]t0M-KLPf!cIœZl M_)DOP͛{9Մ K |cEPB)pIuhO N*୕sE_,sѽ=)n7)`!;n`V!Ua(-WXHb%Ǜپy}<ۖo~Gǟmժ *2LIv rWk5ޮKd"g5ssЌh{<*d4dz-nJ0Nь9Q{c(_ܖxcKmڢѨoH7bAe| |+x"Jbw].cDI u@eP"gz3P$8y5|1+`* gc"$̠I9W.w$TvAآuy7Ggi8K`9%5[8U* ąUXHW r AI"mgi)b8!e*h~2 R+QQ}|a`SݨQ_u$S5Z޺1Y(CJI T}@T!Cp4Uf?/'Mʢ}5!W#S0g1x+qUmf ISo@5J܄+/.?Ř oZ-5KX4jqs]4%^b~za+Ɓ#"AJ;p`MN5\auϸBOQQik)v0ɭXb L; cv  1CA9*Zr i8>[r2 `ˉ9V<n4dEbQśӑAjV %ġ)6 u y4Gq |v VXQ _a(auu6E)1 #Lt^G}@Vhx۵y3 iL=DxzxƘ8JpT'\ :% D"rǴoL:+'O=ͣ Zq>u5F_ùIps!ܗ+ٳ2J,Y(}6V} Ie Dhu*\V>?h? zBx|WCV >#:LoN9 8@b%)b. }x/<,B0Ef 3ӑ 8 :;<27X]F[5e8ItMg_*3;Jq|vpmZ"ܻ;\lO-5?ݴP.,R6h݂v*i\-Dm0ZIk| 8t&k"V;HOnl)drv/h$5jr;Wũ]$bsv8Opv#-خE[44vsނAqһTcPŻ5`/34S'^v!MۭbԆR}p;K'bN#ɬc/;f{ \ىc8Hх*x'#[ &VDBZzsn#6 & đϕ0SJT{dp"7z~;%: F\eUv…/"TXes(8#tsE'mU @vSktx+'9vwk-%/CNR**e(: l5oGp\Rh̷|ht$б8|^- N8wFRW klm7}P"ig2uf'mҖ870xBKج?ad7*0EHWi,yRД](5 jT+&͙/*V:Oi2ҵblߞ[/РHȢ9TS_2xHa2{l |O^KЀ^Tߩz{Տcmj}Ķ) HCXɼt˺Z XٙX܋e(ocZǽ?"D=QDn_ 'endstream endobj 1082 0 obj 3969 endobj 1086 0 obj <> stream xZYs-W~} z_ʕqx)J`\ H|{fN!(.`YvيAn=:>6it+__?nl1=ĂqN9=||+c_N6u!DaMggQwC/oUwκAkwjJKݽP`;wZA}AeLc>kq^v/0Si/z2i"ew:xmI  >5Y4AoTTg9໘9Ғp`^\|6z!C"=HFnpYA |҃h^[bWAcR~ZV_oo};)J-TC5;ΈA TL җ+è㴫@]W`@[P=4SjpJR|i`j nV-t28iCS*j\ޯO30N2$g D~gq+T 4|iP٘dn<-,k^d4e5jhFA`WY<%)⠘l6VI"LggGsw*F`CmwX~n[虴iӣfRN`(4?X2q|*FO"rLTPz֧Z2]4Sd%G`H"# t/3_{! ^\T6NhdPd~m )K[W*?g_3-.\ W pppfs`!Bܾn_鯻>?asj_ hZH |kU06b,{҅"xcRV@raX&\2*/0Vq1 cH5X,gCz#ʘ# b?͉J|PoA1K+=eFH2ҦLg̝k|1 -Na[)tC p0y_ Y#4jkvX!=[{vV+}F5uw:L!1Q:6BgD[+谙wUsZe1*hőxKcsZzHۤjߟz` iJKلk/Ld7)<ȝdBS5gD3itJFʭkd "ꮔQ+ XM =a9u=<]RSbxŔZTYDUAQ0Aj" z]AJ Ǜ~ N~{O TA{_M짰'j>|3أLnP"4atKe ʹ*OaKSj4𾗹~05f` u`3Bbra -2  V6$MIN#n:B KL'$=x%`c&g1?Zca fta ,}aM%*#\aJXagT@s0{p(E w+6ԣGwTuDاhH}2yA)yJ ذVXeB_r> GEK:&9#(:.I|>I=OeOQAU#%w)_c.4f`\`zf_6 @8 yTڍQj@MR{ z, .>TEM)\`Iq+C9Eʎd&L DUD*`>25hv߸{ʧ.㘷hPS_\&i'yrB2͘nkϔb+T4y=|(c﫲8Bϣ^Ve͒4X6?x|;keAM ' l,ЯZdtSQU*MeiQrs7ձŖS#KƕkYh=xdIZX۹AEj:Jp!0*o/Gc䗯5;QIQP ;lE3t,`jC %?F@b]ua3EZ$EaY8bt r35.b]_76ʑN/G߾-|ٲwUrO!'.BDʬ`?.eD()G4VLS9si.+Ӆ]jST5/gY^1О rd>j4 Q\SpQV)VuGq+t!N`~ψWӡ^c ?e)K>dp.-7^}[sMzjfBTS2V7|3R^mL;qGakɍ ˎƣ=y'V}L4*_wҠS"8X'"t ly(M|_D̺]܎WGԚ=vZwEz4acSX(֧t6`OҞ}ğtI@*}b>Gei0_xR7gӄղ[< =yP;GUMqBB1qFӺG.e8THV%x U6+FG;{ׂ~,B [t6"ΫͲo27,tW[+﷋1~}"BH|&tp_? endstream endobj 1087 0 obj 3608 endobj 1091 0 obj <> stream xYKoE~J\f#VNdoM;NU?jvgl ntW㫪W+`>< |RfWj=;:nWnqUV9V''ǨbfSR\|7zUڻ!aaa%)@Q!C$KfmA !!CJb9MZWhteW}O)FNa a`N>>- [9<q"z'&3REUw9AheI A911Q4D5 ;Xl6xd^ŠdqI欂ٌYETk ;I@:U{Sָk %[pba.VM.I BQzLsIEoNg܍_|~~B#oЦ5D $TbYj\ț_d2z$`[ ތMsvy7h⧟ǜG_- #CU A3x4ۗO@qtlEGڠ)8ι4[FcuBQ-:24dF-" Zg ٺPS^Άw]Td1 A("j!"4$t  !2Wu)d^aFk Rg-E}f7)͸ %:T1c+43[e8VW2Nʪcc8/csz;lsQ5We6k3@D4Okd-&/j H5\O8hRizj(T{n*8 "Gu}  xK :@R:b d Wrj  "XLPjVsphX-^n ax8:T `58iƑfPZj(퍀/PK0#eH5b_eXNY _ r6М'%)!fu" dt%8 )p:ۙ۳՘'=[8(7pq O%TVkCs;:q뵧k Y@߯MVɪk"-sL,sGyZf/YEGiA`rIO^^Mk¥m>L9oTEpFÐ *IfvU6\)D“@K>gzstlN9zHZoxpc+磠 G)Trv+haM:odqP( j>d[֍0 $!g\V4?X'>AHb_pUY fZ=Pzu %83LrSdǤQ~8PPY@lQ;+ReMo_QuN>>l1MBr{JL8>I)?c>"lv@z}$} Vxendstream endobj 1092 0 obj 1926 endobj 1096 0 obj <> stream x՛[4y^! e%Rh|{ƹIނhɌ{<3N_7A㟗/v/;_7wxPP: \20 &Ѫ}qt/AJewfgk_}>9O=BH?d\)݃FmcƚFipaw.v.lַ n}wŽ*09rxX)YL~"]| it0=f.fL^vB3iF+U3 0wAU&-N0ӣ&^F uN>p- u>k\7_Ƹ>>[mma=.`$ /7a~\toXUhUvW; Uz Ԭ=+KmRȒ";ZܭWwŰCV4 ?C'nwIXh6GJAJJQ}[$;Bċ xrOF zLVi#YBlؾKIvuJHhdF6k/ѠNvpHzƱkEɲ7p2]m-Vaֶh[oRꅚnª'mV!Ҽ)GSM]U.ɫ,fżpHt),嫆KkW<q8>+vgX`Ru`n N )Oup>b.4@ĉn% YB▿H:J~)_,&1GXU~E]#̅hvL_&clXR~@sK4s? ^filMXQ=$rzKYLP ?A4RYB+gښ+&n$ͳ֯8/za ]K2h9HC0)4?.E8 5p̨3ˉ)="wdoBg0;g(pCJnPhPpoLGnMS 7p^hjM P">tM]W 9]$+*pg). Gq "iDžiWi> y@"=*uPsa@3f%P2M+%+00>%-Ϙ< V=7!{f\sˢ],@^ͼ/p'u}q b0<- *2/id6ى8 "+VM%Kif^EW{KM8͝trA0%1'`ptY7&J5ooA™$i< L=IfR].)B,{-mWMIҡQ1ȊvˁD5|&:֑Ou?&j]qv',<ЯJM4GNiՂi#g!`6w\K.Ԑ oBe&$  ƃY@^^v.U(W 2r,%Q*uJǘ.UY* G,ݡMeulcŢα`sk6VD6Z;+Xou@Cp&vвnr`FdgM;?(hiݷHy),(5w-fuw-&jniٔ[_ŢTOǤcm 7qIċj"=Qd@~;I*H'i,3Yh^nG6մQ{@6ȀRX{NLew-nCjnѵ#J6y p'c"=Qd@W-QnS>"orp{dTy -UU_,endstream endobj 1097 0 obj 2271 endobj 1101 0 obj <> stream x]K y*?b3lUSQTEV`K8zr&8Y6Rэ y܋_~^~ؽQ>x _j3v|;6A;w8Bxbԇ0?BS> -NHkor0 sx>_8^A)۶b^!Ӎ1G2ݓ:2H['<|=݃݃?=#ov_>?HF;QtJ . j9"`#*W+ލurCfXLO ©5o1R%-SRCBjqYHvmKWghGfN{ajᡷ3L&T]ԙ[ª,itؑ=W<`hU<Ā ;*;Kamb+}2JR*1\~G**Tpj!NJ`9"ɥ5fT 2 Q9L 0©6Gu{1!()LɔtL&T(,?MDb@m' 9I5ȓnsxF5<6r HtI9L&T]c 9V/1ϭD; }b@Sb*j˓sB Pv֚ؖ1eu3YU0{Ԁ +5unL #V񲘞Q1=sPnVSM:)%@pټÂa!|-ZCpbDdc<Ԉ2?0,,] J_VUɯW˾x`̌Cp.ka1eZq8!ޮB[q'8\j l 6hZ-zC; ab<cN!o :2axRe9L@pz-NrԛbnhV[m-iɍoľ}A6 桲3%wj=N0%WYɌ8VMgf,ha%N6?:m~5|T;M?x?VTB0ݵHxJfJmAErԲ礆U<F,?w̽XtQZ*ZK볮Y'֜LxbMhR謉zܢ "nXu: s$,{nncCu7N'(i|vEE.fFN/|uWD𨮓=[APcՆ< u>Kfuto6 mݻ,N/ 鳯 j͢A7ԚZEE0dڃ~S7#쪮дReL*EIL_c|χ+ ;qo`蛹ro>xմKLb[C8 LPAS8.7 `]#9ZvH-uD@$ :4-':(+jNsWzA].HͨK-z.mQZc{ˆc ZB\$fĥ~'PeOr83|D[#W/fݐ|5pIvמ힫%؞X=Fc{ӵ}:z9w썙H'ifc(fӫPY4LC[BںX)PȠGti96^ΖDq.s0wnz5qb ^bڞg:%gT7{rHCZ0cM/žH3]g~}r!ժxK7Nl ?Ҷ .lԦꓹ!{~n=DZ}MP}gifqK݋e0zWR-@;h)$%ϵ7,:dPUOW#Ԫ=B? '9?Ɠ/*ەP]5-Z965dfOsͻjH o쭾/;zӓ_FKmjݿ^Tz/&-endstream endobj 1102 0 obj 3392 endobj 1106 0 obj <> stream x\[TF 8^jŐ"9-iZ#z\)@E};߹ѼX+}m?W+^=IWww6JP~C4/0C &4?Ql%ӰYXN"Vk((3:dg8-.֡ralI['b%vVlC'AjDٞOIӘi-ePHTs%96orvuo#+ApdFBi?u]y~z^::s9L@KWnVET7X`$7Lx E`Pr/RF ̫ҕD )k2Ҕч~&IJӀ{ρ }~ӏgZc?e:(*}%ɶqƝ -+;Weg@neH;H,f#Ǔa%ʎ{${,`^Bi7o@md^vV$qVx4cN:aȠ^)]p38 }Mڔ[2)J!"ba<\1s=ܪ7B[ʆ.Ay Iďu-p& +M˼4JCxh;Vhk2ǬA8%B[b.m_ˍ/8eO$< #/\}V_PaɗdeK/]|fjwnLqJ\dXPq(rKQ2@`> ^$5lV>]#l$8x_"χ*cm K Ro'Ɯ θ pX&2 4"ziu9T^9Ƴ0G"6% j6 @)J[e VeZMad NFL_*"b^q.AUN2 JKV ,ҊEuAZc](l +mQ2ld"aULasP&K~{DzZ)FM.y=ׇ8AD0x4Y8ώ0JKv ;#֊;XpR.õ Rpzy@[#5).ς]$Vy`s>,,[ .na,H)EH9 ӂ픉nJ&TQ%WVħi8aki}IciM?_°ʀ:?׹kS,X0I%~Dzzrl8c:ޒ8q%$fr;[{[KKO$>9B 5c#EHKO~Kj0l"荣Ɖ[CCB:7eHHޡc7ŀRV5KS Kx3XzU):eQiЩTĝ?I r| =;P j"']\\4:wED#|ѡ!L~.5$+2JyED_ͫҢE^Ѳfz VL@Ʋ3f,+-zd}5JYFD[ pj?PXՁ`d|u3=`E#9j^XJr `;џ'rendstream endobj 1107 0 obj 3008 endobj 1111 0 obj <> stream x\[ܶ?bhᝏ6&vN/@ۇqA;#QP9ȑo.n/Z /Ӯt?D>JW ~߹Y!V'vnhZэ.}*^^=ty p84jon#R_GJ[yſm0t N2ͽ|M{{W= GݢpnopMݝ_?σ|! Kô~}8V@!Jm'~ޟgL+|v8*e[TY/&_RJfo o_O[$VJB^cBj&=TҪӼ: ߥU|ۃ)͛YR=V䪗׶ 7xyhu{Kk뀍썲 8;NC* <Ӭzd_h)OxD_0QóW&o@蛤$2EK_tk{eRWU`4^-:'VBR6wɉ+@ % UBT])>'6yA &Ejӣ1yB_%Roɴ@AػDr =}Ld0쳸^#c'T"i'h``.!4 xn)i>TkvWC w=hiF ()j}VS\HNE,9/J#z*3_Kr詔'˖1E%E=NNcD|7YL撞AQ>Cga(y=I~KXhKA%p) y؛'P t![5 CKB gQu>5- L4g Ag zF<k}5w緄60?_M(f3,>vwT`S\iXhKE)*dl2rSsG+m*C1R,dŖ߀'9g,Y e)(O$ENNU}ꖇ_e%gzn2sʹTiN\9uPl#A_b3A3 =7gl2WiׯTCPҵF-f'|f[2aqb"AK.76orQTT$%R@hC?%ChF J(=["fCyFuS ma'qDVș'a@N¤Ȇ|d q,-} w ՙ Ul0ēn/ ʯ,_& g#VFEn0ˆ)X!V>d6z9 `^u,$B|4? M26Bhp*/V2v9J;Խ%`JmR 'l^fȲ `$a$$V[,!k!4ڽY䏠Z]7fɗ7 aM#%svʍ味.ga.ʚkUoZ.ټOl]bK2>ysJvAL3ou=*HBf=***ܒmoiEs;Oz<#};F KK$3{ꪆ`z֝QQ*}8tR;nrp ]@anN0=Xw 4WJ ]"[DC6#<sm.C=/!5: j`MW˾\V@6d0 j8_[YhE/+ ͉fe߹V[4 l ~p'<~__tf3_2^OQ" r wyʿ5݄}eԬ-Z&m5j=RΤSiB%jMr}6ԛPW˩[[H]&ZuEE|VB )ɨ6>Z nOd$d-Z$#vd-/ sd\BlC!.am"h?R:7Qw!9%][u(.$O]Mqq%oa8Q]8h70R<8lø[v0ڢE`哽/ }hKzQ JR7Q)wJkUDJmUUi><9>naQv2/:lL&v/vϸ<NEZU1ӢjO%{ܢB\; (Җ@`$b:͡AhEuтO >-^P6\{x2]ۣz ވ RiAJȲ<-.; 1VS8L3w'u#>E?ȴ8zx e+;1NV9\<.' p+vyŗ+#MG6~Z` sAy`l[' νgiYrUXW[DE8ahƃf*-=NmMzҌ _1C@2 ;ڎOK:}k&FՕ,0{(iyٿ#]#(?"4l8sĉ+ua0̘/uF79P{% WY2Ώ++>6 !aꬻ܆k$kiIk#~m[@)aatRݘc("l:lΣN/@3Ěf1='һX4=P}@IZ|4ګXQ.<Ϡ\|08YB|J0`o3\Yr/Zbv;\]qN25s3't2٫?ʌ?nk6wƓE+FId 5j/cBf.AdѥM‬]`F{MDX[_[ZxITzuF | S,;0W{pټ7ʻGu]ה%_ϦU '! endstream endobj 1112 0 obj 3118 endobj 1116 0 obj <> stream x[Y B2nJ[Ҧ8J&.{Xh9$R˫+)T%ӿc_yמTU9z{S!TQDT?T*t A^yW}%" F JShJ_=`̿(@2!ZGQ)[dz|ݿ/E7`1ߤ{~(].iMmwŨ?7{@u,7%P?y%R1^s FB?Fhg-/pvӏ:ѐ潎-¬6)@iE}/HS2Uv^ͨ …USj@(lPA?ԽM9LFN>BZ -o fwf;WV7;ƋI=0]5<8̙+R[I-l\) Nj20MHXFxʪgݑ8Դn@PsiZka) [*GI#>ޠ.mF&}; }尔^]AWٓP"~Up&!DCޞCq4gu(=tHؠ;Aԑe9X- L:4Rxz%C0ͅ[3luۀc"S«t|mF8Lk)0o_% !sӂ#l$ ,v9T~I ތuW=D!S1/KH3}:@ahnM(&600Z{eً5l]zڢ+t/9#:1۸_؛ԠNT2ҺsӕA@Y `1@66>>w)ڢcƁKOS-[A RuJ&zɻ9ʇl{ªJiql(pz/7c'6ON?vQ6'ֲ-Aas>@DŽ`[tۖ$σfTy6AYXlDv7Z Ng;|ņE yb8RveL1kYCy [ɦ0X = sX>E32W xa5:ge~]YI3^k'ZIf!ReRreY}GgxL :[r4L벞A/ǚ{˾k9%2SY(), )C^κvbMX:2:cT%+Wu?d/}Z@e3[QԮcr1kyٱ0%JdN'S+ +<1U|nhU&%ˠ$6#7ľAO`h۴X@&P,p&զi gӎZ~O䚭]F`gsgnJaBeA$ܪy? =)@Lk\ \&h6Cob*tYw$0O݆ n`Qjnψt9Ea@D,5Y%lGEM0w>4nKcQϦW`TE! 1i,'{j}+e0N?э(DW;JKB_F@8X+Fe}XɊQ 2%bP+ Y]:-^^\iTcm4iVu.oI7hWac?@̐YY \oWpϦ4F1$Fw<6Pގ?"ObEj />O9 TNϸu܍)HzS*k<]w\kZeӽ#l5"zLiW6f2 V>MKzJ`@㎛%_ͨjx1% Щ Vq6(wFΤ͟&}ԷZʯ:.2 hfUge80O!YPT;rê +gpԘ̃0HsXȟҼ;~S2ńM0t~;z.W, dmwLm鯶l?2mrFdӸ9Z~ÞUendstream endobj 1117 0 obj 2547 endobj 4 0 obj <> /Contents 5 0 R >> endobj 16 0 obj <> /Contents 17 0 R >> endobj 21 0 obj <> /Contents 22 0 R >> endobj 30 0 obj <> /Contents 31 0 R >> endobj 35 0 obj <> /Contents 36 0 R >> endobj 40 0 obj <> /Contents 41 0 R >> endobj 45 0 obj <> /Contents 46 0 R >> endobj 50 0 obj <> /Contents 51 0 R >> endobj 55 0 obj <> /Contents 56 0 R >> endobj 60 0 obj <> >> endobj 61 0 obj <> /Contents 62 0 R >> endobj 66 0 obj <> /Contents 67 0 R >> endobj 71 0 obj <> /Contents 72 0 R >> endobj 76 0 obj <> /Contents 77 0 R >> endobj 85 0 obj <> /Contents 86 0 R >> endobj 92 0 obj <> /Contents 93 0 R >> endobj 97 0 obj <> /Contents 98 0 R >> endobj 102 0 obj <> /Contents 103 0 R >> endobj 107 0 obj <> /Contents 108 0 R >> endobj 118 0 obj <> /Contents 119 0 R >> endobj 123 0 obj <> /Contents 124 0 R >> endobj 136 0 obj <> /Contents 137 0 R >> endobj 141 0 obj <> /Contents 142 0 R >> endobj 146 0 obj <> /Contents 147 0 R >> endobj 151 0 obj <> /Contents 152 0 R >> endobj 156 0 obj <> /Contents 157 0 R >> endobj 167 0 obj <> /Contents 168 0 R >> endobj 172 0 obj <> /Contents 173 0 R >> endobj 177 0 obj <> /Contents 178 0 R >> endobj 186 0 obj <> /Contents 187 0 R >> endobj 191 0 obj <> /Contents 192 0 R >> endobj 196 0 obj <> /Contents 197 0 R >> endobj 203 0 obj <> /Contents 204 0 R >> endobj 208 0 obj <> /Contents 209 0 R >> endobj 213 0 obj <> /Contents 214 0 R >> endobj 222 0 obj <> /Contents 223 0 R >> endobj 227 0 obj <> /Contents 228 0 R >> endobj 232 0 obj <> /Contents 233 0 R >> endobj 237 0 obj <> /Contents 238 0 R >> endobj 242 0 obj <> /Contents 243 0 R >> endobj 247 0 obj <> /Contents 248 0 R >> endobj 252 0 obj <> /Contents 253 0 R >> endobj 257 0 obj <> /Contents 258 0 R >> endobj 262 0 obj <> /Contents 263 0 R >> endobj 267 0 obj <> /Contents 268 0 R >> endobj 272 0 obj <> /Contents 273 0 R >> endobj 277 0 obj <> /Contents 278 0 R >> endobj 282 0 obj <> /Contents 283 0 R >> endobj 289 0 obj <> /Contents 290 0 R >> endobj 294 0 obj <> /Contents 295 0 R >> endobj 299 0 obj <> /Contents 300 0 R >> endobj 304 0 obj <> /Contents 305 0 R >> endobj 309 0 obj <> /Contents 310 0 R >> endobj 314 0 obj <> /Contents 315 0 R >> endobj 319 0 obj <> /Contents 320 0 R >> endobj 324 0 obj <> /Contents 325 0 R >> endobj 329 0 obj <> /Contents 330 0 R >> endobj 334 0 obj <> /Contents 335 0 R >> endobj 339 0 obj <> /Contents 340 0 R >> endobj 344 0 obj <> /Contents 345 0 R >> endobj 349 0 obj <> /Contents 350 0 R >> endobj 354 0 obj <> /Contents 355 0 R >> endobj 359 0 obj <> /Contents 360 0 R >> endobj 364 0 obj <> /Contents 365 0 R >> endobj 369 0 obj <> /Contents 370 0 R >> endobj 374 0 obj <> /Contents 375 0 R >> endobj 379 0 obj <> /Contents 380 0 R >> endobj 384 0 obj <> /Contents 385 0 R >> endobj 389 0 obj <> /Contents 390 0 R >> endobj 394 0 obj <> /Contents 395 0 R >> endobj 399 0 obj <> /Contents 400 0 R >> endobj 404 0 obj <> /Contents 405 0 R >> endobj 409 0 obj <> /Contents 410 0 R >> endobj 414 0 obj <> /Contents 415 0 R >> endobj 419 0 obj <> /Contents 420 0 R >> endobj 424 0 obj <> /Contents 425 0 R >> endobj 429 0 obj <> /Contents 430 0 R >> endobj 434 0 obj <> /Contents 435 0 R >> endobj 441 0 obj <> /Contents 442 0 R >> endobj 446 0 obj <> /Contents 447 0 R >> endobj 451 0 obj <> /Contents 452 0 R >> endobj 456 0 obj <> /Contents 457 0 R >> endobj 461 0 obj <> /Contents 462 0 R >> endobj 466 0 obj <> /Contents 467 0 R >> endobj 471 0 obj <> /Contents 472 0 R >> endobj 476 0 obj <> /Contents 477 0 R >> endobj 481 0 obj <> /Contents 482 0 R >> endobj 486 0 obj <> /Contents 487 0 R >> endobj 491 0 obj <> /Contents 492 0 R >> endobj 496 0 obj <> /Contents 497 0 R >> endobj 501 0 obj <> /Contents 502 0 R >> endobj 506 0 obj <> /Contents 507 0 R >> endobj 511 0 obj <> /Contents 512 0 R >> endobj 516 0 obj <> /Contents 517 0 R >> endobj 521 0 obj <> /Contents 522 0 R >> endobj 526 0 obj <> /Contents 527 0 R >> endobj 531 0 obj <> /Contents 532 0 R >> endobj 536 0 obj <> /Contents 537 0 R >> endobj 541 0 obj <> /Contents 542 0 R >> endobj 546 0 obj <> /Contents 547 0 R >> endobj 551 0 obj <> /Contents 552 0 R >> endobj 556 0 obj <> /Contents 557 0 R >> endobj 561 0 obj <> /Contents 562 0 R >> endobj 566 0 obj <> /Contents 567 0 R >> endobj 571 0 obj <> /Contents 572 0 R >> endobj 576 0 obj <> /Contents 577 0 R >> endobj 581 0 obj <> /Contents 582 0 R >> endobj 586 0 obj <> /Contents 587 0 R >> endobj 591 0 obj <> /Contents 592 0 R >> endobj 596 0 obj <> /Contents 597 0 R >> endobj 601 0 obj <> /Contents 602 0 R >> endobj 606 0 obj <> /Contents 607 0 R >> endobj 611 0 obj <> /Contents 612 0 R >> endobj 616 0 obj <> /Contents 617 0 R >> endobj 621 0 obj <> /Contents 622 0 R >> endobj 626 0 obj <> /Contents 627 0 R >> endobj 631 0 obj <> /Contents 632 0 R >> endobj 636 0 obj <> /Contents 637 0 R >> endobj 641 0 obj <> /Contents 642 0 R >> endobj 646 0 obj <> /Contents 647 0 R >> endobj 651 0 obj <> /Contents 652 0 R >> endobj 656 0 obj <> /Contents 657 0 R >> endobj 661 0 obj <> /Contents 662 0 R >> endobj 666 0 obj <> /Contents 667 0 R >> endobj 671 0 obj <> /Contents 672 0 R >> endobj 676 0 obj <> /Contents 677 0 R >> endobj 681 0 obj <> /Contents 682 0 R >> endobj 686 0 obj <> /Contents 687 0 R >> endobj 691 0 obj <> /Contents 692 0 R >> endobj 696 0 obj <> /Contents 697 0 R >> endobj 701 0 obj <> /Contents 702 0 R >> endobj 706 0 obj <> /Contents 707 0 R >> endobj 711 0 obj <> /Contents 712 0 R >> endobj 716 0 obj <> /Contents 717 0 R >> endobj 723 0 obj <> /Contents 724 0 R >> endobj 728 0 obj <> /Contents 729 0 R >> endobj 733 0 obj <> /Contents 734 0 R >> endobj 738 0 obj <> /Contents 739 0 R >> endobj 743 0 obj <> /Contents 744 0 R >> endobj 748 0 obj <> /Contents 749 0 R >> endobj 753 0 obj <> /Contents 754 0 R >> endobj 758 0 obj <> /Contents 759 0 R >> endobj 763 0 obj <> /Contents 764 0 R >> endobj 768 0 obj <> /Contents 769 0 R >> endobj 773 0 obj <> /Contents 774 0 R >> endobj 778 0 obj <> /Contents 779 0 R >> endobj 783 0 obj <> /Contents 784 0 R >> endobj 788 0 obj <> /Contents 789 0 R >> endobj 793 0 obj <> /Contents 794 0 R >> endobj 798 0 obj <> /Contents 799 0 R >> endobj 803 0 obj <> /Contents 804 0 R >> endobj 808 0 obj <> /Contents 809 0 R >> endobj 813 0 obj <> /Contents 814 0 R >> endobj 818 0 obj <> /Contents 819 0 R >> endobj 823 0 obj <> /Contents 824 0 R >> endobj 828 0 obj <> /Contents 829 0 R >> endobj 833 0 obj <> /Contents 834 0 R >> endobj 838 0 obj <> /Contents 839 0 R >> endobj 843 0 obj <> /Contents 844 0 R >> endobj 848 0 obj <> /Contents 849 0 R >> endobj 853 0 obj <> /Contents 854 0 R >> endobj 858 0 obj <> /Contents 859 0 R >> endobj 863 0 obj <> /Contents 864 0 R >> endobj 870 0 obj <> /Contents 871 0 R >> endobj 875 0 obj <> /Contents 876 0 R >> endobj 880 0 obj <> /Contents 881 0 R >> endobj 885 0 obj <> /Contents 886 0 R >> endobj 890 0 obj <> /Contents 891 0 R >> endobj 895 0 obj <> /Contents 896 0 R >> endobj 900 0 obj <> /Contents 901 0 R >> endobj 905 0 obj <> /Contents 906 0 R >> endobj 910 0 obj <> /Contents 911 0 R >> endobj 915 0 obj <> /Contents 916 0 R >> endobj 920 0 obj <> /Contents 921 0 R >> endobj 925 0 obj <> /Contents 926 0 R >> endobj 930 0 obj <> /Contents 931 0 R >> endobj 935 0 obj <> /Contents 936 0 R >> endobj 940 0 obj <> /Contents 941 0 R >> endobj 945 0 obj <> /Contents 946 0 R >> endobj 950 0 obj <> /Contents 951 0 R >> endobj 955 0 obj <> /Contents 956 0 R >> endobj 960 0 obj <> /Contents 961 0 R >> endobj 965 0 obj <> /Contents 966 0 R >> endobj 970 0 obj <> /Contents 971 0 R >> endobj 975 0 obj <> /Contents 976 0 R >> endobj 980 0 obj <> /Contents 981 0 R >> endobj 985 0 obj <> /Contents 986 0 R >> endobj 990 0 obj <> /Contents 991 0 R >> endobj 995 0 obj <> /Contents 996 0 R >> endobj 1000 0 obj <> /Contents 1001 0 R >> endobj 1005 0 obj <> /Contents 1006 0 R >> endobj 1010 0 obj <> /Contents 1011 0 R >> endobj 1015 0 obj <> /Contents 1016 0 R >> endobj 1020 0 obj <> /Contents 1021 0 R >> endobj 1025 0 obj <> /Contents 1026 0 R >> endobj 1030 0 obj <> /Contents 1031 0 R >> endobj 1035 0 obj <> /Contents 1036 0 R >> endobj 1040 0 obj <> /Contents 1041 0 R >> endobj 1045 0 obj <> /Contents 1046 0 R >> endobj 1050 0 obj <> /Contents 1051 0 R >> endobj 1055 0 obj <> /Contents 1056 0 R >> endobj 1060 0 obj <> /Contents 1061 0 R >> endobj 1065 0 obj <> /Contents 1066 0 R >> endobj 1070 0 obj <> /Contents 1071 0 R >> endobj 1075 0 obj <> /Contents 1076 0 R >> endobj 1080 0 obj <> /Contents 1081 0 R >> endobj 1085 0 obj <> /Contents 1086 0 R >> endobj 1090 0 obj <> /Contents 1091 0 R >> endobj 1095 0 obj <> /Contents 1096 0 R >> endobj 1100 0 obj <> /Contents 1101 0 R >> endobj 1105 0 obj <> /Contents 1106 0 R >> endobj 1110 0 obj <> /Contents 1111 0 R >> endobj 1115 0 obj <> /Contents 1116 0 R >> endobj 3 0 obj << /Type /Pages /Kids [ 4 0 R 16 0 R 21 0 R 30 0 R 35 0 R 40 0 R 45 0 R 50 0 R 55 0 R 60 0 R 61 0 R 66 0 R 71 0 R 76 0 R 85 0 R 92 0 R 97 0 R 102 0 R 107 0 R 118 0 R 123 0 R 136 0 R 141 0 R 146 0 R 151 0 R 156 0 R 167 0 R 172 0 R 177 0 R 186 0 R 191 0 R 196 0 R 203 0 R 208 0 R 213 0 R 222 0 R 227 0 R 232 0 R 237 0 R 242 0 R 247 0 R 252 0 R 257 0 R 262 0 R 267 0 R 272 0 R 277 0 R 282 0 R 289 0 R 294 0 R 299 0 R 304 0 R 309 0 R 314 0 R 319 0 R 324 0 R 329 0 R 334 0 R 339 0 R 344 0 R 349 0 R 354 0 R 359 0 R 364 0 R 369 0 R 374 0 R 379 0 R 384 0 R 389 0 R 394 0 R 399 0 R 404 0 R 409 0 R 414 0 R 419 0 R 424 0 R 429 0 R 434 0 R 441 0 R 446 0 R 451 0 R 456 0 R 461 0 R 466 0 R 471 0 R 476 0 R 481 0 R 486 0 R 491 0 R 496 0 R 501 0 R 506 0 R 511 0 R 516 0 R 521 0 R 526 0 R 531 0 R 536 0 R 541 0 R 546 0 R 551 0 R 556 0 R 561 0 R 566 0 R 571 0 R 576 0 R 581 0 R 586 0 R 591 0 R 596 0 R 601 0 R 606 0 R 611 0 R 616 0 R 621 0 R 626 0 R 631 0 R 636 0 R 641 0 R 646 0 R 651 0 R 656 0 R 661 0 R 666 0 R 671 0 R 676 0 R 681 0 R 686 0 R 691 0 R 696 0 R 701 0 R 706 0 R 711 0 R 716 0 R 723 0 R 728 0 R 733 0 R 738 0 R 743 0 R 748 0 R 753 0 R 758 0 R 763 0 R 768 0 R 773 0 R 778 0 R 783 0 R 788 0 R 793 0 R 798 0 R 803 0 R 808 0 R 813 0 R 818 0 R 823 0 R 828 0 R 833 0 R 838 0 R 843 0 R 848 0 R 853 0 R 858 0 R 863 0 R 870 0 R 875 0 R 880 0 R 885 0 R 890 0 R 895 0 R 900 0 R 905 0 R 910 0 R 915 0 R 920 0 R 925 0 R 930 0 R 935 0 R 940 0 R 945 0 R 950 0 R 955 0 R 960 0 R 965 0 R 970 0 R 975 0 R 980 0 R 985 0 R 990 0 R 995 0 R 1000 0 R 1005 0 R 1010 0 R 1015 0 R 1020 0 R 1025 0 R 1030 0 R 1035 0 R 1040 0 R 1045 0 R 1050 0 R 1055 0 R 1060 0 R 1065 0 R 1070 0 R 1075 0 R 1080 0 R 1085 0 R 1090 0 R 1095 0 R 1100 0 R 1105 0 R 1110 0 R 1115 0 R ] /Count 213 >> endobj 1 0 obj <> endobj 7 0 obj <>endobj 14 0 obj <> endobj 15 0 obj <> endobj 19 0 obj <> endobj 20 0 obj <> endobj 28 0 obj <> endobj 29 0 obj <> endobj 33 0 obj <> endobj 34 0 obj <> endobj 38 0 obj <> endobj 39 0 obj <> endobj 43 0 obj <> endobj 44 0 obj <> endobj 48 0 obj <> endobj 49 0 obj <> endobj 53 0 obj <> endobj 54 0 obj <> endobj 58 0 obj <> endobj 59 0 obj <> endobj 64 0 obj <> endobj 65 0 obj <> endobj 69 0 obj <> endobj 70 0 obj <> endobj 74 0 obj <> endobj 75 0 obj <> endobj 83 0 obj <> endobj 84 0 obj <> endobj 90 0 obj <> endobj 91 0 obj <> endobj 95 0 obj <> endobj 96 0 obj <> endobj 100 0 obj <> endobj 101 0 obj <> endobj 105 0 obj <> endobj 106 0 obj <> endobj 116 0 obj <> endobj 117 0 obj <> endobj 121 0 obj <> endobj 122 0 obj <> endobj 134 0 obj <> endobj 135 0 obj <> endobj 139 0 obj <> endobj 140 0 obj <> endobj 144 0 obj <> endobj 145 0 obj <> endobj 149 0 obj <> endobj 150 0 obj <> endobj 154 0 obj <> endobj 155 0 obj <> endobj 165 0 obj <> endobj 166 0 obj <> endobj 170 0 obj <> endobj 171 0 obj <> endobj 175 0 obj <> endobj 176 0 obj <> endobj 184 0 obj <> endobj 185 0 obj <> endobj 189 0 obj <> endobj 190 0 obj <> endobj 194 0 obj <> endobj 195 0 obj <> endobj 201 0 obj <> endobj 202 0 obj <> endobj 206 0 obj <> endobj 207 0 obj <> endobj 211 0 obj <> endobj 212 0 obj <> endobj 220 0 obj <> endobj 221 0 obj <> endobj 225 0 obj <> endobj 226 0 obj <> endobj 230 0 obj <> endobj 231 0 obj <> endobj 235 0 obj <> endobj 236 0 obj <> endobj 240 0 obj <> endobj 241 0 obj <> endobj 245 0 obj <> endobj 246 0 obj <> endobj 250 0 obj <> endobj 251 0 obj <> endobj 255 0 obj <> endobj 256 0 obj <> endobj 260 0 obj <> endobj 261 0 obj <> endobj 265 0 obj <> endobj 266 0 obj <> endobj 270 0 obj <> endobj 271 0 obj <> endobj 275 0 obj <> endobj 276 0 obj <> endobj 280 0 obj <> endobj 281 0 obj <> endobj 287 0 obj <> endobj 288 0 obj <> endobj 292 0 obj <> endobj 293 0 obj <> endobj 297 0 obj <> endobj 298 0 obj <> endobj 302 0 obj <> endobj 303 0 obj <> endobj 307 0 obj <> endobj 308 0 obj <> endobj 312 0 obj <> endobj 313 0 obj <> endobj 317 0 obj <> endobj 318 0 obj <> endobj 322 0 obj <> endobj 323 0 obj <> endobj 327 0 obj <> endobj 328 0 obj <> endobj 332 0 obj <> endobj 333 0 obj <> endobj 337 0 obj <> endobj 338 0 obj <> endobj 342 0 obj <> endobj 343 0 obj <> endobj 347 0 obj <> endobj 348 0 obj <> endobj 352 0 obj <> endobj 353 0 obj <> endobj 357 0 obj <> endobj 358 0 obj <> endobj 362 0 obj <> endobj 363 0 obj <> endobj 367 0 obj <> endobj 368 0 obj <> endobj 372 0 obj <> endobj 373 0 obj <> endobj 377 0 obj <> endobj 378 0 obj <> endobj 382 0 obj <> endobj 383 0 obj <> endobj 387 0 obj <> endobj 388 0 obj <> endobj 392 0 obj <> endobj 393 0 obj <> endobj 397 0 obj <> endobj 398 0 obj <> endobj 402 0 obj <> endobj 403 0 obj <> endobj 407 0 obj <> endobj 408 0 obj <> endobj 412 0 obj <> endobj 413 0 obj <> endobj 417 0 obj <> endobj 418 0 obj <> endobj 422 0 obj <> endobj 423 0 obj <> endobj 427 0 obj <> endobj 428 0 obj <> endobj 432 0 obj <> endobj 433 0 obj <> endobj 439 0 obj <> endobj 440 0 obj <> endobj 444 0 obj <> endobj 445 0 obj <> endobj 449 0 obj <> endobj 450 0 obj <> endobj 454 0 obj <> endobj 455 0 obj <> endobj 459 0 obj <> endobj 460 0 obj <> endobj 464 0 obj <> endobj 465 0 obj <> endobj 469 0 obj <> endobj 470 0 obj <> endobj 474 0 obj <> endobj 475 0 obj <> endobj 479 0 obj <> endobj 480 0 obj <> endobj 484 0 obj <> endobj 485 0 obj <> endobj 489 0 obj <> endobj 490 0 obj <> endobj 494 0 obj <> endobj 495 0 obj <> endobj 499 0 obj <> endobj 500 0 obj <> endobj 504 0 obj <> endobj 505 0 obj <> endobj 509 0 obj <> endobj 510 0 obj <> endobj 514 0 obj <> endobj 515 0 obj <> endobj 519 0 obj <> endobj 520 0 obj <> endobj 524 0 obj <> endobj 525 0 obj <> endobj 529 0 obj <> endobj 530 0 obj <> endobj 534 0 obj <> endobj 535 0 obj <> endobj 539 0 obj <> endobj 540 0 obj <> endobj 544 0 obj <> endobj 545 0 obj <> endobj 549 0 obj <> endobj 550 0 obj <> endobj 554 0 obj <> endobj 555 0 obj <> endobj 559 0 obj <> endobj 560 0 obj <> endobj 564 0 obj <> endobj 565 0 obj <> endobj 569 0 obj <> endobj 570 0 obj <> endobj 574 0 obj <> endobj 575 0 obj <> endobj 579 0 obj <> endobj 580 0 obj <> endobj 584 0 obj <> endobj 585 0 obj <> endobj 589 0 obj <> endobj 590 0 obj <> endobj 594 0 obj <> endobj 595 0 obj <> endobj 599 0 obj <> endobj 600 0 obj <> endobj 604 0 obj <> endobj 605 0 obj <> endobj 609 0 obj <> endobj 610 0 obj <> endobj 614 0 obj <> endobj 615 0 obj <> endobj 619 0 obj <> endobj 620 0 obj <> endobj 624 0 obj <> endobj 625 0 obj <> endobj 629 0 obj <> endobj 630 0 obj <> endobj 634 0 obj <> endobj 635 0 obj <> endobj 639 0 obj <> endobj 640 0 obj <> endobj 644 0 obj <> endobj 645 0 obj <> endobj 649 0 obj <> endobj 650 0 obj <> endobj 654 0 obj <> endobj 655 0 obj <> endobj 659 0 obj <> endobj 660 0 obj <> endobj 664 0 obj <> endobj 665 0 obj <> endobj 669 0 obj <> endobj 670 0 obj <> endobj 674 0 obj <> endobj 675 0 obj <> endobj 679 0 obj <> endobj 680 0 obj <> endobj 684 0 obj <> endobj 685 0 obj <> endobj 689 0 obj <> endobj 690 0 obj <> endobj 694 0 obj <> endobj 695 0 obj <> endobj 699 0 obj <> endobj 700 0 obj <> endobj 704 0 obj <> endobj 705 0 obj <> endobj 709 0 obj <> endobj 710 0 obj <> endobj 714 0 obj <> endobj 715 0 obj <> endobj 721 0 obj <> endobj 722 0 obj <> endobj 726 0 obj <> endobj 727 0 obj <> endobj 731 0 obj <> endobj 732 0 obj <> endobj 736 0 obj <> endobj 737 0 obj <> endobj 741 0 obj <> endobj 742 0 obj <> endobj 746 0 obj <> endobj 747 0 obj <> endobj 751 0 obj <> endobj 752 0 obj <> endobj 756 0 obj <> endobj 757 0 obj <> endobj 761 0 obj <> endobj 762 0 obj <> endobj 766 0 obj <> endobj 767 0 obj <> endobj 771 0 obj <> endobj 772 0 obj <> endobj 776 0 obj <> endobj 777 0 obj <> endobj 781 0 obj <> endobj 782 0 obj <> endobj 786 0 obj <> endobj 787 0 obj <> endobj 791 0 obj <> endobj 792 0 obj <> endobj 796 0 obj <> endobj 797 0 obj <> endobj 801 0 obj <> endobj 802 0 obj <> endobj 806 0 obj <> endobj 807 0 obj <> endobj 811 0 obj <> endobj 812 0 obj <> endobj 816 0 obj <> endobj 817 0 obj <> endobj 821 0 obj <> endobj 822 0 obj <> endobj 826 0 obj <> endobj 827 0 obj <> endobj 831 0 obj <> endobj 832 0 obj <> endobj 836 0 obj <> endobj 837 0 obj <> endobj 841 0 obj <> endobj 842 0 obj <> endobj 846 0 obj <> endobj 847 0 obj <> endobj 851 0 obj <> endobj 852 0 obj <> endobj 856 0 obj <> endobj 857 0 obj <> endobj 861 0 obj <> endobj 862 0 obj <> endobj 868 0 obj <> endobj 869 0 obj <> endobj 873 0 obj <> endobj 874 0 obj <> endobj 878 0 obj <> endobj 879 0 obj <> endobj 883 0 obj <> endobj 884 0 obj <> endobj 888 0 obj <> endobj 889 0 obj <> endobj 893 0 obj <> endobj 894 0 obj <> endobj 898 0 obj <> endobj 899 0 obj <> endobj 903 0 obj <> endobj 904 0 obj <> endobj 908 0 obj <> endobj 909 0 obj <> endobj 913 0 obj <> endobj 914 0 obj <> endobj 918 0 obj <> endobj 919 0 obj <> endobj 923 0 obj <> endobj 924 0 obj <> endobj 928 0 obj <> endobj 929 0 obj <> endobj 933 0 obj <> endobj 934 0 obj <> endobj 938 0 obj <> endobj 939 0 obj <> endobj 943 0 obj <> endobj 944 0 obj <> endobj 948 0 obj <> endobj 949 0 obj <> endobj 953 0 obj <> endobj 954 0 obj <> endobj 958 0 obj <> endobj 959 0 obj <> endobj 963 0 obj <> endobj 964 0 obj <> endobj 968 0 obj <> endobj 969 0 obj <> endobj 973 0 obj <> endobj 974 0 obj <> endobj 978 0 obj <> endobj 979 0 obj <> endobj 983 0 obj <> endobj 984 0 obj <> endobj 988 0 obj <> endobj 989 0 obj <> endobj 993 0 obj <> endobj 994 0 obj <> endobj 998 0 obj <> endobj 999 0 obj <> endobj 1003 0 obj <> endobj 1004 0 obj <> endobj 1008 0 obj <> endobj 1009 0 obj <> endobj 1013 0 obj <> endobj 1014 0 obj <> endobj 1018 0 obj <> endobj 1019 0 obj <> endobj 1023 0 obj <> endobj 1024 0 obj <> endobj 1028 0 obj <> endobj 1029 0 obj <> endobj 1033 0 obj <> endobj 1034 0 obj <> endobj 1038 0 obj <> endobj 1039 0 obj <> endobj 1043 0 obj <> endobj 1044 0 obj <> endobj 1048 0 obj <> endobj 1049 0 obj <> endobj 1053 0 obj <> endobj 1054 0 obj <> endobj 1058 0 obj <> endobj 1059 0 obj <> endobj 1063 0 obj <> endobj 1064 0 obj <> endobj 1068 0 obj <> endobj 1069 0 obj <> endobj 1073 0 obj <> endobj 1074 0 obj <> endobj 1078 0 obj <> endobj 1079 0 obj <> endobj 1083 0 obj <> endobj 1084 0 obj <> endobj 1088 0 obj <> endobj 1089 0 obj <> endobj 1093 0 obj <> endobj 1094 0 obj <> endobj 1098 0 obj <> endobj 1099 0 obj <> endobj 1103 0 obj <> endobj 1104 0 obj <> endobj 1108 0 obj <> endobj 1109 0 obj <> endobj 1113 0 obj <> endobj 1114 0 obj <> endobj 1118 0 obj <> endobj 1119 0 obj <> endobj 161 0 obj <> endobj 26 0 obj <> endobj 1147 0 obj <> endobj 159 0 obj <> endobj 24 0 obj <> endobj 1148 0 obj <> endobj 132 0 obj <> endobj 1149 0 obj <> endobj 12 0 obj <> endobj 1150 0 obj <> endobj 130 0 obj <> endobj 1151 0 obj <> endobj 10 0 obj <> endobj 128 0 obj <> endobj 1152 0 obj <> endobj 8 0 obj <> endobj 866 0 obj <> endobj 126 0 obj <> endobj 1153 0 obj <> endobj 719 0 obj <> endobj 114 0 obj <> endobj 1154 0 obj <> endobj 437 0 obj <> endobj 112 0 obj <> endobj 1155 0 obj <> endobj 285 0 obj <> endobj 1156 0 obj <> endobj 110 0 obj <> endobj 1157 0 obj <> endobj 218 0 obj <> endobj 1158 0 obj <> endobj 88 0 obj <> endobj 1159 0 obj <> endobj 216 0 obj <> endobj 1160 0 obj <> endobj 81 0 obj <> endobj 1161 0 obj <> endobj 199 0 obj <> endobj 1162 0 obj <> endobj 79 0 obj <> endobj 182 0 obj <> endobj 1163 0 obj <> endobj 180 0 obj <> endobj 1164 0 obj <> endobj 163 0 obj <> endobj 1165 0 obj <> endobj 162 0 obj <> endobj 1120 0 obj <>stream x={PSGͅdQ*E}Z)>B"E-RH"`y1c@@J0ĐR Jj)Z#k^ful93{)'EӴs`Xe?' ) h!?gpeթqwg}L14*:PJߖ"8ChdBJ&I¤) iHD()is%+%/ԒpZeËJUIE{ }|Q;5CXj5@MF:dS"JAt`b;9Ԩɔ:$] ÷ &'z @ Fz뜣J!ؠOOߟ?VE#j BswrA`v@o;o7hl`2ZtBBA< Wˌ^C+AAcEPav:p okحB}FNȞŐњ=,;qA&gNImUǪ3'zձtW ˃ |cm~uF0V<tO#d LP5ۓӱ ӟ >KFZۦ"e^X[TWXZ\ĵ=R@g{~g}%s!'/;r8Ľ|~~E5PJegl/$6C3Da~rʻ;< />_e5*YLRHBZRZ )Zص+qx.c ca%ȋ_ncOhGdf(F剼 nk27ت&^dx8o$J,i>$7b-qu?Ek endstream endobj 27 0 obj <> endobj 1121 0 obj <>stream xy \TeGMQ47RK3DMQs_DAgMEAQY#fWoeZYf}-}7?e<}]}(޽B.qY7yO'iBKzQ 43 )_6 2JbkHhlx@ױO0w_xf`%ޑ~۽#9 mVȿ//<ϷgsאQ~KB|ƒqqyK]C6,mp#V, \0j[Awl^8fZ1c'M~)S_7`gf$Yc3/3/1ی3,g3o2f2Ȭd20N*-Uf YLa2k8f-μƬc0.4fYʸ23ӇX3F fxfclg{& c\iY̜U(RܤgW{ *v"[vrܹ>yw ^oq_ob}zj~S~?hƠ݃]]1{ErHۓyٝ~}=pXpXb0S]WstWTċZU8 Y(.UtD`8"u0Zk/>EiQR '쏇8)/]EkUMupށC:NdSh55'.G t{hfMt8|'"uV$FE!Zt^TT R?>Мu3# h#eMo؛h0hK DVgDVdC]aqY׈H(~7Bh"Cc|׉>?9|g-6//T٪E^/^8q>ncylT|GƯY.LP K$[iY!igR͊8]p|N}4$qb՗&\r`.%G쿛/k* 4!#fpDt!7ty٪b+ng5 F$bu׃iy`_s^"vnث,{B_u0#H(Hp~28-X,PjIXtUKX'c1.b8c8 xdJ߻pNLwsLY ΃^%/h+YFj&Mڔ) 2q8_i{\\iqhA?im:bl-oܜ_ L u<'/EŧD+rA|v>LGE-ZʣMFЁikT\JCDXo-MNUsw^碳qM* C@|ơ[M.oK[/'_p\Z}!o^> W{EZat%[tRS,q.[1ClthUSQud߇c:ܚe/(yz,xuRъM>>1>?F.U>"?_j2az:Y#dE j*qNuF賄] 1y5?X_>s,a8G{SfPyd8J,ԊgytSQ@qb5KkSD PStd(v0ٮ`/fy&sO4~,!%4\I^UT8چV)S|NOiCU$?_ZuVcVWZ5Z( ;!Q[[_|zuZ#u;Zg< sl[0Ŧ;7TM\xqťUqMwiu|4Vt)Ԅnhؕ9Sw2{t.CםZtuw6 +kxfܔpJ 7}_f6w汏`j2pwPC6m 2mp(%<~ *PȋBwU4bU6p?5adCI.&o!"a;^HvO\E}v8vBTx2v[Q ncG1AT>ejW1BXA@fJreeqéw-7=tDv-^H+LE@j(H*2r}fӱSP\ ض)F[9{ٟ ZJz JqY"C4E zqw? L%\: &8t愭z'Z7/SM3t ;x=x{Hz}A)=6jJ:V}ⷐf.>bނ F]KK/_U ڐǠIGmet=U!cUu^EYuch/G_Q+ba94_z1, B(اln ˩4QZF J 0ve{7h>ɡ| bu.]sRwa LTvxD'Cp3hP86{^0IOGO?anlY~D'S&GJ>gi%_.Ѯxh%;}Y3~'YϢCuLlu^*b \2ioSU*r?Q}u8kUg̴f]/vF>tc_7sGZ=34Qb+ڲFD6ըQizcۭ3[. =E>Ei.D Dvr/? r͹\&=h-F ]̲FFbae2f zNc@D;0/'*؋l.PXd4vBf]v2YNIѺNPP#v(,pwSg"dBIsZ~wmJY z}G-.'ĞWqŗԣ z Tw{3 ҳ/o7DiMQr: :]AIr UA`ަt|=m W^7y2&S`2tX ՐU~=%Yr(1s\\d>7> jVm4.;z3 EK}? UePUh)`*9*wGƮ {_}:I:H$d=[H}d%C>[Z+8O`OnsQdfN.TQwSvH97+y5xCi|^: ~.xvy@);9LӺoYM\EyUrJ~R4}ivcjUaw}QoN[:P#n:Ei[ eyicV>*bU7^25@=y2O~~V?1Xc1 GZFMZ~cDLAy> K/v۵8*sjs_dJKJ9u[rvp^;2e}M&Z:{xYsX礪Ua` AgU{G*=#>h3ʡHPCޓBkI8&9]+툛i anmeN~>Ŕ;P"tءKך~D~9Ip|󩤷۪:H Q%:|xm>w,{_ce d+$>7o8{r>2DsrXL"#;2_,,.;לK R+4󀃶b/o!;j pɉ4Ԡ H܀L~Lz]ĥq C%N‰įf徢+:iq,A,7E;c~odJR $i#ىb¸FDVV칑t gCx/TkUZĔn*B9\R~}v]8Qzx|At* KCJ0k(ډr;e"8kPu=j~L[x[9ȇs8Ⱘ8p> JiۑxwJBI\'xT[{"/}DFK&}|WU}sʼnSE҅ڪyn[0gyxi}4;>mVG>9Τ?%/wg[5e3Aspde 3Uzy{BS:>7/޺@l_J4CAH;vuWBl.GUN _ [~CӐS] -\{P&u/C5C Qr+/^GK{fEԚT/ kJrݐSCYj* LY‘cgriu^}SHsނT[E/k_ĮIK_)Fkxr"Rm],-k_xr JQW ۹ʐ#G,.ӧ A+ye8kCf{k~&k!Hrz%:#89\?z$~Rm_=䯇Gʄ _4%R) XVw=`okT qq n9 @2ʗhoGa[.e|J<=>7L/U$}.U,js?.(H7e~43UQ1ѱQIoW2 ,3p|29>wzy·X7m/7*v17"o!8 ̡( O1oD$f];,?n>BtMVra=muIJLzmM^O;ᶦ6Ϭ:]Hfz,V싪Ӝկj7f@ endstream endobj 160 0 obj <> endobj 1122 0 obj <>stream xU{LSWQ}[cEt:I-Lbt U,NDʯ- B (&* 2p.l=€eD,s8rQ4M;+|^l iaHX1 禲AʀԩeX9M 7i MQ:"2QRJ#Uia8y21RLtb{5ajU7~117A6YYOJTi做p6(U^kyї\j.Nͣ8j>ZH-f9) Jt4="]c999A>/RXwF q*#Ad~ d5sDD|2ߘ[$# Q[ѡB N /Yv͡yߚ QZRPyl)<>s?#D E9\{٦X;&(J9mT +b*~ Ӎ( CYoHQ=xy/.;f(/Sn\ޠY 306Y$ WŀM87$+YK8tN_9`N-Oڝsl+9wخv ~,"󈛏:JW--nTu{&@9FAeTM"6<ꭧ>B_ =nr) [WڧuKB%۔PѤ|. Q5\cG<C U64Zm#r~ דiȢT|^y>Gv *#<Htljq#g'$㐖œ}5dl#]~Z_ߥgM`nJ˹g"R!݆hiqܥ( VVksP%d@!ƀz(62?/%)Q~`4׊[*}x"uR{ vF| ];Жy ԱBרJq:\t^ڗ:O# xK=s- 9-j ОcS V$54XW+kdY@]]|t_q|($~O>ڐW+n_lٖAn6v~ N_;zWq+pm]0N.~oR[t%x_ބ*KAj f>8ҚVqHZ߷ ݾvGzP+F9Phݶ5o~}=4߱ HhG dcc> endobj 1123 0 obj <>stream xy XWvMwEMX +(. t}_UVDQ4Hc1.D?cNt)r 4K2?<>Tݾu9yޖ1&LZ.q1S8-v/qH& +&G޶5HĽp\&Yhd>jy,{xt1u rwv x:|:\]]]z^n'55aՋC}v:.yKwY t_,c=V{n\i^og&O:j~gN_˹a3f$yYc2GƎfe1 3,cf0crf&3`f1㙍Jf63ļLdf2KKf2YX1sތ)ӏ `L f0&cf( c_fcCMX1%^{5m&reb 6Ev[85{HoCSmo X3j7f=pAAip뛶o#C"|=tЈC[% lˆ[-o[2b܈|\_*`(>6p4wrX;)mL8s1[43a~B-eKVCӍ2s_I$ƇŇ79 9 VV>ZPpl:p0+?!Sch,'ȑfPҕ`VQV2'3 Ҳ.CXG˦Adrr6YEzt&)Ne >`tm$FE$Fo$ ]J]4q@W`VnxLߩ35P2.-b?w>AzYٺ/KI)LpQ6jBwӫg6"s!}Bq_LNh6ʚ/.CS莽h j~˧G,'=Cqh9MVhUɑ9WooM،ƚp%o? z2W y\9i:CYujWmTiӈylš'.%tQ|mTi{x#@.mDl@ ZYEXӝ]6'm0v.'RvYIm&,^u\\ EIx0V `F<(8/*aV ц$i+#0'Mx*Ūң3b2rsװ s8@PCl!>~a$l0Bl0G:#m%:q`qޭ9闭5oC&-3+pL`"<~,.&VEQb^'W\AW{Oe4YhQf|_ފr(I}M7o eGY[N8= KE43Nþr}y|k2XE  DGd`mAi#Fb27Gn.PtRu$̸>ŰSֆ"wYĜz2NYPYx8EȺNk"7F^ޤ?}.5԰{ wuWjTj67IୂjF6&+1<`l7|R(H)BE9I[+y mr4vcr)!t mnT6*!B%b<%:DWR\T 6|T5ɵI)Zu͑692}ԣQv-ĔygLlR_^LJƐ]' d?'@VK&~Y%?qo<(WN_48\TGb!.t*|Ɉc o=A$7(|k-;ϝ,Y+[ve mf}zΎ #cVm^* e e\_AsC|ET_֦rjYff1d16'ᤣ/ !!L_"ؑŷNjMt) ˍd)%~D5uؕh!oyt'%$ qCsb~2G tHȯg&~G7qKT[vy0GlAm_[,M7~Oyg78ة/Cyں'!Z-@x ݷo[{4̾CH}-Qi$})Vdi5BxL>v6V76,N䮄,V_#?wg:S-G%l L4}avh%3d&%T]{DƺVZyK2MET!=/i#.8{Sv &v- K4c9煪sR.q$aNW0,$<עE?Z;tnم?L 8 {  s6쫪27w|)6z}}@$%p y@V_dܖ\? (S_^niQUt VW+CsKݦ/^9-}{C a At9w|xyc*EHLQgF5A)ds' ;߻6۶li_iV0M>BUOMh Ku6:Y% $ R O@l[+63o2ȐƞDUM!!  '/!auc_!L`HR :(*K%`v qCHGƜUqGyuNH̒YWUj]nY-Al|Ү/(C8bpZ̷ WC;VRϻy=+!SvZR3 $+ ۫.G? ϊ/}^QѬ:y&0<ȑ@*kg~"G7Gh\Ԏw?>}Գ\k=}MpgWxx+͍.GK4/N9߼յޣY K *νF`S.tH%x"W1S\͏/O\z!5/vdmL|x"3lyւI σӔG~":'hK 5z#fWUv;R?{;DVz%Kz-ޔ9aTЬ˼̒rK^ݗ!QI>ۣv _k~պk,J:%#)bq}~BʻJ\5ʧԍ9)ï-P8eb?eYwq4p!ʛgԧ| _MY٤W5UWBb ӀƁƁsD6RB(M'-G2݉z&1Nge}"m7u]Smbs$C|`mť]+te\ z$c;mr9YMXߣ*4YI*D5GΒP\lQ^a~y #Ӈe%kl3: Ea)I SPD#lS Tdɨk)JgqnK pޡj|-^&EQ߈inєHb)!"Dr [/Gv.=?7;T"bNSrVpZ˔\QvϾAWҠKNK$-H[jh!)=•94ZZz ZjTOЏF5{xhyo= ud?G:S1)Y@9yKVV.nUG4ZbϺh#=wyrݺ3LpL{`G?<:ɡ= T<=vo:}D/1au*ݑ?xdI }+ú]*/ǭ1 v(1њ]7ӬYYL DhA"u#D/ R@zAwf] Z #O ;,eKpfF.USFXRHO,z IL u$4-!&hƥ }69hH 1VMed5@VNHU O_PPed$r.1 @SBbb$KAlBj!ʃlZp%\ %7Mz\LU.ǝ7q<D.6/&#~~]ܪjK ҄b\PrI4%uO7Z{tk4^[BS\&;!ote>%"h@[ea5HUWX^Hۑ,? 4$)<2IC +#Ϸ>Tn! b _W{ 1YdNDIYZa~pdwmsl=8 >1Z/FHgx@I Da4F`l=!0?DPVBɂ'W2ˡ·XRc.$:<;$/&P:D J1 9>dZ x W^u tdʉJͶmzѭ Ȉ6z[fFi4C;|S.ГwR&ۅ/pͧ)\}qhjuҊ&o2W7ꏵx҄#:=l]d`ZEIHL, ^>q˷F9:xli}V:Q);T(`AUz}j||=݈pލ===V#|Sy]i%,G%4ޥن)Y(2`3#5wn} ?1Sz6$t ytZ?y8[JLcrekR/qn5A Ն֏v~< $ haR,Wh>!`Ne#~|aဎqaW^:"C˞$2)KiΑFb"Uxci'{~ xßњк?>ʍ2o@Cɋ|7e< Q4M&sR&@쌯ppp"2Ύp3`  33"@['׹W`ďnJ9&էWܳiDF̖.k.QlkasTis/\ ʛ?*߾9Tn@zׇ~ 55R;~7=v%1 \<_aZ O ]"xmLr* j3zh*ATaߖ hr?nBź4Uvs>-W 9qq!毎(8PJ 2B忂/cn7hBk`2FsFu.#ٸLIeFSLM,>ݷ/*K۟a_i endstream endobj 133 0 obj <> endobj 1124 0 obj <>stream x-]HSqme48˝ DHBB Z9}620A"qcP]uUtQ7t?,jZ7 # auD<Ń2S~JnԊj~2J.#[ I6}ykeBFͬí{-z`'aX;Ͱcp:toc)j0q6.u'cA^PB+x^D  @)2HI)br\^0l$ mPu#$1y^Eiwx>v.#Rh&%S֛'@Υ PPml7U٪&4pyNt>w 0ظ>>TԨwfD.H%IǏ姰/7^_}*$|}( 񶂸5gTB*.u~^[%!/&|<|AAxH^Qκ`y.+tI|[_JyKgW-yB0 ~%-ߚׂ'-a{(tƩ5wkM fګsY-+Dc^]SɫIJ"f endstream endobj 13 0 obj <> endobj 1125 0 obj <>stream xYxTe־Ð^+ @HPCI$!dH2rf&Ig@MzYAi(ˮw'3}9+cڷcd2bcFK ľW):ˡsھ#=q=0e oL2L-q w _ p9L?~++B axxogf♑.ف Zv!>+n]9?l۪;|^C>Q>z̴.㦏0`Γl=ej 3g2s)(Ufyʼ d3s7k f3Ĭd3c*f383 Pf5 c0pf-LbF0wdFpL#Ӊta1]nL{;Ӄʼcxe&y3v-Ɖ `z3}de54; lb"9m?}!][acyc ܞ};vTt s7:?ڵGnka zCe=++c?w_ͽ;~9޷C_g^YJ+lC5Q~:afWS8v|^ A/>C l3ӵn ů+ԯŒdpS. y5vn4L3W^3Uͥ^')6%ۮ ,ꦙrq@b>9W Ѡ$o#׺88?ĸTv86pvv]pY٘e4a/ 2Ҩ5i@?1pШRMWp&f@;0Eu;W[-1.+%]1cЧB!\LaF aA?m,} 8C`g QF](<,sLݦ [0w$C(DS2lPGoj>z~ߙ3]p3vѡ1۝_| =/R`;|+I kLPNC[ |5Tb˧/v^!q .Wp~u,al X)̒j?㌤Ɏ12yP_&}<#_tり+->-u sVN%}x/Vۏpҗ'2kU-0heM+ zc|7ڪwW5:Y>aS [ N>IMd#YoNΠ)[~#ݞnx,1z$88#Lc7'ceQPl^8$f- >,jZ6TEPHa&ϴ3~b 9j 6].G*Z)ce`KNЧ}pB%Y]j\jB8e9#% M]͗mQԛ?/PO¾ϮSl)Pj'AH|Α3]^^{OTijf=1Xlǣ1QՋO"rQ )w/Bs/e??p_:ݻ;Syj '=Zq}sL!(_*r &Hr!R Wj2Lcq= R%A zHvM›B\H wl& jGEWQ.G]7/nOIcQqߡR AąPGcx@š8ʷo;9lke(:Ы'@^)~ۉGTO,8ďU۾ܹ8`(!ppwu +KE߰)l l=Atg`ԛUԜZhoʎ䞓oݖKOn_n j_ADZըb% ݤ,T'kYA*Tޔ# #EG.B/#YLu-HP-]^:/ѷRR)ǘ|BA_",|ChO1_Ȧ& )qD#x!QX7ӫnD dBq"P\ǩAӠJ$BdCcx~ewGA)ty٪jYm6ѩ1KXp{|ձ#Uǀ8@=ie_* FpڧF7:FGIiUGs9]YLwʡƬUd벿g "eF63Xw~DϽ>~y ʋM zM^3p u+]uʧ[e{ExH[un4Q.h˧gӝsWQކQަî8k٩$NQ`DWJ\ %n"QE$K(B&+p +o\&eny'>q N##xF\qsq!qI _ט98裛w9$W&.-|Lۢ򱼶i:D2\A2]E^[?iNJRر9eNF#z\|P*HΡ-,"}C>OY3ah8o!܀ae >޷ʦ2Oܬw,v_4_-iV`2l2l9򨰓)~|Hⵑq̅WT[JjV=quo}N=[^aS%4ahtΔ i$S[G1/8M!_WT3 5J  / y,i]]Zq/vΎ5[2ySLF"3((w ~Ä1hhGBŪ|ϑ)ŢLkn^|z θ(Z~nI! ؊r%VP^v,Q}럇S\qV BIWq㽔`0 cu~*#;084J pnH7`.].QK-6Y \Tn|AVqzIa|GfZjnܹomyPDnN~Q[*:v6Jaurx:-dMajHB J?h0S0yκV~O.a7XEY2<m"]!e'pq"l$eł V졿|rW|j[Gk2{~޵nc1~&IBjVztڝ ZgPuҧ "LUT${ޘ!S7`ho΀?(~燚 2a66}ާ4^eedSWD:'2C؇q_8F^X_Xj%v5{OZ'<|nX{6pYޔ2Fh"xFgV{ä=Q&,$k[l˺sC[߻V;B];d"K\iOIJKגl;N~8S-ɫ8Xao T˕/gW3=BsŠ]mj;<'L K۳lWOJmm^q_l +ˬm-2u~+{.]XMsy}II862yS`Ԁ& %IC|¿mXq'u=P=q|X+E'7gIۧY-,?`3d%#]Zn4e `4kNط^K_NvwRߕM|[ͤ'؄đ9b>'~:ƞ|Ώaq>VGdo.;~üY Uۑ"i0G>PAYk1W@1BZ$M %BnbɃ <t\/(F )ݾ=$dҐR)RS@Q7Ŋ3eueq34oFEDc 58吥jA  V )C rg@nǦZWMU/ߖG&*־Ϝg߻r j\(&Mْrss[t7 )T[ľkM5j.+cxgh|> (!7dB$Zk$ÑjM.xS^(oX}1:)\?H1-֔ fki* j=(, 40CsY5 KL Yj$ҟtuC?j`4 {Ե+!)"JAϪ4gBT 2fDe<8OYip8 c8U+l[]$Cû|Q{n00LҒ HM$qVks R{_, k![]TMz8-9jtQbOcj9Q)-5sԧr VoQG yi!/Te^ -ʎ֊{z6^']RK۟)wCu:x%2MZhl&- DF!w8IB3P2lKqCi*1Ϳ:GrLy\i~!"@qqfFƉc7ihΗrVihZ($@ΝrqGY. ִ8w}4鵰e:Î/.V9RZnۗXV޿%ZMqޭ8KK,8i, Ѱ\? .+6,_@n,Ш/fNʅ|UռIGz un4eHBBL4eخPBy- br8VHT3Qm0/ξ )9^hN0\":ZmCJlcy\QS^ꦙM.|Z i\vBzgrRFX7o~,x:Q#s&'S^9sUzM=-hplvۘ8H:+!+˔!80zY3{JyK-.mh.3=~*+x*69s!DYҨ16FLMx*>R7?ÎBkG@_WZdߟ-ӄ IGڃȕJKך5;#eZ.)e.9,R;F7j b ҶWjt/T}7 t/2t'=ZIѦe ǰ]G ~BE 2ΣbqfJ:8$D.o9eEv&bTG1qD_@T "IT T#`b[1;s srPۄWWRuf]mòsQmV<؀,2ѡA.(y`D@Tc"!"V 5pZ8TH)b!b⼶,,/YWElvQi4h[r^,9iYϺ7bEvW5k# {7c9Tc!tKoqYY6ɱ gIr[{.hGV[Հ,Mrx }V8]=3NceP#d鰘:yE1#Vo&P~*M/` ,R[/i#J4п;-—ˮo7:Iɤ)o_sߐ7E\ß.;3n/qHOڼ3&)qm82_ FIx섊1_acWsamξrD=tBɇ'w)o{sYE!N"+E8} g$XɗGUxh@I!/:r.9%Y=y:鸴tڢrW\&e2u^Kl7LKI܏?_Vqt6[Db:1: _Ya.ؐh'A!;9eZŗ󆒾so2=Um{@ͣ.@v/_*1yK?E²G]G P,pkIlB`?q68W[+72 |nNzuڔsPGIdaƐ>ۈ ^tp|*dJI>[McHTX"ſ -Zo@d+_Ug[Do;OѨ=ЧP)$hwBDfjDV'qM T;rq4g:+m& W7pk͛hj># D¥\˾[ m?[M Z'-Ơ?n{LZjYHҁ ˣm4z|g{>!!,'(J t( ;^$tl?ҹ-sK]_w endstream endobj 131 0 obj <> endobj 1126 0 obj <>stream xe{lSuw Jͦƈ"G72ƶuzOK{z[€1gb01JH?L;/oO9sCa؜ꭕJeLXV",ATn,2dJ=Ⱦa637+lPo(c `1{LN\bUBSVֆ EzNWC#Kˍw_y#䢧οf&\,pHؘ݉/ S&/F0gom->f `w0M|L M 1_p^000]p /tح e1 KS\|ڵcunC1`!W!0 `b6tZT,^8q\.-b|_G`I΃6c16j?D?7;E '׻hI_ZT)q`Sָek͙CBqBT n4ic4T㺕`f.4ן!"cNtMj=33R =_#Ũڥv$&ԥY^6z}~q27:^'CKL%⒏GI (ajn˜0s'3k>:˦0N%.m/FD?)135֋oYΖ=nWa1jԶj.'[<< Ϊ]5$@GP+Ey&4=H;Ŀ#\snIL?t^o2ǒ`4/G> endobj 1127 0 obj <>stream xuSiPgeCv -v܍:HhF+Zk`1Z#y\E ($Q"T:aTVM?lo{}$d^Ir:.|P $ /q.x;(dGh "ktY嫪EetVj!S1He|^jְk2:'GAPiwhڴUy|VTiA:O]/b1XM, BM ix&|RQN'K'W~^d'1RG(q#d.8  uY 7z 7 {N*XN,gN8 ]&I-A|{ҥs^~z0ql4I"SlB! 0.,u2A4,9`x(Nu@5ʟԔ5Za>Dn2W(;,p :$d!E}|:gw0y>ƝX7Nk %v5\Y.zKlĦCR04~聋' ՝v(A:dz{Bއ;LF7;Q] m'Q p$;e ݪK G,KUV_ӘD]ݞd~,?,ؠ58dƅױ ycEpV: {C%HgC K8=tO g0 "*jʍ =Bmtm@[,/?yMq vz2]=z$GhDa-z2l?‹KIg*XolH8J]*OoR]1{ 0pʏAvnαm3#JG/pm61cdpev1/9z ,iȊSƉUQy7ūm\M¡`ھjşˏv0|bdoۚr4 @+p~m6uYXH;}F|9Y]}B1ҬFl endstream endobj 129 0 obj <> endobj 1128 0 obj <>stream xW TW@_JabF?1DQDVA'A~4 ?A#Hv$$h&YNc)r;w 43ޛUusgc5dy^~3o2q%9( kikðe(0rcj^TtRLxN.\f̘4wKHLxPV'Cn?"VFlOzindDOHlHL|Hp߻EmaK&m r,:{~肘0>W.]*2pɖ5.1$f4b̫fYLfV0kXƓǬd2Ό/¬b3SWf53YLcwf"yal0f 3aY/ h,OwYͰz b;¸ 6lmm[ldjaɠۻ18y!C j0dh/1`{2c彮xSdz %9=YICa= KaTbk<ǘ%U2qg.hR`!+t1DUye3 3Q%+I*ChcG,Qц4Z4=vt.C֛f~ _741[ R5S㐦]N $2; _m. Ӏ.kQnlp̆l2T(cDDT\Ȫ6]Aׇ}{A&ڢ \]<W; Vd G 27Zv`%T `Qg4&O d^{Ѫw hr >.#.rQ_NSL!arhW:8GNMTnS}lS}Su7 '228\P{Lp48߬Ka҅ށ8\.vHhڴTG]ytQXۦR|h8ǡ =6ZR- :=9Öo3v0~(,Uz- #Zh&Gӄc$C&_6Pޡ|?Xs~B*q@:ws2C,W)0X>,%]YI$ r8MA 6A0BTF[.N|q>ɐ$X;um(4w4*OJ Sdn\CRE4Rtp+#'DfSҐ!_;;y^'#Wq8O^&&z_CHE^w V QLBxDx齚Z ͬw&*y]=hwKEYk:Uzރ`+%Ηi)>8ࣔwYZ3!(1*OY0 5<WkV,DF.e j45zqql6j3*MaPFYB'X*.J4U}G& OMTbD*(2MY42SlO9/"6jJ!ьK^.Fc_] ;*[T4Gsؑq68Nff+YTy*.|b$?vWv\ve&dx !/xN2@?*+fK. XI6~jwb\x9q)uyq^X,c~;HUC(Wp[:tA7gEB/7ٛp=ݷ}e|̍KK^ #B=*6"* }P ZZޙ \`SܡSGpۣ O٪}*Sp 43q% f,u~W){ sի6mc郁fL)ʌu&3(6rxxBOg,Oݧ Bs_:vxVA]ơ- RX߽=R9~hLSoץ9Ȅ(Yg]Z8z O`Stlo[d&͆I0b9Ud c f2W)tֿ2V"XxS gֲÒbV@w [vdhr9ft`]؆wB;_Wn}D10C3/>if!o>Q\3j>=z+adөӄ+hq6+6fW)ͽVi kk!KȞ@xo2_t 1Ȣ>΃" x4e23X|sٌEFoKf}a5c`F?6礈"z}N_#fMsO<@ў8Vκ\~9+r <Йט3 .k65;?8]Iw=! o ow2% K->^I77p2Bkݦ^so'B7mx7tӆwN4 v6NOrF(ٚ aU.AUQG 8:$dt> Gi$h%sȫ߱wn4C!!)3.¸Q-kB2. O3ݿ 6+?]Y^RRXU 5SlW٘ =6 endstream endobj 9 0 obj <> endobj 1129 0 obj <>stream xkLW003–IN@ixk(hr[6 Ÿ(~ ZD7kA5V럚&/ڦ!iMӟ͜$;3 AE1n2Rf(3i m0Р =5#TNxǽhJJM6KIQU;O7_lYvURϯԦ[ VP0K V[vUy6=XQM7T,[ +LVEj,4X*BkmFb-XQP,D,eMh Z!ҨE4j4$9?W: - =AG!!2_A+>ۘyI4I.; ;j+xdPP#as I0+El%Dr}V^ŏ#Y[46v8"SI7t@+4MrLPYSsH9i-ԁeMuw!m6JPDBMiEKyTHUF=Zi Nk?>kCE>{ܪs@hԓa~F|/[[T2Wu8i=v$tUщ)p 'qAa8P/NPg(xY$(xǬ\7cw+ 6ɴ9R  J8gޣ~Beغ56kTz2lhۿ 胳2 * ;9y|Vw9Lb:./Iun;Xq[XT0MCM 9/:9.m!ڌ)vfSBB`\ endstream endobj 867 0 obj <> endobj 1130 0 obj <>stream xcd`ab`dddu 21T~H3a!]O=nnu? }7]K+9(3=DAYS\17(391O7$#57QOL-SpQ(VJ-N-*KM뜟[PZZZlhd v ;C)7,3нǴ3~?OѕYr.޿˻9->wt ǟExCOC#\׶3>}7&uT4V76wts`;㛟+w߼~+ְ 4s[[sojzy"#bgy˭sFپOOi5!eU݋96/-KT]wo:]ͶT;Ϧ׻sU=[7Fay+/X~yDm;-渲?=0@U>k8vϕ+]~esMc4};n9.> endobj 1131 0 obj <>stream xy\+;u"dvE1AD^wiKg,E%F7F&&bg?jKrX~f9كH$VVsqސoޒƆL V`-oX5@mQRdɲ"xy؏^4~ A{Wx{?xDN_(ۯ_[yo@hGJA~EbaD޺jQw=,Z${sȞKCnx/gpۦ63v '9N2iۧ[13EMQۨԻ5NmPY$jZB9R#u35rSK)(j5MmQoScMrj5LS-Jj5JQ3^ToeMQ(j5Dj0KR(;_қZFN _IB$&ҖSz{> ²cڏŤbz{m}߶.ﻪ~y'7mbl X>h`Ao gQ[1xmF=xHP_I9ͣo1oq67ߛǷo?fwиa %ٔCW%X:$  G9L`g`ޖɨ*1-WkyvJp102^wҞ<.D.TKcYm%aBrVΌh$'Gcom{Ci9P P3BEYi6"Sw=rrpZ pWX蕠̊bpPȢVC(fnZ$%_IK6%=G-8_OЪ/HeJ|JN=Q~rޮLަ ׺nt khJ'm HK *WUeBSQyr9rYFx,A=o Ra/`.TׇTynsI?AG*լm<.w(=mb8ړbSB+ۉn[?r 9yJYC%ņǂX^Qa*\X*4`oQ j%h%o= j_^0Y`Y4 \39B`7DŨ7i IJϱCFu* EGνK v+h` |!1d*JZljDz ]w> !'-#-A^h:VfƓevrb8IpteCPj#izA6DϑɺQ`H0,IE?@{<<?s8oa9@`V_#59~,!=en-6ǎp7`4 ȳIĽ]a{hUɹL`|l*h\vN8 O酝XuLeG;{y`S`CKkYNB 0F"W/lIᖈrooխPPdAˆ*ɳl~:u{?"z(pMwR5K;"w,ډ'[M> ]#*qDS+_ 5~9Xs0?At / "=ZBh2~Ca-%BC<Tz^F.afEa+(*Y"-%]X<k]7Eo,Qy_wQH֔n>Ykdkwo~:sjz5ʂ,[]{F>JіlMJ6 &8\YT\c߆NkFq#?{q\q8ڋ;28S*tQt]b͖!yepe-3DZ ^"ԨE݁},CN{xﻝ}uCUҎ].O \w;T(W"4| 7%ʺKr؞P/X2_ b$Ϯ=ZlA- \0`*3ָvs[i?9BR*JJT)>bn֝"̚-1|ꭣuqy60JHFQWm*(y4_ASP>;܎rb32ʹo? 9ƸdƷa#5a[.;q/CO?뱭ikc3ˀ{GpNNˣi_̞@M55N6 (.͂ZQJ*- }VqjLC)<Y]h{05 1H tZAɯq?<𚣨U+jPWNc'F[]o8Z4xgYbHm]@ Y" 4JUbD+e#ƪ=Rw#P."خZӄ%)Z-t5 ? KMyy GĚ^J&hzIw f BtMtaÇ ~ϑ[\Ӎ.$|%<2Y`6 ( [/ q=6n["{Aq(SI5 P ٚ]<4$l{ f[.k0L>0ȯRef+%~yة[+3$E٠7.3iUv3"I2ӷ /1I^l.H.;dڵU8D gk |T!57֋څ4/7՚x&E9bPk!îZԄh]Ig^঍Id5(P0RԄ*j=pՠiHC ZcDCDt\B" *aYmy?ӗNYZjWX&^w\wdE~`ב#JJ.bcZRNx7PߡCDoġNO#xmj>(!"9$h})F6o쾽xw ,LMh<8OV}7'qL8 0>ċ.Ů9ARMbIĂfm^\du$lu@D `+;ԻH.$>P͉R溓XR ڎG®@0v`}H-EJƸi C|>CjNjv;g ޗ|0df3/tCԭ+:Z[ G_ÌՏ͒O75X8 u.)쌐7ѹbu%/J#BڐY{7Z hI5h  dRaFn,,;{?| G q c3A'~JZxMZWg$lF= :%TZm|pINqGV՚ItTxRT&dfJn<)x<z9;͘EvyʂH qCVh%ixlM\D.RiTex4t9,^PA]lNtQZd9dm,3 r8MUw>ɄN6S%_TpB,/34y@qhr>@ǒ_CG/=hB Ď`Y.9_2;7Qw{Gԛu͛r($UJ~+W YkDIіSlu 0`m}0\*lH_Tp H1&eSj`I_) Wh~ZX ],Q͂L?yNϣ[2ܨjJ6E pxKEu.Osak°la|Zu QhX,yǃDM7P 2ƸMy1Kn3q 37>|{K#M=\EҤ-x}A[ h ZP2qPȽ*bHTߐ :8FfD(_i$\\v ab\zsJ/t-#酂a_<)H5HZPBҟ"[4pclzj?g6EuD.0W,z\pVręo'muI/^eum՘bx{6ZK@~ed9(JSq -GaYVFq_]'x,p64ZP* ϺU3؃egr Sia?~;+ X( rGi@Js:)KR6#v>hK~u7KAUGH+aM8=yӂIy^~\aDzS֬'fK %@ pL"EG}TB#sݼq;Cykئ+ne1|`3g9osc>ixN*a-2wfQڬCW }#^ldֆHr\3J{ӭoXC% endstream endobj 720 0 obj <> endobj 1132 0 obj <>stream xcd`ab`ddd v541U~H3a!S#k7s7ˊk ~W"_PYQᬩ`hiiZXX('gT)8(t+@lv-I-b```b`f`bddY=)+:eFwowܚJ?ql5%:XkM2q^SxdžwT!Y9{܏l+{.)1iRsMgcy\onJl ?~b+onG?~p]>{E;;9t;i:fr\,y8Mb^)Տ endstream endobj 115 0 obj <> endobj 1133 0 obj <>stream xyXSW!7WU^uY{H!@$̰Gž"*jqVR= A|=D}'<¢v;v,25ǽOD7`u}pn0YC >nӞՁ`oO/͔Sm,Zf{Cb/wCbg=]1f6Ìm!n=[I6vnA8o^d*2m"=k<{n]m{ώa~vn w5iSN>c&|8;j's[>.E/!xbaO! 3@%:b 1Dl#svb1Al$SG–OL%v4bN8v*b!1Ml!V$!$(?1HX~`O !,0b/>1G0b?# &hŠXFXˉ1 b, OA\~跬y L W;ur!Y''<(@bW`=YJ-_(, $Ydža^ Ňo脺87HotXEV<'^"3^[ DΣ0 Ts JMVpbP2T٪,PF5Hdd eF&jPda[z'QdBmع[⮄d3rA! Q7] j0=&^0[Z@y)ScH:e@b=ʁoľ]-gܑZ؇O h8tH3hiZe+M+7o}n7wUq:O;Jktc﨟AJJ]w OGА' V}shWsݮ38%x-8iȂZ< Uvhh+ [ᰀ˔}ҐpTևכ c0nGBPkLЮ薄e>l [I/v. iYkA_)+}aw*y:k:xzx> ЅWňKW;`B|ڀ6~}h{qXAG+b5gџp"˾lzp%40`68B/L%dш_pb/Yhwks.tKϵݰj#ppw [ Қ2pR?! 1 DCG1O* 9Z"gCm`+Xx8J>g8/k.=@ZB rz)2M@wIA"K#e~2Qf*EսEAv.Tqe8\P:bOƜ_.9מ6 ;k=Xs,&=yvvKBͲ+ Gp8 YȢ$O<`\P[YxxG|F:7. %r 8wN/(`YZf"3&kzǞOtۺ{ۖ3o<(R ȍ$^V1i"mPU W?dwOFz3l+5m=HLFz*,4/xُ?yHbTm$oV@rWcwrY?ԻxY|g'A2/za9 d{_wڟczfZ/KpQ 7/ &ͣ&!PҘmqtf덛 Ӳ_%fF<PU٫pUΠUt<( b *(t\yMd[W*Pfi qJK*%;<\/@\jGoI+ A6PX(Hyp]?Ի0{v:vlAGǃX%ZC?<ڃ:plzY[Xh3islh5Ggv$obk2ɒhtag gtgcPM V'&'d BMFd89P>p*XEQ(d oS6op7MA 6*L(]%\ :+ꗯx=X]k偁bq``AhAD͂ixJ_=w 6s[* ?qluH v/]X;Pp/2'fTV]tqU}5RKSR5^GtuYI_]Y zO~GYS{s=C3Vz6TǩS7pVp:_Z7A7XVpM A¦!QnJq8wHqreef$J'g^zԚQ׆mrl>hw yy`VEc%UFR ;:P(eV8pV ߂pÇswPwú%Nfc?0.K63 BtKP7=#z|u Nd5s`WENDP'2?L+X?*T KA%kdqEÁBd٦EI4M_nhẗf.foHoo-MS-Jqԝ̍2UZ􄜸yΝϽfZzNag|)\ןL=\IbX6ILTEDY``xX_~L_LX>ǤA&'!T2:B||rҨT*1 #A+@ {}^˥uH)*ZQPJ2-.SRl&;9TPD[o>"y"A̞ExT/~m^/@6&eEԗ'}hYS7~λv2ޝ^wDICAV8&yAa8Tior-WpR>ajfQWkQldvu*(KhLɍ:\[]^G‘9nPk&G\V*1kp5r ksk ժLEFŇ&3ՊĔD -Vfir3}׳iUg5ueoO(-.8.g#y^#֬hv#6GT꒐ #Ru]P|p3=)H(V!? ]v}/Sׂߺ{ 2Q(O𢖞^sBksC5s;nTnW% pʊ/j:Ӳ(GG};(5u L ߽tBM@XP@'c?ml.k?aBt|K^xFHU:R%U*SUX-$QCqIq (Uy4c1q>ܸEq,d2wp_+koqT}VF4'Q#/:;ȹ` P0ڌ_W:Sr0ip={|$I|TN:V!LCm%]q<3ۋ.0)~ n`Dˍ Ň_RT6h^"*xYPɁu4*<&#$cm%YFiiiRUEp-Y&Д]ST2'EՑRh J5ىi$ٱ?>*E *ɓRR J ܃K$<Ґ!s# E d\px0E0p'X2yOtSAE'I"ܝ")@BI #J^=xTZJU{|Ň׸+C;2tR(2e\z'8GuZKǻs ]&}F}x?}tS@~d9G{Ur`yy n{)F/?[}=D~[݃^,v2iq'Ye ΍> 75V[M~kF>{DHp8r&2 B"ҫәf~ume>zNQ"7cIgeo %1苿VGT`-.TKpNa#&poe,`2lіWh4p eJ?@'ΝpedME/#ߪ ~3Nʕ.ǧ+SX_rB<;9;5ZW߁ `:lt^x>J<[t(ݺ_@!e E@s+=yνw\ˢ7_vG?\߲qņ8/-. {Id%$r,Ac::-Y0-oZ%?^uQ],ϐe{5X񰜖K2 +LHTydy(,_$X8`,"MFI sELC&(TQXll.ݝoo~z;U2QdHފiհkM[`,%zV1{s7{KR 8udkϝPpYt䐧(+\=DB@fEDerA endstream endobj 438 0 obj <> endobj 1134 0 obj <>stream xT}P-{m &"T'{jX󥙨Imc `$F'w\& p + S5ԵC/#muc4λ_:v9 wgvv}yyMa,xV1ilTO 24'nL\5DXY[;Nsq[w/Hc596]fwɺ٭e'F])+må`rDiMN]Bnmm-!d5'O'Iyl$I.yUq'sMdR-9e62ci Ҏ{+JSW폴ߦe=B$RVdHU*lj.~>@UAajqThs{ HF*GF:vBnvnWnmi4vh.34vtwTzgG?=~4i8Z.ZQ[ zq[1A[Xw&6Ҍl@?^U ; 8g7l:fGqXccgΌ=)q'eq Y,NsP-WGט7.'nND[PWK,$=+}raش_2Ɗvi_x/[J1XmHtI_]c]'IPӕ.e(p燏ˢYQޔ'0 b3눪yvOn&Ȋ/ئB8J_cg_A}:_n(vρ}R4!a9sEVjbH$&<%$c(%?p{cj;V#.!EO>Uf_M33esP r<^p@vmk Wxa>ڔ BȩeN8;3P>.L't4 dv S<9]8'ϳ6nťQ 0 KT.,g7XJ;1pt{bAv{m0ّ-I|'b{޲W_~ńujM-;ꤕwQU[ ^~bR?*&|So1ԘŪa ai,s4FP|)t%:-uM9I׺TBOԧ6r}CNM rZTT7Kޢ1XX¡h^Zb8<0QWg :He$Oj?@m@.>|f]HݰU; =cϸ endstream endobj 113 0 obj <> endobj 1135 0 obj <>stream xYxײ^!{tYzzĀ ` &U:rUro`L`@QHHB$Β|Y7w=;?3̊(H$,qpt:XaHCxKÅ}/WX>bǢ~V¼SPbhK¥#/yg9sa&ܵo`7ߝgz]nGXgx#h: 7inK}Bݤ#wI(ڴ.o&7^㥁{,]`x9ڇzoXsJӘƿ3a⤷9y{S"O]0Mp[gm{l9.sQԻHj 1CMFQ[52j.5ZK-QS1:Cj*5ZO}DMQ=5OmVP3wJj&5rVQ&ʁZLOM6S%l$CzQ>T_ՏS) j5FEYQeM9S<5b|jRPj5Nm&^"/mt+=F$>gn[,C*Y)ibz0>̵{e'o゚{_N:m`gyY*o6ipCZm6ێm{C36dﰬa? o-.s'|pDȈ{oo~;w[#7l㨭4Ǐ^9:qmPt\'bX.`[Tx< B>Uo1] }Y9|D(,[%ЁF^*>E"ۡ`MLCьo5*ӥd0Wa QadJT?KQ}ARnLAgsKlC-L'Ӊ  tTb^=$'ت26l2$T[FqHTH)-stWF:#0UҀv<=6y\ЦsY=у~W0W6]b:RJDWBns1]t( %pe>[1vK:ֽk.~=e2þ:J'vDlJS%pѲmvڏ'kAô (W"R[RwsrƋ>ç>?+Zwc,5 lYNUwcѶ_. P/5> $+hC-. 1Y ?ፖ!?2LM:J:ѵVjqW%1*:tWfUJ1'ҢFC.xP jI+1=:;-#!3>?!´!3,\Ҩp=튒@xP8~C~+3H$@r/Wo h6WʏAmá`*Κ9m" *,/o:,P;oٽf m=ҋ jid~L{{%2 i5\5JUJA娌H 2TNb94snT}*"|Fbx<[< z@+3Y;ۏz++LvXdwp:YC&MuuGM3yg!nH|=L-u^;aIx85u:y .6CQ1c5r@Kc7Į L C^|IˆE|y<W<0f̄ ؖǒ E$3ZbCouQup\4Y錽&@/7Why,0P^2g݊k]sBId?/LRYw9sv7i*k/Cnmg@xƚJ TJخRJ):Й4$a`n>|!8z}nI/--9|'P4 сKg0 o#k&C_n|,u+lڇ˸]#]9<\@MIgivNڌXzX~1j@_NTVrMq&M+W9}FQ)msMWPhR;T%%~ɪ@b>łv8ѣg޶q?ՃMSnẠ7u62@P YÆ-*|dGvļtѬ%^E2SߡȣPc>Da z}sM5\tYFǣhjȘB\zEG46jt1`f,1_Q:lQ * [K(8ZZڔs7gHeFIp 7=ƝSF_s}{|jGy+r66 &zFQR!&#Y:%-{~D0L @- 7g8xA3ǽr/3O6E[AG7l68=,Ma>nlB4NUC J'(9 + ދGrqK75e;R.49/1p'H">XݜϵU֒1ۓ`VeN b8Κ.&t6ʺV`ߩא)Bܠ]u)Ϛtp//3Ӥw_hSw2TCQډV 2}\فFRゑWG^Fي ..X+c: upr=Twr>7Cm t زm#b~wN`L1]әIQGę}FaBOWhf7_~׈ hAԐg7g){?)/o޺{i=TaљYTuSڻOr& eylYmO2H ) /-/^Ui3WUak C3koII>*UJPm:a[YؘE^!enC\wO<t`it7`pǻ4@nn>0ZJTD}+:cC+ F8Ul`C|гټ!{;; H6(2+̀Lu1ev}le|nDBn`Ep۲z$qim@y{n^֛ib AbdvfC “,0+Lho1YrG:.ev[FU _d֌ NNW?K7GПC{Ysd[QJFmO 0Y vzDBXnpa2 ݦÃ:"e| Tc_N@q`Ɔ$\reqdݯkQ= EDQZNꁺ0QN͸gz|~D)G(8O}ztm=3 :@0TȖT@LmW3.#- ;Ơžʢڜf5jMj 3>KyxY yWHa5%('6MX$ގ\bTlkPi6Yba8Zv@tûFq%K^1qFMg}^c #pe9IY2=9S~Rhoylآ3W tȃ4sotW-MG%iAs~D|9VfIQy^2 ֘# FZZ$baˁlznjQ%aA $W,9NleőeYy|{k͛k^sT[܌lѲY@ 7w;[nq[h'Op۸R_W o7u0X'g~ 6L`RWŢX53`crعg/ETB\yY뵫+*YP|pbɗg5heG6]@gu_$>E |mxnW6,f.TWKHy=-ج2=ݓq\s2/*p^ k`N ? W{]4Yjʥ#E,e||R\dK䅕9ڗA*H%m[ayY騈Nǧ6m.1l$l?/"6\ibX|T^BF $Ÿ=æD'(&>3v P+ %Ң.UʘtTV?Cu{Oma(Oڌ~݅&>X-Б?JF*&0BېVC?p;%6TڗaXp~ٟ*V#߆lo^B(6(BSUTN~A10:'櫟!,P g V$nݼǯ5[ ?(W K~0-&dj2+I _E#xU"ڌ䎢#ݣ6H[U JI䋜>p16I O#xk``Ur?\UW]eqVpFd I(W#)*.Ebt<٢*TWY<>FfO0u;,1TYN2e*TIT&/. n61`KRAlolBbs9FC%ɣC~aLO1g[~1%ϲ˽q sSҸ)wg(;PtWKBȏqNvUSv-;gdde"Mw4ZN.w}tBO[*d20`6$>$d{rtJRE1x^Â[/2Р:32h -\\C 3 ^ oIQpcizFn6Wx -^1o>OT"*F*vnX_q/C/GIIe_ִqWJ|2q`oMz9 Cs!]zنMom5ԄglLV"JAHR$~6Q(ILTgsP2mencV"=&sڠ Aw q;8<`pWgdd2\( .] ON@X? &ؠLgΔ:܍ߺƑb+S)( %G"al'b.WBH؛`O/Z}t 6z,*>1E@XÕr,>mts/h 89 endstream endobj 286 0 obj <> endobj 1136 0 obj <>stream x TSgoīRN:f܋K[uMjUp+.T ;!B@' !!+ !lEEZZ.ck}m7t {3ϯ瞜@ι>QĬ\bCBS#Be3 "! QZi2VO@s&lkɊM1. |MjvA-5hZd󆌷V=ݥhhlma}DW_bc԰蘈+ _I1>'5֣uX}iY'SY֧n=,y: XaBx$aj JSX'6p,3ԱWvUm}oK>W?._M/e)Vg%8N:~?,= {{dߥnS畴NQ&'X/؃_&I֪j@/v&!.)g)*3Bҗts}?XH[U9VJd^e <}=~ͺ~Ntt! [1oFx~3[T1MJg  ]-֦jsR[}*ow"$BDu vҥ})T_nǷp+F3=kn)XfntQ2 rVbxD]Fn6b>hKy&vSw0DrzLۂ64F6=mg3s ὚Bs+d(^ 3e29S!\()Cp94]^@lۏOae1LbxqO=u5$Ļpd_G_g w[f<D-.2^oRez3_NVdm\p2/]WBt,LJ]nWE[XVh]hK0Z t^ QCƜgٟBM2i7Ԫ^^ +!d9C k x.ۜKDž19RjҀdqt 5k0 id)x/g7L܏(8dXozAOd l&0˴R[2E?nݭvR,}[dž>4hjm̖۾ @e-Կяgd"7Xhkr~Ax+wNlC?W[ys$/pLL`YTYe98X`Fr'iᰦ%tgE2J :XRQ6@ v}#8o>cGOwb[ln^RW$(*|&|E=[݉t`_ZenS4}MY|)ػ)A׋]n/u=Cgc½v p/C_C(T$(Ȭj/ 'bûoRzGy)ٗN?Csל#>{-i_JD4ĐÂ객KAA^wnH)ZH\M*~j}ԾvB]`~M5{[E7oڒZ\,V9y^`TπN*Uٽ-־LJ;bKOz? KYJFb%cV0VSaF GeGO)vCTAL1W5~ 0&Tվ$=l^S,}c4,娓Hrwo :U*^q6ίo TM*>Էq[R[_pۚ;M8͵?#؃&rmx]`$J\V4,,1 R媬Ƒ%*`" yh')0G( BoH6:z,uϮeҿE7)lO.Ĵ9:ZqşG\Z-ՏFqO)rU(`i C6",ȟ-(-z&%88շlU57=(wJ!^=7l62Hvqq.v v0<| ӠGxvFr$rr`n%+SJSx XXPX/K6\56[*Xa"Njj2v$4rmmc/Ǝz5&h"< endstream endobj 111 0 obj <> endobj 1137 0 obj <>stream xUmLSWB{mf6p2dꦙM1c<}"Te l`d,&\aK[,~2S.@LNιZoZp Amz]gAt!;>1?KcWǿ pFqxSx'Q]<38 X$0aPI4D_H.'Iqe> k q^wIp=M1<41N5G;H#^!Cb'tIÂ_& HvtɊ,`u;>;>~,`DC |8w=Ѹ #EG=6'\(s'fq AH(h$iK]tR`2>4j#ʨD-]\ *NlHHkX|*+ڃT |+r}v(tb.9P`y> endobj 1138 0 obj <>stream xcd`ab`ddds 4T~H3a!s<<,s}7n]G;9(3=DAYS\17(391O7$#57QOL-SpQ(VJ-N-*KM[윟[PZZZ$b=;;w˿_QdźEWglw?뿗XܽxIIwwl%Eŋg,iT=\/La``[ endstream endobj 89 0 obj <> endobj 1139 0 obj <>stream xytga )Ei6 $$лC ظ⊛>3wݻ-0!@J!=$l;߷+ os,Y̝{ϽQP2lм&|L_&=0@zPnEC@\J2قe/KJNq'?̴sRc#¶^J Ӑ "b4GIHw"mԌH%%&kRG/OJNQԬesGlX>Wb^rѫ^Hݶ -fBMlgg&[~ć 䔩O=8mz35zDSPU $j5 RǨ`j5zZLMRK8j5ZO-6P˩4 j#GMQéT'j5RP{DJI$>j6I*5J y,!.x#เ z }nPܠPaw. 89ls̻;=b #<{ŹQzJF}qϺ<8Aաj̦Vn0͇6<ɖWuH{P"NT f&u6*Rk-Tû᠊`M0py(6fy``y| PӼN(uTMՃmJke RIbW#s ,C>2=,&eOՉ=P o-M_mkY[Pe nDN[ j0]w~a/E7C॒Sqa04<%T.% [Y^e!XDSi7,-Q`]`W&w)Jy $Bb5%(_ٝ)AiՋ[?);Me˫貗6C ӔIOFwmjٟmx%G&zSEMp9!rs~N0'\)VIXexMpl@me]\EhkfWm\PśMQ9TTp G׶JֹV79w@ᦦI%P7/,ib=o-N6׶?;VA L긅kViy{,?Ǵ񁴡\.E+Y襪ڞ߃`Q@!fIQ' n~і (0:|1*(o+G̓HHebUJ,bQ0_;=8 6-@J4; Hfv'hlׅ]X,3Zz%rۘay)*9w\/gִ>ΒfyNP]!^罂ӫL[\"M( PF?S~9am]&n3&^D'gR^rTB˷3X+ Ut Ax01-oU=1i$<#{<6i\ Sl6p1FRw(T@#݀nf߰|*t@]v<85#e&qRGvA.K>0oNG )P zTKQ4,CGC۫ij Y&y1a=0~z GEtw+-1> ep2\PQX]W_W].V)P!f7YUhV.iQpY h37oLD8Plc\?r]$B5$3U.oҒj} DICg3+a%;# ߻jt VާqP4 &mGSƢ8**|K͋xւÆ8oc"ߝA]列Q _7m;TuM-/A fr2F~zDj7n!~T#z-hZ}[[AB;O mZ"ԃ/r_Z}&:Qߟ=K=_ϹgM~ ]H"m]{mN>/N"ٌb ut.]o+9S~ȗQM5Ͷu\.e}mޟ23AfGyHhn 2|C-5fdJ>O}mWH>WT*,FUCp)b*_uóNOy;zQVrِ$6jړ#nZ>MMzGkN^G!eG;QDZrH0yskjM۶jcպئ5}O~2"R Q"Vh* f!̒O6=h ƩZ!55tyҧ-Fm=g?RTREBD)㽆nY LzBM$-+xW;X_Y6ה{\殘(h}Bk+XiI257(3e0=} (c!UGU#[ ס#g=J5_|F1|L.UX|B89C~@Olk %bѓ_jfM~t`bSٴ 5Jp< c[\QS;eGSlnǺ>ڝӘ]noKq-) .Ì5!(N/l%[k>/9 мn?nE\ZO L noF8ηZ6=pj*C̃zGHo{Gj;o̍qj|W-=;@!Cj[!h 21g(&`.\ƚx0O]?V2c_ L(XbRcje ,#h׉ŵvU̗c`<׼~ m)V8~U‡ $Ȁma%MK[eLl^Z NyLCON@b\OD!&V3H,t]؏E &lD]$ފ7L)H|ʥ#;ؒr lJdKhz #3גo~nC s&$KW^CpMvVW9&.KD)Ő&LD.4gZuĤmMVOk~}-~_^PnߠUdBίIT{˥=I UhM~ߕn zL3.e(Ϧ(ǦFtJ%z S~6s*vb[Go/DFCj#Qxʊbe#h+O#̅!hRQPjsVB/Pgb|sT h7~9|Q9nvk v-49$Dn-BklD*8 bT~7Ǚtς*_? GLgtg(N+TvXƽov~[<?QXBگۅռ!Қ曵N1r('7DMIi'"GWQBAۍ7Jo'VHa5Dy>?3+oݼmb.IiA 4#g"RڵaXAgHQ:ߐ.4fs`Hj i3Eӑ.џt>IHg œR`Ɍs&΂E Aq BM6)2zqo PT2:x6+7r$Ta|$&N}g̥ĬR8ڡ<;`. vǽvY*/|,7a~jWAu K.Gc7$fnz4 <̇ O{l`گ),MT{j:Z ?cẅ́os~v|[`D{j[vd œhNNK5eh--%zǐ.}OVyotַ4H#d5Ȥ;-Oxސ⊾ł 3Ш|nuVo( G_LWAd&d\+PzS'zhA2@k r]31oC/ Ǖ3 T!E8Pm5:/>~rz7CzP+R9"Sa6M7$G1Xp/mJH,to|s銳:6A kOX va]d5q}+Nih8v舣tKⓅ$6[ Ds%T 99Iɜ%lѰ;g⡤Wa1_M_ ޳W9koO{o{I\.4Em68&9)K]?soRE9x vJ:\݇k#cΐDP z sod|VVvl9̞דҚG-bW'ofz%]," ~OSI:Yˊ҆(n ˬ٢ooI-NIsFgE(gKZҩlDd;_߷p/V1gOA αJ\l*a}S, Gu|5j(#ŎbdK}`Mek)l"m<֭@m1Yq[N+S3b5UVoSڏMA{ZǽFԃT FW@mm8~M @U,@YNRd-5+Z PŢpzwޚ@۔fTE2̡FSB7x?xpz dM!*8!>8˽kD305亂W\5'&YڜDQTEǦC`l oN&4oG k[pUО{d>n k]St bv1&ѭHvάkιWGub|3H x.sI[[$Eq#xܸ8Y3CJCzˇHGC~8(CA?{}膢Za{u+ 7bfMV3vt>!&{nPӻMQa;݂KNԪҴƽ>x}]iiEب 1|(EfsA?>V+;!(4d̄BA+Tmr"h fFcFi0Y$l@{ k)o?ȟ=HupݱWسW}^.ؼ.\~_TDlji?Vv>0/ )+YSa3|_#6)j鵂ώ|F2 !\@w_>v=IKȝt] wfa&`pe6wvq iN](%x">$#tA-D\Ų6^ yXju(޺qΌͫįH y"o 첌=V4;QvpԴO,d1Kdݍh;Sj:JApiX>.hlTeD5]Hl*iL̻'?zmS?FQ=֠mh&fg}3] = 6E$;R/=B@~/ȥi-neޓ[m]3k#P\Ѫ)懛V=u~;x8Ƞ1+.wxZ3h乃4s+QF4bK{μ+m/-ɱLN_jV.OE9nBKh^:;]!Ry? endstream endobj 217 0 obj <> endobj 1140 0 obj <>stream xW pSB< I*vMH$eiJ(xc9lK_[-Y=ݷmɲu1sB! %ɤ-iv7;C>dmiv2h$;8NWWe?-<<2'(T>ym.q!/g?WgǸNQBJ\op Wu_rM.ۋ l~]4h9vM|lVjb[3A"JξK Mm k@VЁ̖6`6^\y[z Ɓ<_ niV_2ŀ3ssl#L.jι.!S̪菸hEEcC'.utN ;{qWsŜ}#gH3Wʕ ZƷO4 Dl:,Po3s  [/vo_]V^L9V mHeu[kB`Q99x-)uFi2c0Ut*s^"WH]xi XVh#oڨ[ V6}m;tA8䡡@ؖ5Gۆ%@eba!%;A bصg۽60ٲy? n&"<]SR!G|A'P>z`WQ1ɑƦȣL'~x:vޗI rN`T=ɹp2Eۃ@NWXm r=I0VUOlat}b0e<<>;;94vN0 XPl,8Nw-"#ݥ\x1^{\3 e Roin_hNaGvXF[gh$\^a2vwx-DIrYҀ{H2bmB0z ѩUB* 6C-HZZER0 ȩjl&7}T؈߫eo~ܹ >ĉ֨.V8n\$EJ^ >F>J&a?5]1=ˬ}J4!o0YYf> DHOw}ql&?`@e{ʔm+G9(8qţU7*]xph$F:-6[ ׶40u2u&3iݳ[Tͭ|Qgll?*JQΌK. C5,10*!Ȋ[^q˟ڌkWk pmQ[XH h)>hq3DY,bZI7}[ڬeS}7C,Vi<+ɪ۩~'=ƌۢFV*\ח[ y^BuaOu l]jdʆި] Wk1AK{cBf^S]$%ϴwP~V╦ӎXRx\ ҽBGЃc7szZ0unU/Ġ' % g:clZ3w\uicBEʓT`*gw>?7e#K׎g?Qsh=#;vDⳉуwy "M\~s?f^@ =jS6l+y+u9!鉲)_hߘ8!:)!@"PÞ1##X%kF cci?ne׾ӗ;;2Om 댂Ffv:%=@c:Q 1vg]4DesYܨY&WjQy9fa3nu 팸i2Clz[VHVu}zuԠRd ثlI۠5 'O4)$V;]v[qVΎ>[\ܙf/-%јGGqJ ; f3t'o efB[)ڰp!ڕ )K&/Te9yjcH`n@v غ醮rX e5n];ʿ$Դ%wQf$z? MnT` * ,[Yl2fK@*90[5CMMS`*2L(l-`׎ִ!xiID MLj<{F+;2 l9qq:Eͮ]'$fo  ^矛ur9uU*hVh)x1QXԼoPLǓBEtfm|\7o rVE;0% endstream endobj 82 0 obj <> endobj 1141 0 obj <>stream xzxTe CC94iRDDD 54Cz/CzL3%3)Iτ@B 1tDE~kēߙ$]u.=1t7l.u3я4/NN[80jgҼQcr }-xiTAnZ|l\YgO^l+#S&oψNH-52>:#wIIzGOݫSi7FEvܔ]WF~} zOК㶮͈߶.3awnI5{y]pŢ=dc//{q$A#{ b OL#D ",1BF,'Ok bIl'Yb1Il$'!&b L"sjb81InQF _OzsccWd*/d !'|ꥉC'N5kriSSvOL7~4mδ?M>kƈ%3f=}}f~I_Jw9a3_L@ڸev(2t ޠ# \ \9A J!Nk˥k/iRyTv %`-Y\B*GF%. cIv/r@o6mZx.hY;mGW”qjFR-4衖@Hc Tإ rm<`5[˪:j:;Hõ/g ̊AҦVV5i*)䇨,j:qkxdUwh>l̝n73%vs}zky첕wWjjf-1A)Yo-o iϿs 'ҚtFRgv,EV1E<1?F[* O&xDZK:xݮ:.VB\OnOuI wsRBfq/rPZ3MFw)Ж58>Q]hHa$-WA>h&JJ*d騱Ziיv4zȏ,#d' 3s"E&'u'<@B8_̧_eϨbK\aF3ab7jCCnf-o"Uua-'X;1OѓiڥJF"V[rGZWϙojӇ<vR;#Aya8Zmյ-|PNZezyj Rx'`c=m4AR87ž Z>]-zhזe:Yt x֍ g L FT j:ޣ \6VM'e`ftZ+WGꧬTy$YjH>GOr3A\Kۘ[ g\_+n. UbMnIenlփnC*O˴V-bW<9_F oS.Vx%ѭЮj] Ūe e. `xLz x=ڤ%/?ri6xhtCf֏b0x)H}ES04Oud6}'v5W_?0g4v_CB|FnL38uVWP)S [E|-4*ȕajKVWl-pA-9X`ǛZW$g_`l۾w%HHLvlu]<4ۙ˳h|EJ:w0Ȇ|s5А BcT~x1!ן,7@<+3)ĺxQ1'k,rx O˜Dl~`ᇈklBVRDQQrb\Fu2J% xuv;;G+O=-Y*knn[:e3[~KNosWz圾AKꋵe()At"듀T|ҧՖlȂ"L-em `2yFcd> R U\s}u17~QXU;oLhN'0!T ֠5i,EԦa׷`L}oBJ8nB.lNbWc6K5h4w䷇y"TWzm.Ӄl;'1( YZfT]k-w]`̵R0aΫ8 |W+F\-hϞ_Y^=zȬ%PvBp d&g@NM[N]qyUK8[f\r Ka`d0rIiMPgDU4v|b,ӫ]7p$BŗƋBbA9zε姥eDžvf|ݎb[ke!?wuzƢEKgط݆:kPpo:1`v~:.jwN>&t6cb{ *iuz++LFV*nr2M4Z*3ɮו7_8(EʒS9kr2_暋Hc9=Q>EDMZJ5 M)ZCBZ9P~_,7O"3z@Zf;O*jgm#!Do;1 v,]P.aX Rdͩ-8`Ox-vwf>%>UoFsE5>r3j3&}~p<+5/ @I ,ŕPFUMFE۷*(l08yFIa4EICPP6F{ʒck?8^\L_E^(Aߡe?ވWkh`]*{<{9: @Nj~Y9p+38`x4\&? T=sT>uUJ2RB_}iE(RX tՕԵH?$y73vVCkAEeI]OMh?ZkuM77躸$/}$ 2ϸir_gem-:3~5AW;v)30{ !v=ۯ\gPlٯ/h**Gw\WBUp-ާBb{ZjHQmɉl%jZZ_e< p.cW9}$0Ou(gَYbro0Շ)azQpKLSTY4 %԰@]6Tw2Aq'S߿@[ݱv0Τ{kK..pP V'o!,綠Y$YQb%ܼAF]Ͷi|w<ߧR\)7խ@ sÚw,zܱ7?0A4O"xM*Ֆ,ioU◭c|3&f^<;[ccz _cF.N$q4CP_h%W2:hd[Y4᪯h`__Uh4xCEF7q#M*ܩj{n.A5uq?t %;WWRCO.g Ew ՟ð-~huHsA>h-:(*f$Z jVDz1Aٸ٠yn06gU`Z[14lVR&S^yn.+,'.`$TWs*ƍ$ a&EXLL:@b9 V54;]P$]"fChۡSՆA7َCtDC܂sh8;TIHe&U}@4uk`<&e,59%ڒd>rnj{cWAުN-+Y2P8kʰY},`r:.j٢]9kq U*sH+q>,kuU:GOb7p">C/omOm]7 ;! *H!_vCL@"˛`!ۛ?wn/̌]&B&H{kqǣ!uxݙbG_qf7[tbn}B PاǛF[^/*RȒ}19n W#mitXVwsMmvI*^^{6ʣKr%A[xh5%,UBR@xl)sׂl7; -M]2hC%1mp:mv͇3/!"Ed$F~@/ܶ6L^N 0 ^{t7"wLJTdC㭮0rP(YZ^`Nx*1muf3#yڛDYBCt&&<44 \ɓ&n~њpFIoS0ޣ{grz3kw[ԩFf2|@# ]A:Jїo<9oU1*nA=̓4}OUӬăFOs~BA lL:ɍÛϟ!؟A)R9ޜ|AiyĄy͞7Gb0aGhE9D*WQ}GWgli 3 zÜfd6V/r=հLFO=}j-${OK s}tg@N޸2=6ܷ{WcB{yarzyz,EVH&6ד F샌QA*DY (k`īr迾&z.a‹}_0J,PFs+z/ SH ݰQ~G4c:(wh, U|Cׇz>[ 'V#gL]W}dS]J),2>15%[^Q~G_]/ae?ܧUhswYa3'kӵd<%Ds4U[=B\O" Bt >/"Ȩv~v|}rQ wUbJbr[b5 8$.QTKvvҫJ2La(W4ä WKJbй4_DQB;|uˎM`ZLZBVv3'N\R)5j*eK):%~Z¾Qi^2MflN]xӊME+nY3c|ވmECK'\=Bo=FD^J 뙩?iC"= .p eК IF;);m@Ϫ>9rEpA-ܫ -'c-jz ;*] y^3SќoYao}nuio}q4 tf|Tx Bo~xeGRMWbis2 pLU|7~4\NP7s})×cDpChΡώz6tunc\]mD>U]h`DxCDv!~Cʗ&y-,t4 MCSK=o%/;?q: tAM(r|׋r5}˓D/wvq)=o䭍쐙g:Rm"$j"ٗ_ʙ ;lCzjTԔ]GQ.rڧ\ # [cb}*gx5U9/v+xY~_0 YxN}] }WnG73WƲplByߖu`of̸fQq g8@|nJn?޻1/hQ3xv; aaPlxڈ&֟ݝTްa/zozA*Úa#^U+5>)1)46+g9 :ťuחe{SmBin"'|[][qsUXxxrL!McǓ{ZJ͎ƓUEXRIauUc!m٫TtKA !Z' Q taHܿ.hzn#!w-peFq:_!}}`i78P'LՓz|9> endobj 1142 0 obj <>stream xX tSU!%PEEq*ֲB}Ifٷ&]-BEAeEgSq榾~ǹ-(|z9==Mr߽paEYb|ބZ^p܉'>7 9ˈ?SM@ݭNU ݼr/Txm|ݚVbNFfT *ߤKx`6;+AIvXBdR-TaKA%( H&C.`A4/'ϺOsÁ|[)(I$ Qۼt\hvؼPINfJ^v^bu}HטHۘqO>x]hiRi cA&dՍvsXJiXش~oq4"pL' O>?E|}1.{|=?j+.:m#ͯNI]))F-䓱nGS%{&CRʘ Zf-㪦+v#.FO\%>5RY'.'IE@OpNU^ 7YQkLzQn\Xe$ZЁѨQ]87o: xCP=x1 ﱻ^ Jn\Ld&11Sf͍Oށ m9 1)AJ3yyy!Mȗç &sI;w5UTW 58KWL#b3)PRP31Gq4r-z:OpW_zĬ o5.ZtCP,JF9(r>. e^iPGkB[p} f,C1Ӣn9^Dϑo& 2R"H,f5HVy I½[oSh & rio#wMovYd0Y L`{BZ8z]U/4-HVf b  xgPFǍXl] mSDV:{E^V;j^4|vJYP*&W^y{wjpQX[]?#f& իܯ N:gC7\BoXkN4vʪ˵ǹӝCVIS\~)J_خ,/K&(3ye#JzZݕMMo,&>{1'P46ڣpQ棏y <3ȓDfg)~" &qm'=x20Lb-H'Z!tJ 꾫4Ti.sr3j`uM-Uҟ˿5oK^O6A7u@)iZThPU9PSs^oVmgQYnߤy|Ė dRmkSa+1Q G>=ƤTiCgjثeS3?%J Flg!FƮs9-Vm9,ڂ& {p0 scʌ$}'~]bt`ȥ0GXν^,zݮ%% N5Ne0BWuo/ .+tҝm <x˘߻W$pD0~Fp~VaFN@寭 RL<×mL$2R`ς IGVS7<[VĎ-'wP-׉n&a]a~-FmvZ'Ҫ^fR&AJ%6KJ5`,+ABWZkū`4@6̶Vʊz8Xk `9HHxbQ+ëC@B]+s9ת6C'z3'ߵ) ƦN G!uŃom{nWhT@ Rv75t %L+d7d+f6xggQanX&&@]P)) 'y~g~c( D|9f@R;z3}lERQ{`+$0ܢݫVtuYOwYjO8lȗջ5,6Ad'(sKc+nwԑ;0+PB<9qT. aVۆś( k 6׫$ ۯkqu7Ե4TQMM7#8kC<|lnҥkt@B5m%^!*NxwEfզrS[2HDSAdMR_W.VaZfP Z_W+MDp%\ s>&Lg̅A9]/j# {CyA#k$UғsښZ O^oC /W|r4/QB!h9&Mbӿ}l™1Ӧ{Wz;}>a_Bmg3FMvl9\#kk5ZѬ)ʮ=9%;3XϿ>ؑ&_p %6r3> Gޯ`ߝyu(m?1,&Tu߆aaG\®1TW~J4ekrH&KƲ+(H_P3sS©oo#(Y.Pg&q=-o~5SEf#81r]A/(t endstream endobj 80 0 obj <> endobj 1143 0 obj <>stream x}{L[U垕B6r uH` ۰8Ύ<+v}dA9sѨ̜YFq, 1ctcvn=||}rFs0YnpЈz (oX 'ᘭ|Pg,/-3"QxYJX^TP%S˴f>4r.ZԾ&ZkԖ+ (Sꋵ*Ho,5* P 82JpA>hR. Y'Aӻ7)e&sM_jn _Y><̮G 'EwLzw`)ѡ׆ְh_|4%"(oRb]]3%qy,YSbVa^md1"r=8o|w څ|}Rƻnͺqsn8[^&g]ao #'6jCh>z#u>DRQF} `Y?e>cw TN-t,T"> endobj 1144 0 obj <>stream xcd`ab`dddwu041UH3a!-fnne? ~%Q_PYQᬩ`hiiZXX('gT)8(t+@,w-(-I-ROI-+H,J䤦 L ] @_T( dX3~o#ߕn8ze7G[Kgs{oG3V[~/2ҭ׭֤Z[!:"yRYN̜.;ߋ9ѹPwhwgog_;K5}~}>yM1&ԿNN7oݿ.vjg1}.n9.|͓xx endstream endobj 181 0 obj <> endobj 1145 0 obj <>stream xY xSU!mQE *8ꠀHA(첔.t_6=f4i7[ D 2qQg޾;2|ɹo+ Ǝ!ظs[gL^a:guH5& a{÷3)h-H XjĔY^ɴ͝?ie&&gM$eK6d'&IdL{.#cz''&%>>6;3@7-.;1)/ko|ff|NJ=Ix Y,+aKܒձ9Ik],?e Ԃ=yzE7?0 Ӊmyb>1N%ezb.1@,'/+ljb#"XEKVb5KBBK,(>7b<<#@c؇Ǎ*JO%%knz'ym3,r[o{ⶦ]QӢ`ꎩWYqߍi2 /xK@ K̙@jPpB28Pz#ȹmQDzʑOUёQ-`eDY`0vʨ+PDs@eXpL*r hG84(@/eQ %V!lFڙ m^UP{Xx$L>P2~0o}TbP&^=4K1D^UtxmEp//\|Jo(2'$@i0RUl2dUTY-UQ:C/jr9;QKWEq+t>|4A/sdnJ5UZk=m@:HderީmF||[¦ԤP;ݕt!9$do|h\#{3btV^9!fJБ2S)9d7;Ͷ-dM"_s&m(M$F9(ȗS]D.0J`JuT ia4h\5uZg10@'vbJwlOxiRVZhlFwt24>Qە`%uUE\k/++)5̯Rj{^yyn.7Ќ?|iZR b8ȁ\gmomU!''\ A YQSh;0XxZ\?g7TęqwЦ,ph労:Q޶-L(6!LuB71 A5*6PYQ~}յQk\QK Ť s<$d3W jz9k0$^] }k4ve<3 *{ˡHceFi  jf\?oEards34%#ȥÂᷢFN15ȅh^TR9hЕq-JP4Cʍ2qnH/ UFDzX$Lr8 6>7B=`n| 3Fd"V49,`P׆΄P7믯 oXАCЄ^Xw!7UKҊ$H$U2~$~vy?D#J]?1Ls+⟊Y։> <;fC&! 9ůoFG_3hJGen/,ɇ|W54 xPg:&DgP M wSҒ;ĤT06_KU/*iުVRE SB\U  G}s0_-}s.7LǼ*Fw# ͢ W!޽++hy>@E#ǛI,"C{=гbӥUbJ$_aFI1Ek83a'M-ܬ9x?xr~vķvlwxO2_dS5-~zOxK{JZz4 >䛾ZAkθ!%CL*z۴aS!Ŝ|8 1n(.7PWY TQjoSy%RVajɥb::DEY`*irlp̻wcN9a ءbbFZH'; \Nݞ?3R@$/[lê@ν(zl=7t}#ʼnE`IXϼ`bi)f'a7YN5hv)WRxBF4C e[u71U nE֟yvi#RSIF/O+ƪpdOmڵixYt{Z2+?dwz&$8x[h *7%ӑs#$[ bgX_p?xpIw_Vy!+u?O-Xi YTk@r)\ 7qwvtЪ4nFV7r,a'TPd39iFnB/tw5ڗlFOfoX'OI+0QUH zaD_|Yt]ߊǍqK +%) ۥW@))B]wI]%ɤ2\v`aZPc!Zy :hvv@Y#Hs vzω*T y'Vzt S3+1tVtDƾwͽL쇹Y !#~AP=c3YYFģ@~*?gYb{;ר1D;` 2jce²!Dz5P/r1˹gfL~G}.#i@ɤ :#QhB q6U3T2ɣ|DZg;k9>ܜ5? F Ή:fmDϙtM2=t2 h5E*E5J bE5:Ol5Y=*Gk9[x67+ȇ\-hOomRJݷ_ ?^E/#鑛,.rW2GWO:SyL9‰C.5ΓC^sH!v6;8&V*9鲄=E[/?XAIf6WW -eȲ*^ 鰇yӄI;uhJ(T'8rP+ȋ61zz-DO܇xr"{k)}H9 ?DnƬWtFϯKUڠ|9 éßl=.".~qE vq!7-\9`kW^\m[7`PaOWOoo uѨӹLMY'X>Fg?(1ڦuiFsT*qè JdO4߀gn" P d~MЄC^8I;klx-S&6KX0Ѓݑ lcQ j}=E%ܵRi:<\SܤE/tuH֔x s3 wHF7uH*1˺˹ב`>䕺# [.=$KԆ\F0 q3/G#Z9++=>+xwmL6G+k3;BVԽ8AjZ-s__aWM Wmؑo B!t4|[郶w^Vl5f'ۂ y !&dYb")}.XJ*=&3ѿNTHD7yK|Uo[qՆRuVBkUɸb@<*Fc],2M^&ޅ[qmqBe_GBn TWy.l&3KL.ku(}i%n6`YԒ H XhRGJ&0ǢRT&gsc;)@><} ѝkov_d`ؠ)!ڃ /я:tkl#dSTT"98v7KZwfP?K&%&$"n\ܐWpCӢ$**5_m 0h$zCu?U9O}&jY5_-ϧ"ţ$'C&5]Ӗ@ŀ{e> x\wcpeĈf=*ہbQv[~~Uŏcy S{!#PA2%ZT?t\:j6;l: 7) v[\AzGу_&`OE2sQP yOzƄ=ly?B|l .|rP ٺ<AXZ_꺔M9wf 6c='MN͙:"vպ4$.%~hqH(YC y;8qf<@~9u<T@M{!g%-mv1&;fdCSWkzMB7BR)6++??+6a8scC/13-nS0Z_q =NkmxeMDbu-(0COEtbnWhʩW9>\ȣAйuFW Nۭmp~"VGmUX_Er;HJPY>  q0~itZPlwq.:rWpx$`@\պbM]$#qoj^GM5` &i`O*hAPg'<06YɄWawu)7;CA.>|\p>iE"h.h]֐ߣڀ;vi潟8m^CsDp15hY;lĖY<ꏯXRnd&X?ȳ s817{ոIFOw!_YCH)a#Plxw<&lFt~dźkEg)p|sǩǹ;JP^j7A;V.5nPl#8ە* 7Bz5IY Es^oY -g>T8;hggj9z{KW9mг!x  c N6iA7X endstream endobj 164 0 obj <> endobj 1146 0 obj <>stream xyXTGќ{=vc/+V {oCgf03 }Ă(],1\cX!ޛ?G]z׻=(Hdxƙ/#EĀտH2>bӳqz MQP4n%ں8 0*kgc,&Ϛ5b{POw?P򇯅M{h!C܃wo^l&`{?EQFmY(:`ֵ- X4xύClVmZ*vuݸ&NRKM^P/2{⚞=cz$H M_aF2;kF{?쳮ozk0d@@Dk |2hɠO~;Aൃϛ1g!!pgzo[$i/2io"ױTzeP`5Ј'b7Jdx50$)_I7BSnA(_a(`.oe$xH;KhE|.̛?(ÛdM/щ9+ش|yv4D<9-t>2K w7[}J`7Q9cTA:,"S3T%9Gke s?; 8ɴdJ4m ٲ nX5@6cY ; Gb~zVi1[< p!Kڂ?9](PHU,pfPaJ!dƼ^UhG3A8laq(P)3GKK iVFE.2°x_'yn֮`n"b>ft?9l^G$J"QY[ xV_=z|5~nͤޯKES1ߓdCAFJ.,ƃ^Fe#ꕗ4eK ; 5Sh׳O@TmV,ԡ[ 0PLP IVEq(ONI\3l65陠5+-O`IBκ-#r@ 9yEhzOQ|Em@#Xm#D\u)[hmӲS+{cz1ŨxG"I װOOlk&3=0yJ)^Wue!RcH:z(;]ᢒҢ! *))>Rk`f }_}SP $/mDЋ{-TuLt`~E$?}sxS`##^䨀E.h_J`ם1=eDFdž+stFT~Q|%ƢIW̆Il([W0aջ T HLךd|Q3R!U6V9ۄsWŀQa_P7xP<eo?x={+Owr n&`'p6[O.D=u.=; Ɉ ~Q(7x$Ty=vx֒H):qosΘCT9Y&Sohs#!/_jz:n@[t__=d:1;oh/o8yg]蝩_DO^0-`x7A>EҋakZN5[Ƽ3UA%q_h1DSWQC).Ei*b>ܽ%MjDA2ȏ&Yw#AAb* LQK* .Ō J$U* 9d(`Nts'B%w 0'#ws9{]N'L<:t<ݐÕW䍊0DEZz鵴fL͇L0C6LL|AZfY^@.m^abtU|vY[27!8b{S9eeJxHT<3f| "O}}}=" Ë"" "ʂ ˌj{LK&4;[ Z=za~s{(>V,p+p%'m չy>ӫLc. +yOxxh%u]ܛ >_"72y"e0A ݪJr[H0_i1FyJMz.yf/HE, rs,3VTD j_׸AI("hrw&K5UkףÓj>yX|\ۤ }VEUKu5aZ${YR_z||T L1CsZj`rjDƄ{\;vVS.\A\2upI?]EPOGsT&+i RlymzBC@=UDAl `9("wDf"wsԻ2 ~ֶ?^Zh ZY Ud!; 9)KHKGF/a3Ρ$r3@fI+6.Nw}'xQD6|ųچ:@Ka[ߥ !>M&^h6@x5*y7 $fP)mpitmp38JA>jRg#lEP,+Pkjkk>5޺PrHN 䄜-%:aH _'(',`E]ۨ[caY| {{zK[6_6AhS%\juo͵wW’ڦֲC HPCmwNlwpJPȍɎ/YOL2=xL32/8/üq޴w yt1i @f&-w%Y(IڂnI¶ehh]!Kr$ejF}NEWX^V Nu,V_F1jEKq-td'H,FN؆0}CyeD$1ѱ &L~bN|LLau}_v wҋ,jwGl**B V{ A/d +''I%vW~x : ~'Fș-*l6\8~ aPQ)3w})e{oW{rQ;EV+2>؜Jjr_<"y,25 bH縬9:? L{m0lv O鞪 hq?!rj9\zG~2w'b+z]ymOAk>uK]LK]b~d%3q)nv ]xz^/jz',zI$K#|'ߞhd?^[xKn7{Z idA=ڎHlay" ʒܽNRlͰ/DW<;reCjxu?]~?g(diqBQqX̟m8~u[v_%yߋqnZ4j0u!Q O>ACcpr"g56=\sjn]+\ڕ2{<`:½]{{{IC2'wYXikjB i]=ې~mVfqHA*Յ( G]riC^=gsO_ȊO endstream endobj 1166 0 obj <>stream GPL Ghostscript 8.54 PDF Writer crypt.dvi endstream endobj 2 0 obj <>endobj xref 0 1167 0000000000 65535 f 0000653779 00000 n 0000803669 00000 n 0000652014 00000 n 0000615683 00000 n 0000000015 00000 n 0000000496 00000 n 0000653846 00000 n 0000681583 00000 n 0000725596 00000 n 0000680768 00000 n 0000719557 00000 n 0000679683 00000 n 0000708621 00000 n 0000653887 00000 n 0000653917 00000 n 0000615843 00000 n 0000000515 00000 n 0000001246 00000 n 0000653969 00000 n 0000653999 00000 n 0000616005 00000 n 0000001266 00000 n 0000003248 00000 n 0000678724 00000 n 0000700504 00000 n 0000677899 00000 n 0000691401 00000 n 0000654031 00000 n 0000654061 00000 n 0000616167 00000 n 0000003269 00000 n 0000005324 00000 n 0000654115 00000 n 0000654145 00000 n 0000616329 00000 n 0000005345 00000 n 0000007271 00000 n 0000654188 00000 n 0000654218 00000 n 0000616491 00000 n 0000007292 00000 n 0000009310 00000 n 0000654261 00000 n 0000654291 00000 n 0000616653 00000 n 0000009331 00000 n 0000011398 00000 n 0000654334 00000 n 0000654364 00000 n 0000616815 00000 n 0000011419 00000 n 0000014152 00000 n 0000654407 00000 n 0000654437 00000 n 0000616985 00000 n 0000014173 00000 n 0000015665 00000 n 0000654480 00000 n 0000654510 00000 n 0000617147 00000 n 0000617246 00000 n 0000015686 00000 n 0000016740 00000 n 0000654542 00000 n 0000654572 00000 n 0000617408 00000 n 0000016760 00000 n 0000016948 00000 n 0000654615 00000 n 0000654645 00000 n 0000617570 00000 n 0000016968 00000 n 0000020258 00000 n 0000654677 00000 n 0000654707 00000 n 0000617732 00000 n 0000020279 00000 n 0000024999 00000 n 0000687889 00000 n 0000786455 00000 n 0000686750 00000 n 0000772667 00000 n 0000654750 00000 n 0000654780 00000 n 0000617894 00000 n 0000025020 00000 n 0000029484 00000 n 0000685747 00000 n 0000761147 00000 n 0000654856 00000 n 0000654886 00000 n 0000618064 00000 n 0000029505 00000 n 0000032256 00000 n 0000654951 00000 n 0000654981 00000 n 0000618234 00000 n 0000032277 00000 n 0000032983 00000 n 0000655046 00000 n 0000655077 00000 n 0000618398 00000 n 0000033003 00000 n 0000033276 00000 n 0000655121 00000 n 0000655152 00000 n 0000618564 00000 n 0000033297 00000 n 0000035554 00000 n 0000684884 00000 n 0000759040 00000 n 0000683751 00000 n 0000746667 00000 n 0000682802 00000 n 0000736542 00000 n 0000655196 00000 n 0000655227 00000 n 0000618738 00000 n 0000035576 00000 n 0000038094 00000 n 0000655321 00000 n 0000655352 00000 n 0000618904 00000 n 0000038116 00000 n 0000041603 00000 n 0000682027 00000 n 0000728079 00000 n 0000681043 00000 n 0000721198 00000 n 0000680380 00000 n 0000717798 00000 n 0000679337 00000 n 0000707659 00000 n 0000655431 00000 n 0000655462 00000 n 0000619078 00000 n 0000041625 00000 n 0000045048 00000 n 0000655593 00000 n 0000655624 00000 n 0000619252 00000 n 0000045070 00000 n 0000048507 00000 n 0000655703 00000 n 0000655734 00000 n 0000619426 00000 n 0000048529 00000 n 0000048808 00000 n 0000655824 00000 n 0000655855 00000 n 0000619592 00000 n 0000048829 00000 n 0000051618 00000 n 0000655899 00000 n 0000655930 00000 n 0000619766 00000 n 0000051640 00000 n 0000056022 00000 n 0000678513 00000 n 0000698576 00000 n 0000677708 00000 n 0000689647 00000 n 0000689059 00000 n 0000795142 00000 n 0000655998 00000 n 0000656029 00000 n 0000619940 00000 n 0000056044 00000 n 0000059154 00000 n 0000656158 00000 n 0000656189 00000 n 0000620114 00000 n 0000059176 00000 n 0000062186 00000 n 0000656331 00000 n 0000656362 00000 n 0000620280 00000 n 0000062208 00000 n 0000066404 00000 n 0000688471 00000 n 0000788549 00000 n 0000688210 00000 n 0000787803 00000 n 0000656443 00000 n 0000656474 00000 n 0000620454 00000 n 0000066426 00000 n 0000069604 00000 n 0000656605 00000 n 0000656636 00000 n 0000620628 00000 n 0000069626 00000 n 0000072720 00000 n 0000656715 00000 n 0000656746 00000 n 0000620802 00000 n 0000072742 00000 n 0000078535 00000 n 0000687366 00000 n 0000781740 00000 n 0000656829 00000 n 0000656860 00000 n 0000620976 00000 n 0000078557 00000 n 0000081966 00000 n 0000657019 00000 n 0000657050 00000 n 0000621150 00000 n 0000081988 00000 n 0000085071 00000 n 0000657157 00000 n 0000657188 00000 n 0000621324 00000 n 0000085093 00000 n 0000088508 00000 n 0000686336 00000 n 0000768907 00000 n 0000685493 00000 n 0000760581 00000 n 0000657280 00000 n 0000657311 00000 n 0000621490 00000 n 0000088530 00000 n 0000091680 00000 n 0000657431 00000 n 0000657462 00000 n 0000621656 00000 n 0000091702 00000 n 0000095334 00000 n 0000657593 00000 n 0000657624 00000 n 0000621830 00000 n 0000095356 00000 n 0000100082 00000 n 0000657703 00000 n 0000657734 00000 n 0000622004 00000 n 0000100104 00000 n 0000103199 00000 n 0000657852 00000 n 0000657883 00000 n 0000622170 00000 n 0000103221 00000 n 0000107633 00000 n 0000658001 00000 n 0000658032 00000 n 0000622344 00000 n 0000107655 00000 n 0000108996 00000 n 0000658122 00000 n 0000658153 00000 n 0000622518 00000 n 0000109018 00000 n 0000110889 00000 n 0000658232 00000 n 0000658263 00000 n 0000622684 00000 n 0000110911 00000 n 0000113424 00000 n 0000658331 00000 n 0000658362 00000 n 0000622850 00000 n 0000113446 00000 n 0000116837 00000 n 0000658430 00000 n 0000658461 00000 n 0000623024 00000 n 0000116859 00000 n 0000120424 00000 n 0000658566 00000 n 0000658597 00000 n 0000623198 00000 n 0000120446 00000 n 0000123480 00000 n 0000658715 00000 n 0000658746 00000 n 0000623364 00000 n 0000123502 00000 n 0000126587 00000 n 0000658825 00000 n 0000658856 00000 n 0000623538 00000 n 0000126609 00000 n 0000131220 00000 n 0000684354 00000 n 0000754737 00000 n 0000658924 00000 n 0000658955 00000 n 0000623712 00000 n 0000131242 00000 n 0000135160 00000 n 0000659086 00000 n 0000659117 00000 n 0000623886 00000 n 0000135182 00000 n 0000137851 00000 n 0000659196 00000 n 0000659227 00000 n 0000624060 00000 n 0000137873 00000 n 0000140004 00000 n 0000659295 00000 n 0000659326 00000 n 0000624226 00000 n 0000140026 00000 n 0000143826 00000 n 0000659383 00000 n 0000659414 00000 n 0000624400 00000 n 0000143848 00000 n 0000147335 00000 n 0000659545 00000 n 0000659576 00000 n 0000624566 00000 n 0000147357 00000 n 0000150192 00000 n 0000659655 00000 n 0000659686 00000 n 0000624740 00000 n 0000150214 00000 n 0000154158 00000 n 0000659765 00000 n 0000659796 00000 n 0000624906 00000 n 0000154180 00000 n 0000157424 00000 n 0000659899 00000 n 0000659930 00000 n 0000625080 00000 n 0000157446 00000 n 0000160406 00000 n 0000660061 00000 n 0000660092 00000 n 0000625246 00000 n 0000160428 00000 n 0000163833 00000 n 0000660171 00000 n 0000660202 00000 n 0000625412 00000 n 0000163855 00000 n 0000167195 00000 n 0000660281 00000 n 0000660312 00000 n 0000625586 00000 n 0000167217 00000 n 0000170522 00000 n 0000660391 00000 n 0000660422 00000 n 0000625760 00000 n 0000170544 00000 n 0000172188 00000 n 0000660501 00000 n 0000660532 00000 n 0000625926 00000 n 0000172210 00000 n 0000173763 00000 n 0000660589 00000 n 0000660620 00000 n 0000626092 00000 n 0000173785 00000 n 0000174474 00000 n 0000660677 00000 n 0000660708 00000 n 0000626258 00000 n 0000174495 00000 n 0000174774 00000 n 0000660765 00000 n 0000660796 00000 n 0000626424 00000 n 0000174795 00000 n 0000177410 00000 n 0000660840 00000 n 0000660871 00000 n 0000626598 00000 n 0000177432 00000 n 0000180200 00000 n 0000660978 00000 n 0000661009 00000 n 0000626772 00000 n 0000180222 00000 n 0000183985 00000 n 0000661101 00000 n 0000661132 00000 n 0000626946 00000 n 0000184007 00000 n 0000185678 00000 n 0000661211 00000 n 0000661242 00000 n 0000627112 00000 n 0000185700 00000 n 0000189308 00000 n 0000661299 00000 n 0000661330 00000 n 0000627286 00000 n 0000189330 00000 n 0000192341 00000 n 0000661409 00000 n 0000661440 00000 n 0000627460 00000 n 0000192363 00000 n 0000194763 00000 n 0000661543 00000 n 0000661574 00000 n 0000627634 00000 n 0000194785 00000 n 0000198389 00000 n 0000661642 00000 n 0000661673 00000 n 0000627808 00000 n 0000198411 00000 n 0000200530 00000 n 0000661752 00000 n 0000661783 00000 n 0000627974 00000 n 0000200552 00000 n 0000200831 00000 n 0000661862 00000 n 0000661893 00000 n 0000628140 00000 n 0000200852 00000 n 0000203558 00000 n 0000661937 00000 n 0000661968 00000 n 0000628306 00000 n 0000203580 00000 n 0000207506 00000 n 0000662036 00000 n 0000662067 00000 n 0000628472 00000 n 0000207528 00000 n 0000210983 00000 n 0000662135 00000 n 0000662166 00000 n 0000628646 00000 n 0000211005 00000 n 0000213839 00000 n 0000683410 00000 n 0000744701 00000 n 0000662258 00000 n 0000662289 00000 n 0000628820 00000 n 0000213861 00000 n 0000217637 00000 n 0000662407 00000 n 0000662438 00000 n 0000628994 00000 n 0000217659 00000 n 0000221106 00000 n 0000662569 00000 n 0000662600 00000 n 0000629168 00000 n 0000221128 00000 n 0000222841 00000 n 0000662692 00000 n 0000662723 00000 n 0000629334 00000 n 0000222863 00000 n 0000226115 00000 n 0000662780 00000 n 0000662811 00000 n 0000629508 00000 n 0000226137 00000 n 0000229720 00000 n 0000662942 00000 n 0000662973 00000 n 0000629682 00000 n 0000229742 00000 n 0000232640 00000 n 0000663063 00000 n 0000663094 00000 n 0000629856 00000 n 0000232662 00000 n 0000234915 00000 n 0000663173 00000 n 0000663204 00000 n 0000630022 00000 n 0000234937 00000 n 0000239226 00000 n 0000663272 00000 n 0000663303 00000 n 0000630196 00000 n 0000239248 00000 n 0000242829 00000 n 0000663421 00000 n 0000663452 00000 n 0000630370 00000 n 0000242851 00000 n 0000246594 00000 n 0000663542 00000 n 0000663573 00000 n 0000630544 00000 n 0000246616 00000 n 0000250231 00000 n 0000663663 00000 n 0000663694 00000 n 0000630718 00000 n 0000250253 00000 n 0000250532 00000 n 0000663773 00000 n 0000663804 00000 n 0000630884 00000 n 0000250553 00000 n 0000253333 00000 n 0000663848 00000 n 0000663879 00000 n 0000631058 00000 n 0000253355 00000 n 0000256963 00000 n 0000663958 00000 n 0000663989 00000 n 0000631232 00000 n 0000256985 00000 n 0000260825 00000 n 0000664068 00000 n 0000664099 00000 n 0000631406 00000 n 0000260847 00000 n 0000263197 00000 n 0000664178 00000 n 0000664209 00000 n 0000631580 00000 n 0000263219 00000 n 0000266311 00000 n 0000664288 00000 n 0000664319 00000 n 0000631754 00000 n 0000266333 00000 n 0000271043 00000 n 0000664398 00000 n 0000664429 00000 n 0000631928 00000 n 0000271065 00000 n 0000275442 00000 n 0000664571 00000 n 0000664602 00000 n 0000632102 00000 n 0000275464 00000 n 0000277401 00000 n 0000664657 00000 n 0000664688 00000 n 0000632268 00000 n 0000277423 00000 n 0000282164 00000 n 0000664767 00000 n 0000664798 00000 n 0000632442 00000 n 0000282186 00000 n 0000284674 00000 n 0000664929 00000 n 0000664960 00000 n 0000632616 00000 n 0000284696 00000 n 0000285685 00000 n 0000665028 00000 n 0000665059 00000 n 0000632782 00000 n 0000285706 00000 n 0000285985 00000 n 0000665116 00000 n 0000665147 00000 n 0000632948 00000 n 0000286006 00000 n 0000288454 00000 n 0000665191 00000 n 0000665222 00000 n 0000633122 00000 n 0000288476 00000 n 0000292147 00000 n 0000665288 00000 n 0000665319 00000 n 0000633296 00000 n 0000292169 00000 n 0000296205 00000 n 0000665409 00000 n 0000665440 00000 n 0000633470 00000 n 0000296227 00000 n 0000299916 00000 n 0000665556 00000 n 0000665587 00000 n 0000633644 00000 n 0000299938 00000 n 0000303002 00000 n 0000665666 00000 n 0000665697 00000 n 0000633818 00000 n 0000303024 00000 n 0000308268 00000 n 0000665802 00000 n 0000665833 00000 n 0000633984 00000 n 0000308290 00000 n 0000313633 00000 n 0000665951 00000 n 0000665982 00000 n 0000634158 00000 n 0000313655 00000 n 0000316915 00000 n 0000666137 00000 n 0000666168 00000 n 0000634332 00000 n 0000316937 00000 n 0000320116 00000 n 0000666258 00000 n 0000666289 00000 n 0000634506 00000 n 0000320138 00000 n 0000323304 00000 n 0000666379 00000 n 0000666410 00000 n 0000634680 00000 n 0000323326 00000 n 0000326980 00000 n 0000666500 00000 n 0000666531 00000 n 0000634854 00000 n 0000327002 00000 n 0000330451 00000 n 0000666636 00000 n 0000666667 00000 n 0000635028 00000 n 0000330473 00000 n 0000333982 00000 n 0000666770 00000 n 0000666801 00000 n 0000635202 00000 n 0000334004 00000 n 0000335815 00000 n 0000666904 00000 n 0000666935 00000 n 0000635368 00000 n 0000335837 00000 n 0000338663 00000 n 0000666992 00000 n 0000667023 00000 n 0000635534 00000 n 0000338685 00000 n 0000341116 00000 n 0000667115 00000 n 0000667146 00000 n 0000635708 00000 n 0000341138 00000 n 0000344172 00000 n 0000667236 00000 n 0000667267 00000 n 0000635874 00000 n 0000344194 00000 n 0000349413 00000 n 0000667363 00000 n 0000667394 00000 n 0000636048 00000 n 0000349435 00000 n 0000352543 00000 n 0000667538 00000 n 0000667569 00000 n 0000636222 00000 n 0000352565 00000 n 0000355066 00000 n 0000667661 00000 n 0000667692 00000 n 0000636396 00000 n 0000355088 00000 n 0000358384 00000 n 0000667810 00000 n 0000667841 00000 n 0000636570 00000 n 0000358406 00000 n 0000361381 00000 n 0000667920 00000 n 0000667951 00000 n 0000636744 00000 n 0000361403 00000 n 0000364334 00000 n 0000668041 00000 n 0000668072 00000 n 0000636910 00000 n 0000364356 00000 n 0000367985 00000 n 0000668151 00000 n 0000668182 00000 n 0000637084 00000 n 0000368007 00000 n 0000371126 00000 n 0000668274 00000 n 0000668305 00000 n 0000637250 00000 n 0000371148 00000 n 0000374372 00000 n 0000668384 00000 n 0000668415 00000 n 0000637416 00000 n 0000374394 00000 n 0000376030 00000 n 0000668494 00000 n 0000668525 00000 n 0000637582 00000 n 0000376052 00000 n 0000376333 00000 n 0000668580 00000 n 0000668611 00000 n 0000637748 00000 n 0000376354 00000 n 0000378864 00000 n 0000668655 00000 n 0000668686 00000 n 0000637914 00000 n 0000378886 00000 n 0000380767 00000 n 0000668754 00000 n 0000668785 00000 n 0000638080 00000 n 0000380789 00000 n 0000384938 00000 n 0000668853 00000 n 0000668884 00000 n 0000638254 00000 n 0000384960 00000 n 0000388271 00000 n 0000682645 00000 n 0000735878 00000 n 0000669013 00000 n 0000669044 00000 n 0000638420 00000 n 0000388293 00000 n 0000391516 00000 n 0000669175 00000 n 0000669206 00000 n 0000638594 00000 n 0000391538 00000 n 0000393926 00000 n 0000669296 00000 n 0000669327 00000 n 0000638760 00000 n 0000393948 00000 n 0000396367 00000 n 0000669406 00000 n 0000669437 00000 n 0000638934 00000 n 0000396389 00000 n 0000396672 00000 n 0000669527 00000 n 0000669558 00000 n 0000639100 00000 n 0000396693 00000 n 0000399267 00000 n 0000669602 00000 n 0000669633 00000 n 0000639274 00000 n 0000399289 00000 n 0000403042 00000 n 0000669712 00000 n 0000669743 00000 n 0000639448 00000 n 0000403064 00000 n 0000407847 00000 n 0000669833 00000 n 0000669864 00000 n 0000639622 00000 n 0000407869 00000 n 0000411200 00000 n 0000669969 00000 n 0000670000 00000 n 0000639796 00000 n 0000411222 00000 n 0000415080 00000 n 0000670079 00000 n 0000670110 00000 n 0000639970 00000 n 0000415102 00000 n 0000418602 00000 n 0000670202 00000 n 0000670233 00000 n 0000640144 00000 n 0000418624 00000 n 0000422375 00000 n 0000670323 00000 n 0000670354 00000 n 0000640318 00000 n 0000422397 00000 n 0000424741 00000 n 0000670433 00000 n 0000670464 00000 n 0000640484 00000 n 0000424763 00000 n 0000426650 00000 n 0000670593 00000 n 0000670624 00000 n 0000640650 00000 n 0000426672 00000 n 0000429501 00000 n 0000670703 00000 n 0000670734 00000 n 0000640824 00000 n 0000429523 00000 n 0000432086 00000 n 0000670852 00000 n 0000670883 00000 n 0000640998 00000 n 0000432108 00000 n 0000435719 00000 n 0000670962 00000 n 0000670993 00000 n 0000641172 00000 n 0000435741 00000 n 0000439903 00000 n 0000671109 00000 n 0000671140 00000 n 0000641346 00000 n 0000439925 00000 n 0000444900 00000 n 0000671271 00000 n 0000671302 00000 n 0000641520 00000 n 0000444922 00000 n 0000448357 00000 n 0000671392 00000 n 0000671423 00000 n 0000641686 00000 n 0000448379 00000 n 0000451968 00000 n 0000671491 00000 n 0000671522 00000 n 0000641860 00000 n 0000451990 00000 n 0000455543 00000 n 0000671614 00000 n 0000671645 00000 n 0000642034 00000 n 0000455565 00000 n 0000457140 00000 n 0000671724 00000 n 0000671755 00000 n 0000642200 00000 n 0000457162 00000 n 0000460072 00000 n 0000671812 00000 n 0000671843 00000 n 0000642366 00000 n 0000460094 00000 n 0000465264 00000 n 0000671900 00000 n 0000671931 00000 n 0000642540 00000 n 0000465286 00000 n 0000468411 00000 n 0000672101 00000 n 0000672132 00000 n 0000642714 00000 n 0000468433 00000 n 0000468716 00000 n 0000672237 00000 n 0000672268 00000 n 0000642880 00000 n 0000468737 00000 n 0000471148 00000 n 0000672312 00000 n 0000672343 00000 n 0000643046 00000 n 0000471170 00000 n 0000475379 00000 n 0000672398 00000 n 0000672429 00000 n 0000643220 00000 n 0000475401 00000 n 0000478360 00000 n 0000681864 00000 n 0000727201 00000 n 0000672519 00000 n 0000672550 00000 n 0000643394 00000 n 0000478382 00000 n 0000481375 00000 n 0000672672 00000 n 0000672703 00000 n 0000643568 00000 n 0000481397 00000 n 0000484153 00000 n 0000672758 00000 n 0000672789 00000 n 0000643734 00000 n 0000484175 00000 n 0000487833 00000 n 0000672833 00000 n 0000672864 00000 n 0000643908 00000 n 0000487855 00000 n 0000491386 00000 n 0000672965 00000 n 0000672996 00000 n 0000644082 00000 n 0000491408 00000 n 0000494438 00000 n 0000673099 00000 n 0000673130 00000 n 0000644248 00000 n 0000494460 00000 n 0000498705 00000 n 0000673233 00000 n 0000673264 00000 n 0000644422 00000 n 0000498727 00000 n 0000503060 00000 n 0000673354 00000 n 0000673385 00000 n 0000644596 00000 n 0000503082 00000 n 0000507301 00000 n 0000673462 00000 n 0000673493 00000 n 0000644770 00000 n 0000507323 00000 n 0000512363 00000 n 0000673587 00000 n 0000673618 00000 n 0000644944 00000 n 0000512385 00000 n 0000517008 00000 n 0000673684 00000 n 0000673715 00000 n 0000645118 00000 n 0000517030 00000 n 0000520965 00000 n 0000673781 00000 n 0000673812 00000 n 0000645292 00000 n 0000520987 00000 n 0000524759 00000 n 0000673893 00000 n 0000673924 00000 n 0000645466 00000 n 0000524781 00000 n 0000525064 00000 n 0000674014 00000 n 0000674045 00000 n 0000645632 00000 n 0000525085 00000 n 0000528742 00000 n 0000674089 00000 n 0000674120 00000 n 0000645798 00000 n 0000528764 00000 n 0000530740 00000 n 0000674175 00000 n 0000674206 00000 n 0000645972 00000 n 0000530762 00000 n 0000532272 00000 n 0000674274 00000 n 0000674305 00000 n 0000646138 00000 n 0000532294 00000 n 0000533453 00000 n 0000674362 00000 n 0000674393 00000 n 0000646304 00000 n 0000533475 00000 n 0000534761 00000 n 0000674450 00000 n 0000674481 00000 n 0000646470 00000 n 0000534783 00000 n 0000536706 00000 n 0000674538 00000 n 0000674569 00000 n 0000646636 00000 n 0000536728 00000 n 0000538447 00000 n 0000674626 00000 n 0000674657 00000 n 0000646802 00000 n 0000538469 00000 n 0000540482 00000 n 0000674714 00000 n 0000674745 00000 n 0000646976 00000 n 0000540504 00000 n 0000544271 00000 n 0000674824 00000 n 0000674855 00000 n 0000647150 00000 n 0000544293 00000 n 0000548475 00000 n 0000674934 00000 n 0000674965 00000 n 0000647324 00000 n 0000548497 00000 n 0000553061 00000 n 0000675042 00000 n 0000675073 00000 n 0000647498 00000 n 0000553083 00000 n 0000556940 00000 n 0000675139 00000 n 0000675170 00000 n 0000647672 00000 n 0000556962 00000 n 0000559278 00000 n 0000675251 00000 n 0000675282 00000 n 0000647846 00000 n 0000559300 00000 n 0000561114 00000 n 0000675361 00000 n 0000675393 00000 n 0000648024 00000 n 0000561137 00000 n 0000563509 00000 n 0000675462 00000 n 0000675494 00000 n 0000648194 00000 n 0000563532 00000 n 0000566206 00000 n 0000675561 00000 n 0000675593 00000 n 0000648372 00000 n 0000566229 00000 n 0000567910 00000 n 0000675662 00000 n 0000675694 00000 n 0000648542 00000 n 0000567933 00000 n 0000570331 00000 n 0000675752 00000 n 0000675784 00000 n 0000648720 00000 n 0000570354 00000 n 0000573042 00000 n 0000675853 00000 n 0000675885 00000 n 0000648890 00000 n 0000573065 00000 n 0000574684 00000 n 0000675965 00000 n 0000675997 00000 n 0000649060 00000 n 0000574707 00000 n 0000576412 00000 n 0000676055 00000 n 0000676087 00000 n 0000649230 00000 n 0000576435 00000 n 0000578045 00000 n 0000676145 00000 n 0000676177 00000 n 0000649400 00000 n 0000578068 00000 n 0000579216 00000 n 0000676235 00000 n 0000676267 00000 n 0000649570 00000 n 0000579239 00000 n 0000580712 00000 n 0000676325 00000 n 0000676357 00000 n 0000649740 00000 n 0000580735 00000 n 0000581922 00000 n 0000676415 00000 n 0000676447 00000 n 0000649910 00000 n 0000581945 00000 n 0000583444 00000 n 0000676505 00000 n 0000676537 00000 n 0000650080 00000 n 0000583467 00000 n 0000585051 00000 n 0000676595 00000 n 0000676627 00000 n 0000650250 00000 n 0000585074 00000 n 0000587111 00000 n 0000676685 00000 n 0000676717 00000 n 0000650420 00000 n 0000587134 00000 n 0000591029 00000 n 0000676775 00000 n 0000676807 00000 n 0000650598 00000 n 0000591052 00000 n 0000595097 00000 n 0000676924 00000 n 0000676956 00000 n 0000650776 00000 n 0000595120 00000 n 0000598804 00000 n 0000677060 00000 n 0000677092 00000 n 0000650954 00000 n 0000598827 00000 n 0000600829 00000 n 0000677222 00000 n 0000677254 00000 n 0000651124 00000 n 0000600852 00000 n 0000603199 00000 n 0000677323 00000 n 0000677355 00000 n 0000651302 00000 n 0000603222 00000 n 0000606690 00000 n 0000677400 00000 n 0000677432 00000 n 0000651480 00000 n 0000606713 00000 n 0000609797 00000 n 0000677477 00000 n 0000677509 00000 n 0000651658 00000 n 0000609820 00000 n 0000613014 00000 n 0000677554 00000 n 0000677586 00000 n 0000651836 00000 n 0000613037 00000 n 0000615660 00000 n 0000677631 00000 n 0000677663 00000 n 0000689905 00000 n 0000691817 00000 n 0000698857 00000 n 0000700940 00000 n 0000707891 00000 n 0000709180 00000 n 0000718046 00000 n 0000719790 00000 n 0000721520 00000 n 0000725828 00000 n 0000727423 00000 n 0000728539 00000 n 0000736086 00000 n 0000737183 00000 n 0000744962 00000 n 0000747293 00000 n 0000755033 00000 n 0000759342 00000 n 0000760790 00000 n 0000761543 00000 n 0000769172 00000 n 0000773108 00000 n 0000782035 00000 n 0000786693 00000 n 0000788041 00000 n 0000788889 00000 n 0000795556 00000 n 0000678402 00000 n 0000679233 00000 n 0000679554 00000 n 0000680226 00000 n 0000680672 00000 n 0000681497 00000 n 0000682545 00000 n 0000683316 00000 n 0000684260 00000 n 0000684786 00000 n 0000685279 00000 n 0000685644 00000 n 0000686239 00000 n 0000686660 00000 n 0000687263 00000 n 0000687803 00000 n 0000688362 00000 n 0000688932 00000 n 0000689561 00000 n 0000802346 00000 n trailer << /Size 1167 /Root 1 0 R /Info 2 0 R /ID [] >> startxref 803859 %%EOF libtomcrypt-1.17/src/0000755000175100001440000000000010621351501013312 5ustar tomuserslibtomcrypt-1.17/src/pk/0000755000175100001440000000000010621351501013724 5ustar tomuserslibtomcrypt-1.17/src/pk/ecc/0000755000175100001440000000000010621351501014456 5ustar tomuserslibtomcrypt-1.17/src/pk/ecc/ecc_verify_hash.c0000644000175100001440000001317510621351501017752 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b * * All curves taken from NIST recommendation paper of July 1999 * Available at http://csrc.nist.gov/cryptval/dss.htm */ #include "tomcrypt.h" /** @file ecc_verify_hash.c ECC Crypto, Tom St Denis */ #ifdef LTC_MECC /* verify * * w = s^-1 mod n * u1 = xw * u2 = rw * X = u1*G + u2*Q * v = X_x1 mod n * accept if v == r */ /** Verify an ECC signature @param sig The signature to verify @param siglen The length of the signature (octets) @param hash The hash (message digest) that was signed @param hashlen The length of the hash (octets) @param stat Result of signature, 1==valid, 0==invalid @param key The corresponding public ECC key @return CRYPT_OK if successful (even if the signature is not valid) */ int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, const unsigned char *hash, unsigned long hashlen, int *stat, ecc_key *key) { ecc_point *mG, *mQ; void *r, *s, *v, *w, *u1, *u2, *e, *p, *m; void *mp; int err; LTC_ARGCHK(sig != NULL); LTC_ARGCHK(hash != NULL); LTC_ARGCHK(stat != NULL); LTC_ARGCHK(key != NULL); /* default to invalid signature */ *stat = 0; mp = NULL; /* is the IDX valid ? */ if (ltc_ecc_is_valid_idx(key->idx) != 1) { return CRYPT_PK_INVALID_TYPE; } /* allocate ints */ if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, NULL)) != CRYPT_OK) { return CRYPT_MEM; } /* allocate points */ mG = ltc_ecc_new_point(); mQ = ltc_ecc_new_point(); if (mQ == NULL || mG == NULL) { err = CRYPT_MEM; goto error; } /* parse header */ if ((err = der_decode_sequence_multi(sig, siglen, LTC_ASN1_INTEGER, 1UL, r, LTC_ASN1_INTEGER, 1UL, s, LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto error; } /* get the order */ if ((err = mp_read_radix(p, (char *)key->dp->order, 16)) != CRYPT_OK) { goto error; } /* get the modulus */ if ((err = mp_read_radix(m, (char *)key->dp->prime, 16)) != CRYPT_OK) { goto error; } /* check for zero */ if (mp_iszero(r) || mp_iszero(s) || mp_cmp(r, p) != LTC_MP_LT || mp_cmp(s, p) != LTC_MP_LT) { err = CRYPT_INVALID_PACKET; goto error; } /* read hash */ if ((err = mp_read_unsigned_bin(e, (unsigned char *)hash, (int)hashlen)) != CRYPT_OK) { goto error; } /* w = s^-1 mod n */ if ((err = mp_invmod(s, p, w)) != CRYPT_OK) { goto error; } /* u1 = ew */ if ((err = mp_mulmod(e, w, p, u1)) != CRYPT_OK) { goto error; } /* u2 = rw */ if ((err = mp_mulmod(r, w, p, u2)) != CRYPT_OK) { goto error; } /* find mG and mQ */ if ((err = mp_read_radix(mG->x, (char *)key->dp->Gx, 16)) != CRYPT_OK) { goto error; } if ((err = mp_read_radix(mG->y, (char *)key->dp->Gy, 16)) != CRYPT_OK) { goto error; } if ((err = mp_set(mG->z, 1)) != CRYPT_OK) { goto error; } if ((err = mp_copy(key->pubkey.x, mQ->x)) != CRYPT_OK) { goto error; } if ((err = mp_copy(key->pubkey.y, mQ->y)) != CRYPT_OK) { goto error; } if ((err = mp_copy(key->pubkey.z, mQ->z)) != CRYPT_OK) { goto error; } /* compute u1*mG + u2*mQ = mG */ if (ltc_mp.ecc_mul2add == NULL) { if ((err = ltc_mp.ecc_ptmul(u1, mG, mG, m, 0)) != CRYPT_OK) { goto error; } if ((err = ltc_mp.ecc_ptmul(u2, mQ, mQ, m, 0)) != CRYPT_OK) { goto error; } /* find the montgomery mp */ if ((err = mp_montgomery_setup(m, &mp)) != CRYPT_OK) { goto error; } /* add them */ if ((err = ltc_mp.ecc_ptadd(mQ, mG, mG, m, mp)) != CRYPT_OK) { goto error; } /* reduce */ if ((err = ltc_mp.ecc_map(mG, m, mp)) != CRYPT_OK) { goto error; } } else { /* use Shamir's trick to compute u1*mG + u2*mQ using half of the doubles */ if ((err = ltc_mp.ecc_mul2add(mG, u1, mQ, u2, mG, m)) != CRYPT_OK) { goto error; } } /* v = X_x1 mod n */ if ((err = mp_mod(mG->x, p, v)) != CRYPT_OK) { goto error; } /* does v == r */ if (mp_cmp(v, r) == LTC_MP_EQ) { *stat = 1; } /* clear up and return */ err = CRYPT_OK; error: ltc_ecc_del_point(mG); ltc_ecc_del_point(mQ); mp_clear_multi(r, s, v, w, u1, u2, p, e, m, NULL); if (mp != NULL) { mp_montgomery_free(mp); } return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_verify_hash.c,v $ */ /* $Revision: 1.14 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/ecc/ltc_ecc_points.c0000644000175100001440000000257110621351501017617 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b * * All curves taken from NIST recommendation paper of July 1999 * Available at http://csrc.nist.gov/cryptval/dss.htm */ #include "tomcrypt.h" /** @file ltc_ecc_points.c ECC Crypto, Tom St Denis */ #ifdef LTC_MECC /** Allocate a new ECC point @return A newly allocated point or NULL on error */ ecc_point *ltc_ecc_new_point(void) { ecc_point *p; p = XCALLOC(1, sizeof(*p)); if (p == NULL) { return NULL; } if (mp_init_multi(&p->x, &p->y, &p->z, NULL) != CRYPT_OK) { XFREE(p); return NULL; } return p; } /** Free an ECC point from memory @param p The point to free */ void ltc_ecc_del_point(ecc_point *p) { /* prevents free'ing null arguments */ if (p != NULL) { mp_clear_multi(p->x, p->y, p->z, NULL); /* note: p->z may be NULL but that's ok with this function anyways */ XFREE(p); } } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_points.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/ecc/ecc_sign_hash.c0000644000175100001440000000724010621351501017402 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b * * All curves taken from NIST recommendation paper of July 1999 * Available at http://csrc.nist.gov/cryptval/dss.htm */ #include "tomcrypt.h" /** @file ecc_sign_hash.c ECC Crypto, Tom St Denis */ #ifdef LTC_MECC /** Sign a message digest @param in The message digest to sign @param inlen The length of the digest @param out [out] The destination for the signature @param outlen [in/out] The max size and resulting size of the signature @param prng An active PRNG state @param wprng The index of the PRNG you wish to use @param key A private ECC key @return CRYPT_OK if successful */ int ecc_sign_hash(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, prng_state *prng, int wprng, ecc_key *key) { ecc_key pubkey; void *r, *s, *e, *p; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); /* is this a private key? */ if (key->type != PK_PRIVATE) { return CRYPT_PK_NOT_PRIVATE; } /* is the IDX valid ? */ if (ltc_ecc_is_valid_idx(key->idx) != 1) { return CRYPT_PK_INVALID_TYPE; } if ((err = prng_is_valid(wprng)) != CRYPT_OK) { return err; } /* get the hash and load it as a bignum into 'e' */ /* init the bignums */ if ((err = mp_init_multi(&r, &s, &p, &e, NULL)) != CRYPT_OK) { return err; } if ((err = mp_read_radix(p, (char *)key->dp->order, 16)) != CRYPT_OK) { goto errnokey; } if ((err = mp_read_unsigned_bin(e, (unsigned char *)in, (int)inlen)) != CRYPT_OK) { goto errnokey; } /* make up a key and export the public copy */ for (;;) { if ((err = ecc_make_key_ex(prng, wprng, &pubkey, key->dp)) != CRYPT_OK) { goto errnokey; } /* find r = x1 mod n */ if ((err = mp_mod(pubkey.pubkey.x, p, r)) != CRYPT_OK) { goto error; } if (mp_iszero(r) == LTC_MP_YES) { ecc_free(&pubkey); } else { /* find s = (e + xr)/k */ if ((err = mp_invmod(pubkey.k, p, pubkey.k)) != CRYPT_OK) { goto error; } /* k = 1/k */ if ((err = mp_mulmod(key->k, r, p, s)) != CRYPT_OK) { goto error; } /* s = xr */ if ((err = mp_add(e, s, s)) != CRYPT_OK) { goto error; } /* s = e + xr */ if ((err = mp_mod(s, p, s)) != CRYPT_OK) { goto error; } /* s = e + xr */ if ((err = mp_mulmod(s, pubkey.k, p, s)) != CRYPT_OK) { goto error; } /* s = (e + xr)/k */ ecc_free(&pubkey); if (mp_iszero(s) == LTC_MP_NO) { break; } } } /* store as SEQUENCE { r, s -- integer } */ err = der_encode_sequence_multi(out, outlen, LTC_ASN1_INTEGER, 1UL, r, LTC_ASN1_INTEGER, 1UL, s, LTC_ASN1_EOL, 0UL, NULL); goto errnokey; error: ecc_free(&pubkey); errnokey: mp_clear_multi(r, s, p, e, NULL); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_sign_hash.c,v $ */ /* $Revision: 1.11 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/ecc/ltc_ecc_mulmod.c0000644000175100001440000001553410621351501017603 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b * * All curves taken from NIST recommendation paper of July 1999 * Available at http://csrc.nist.gov/cryptval/dss.htm */ #include "tomcrypt.h" /** @file ltc_ecc_mulmod.c ECC Crypto, Tom St Denis */ #ifdef LTC_MECC #ifndef LTC_ECC_TIMING_RESISTANT /* size of sliding window, don't change this! */ #define WINSIZE 4 /** Perform a point multiplication @param k The scalar to multiply by @param G The base point @param R [out] Destination for kG @param modulus The modulus of the field the ECC curve is in @param map Boolean whether to map back to affine or not (1==map, 0 == leave in projective) @return CRYPT_OK on success */ int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map) { ecc_point *tG, *M[8]; int i, j, err; void *mu, *mp; unsigned long buf; int first, bitbuf, bitcpy, bitcnt, mode, digidx; LTC_ARGCHK(k != NULL); LTC_ARGCHK(G != NULL); LTC_ARGCHK(R != NULL); LTC_ARGCHK(modulus != NULL); /* init montgomery reduction */ if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { return err; } if ((err = mp_init(&mu)) != CRYPT_OK) { mp_montgomery_free(mp); return err; } if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { mp_montgomery_free(mp); mp_clear(mu); return err; } /* alloc ram for window temps */ for (i = 0; i < 8; i++) { M[i] = ltc_ecc_new_point(); if (M[i] == NULL) { for (j = 0; j < i; j++) { ltc_ecc_del_point(M[j]); } mp_montgomery_free(mp); mp_clear(mu); return CRYPT_MEM; } } /* make a copy of G incase R==G */ tG = ltc_ecc_new_point(); if (tG == NULL) { err = CRYPT_MEM; goto done; } /* tG = G and convert to montgomery */ if (mp_cmp_d(mu, 1) == LTC_MP_EQ) { if ((err = mp_copy(G->x, tG->x)) != CRYPT_OK) { goto done; } if ((err = mp_copy(G->y, tG->y)) != CRYPT_OK) { goto done; } if ((err = mp_copy(G->z, tG->z)) != CRYPT_OK) { goto done; } } else { if ((err = mp_mulmod(G->x, mu, modulus, tG->x)) != CRYPT_OK) { goto done; } if ((err = mp_mulmod(G->y, mu, modulus, tG->y)) != CRYPT_OK) { goto done; } if ((err = mp_mulmod(G->z, mu, modulus, tG->z)) != CRYPT_OK) { goto done; } } mp_clear(mu); mu = NULL; /* calc the M tab, which holds kG for k==8..15 */ /* M[0] == 8G */ if ((err = ltc_mp.ecc_ptdbl(tG, M[0], modulus, mp)) != CRYPT_OK) { goto done; } if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], modulus, mp)) != CRYPT_OK) { goto done; } if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], modulus, mp)) != CRYPT_OK) { goto done; } /* now find (8+k)G for k=1..7 */ for (j = 9; j < 16; j++) { if ((err = ltc_mp.ecc_ptadd(M[j-9], tG, M[j-8], modulus, mp)) != CRYPT_OK) { goto done; } } /* setup sliding window */ mode = 0; bitcnt = 1; buf = 0; digidx = mp_get_digit_count(k) - 1; bitcpy = bitbuf = 0; first = 1; /* perform ops */ for (;;) { /* grab next digit as required */ if (--bitcnt == 0) { if (digidx == -1) { break; } buf = mp_get_digit(k, digidx); bitcnt = (int) ltc_mp.bits_per_digit; --digidx; } /* grab the next msb from the ltiplicand */ i = (buf >> (ltc_mp.bits_per_digit - 1)) & 1; buf <<= 1; /* skip leading zero bits */ if (mode == 0 && i == 0) { continue; } /* if the bit is zero and mode == 1 then we double */ if (mode == 1 && i == 0) { if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; } continue; } /* else we add it to the window */ bitbuf |= (i << (WINSIZE - ++bitcpy)); mode = 2; if (bitcpy == WINSIZE) { /* if this is the first window we do a simple copy */ if (first == 1) { /* R = kG [k = first window] */ if ((err = mp_copy(M[bitbuf-8]->x, R->x)) != CRYPT_OK) { goto done; } if ((err = mp_copy(M[bitbuf-8]->y, R->y)) != CRYPT_OK) { goto done; } if ((err = mp_copy(M[bitbuf-8]->z, R->z)) != CRYPT_OK) { goto done; } first = 0; } else { /* normal window */ /* ok window is filled so double as required and add */ /* double first */ for (j = 0; j < WINSIZE; j++) { if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; } } /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */ if ((err = ltc_mp.ecc_ptadd(R, M[bitbuf-8], R, modulus, mp)) != CRYPT_OK) { goto done; } } /* empty window and reset */ bitcpy = bitbuf = 0; mode = 1; } } /* if bits remain then double/add */ if (mode == 2 && bitcpy > 0) { /* double then add */ for (j = 0; j < bitcpy; j++) { /* only double if we have had at least one add first */ if (first == 0) { if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; } } bitbuf <<= 1; if ((bitbuf & (1 << WINSIZE)) != 0) { if (first == 1){ /* first add, so copy */ if ((err = mp_copy(tG->x, R->x)) != CRYPT_OK) { goto done; } if ((err = mp_copy(tG->y, R->y)) != CRYPT_OK) { goto done; } if ((err = mp_copy(tG->z, R->z)) != CRYPT_OK) { goto done; } first = 0; } else { /* then add */ if ((err = ltc_mp.ecc_ptadd(R, tG, R, modulus, mp)) != CRYPT_OK) { goto done; } } } } } /* map R back from projective space */ if (map) { err = ltc_ecc_map(R, modulus, mp); } else { err = CRYPT_OK; } done: if (mu != NULL) { mp_clear(mu); } mp_montgomery_free(mp); ltc_ecc_del_point(tG); for (i = 0; i < 8; i++) { ltc_ecc_del_point(M[i]); } return err; } #endif #undef WINSIZE #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod.c,v $ */ /* $Revision: 1.26 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/ecc/ecc_sizes.c0000644000175100001440000000212110621351501016565 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b * * All curves taken from NIST recommendation paper of July 1999 * Available at http://csrc.nist.gov/cryptval/dss.htm */ #include "tomcrypt.h" /** @file ecc_sizes.c ECC Crypto, Tom St Denis */ #ifdef LTC_MECC void ecc_sizes(int *low, int *high) { int i; LTC_ARGCHKVD(low != NULL); LTC_ARGCHKVD(high != NULL); *low = INT_MAX; *high = 0; for (i = 0; ltc_ecc_sets[i].size != 0; i++) { if (ltc_ecc_sets[i].size < *low) { *low = ltc_ecc_sets[i].size; } if (ltc_ecc_sets[i].size > *high) { *high = ltc_ecc_sets[i].size; } } } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_sizes.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/ecc/ecc.c0000644000175100001440000001036310621351501015357 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b * * All curves taken from NIST recommendation paper of July 1999 * Available at http://csrc.nist.gov/cryptval/dss.htm */ #include "tomcrypt.h" /** @file ecc.c ECC Crypto, Tom St Denis */ #ifdef LTC_MECC /* This holds the key settings. ***MUST*** be organized by size from smallest to largest. */ const ltc_ecc_set_type ltc_ecc_sets[] = { #ifdef ECC112 { 14, "SECP112R1", "DB7C2ABF62E35E668076BEAD208B", "659EF8BA043916EEDE8911702B22", "DB7C2ABF62E35E7628DFAC6561C5", "09487239995A5EE76B55F9C2F098", "A89CE5AF8724C0A23E0E0FF77500" }, #endif #ifdef ECC128 { 16, "SECP128R1", "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", "E87579C11079F43DD824993C2CEE5ED3", "FFFFFFFE0000000075A30D1B9038A115", "161FF7528B899B2D0C28607CA52C5B86", "CF5AC8395BAFEB13C02DA292DDED7A83", }, #endif #ifdef ECC160 { 20, "SECP160R1", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", "0100000000000000000001F4C8F927AED3CA752257", "4A96B5688EF573284664698968C38BB913CBFC82", "23A628553168947D59DCC912042351377AC5FB32", }, #endif #ifdef ECC192 { 24, "ECC-192", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811", }, #endif #ifdef ECC224 { 28, "ECC-224", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", }, #endif #ifdef ECC256 { 32, "ECC-256", "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", }, #endif #ifdef ECC384 { 48, "ECC-384", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", }, #endif #ifdef ECC521 { 66, "ECC-521", "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", }, #endif { 0, NULL, NULL, NULL, NULL, NULL, NULL } }; #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc.c,v $ */ /* $Revision: 1.40 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/ecc/ecc_ansi_x963_import.c0000644000175100001440000000531310621351501020553 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b * * All curves taken from NIST recommendation paper of July 1999 * Available at http://csrc.nist.gov/cryptval/dss.htm */ #include "tomcrypt.h" /** @file ecc_ansi_x963_import.c ECC Crypto, Tom St Denis */ #ifdef LTC_MECC /** Import an ANSI X9.63 format public key @param in The input data to read @param inlen The length of the input data @param key [out] destination to store imported key \ */ int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key) { return ecc_ansi_x963_import_ex(in, inlen, key, NULL); } int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp) { int x, err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(key != NULL); /* must be odd */ if ((inlen & 1) == 0) { return CRYPT_INVALID_ARG; } /* init key */ if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL) != CRYPT_OK) { return CRYPT_MEM; } /* check for 4, 6 or 7 */ if (in[0] != 4 && in[0] != 6 && in[0] != 7) { err = CRYPT_INVALID_PACKET; goto error; } /* read data */ if ((err = mp_read_unsigned_bin(key->pubkey.x, (unsigned char *)in+1, (inlen-1)>>1)) != CRYPT_OK) { goto error; } if ((err = mp_read_unsigned_bin(key->pubkey.y, (unsigned char *)in+1+((inlen-1)>>1), (inlen-1)>>1)) != CRYPT_OK) { goto error; } if ((err = mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto error; } if (dp == NULL) { /* determine the idx */ for (x = 0; ltc_ecc_sets[x].size != 0; x++) { if ((unsigned)ltc_ecc_sets[x].size >= ((inlen-1)>>1)) { break; } } if (ltc_ecc_sets[x].size == 0) { err = CRYPT_INVALID_PACKET; goto error; } /* set the idx */ key->idx = x; key->dp = <c_ecc_sets[x]; } else { if (((inlen-1)>>1) != (unsigned long) dp->size) { err = CRYPT_INVALID_PACKET; goto error; } key->idx = -1; key->dp = dp; } key->type = PK_PUBLIC; /* we're done */ return CRYPT_OK; error: mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_ansi_x963_import.c,v $ */ /* $Revision: 1.11 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/ecc/ltc_ecc_is_valid_idx.c0000644000175100001440000000216610621351501020741 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b * * All curves taken from NIST recommendation paper of July 1999 * Available at http://csrc.nist.gov/cryptval/dss.htm */ #include "tomcrypt.h" /** @file ltc_ecc_is_valid_idx.c ECC Crypto, Tom St Denis */ #ifdef LTC_MECC /** Returns whether an ECC idx is valid or not @param n The idx number to check @return 1 if valid, 0 if not */ int ltc_ecc_is_valid_idx(int n) { int x; for (x = 0; ltc_ecc_sets[x].size != 0; x++); /* -1 is a valid index --- indicating that the domain params were supplied by the user */ if ((n >= -1) && (n < x)) { return 1; } return 0; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_is_valid_idx.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/ecc/ltc_ecc_map.c0000644000175100001440000000470410621351501017060 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b * * All curves taken from NIST recommendation paper of July 1999 * Available at http://csrc.nist.gov/cryptval/dss.htm */ #include "tomcrypt.h" /** @file ltc_ecc_map.c ECC Crypto, Tom St Denis */ #ifdef LTC_MECC /** Map a projective jacbobian point back to affine space @param P [in/out] The point to map @param modulus The modulus of the field the ECC curve is in @param mp The "b" value from montgomery_setup() @return CRYPT_OK on success */ int ltc_ecc_map(ecc_point *P, void *modulus, void *mp) { void *t1, *t2; int err; LTC_ARGCHK(P != NULL); LTC_ARGCHK(modulus != NULL); LTC_ARGCHK(mp != NULL); if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) { return CRYPT_MEM; } /* first map z back to normal */ if ((err = mp_montgomery_reduce(P->z, modulus, mp)) != CRYPT_OK) { goto done; } /* get 1/z */ if ((err = mp_invmod(P->z, modulus, t1)) != CRYPT_OK) { goto done; } /* get 1/z^2 and 1/z^3 */ if ((err = mp_sqr(t1, t2)) != CRYPT_OK) { goto done; } if ((err = mp_mod(t2, modulus, t2)) != CRYPT_OK) { goto done; } if ((err = mp_mul(t1, t2, t1)) != CRYPT_OK) { goto done; } if ((err = mp_mod(t1, modulus, t1)) != CRYPT_OK) { goto done; } /* multiply against x/y */ if ((err = mp_mul(P->x, t2, P->x)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(P->x, modulus, mp)) != CRYPT_OK) { goto done; } if ((err = mp_mul(P->y, t1, P->y)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(P->y, modulus, mp)) != CRYPT_OK) { goto done; } if ((err = mp_set(P->z, 1)) != CRYPT_OK) { goto done; } err = CRYPT_OK; done: mp_clear_multi(t1, t2, NULL); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_map.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/ecc/ecc_shared_secret.c0000644000175100001440000000526510621351501020257 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b * * All curves taken from NIST recommendation paper of July 1999 * Available at http://csrc.nist.gov/cryptval/dss.htm */ #include "tomcrypt.h" /** @file ecc_shared_secret.c ECC Crypto, Tom St Denis */ #ifdef LTC_MECC /** Create an ECC shared secret between two keys @param private_key The private ECC key @param public_key The public key @param out [out] Destination of the shared secret (Conforms to EC-DH from ANSI X9.63) @param outlen [in/out] The max size and resulting size of the shared secret @return CRYPT_OK if successful */ int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, unsigned char *out, unsigned long *outlen) { unsigned long x; ecc_point *result; void *prime; int err; LTC_ARGCHK(private_key != NULL); LTC_ARGCHK(public_key != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* type valid? */ if (private_key->type != PK_PRIVATE) { return CRYPT_PK_NOT_PRIVATE; } if (ltc_ecc_is_valid_idx(private_key->idx) == 0 || ltc_ecc_is_valid_idx(public_key->idx) == 0) { return CRYPT_INVALID_ARG; } if (XSTRCMP(private_key->dp->name, public_key->dp->name) != 0) { return CRYPT_PK_TYPE_MISMATCH; } /* make new point */ result = ltc_ecc_new_point(); if (result == NULL) { return CRYPT_MEM; } if ((err = mp_init(&prime)) != CRYPT_OK) { ltc_ecc_del_point(result); return err; } if ((err = mp_read_radix(prime, (char *)private_key->dp->prime, 16)) != CRYPT_OK) { goto done; } if ((err = ltc_mp.ecc_ptmul(private_key->k, &public_key->pubkey, result, prime, 1)) != CRYPT_OK) { goto done; } x = (unsigned long)mp_unsigned_bin_size(prime); if (*outlen < x) { *outlen = x; err = CRYPT_BUFFER_OVERFLOW; goto done; } zeromem(out, x); if ((err = mp_to_unsigned_bin(result->x, out + (x - mp_unsigned_bin_size(result->x)))) != CRYPT_OK) { goto done; } err = CRYPT_OK; *outlen = x; done: mp_clear(prime); ltc_ecc_del_point(result); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_shared_secret.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/ecc/ecc_ansi_x963_export.c0000644000175100001440000000357110621351501020566 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b * * All curves taken from NIST recommendation paper of July 1999 * Available at http://csrc.nist.gov/cryptval/dss.htm */ #include "tomcrypt.h" /** @file ecc_ansi_x963_export.c ECC Crypto, Tom St Denis */ #ifdef LTC_MECC /** ECC X9.63 (Sec. 4.3.6) uncompressed export @param key Key to export @param out [out] destination of export @param outlen [in/out] Length of destination and final output size Return CRYPT_OK on success */ int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen) { unsigned char buf[ECC_BUF_SIZE]; unsigned long numlen; LTC_ARGCHK(key != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); if (ltc_ecc_is_valid_idx(key->idx) == 0) { return CRYPT_INVALID_ARG; } numlen = key->dp->size; if (*outlen < (1 + 2*numlen)) { *outlen = 1 + 2*numlen; return CRYPT_BUFFER_OVERFLOW; } /* store byte 0x04 */ out[0] = 0x04; /* pad and store x */ zeromem(buf, sizeof(buf)); mp_to_unsigned_bin(key->pubkey.x, buf + (numlen - mp_unsigned_bin_size(key->pubkey.x))); XMEMCPY(out+1, buf, numlen); /* pad and store y */ zeromem(buf, sizeof(buf)); mp_to_unsigned_bin(key->pubkey.y, buf + (numlen - mp_unsigned_bin_size(key->pubkey.y))); XMEMCPY(out+1+numlen, buf, numlen); *outlen = 1 + 2*numlen; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_ansi_x963_export.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/ecc/ltc_ecc_mul2add.c0000644000175100001440000001447410621351501017640 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b * * All curves taken from NIST recommendation paper of July 1999 * Available at http://csrc.nist.gov/cryptval/dss.htm */ #include "tomcrypt.h" /** @file ltc_ecc_mul2add.c ECC Crypto, Shamir's Trick, Tom St Denis */ #ifdef LTC_MECC #ifdef LTC_ECC_SHAMIR /** Computes kA*A + kB*B = C using Shamir's Trick @param A First point to multiply @param kA What to multiple A by @param B Second point to multiply @param kB What to multiple B by @param C [out] Destination point (can overlap with A or B @param modulus Modulus for curve @return CRYPT_OK on success */ int ltc_ecc_mul2add(ecc_point *A, void *kA, ecc_point *B, void *kB, ecc_point *C, void *modulus) { ecc_point *precomp[16]; unsigned bitbufA, bitbufB, lenA, lenB, len, x, y, nA, nB, nibble; unsigned char *tA, *tB; int err, first; void *mp, *mu; /* argchks */ LTC_ARGCHK(A != NULL); LTC_ARGCHK(B != NULL); LTC_ARGCHK(C != NULL); LTC_ARGCHK(kA != NULL); LTC_ARGCHK(kB != NULL); LTC_ARGCHK(modulus != NULL); /* allocate memory */ tA = XCALLOC(1, ECC_BUF_SIZE); if (tA == NULL) { return CRYPT_MEM; } tB = XCALLOC(1, ECC_BUF_SIZE); if (tB == NULL) { XFREE(tA); return CRYPT_MEM; } /* get sizes */ lenA = mp_unsigned_bin_size(kA); lenB = mp_unsigned_bin_size(kB); len = MAX(lenA, lenB); /* sanity check */ if ((lenA > ECC_BUF_SIZE) || (lenB > ECC_BUF_SIZE)) { err = CRYPT_INVALID_ARG; goto ERR_T; } /* extract and justify kA */ mp_to_unsigned_bin(kA, (len - lenA) + tA); /* extract and justify kB */ mp_to_unsigned_bin(kB, (len - lenB) + tB); /* allocate the table */ for (x = 0; x < 16; x++) { precomp[x] = ltc_ecc_new_point(); if (precomp[x] == NULL) { for (y = 0; y < x; ++y) { ltc_ecc_del_point(precomp[y]); } err = CRYPT_MEM; goto ERR_T; } } /* init montgomery reduction */ if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto ERR_P; } if ((err = mp_init(&mu)) != CRYPT_OK) { goto ERR_MP; } if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { goto ERR_MU; } /* copy ones ... */ if ((err = mp_mulmod(A->x, mu, modulus, precomp[1]->x)) != CRYPT_OK) { goto ERR_MU; } if ((err = mp_mulmod(A->y, mu, modulus, precomp[1]->y)) != CRYPT_OK) { goto ERR_MU; } if ((err = mp_mulmod(A->z, mu, modulus, precomp[1]->z)) != CRYPT_OK) { goto ERR_MU; } if ((err = mp_mulmod(B->x, mu, modulus, precomp[1<<2]->x)) != CRYPT_OK) { goto ERR_MU; } if ((err = mp_mulmod(B->y, mu, modulus, precomp[1<<2]->y)) != CRYPT_OK) { goto ERR_MU; } if ((err = mp_mulmod(B->z, mu, modulus, precomp[1<<2]->z)) != CRYPT_OK) { goto ERR_MU; } /* precomp [i,0](A + B) table */ if ((err = ltc_mp.ecc_ptdbl(precomp[1], precomp[2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; } if ((err = ltc_mp.ecc_ptadd(precomp[1], precomp[2], precomp[3], modulus, mp)) != CRYPT_OK) { goto ERR_MU; } /* precomp [0,i](A + B) table */ if ((err = ltc_mp.ecc_ptdbl(precomp[1<<2], precomp[2<<2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; } if ((err = ltc_mp.ecc_ptadd(precomp[1<<2], precomp[2<<2], precomp[3<<2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; } /* precomp [i,j](A + B) table (i != 0, j != 0) */ for (x = 1; x < 4; x++) { for (y = 1; y < 4; y++) { if ((err = ltc_mp.ecc_ptadd(precomp[x], precomp[(y<<2)], precomp[x+(y<<2)], modulus, mp)) != CRYPT_OK) { goto ERR_MU; } } } nibble = 3; first = 1; bitbufA = tA[0]; bitbufB = tB[0]; /* for every byte of the multiplicands */ for (x = -1;; ) { /* grab a nibble */ if (++nibble == 4) { ++x; if (x == len) break; bitbufA = tA[x]; bitbufB = tB[x]; nibble = 0; } /* extract two bits from both, shift/update */ nA = (bitbufA >> 6) & 0x03; nB = (bitbufB >> 6) & 0x03; bitbufA = (bitbufA << 2) & 0xFF; bitbufB = (bitbufB << 2) & 0xFF; /* if both zero, if first, continue */ if ((nA == 0) && (nB == 0) && (first == 1)) { continue; } /* double twice, only if this isn't the first */ if (first == 0) { /* double twice */ if ((err = ltc_mp.ecc_ptdbl(C, C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } if ((err = ltc_mp.ecc_ptdbl(C, C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } } /* if not both zero */ if ((nA != 0) || (nB != 0)) { if (first == 1) { /* if first, copy from table */ first = 0; if ((err = mp_copy(precomp[nA + (nB<<2)]->x, C->x)) != CRYPT_OK) { goto ERR_MU; } if ((err = mp_copy(precomp[nA + (nB<<2)]->y, C->y)) != CRYPT_OK) { goto ERR_MU; } if ((err = mp_copy(precomp[nA + (nB<<2)]->z, C->z)) != CRYPT_OK) { goto ERR_MU; } } else { /* if not first, add from table */ if ((err = ltc_mp.ecc_ptadd(C, precomp[nA + (nB<<2)], C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } } } } /* reduce to affine */ err = ltc_ecc_map(C, modulus, mp); /* clean up */ ERR_MU: mp_clear(mu); ERR_MP: mp_montgomery_free(mp); ERR_P: for (x = 0; x < 16; x++) { ltc_ecc_del_point(precomp[x]); } ERR_T: #ifdef LTC_CLEAN_STACK zeromem(tA, ECC_BUF_SIZE); zeromem(tB, ECC_BUF_SIZE); #endif XFREE(tA); XFREE(tB); return err; } #endif #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_mul2add.c,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/ecc/ecc_free.c0000644000175100001440000000170210621351501016355 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b * * All curves taken from NIST recommendation paper of July 1999 * Available at http://csrc.nist.gov/cryptval/dss.htm */ #include "tomcrypt.h" /** @file ecc_free.c ECC Crypto, Tom St Denis */ #ifdef LTC_MECC /** Free an ECC key from memory @param key The key you wish to free */ void ecc_free(ecc_key *key) { LTC_ARGCHKVD(key != NULL); mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_free.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/ecc/ecc_get_size.c0000644000175100001440000000214610621351501017250 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b * * All curves taken from NIST recommendation paper of July 1999 * Available at http://csrc.nist.gov/cryptval/dss.htm */ #include "tomcrypt.h" /** @file ecc_get_size.c ECC Crypto, Tom St Denis */ #ifdef LTC_MECC /** Get the size of an ECC key @param key The key to get the size of @return The size (octets) of the key or INT_MAX on error */ int ecc_get_size(ecc_key *key) { LTC_ARGCHK(key != NULL); if (ltc_ecc_is_valid_idx(key->idx)) return key->dp->size; else return INT_MAX; /* large value known to cause it to fail when passed to ecc_make_key() */ } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_get_size.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/ecc/ltc_ecc_projective_add_point.c0000644000175100001440000002130010621351501022465 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b * * All curves taken from NIST recommendation paper of July 1999 * Available at http://csrc.nist.gov/cryptval/dss.htm */ #include "tomcrypt.h" /** @file ltc_ecc_projective_add_point.c ECC Crypto, Tom St Denis */ #if defined(LTC_MECC) && (!defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC)) /** Add two ECC points @param P The point to add @param Q The point to add @param R [out] The destination of the double @param modulus The modulus of the field the ECC curve is in @param mp The "b" value from montgomery_setup() @return CRYPT_OK on success */ int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp) { void *t1, *t2, *x, *y, *z; int err; LTC_ARGCHK(P != NULL); LTC_ARGCHK(Q != NULL); LTC_ARGCHK(R != NULL); LTC_ARGCHK(modulus != NULL); LTC_ARGCHK(mp != NULL); if ((err = mp_init_multi(&t1, &t2, &x, &y, &z, NULL)) != CRYPT_OK) { return err; } /* should we dbl instead? */ if ((err = mp_sub(modulus, Q->y, t1)) != CRYPT_OK) { goto done; } if ( (mp_cmp(P->x, Q->x) == LTC_MP_EQ) && (Q->z != NULL && mp_cmp(P->z, Q->z) == LTC_MP_EQ) && (mp_cmp(P->y, Q->y) == LTC_MP_EQ || mp_cmp(P->y, t1) == LTC_MP_EQ)) { mp_clear_multi(t1, t2, x, y, z, NULL); return ltc_ecc_projective_dbl_point(P, R, modulus, mp); } if ((err = mp_copy(P->x, x)) != CRYPT_OK) { goto done; } if ((err = mp_copy(P->y, y)) != CRYPT_OK) { goto done; } if ((err = mp_copy(P->z, z)) != CRYPT_OK) { goto done; } /* if Z is one then these are no-operations */ if (Q->z != NULL) { /* T1 = Z' * Z' */ if ((err = mp_sqr(Q->z, t1)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } /* X = X * T1 */ if ((err = mp_mul(t1, x, x)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(x, modulus, mp)) != CRYPT_OK) { goto done; } /* T1 = Z' * T1 */ if ((err = mp_mul(Q->z, t1, t1)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } /* Y = Y * T1 */ if ((err = mp_mul(t1, y, y)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(y, modulus, mp)) != CRYPT_OK) { goto done; } } /* T1 = Z*Z */ if ((err = mp_sqr(z, t1)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } /* T2 = X' * T1 */ if ((err = mp_mul(Q->x, t1, t2)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } /* T1 = Z * T1 */ if ((err = mp_mul(z, t1, t1)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } /* T1 = Y' * T1 */ if ((err = mp_mul(Q->y, t1, t1)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } /* Y = Y - T1 */ if ((err = mp_sub(y, t1, y)) != CRYPT_OK) { goto done; } if (mp_cmp_d(y, 0) == LTC_MP_LT) { if ((err = mp_add(y, modulus, y)) != CRYPT_OK) { goto done; } } /* T1 = 2T1 */ if ((err = mp_add(t1, t1, t1)) != CRYPT_OK) { goto done; } if (mp_cmp(t1, modulus) != LTC_MP_LT) { if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } } /* T1 = Y + T1 */ if ((err = mp_add(t1, y, t1)) != CRYPT_OK) { goto done; } if (mp_cmp(t1, modulus) != LTC_MP_LT) { if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } } /* X = X - T2 */ if ((err = mp_sub(x, t2, x)) != CRYPT_OK) { goto done; } if (mp_cmp_d(x, 0) == LTC_MP_LT) { if ((err = mp_add(x, modulus, x)) != CRYPT_OK) { goto done; } } /* T2 = 2T2 */ if ((err = mp_add(t2, t2, t2)) != CRYPT_OK) { goto done; } if (mp_cmp(t2, modulus) != LTC_MP_LT) { if ((err = mp_sub(t2, modulus, t2)) != CRYPT_OK) { goto done; } } /* T2 = X + T2 */ if ((err = mp_add(t2, x, t2)) != CRYPT_OK) { goto done; } if (mp_cmp(t2, modulus) != LTC_MP_LT) { if ((err = mp_sub(t2, modulus, t2)) != CRYPT_OK) { goto done; } } /* if Z' != 1 */ if (Q->z != NULL) { /* Z = Z * Z' */ if ((err = mp_mul(z, Q->z, z)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(z, modulus, mp)) != CRYPT_OK) { goto done; } } /* Z = Z * X */ if ((err = mp_mul(z, x, z)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(z, modulus, mp)) != CRYPT_OK) { goto done; } /* T1 = T1 * X */ if ((err = mp_mul(t1, x, t1)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } /* X = X * X */ if ((err = mp_sqr(x, x)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(x, modulus, mp)) != CRYPT_OK) { goto done; } /* T2 = T2 * x */ if ((err = mp_mul(t2, x, t2)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } /* T1 = T1 * X */ if ((err = mp_mul(t1, x, t1)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } /* X = Y*Y */ if ((err = mp_sqr(y, x)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(x, modulus, mp)) != CRYPT_OK) { goto done; } /* X = X - T2 */ if ((err = mp_sub(x, t2, x)) != CRYPT_OK) { goto done; } if (mp_cmp_d(x, 0) == LTC_MP_LT) { if ((err = mp_add(x, modulus, x)) != CRYPT_OK) { goto done; } } /* T2 = T2 - X */ if ((err = mp_sub(t2, x, t2)) != CRYPT_OK) { goto done; } if (mp_cmp_d(t2, 0) == LTC_MP_LT) { if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; } } /* T2 = T2 - X */ if ((err = mp_sub(t2, x, t2)) != CRYPT_OK) { goto done; } if (mp_cmp_d(t2, 0) == LTC_MP_LT) { if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; } } /* T2 = T2 * Y */ if ((err = mp_mul(t2, y, t2)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } /* Y = T2 - T1 */ if ((err = mp_sub(t2, t1, y)) != CRYPT_OK) { goto done; } if (mp_cmp_d(y, 0) == LTC_MP_LT) { if ((err = mp_add(y, modulus, y)) != CRYPT_OK) { goto done; } } /* Y = Y/2 */ if (mp_isodd(y)) { if ((err = mp_add(y, modulus, y)) != CRYPT_OK) { goto done; } } if ((err = mp_div_2(y, y)) != CRYPT_OK) { goto done; } if ((err = mp_copy(x, R->x)) != CRYPT_OK) { goto done; } if ((err = mp_copy(y, R->y)) != CRYPT_OK) { goto done; } if ((err = mp_copy(z, R->z)) != CRYPT_OK) { goto done; } err = CRYPT_OK; done: mp_clear_multi(t1, t2, x, y, z, NULL); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_projective_add_point.c,v $ */ /* $Revision: 1.16 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/ecc/ltc_ecc_mulmod_timing.c0000644000175100001440000001216110621351501021143 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b * * All curves taken from NIST recommendation paper of July 1999 * Available at http://csrc.nist.gov/cryptval/dss.htm */ #include "tomcrypt.h" /** @file ltc_ecc_mulmod_timing.c ECC Crypto, Tom St Denis */ #ifdef LTC_MECC #ifdef LTC_ECC_TIMING_RESISTANT /** Perform a point multiplication (timing resistant) @param k The scalar to multiply by @param G The base point @param R [out] Destination for kG @param modulus The modulus of the field the ECC curve is in @param map Boolean whether to map back to affine or not (1==map, 0 == leave in projective) @return CRYPT_OK on success */ int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map) { ecc_point *tG, *M[3]; int i, j, err; void *mu, *mp; unsigned long buf; int first, bitbuf, bitcpy, bitcnt, mode, digidx; LTC_ARGCHK(k != NULL); LTC_ARGCHK(G != NULL); LTC_ARGCHK(R != NULL); LTC_ARGCHK(modulus != NULL); /* init montgomery reduction */ if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { return err; } if ((err = mp_init(&mu)) != CRYPT_OK) { mp_montgomery_free(mp); return err; } if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { mp_clear(mu); mp_montgomery_free(mp); return err; } /* alloc ram for window temps */ for (i = 0; i < 3; i++) { M[i] = ltc_ecc_new_point(); if (M[i] == NULL) { for (j = 0; j < i; j++) { ltc_ecc_del_point(M[j]); } mp_clear(mu); mp_montgomery_free(mp); return CRYPT_MEM; } } /* make a copy of G incase R==G */ tG = ltc_ecc_new_point(); if (tG == NULL) { err = CRYPT_MEM; goto done; } /* tG = G and convert to montgomery */ if ((err = mp_mulmod(G->x, mu, modulus, tG->x)) != CRYPT_OK) { goto done; } if ((err = mp_mulmod(G->y, mu, modulus, tG->y)) != CRYPT_OK) { goto done; } if ((err = mp_mulmod(G->z, mu, modulus, tG->z)) != CRYPT_OK) { goto done; } mp_clear(mu); mu = NULL; /* calc the M tab */ /* M[0] == G */ if ((err = mp_copy(tG->x, M[0]->x)) != CRYPT_OK) { goto done; } if ((err = mp_copy(tG->y, M[0]->y)) != CRYPT_OK) { goto done; } if ((err = mp_copy(tG->z, M[0]->z)) != CRYPT_OK) { goto done; } /* M[1] == 2G */ if ((err = ltc_mp.ecc_ptdbl(tG, M[1], modulus, mp)) != CRYPT_OK) { goto done; } /* setup sliding window */ mode = 0; bitcnt = 1; buf = 0; digidx = mp_get_digit_count(k) - 1; bitcpy = bitbuf = 0; first = 1; /* perform ops */ for (;;) { /* grab next digit as required */ if (--bitcnt == 0) { if (digidx == -1) { break; } buf = mp_get_digit(k, digidx); bitcnt = (int) MP_DIGIT_BIT; --digidx; } /* grab the next msb from the ltiplicand */ i = (buf >> (MP_DIGIT_BIT - 1)) & 1; buf <<= 1; if (mode == 0 && i == 0) { /* dummy operations */ if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; } if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; } continue; } if (mode == 0 && i == 1) { mode = 1; /* dummy operations */ if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; } if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; } continue; } if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[i^1], modulus, mp)) != CRYPT_OK) { goto done; } if ((err = ltc_mp.ecc_ptdbl(M[i], M[i], modulus, mp)) != CRYPT_OK) { goto done; } } /* copy result out */ if ((err = mp_copy(M[0]->x, R->x)) != CRYPT_OK) { goto done; } if ((err = mp_copy(M[0]->y, R->y)) != CRYPT_OK) { goto done; } if ((err = mp_copy(M[0]->z, R->z)) != CRYPT_OK) { goto done; } /* map R back from projective space */ if (map) { err = ltc_ecc_map(R, modulus, mp); } else { err = CRYPT_OK; } done: if (mu != NULL) { mp_clear(mu); } mp_montgomery_free(mp); ltc_ecc_del_point(tG); for (i = 0; i < 3; i++) { ltc_ecc_del_point(M[i]); } return err; } #endif #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_mulmod_timing.c,v $ */ /* $Revision: 1.13 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/ecc/ecc_decrypt_key.c0000644000175100001440000000763610621351501017772 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b * * All curves taken from NIST recommendation paper of July 1999 * Available at http://csrc.nist.gov/cryptval/dss.htm */ #include "tomcrypt.h" /** @file ecc_decrypt_key.c ECC Crypto, Tom St Denis */ #ifdef LTC_MECC /** Decrypt an ECC encrypted key @param in The ciphertext @param inlen The length of the ciphertext (octets) @param out [out] The plaintext @param outlen [in/out] The max size and resulting size of the plaintext @param key The corresponding private ECC key @return CRYPT_OK if successful */ int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, ecc_key *key) { unsigned char *ecc_shared, *skey, *pub_expt; unsigned long x, y, hashOID[32]; int hash, err; ecc_key pubkey; ltc_asn1_list decode[3]; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); /* right key type? */ if (key->type != PK_PRIVATE) { return CRYPT_PK_NOT_PRIVATE; } /* decode to find out hash */ LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0])); if ((err = der_decode_sequence(in, inlen, decode, 1)) != CRYPT_OK) { return err; } hash = find_hash_oid(hashOID, decode[0].size); if (hash_is_valid(hash) != CRYPT_OK) { return CRYPT_INVALID_PACKET; } /* we now have the hash! */ /* allocate memory */ pub_expt = XMALLOC(ECC_BUF_SIZE); ecc_shared = XMALLOC(ECC_BUF_SIZE); skey = XMALLOC(MAXBLOCKSIZE); if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) { if (pub_expt != NULL) { XFREE(pub_expt); } if (ecc_shared != NULL) { XFREE(ecc_shared); } if (skey != NULL) { XFREE(skey); } return CRYPT_MEM; } LTC_SET_ASN1(decode, 1, LTC_ASN1_OCTET_STRING, pub_expt, ECC_BUF_SIZE); LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING, skey, MAXBLOCKSIZE); /* read the structure in now */ if ((err = der_decode_sequence(in, inlen, decode, 3)) != CRYPT_OK) { goto LBL_ERR; } /* import ECC key from packet */ if ((err = ecc_import(decode[1].data, decode[1].size, &pubkey)) != CRYPT_OK) { goto LBL_ERR; } /* make shared key */ x = ECC_BUF_SIZE; if ((err = ecc_shared_secret(key, &pubkey, ecc_shared, &x)) != CRYPT_OK) { ecc_free(&pubkey); goto LBL_ERR; } ecc_free(&pubkey); y = MIN(ECC_BUF_SIZE, MAXBLOCKSIZE); if ((err = hash_memory(hash, ecc_shared, x, ecc_shared, &y)) != CRYPT_OK) { goto LBL_ERR; } /* ensure the hash of the shared secret is at least as big as the encrypt itself */ if (decode[2].size > y) { err = CRYPT_INVALID_PACKET; goto LBL_ERR; } /* avoid buffer overflow */ if (*outlen < decode[2].size) { *outlen = decode[2].size; err = CRYPT_BUFFER_OVERFLOW; goto LBL_ERR; } /* Decrypt the key */ for (x = 0; x < decode[2].size; x++) { out[x] = skey[x] ^ ecc_shared[x]; } *outlen = x; err = CRYPT_OK; LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(pub_expt, ECC_BUF_SIZE); zeromem(ecc_shared, ECC_BUF_SIZE); zeromem(skey, MAXBLOCKSIZE); #endif XFREE(pub_expt); XFREE(ecc_shared); XFREE(skey); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_decrypt_key.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/ecc/ecc_test.c0000644000175100001440000000544210621351501016420 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b * * All curves taken from NIST recommendation paper of July 1999 * Available at http://csrc.nist.gov/cryptval/dss.htm */ #include "tomcrypt.h" /** @file ecc_test.c ECC Crypto, Tom St Denis */ #ifdef LTC_MECC /** Perform on the ECC system @return CRYPT_OK if successful */ int ecc_test(void) { void *modulus, *order; ecc_point *G, *GG; int i, err, primality; if ((err = mp_init_multi(&modulus, &order, NULL)) != CRYPT_OK) { return err; } G = ltc_ecc_new_point(); GG = ltc_ecc_new_point(); if (G == NULL || GG == NULL) { mp_clear_multi(modulus, order, NULL); ltc_ecc_del_point(G); ltc_ecc_del_point(GG); return CRYPT_MEM; } for (i = 0; ltc_ecc_sets[i].size; i++) { #if 0 printf("Testing %d\n", ltc_ecc_sets[i].size); #endif if ((err = mp_read_radix(modulus, (char *)ltc_ecc_sets[i].prime, 16)) != CRYPT_OK) { goto done; } if ((err = mp_read_radix(order, (char *)ltc_ecc_sets[i].order, 16)) != CRYPT_OK) { goto done; } /* is prime actually prime? */ if ((err = mp_prime_is_prime(modulus, 8, &primality)) != CRYPT_OK) { goto done; } if (primality == 0) { err = CRYPT_FAIL_TESTVECTOR; goto done; } /* is order prime ? */ if ((err = mp_prime_is_prime(order, 8, &primality)) != CRYPT_OK) { goto done; } if (primality == 0) { err = CRYPT_FAIL_TESTVECTOR; goto done; } if ((err = mp_read_radix(G->x, (char *)ltc_ecc_sets[i].Gx, 16)) != CRYPT_OK) { goto done; } if ((err = mp_read_radix(G->y, (char *)ltc_ecc_sets[i].Gy, 16)) != CRYPT_OK) { goto done; } mp_set(G->z, 1); /* then we should have G == (order + 1)G */ if ((err = mp_add_d(order, 1, order)) != CRYPT_OK) { goto done; } if ((err = ltc_mp.ecc_ptmul(order, G, GG, modulus, 1)) != CRYPT_OK) { goto done; } if (mp_cmp(G->x, GG->x) != LTC_MP_EQ || mp_cmp(G->y, GG->y) != LTC_MP_EQ) { err = CRYPT_FAIL_TESTVECTOR; goto done; } } err = CRYPT_OK; done: ltc_ecc_del_point(GG); ltc_ecc_del_point(G); mp_clear_multi(order, modulus, NULL); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_test.c,v $ */ /* $Revision: 1.12 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/ecc/ecc_import.c0000644000175100001440000001412410621351501016750 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b * * All curves taken from NIST recommendation paper of July 1999 * Available at http://csrc.nist.gov/cryptval/dss.htm */ #include "tomcrypt.h" /** @file ecc_import.c ECC Crypto, Tom St Denis */ #ifdef LTC_MECC static int is_point(ecc_key *key) { void *prime, *b, *t1, *t2; int err; if ((err = mp_init_multi(&prime, &b, &t1, &t2, NULL)) != CRYPT_OK) { return err; } /* load prime and b */ if ((err = mp_read_radix(prime, key->dp->prime, 16)) != CRYPT_OK) { goto error; } if ((err = mp_read_radix(b, key->dp->B, 16)) != CRYPT_OK) { goto error; } /* compute y^2 */ if ((err = mp_sqr(key->pubkey.y, t1)) != CRYPT_OK) { goto error; } /* compute x^3 */ if ((err = mp_sqr(key->pubkey.x, t2)) != CRYPT_OK) { goto error; } if ((err = mp_mod(t2, prime, t2)) != CRYPT_OK) { goto error; } if ((err = mp_mul(key->pubkey.x, t2, t2)) != CRYPT_OK) { goto error; } /* compute y^2 - x^3 */ if ((err = mp_sub(t1, t2, t1)) != CRYPT_OK) { goto error; } /* compute y^2 - x^3 + 3x */ if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; } if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; } if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; } if ((err = mp_mod(t1, prime, t1)) != CRYPT_OK) { goto error; } while (mp_cmp_d(t1, 0) == LTC_MP_LT) { if ((err = mp_add(t1, prime, t1)) != CRYPT_OK) { goto error; } } while (mp_cmp(t1, prime) != LTC_MP_LT) { if ((err = mp_sub(t1, prime, t1)) != CRYPT_OK) { goto error; } } /* compare to b */ if (mp_cmp(t1, b) != LTC_MP_EQ) { err = CRYPT_INVALID_PACKET; } else { err = CRYPT_OK; } error: mp_clear_multi(prime, b, t1, t2, NULL); return err; } /** Import an ECC key from a binary packet @param in The packet to import @param inlen The length of the packet @param key [out] The destination of the import @return CRYPT_OK if successful, upon error all allocated memory will be freed */ int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key) { return ecc_import_ex(in, inlen, key, NULL); } /** Import an ECC key from a binary packet, using user supplied domain params rather than one of the NIST ones @param in The packet to import @param inlen The length of the packet @param key [out] The destination of the import @param dp pointer to user supplied params; must be the same as the params used when exporting @return CRYPT_OK if successful, upon error all allocated memory will be freed */ int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp) { unsigned long key_size; unsigned char flags[1]; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(key != NULL); LTC_ARGCHK(ltc_mp.name != NULL); /* init key */ if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL) != CRYPT_OK) { return CRYPT_MEM; } /* find out what type of key it is */ if ((err = der_decode_sequence_multi(in, inlen, LTC_ASN1_BIT_STRING, 1UL, &flags, LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto done; } if (flags[0] == 1) { /* private key */ key->type = PK_PRIVATE; if ((err = der_decode_sequence_multi(in, inlen, LTC_ASN1_BIT_STRING, 1UL, flags, LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, LTC_ASN1_INTEGER, 1UL, key->pubkey.x, LTC_ASN1_INTEGER, 1UL, key->pubkey.y, LTC_ASN1_INTEGER, 1UL, key->k, LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto done; } } else { /* public key */ key->type = PK_PUBLIC; if ((err = der_decode_sequence_multi(in, inlen, LTC_ASN1_BIT_STRING, 1UL, flags, LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, LTC_ASN1_INTEGER, 1UL, key->pubkey.x, LTC_ASN1_INTEGER, 1UL, key->pubkey.y, LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto done; } } if (dp == NULL) { /* find the idx */ for (key->idx = 0; ltc_ecc_sets[key->idx].size && (unsigned long)ltc_ecc_sets[key->idx].size != key_size; ++key->idx); if (ltc_ecc_sets[key->idx].size == 0) { err = CRYPT_INVALID_PACKET; goto done; } key->dp = <c_ecc_sets[key->idx]; } else { key->idx = -1; key->dp = dp; } /* set z */ if ((err = mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto done; } /* is it a point on the curve? */ if ((err = is_point(key)) != CRYPT_OK) { goto done; } /* we're good */ return CRYPT_OK; done: mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_import.c,v $ */ /* $Revision: 1.13 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/ecc/ltc_ecc_projective_dbl_point.c0000644000175100001440000001440610621351501022507 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b * * All curves taken from NIST recommendation paper of July 1999 * Available at http://csrc.nist.gov/cryptval/dss.htm */ #include "tomcrypt.h" /** @file ltc_ecc_projective_dbl_point.c ECC Crypto, Tom St Denis */ #if defined(LTC_MECC) && (!defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC)) /** Double an ECC point @param P The point to double @param R [out] The destination of the double @param modulus The modulus of the field the ECC curve is in @param mp The "b" value from montgomery_setup() @return CRYPT_OK on success */ int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp) { void *t1, *t2; int err; LTC_ARGCHK(P != NULL); LTC_ARGCHK(R != NULL); LTC_ARGCHK(modulus != NULL); LTC_ARGCHK(mp != NULL); if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) { return err; } if (P != R) { if ((err = mp_copy(P->x, R->x)) != CRYPT_OK) { goto done; } if ((err = mp_copy(P->y, R->y)) != CRYPT_OK) { goto done; } if ((err = mp_copy(P->z, R->z)) != CRYPT_OK) { goto done; } } /* t1 = Z * Z */ if ((err = mp_sqr(R->z, t1)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(t1, modulus, mp)) != CRYPT_OK) { goto done; } /* Z = Y * Z */ if ((err = mp_mul(R->z, R->y, R->z)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(R->z, modulus, mp)) != CRYPT_OK) { goto done; } /* Z = 2Z */ if ((err = mp_add(R->z, R->z, R->z)) != CRYPT_OK) { goto done; } if (mp_cmp(R->z, modulus) != LTC_MP_LT) { if ((err = mp_sub(R->z, modulus, R->z)) != CRYPT_OK) { goto done; } } /* T2 = X - T1 */ if ((err = mp_sub(R->x, t1, t2)) != CRYPT_OK) { goto done; } if (mp_cmp_d(t2, 0) == LTC_MP_LT) { if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; } } /* T1 = X + T1 */ if ((err = mp_add(t1, R->x, t1)) != CRYPT_OK) { goto done; } if (mp_cmp(t1, modulus) != LTC_MP_LT) { if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } } /* T2 = T1 * T2 */ if ((err = mp_mul(t1, t2, t2)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } /* T1 = 2T2 */ if ((err = mp_add(t2, t2, t1)) != CRYPT_OK) { goto done; } if (mp_cmp(t1, modulus) != LTC_MP_LT) { if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } } /* T1 = T1 + T2 */ if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; } if (mp_cmp(t1, modulus) != LTC_MP_LT) { if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } } /* Y = 2Y */ if ((err = mp_add(R->y, R->y, R->y)) != CRYPT_OK) { goto done; } if (mp_cmp(R->y, modulus) != LTC_MP_LT) { if ((err = mp_sub(R->y, modulus, R->y)) != CRYPT_OK) { goto done; } } /* Y = Y * Y */ if ((err = mp_sqr(R->y, R->y)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(R->y, modulus, mp)) != CRYPT_OK) { goto done; } /* T2 = Y * Y */ if ((err = mp_sqr(R->y, t2)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } /* T2 = T2/2 */ if (mp_isodd(t2)) { if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; } } if ((err = mp_div_2(t2, t2)) != CRYPT_OK) { goto done; } /* Y = Y * X */ if ((err = mp_mul(R->y, R->x, R->y)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(R->y, modulus, mp)) != CRYPT_OK) { goto done; } /* X = T1 * T1 */ if ((err = mp_sqr(t1, R->x)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(R->x, modulus, mp)) != CRYPT_OK) { goto done; } /* X = X - Y */ if ((err = mp_sub(R->x, R->y, R->x)) != CRYPT_OK) { goto done; } if (mp_cmp_d(R->x, 0) == LTC_MP_LT) { if ((err = mp_add(R->x, modulus, R->x)) != CRYPT_OK) { goto done; } } /* X = X - Y */ if ((err = mp_sub(R->x, R->y, R->x)) != CRYPT_OK) { goto done; } if (mp_cmp_d(R->x, 0) == LTC_MP_LT) { if ((err = mp_add(R->x, modulus, R->x)) != CRYPT_OK) { goto done; } } /* Y = Y - X */ if ((err = mp_sub(R->y, R->x, R->y)) != CRYPT_OK) { goto done; } if (mp_cmp_d(R->y, 0) == LTC_MP_LT) { if ((err = mp_add(R->y, modulus, R->y)) != CRYPT_OK) { goto done; } } /* Y = Y * T1 */ if ((err = mp_mul(R->y, t1, R->y)) != CRYPT_OK) { goto done; } if ((err = mp_montgomery_reduce(R->y, modulus, mp)) != CRYPT_OK) { goto done; } /* Y = Y - T2 */ if ((err = mp_sub(R->y, t2, R->y)) != CRYPT_OK) { goto done; } if (mp_cmp_d(R->y, 0) == LTC_MP_LT) { if ((err = mp_add(R->y, modulus, R->y)) != CRYPT_OK) { goto done; } } err = CRYPT_OK; done: mp_clear_multi(t1, t2, NULL); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ltc_ecc_projective_dbl_point.c,v $ */ /* $Revision: 1.11 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/ecc/ecc_encrypt_key.c0000644000175100001440000000774710621351501020007 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b * * All curves taken from NIST recommendation paper of July 1999 * Available at http://csrc.nist.gov/cryptval/dss.htm */ #include "tomcrypt.h" /** @file ecc_encrypt_key.c ECC Crypto, Tom St Denis */ #ifdef LTC_MECC /** Encrypt a symmetric key with ECC @param in The symmetric key you want to encrypt @param inlen The length of the key to encrypt (octets) @param out [out] The destination for the ciphertext @param outlen [in/out] The max size and resulting size of the ciphertext @param prng An active PRNG state @param wprng The index of the PRNG you wish to use @param hash The index of the hash you want to use @param key The ECC key you want to encrypt to @return CRYPT_OK if successful */ int ecc_encrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, prng_state *prng, int wprng, int hash, ecc_key *key) { unsigned char *pub_expt, *ecc_shared, *skey; ecc_key pubkey; unsigned long x, y, pubkeysize; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); /* check that wprng/cipher/hash are not invalid */ if ((err = prng_is_valid(wprng)) != CRYPT_OK) { return err; } if ((err = hash_is_valid(hash)) != CRYPT_OK) { return err; } if (inlen > hash_descriptor[hash].hashsize) { return CRYPT_INVALID_HASH; } /* make a random key and export the public copy */ if ((err = ecc_make_key_ex(prng, wprng, &pubkey, key->dp)) != CRYPT_OK) { return err; } pub_expt = XMALLOC(ECC_BUF_SIZE); ecc_shared = XMALLOC(ECC_BUF_SIZE); skey = XMALLOC(MAXBLOCKSIZE); if (pub_expt == NULL || ecc_shared == NULL || skey == NULL) { if (pub_expt != NULL) { XFREE(pub_expt); } if (ecc_shared != NULL) { XFREE(ecc_shared); } if (skey != NULL) { XFREE(skey); } ecc_free(&pubkey); return CRYPT_MEM; } pubkeysize = ECC_BUF_SIZE; if ((err = ecc_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) { ecc_free(&pubkey); goto LBL_ERR; } /* make random key */ x = ECC_BUF_SIZE; if ((err = ecc_shared_secret(&pubkey, key, ecc_shared, &x)) != CRYPT_OK) { ecc_free(&pubkey); goto LBL_ERR; } ecc_free(&pubkey); y = MAXBLOCKSIZE; if ((err = hash_memory(hash, ecc_shared, x, skey, &y)) != CRYPT_OK) { goto LBL_ERR; } /* Encrypt key */ for (x = 0; x < inlen; x++) { skey[x] ^= in[x]; } err = der_encode_sequence_multi(out, outlen, LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash].OIDlen, hash_descriptor[hash].OID, LTC_ASN1_OCTET_STRING, pubkeysize, pub_expt, LTC_ASN1_OCTET_STRING, inlen, skey, LTC_ASN1_EOL, 0UL, NULL); LBL_ERR: #ifdef LTC_CLEAN_STACK /* clean up */ zeromem(pub_expt, ECC_BUF_SIZE); zeromem(ecc_shared, ECC_BUF_SIZE); zeromem(skey, MAXBLOCKSIZE); #endif XFREE(skey); XFREE(ecc_shared); XFREE(pub_expt); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_encrypt_key.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/ecc/ecc_make_key.c0000644000175100001440000000774410621351501017235 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b * * All curves taken from NIST recommendation paper of July 1999 * Available at http://csrc.nist.gov/cryptval/dss.htm */ #include "tomcrypt.h" /** @file ecc_make_key.c ECC Crypto, Tom St Denis */ #ifdef LTC_MECC /** Make a new ECC key @param prng An active PRNG state @param wprng The index of the PRNG you wish to use @param keysize The keysize for the new key (in octets from 20 to 65 bytes) @param key [out] Destination of the newly created key @return CRYPT_OK if successful, upon error all allocated memory will be freed */ int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key) { int x, err; /* find key size */ for (x = 0; (keysize > ltc_ecc_sets[x].size) && (ltc_ecc_sets[x].size != 0); x++); keysize = ltc_ecc_sets[x].size; if (keysize > ECC_MAXSIZE || ltc_ecc_sets[x].size == 0) { return CRYPT_INVALID_KEYSIZE; } err = ecc_make_key_ex(prng, wprng, key, <c_ecc_sets[x]); key->idx = x; return err; } int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp) { int err; ecc_point *base; void *prime, *order; unsigned char *buf; int keysize; LTC_ARGCHK(key != NULL); LTC_ARGCHK(ltc_mp.name != NULL); LTC_ARGCHK(dp != NULL); /* good prng? */ if ((err = prng_is_valid(wprng)) != CRYPT_OK) { return err; } key->idx = -1; key->dp = dp; keysize = dp->size; /* allocate ram */ base = NULL; buf = XMALLOC(ECC_MAXSIZE); if (buf == NULL) { return CRYPT_MEM; } /* make up random string */ if (prng_descriptor[wprng].read(buf, (unsigned long)keysize, prng) != (unsigned long)keysize) { err = CRYPT_ERROR_READPRNG; goto ERR_BUF; } /* setup the key variables */ if ((err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, &prime, &order, NULL)) != CRYPT_OK) { goto ERR_BUF; } base = ltc_ecc_new_point(); if (base == NULL) { err = CRYPT_MEM; goto errkey; } /* read in the specs for this key */ if ((err = mp_read_radix(prime, (char *)key->dp->prime, 16)) != CRYPT_OK) { goto errkey; } if ((err = mp_read_radix(order, (char *)key->dp->order, 16)) != CRYPT_OK) { goto errkey; } if ((err = mp_read_radix(base->x, (char *)key->dp->Gx, 16)) != CRYPT_OK) { goto errkey; } if ((err = mp_read_radix(base->y, (char *)key->dp->Gy, 16)) != CRYPT_OK) { goto errkey; } if ((err = mp_set(base->z, 1)) != CRYPT_OK) { goto errkey; } if ((err = mp_read_unsigned_bin(key->k, (unsigned char *)buf, keysize)) != CRYPT_OK) { goto errkey; } /* the key should be smaller than the order of base point */ if (mp_cmp(key->k, order) != LTC_MP_LT) { if((err = mp_mod(key->k, order, key->k)) != CRYPT_OK) { goto errkey; } } /* make the public key */ if ((err = ltc_mp.ecc_ptmul(key->k, base, &key->pubkey, prime, 1)) != CRYPT_OK) { goto errkey; } key->type = PK_PRIVATE; /* free up ram */ err = CRYPT_OK; goto cleanup; errkey: mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL); cleanup: ltc_ecc_del_point(base); mp_clear_multi(prime, order, NULL); ERR_BUF: #ifdef LTC_CLEAN_STACK zeromem(buf, ECC_MAXSIZE); #endif XFREE(buf); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_make_key.c,v $ */ /* $Revision: 1.13 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/ecc/ecc_export.c0000644000175100001440000000507710621351501016766 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b * * All curves taken from NIST recommendation paper of July 1999 * Available at http://csrc.nist.gov/cryptval/dss.htm */ #include "tomcrypt.h" /** @file ecc_export.c ECC Crypto, Tom St Denis */ #ifdef LTC_MECC /** Export an ECC key as a binary packet @param out [out] Destination for the key @param outlen [in/out] Max size and resulting size of the exported key @param type The type of key you want to export (PK_PRIVATE or PK_PUBLIC) @param key The key to export @return CRYPT_OK if successful */ int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key) { int err; unsigned char flags[1]; unsigned long key_size; LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); /* type valid? */ if (key->type != PK_PRIVATE && type == PK_PRIVATE) { return CRYPT_PK_TYPE_MISMATCH; } if (ltc_ecc_is_valid_idx(key->idx) == 0) { return CRYPT_INVALID_ARG; } /* we store the NIST byte size */ key_size = key->dp->size; if (type == PK_PRIVATE) { flags[0] = 1; err = der_encode_sequence_multi(out, outlen, LTC_ASN1_BIT_STRING, 1UL, flags, LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, LTC_ASN1_INTEGER, 1UL, key->pubkey.x, LTC_ASN1_INTEGER, 1UL, key->pubkey.y, LTC_ASN1_INTEGER, 1UL, key->k, LTC_ASN1_EOL, 0UL, NULL); } else { flags[0] = 0; err = der_encode_sequence_multi(out, outlen, LTC_ASN1_BIT_STRING, 1UL, flags, LTC_ASN1_SHORT_INTEGER, 1UL, &key_size, LTC_ASN1_INTEGER, 1UL, key->pubkey.x, LTC_ASN1_INTEGER, 1UL, key->pubkey.y, LTC_ASN1_EOL, 0UL, NULL); } return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/ecc/ecc_export.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/dsa/0000755000175100001440000000000010621351501014473 5ustar tomuserslibtomcrypt-1.17/src/pk/dsa/dsa_verify_key.c0000644000175100001440000000525610621351501017652 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file dsa_verify_key.c DSA implementation, verify a key, Tom St Denis */ #ifdef LTC_MDSA /** Verify a DSA key for validity @param key The key to verify @param stat [out] Result of test, 1==valid, 0==invalid @return CRYPT_OK if successful */ int dsa_verify_key(dsa_key *key, int *stat) { void *tmp, *tmp2; int res, err; LTC_ARGCHK(key != NULL); LTC_ARGCHK(stat != NULL); /* default to an invalid key */ *stat = 0; /* first make sure key->q and key->p are prime */ if ((err = mp_prime_is_prime(key->q, 8, &res)) != CRYPT_OK) { return err; } if (res == 0) { return CRYPT_OK; } if ((err = mp_prime_is_prime(key->p, 8, &res)) != CRYPT_OK) { return err; } if (res == 0) { return CRYPT_OK; } /* now make sure that g is not -1, 0 or 1 and

g, 0) == LTC_MP_EQ || mp_cmp_d(key->g, 1) == LTC_MP_EQ) { return CRYPT_OK; } if ((err = mp_init_multi(&tmp, &tmp2, NULL)) != CRYPT_OK) { return err; } if ((err = mp_sub_d(key->p, 1, tmp)) != CRYPT_OK) { goto error; } if (mp_cmp(tmp, key->g) == LTC_MP_EQ || mp_cmp(key->g, key->p) != LTC_MP_LT) { err = CRYPT_OK; goto error; } /* 1 < y < p-1 */ if (!(mp_cmp_d(key->y, 1) == LTC_MP_GT && mp_cmp(key->y, tmp) == LTC_MP_LT)) { err = CRYPT_OK; goto error; } /* now we have to make sure that g^q = 1, and that p-1/q gives 0 remainder */ if ((err = mp_div(tmp, key->q, tmp, tmp2)) != CRYPT_OK) { goto error; } if (mp_iszero(tmp2) != LTC_MP_YES) { err = CRYPT_OK; goto error; } if ((err = mp_exptmod(key->g, key->q, key->p, tmp)) != CRYPT_OK) { goto error; } if (mp_cmp_d(tmp, 1) != LTC_MP_EQ) { err = CRYPT_OK; goto error; } /* now we have to make sure that y^q = 1, this makes sure y \in g^x mod p */ if ((err = mp_exptmod(key->y, key->q, key->p, tmp)) != CRYPT_OK) { goto error; } if (mp_cmp_d(tmp, 1) != LTC_MP_EQ) { err = CRYPT_OK; goto error; } /* at this point we are out of tests ;-( */ err = CRYPT_OK; *stat = 1; error: mp_clear_multi(tmp, tmp2, NULL); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_verify_key.c,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/dsa/dsa_sign_hash.c0000644000175100001440000001161010621351501017430 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file dsa_sign_hash.c DSA implementation, sign a hash, Tom St Denis */ #ifdef LTC_MDSA /** Sign a hash with DSA @param in The hash to sign @param inlen The length of the hash to sign @param r The "r" integer of the signature (caller must initialize with mp_init() first) @param s The "s" integer of the signature (caller must initialize with mp_init() first) @param prng An active PRNG state @param wprng The index of the PRNG desired @param key A private DSA key @return CRYPT_OK if successful */ int dsa_sign_hash_raw(const unsigned char *in, unsigned long inlen, void *r, void *s, prng_state *prng, int wprng, dsa_key *key) { void *k, *kinv, *tmp; unsigned char *buf; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(r != NULL); LTC_ARGCHK(s != NULL); LTC_ARGCHK(key != NULL); if ((err = prng_is_valid(wprng)) != CRYPT_OK) { return err; } if (key->type != PK_PRIVATE) { return CRYPT_PK_NOT_PRIVATE; } /* check group order size */ if (key->qord >= LTC_MDSA_MAX_GROUP) { return CRYPT_INVALID_ARG; } buf = XMALLOC(LTC_MDSA_MAX_GROUP); if (buf == NULL) { return CRYPT_MEM; } /* Init our temps */ if ((err = mp_init_multi(&k, &kinv, &tmp, NULL)) != CRYPT_OK) { goto ERRBUF; } retry: do { /* gen random k */ if (prng_descriptor[wprng].read(buf, key->qord, prng) != (unsigned long)key->qord) { err = CRYPT_ERROR_READPRNG; goto error; } /* read k */ if ((err = mp_read_unsigned_bin(k, buf, key->qord)) != CRYPT_OK) { goto error; } /* k > 1 ? */ if (mp_cmp_d(k, 1) != LTC_MP_GT) { goto retry; } /* test gcd */ if ((err = mp_gcd(k, key->q, tmp)) != CRYPT_OK) { goto error; } } while (mp_cmp_d(tmp, 1) != LTC_MP_EQ); /* now find 1/k mod q */ if ((err = mp_invmod(k, key->q, kinv)) != CRYPT_OK) { goto error; } /* now find r = g^k mod p mod q */ if ((err = mp_exptmod(key->g, k, key->p, r)) != CRYPT_OK) { goto error; } if ((err = mp_mod(r, key->q, r)) != CRYPT_OK) { goto error; } if (mp_iszero(r) == LTC_MP_YES) { goto retry; } /* now find s = (in + xr)/k mod q */ if ((err = mp_read_unsigned_bin(tmp, (unsigned char *)in, inlen)) != CRYPT_OK) { goto error; } if ((err = mp_mul(key->x, r, s)) != CRYPT_OK) { goto error; } if ((err = mp_add(s, tmp, s)) != CRYPT_OK) { goto error; } if ((err = mp_mulmod(s, kinv, key->q, s)) != CRYPT_OK) { goto error; } if (mp_iszero(s) == LTC_MP_YES) { goto retry; } err = CRYPT_OK; error: mp_clear_multi(k, kinv, tmp, NULL); ERRBUF: #ifdef LTC_CLEAN_STACK zeromem(buf, LTC_MDSA_MAX_GROUP); #endif XFREE(buf); return err; } /** Sign a hash with DSA @param in The hash to sign @param inlen The length of the hash to sign @param out [out] Where to store the signature @param outlen [in/out] The max size and resulting size of the signature @param prng An active PRNG state @param wprng The index of the PRNG desired @param key A private DSA key @return CRYPT_OK if successful */ int dsa_sign_hash(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, prng_state *prng, int wprng, dsa_key *key) { void *r, *s; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); if (mp_init_multi(&r, &s, NULL) != CRYPT_OK) { return CRYPT_MEM; } if ((err = dsa_sign_hash_raw(in, inlen, r, s, prng, wprng, key)) != CRYPT_OK) { goto error; } err = der_encode_sequence_multi(out, outlen, LTC_ASN1_INTEGER, 1UL, r, LTC_ASN1_INTEGER, 1UL, s, LTC_ASN1_EOL, 0UL, NULL); error: mp_clear_multi(r, s, NULL); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_sign_hash.c,v $ */ /* $Revision: 1.14 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/dsa/dsa_free.c0000644000175100001440000000141610621351501016411 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file dsa_free.c DSA implementation, free a DSA key, Tom St Denis */ #ifdef LTC_MDSA /** Free a DSA key @param key The key to free from memory */ void dsa_free(dsa_key *key) { LTC_ARGCHKVD(key != NULL); mp_clear_multi(key->g, key->q, key->p, key->x, key->y, NULL); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_free.c,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/dsa/dsa_shared_secret.c0000644000175100001440000000374110621351501020306 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file dsa_shared_secret.c DSA Crypto, Tom St Denis */ #ifdef LTC_MDSA /** Create a DSA shared secret between two keys @param private_key The private DSA key (the exponent) @param base The base of the exponentiation (allows this to be used for both encrypt and decrypt) @param public_key The public key @param out [out] Destination of the shared secret @param outlen [in/out] The max size and resulting size of the shared secret @return CRYPT_OK if successful */ int dsa_shared_secret(void *private_key, void *base, dsa_key *public_key, unsigned char *out, unsigned long *outlen) { unsigned long x; void *res; int err; LTC_ARGCHK(private_key != NULL); LTC_ARGCHK(public_key != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* make new point */ if ((err = mp_init(&res)) != CRYPT_OK) { return err; } if ((err = mp_exptmod(base, private_key, public_key->p, res)) != CRYPT_OK) { mp_clear(res); return err; } x = (unsigned long)mp_unsigned_bin_size(res); if (*outlen < x) { *outlen = x; err = CRYPT_BUFFER_OVERFLOW; goto done; } zeromem(out, x); if ((err = mp_to_unsigned_bin(res, out + (x - mp_unsigned_bin_size(res)))) != CRYPT_OK) { goto done; } err = CRYPT_OK; *outlen = x; done: mp_clear(res); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_shared_secret.c,v $ */ /* $Revision: 1.9 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/dsa/dsa_decrypt_key.c0000644000175100001440000000675410621351501020024 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file dsa_decrypt_key.c DSA Crypto, Tom St Denis */ #ifdef LTC_MDSA /** Decrypt an DSA encrypted key @param in The ciphertext @param inlen The length of the ciphertext (octets) @param out [out] The plaintext @param outlen [in/out] The max size and resulting size of the plaintext @param key The corresponding private DSA key @return CRYPT_OK if successful */ int dsa_decrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, dsa_key *key) { unsigned char *skey, *expt; void *g_pub; unsigned long x, y, hashOID[32]; int hash, err; ltc_asn1_list decode[3]; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); /* right key type? */ if (key->type != PK_PRIVATE) { return CRYPT_PK_NOT_PRIVATE; } /* decode to find out hash */ LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0])); if ((err = der_decode_sequence(in, inlen, decode, 1)) != CRYPT_OK) { return err; } hash = find_hash_oid(hashOID, decode[0].size); if (hash_is_valid(hash) != CRYPT_OK) { return CRYPT_INVALID_PACKET; } /* we now have the hash! */ if ((err = mp_init(&g_pub)) != CRYPT_OK) { return err; } /* allocate memory */ expt = XMALLOC(mp_unsigned_bin_size(key->p) + 1); skey = XMALLOC(MAXBLOCKSIZE); if (expt == NULL || skey == NULL) { if (expt != NULL) { XFREE(expt); } if (skey != NULL) { XFREE(skey); } mp_clear(g_pub); return CRYPT_MEM; } LTC_SET_ASN1(decode, 1, LTC_ASN1_INTEGER, g_pub, 1UL); LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING, skey, MAXBLOCKSIZE); /* read the structure in now */ if ((err = der_decode_sequence(in, inlen, decode, 3)) != CRYPT_OK) { goto LBL_ERR; } /* make shared key */ x = mp_unsigned_bin_size(key->p) + 1; if ((err = dsa_shared_secret(key->x, g_pub, key, expt, &x)) != CRYPT_OK) { goto LBL_ERR; } y = MIN(mp_unsigned_bin_size(key->p) + 1, MAXBLOCKSIZE); if ((err = hash_memory(hash, expt, x, expt, &y)) != CRYPT_OK) { goto LBL_ERR; } /* ensure the hash of the shared secret is at least as big as the encrypt itself */ if (decode[2].size > y) { err = CRYPT_INVALID_PACKET; goto LBL_ERR; } /* avoid buffer overflow */ if (*outlen < decode[2].size) { *outlen = decode[2].size; err = CRYPT_BUFFER_OVERFLOW; goto LBL_ERR; } /* Decrypt the key */ for (x = 0; x < decode[2].size; x++) { out[x] = expt[x] ^ skey[x]; } *outlen = x; err = CRYPT_OK; LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(expt, mp_unsigned_bin_size(key->p) + 1); zeromem(skey, MAXBLOCKSIZE); #endif XFREE(expt); XFREE(skey); mp_clear(g_pub); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_decrypt_key.c,v $ */ /* $Revision: 1.11 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/dsa/dsa_encrypt_key.c0000644000175100001440000000761510621351501020033 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file dsa_encrypt_key.c DSA Crypto, Tom St Denis */ #ifdef LTC_MDSA /** Encrypt a symmetric key with DSA @param in The symmetric key you want to encrypt @param inlen The length of the key to encrypt (octets) @param out [out] The destination for the ciphertext @param outlen [in/out] The max size and resulting size of the ciphertext @param prng An active PRNG state @param wprng The index of the PRNG you wish to use @param hash The index of the hash you want to use @param key The DSA key you want to encrypt to @return CRYPT_OK if successful */ int dsa_encrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, prng_state *prng, int wprng, int hash, dsa_key *key) { unsigned char *expt, *skey; void *g_pub, *g_priv; unsigned long x, y; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); /* check that wprng/cipher/hash are not invalid */ if ((err = prng_is_valid(wprng)) != CRYPT_OK) { return err; } if ((err = hash_is_valid(hash)) != CRYPT_OK) { return err; } if (inlen > hash_descriptor[hash].hashsize) { return CRYPT_INVALID_HASH; } /* make a random key and export the public copy */ if ((err = mp_init_multi(&g_pub, &g_priv, NULL)) != CRYPT_OK) { return err; } expt = XMALLOC(mp_unsigned_bin_size(key->p) + 1); skey = XMALLOC(MAXBLOCKSIZE); if (expt == NULL || skey == NULL) { if (expt != NULL) { XFREE(expt); } if (skey != NULL) { XFREE(skey); } mp_clear_multi(g_pub, g_priv, NULL); return CRYPT_MEM; } /* make a random x, g^x pair */ x = mp_unsigned_bin_size(key->q); if (prng_descriptor[wprng].read(expt, x, prng) != x) { err = CRYPT_ERROR_READPRNG; goto LBL_ERR; } /* load x */ if ((err = mp_read_unsigned_bin(g_priv, expt, x)) != CRYPT_OK) { goto LBL_ERR; } /* compute y */ if ((err = mp_exptmod(key->g, g_priv, key->p, g_pub)) != CRYPT_OK) { goto LBL_ERR; } /* make random key */ x = mp_unsigned_bin_size(key->p) + 1; if ((err = dsa_shared_secret(g_priv, key->y, key, expt, &x)) != CRYPT_OK) { goto LBL_ERR; } y = MAXBLOCKSIZE; if ((err = hash_memory(hash, expt, x, skey, &y)) != CRYPT_OK) { goto LBL_ERR; } /* Encrypt key */ for (x = 0; x < inlen; x++) { skey[x] ^= in[x]; } err = der_encode_sequence_multi(out, outlen, LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash].OIDlen, hash_descriptor[hash].OID, LTC_ASN1_INTEGER, 1UL, g_pub, LTC_ASN1_OCTET_STRING, inlen, skey, LTC_ASN1_EOL, 0UL, NULL); LBL_ERR: #ifdef LTC_CLEAN_STACK /* clean up */ zeromem(expt, mp_unsigned_bin_size(key->p) + 1); zeromem(skey, MAXBLOCKSIZE); #endif XFREE(skey); XFREE(expt); mp_clear_multi(g_pub, g_priv, NULL); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_encrypt_key.c,v $ */ /* $Revision: 1.9 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/dsa/dsa_import.c0000644000175100001440000000576010621351501017010 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file dsa_import.c DSA implementation, import a DSA key, Tom St Denis */ #ifdef LTC_MDSA /** Import a DSA key @param in The binary packet to import from @param inlen The length of the binary packet @param key [out] Where to store the imported key @return CRYPT_OK if successful, upon error this function will free all allocated memory */ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key) { unsigned char flags[1]; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(key != NULL); LTC_ARGCHK(ltc_mp.name != NULL); /* init key */ if (mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL) != CRYPT_OK) { return CRYPT_MEM; } /* get key type */ if ((err = der_decode_sequence_multi(in, inlen, LTC_ASN1_BIT_STRING, 1UL, flags, LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto error; } if (flags[0] == 1) { if ((err = der_decode_sequence_multi(in, inlen, LTC_ASN1_BIT_STRING, 1UL, flags, LTC_ASN1_INTEGER, 1UL, key->g, LTC_ASN1_INTEGER, 1UL, key->p, LTC_ASN1_INTEGER, 1UL, key->q, LTC_ASN1_INTEGER, 1UL, key->y, LTC_ASN1_INTEGER, 1UL, key->x, LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto error; } key->type = PK_PRIVATE; } else { if ((err = der_decode_sequence_multi(in, inlen, LTC_ASN1_BIT_STRING, 1UL, flags, LTC_ASN1_INTEGER, 1UL, key->g, LTC_ASN1_INTEGER, 1UL, key->p, LTC_ASN1_INTEGER, 1UL, key->q, LTC_ASN1_INTEGER, 1UL, key->y, LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto error; } key->type = PK_PUBLIC; } key->qord = mp_unsigned_bin_size(key->q); if (key->qord >= LTC_MDSA_MAX_GROUP || key->qord <= 15 || (unsigned long)key->qord >= mp_unsigned_bin_size(key->p) || (mp_unsigned_bin_size(key->p) - key->qord) >= LTC_MDSA_DELTA) { err = CRYPT_INVALID_PACKET; goto error; } return CRYPT_OK; error: mp_clear_multi(key->p, key->g, key->q, key->x, key->y, NULL); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_import.c,v $ */ /* $Revision: 1.14 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/dsa/dsa_make_key.c0000644000175100001440000001062310621351501017255 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file dsa_make_key.c DSA implementation, generate a DSA key, Tom St Denis */ #ifdef LTC_MDSA /** Create a DSA key @param prng An active PRNG state @param wprng The index of the PRNG desired @param group_size Size of the multiplicative group (octets) @param modulus_size Size of the modulus (octets) @param key [out] Where to store the created key @return CRYPT_OK if successful, upon error this function will free all allocated memory */ int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key) { void *tmp, *tmp2; int err, res; unsigned char *buf; LTC_ARGCHK(key != NULL); LTC_ARGCHK(ltc_mp.name != NULL); /* check prng */ if ((err = prng_is_valid(wprng)) != CRYPT_OK) { return err; } /* check size */ if (group_size >= LTC_MDSA_MAX_GROUP || group_size <= 15 || group_size >= modulus_size || (modulus_size - group_size) >= LTC_MDSA_DELTA) { return CRYPT_INVALID_ARG; } /* allocate ram */ buf = XMALLOC(LTC_MDSA_DELTA); if (buf == NULL) { return CRYPT_MEM; } /* init mp_ints */ if ((err = mp_init_multi(&tmp, &tmp2, &key->g, &key->q, &key->p, &key->x, &key->y, NULL)) != CRYPT_OK) { XFREE(buf); return err; } /* make our prime q */ if ((err = rand_prime(key->q, group_size, prng, wprng)) != CRYPT_OK) { goto error; } /* double q */ if ((err = mp_add(key->q, key->q, tmp)) != CRYPT_OK) { goto error; } /* now make a random string and multply it against q */ if (prng_descriptor[wprng].read(buf+1, modulus_size - group_size, prng) != (unsigned long)(modulus_size - group_size)) { err = CRYPT_ERROR_READPRNG; goto error; } /* force magnitude */ buf[0] |= 0xC0; /* force even */ buf[modulus_size - group_size - 1] &= ~1; if ((err = mp_read_unsigned_bin(tmp2, buf, modulus_size - group_size)) != CRYPT_OK) { goto error; } if ((err = mp_mul(key->q, tmp2, key->p)) != CRYPT_OK) { goto error; } if ((err = mp_add_d(key->p, 1, key->p)) != CRYPT_OK) { goto error; } /* now loop until p is prime */ for (;;) { if ((err = mp_prime_is_prime(key->p, 8, &res)) != CRYPT_OK) { goto error; } if (res == LTC_MP_YES) break; /* add 2q to p and 2 to tmp2 */ if ((err = mp_add(tmp, key->p, key->p)) != CRYPT_OK) { goto error; } if ((err = mp_add_d(tmp2, 2, tmp2)) != CRYPT_OK) { goto error; } } /* now p = (q * tmp2) + 1 is prime, find a value g for which g^tmp2 != 1 */ mp_set(key->g, 1); do { if ((err = mp_add_d(key->g, 1, key->g)) != CRYPT_OK) { goto error; } if ((err = mp_exptmod(key->g, tmp2, key->p, tmp)) != CRYPT_OK) { goto error; } } while (mp_cmp_d(tmp, 1) == LTC_MP_EQ); /* at this point tmp generates a group of order q mod p */ mp_exch(tmp, key->g); /* so now we have our DH structure, generator g, order q, modulus p Now we need a random exponent [mod q] and it's power g^x mod p */ do { if (prng_descriptor[wprng].read(buf, group_size, prng) != (unsigned long)group_size) { err = CRYPT_ERROR_READPRNG; goto error; } if ((err = mp_read_unsigned_bin(key->x, buf, group_size)) != CRYPT_OK) { goto error; } } while (mp_cmp_d(key->x, 1) != LTC_MP_GT); if ((err = mp_exptmod(key->g, key->x, key->p, key->y)) != CRYPT_OK) { goto error; } key->type = PK_PRIVATE; key->qord = group_size; #ifdef LTC_CLEAN_STACK zeromem(buf, LTC_MDSA_DELTA); #endif err = CRYPT_OK; goto done; error: mp_clear_multi(key->g, key->q, key->p, key->x, key->y, NULL); done: mp_clear_multi(tmp, tmp2, NULL); XFREE(buf); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_make_key.c,v $ */ /* $Revision: 1.12 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/dsa/dsa_verify_hash.c0000644000175100001440000001003210621351501017771 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file dsa_verify_hash.c DSA implementation, verify a signature, Tom St Denis */ #ifdef LTC_MDSA /** Verify a DSA signature @param r DSA "r" parameter @param s DSA "s" parameter @param hash The hash that was signed @param hashlen The length of the hash that was signed @param stat [out] The result of the signature verification, 1==valid, 0==invalid @param key The corresponding public DH key @return CRYPT_OK if successful (even if the signature is invalid) */ int dsa_verify_hash_raw( void *r, void *s, const unsigned char *hash, unsigned long hashlen, int *stat, dsa_key *key) { void *w, *v, *u1, *u2; int err; LTC_ARGCHK(r != NULL); LTC_ARGCHK(s != NULL); LTC_ARGCHK(stat != NULL); LTC_ARGCHK(key != NULL); /* default to invalid signature */ *stat = 0; /* init our variables */ if ((err = mp_init_multi(&w, &v, &u1, &u2, NULL)) != CRYPT_OK) { return err; } /* neither r or s can be null or >q*/ if (mp_iszero(r) == LTC_MP_YES || mp_iszero(s) == LTC_MP_YES || mp_cmp(r, key->q) != LTC_MP_LT || mp_cmp(s, key->q) != LTC_MP_LT) { err = CRYPT_INVALID_PACKET; goto error; } /* w = 1/s mod q */ if ((err = mp_invmod(s, key->q, w)) != CRYPT_OK) { goto error; } /* u1 = m * w mod q */ if ((err = mp_read_unsigned_bin(u1, (unsigned char *)hash, hashlen)) != CRYPT_OK) { goto error; } if ((err = mp_mulmod(u1, w, key->q, u1)) != CRYPT_OK) { goto error; } /* u2 = r*w mod q */ if ((err = mp_mulmod(r, w, key->q, u2)) != CRYPT_OK) { goto error; } /* v = g^u1 * y^u2 mod p mod q */ if ((err = mp_exptmod(key->g, u1, key->p, u1)) != CRYPT_OK) { goto error; } if ((err = mp_exptmod(key->y, u2, key->p, u2)) != CRYPT_OK) { goto error; } if ((err = mp_mulmod(u1, u2, key->p, v)) != CRYPT_OK) { goto error; } if ((err = mp_mod(v, key->q, v)) != CRYPT_OK) { goto error; } /* if r = v then we're set */ if (mp_cmp(r, v) == LTC_MP_EQ) { *stat = 1; } err = CRYPT_OK; error: mp_clear_multi(w, v, u1, u2, NULL); return err; } /** Verify a DSA signature @param sig The signature @param siglen The length of the signature (octets) @param hash The hash that was signed @param hashlen The length of the hash that was signed @param stat [out] The result of the signature verification, 1==valid, 0==invalid @param key The corresponding public DH key @return CRYPT_OK if successful (even if the signature is invalid) */ int dsa_verify_hash(const unsigned char *sig, unsigned long siglen, const unsigned char *hash, unsigned long hashlen, int *stat, dsa_key *key) { int err; void *r, *s; if ((err = mp_init_multi(&r, &s, NULL)) != CRYPT_OK) { return CRYPT_MEM; } /* decode the sequence */ if ((err = der_decode_sequence_multi(sig, siglen, LTC_ASN1_INTEGER, 1UL, r, LTC_ASN1_INTEGER, 1UL, s, LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto LBL_ERR; } /* do the op */ err = dsa_verify_hash_raw(r, s, hash, hashlen, stat, key); LBL_ERR: mp_clear_multi(r, s, NULL); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_verify_hash.c,v $ */ /* $Revision: 1.15 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/dsa/dsa_export.c0000644000175100001440000000455310621351501017016 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file dsa_export.c DSA implementation, export key, Tom St Denis */ #ifdef LTC_MDSA /** Export a DSA key to a binary packet @param out [out] Where to store the packet @param outlen [in/out] The max size and resulting size of the packet @param type The type of key to export (PK_PRIVATE or PK_PUBLIC) @param key The key to export @return CRYPT_OK if successful */ int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key) { unsigned char flags[1]; LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); /* can we store the static header? */ if (type == PK_PRIVATE && key->type != PK_PRIVATE) { return CRYPT_PK_TYPE_MISMATCH; } if (type != PK_PUBLIC && type != PK_PRIVATE) { return CRYPT_INVALID_ARG; } flags[0] = (type != PK_PUBLIC) ? 1 : 0; if (type == PK_PRIVATE) { return der_encode_sequence_multi(out, outlen, LTC_ASN1_BIT_STRING, 1UL, flags, LTC_ASN1_INTEGER, 1UL, key->g, LTC_ASN1_INTEGER, 1UL, key->p, LTC_ASN1_INTEGER, 1UL, key->q, LTC_ASN1_INTEGER, 1UL, key->y, LTC_ASN1_INTEGER, 1UL, key->x, LTC_ASN1_EOL, 0UL, NULL); } else { return der_encode_sequence_multi(out, outlen, LTC_ASN1_BIT_STRING, 1UL, flags, LTC_ASN1_INTEGER, 1UL, key->g, LTC_ASN1_INTEGER, 1UL, key->p, LTC_ASN1_INTEGER, 1UL, key->q, LTC_ASN1_INTEGER, 1UL, key->y, LTC_ASN1_EOL, 0UL, NULL); } } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/dsa/dsa_export.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/rsa/0000755000175100001440000000000010621351501014511 5ustar tomuserslibtomcrypt-1.17/src/pk/rsa/rsa_sign_hash.c0000644000175100001440000001025110621351501017464 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file rsa_sign_hash.c RSA LTC_PKCS #1 v1.5 and v2 PSS sign hash, Tom St Denis and Andreas Lange */ #ifdef LTC_MRSA /** LTC_PKCS #1 pad then sign @param in The hash to sign @param inlen The length of the hash to sign (octets) @param out [out] The signature @param outlen [in/out] The max size and resulting size of the signature @param padding Type of padding (LTC_LTC_PKCS_1_PSS or LTC_LTC_PKCS_1_V1_5) @param prng An active PRNG state @param prng_idx The index of the PRNG desired @param hash_idx The index of the hash desired @param saltlen The length of the salt desired (octets) @param key The private RSA key to use @return CRYPT_OK if successful */ int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, int padding, prng_state *prng, int prng_idx, int hash_idx, unsigned long saltlen, rsa_key *key) { unsigned long modulus_bitlen, modulus_bytelen, x, y; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); /* valid padding? */ if ((padding != LTC_LTC_PKCS_1_V1_5) && (padding != LTC_LTC_PKCS_1_PSS)) { return CRYPT_PK_INVALID_PADDING; } if (padding == LTC_LTC_PKCS_1_PSS) { /* valid prng and hash ? */ if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { return err; } if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { return err; } } /* get modulus len in bits */ modulus_bitlen = mp_count_bits((key->N)); /* outlen must be at least the size of the modulus */ modulus_bytelen = mp_unsigned_bin_size((key->N)); if (modulus_bytelen > *outlen) { *outlen = modulus_bytelen; return CRYPT_BUFFER_OVERFLOW; } if (padding == LTC_LTC_PKCS_1_PSS) { /* PSS pad the key */ x = *outlen; if ((err = pkcs_1_pss_encode(in, inlen, saltlen, prng, prng_idx, hash_idx, modulus_bitlen, out, &x)) != CRYPT_OK) { return err; } } else { /* LTC_PKCS #1 v1.5 pad the hash */ unsigned char *tmpin; ltc_asn1_list digestinfo[2], siginfo[2]; /* not all hashes have OIDs... so sad */ if (hash_descriptor[hash_idx].OIDlen == 0) { return CRYPT_INVALID_ARG; } /* construct the SEQUENCE SEQUENCE { SEQUENCE {hashoid OID blah NULL } hash OCTET STRING } */ LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash_idx].OID, hash_descriptor[hash_idx].OIDlen); LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0); LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2); LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, in, inlen); /* allocate memory for the encoding */ y = mp_unsigned_bin_size(key->N); tmpin = XMALLOC(y); if (tmpin == NULL) { return CRYPT_MEM; } if ((err = der_encode_sequence(siginfo, 2, tmpin, &y)) != CRYPT_OK) { XFREE(tmpin); return err; } x = *outlen; if ((err = pkcs_1_v1_5_encode(tmpin, y, LTC_LTC_PKCS_1_EMSA, modulus_bitlen, NULL, 0, out, &x)) != CRYPT_OK) { XFREE(tmpin); return err; } XFREE(tmpin); } /* RSA encode it */ return ltc_mp.rsa_me(out, x, out, outlen, PK_PRIVATE, key); } #endif /* LTC_MRSA */ /* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_sign_hash.c,v $ */ /* $Revision: 1.11 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/rsa/rsa_verify_hash.c0000644000175100001440000001215010621351501020030 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file rsa_verify_hash.c RSA LTC_PKCS #1 v1.5 or v2 PSS signature verification, Tom St Denis and Andreas Lange */ #ifdef LTC_MRSA /** LTC_PKCS #1 de-sign then v1.5 or PSS depad @param sig The signature data @param siglen The length of the signature data (octets) @param hash The hash of the message that was signed @param hashlen The length of the hash of the message that was signed (octets) @param padding Type of padding (LTC_LTC_PKCS_1_PSS or LTC_LTC_PKCS_1_V1_5) @param hash_idx The index of the desired hash @param saltlen The length of the salt used during signature @param stat [out] The result of the signature comparison, 1==valid, 0==invalid @param key The public RSA key corresponding to the key that performed the signature @return CRYPT_OK on success (even if the signature is invalid) */ int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen, const unsigned char *hash, unsigned long hashlen, int padding, int hash_idx, unsigned long saltlen, int *stat, rsa_key *key) { unsigned long modulus_bitlen, modulus_bytelen, x; int err; unsigned char *tmpbuf; LTC_ARGCHK(hash != NULL); LTC_ARGCHK(sig != NULL); LTC_ARGCHK(stat != NULL); LTC_ARGCHK(key != NULL); /* default to invalid */ *stat = 0; /* valid padding? */ if ((padding != LTC_LTC_PKCS_1_V1_5) && (padding != LTC_LTC_PKCS_1_PSS)) { return CRYPT_PK_INVALID_PADDING; } if (padding == LTC_LTC_PKCS_1_PSS) { /* valid hash ? */ if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { return err; } } /* get modulus len in bits */ modulus_bitlen = mp_count_bits( (key->N)); /* outlen must be at least the size of the modulus */ modulus_bytelen = mp_unsigned_bin_size( (key->N)); if (modulus_bytelen != siglen) { return CRYPT_INVALID_PACKET; } /* allocate temp buffer for decoded sig */ tmpbuf = XMALLOC(siglen); if (tmpbuf == NULL) { return CRYPT_MEM; } /* RSA decode it */ x = siglen; if ((err = ltc_mp.rsa_me(sig, siglen, tmpbuf, &x, PK_PUBLIC, key)) != CRYPT_OK) { XFREE(tmpbuf); return err; } /* make sure the output is the right size */ if (x != siglen) { XFREE(tmpbuf); return CRYPT_INVALID_PACKET; } if (padding == LTC_LTC_PKCS_1_PSS) { /* PSS decode and verify it */ err = pkcs_1_pss_decode(hash, hashlen, tmpbuf, x, saltlen, hash_idx, modulus_bitlen, stat); } else { /* LTC_PKCS #1 v1.5 decode it */ unsigned char *out; unsigned long outlen, loid[16]; int decoded; ltc_asn1_list digestinfo[2], siginfo[2]; /* not all hashes have OIDs... so sad */ if (hash_descriptor[hash_idx].OIDlen == 0) { err = CRYPT_INVALID_ARG; goto bail_2; } /* allocate temp buffer for decoded hash */ outlen = ((modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0)) - 3; out = XMALLOC(outlen); if (out == NULL) { err = CRYPT_MEM; goto bail_2; } if ((err = pkcs_1_v1_5_decode(tmpbuf, x, LTC_LTC_PKCS_1_EMSA, modulus_bitlen, out, &outlen, &decoded)) != CRYPT_OK) { XFREE(out); goto bail_2; } /* now we must decode out[0...outlen-1] using ASN.1, test the OID and then test the hash */ /* construct the SEQUENCE SEQUENCE { SEQUENCE {hashoid OID blah NULL } hash OCTET STRING } */ LTC_SET_ASN1(digestinfo, 0, LTC_ASN1_OBJECT_IDENTIFIER, loid, sizeof(loid)/sizeof(loid[0])); LTC_SET_ASN1(digestinfo, 1, LTC_ASN1_NULL, NULL, 0); LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2); LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, tmpbuf, siglen); if ((err = der_decode_sequence(out, outlen, siginfo, 2)) != CRYPT_OK) { XFREE(out); goto bail_2; } /* test OID */ if ((digestinfo[0].size == hash_descriptor[hash_idx].OIDlen) && (XMEMCMP(digestinfo[0].data, hash_descriptor[hash_idx].OID, sizeof(unsigned long) * hash_descriptor[hash_idx].OIDlen) == 0) && (siginfo[1].size == hashlen) && (XMEMCMP(siginfo[1].data, hash, hashlen) == 0)) { *stat = 1; } #ifdef LTC_CLEAN_STACK zeromem(out, outlen); #endif XFREE(out); } bail_2: #ifdef LTC_CLEAN_STACK zeromem(tmpbuf, siglen); #endif XFREE(tmpbuf); return err; } #endif /* LTC_MRSA */ /* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_verify_hash.c,v $ */ /* $Revision: 1.13 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/rsa/rsa_decrypt_key.c0000644000175100001440000000616410621351501020053 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file rsa_decrypt_key.c RSA LTC_PKCS #1 Decryption, Tom St Denis and Andreas Lange */ #ifdef LTC_MRSA /** LTC_PKCS #1 decrypt then v1.5 or OAEP depad @param in The ciphertext @param inlen The length of the ciphertext (octets) @param out [out] The plaintext @param outlen [in/out] The max size and resulting size of the plaintext (octets) @param lparam The system "lparam" value @param lparamlen The length of the lparam value (octets) @param hash_idx The index of the hash desired @param padding Type of padding (LTC_LTC_PKCS_1_OAEP or LTC_LTC_PKCS_1_V1_5) @param stat [out] Result of the decryption, 1==valid, 0==invalid @param key The corresponding private RSA key @return CRYPT_OK if succcessul (even if invalid) */ int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, const unsigned char *lparam, unsigned long lparamlen, int hash_idx, int padding, int *stat, rsa_key *key) { unsigned long modulus_bitlen, modulus_bytelen, x; int err; unsigned char *tmp; LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); LTC_ARGCHK(stat != NULL); /* default to invalid */ *stat = 0; /* valid padding? */ if ((padding != LTC_LTC_PKCS_1_V1_5) && (padding != LTC_LTC_PKCS_1_OAEP)) { return CRYPT_PK_INVALID_PADDING; } if (padding == LTC_LTC_PKCS_1_OAEP) { /* valid hash ? */ if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { return err; } } /* get modulus len in bits */ modulus_bitlen = mp_count_bits( (key->N)); /* outlen must be at least the size of the modulus */ modulus_bytelen = mp_unsigned_bin_size( (key->N)); if (modulus_bytelen != inlen) { return CRYPT_INVALID_PACKET; } /* allocate ram */ tmp = XMALLOC(inlen); if (tmp == NULL) { return CRYPT_MEM; } /* rsa decode the packet */ x = inlen; if ((err = ltc_mp.rsa_me(in, inlen, tmp, &x, PK_PRIVATE, key)) != CRYPT_OK) { XFREE(tmp); return err; } if (padding == LTC_LTC_PKCS_1_OAEP) { /* now OAEP decode the packet */ err = pkcs_1_oaep_decode(tmp, x, lparam, lparamlen, modulus_bitlen, hash_idx, out, outlen, stat); } else { /* now LTC_PKCS #1 v1.5 depad the packet */ err = pkcs_1_v1_5_decode(tmp, x, LTC_LTC_PKCS_1_EME, modulus_bitlen, out, outlen, stat); } XFREE(tmp); return err; } #endif /* LTC_MRSA */ /* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_decrypt_key.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/rsa/rsa_import.c0000644000175100001440000001212110621351501017031 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file rsa_import.c Import a LTC_PKCS RSA key, Tom St Denis */ #ifdef LTC_MRSA /** Import an RSAPublicKey or RSAPrivateKey [two-prime only, only support >= 1024-bit keys, defined in LTC_PKCS #1 v2.1] @param in The packet to import from @param inlen It's length (octets) @param key [out] Destination for newly imported key @return CRYPT_OK if successful, upon error allocated memory is freed */ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key) { int err; void *zero; unsigned char *tmpbuf; unsigned long t, x, y, z, tmpoid[16]; ltc_asn1_list ssl_pubkey_hashoid[2]; ltc_asn1_list ssl_pubkey[2]; LTC_ARGCHK(in != NULL); LTC_ARGCHK(key != NULL); LTC_ARGCHK(ltc_mp.name != NULL); /* init key */ if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) { return err; } /* see if the OpenSSL DER format RSA public key will work */ tmpbuf = XCALLOC(1, MAX_RSA_SIZE*8); if (tmpbuf == NULL) { err = CRYPT_MEM; goto LBL_ERR; } /* this includes the internal hash ID and optional params (NULL in this case) */ LTC_SET_ASN1(ssl_pubkey_hashoid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0])); LTC_SET_ASN1(ssl_pubkey_hashoid, 1, LTC_ASN1_NULL, NULL, 0); /* the actual format of the SSL DER key is odd, it stores a RSAPublicKey in a **BIT** string ... so we have to extract it then proceed to convert bit to octet */ LTC_SET_ASN1(ssl_pubkey, 0, LTC_ASN1_SEQUENCE, &ssl_pubkey_hashoid, 2); LTC_SET_ASN1(ssl_pubkey, 1, LTC_ASN1_BIT_STRING, tmpbuf, MAX_RSA_SIZE*8); if (der_decode_sequence(in, inlen, ssl_pubkey, 2UL) == CRYPT_OK) { /* ok now we have to reassemble the BIT STRING to an OCTET STRING. Thanks OpenSSL... */ for (t = y = z = x = 0; x < ssl_pubkey[1].size; x++) { y = (y << 1) | tmpbuf[x]; if (++z == 8) { tmpbuf[t++] = (unsigned char)y; y = 0; z = 0; } } /* now it should be SEQUENCE { INTEGER, INTEGER } */ if ((err = der_decode_sequence_multi(tmpbuf, t, LTC_ASN1_INTEGER, 1UL, key->N, LTC_ASN1_INTEGER, 1UL, key->e, LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { XFREE(tmpbuf); goto LBL_ERR; } XFREE(tmpbuf); key->type = PK_PUBLIC; return CRYPT_OK; } XFREE(tmpbuf); /* not SSL public key, try to match against LTC_PKCS #1 standards */ if ((err = der_decode_sequence_multi(in, inlen, LTC_ASN1_INTEGER, 1UL, key->N, LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto LBL_ERR; } if (mp_cmp_d(key->N, 0) == LTC_MP_EQ) { if ((err = mp_init(&zero)) != CRYPT_OK) { goto LBL_ERR; } /* it's a private key */ if ((err = der_decode_sequence_multi(in, inlen, LTC_ASN1_INTEGER, 1UL, zero, LTC_ASN1_INTEGER, 1UL, key->N, LTC_ASN1_INTEGER, 1UL, key->e, LTC_ASN1_INTEGER, 1UL, key->d, LTC_ASN1_INTEGER, 1UL, key->p, LTC_ASN1_INTEGER, 1UL, key->q, LTC_ASN1_INTEGER, 1UL, key->dP, LTC_ASN1_INTEGER, 1UL, key->dQ, LTC_ASN1_INTEGER, 1UL, key->qP, LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { mp_clear(zero); goto LBL_ERR; } mp_clear(zero); key->type = PK_PRIVATE; } else if (mp_cmp_d(key->N, 1) == LTC_MP_EQ) { /* we don't support multi-prime RSA */ err = CRYPT_PK_INVALID_TYPE; goto LBL_ERR; } else { /* it's a public key and we lack e */ if ((err = der_decode_sequence_multi(in, inlen, LTC_ASN1_INTEGER, 1UL, key->N, LTC_ASN1_INTEGER, 1UL, key->e, LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto LBL_ERR; } key->type = PK_PUBLIC; } return CRYPT_OK; LBL_ERR: mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL); return err; } #endif /* LTC_MRSA */ /* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_import.c,v $ */ /* $Revision: 1.23 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/rsa/rsa_free.c0000644000175100001440000000143210621351501016443 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file rsa_free.c Free an RSA key, Tom St Denis */ #ifdef LTC_MRSA /** Free an RSA key from memory @param key The RSA key to free */ void rsa_free(rsa_key *key) { LTC_ARGCHKVD(key != NULL); mp_clear_multi(key->e, key->d, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_free.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/rsa/rsa_exptmod.c0000644000175100001440000000734310621351501017211 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file rsa_exptmod.c RSA LTC_PKCS exptmod, Tom St Denis */ #ifdef LTC_MRSA /** Compute an RSA modular exponentiation @param in The input data to send into RSA @param inlen The length of the input (octets) @param out [out] The destination @param outlen [in/out] The max size and resulting size of the output @param which Which exponent to use, e.g. PK_PRIVATE or PK_PUBLIC @param key The RSA key to use @return CRYPT_OK if successful */ int rsa_exptmod(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, int which, rsa_key *key) { void *tmp, *tmpa, *tmpb; unsigned long x; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); /* is the key of the right type for the operation? */ if (which == PK_PRIVATE && (key->type != PK_PRIVATE)) { return CRYPT_PK_NOT_PRIVATE; } /* must be a private or public operation */ if (which != PK_PRIVATE && which != PK_PUBLIC) { return CRYPT_PK_INVALID_TYPE; } /* init and copy into tmp */ if ((err = mp_init_multi(&tmp, &tmpa, &tmpb, NULL)) != CRYPT_OK) { return err; } if ((err = mp_read_unsigned_bin(tmp, (unsigned char *)in, (int)inlen)) != CRYPT_OK) { goto error; } /* sanity check on the input */ if (mp_cmp(key->N, tmp) == LTC_MP_LT) { err = CRYPT_PK_INVALID_SIZE; goto error; } /* are we using the private exponent and is the key optimized? */ if (which == PK_PRIVATE) { /* tmpa = tmp^dP mod p */ if ((err = mp_exptmod(tmp, key->dP, key->p, tmpa)) != CRYPT_OK) { goto error; } /* tmpb = tmp^dQ mod q */ if ((err = mp_exptmod(tmp, key->dQ, key->q, tmpb)) != CRYPT_OK) { goto error; } /* tmp = (tmpa - tmpb) * qInv (mod p) */ if ((err = mp_sub(tmpa, tmpb, tmp)) != CRYPT_OK) { goto error; } if ((err = mp_mulmod(tmp, key->qP, key->p, tmp)) != CRYPT_OK) { goto error; } /* tmp = tmpb + q * tmp */ if ((err = mp_mul(tmp, key->q, tmp)) != CRYPT_OK) { goto error; } if ((err = mp_add(tmp, tmpb, tmp)) != CRYPT_OK) { goto error; } } else { /* exptmod it */ if ((err = mp_exptmod(tmp, key->e, key->N, tmp)) != CRYPT_OK) { goto error; } } /* read it back */ x = (unsigned long)mp_unsigned_bin_size(key->N); if (x > *outlen) { *outlen = x; err = CRYPT_BUFFER_OVERFLOW; goto error; } /* this should never happen ... */ if (mp_unsigned_bin_size(tmp) > mp_unsigned_bin_size(key->N)) { err = CRYPT_ERROR; goto error; } *outlen = x; /* convert it */ zeromem(out, x); if ((err = mp_to_unsigned_bin(tmp, out+(x-mp_unsigned_bin_size(tmp)))) != CRYPT_OK) { goto error; } /* clean up and return */ err = CRYPT_OK; error: mp_clear_multi(tmp, tmpa, tmpb, NULL); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_exptmod.c,v $ */ /* $Revision: 1.18 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/rsa/rsa_encrypt_key.c0000644000175100001440000000624710621351501020067 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file rsa_encrypt_key.c RSA LTC_PKCS #1 encryption, Tom St Denis and Andreas Lange */ #ifdef LTC_MRSA /** (LTC_PKCS #1 v2.0) OAEP pad then encrypt @param in The plaintext @param inlen The length of the plaintext (octets) @param out [out] The ciphertext @param outlen [in/out] The max size and resulting size of the ciphertext @param lparam The system "lparam" for the encryption @param lparamlen The length of lparam (octets) @param prng An active PRNG @param prng_idx The index of the desired prng @param hash_idx The index of the desired hash @param padding Type of padding (LTC_LTC_PKCS_1_OAEP or LTC_LTC_PKCS_1_V1_5) @param key The RSA key to encrypt to @return CRYPT_OK if successful */ int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, const unsigned char *lparam, unsigned long lparamlen, prng_state *prng, int prng_idx, int hash_idx, int padding, rsa_key *key) { unsigned long modulus_bitlen, modulus_bytelen, x; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); /* valid padding? */ if ((padding != LTC_LTC_PKCS_1_V1_5) && (padding != LTC_LTC_PKCS_1_OAEP)) { return CRYPT_PK_INVALID_PADDING; } /* valid prng? */ if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { return err; } if (padding == LTC_LTC_PKCS_1_OAEP) { /* valid hash? */ if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { return err; } } /* get modulus len in bits */ modulus_bitlen = mp_count_bits( (key->N)); /* outlen must be at least the size of the modulus */ modulus_bytelen = mp_unsigned_bin_size( (key->N)); if (modulus_bytelen > *outlen) { *outlen = modulus_bytelen; return CRYPT_BUFFER_OVERFLOW; } if (padding == LTC_LTC_PKCS_1_OAEP) { /* OAEP pad the key */ x = *outlen; if ((err = pkcs_1_oaep_encode(in, inlen, lparam, lparamlen, modulus_bitlen, prng, prng_idx, hash_idx, out, &x)) != CRYPT_OK) { return err; } } else { /* LTC_PKCS #1 v1.5 pad the key */ x = *outlen; if ((err = pkcs_1_v1_5_encode(in, inlen, LTC_LTC_PKCS_1_EME, modulus_bitlen, prng, prng_idx, out, &x)) != CRYPT_OK) { return err; } } /* rsa exptmod the OAEP or LTC_PKCS #1 v1.5 pad */ return ltc_mp.rsa_me(out, x, out, outlen, PK_PUBLIC, key); } #endif /* LTC_MRSA */ /* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_encrypt_key.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/rsa/rsa_make_key.c0000644000175100001440000001100710621351501017306 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file rsa_make_key.c RSA key generation, Tom St Denis */ #ifdef LTC_MRSA /** Create an RSA key @param prng An active PRNG state @param wprng The index of the PRNG desired @param size The size of the modulus (key size) desired (octets) @param e The "e" value (public key). e==65537 is a good choice @param key [out] Destination of a newly created private key pair @return CRYPT_OK if successful, upon error all allocated ram is freed */ int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key) { void *p, *q, *tmp1, *tmp2, *tmp3; int err; LTC_ARGCHK(ltc_mp.name != NULL); LTC_ARGCHK(key != NULL); if ((size < (MIN_RSA_SIZE/8)) || (size > (MAX_RSA_SIZE/8))) { return CRYPT_INVALID_KEYSIZE; } if ((e < 3) || ((e & 1) == 0)) { return CRYPT_INVALID_ARG; } if ((err = prng_is_valid(wprng)) != CRYPT_OK) { return err; } if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != CRYPT_OK) { return err; } /* make primes p and q (optimization provided by Wayne Scott) */ if ((err = mp_set_int(tmp3, e)) != CRYPT_OK) { goto errkey; } /* tmp3 = e */ /* make prime "p" */ do { if ((err = rand_prime( p, size/2, prng, wprng)) != CRYPT_OK) { goto errkey; } if ((err = mp_sub_d( p, 1, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = p-1 */ if ((err = mp_gcd( tmp1, tmp3, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = gcd(p-1, e) */ } while (mp_cmp_d( tmp2, 1) != 0); /* while e divides p-1 */ /* make prime "q" */ do { if ((err = rand_prime( q, size/2, prng, wprng)) != CRYPT_OK) { goto errkey; } if ((err = mp_sub_d( q, 1, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = q-1 */ if ((err = mp_gcd( tmp1, tmp3, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = gcd(q-1, e) */ } while (mp_cmp_d( tmp2, 1) != 0); /* while e divides q-1 */ /* tmp1 = lcm(p-1, q-1) */ if ((err = mp_sub_d( p, 1, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = p-1 */ /* tmp1 = q-1 (previous do/while loop) */ if ((err = mp_lcm( tmp1, tmp2, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = lcm(p-1, q-1) */ /* make key */ if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL)) != CRYPT_OK) { goto errkey; } if ((err = mp_set_int( key->e, e)) != CRYPT_OK) { goto errkey; } /* key->e = e */ if ((err = mp_invmod( key->e, tmp1, key->d)) != CRYPT_OK) { goto errkey; } /* key->d = 1/e mod lcm(p-1,q-1) */ if ((err = mp_mul( p, q, key->N)) != CRYPT_OK) { goto errkey; } /* key->N = pq */ /* optimize for CRT now */ /* find d mod q-1 and d mod p-1 */ if ((err = mp_sub_d( p, 1, tmp1)) != CRYPT_OK) { goto errkey; } /* tmp1 = q-1 */ if ((err = mp_sub_d( q, 1, tmp2)) != CRYPT_OK) { goto errkey; } /* tmp2 = p-1 */ if ((err = mp_mod( key->d, tmp1, key->dP)) != CRYPT_OK) { goto errkey; } /* dP = d mod p-1 */ if ((err = mp_mod( key->d, tmp2, key->dQ)) != CRYPT_OK) { goto errkey; } /* dQ = d mod q-1 */ if ((err = mp_invmod( q, p, key->qP)) != CRYPT_OK) { goto errkey; } /* qP = 1/q mod p */ if ((err = mp_copy( p, key->p)) != CRYPT_OK) { goto errkey; } if ((err = mp_copy( q, key->q)) != CRYPT_OK) { goto errkey; } /* set key type (in this case it's CRT optimized) */ key->type = PK_PRIVATE; /* return ok and free temps */ err = CRYPT_OK; goto cleanup; errkey: mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL); cleanup: mp_clear_multi(tmp3, tmp2, tmp1, p, q, NULL); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_make_key.c,v $ */ /* $Revision: 1.16 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/rsa/rsa_export.c0000644000175100001440000000453510621351501017052 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file rsa_export.c Export RSA LTC_PKCS keys, Tom St Denis */ #ifdef LTC_MRSA /** This will export either an RSAPublicKey or RSAPrivateKey [defined in LTC_PKCS #1 v2.1] @param out [out] Destination of the packet @param outlen [in/out] The max size and resulting size of the packet @param type The type of exported key (PK_PRIVATE or PK_PUBLIC) @param key The RSA key to export @return CRYPT_OK if successful */ int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key) { unsigned long zero=0; LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); /* type valid? */ if (!(key->type == PK_PRIVATE) && (type == PK_PRIVATE)) { return CRYPT_PK_INVALID_TYPE; } if (type == PK_PRIVATE) { /* private key */ /* output is Version, n, e, d, p, q, d mod (p-1), d mod (q - 1), 1/q mod p */ return der_encode_sequence_multi(out, outlen, LTC_ASN1_SHORT_INTEGER, 1UL, &zero, LTC_ASN1_INTEGER, 1UL, key->N, LTC_ASN1_INTEGER, 1UL, key->e, LTC_ASN1_INTEGER, 1UL, key->d, LTC_ASN1_INTEGER, 1UL, key->p, LTC_ASN1_INTEGER, 1UL, key->q, LTC_ASN1_INTEGER, 1UL, key->dP, LTC_ASN1_INTEGER, 1UL, key->dQ, LTC_ASN1_INTEGER, 1UL, key->qP, LTC_ASN1_EOL, 0UL, NULL); } else { /* public key */ return der_encode_sequence_multi(out, outlen, LTC_ASN1_INTEGER, 1UL, key->N, LTC_ASN1_INTEGER, 1UL, key->e, LTC_ASN1_EOL, 0UL, NULL); } } #endif /* LTC_MRSA */ /* $Source: /cvs/libtom/libtomcrypt/src/pk/rsa/rsa_export.c,v $ */ /* $Revision: 1.17 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/asn1/0000755000175100001440000000000010621351501014566 5ustar tomuserslibtomcrypt-1.17/src/pk/asn1/der/0000755000175100001440000000000010621351501015340 5ustar tomuserslibtomcrypt-1.17/src/pk/asn1/der/bit/0000755000175100001440000000000010621351501016116 5ustar tomuserslibtomcrypt-1.17/src/pk/asn1/der/bit/der_length_bit_string.c0000644000175100001440000000260310621351501022622 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_length_bit_string.c ASN.1 DER, get length of BIT STRING, Tom St Denis */ #ifdef LTC_DER /** Gets length of DER encoding of BIT STRING @param nbits The number of bits in the string to encode @param outlen [out] The length of the DER encoding for the given string @return CRYPT_OK if successful */ int der_length_bit_string(unsigned long nbits, unsigned long *outlen) { unsigned long nbytes; LTC_ARGCHK(outlen != NULL); /* get the number of the bytes */ nbytes = (nbits >> 3) + ((nbits & 7) ? 1 : 0) + 1; if (nbytes < 128) { /* 03 LL PP DD DD DD ... */ *outlen = 2 + nbytes; } else if (nbytes < 256) { /* 03 81 LL PP DD DD DD ... */ *outlen = 3 + nbytes; } else if (nbytes < 65536) { /* 03 82 LL LL PP DD DD DD ... */ *outlen = 4 + nbytes; } else { return CRYPT_INVALID_ARG; } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_length_bit_string.c,v $ */ /* $Revision: 1.3 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/bit/der_decode_bit_string.c0000644000175100001440000000454110621351501022567 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_decode_bit_string.c ASN.1 DER, encode a BIT STRING, Tom St Denis */ #ifdef LTC_DER /** Store a BIT STRING @param in The DER encoded BIT STRING @param inlen The size of the DER BIT STRING @param out [out] The array of bits stored (one per char) @param outlen [in/out] The number of bits stored @return CRYPT_OK if successful */ int der_decode_bit_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { unsigned long dlen, blen, x, y; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* packet must be at least 4 bytes */ if (inlen < 4) { return CRYPT_INVALID_ARG; } /* check for 0x03 */ if ((in[0]&0x1F) != 0x03) { return CRYPT_INVALID_PACKET; } /* offset in the data */ x = 1; /* get the length of the data */ if (in[x] & 0x80) { /* long format get number of length bytes */ y = in[x++] & 0x7F; /* invalid if 0 or > 2 */ if (y == 0 || y > 2) { return CRYPT_INVALID_PACKET; } /* read the data len */ dlen = 0; while (y--) { dlen = (dlen << 8) | (unsigned long)in[x++]; } } else { /* short format */ dlen = in[x++] & 0x7F; } /* is the data len too long or too short? */ if ((dlen == 0) || (dlen + x > inlen)) { return CRYPT_INVALID_PACKET; } /* get padding count */ blen = ((dlen - 1) << 3) - (in[x++] & 7); /* too many bits? */ if (blen > *outlen) { *outlen = blen; return CRYPT_BUFFER_OVERFLOW; } /* decode/store the bits */ for (y = 0; y < blen; y++) { out[y] = (in[x] & (1 << (7 - (y & 7)))) ? 1 : 0; if ((y & 7) == 7) { ++x; } } /* we done */ *outlen = blen; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_decode_bit_string.c,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/bit/der_encode_bit_string.c0000644000175100001440000000436410621351501022604 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_encode_bit_string.c ASN.1 DER, encode a BIT STRING, Tom St Denis */ #ifdef LTC_DER /** Store a BIT STRING @param in The array of bits to store (one per char) @param inlen The number of bits tostore @param out [out] The destination for the DER encoded BIT STRING @param outlen [in/out] The max size and resulting size of the DER BIT STRING @return CRYPT_OK if successful */ int der_encode_bit_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { unsigned long len, x, y; unsigned char buf; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* avoid overflows */ if ((err = der_length_bit_string(inlen, &len)) != CRYPT_OK) { return err; } if (len > *outlen) { *outlen = len; return CRYPT_BUFFER_OVERFLOW; } /* store header (include bit padding count in length) */ x = 0; y = (inlen >> 3) + ((inlen&7) ? 1 : 0) + 1; out[x++] = 0x03; if (y < 128) { out[x++] = (unsigned char)y; } else if (y < 256) { out[x++] = 0x81; out[x++] = (unsigned char)y; } else if (y < 65536) { out[x++] = 0x82; out[x++] = (unsigned char)((y>>8)&255); out[x++] = (unsigned char)(y&255); } /* store number of zero padding bits */ out[x++] = (unsigned char)((8 - inlen) & 7); /* store the bits in big endian format */ for (y = buf = 0; y < inlen; y++) { buf |= (in[y] ? 1 : 0) << (7 - (y & 7)); if ((y & 7) == 7) { out[x++] = buf; buf = 0; } } /* store last byte */ if (inlen & 7) { out[x++] = buf; } *outlen = x; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/bit/der_encode_bit_string.c,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/ia5/0000755000175100001440000000000010621351501016016 5ustar tomuserslibtomcrypt-1.17/src/pk/asn1/der/ia5/der_length_ia5_string.c0000644000175100001440000000713410621351501022426 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_length_ia5_string.c ASN.1 DER, get length of IA5 STRING, Tom St Denis */ #ifdef LTC_DER static const struct { int code, value; } ia5_table[] = { { '\0', 0 }, { '\a', 7 }, { '\b', 8 }, { '\t', 9 }, { '\n', 10 }, { '\f', 12 }, { '\r', 13 }, { ' ', 32 }, { '!', 33 }, { '"', 34 }, { '#', 35 }, { '$', 36 }, { '%', 37 }, { '&', 38 }, { '\'', 39 }, { '(', 40 }, { ')', 41 }, { '*', 42 }, { '+', 43 }, { ',', 44 }, { '-', 45 }, { '.', 46 }, { '/', 47 }, { '0', 48 }, { '1', 49 }, { '2', 50 }, { '3', 51 }, { '4', 52 }, { '5', 53 }, { '6', 54 }, { '7', 55 }, { '8', 56 }, { '9', 57 }, { ':', 58 }, { ';', 59 }, { '<', 60 }, { '=', 61 }, { '>', 62 }, { '?', 63 }, { '@', 64 }, { 'A', 65 }, { 'B', 66 }, { 'C', 67 }, { 'D', 68 }, { 'E', 69 }, { 'F', 70 }, { 'G', 71 }, { 'H', 72 }, { 'I', 73 }, { 'J', 74 }, { 'K', 75 }, { 'L', 76 }, { 'M', 77 }, { 'N', 78 }, { 'O', 79 }, { 'P', 80 }, { 'Q', 81 }, { 'R', 82 }, { 'S', 83 }, { 'T', 84 }, { 'U', 85 }, { 'V', 86 }, { 'W', 87 }, { 'X', 88 }, { 'Y', 89 }, { 'Z', 90 }, { '[', 91 }, { '\\', 92 }, { ']', 93 }, { '^', 94 }, { '_', 95 }, { '`', 96 }, { 'a', 97 }, { 'b', 98 }, { 'c', 99 }, { 'd', 100 }, { 'e', 101 }, { 'f', 102 }, { 'g', 103 }, { 'h', 104 }, { 'i', 105 }, { 'j', 106 }, { 'k', 107 }, { 'l', 108 }, { 'm', 109 }, { 'n', 110 }, { 'o', 111 }, { 'p', 112 }, { 'q', 113 }, { 'r', 114 }, { 's', 115 }, { 't', 116 }, { 'u', 117 }, { 'v', 118 }, { 'w', 119 }, { 'x', 120 }, { 'y', 121 }, { 'z', 122 }, { '{', 123 }, { '|', 124 }, { '}', 125 }, { '~', 126 } }; int der_ia5_char_encode(int c) { int x; for (x = 0; x < (int)(sizeof(ia5_table)/sizeof(ia5_table[0])); x++) { if (ia5_table[x].code == c) { return ia5_table[x].value; } } return -1; } int der_ia5_value_decode(int v) { int x; for (x = 0; x < (int)(sizeof(ia5_table)/sizeof(ia5_table[0])); x++) { if (ia5_table[x].value == v) { return ia5_table[x].code; } } return -1; } /** Gets length of DER encoding of IA5 STRING @param octets The values you want to encode @param noctets The number of octets in the string to encode @param outlen [out] The length of the DER encoding for the given string @return CRYPT_OK if successful */ int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen) { unsigned long x; LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(octets != NULL); /* scan string for validity */ for (x = 0; x < noctets; x++) { if (der_ia5_char_encode(octets[x]) == -1) { return CRYPT_INVALID_ARG; } } if (noctets < 128) { /* 16 LL DD DD DD ... */ *outlen = 2 + noctets; } else if (noctets < 256) { /* 16 81 LL DD DD DD ... */ *outlen = 3 + noctets; } else if (noctets < 65536UL) { /* 16 82 LL LL DD DD DD ... */ *outlen = 4 + noctets; } else if (noctets < 16777216UL) { /* 16 83 LL LL LL DD DD DD ... */ *outlen = 5 + noctets; } else { return CRYPT_INVALID_ARG; } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/ia5/der_length_ia5_string.c,v $ */ /* $Revision: 1.3 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/ia5/der_decode_ia5_string.c0000644000175100001440000000420710621351501022366 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_decode_ia5_string.c ASN.1 DER, encode a IA5 STRING, Tom St Denis */ #ifdef LTC_DER /** Store a IA5 STRING @param in The DER encoded IA5 STRING @param inlen The size of the DER IA5 STRING @param out [out] The array of octets stored (one per char) @param outlen [in/out] The number of octets stored @return CRYPT_OK if successful */ int der_decode_ia5_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { unsigned long x, y, len; int t; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* must have header at least */ if (inlen < 2) { return CRYPT_INVALID_PACKET; } /* check for 0x16 */ if ((in[0] & 0x1F) != 0x16) { return CRYPT_INVALID_PACKET; } x = 1; /* decode the length */ if (in[x] & 0x80) { /* valid # of bytes in length are 1,2,3 */ y = in[x] & 0x7F; if ((y == 0) || (y > 3) || ((x + y) > inlen)) { return CRYPT_INVALID_PACKET; } /* read the length in */ len = 0; ++x; while (y--) { len = (len << 8) | in[x++]; } } else { len = in[x++] & 0x7F; } /* is it too long? */ if (len > *outlen) { *outlen = len; return CRYPT_BUFFER_OVERFLOW; } if (len + x > inlen) { return CRYPT_INVALID_PACKET; } /* read the data */ for (y = 0; y < len; y++) { t = der_ia5_value_decode(in[x++]); if (t == -1) { return CRYPT_INVALID_ARG; } out[y] = t; } *outlen = y; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/ia5/der_decode_ia5_string.c,v $ */ /* $Revision: 1.4 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/ia5/der_encode_ia5_string.c0000644000175100001440000000427210621351501022402 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_encode_ia5_string.c ASN.1 DER, encode a IA5 STRING, Tom St Denis */ #ifdef LTC_DER /** Store an IA5 STRING @param in The array of IA5 to store (one per char) @param inlen The number of IA5 to store @param out [out] The destination for the DER encoded IA5 STRING @param outlen [in/out] The max size and resulting size of the DER IA5 STRING @return CRYPT_OK if successful */ int der_encode_ia5_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { unsigned long x, y, len; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* get the size */ if ((err = der_length_ia5_string(in, inlen, &len)) != CRYPT_OK) { return err; } /* too big? */ if (len > *outlen) { *outlen = len; return CRYPT_BUFFER_OVERFLOW; } /* encode the header+len */ x = 0; out[x++] = 0x16; if (inlen < 128) { out[x++] = (unsigned char)inlen; } else if (inlen < 256) { out[x++] = 0x81; out[x++] = (unsigned char)inlen; } else if (inlen < 65536UL) { out[x++] = 0x82; out[x++] = (unsigned char)((inlen>>8)&255); out[x++] = (unsigned char)(inlen&255); } else if (inlen < 16777216UL) { out[x++] = 0x83; out[x++] = (unsigned char)((inlen>>16)&255); out[x++] = (unsigned char)((inlen>>8)&255); out[x++] = (unsigned char)(inlen&255); } else { return CRYPT_INVALID_ARG; } /* store octets */ for (y = 0; y < inlen; y++) { out[x++] = der_ia5_char_encode(in[y]); } /* retun length */ *outlen = x; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/ia5/der_encode_ia5_string.c,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/set/0000755000175100001440000000000010621351501016133 5ustar tomuserslibtomcrypt-1.17/src/pk/asn1/der/set/der_encode_set.c0000644000175100001440000000570110621351501021244 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_encode_set.c ASN.1 DER, Encode a SET, Tom St Denis */ #ifdef LTC_DER /* LTC define to ASN.1 TAG */ static int ltc_to_asn1(int v) { switch (v) { case LTC_ASN1_BOOLEAN: return 0x01; case LTC_ASN1_INTEGER: case LTC_ASN1_SHORT_INTEGER: return 0x02; case LTC_ASN1_BIT_STRING: return 0x03; case LTC_ASN1_OCTET_STRING: return 0x04; case LTC_ASN1_NULL: return 0x05; case LTC_ASN1_OBJECT_IDENTIFIER: return 0x06; case LTC_ASN1_UTF8_STRING: return 0x0C; case LTC_ASN1_PRINTABLE_STRING: return 0x13; case LTC_ASN1_IA5_STRING: return 0x16; case LTC_ASN1_UTCTIME: return 0x17; case LTC_ASN1_SEQUENCE: return 0x30; case LTC_ASN1_SET: case LTC_ASN1_SETOF: return 0x31; default: return -1; } } static int qsort_helper(const void *a, const void *b) { ltc_asn1_list *A = (ltc_asn1_list *)a, *B = (ltc_asn1_list *)b; int r; r = ltc_to_asn1(A->type) - ltc_to_asn1(B->type); /* for QSORT the order is UNDEFINED if they are "equal" which means it is NOT DETERMINISTIC. So we force it to be :-) */ if (r == 0) { /* their order in the original list now determines the position */ return A->used - B->used; } else { return r; } } /* Encode a SET type @param list The list of items to encode @param inlen The number of items in the list @param out [out] The destination @param outlen [in/out] The size of the output @return CRYPT_OK on success */ int der_encode_set(ltc_asn1_list *list, unsigned long inlen, unsigned char *out, unsigned long *outlen) { ltc_asn1_list *copy; unsigned long x; int err; /* make copy of list */ copy = XCALLOC(inlen, sizeof(*copy)); if (copy == NULL) { return CRYPT_MEM; } /* fill in used member with index so we can fully sort it */ for (x = 0; x < inlen; x++) { copy[x] = list[x]; copy[x].used = x; } /* sort it by the "type" field */ XQSORT(copy, inlen, sizeof(*copy), &qsort_helper); /* call der_encode_sequence_ex() */ err = der_encode_sequence_ex(copy, inlen, out, outlen, LTC_ASN1_SET); /* free list */ XFREE(copy); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/set/der_encode_set.c,v $ */ /* $Revision: 1.12 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/set/der_encode_setof.c0000644000175100001440000000735710621351501021602 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_encode_setof.c ASN.1 DER, Encode SET OF, Tom St Denis */ #ifdef LTC_DER struct edge { unsigned char *start; unsigned long size; }; static int qsort_helper(const void *a, const void *b) { struct edge *A = (struct edge *)a, *B = (struct edge *)b; int r; unsigned long x; /* compare min length */ r = XMEMCMP(A->start, B->start, MIN(A->size, B->size)); if (r == 0 && A->size != B->size) { if (A->size > B->size) { for (x = B->size; x < A->size; x++) { if (A->start[x]) { return 1; } } } else { for (x = A->size; x < B->size; x++) { if (B->start[x]) { return -1; } } } } return r; } /** Encode a SETOF stucture @param list The list of items to encode @param inlen The number of items in the list @param out [out] The destination @param outlen [in/out] The size of the output @return CRYPT_OK on success */ int der_encode_setof(ltc_asn1_list *list, unsigned long inlen, unsigned char *out, unsigned long *outlen) { unsigned long x, y, z, hdrlen; int err; struct edge *edges; unsigned char *ptr, *buf; /* check that they're all the same type */ for (x = 1; x < inlen; x++) { if (list[x].type != list[x-1].type) { return CRYPT_INVALID_ARG; } } /* alloc buffer to store copy of output */ buf = XCALLOC(1, *outlen); if (buf == NULL) { return CRYPT_MEM; } /* encode list */ if ((err = der_encode_sequence_ex(list, inlen, buf, outlen, LTC_ASN1_SETOF)) != CRYPT_OK) { XFREE(buf); return err; } /* allocate edges */ edges = XCALLOC(inlen, sizeof(*edges)); if (edges == NULL) { XFREE(buf); return CRYPT_MEM; } /* skip header */ ptr = buf + 1; /* now skip length data */ x = *ptr++; if (x >= 0x80) { ptr += (x & 0x7F); } /* get the size of the static header */ hdrlen = ((unsigned long)ptr) - ((unsigned long)buf); /* scan for edges */ x = 0; while (ptr < (buf + *outlen)) { /* store start */ edges[x].start = ptr; /* skip type */ z = 1; /* parse length */ y = ptr[z++]; if (y < 128) { edges[x].size = y; } else { y &= 0x7F; edges[x].size = 0; while (y--) { edges[x].size = (edges[x].size << 8) | ((unsigned long)ptr[z++]); } } /* skip content */ edges[x].size += z; ptr += edges[x].size; ++x; } /* sort based on contents (using edges) */ XQSORT(edges, inlen, sizeof(*edges), &qsort_helper); /* copy static header */ XMEMCPY(out, buf, hdrlen); /* copy+sort using edges+indecies to output from buffer */ for (y = hdrlen, x = 0; x < inlen; x++) { XMEMCPY(out+y, edges[x].start, edges[x].size); y += edges[x].size; } #ifdef LTC_CLEAN_STACK zeromem(buf, *outlen); #endif /* free buffers */ XFREE(edges); XFREE(buf); return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/set/der_encode_setof.c,v $ */ /* $Revision: 1.12 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/utf8/0000755000175100001440000000000010621351501016226 5ustar tomuserslibtomcrypt-1.17/src/pk/asn1/der/utf8/der_encode_utf8_string.c0000644000175100001440000000566710621351501023033 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_encode_utf8_string.c ASN.1 DER, encode a UTF8 STRING, Tom St Denis */ #ifdef LTC_DER /** Store an UTF8 STRING @param in The array of UTF8 to store (one per wchar_t) @param inlen The number of UTF8 to store @param out [out] The destination for the DER encoded UTF8 STRING @param outlen [in/out] The max size and resulting size of the DER UTF8 STRING @return CRYPT_OK if successful */ int der_encode_utf8_string(const wchar_t *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { unsigned long x, y, len; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* get the size */ for (x = len = 0; x < inlen; x++) { if (in[x] < 0 || in[x] > 0x1FFFF) { return CRYPT_INVALID_ARG; } len += der_utf8_charsize(in[x]); } if (len < 128) { y = 2 + len; } else if (len < 256) { y = 3 + len; } else if (len < 65536UL) { y = 4 + len; } else if (len < 16777216UL) { y = 5 + len; } else { return CRYPT_INVALID_ARG; } /* too big? */ if (y > *outlen) { *outlen = len; return CRYPT_BUFFER_OVERFLOW; } /* encode the header+len */ x = 0; out[x++] = 0x0C; if (len < 128) { out[x++] = (unsigned char)len; } else if (len < 256) { out[x++] = 0x81; out[x++] = (unsigned char)len; } else if (len < 65536UL) { out[x++] = 0x82; out[x++] = (unsigned char)((len>>8)&255); out[x++] = (unsigned char)(len&255); } else if (len < 16777216UL) { out[x++] = 0x83; out[x++] = (unsigned char)((len>>16)&255); out[x++] = (unsigned char)((len>>8)&255); out[x++] = (unsigned char)(len&255); } else { return CRYPT_INVALID_ARG; } /* store UTF8 */ for (y = 0; y < inlen; y++) { switch (der_utf8_charsize(in[y])) { case 1: out[x++] = (unsigned char)in[y]; break; case 2: out[x++] = 0xC0 | ((in[y] >> 6) & 0x1F); out[x++] = 0x80 | (in[y] & 0x3F); break; case 3: out[x++] = 0xE0 | ((in[y] >> 12) & 0x0F); out[x++] = 0x80 | ((in[y] >> 6) & 0x3F); out[x++] = 0x80 | (in[y] & 0x3F); break; case 4: out[x++] = 0xF0 | ((in[y] >> 18) & 0x07); out[x++] = 0x80 | ((in[y] >> 12) & 0x3F); out[x++] = 0x80 | ((in[y] >> 6) & 0x3F); out[x++] = 0x80 | (in[y] & 0x3F); break; } } /* retun length */ *outlen = x; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utf8/der_encode_utf8_string.c,v $ */ /* $Revision: 1.9 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/utf8/der_length_utf8_string.c0000644000175100001440000000376210621351501023051 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_length_utf8_string.c ASN.1 DER, get length of UTF8 STRING, Tom St Denis */ #ifdef LTC_DER /** Return the size in bytes of a UTF-8 character @param c The UTF-8 character to measure @return The size in bytes */ unsigned long der_utf8_charsize(const wchar_t c) { if (c <= 0x7F) { return 1; } else if (c <= 0x7FF) { return 2; } else if (c <= 0xFFFF) { return 3; } else { return 4; } } /** Gets length of DER encoding of UTF8 STRING @param in The characters to measure the length of @param noctets The number of octets in the string to encode @param outlen [out] The length of the DER encoding for the given string @return CRYPT_OK if successful */ int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen) { unsigned long x, len; LTC_ARGCHK(in != NULL); LTC_ARGCHK(outlen != NULL); len = 0; for (x = 0; x < noctets; x++) { if (in[x] < 0 || in[x] > 0x10FFFF) { return CRYPT_INVALID_ARG; } len += der_utf8_charsize(in[x]); } if (len < 128) { /* 0C LL DD DD DD ... */ *outlen = 2 + len; } else if (len < 256) { /* 0C 81 LL DD DD DD ... */ *outlen = 3 + len; } else if (len < 65536UL) { /* 0C 82 LL LL DD DD DD ... */ *outlen = 4 + len; } else if (len < 16777216UL) { /* 0C 83 LL LL LL DD DD DD ... */ *outlen = 5 + len; } else { return CRYPT_INVALID_ARG; } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utf8/der_length_utf8_string.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/utf8/der_decode_utf8_string.c0000644000175100001440000000507710621351501023014 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_decode_utf8_string.c ASN.1 DER, encode a UTF8 STRING, Tom St Denis */ #ifdef LTC_DER /** Store a UTF8 STRING @param in The DER encoded UTF8 STRING @param inlen The size of the DER UTF8 STRING @param out [out] The array of utf8s stored (one per char) @param outlen [in/out] The number of utf8s stored @return CRYPT_OK if successful */ int der_decode_utf8_string(const unsigned char *in, unsigned long inlen, wchar_t *out, unsigned long *outlen) { wchar_t tmp; unsigned long x, y, z, len; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* must have header at least */ if (inlen < 2) { return CRYPT_INVALID_PACKET; } /* check for 0x0C */ if ((in[0] & 0x1F) != 0x0C) { return CRYPT_INVALID_PACKET; } x = 1; /* decode the length */ if (in[x] & 0x80) { /* valid # of bytes in length are 1,2,3 */ y = in[x] & 0x7F; if ((y == 0) || (y > 3) || ((x + y) > inlen)) { return CRYPT_INVALID_PACKET; } /* read the length in */ len = 0; ++x; while (y--) { len = (len << 8) | in[x++]; } } else { len = in[x++] & 0x7F; } if (len + x > inlen) { return CRYPT_INVALID_PACKET; } /* proceed to decode */ for (y = 0; x < inlen; ) { /* get first byte */ tmp = in[x++]; /* count number of bytes */ for (z = 0; (tmp & 0x80) && (z <= 4); z++, tmp = (tmp << 1) & 0xFF); if (z > 4 || (x + (z - 1) > inlen)) { return CRYPT_INVALID_PACKET; } /* decode, grab upper bits */ tmp >>= z; /* grab remaining bytes */ if (z > 1) { --z; } while (z-- != 0) { if ((in[x] & 0xC0) != 0x80) { return CRYPT_INVALID_PACKET; } tmp = (tmp << 6) | ((wchar_t)in[x++] & 0x3F); } if (y > *outlen) { *outlen = y; return CRYPT_BUFFER_OVERFLOW; } out[y++] = tmp; } *outlen = y; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utf8/der_decode_utf8_string.c,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/short_integer/0000755000175100001440000000000010621351501020214 5ustar tomuserslibtomcrypt-1.17/src/pk/asn1/der/short_integer/der_length_short_integer.c0000644000175100001440000000265510621351501025437 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_length_short_integer.c ASN.1 DER, get length of encoding, Tom St Denis */ #ifdef LTC_DER /** Gets length of DER encoding of num @param num The integer to get the size of @param outlen [out] The length of the DER encoding for the given integer @return CRYPT_OK if successful */ int der_length_short_integer(unsigned long num, unsigned long *outlen) { unsigned long z, y, len; LTC_ARGCHK(outlen != NULL); /* force to 32 bits */ num &= 0xFFFFFFFFUL; /* get the number of bytes */ z = 0; y = num; while (y) { ++z; y >>= 8; } /* handle zero */ if (z == 0) { z = 1; } /* we need a 0x02 to indicate it's INTEGER */ len = 1; /* length byte */ ++len; /* bytes in value */ len += z; /* see if msb is set */ len += (num&(1UL<<((z<<3) - 1))) ? 1 : 0; /* return length */ *outlen = len; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/short_integer/der_length_short_integer.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/short_integer/der_encode_short_integer.c0000644000175100001440000000413010621351501025401 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_encode_short_integer.c ASN.1 DER, encode an integer, Tom St Denis */ #ifdef LTC_DER /** Store a short integer in the range (0,2^32-1) @param num The integer to encode @param out [out] The destination for the DER encoded integers @param outlen [in/out] The max size and resulting size of the DER encoded integers @return CRYPT_OK if successful */ int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen) { unsigned long len, x, y, z; int err; LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* force to 32 bits */ num &= 0xFFFFFFFFUL; /* find out how big this will be */ if ((err = der_length_short_integer(num, &len)) != CRYPT_OK) { return err; } if (*outlen < len) { *outlen = len; return CRYPT_BUFFER_OVERFLOW; } /* get len of output */ z = 0; y = num; while (y) { ++z; y >>= 8; } /* handle zero */ if (z == 0) { z = 1; } /* see if msb is set */ z += (num&(1UL<<((z<<3) - 1))) ? 1 : 0; /* adjust the number so the msB is non-zero */ for (x = 0; (z <= 4) && (x < (4 - z)); x++) { num <<= 8; } /* store header */ x = 0; out[x++] = 0x02; out[x++] = (unsigned char)z; /* if 31st bit is set output a leading zero and decrement count */ if (z == 5) { out[x++] = 0; --z; } /* store values */ for (y = 0; y < z; y++) { out[x++] = (unsigned char)((num >> 24) & 0xFF); num <<= 8; } /* we good */ *outlen = x; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/short_integer/der_encode_short_integer.c,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/short_integer/der_decode_short_integer.c0000644000175100001440000000263510621351501025377 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_decode_short_integer.c ASN.1 DER, decode an integer, Tom St Denis */ #ifdef LTC_DER /** Read a short integer @param in The DER encoded data @param inlen Size of data @param num [out] The integer to decode @return CRYPT_OK if successful */ int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num) { unsigned long len, x, y; LTC_ARGCHK(num != NULL); LTC_ARGCHK(in != NULL); /* check length */ if (inlen < 2) { return CRYPT_INVALID_PACKET; } /* check header */ x = 0; if ((in[x++] & 0x1F) != 0x02) { return CRYPT_INVALID_PACKET; } /* get the packet len */ len = in[x++]; if (x + len > inlen) { return CRYPT_INVALID_PACKET; } /* read number */ y = 0; while (len--) { y = (y<<8) | (unsigned long)in[x++]; } *num = y; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/short_integer/der_decode_short_integer.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/octet/0000755000175100001440000000000010621351501016456 5ustar tomuserslibtomcrypt-1.17/src/pk/asn1/der/octet/der_encode_octet_string.c0000644000175100001440000000427410621351501023504 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_encode_octet_string.c ASN.1 DER, encode a OCTET STRING, Tom St Denis */ #ifdef LTC_DER /** Store an OCTET STRING @param in The array of OCTETS to store (one per char) @param inlen The number of OCTETS to store @param out [out] The destination for the DER encoded OCTET STRING @param outlen [in/out] The max size and resulting size of the DER OCTET STRING @return CRYPT_OK if successful */ int der_encode_octet_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { unsigned long x, y, len; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* get the size */ if ((err = der_length_octet_string(inlen, &len)) != CRYPT_OK) { return err; } /* too big? */ if (len > *outlen) { *outlen = len; return CRYPT_BUFFER_OVERFLOW; } /* encode the header+len */ x = 0; out[x++] = 0x04; if (inlen < 128) { out[x++] = (unsigned char)inlen; } else if (inlen < 256) { out[x++] = 0x81; out[x++] = (unsigned char)inlen; } else if (inlen < 65536UL) { out[x++] = 0x82; out[x++] = (unsigned char)((inlen>>8)&255); out[x++] = (unsigned char)(inlen&255); } else if (inlen < 16777216UL) { out[x++] = 0x83; out[x++] = (unsigned char)((inlen>>16)&255); out[x++] = (unsigned char)((inlen>>8)&255); out[x++] = (unsigned char)(inlen&255); } else { return CRYPT_INVALID_ARG; } /* store octets */ for (y = 0; y < inlen; y++) { out[x++] = in[y]; } /* retun length */ *outlen = x; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/octet/der_encode_octet_string.c,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/octet/der_length_octet_string.c0000644000175100001440000000261310621351501023523 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_length_octet_string.c ASN.1 DER, get length of OCTET STRING, Tom St Denis */ #ifdef LTC_DER /** Gets length of DER encoding of OCTET STRING @param noctets The number of octets in the string to encode @param outlen [out] The length of the DER encoding for the given string @return CRYPT_OK if successful */ int der_length_octet_string(unsigned long noctets, unsigned long *outlen) { LTC_ARGCHK(outlen != NULL); if (noctets < 128) { /* 04 LL DD DD DD ... */ *outlen = 2 + noctets; } else if (noctets < 256) { /* 04 81 LL DD DD DD ... */ *outlen = 3 + noctets; } else if (noctets < 65536UL) { /* 04 82 LL LL DD DD DD ... */ *outlen = 4 + noctets; } else if (noctets < 16777216UL) { /* 04 83 LL LL LL DD DD DD ... */ *outlen = 5 + noctets; } else { return CRYPT_INVALID_ARG; } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/octet/der_length_octet_string.c,v $ */ /* $Revision: 1.3 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/octet/der_decode_octet_string.c0000644000175100001440000000403510621351501023465 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_decode_octet_string.c ASN.1 DER, encode a OCTET STRING, Tom St Denis */ #ifdef LTC_DER /** Store a OCTET STRING @param in The DER encoded OCTET STRING @param inlen The size of the DER OCTET STRING @param out [out] The array of octets stored (one per char) @param outlen [in/out] The number of octets stored @return CRYPT_OK if successful */ int der_decode_octet_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { unsigned long x, y, len; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* must have header at least */ if (inlen < 2) { return CRYPT_INVALID_PACKET; } /* check for 0x04 */ if ((in[0] & 0x1F) != 0x04) { return CRYPT_INVALID_PACKET; } x = 1; /* decode the length */ if (in[x] & 0x80) { /* valid # of bytes in length are 1,2,3 */ y = in[x] & 0x7F; if ((y == 0) || (y > 3) || ((x + y) > inlen)) { return CRYPT_INVALID_PACKET; } /* read the length in */ len = 0; ++x; while (y--) { len = (len << 8) | in[x++]; } } else { len = in[x++] & 0x7F; } /* is it too long? */ if (len > *outlen) { *outlen = len; return CRYPT_BUFFER_OVERFLOW; } if (len + x > inlen) { return CRYPT_INVALID_PACKET; } /* read the data */ for (y = 0; y < len; y++) { out[y] = in[x++]; } *outlen = y; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/octet/der_decode_octet_string.c,v $ */ /* $Revision: 1.4 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/printable_string/0000755000175100001440000000000010621351501020706 5ustar tomuserslibtomcrypt-1.17/src/pk/asn1/der/printable_string/der_encode_printable_string.c0000644000175100001440000000441110621351501026567 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_encode_printable_string.c ASN.1 DER, encode a printable STRING, Tom St Denis */ #ifdef LTC_DER /** Store an printable STRING @param in The array of printable to store (one per char) @param inlen The number of printable to store @param out [out] The destination for the DER encoded printable STRING @param outlen [in/out] The max size and resulting size of the DER printable STRING @return CRYPT_OK if successful */ int der_encode_printable_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { unsigned long x, y, len; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* get the size */ if ((err = der_length_printable_string(in, inlen, &len)) != CRYPT_OK) { return err; } /* too big? */ if (len > *outlen) { *outlen = len; return CRYPT_BUFFER_OVERFLOW; } /* encode the header+len */ x = 0; out[x++] = 0x13; if (inlen < 128) { out[x++] = (unsigned char)inlen; } else if (inlen < 256) { out[x++] = 0x81; out[x++] = (unsigned char)inlen; } else if (inlen < 65536UL) { out[x++] = 0x82; out[x++] = (unsigned char)((inlen>>8)&255); out[x++] = (unsigned char)(inlen&255); } else if (inlen < 16777216UL) { out[x++] = 0x83; out[x++] = (unsigned char)((inlen>>16)&255); out[x++] = (unsigned char)((inlen>>8)&255); out[x++] = (unsigned char)(inlen&255); } else { return CRYPT_INVALID_ARG; } /* store octets */ for (y = 0; y < inlen; y++) { out[x++] = der_printable_char_encode(in[y]); } /* retun length */ *outlen = x; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/printable_string/der_encode_printable_string.c,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/printable_string/der_length_printable_string.c0000644000175100001440000000650210621351501026616 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_length_printable_string.c ASN.1 DER, get length of Printable STRING, Tom St Denis */ #ifdef LTC_DER static const struct { int code, value; } printable_table[] = { { ' ', 32 }, { '\'', 39 }, { '(', 40 }, { ')', 41 }, { '+', 43 }, { ',', 44 }, { '-', 45 }, { '.', 46 }, { '/', 47 }, { '0', 48 }, { '1', 49 }, { '2', 50 }, { '3', 51 }, { '4', 52 }, { '5', 53 }, { '6', 54 }, { '7', 55 }, { '8', 56 }, { '9', 57 }, { ':', 58 }, { '=', 61 }, { '?', 63 }, { 'A', 65 }, { 'B', 66 }, { 'C', 67 }, { 'D', 68 }, { 'E', 69 }, { 'F', 70 }, { 'G', 71 }, { 'H', 72 }, { 'I', 73 }, { 'J', 74 }, { 'K', 75 }, { 'L', 76 }, { 'M', 77 }, { 'N', 78 }, { 'O', 79 }, { 'P', 80 }, { 'Q', 81 }, { 'R', 82 }, { 'S', 83 }, { 'T', 84 }, { 'U', 85 }, { 'V', 86 }, { 'W', 87 }, { 'X', 88 }, { 'Y', 89 }, { 'Z', 90 }, { 'a', 97 }, { 'b', 98 }, { 'c', 99 }, { 'd', 100 }, { 'e', 101 }, { 'f', 102 }, { 'g', 103 }, { 'h', 104 }, { 'i', 105 }, { 'j', 106 }, { 'k', 107 }, { 'l', 108 }, { 'm', 109 }, { 'n', 110 }, { 'o', 111 }, { 'p', 112 }, { 'q', 113 }, { 'r', 114 }, { 's', 115 }, { 't', 116 }, { 'u', 117 }, { 'v', 118 }, { 'w', 119 }, { 'x', 120 }, { 'y', 121 }, { 'z', 122 }, }; int der_printable_char_encode(int c) { int x; for (x = 0; x < (int)(sizeof(printable_table)/sizeof(printable_table[0])); x++) { if (printable_table[x].code == c) { return printable_table[x].value; } } return -1; } int der_printable_value_decode(int v) { int x; for (x = 0; x < (int)(sizeof(printable_table)/sizeof(printable_table[0])); x++) { if (printable_table[x].value == v) { return printable_table[x].code; } } return -1; } /** Gets length of DER encoding of Printable STRING @param octets The values you want to encode @param noctets The number of octets in the string to encode @param outlen [out] The length of the DER encoding for the given string @return CRYPT_OK if successful */ int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen) { unsigned long x; LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(octets != NULL); /* scan string for validity */ for (x = 0; x < noctets; x++) { if (der_printable_char_encode(octets[x]) == -1) { return CRYPT_INVALID_ARG; } } if (noctets < 128) { /* 16 LL DD DD DD ... */ *outlen = 2 + noctets; } else if (noctets < 256) { /* 16 81 LL DD DD DD ... */ *outlen = 3 + noctets; } else if (noctets < 65536UL) { /* 16 82 LL LL DD DD DD ... */ *outlen = 4 + noctets; } else if (noctets < 16777216UL) { /* 16 83 LL LL LL DD DD DD ... */ *outlen = 5 + noctets; } else { return CRYPT_INVALID_ARG; } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/printable_string/der_length_printable_string.c,v $ */ /* $Revision: 1.3 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/printable_string/der_decode_printable_string.c0000644000175100001440000000430410621351501026556 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_decode_printable_string.c ASN.1 DER, encode a printable STRING, Tom St Denis */ #ifdef LTC_DER /** Store a printable STRING @param in The DER encoded printable STRING @param inlen The size of the DER printable STRING @param out [out] The array of octets stored (one per char) @param outlen [in/out] The number of octets stored @return CRYPT_OK if successful */ int der_decode_printable_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { unsigned long x, y, len; int t; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* must have header at least */ if (inlen < 2) { return CRYPT_INVALID_PACKET; } /* check for 0x13 */ if ((in[0] & 0x1F) != 0x13) { return CRYPT_INVALID_PACKET; } x = 1; /* decode the length */ if (in[x] & 0x80) { /* valid # of bytes in length are 1,2,3 */ y = in[x] & 0x7F; if ((y == 0) || (y > 3) || ((x + y) > inlen)) { return CRYPT_INVALID_PACKET; } /* read the length in */ len = 0; ++x; while (y--) { len = (len << 8) | in[x++]; } } else { len = in[x++] & 0x7F; } /* is it too long? */ if (len > *outlen) { *outlen = len; return CRYPT_BUFFER_OVERFLOW; } if (len + x > inlen) { return CRYPT_INVALID_PACKET; } /* read the data */ for (y = 0; y < len; y++) { t = der_printable_value_decode(in[x++]); if (t == -1) { return CRYPT_INVALID_ARG; } out[y] = t; } *outlen = y; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/printable_string/der_decode_printable_string.c,v $ */ /* $Revision: 1.4 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/choice/0000755000175100001440000000000010621351501016572 5ustar tomuserslibtomcrypt-1.17/src/pk/asn1/der/choice/der_decode_choice.c0000644000175100001440000001327610621351501022336 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_decode_choice.c ASN.1 DER, decode a CHOICE, Tom St Denis */ #ifdef LTC_DER /** Decode a CHOICE @param in The DER encoded input @param inlen [in/out] The size of the input and resulting size of read type @param list The list of items to decode @param outlen The number of items in the list @return CRYPT_OK on success */ int der_decode_choice(const unsigned char *in, unsigned long *inlen, ltc_asn1_list *list, unsigned long outlen) { unsigned long size, x, z; void *data; LTC_ARGCHK(in != NULL); LTC_ARGCHK(inlen != NULL); LTC_ARGCHK(list != NULL); /* get blk size */ if (*inlen < 2) { return CRYPT_INVALID_PACKET; } /* set all of the "used" flags to zero */ for (x = 0; x < outlen; x++) { list[x].used = 0; } /* now scan until we have a winner */ for (x = 0; x < outlen; x++) { size = list[x].size; data = list[x].data; switch (list[x].type) { case LTC_ASN1_INTEGER: if (der_decode_integer(in, *inlen, data) == CRYPT_OK) { if (der_length_integer(data, &z) == CRYPT_OK) { list[x].used = 1; *inlen = z; return CRYPT_OK; } } break; case LTC_ASN1_SHORT_INTEGER: if (der_decode_short_integer(in, *inlen, data) == CRYPT_OK) { if (der_length_short_integer(size, &z) == CRYPT_OK) { list[x].used = 1; *inlen = z; return CRYPT_OK; } } break; case LTC_ASN1_BIT_STRING: if (der_decode_bit_string(in, *inlen, data, &size) == CRYPT_OK) { if (der_length_bit_string(size, &z) == CRYPT_OK) { list[x].used = 1; list[x].size = size; *inlen = z; return CRYPT_OK; } } break; case LTC_ASN1_OCTET_STRING: if (der_decode_octet_string(in, *inlen, data, &size) == CRYPT_OK) { if (der_length_octet_string(size, &z) == CRYPT_OK) { list[x].used = 1; list[x].size = size; *inlen = z; return CRYPT_OK; } } break; case LTC_ASN1_NULL: if (*inlen == 2 && in[x] == 0x05 && in[x+1] == 0x00) { *inlen = 2; list[x].used = 1; return CRYPT_OK; } break; case LTC_ASN1_OBJECT_IDENTIFIER: if (der_decode_object_identifier(in, *inlen, data, &size) == CRYPT_OK) { if (der_length_object_identifier(data, size, &z) == CRYPT_OK) { list[x].used = 1; list[x].size = size; *inlen = z; return CRYPT_OK; } } break; case LTC_ASN1_IA5_STRING: if (der_decode_ia5_string(in, *inlen, data, &size) == CRYPT_OK) { if (der_length_ia5_string(data, size, &z) == CRYPT_OK) { list[x].used = 1; list[x].size = size; *inlen = z; return CRYPT_OK; } } break; case LTC_ASN1_PRINTABLE_STRING: if (der_decode_printable_string(in, *inlen, data, &size) == CRYPT_OK) { if (der_length_printable_string(data, size, &z) == CRYPT_OK) { list[x].used = 1; list[x].size = size; *inlen = z; return CRYPT_OK; } } break; case LTC_ASN1_UTF8_STRING: if (der_decode_utf8_string(in, *inlen, data, &size) == CRYPT_OK) { if (der_length_utf8_string(data, size, &z) == CRYPT_OK) { list[x].used = 1; list[x].size = size; *inlen = z; return CRYPT_OK; } } break; case LTC_ASN1_UTCTIME: z = *inlen; if (der_decode_utctime(in, &z, data) == CRYPT_OK) { list[x].used = 1; *inlen = z; return CRYPT_OK; } break; case LTC_ASN1_SET: case LTC_ASN1_SETOF: case LTC_ASN1_SEQUENCE: if (der_decode_sequence(in, *inlen, data, size) == CRYPT_OK) { if (der_length_sequence(data, size, &z) == CRYPT_OK) { list[x].used = 1; *inlen = z; return CRYPT_OK; } } break; default: return CRYPT_INVALID_ARG; } } return CRYPT_INVALID_PACKET; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/choice/der_decode_choice.c,v $ */ /* $Revision: 1.9 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/utctime/0000755000175100001440000000000010621351501017012 5ustar tomuserslibtomcrypt-1.17/src/pk/asn1/der/utctime/der_length_utctime.c0000644000175100001440000000223210621351501023022 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_length_utctime.c ASN.1 DER, get length of UTCTIME, Tom St Denis */ #ifdef LTC_DER /** Gets length of DER encoding of UTCTIME @param utctime The UTC time structure to get the size of @param outlen [out] The length of the DER encoding @return CRYPT_OK if successful */ int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen) { LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(utctime != NULL); if (utctime->off_hh == 0 && utctime->off_mm == 0) { /* we encode as YYMMDDhhmmssZ */ *outlen = 2 + 13; } else { /* we encode as YYMMDDhhmmss{+|-}hh'mm' */ *outlen = 2 + 17; } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utctime/der_length_utctime.c,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/utctime/der_decode_utctime.c0000644000175100001440000000604010621351501022765 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_decode_utctime.c ASN.1 DER, decode a UTCTIME, Tom St Denis */ #ifdef LTC_DER static int char_to_int(unsigned char x) { switch (x) { case '0': return 0; case '1': return 1; case '2': return 2; case '3': return 3; case '4': return 4; case '5': return 5; case '6': return 6; case '7': return 7; case '8': return 8; case '9': return 9; } return 100; } #define DECODE_V(y, max) \ y = char_to_int(buf[x])*10 + char_to_int(buf[x+1]); \ if (y >= max) return CRYPT_INVALID_PACKET; \ x += 2; /** Decodes a UTC time structure in DER format (reads all 6 valid encoding formats) @param in Input buffer @param inlen Length of input buffer in octets @param out [out] Destination of UTC time structure @return CRYPT_OK if successful */ int der_decode_utctime(const unsigned char *in, unsigned long *inlen, ltc_utctime *out) { unsigned char buf[32]; unsigned long x; int y; LTC_ARGCHK(in != NULL); LTC_ARGCHK(inlen != NULL); LTC_ARGCHK(out != NULL); /* check header */ if (*inlen < 2UL || (in[1] >= sizeof(buf)) || ((in[1] + 2UL) > *inlen)) { return CRYPT_INVALID_PACKET; } /* decode the string */ for (x = 0; x < in[1]; x++) { y = der_ia5_value_decode(in[x+2]); if (y == -1) { return CRYPT_INVALID_PACKET; } buf[x] = y; } *inlen = 2 + x; /* possible encodings are YYMMDDhhmmZ YYMMDDhhmm+hh'mm' YYMMDDhhmm-hh'mm' YYMMDDhhmmssZ YYMMDDhhmmss+hh'mm' YYMMDDhhmmss-hh'mm' So let's do a trivial decode upto [including] mm */ x = 0; DECODE_V(out->YY, 100); DECODE_V(out->MM, 13); DECODE_V(out->DD, 32); DECODE_V(out->hh, 24); DECODE_V(out->mm, 60); /* clear timezone and seconds info */ out->off_dir = out->off_hh = out->off_mm = out->ss = 0; /* now is it Z, +, - or 0-9 */ if (buf[x] == 'Z') { return CRYPT_OK; } else if (buf[x] == '+' || buf[x] == '-') { out->off_dir = (buf[x++] == '+') ? 0 : 1; DECODE_V(out->off_hh, 24); DECODE_V(out->off_mm, 60); return CRYPT_OK; } /* decode seconds */ DECODE_V(out->ss, 60); /* now is it Z, +, - */ if (buf[x] == 'Z') { return CRYPT_OK; } else if (buf[x] == '+' || buf[x] == '-') { out->off_dir = (buf[x++] == '+') ? 0 : 1; DECODE_V(out->off_hh, 24); DECODE_V(out->off_mm, 60); return CRYPT_OK; } else { return CRYPT_INVALID_PACKET; } } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utctime/der_decode_utctime.c,v $ */ /* $Revision: 1.9 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/utctime/der_encode_utctime.c0000644000175100001440000000415510621351501023004 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_encode_utctime.c ASN.1 DER, encode a UTCTIME, Tom St Denis */ #ifdef LTC_DER static const char *baseten = "0123456789"; #define STORE_V(y) \ out[x++] = der_ia5_char_encode(baseten[(y/10) % 10]); \ out[x++] = der_ia5_char_encode(baseten[y % 10]); /** Encodes a UTC time structure in DER format @param utctime The UTC time structure to encode @param out The destination of the DER encoding of the UTC time structure @param outlen [in/out] The length of the DER encoding @return CRYPT_OK if successful */ int der_encode_utctime(ltc_utctime *utctime, unsigned char *out, unsigned long *outlen) { unsigned long x, tmplen; int err; LTC_ARGCHK(utctime != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); if ((err = der_length_utctime(utctime, &tmplen)) != CRYPT_OK) { return err; } if (tmplen > *outlen) { *outlen = tmplen; return CRYPT_BUFFER_OVERFLOW; } /* store header */ out[0] = 0x17; /* store values */ x = 2; STORE_V(utctime->YY); STORE_V(utctime->MM); STORE_V(utctime->DD); STORE_V(utctime->hh); STORE_V(utctime->mm); STORE_V(utctime->ss); if (utctime->off_mm || utctime->off_hh) { out[x++] = der_ia5_char_encode(utctime->off_dir ? '-' : '+'); STORE_V(utctime->off_hh); STORE_V(utctime->off_mm); } else { out[x++] = der_ia5_char_encode('Z'); } /* store length */ out[1] = (unsigned char)(x - 2); /* all good let's return */ *outlen = x; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/utctime/der_encode_utctime.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/sequence/0000755000175100001440000000000010621351501017150 5ustar tomuserslibtomcrypt-1.17/src/pk/asn1/der/sequence/der_decode_sequence_flexi.c0000644000175100001440000002456510621351501024464 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_decode_sequence_flexi.c ASN.1 DER, decode an array of ASN.1 types with a flexi parser, Tom St Denis */ #ifdef LTC_DER static unsigned long fetch_length(const unsigned char *in, unsigned long inlen) { unsigned long x, y, z; y = 0; /* skip type and read len */ if (inlen < 2) { return 0xFFFFFFFF; } ++in; ++y; /* read len */ x = *in++; ++y; /* <128 means literal */ if (x < 128) { return x+y; } x &= 0x7F; /* the lower 7 bits are the length of the length */ inlen -= 2; /* len means len of len! */ if (x == 0 || x > 4 || x > inlen) { return 0xFFFFFFFF; } y += x; z = 0; while (x--) { z = (z<<8) | ((unsigned long)*in); ++in; } return z+y; } /** ASN.1 DER Flexi(ble) decoder will decode arbitrary DER packets and create a linked list of the decoded elements. @param in The input buffer @param inlen [in/out] The length of the input buffer and on output the amount of decoded data @param out [out] A pointer to the linked list @return CRYPT_OK on success. */ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out) { ltc_asn1_list *l; unsigned long err, type, len, totlen, x, y; void *realloc_tmp; LTC_ARGCHK(in != NULL); LTC_ARGCHK(inlen != NULL); LTC_ARGCHK(out != NULL); l = NULL; totlen = 0; /* scan the input and and get lengths and what not */ while (*inlen) { /* read the type byte */ type = *in; /* fetch length */ len = fetch_length(in, *inlen); if (len > *inlen) { err = CRYPT_INVALID_PACKET; goto error; } /* alloc new link */ if (l == NULL) { l = XCALLOC(1, sizeof(*l)); if (l == NULL) { err = CRYPT_MEM; goto error; } } else { l->next = XCALLOC(1, sizeof(*l)); if (l->next == NULL) { err = CRYPT_MEM; goto error; } l->next->prev = l; l = l->next; } /* now switch on type */ switch (type) { case 0x01: /* BOOLEAN */ l->type = LTC_ASN1_BOOLEAN; l->size = 1; l->data = XCALLOC(1, sizeof(int)); if ((err = der_decode_boolean(in, *inlen, l->data)) != CRYPT_OK) { goto error; } if ((err = der_length_boolean(&len)) != CRYPT_OK) { goto error; } break; case 0x02: /* INTEGER */ /* init field */ l->type = LTC_ASN1_INTEGER; l->size = 1; if ((err = mp_init(&l->data)) != CRYPT_OK) { goto error; } /* decode field */ if ((err = der_decode_integer(in, *inlen, l->data)) != CRYPT_OK) { goto error; } /* calc length of object */ if ((err = der_length_integer(l->data, &len)) != CRYPT_OK) { goto error; } break; case 0x03: /* BIT */ /* init field */ l->type = LTC_ASN1_BIT_STRING; l->size = len * 8; /* *8 because we store decoded bits one per char and they are encoded 8 per char. */ if ((l->data = XCALLOC(1, l->size)) == NULL) { err = CRYPT_MEM; goto error; } if ((err = der_decode_bit_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { goto error; } if ((err = der_length_bit_string(l->size, &len)) != CRYPT_OK) { goto error; } break; case 0x04: /* OCTET */ /* init field */ l->type = LTC_ASN1_OCTET_STRING; l->size = len; if ((l->data = XCALLOC(1, l->size)) == NULL) { err = CRYPT_MEM; goto error; } if ((err = der_decode_octet_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { goto error; } if ((err = der_length_octet_string(l->size, &len)) != CRYPT_OK) { goto error; } break; case 0x05: /* NULL */ /* valid NULL is 0x05 0x00 */ if (in[0] != 0x05 || in[1] != 0x00) { err = CRYPT_INVALID_PACKET; goto error; } /* simple to store ;-) */ l->type = LTC_ASN1_NULL; l->data = NULL; l->size = 0; len = 2; break; case 0x06: /* OID */ /* init field */ l->type = LTC_ASN1_OBJECT_IDENTIFIER; l->size = len; if ((l->data = XCALLOC(len, sizeof(unsigned long))) == NULL) { err = CRYPT_MEM; goto error; } if ((err = der_decode_object_identifier(in, *inlen, l->data, &l->size)) != CRYPT_OK) { goto error; } if ((err = der_length_object_identifier(l->data, l->size, &len)) != CRYPT_OK) { goto error; } /* resize it to save a bunch of mem */ if ((realloc_tmp = XREALLOC(l->data, l->size * sizeof(unsigned long))) == NULL) { /* out of heap but this is not an error */ break; } l->data = realloc_tmp; break; case 0x0C: /* UTF8 */ /* init field */ l->type = LTC_ASN1_UTF8_STRING; l->size = len; if ((l->data = XCALLOC(sizeof(wchar_t), l->size)) == NULL) { err = CRYPT_MEM; goto error; } if ((err = der_decode_utf8_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { goto error; } if ((err = der_length_utf8_string(l->data, l->size, &len)) != CRYPT_OK) { goto error; } break; case 0x13: /* PRINTABLE */ /* init field */ l->type = LTC_ASN1_PRINTABLE_STRING; l->size = len; if ((l->data = XCALLOC(1, l->size)) == NULL) { err = CRYPT_MEM; goto error; } if ((err = der_decode_printable_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { goto error; } if ((err = der_length_printable_string(l->data, l->size, &len)) != CRYPT_OK) { goto error; } break; case 0x16: /* IA5 */ /* init field */ l->type = LTC_ASN1_IA5_STRING; l->size = len; if ((l->data = XCALLOC(1, l->size)) == NULL) { err = CRYPT_MEM; goto error; } if ((err = der_decode_ia5_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) { goto error; } if ((err = der_length_ia5_string(l->data, l->size, &len)) != CRYPT_OK) { goto error; } break; case 0x17: /* UTC TIME */ /* init field */ l->type = LTC_ASN1_UTCTIME; l->size = 1; if ((l->data = XCALLOC(1, sizeof(ltc_utctime))) == NULL) { err = CRYPT_MEM; goto error; } len = *inlen; if ((err = der_decode_utctime(in, &len, l->data)) != CRYPT_OK) { goto error; } if ((err = der_length_utctime(l->data, &len)) != CRYPT_OK) { goto error; } break; case 0x30: /* SEQUENCE */ case 0x31: /* SET */ /* init field */ l->type = (type == 0x30) ? LTC_ASN1_SEQUENCE : LTC_ASN1_SET; /* we have to decode the SEQUENCE header and get it's length */ /* move past type */ ++in; --(*inlen); /* read length byte */ x = *in++; --(*inlen); /* smallest SEQUENCE/SET header */ y = 2; /* now if it's > 127 the next bytes are the length of the length */ if (x > 128) { x &= 0x7F; in += x; *inlen -= x; /* update sequence header len */ y += x; } /* Sequence elements go as child */ len = len - y; if ((err = der_decode_sequence_flexi(in, &len, &(l->child))) != CRYPT_OK) { goto error; } /* len update */ totlen += y; /* link them up y0 */ l->child->parent = l; break; default: /* invalid byte ... this is a soft error */ /* remove link */ l = l->prev; XFREE(l->next); l->next = NULL; goto outside; } /* advance pointers */ totlen += len; in += len; *inlen -= len; } outside: /* rewind l please */ while (l->prev != NULL || l->parent != NULL) { if (l->parent != NULL) { l = l->parent; } else { l = l->prev; } } /* return */ *out = l; *inlen = totlen; return CRYPT_OK; error: /* free list */ der_sequence_free(l); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_flexi.c,v $ */ /* $Revision: 1.26 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/sequence/der_length_sequence.c0000644000175100001440000001046110621351501023321 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_length_sequence.c ASN.1 DER, length a SEQUENCE, Tom St Denis */ #ifdef LTC_DER /** Get the length of a DER sequence @param list The sequences of items in the SEQUENCE @param inlen The number of items @param outlen [out] The length required in octets to store it @return CRYPT_OK on success */ int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, unsigned long *outlen) { int err, type; unsigned long size, x, y, z, i; void *data; LTC_ARGCHK(list != NULL); LTC_ARGCHK(outlen != NULL); /* get size of output that will be required */ y = 0; for (i = 0; i < inlen; i++) { type = list[i].type; size = list[i].size; data = list[i].data; if (type == LTC_ASN1_EOL) { break; } switch (type) { case LTC_ASN1_BOOLEAN: if ((err = der_length_boolean(&x)) != CRYPT_OK) { goto LBL_ERR; } y += x; break; case LTC_ASN1_INTEGER: if ((err = der_length_integer(data, &x)) != CRYPT_OK) { goto LBL_ERR; } y += x; break; case LTC_ASN1_SHORT_INTEGER: if ((err = der_length_short_integer(*((unsigned long *)data), &x)) != CRYPT_OK) { goto LBL_ERR; } y += x; break; case LTC_ASN1_BIT_STRING: if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) { goto LBL_ERR; } y += x; break; case LTC_ASN1_OCTET_STRING: if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) { goto LBL_ERR; } y += x; break; case LTC_ASN1_NULL: y += 2; break; case LTC_ASN1_OBJECT_IDENTIFIER: if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) { goto LBL_ERR; } y += x; break; case LTC_ASN1_IA5_STRING: if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) { goto LBL_ERR; } y += x; break; case LTC_ASN1_PRINTABLE_STRING: if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) { goto LBL_ERR; } y += x; break; case LTC_ASN1_UTCTIME: if ((err = der_length_utctime(data, &x)) != CRYPT_OK) { goto LBL_ERR; } y += x; break; case LTC_ASN1_UTF8_STRING: if ((err = der_length_utf8_string(data, size, &x)) != CRYPT_OK) { goto LBL_ERR; } y += x; break; case LTC_ASN1_SET: case LTC_ASN1_SETOF: case LTC_ASN1_SEQUENCE: if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) { goto LBL_ERR; } y += x; break; default: err = CRYPT_INVALID_ARG; goto LBL_ERR; } } /* calc header size */ z = y; if (y < 128) { y += 2; } else if (y < 256) { /* 0x30 0x81 LL */ y += 3; } else if (y < 65536UL) { /* 0x30 0x82 LL LL */ y += 4; } else if (y < 16777216UL) { /* 0x30 0x83 LL LL LL */ y += 5; } else { err = CRYPT_INVALID_ARG; goto LBL_ERR; } /* store size */ *outlen = y; err = CRYPT_OK; LBL_ERR: return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_length_sequence.c,v $ */ /* $Revision: 1.14 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/sequence/der_decode_sequence_multi.c0000644000175100001440000000671610621351501024505 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" #include /** @file der_decode_sequence_multi.c ASN.1 DER, decode a SEQUENCE, Tom St Denis */ #ifdef LTC_DER /** Decode a SEQUENCE type using a VA list @param in Input buffer @param inlen Length of input in octets @remark <...> is of the form (int, unsigned long, void*) @return CRYPT_OK on success */ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...) { int err, type; unsigned long size, x; void *data; va_list args; ltc_asn1_list *list; LTC_ARGCHK(in != NULL); /* get size of output that will be required */ va_start(args, inlen); x = 0; for (;;) { type = va_arg(args, int); size = va_arg(args, unsigned long); data = va_arg(args, void*); if (type == LTC_ASN1_EOL) { break; } switch (type) { case LTC_ASN1_BOOLEAN: case LTC_ASN1_INTEGER: case LTC_ASN1_SHORT_INTEGER: case LTC_ASN1_BIT_STRING: case LTC_ASN1_OCTET_STRING: case LTC_ASN1_NULL: case LTC_ASN1_OBJECT_IDENTIFIER: case LTC_ASN1_IA5_STRING: case LTC_ASN1_PRINTABLE_STRING: case LTC_ASN1_UTF8_STRING: case LTC_ASN1_UTCTIME: case LTC_ASN1_SET: case LTC_ASN1_SETOF: case LTC_ASN1_SEQUENCE: case LTC_ASN1_CHOICE: ++x; break; default: va_end(args); return CRYPT_INVALID_ARG; } } va_end(args); /* allocate structure for x elements */ if (x == 0) { return CRYPT_NOP; } list = XCALLOC(sizeof(*list), x); if (list == NULL) { return CRYPT_MEM; } /* fill in the structure */ va_start(args, inlen); x = 0; for (;;) { type = va_arg(args, int); size = va_arg(args, unsigned long); data = va_arg(args, void*); if (type == LTC_ASN1_EOL) { break; } switch (type) { case LTC_ASN1_BOOLEAN: case LTC_ASN1_INTEGER: case LTC_ASN1_SHORT_INTEGER: case LTC_ASN1_BIT_STRING: case LTC_ASN1_OCTET_STRING: case LTC_ASN1_NULL: case LTC_ASN1_OBJECT_IDENTIFIER: case LTC_ASN1_IA5_STRING: case LTC_ASN1_PRINTABLE_STRING: case LTC_ASN1_UTF8_STRING: case LTC_ASN1_UTCTIME: case LTC_ASN1_SEQUENCE: case LTC_ASN1_SET: case LTC_ASN1_SETOF: case LTC_ASN1_CHOICE: list[x].type = type; list[x].size = size; list[x++].data = data; break; default: va_end(args); err = CRYPT_INVALID_ARG; goto LBL_ERR; } } va_end(args); err = der_decode_sequence(in, inlen, list, x); LBL_ERR: XFREE(list); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_multi.c,v $ */ /* $Revision: 1.13 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/sequence/der_decode_sequence_ex.c0000644000175100001440000002102110621351501023751 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" #include /** @file der_decode_sequence_ex.c ASN.1 DER, decode a SEQUENCE, Tom St Denis */ #ifdef LTC_DER /** Decode a SEQUENCE @param in The DER encoded input @param inlen The size of the input @param list The list of items to decode @param outlen The number of items in the list @param ordered Search an unordeded or ordered list @return CRYPT_OK on success */ int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, ltc_asn1_list *list, unsigned long outlen, int ordered) { int err, type; unsigned long size, x, y, z, i, blksize; void *data; LTC_ARGCHK(in != NULL); LTC_ARGCHK(list != NULL); /* get blk size */ if (inlen < 2) { return CRYPT_INVALID_PACKET; } /* sequence type? We allow 0x30 SEQUENCE and 0x31 SET since fundamentally they're the same structure */ x = 0; if (in[x] != 0x30 && in[x] != 0x31) { return CRYPT_INVALID_PACKET; } ++x; if (in[x] < 128) { blksize = in[x++]; } else if (in[x] & 0x80) { if (in[x] < 0x81 || in[x] > 0x83) { return CRYPT_INVALID_PACKET; } y = in[x++] & 0x7F; /* would reading the len bytes overrun? */ if (x + y > inlen) { return CRYPT_INVALID_PACKET; } /* read len */ blksize = 0; while (y--) { blksize = (blksize << 8) | (unsigned long)in[x++]; } } /* would this blksize overflow? */ if (x + blksize > inlen) { return CRYPT_INVALID_PACKET; } /* mark all as unused */ for (i = 0; i < outlen; i++) { list[i].used = 0; } /* ok read data */ inlen = blksize; for (i = 0; i < outlen; i++) { z = 0; type = list[i].type; size = list[i].size; data = list[i].data; if (!ordered && list[i].used == 1) { continue; } if (type == LTC_ASN1_EOL) { break; } switch (type) { case LTC_ASN1_BOOLEAN: z = inlen; if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) { goto LBL_ERR; } if ((err = der_length_boolean(&z)) != CRYPT_OK) { goto LBL_ERR; } break; case LTC_ASN1_INTEGER: z = inlen; if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) { if (!ordered) { continue; } goto LBL_ERR; } if ((err = der_length_integer(data, &z)) != CRYPT_OK) { goto LBL_ERR; } break; case LTC_ASN1_SHORT_INTEGER: z = inlen; if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) { if (!ordered) { continue; } goto LBL_ERR; } if ((err = der_length_short_integer(((unsigned long*)data)[0], &z)) != CRYPT_OK) { goto LBL_ERR; } break; case LTC_ASN1_BIT_STRING: z = inlen; if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) { if (!ordered) { continue; } goto LBL_ERR; } list[i].size = size; if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) { goto LBL_ERR; } break; case LTC_ASN1_OCTET_STRING: z = inlen; if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) { if (!ordered) { continue; } goto LBL_ERR; } list[i].size = size; if ((err = der_length_octet_string(size, &z)) != CRYPT_OK) { goto LBL_ERR; } break; case LTC_ASN1_NULL: if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) { if (!ordered) { continue; } err = CRYPT_INVALID_PACKET; goto LBL_ERR; } z = 2; break; case LTC_ASN1_OBJECT_IDENTIFIER: z = inlen; if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) { if (!ordered) { continue; } goto LBL_ERR; } list[i].size = size; if ((err = der_length_object_identifier(data, size, &z)) != CRYPT_OK) { goto LBL_ERR; } break; case LTC_ASN1_IA5_STRING: z = inlen; if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) { if (!ordered) { continue; } goto LBL_ERR; } list[i].size = size; if ((err = der_length_ia5_string(data, size, &z)) != CRYPT_OK) { goto LBL_ERR; } break; case LTC_ASN1_PRINTABLE_STRING: z = inlen; if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) { if (!ordered) { continue; } goto LBL_ERR; } list[i].size = size; if ((err = der_length_printable_string(data, size, &z)) != CRYPT_OK) { goto LBL_ERR; } break; case LTC_ASN1_UTF8_STRING: z = inlen; if ((err = der_decode_utf8_string(in + x, z, data, &size)) != CRYPT_OK) { if (!ordered) { continue; } goto LBL_ERR; } list[i].size = size; if ((err = der_length_utf8_string(data, size, &z)) != CRYPT_OK) { goto LBL_ERR; } break; case LTC_ASN1_UTCTIME: z = inlen; if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) { if (!ordered) { continue; } goto LBL_ERR; } break; case LTC_ASN1_SET: z = inlen; if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) { if (!ordered) { continue; } goto LBL_ERR; } if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) { goto LBL_ERR; } break; case LTC_ASN1_SETOF: case LTC_ASN1_SEQUENCE: /* detect if we have the right type */ if ((type == LTC_ASN1_SETOF && (in[x] & 0x3F) != 0x31) || (type == LTC_ASN1_SEQUENCE && (in[x] & 0x3F) != 0x30)) { err = CRYPT_INVALID_PACKET; goto LBL_ERR; } z = inlen; if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) { if (!ordered) { continue; } goto LBL_ERR; } if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) { goto LBL_ERR; } break; case LTC_ASN1_CHOICE: z = inlen; if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) { if (!ordered) { continue; } goto LBL_ERR; } break; default: err = CRYPT_INVALID_ARG; goto LBL_ERR; } x += z; inlen -= z; list[i].used = 1; if (!ordered) { /* restart the decoder */ i = -1; } } for (i = 0; i < outlen; i++) { if (list[i].used == 0) { err = CRYPT_INVALID_PACKET; goto LBL_ERR; } } err = CRYPT_OK; LBL_ERR: return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_decode_sequence_ex.c,v $ */ /* $Revision: 1.16 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/sequence/der_encode_sequence_multi.c0000644000175100001440000000672510621351501024517 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" #include /** @file der_encode_sequence_multi.c ASN.1 DER, encode a SEQUENCE, Tom St Denis */ #ifdef LTC_DER /** Encode a SEQUENCE type using a VA list @param out [out] Destination for data @param outlen [in/out] Length of buffer and resulting length of output @remark <...> is of the form (int, unsigned long, void*) @return CRYPT_OK on success */ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...) { int err, type; unsigned long size, x; void *data; va_list args; ltc_asn1_list *list; LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* get size of output that will be required */ va_start(args, outlen); x = 0; for (;;) { type = va_arg(args, int); size = va_arg(args, unsigned long); data = va_arg(args, void*); if (type == LTC_ASN1_EOL) { break; } switch (type) { case LTC_ASN1_BOOLEAN: case LTC_ASN1_INTEGER: case LTC_ASN1_SHORT_INTEGER: case LTC_ASN1_BIT_STRING: case LTC_ASN1_OCTET_STRING: case LTC_ASN1_NULL: case LTC_ASN1_OBJECT_IDENTIFIER: case LTC_ASN1_IA5_STRING: case LTC_ASN1_PRINTABLE_STRING: case LTC_ASN1_UTF8_STRING: case LTC_ASN1_UTCTIME: case LTC_ASN1_SEQUENCE: case LTC_ASN1_SET: case LTC_ASN1_SETOF: ++x; break; default: va_end(args); return CRYPT_INVALID_ARG; } } va_end(args); /* allocate structure for x elements */ if (x == 0) { return CRYPT_NOP; } list = XCALLOC(sizeof(*list), x); if (list == NULL) { return CRYPT_MEM; } /* fill in the structure */ va_start(args, outlen); x = 0; for (;;) { type = va_arg(args, int); size = va_arg(args, unsigned long); data = va_arg(args, void*); if (type == LTC_ASN1_EOL) { break; } switch (type) { case LTC_ASN1_BOOLEAN: case LTC_ASN1_INTEGER: case LTC_ASN1_SHORT_INTEGER: case LTC_ASN1_BIT_STRING: case LTC_ASN1_OCTET_STRING: case LTC_ASN1_NULL: case LTC_ASN1_OBJECT_IDENTIFIER: case LTC_ASN1_IA5_STRING: case LTC_ASN1_PRINTABLE_STRING: case LTC_ASN1_UTF8_STRING: case LTC_ASN1_UTCTIME: case LTC_ASN1_SEQUENCE: case LTC_ASN1_SET: case LTC_ASN1_SETOF: list[x].type = type; list[x].size = size; list[x++].data = data; break; default: va_end(args); err = CRYPT_INVALID_ARG; goto LBL_ERR; } } va_end(args); err = der_encode_sequence(list, x, out, outlen); LBL_ERR: XFREE(list); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_encode_sequence_multi.c,v $ */ /* $Revision: 1.12 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/sequence/der_encode_sequence_ex.c0000644000175100001440000002215610621351501023775 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" #include /** @file der_encode_sequence_ex.c ASN.1 DER, encode a SEQUENCE, Tom St Denis */ #ifdef LTC_DER /** Encode a SEQUENCE @param list The list of items to encode @param inlen The number of items in the list @param out [out] The destination @param outlen [in/out] The size of the output @param type_of LTC_ASN1_SEQUENCE or LTC_ASN1_SET/LTC_ASN1_SETOF @return CRYPT_OK on success */ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, unsigned char *out, unsigned long *outlen, int type_of) { int err, type; unsigned long size, x, y, z, i; void *data; LTC_ARGCHK(list != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* get size of output that will be required */ y = 0; for (i = 0; i < inlen; i++) { type = list[i].type; size = list[i].size; data = list[i].data; if (type == LTC_ASN1_EOL) { break; } switch (type) { case LTC_ASN1_BOOLEAN: if ((err = der_length_boolean(&x)) != CRYPT_OK) { goto LBL_ERR; } y += x; break; case LTC_ASN1_INTEGER: if ((err = der_length_integer(data, &x)) != CRYPT_OK) { goto LBL_ERR; } y += x; break; case LTC_ASN1_SHORT_INTEGER: if ((err = der_length_short_integer(*((unsigned long*)data), &x)) != CRYPT_OK) { goto LBL_ERR; } y += x; break; case LTC_ASN1_BIT_STRING: if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) { goto LBL_ERR; } y += x; break; case LTC_ASN1_OCTET_STRING: if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) { goto LBL_ERR; } y += x; break; case LTC_ASN1_NULL: y += 2; break; case LTC_ASN1_OBJECT_IDENTIFIER: if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) { goto LBL_ERR; } y += x; break; case LTC_ASN1_IA5_STRING: if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) { goto LBL_ERR; } y += x; break; case LTC_ASN1_PRINTABLE_STRING: if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) { goto LBL_ERR; } y += x; break; case LTC_ASN1_UTF8_STRING: if ((err = der_length_utf8_string(data, size, &x)) != CRYPT_OK) { goto LBL_ERR; } y += x; break; case LTC_ASN1_UTCTIME: if ((err = der_length_utctime(data, &x)) != CRYPT_OK) { goto LBL_ERR; } y += x; break; case LTC_ASN1_SET: case LTC_ASN1_SETOF: case LTC_ASN1_SEQUENCE: if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) { goto LBL_ERR; } y += x; break; default: err = CRYPT_INVALID_ARG; goto LBL_ERR; } } /* calc header size */ z = y; if (y < 128) { y += 2; } else if (y < 256) { /* 0x30 0x81 LL */ y += 3; } else if (y < 65536UL) { /* 0x30 0x82 LL LL */ y += 4; } else if (y < 16777216UL) { /* 0x30 0x83 LL LL LL */ y += 5; } else { err = CRYPT_INVALID_ARG; goto LBL_ERR; } /* too big ? */ if (*outlen < y) { *outlen = y; err = CRYPT_BUFFER_OVERFLOW; goto LBL_ERR; } /* store header */ x = 0; out[x++] = (type_of == LTC_ASN1_SEQUENCE) ? 0x30 : 0x31; if (z < 128) { out[x++] = (unsigned char)z; } else if (z < 256) { out[x++] = 0x81; out[x++] = (unsigned char)z; } else if (z < 65536UL) { out[x++] = 0x82; out[x++] = (unsigned char)((z>>8UL)&255); out[x++] = (unsigned char)(z&255); } else if (z < 16777216UL) { out[x++] = 0x83; out[x++] = (unsigned char)((z>>16UL)&255); out[x++] = (unsigned char)((z>>8UL)&255); out[x++] = (unsigned char)(z&255); } /* store data */ *outlen -= x; for (i = 0; i < inlen; i++) { type = list[i].type; size = list[i].size; data = list[i].data; if (type == LTC_ASN1_EOL) { break; } switch (type) { case LTC_ASN1_BOOLEAN: z = *outlen; if ((err = der_encode_boolean(*((int *)data), out + x, &z)) != CRYPT_OK) { goto LBL_ERR; } x += z; *outlen -= z; break; case LTC_ASN1_INTEGER: z = *outlen; if ((err = der_encode_integer(data, out + x, &z)) != CRYPT_OK) { goto LBL_ERR; } x += z; *outlen -= z; break; case LTC_ASN1_SHORT_INTEGER: z = *outlen; if ((err = der_encode_short_integer(*((unsigned long*)data), out + x, &z)) != CRYPT_OK) { goto LBL_ERR; } x += z; *outlen -= z; break; case LTC_ASN1_BIT_STRING: z = *outlen; if ((err = der_encode_bit_string(data, size, out + x, &z)) != CRYPT_OK) { goto LBL_ERR; } x += z; *outlen -= z; break; case LTC_ASN1_OCTET_STRING: z = *outlen; if ((err = der_encode_octet_string(data, size, out + x, &z)) != CRYPT_OK) { goto LBL_ERR; } x += z; *outlen -= z; break; case LTC_ASN1_NULL: out[x++] = 0x05; out[x++] = 0x00; *outlen -= 2; break; case LTC_ASN1_OBJECT_IDENTIFIER: z = *outlen; if ((err = der_encode_object_identifier(data, size, out + x, &z)) != CRYPT_OK) { goto LBL_ERR; } x += z; *outlen -= z; break; case LTC_ASN1_IA5_STRING: z = *outlen; if ((err = der_encode_ia5_string(data, size, out + x, &z)) != CRYPT_OK) { goto LBL_ERR; } x += z; *outlen -= z; break; case LTC_ASN1_PRINTABLE_STRING: z = *outlen; if ((err = der_encode_printable_string(data, size, out + x, &z)) != CRYPT_OK) { goto LBL_ERR; } x += z; *outlen -= z; break; case LTC_ASN1_UTF8_STRING: z = *outlen; if ((err = der_encode_utf8_string(data, size, out + x, &z)) != CRYPT_OK) { goto LBL_ERR; } x += z; *outlen -= z; break; case LTC_ASN1_UTCTIME: z = *outlen; if ((err = der_encode_utctime(data, out + x, &z)) != CRYPT_OK) { goto LBL_ERR; } x += z; *outlen -= z; break; case LTC_ASN1_SET: z = *outlen; if ((err = der_encode_set(data, size, out + x, &z)) != CRYPT_OK) { goto LBL_ERR; } x += z; *outlen -= z; break; case LTC_ASN1_SETOF: z = *outlen; if ((err = der_encode_setof(data, size, out + x, &z)) != CRYPT_OK) { goto LBL_ERR; } x += z; *outlen -= z; break; case LTC_ASN1_SEQUENCE: z = *outlen; if ((err = der_encode_sequence_ex(data, size, out + x, &z, type)) != CRYPT_OK) { goto LBL_ERR; } x += z; *outlen -= z; break; default: err = CRYPT_INVALID_ARG; goto LBL_ERR; } } *outlen = x; err = CRYPT_OK; LBL_ERR: return err; } #endif libtomcrypt-1.17/src/pk/asn1/der/sequence/der_sequence_free.c0000644000175100001440000000320410621351501022756 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_sequence_free.c ASN.1 DER, free's a structure allocated by der_decode_sequence_flexi(), Tom St Denis */ #ifdef LTC_DER /** Free memory allocated by der_decode_sequence_flexi() @param in The list to free */ void der_sequence_free(ltc_asn1_list *in) { ltc_asn1_list *l; /* walk to the start of the chain */ while (in->prev != NULL || in->parent != NULL) { if (in->parent != NULL) { in = in->parent; } else { in = in->prev; } } /* now walk the list and free stuff */ while (in != NULL) { /* is there a child? */ if (in->child) { /* disconnect */ in->child->parent = NULL; der_sequence_free(in->child); } switch (in->type) { case LTC_ASN1_SET: case LTC_ASN1_SETOF: case LTC_ASN1_SEQUENCE: break; case LTC_ASN1_INTEGER : if (in->data != NULL) { mp_clear(in->data); } break; default : if (in->data != NULL) { XFREE(in->data); } } /* move to next and free current */ l = in->next; free(in); in = l; } } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/sequence/der_sequence_free.c,v $ */ /* $Revision: 1.4 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/object_identifier/0000755000175100001440000000000010621351501021010 5ustar tomuserslibtomcrypt-1.17/src/pk/asn1/der/object_identifier/der_length_object_identifier.c0000644000175100001440000000411710621351501027022 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_length_object_identifier.c ASN.1 DER, get length of Object Identifier, Tom St Denis */ #ifdef LTC_DER unsigned long der_object_identifier_bits(unsigned long x) { unsigned long c; x &= 0xFFFFFFFF; c = 0; while (x) { ++c; x >>= 1; } return c; } /** Gets length of DER encoding of Object Identifier @param nwords The number of OID words @param words The actual OID words to get the size of @param outlen [out] The length of the DER encoding for the given string @return CRYPT_OK if successful */ int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen) { unsigned long y, z, t, wordbuf; LTC_ARGCHK(words != NULL); LTC_ARGCHK(outlen != NULL); /* must be >= 2 words */ if (nwords < 2) { return CRYPT_INVALID_ARG; } /* word1 = 0,1,2,3 and word2 0..39 */ if (words[0] > 3 || (words[0] < 2 && words[1] > 39)) { return CRYPT_INVALID_ARG; } /* leading word is the first two */ z = 0; wordbuf = words[0] * 40 + words[1]; for (y = 1; y < nwords; y++) { t = der_object_identifier_bits(wordbuf); z += t/7 + ((t%7) ? 1 : 0) + (wordbuf == 0 ? 1 : 0); if (y < nwords - 1) { /* grab next word */ wordbuf = words[y+1]; } } /* now depending on the length our length encoding changes */ if (z < 128) { z += 2; } else if (z < 256) { z += 3; } else if (z < 65536UL) { z += 4; } else { return CRYPT_INVALID_ARG; } *outlen = z; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/object_identifier/der_length_object_identifier.c,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c0000644000175100001440000000570610621351501027003 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_encode_object_identifier.c ASN.1 DER, Encode Object Identifier, Tom St Denis */ #ifdef LTC_DER /** Encode an OID @param words The words to encode (upto 32-bits each) @param nwords The number of words in the OID @param out [out] Destination of OID data @param outlen [in/out] The max and resulting size of the OID @return CRYPT_OK if successful */ int der_encode_object_identifier(unsigned long *words, unsigned long nwords, unsigned char *out, unsigned long *outlen) { unsigned long i, x, y, z, t, mask, wordbuf; int err; LTC_ARGCHK(words != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* check length */ if ((err = der_length_object_identifier(words, nwords, &x)) != CRYPT_OK) { return err; } if (x > *outlen) { *outlen = x; return CRYPT_BUFFER_OVERFLOW; } /* compute length to store OID data */ z = 0; wordbuf = words[0] * 40 + words[1]; for (y = 1; y < nwords; y++) { t = der_object_identifier_bits(wordbuf); z += t/7 + ((t%7) ? 1 : 0) + (wordbuf == 0 ? 1 : 0); if (y < nwords - 1) { wordbuf = words[y + 1]; } } /* store header + length */ x = 0; out[x++] = 0x06; if (z < 128) { out[x++] = (unsigned char)z; } else if (z < 256) { out[x++] = 0x81; out[x++] = (unsigned char)z; } else if (z < 65536UL) { out[x++] = 0x82; out[x++] = (unsigned char)((z>>8)&255); out[x++] = (unsigned char)(z&255); } else { return CRYPT_INVALID_ARG; } /* store first byte */ wordbuf = words[0] * 40 + words[1]; for (i = 1; i < nwords; i++) { /* store 7 bit words in little endian */ t = wordbuf & 0xFFFFFFFF; if (t) { y = x; mask = 0; while (t) { out[x++] = (unsigned char)((t & 0x7F) | mask); t >>= 7; mask |= 0x80; /* upper bit is set on all but the last byte */ } /* now swap bytes y...x-1 */ z = x - 1; while (y < z) { t = out[y]; out[y] = out[z]; out[z] = (unsigned char)t; ++y; --z; } } else { /* zero word */ out[x++] = 0x00; } if (i < nwords - 1) { wordbuf = words[i + 1]; } } *outlen = x; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/object_identifier/der_encode_object_identifier.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/object_identifier/der_decode_object_identifier.c0000644000175100001440000000456610621351501026774 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_decode_object_identifier.c ASN.1 DER, Decode Object Identifier, Tom St Denis */ #ifdef LTC_DER /** Decode OID data and store the array of integers in words @param in The OID DER encoded data @param inlen The length of the OID data @param words [out] The destination of the OID words @param outlen [in/out] The number of OID words @return CRYPT_OK if successful */ int der_decode_object_identifier(const unsigned char *in, unsigned long inlen, unsigned long *words, unsigned long *outlen) { unsigned long x, y, t, len; LTC_ARGCHK(in != NULL); LTC_ARGCHK(words != NULL); LTC_ARGCHK(outlen != NULL); /* header is at least 3 bytes */ if (inlen < 3) { return CRYPT_INVALID_PACKET; } /* must be room for at least two words */ if (*outlen < 2) { return CRYPT_BUFFER_OVERFLOW; } /* decode the packet header */ x = 0; if ((in[x++] & 0x1F) != 0x06) { return CRYPT_INVALID_PACKET; } /* get the length */ if (in[x] < 128) { len = in[x++]; } else { if (in[x] < 0x81 || in[x] > 0x82) { return CRYPT_INVALID_PACKET; } y = in[x++] & 0x7F; len = 0; while (y--) { len = (len << 8) | (unsigned long)in[x++]; } } if (len < 1 || (len + x) > inlen) { return CRYPT_INVALID_PACKET; } /* decode words */ y = 0; t = 0; while (len--) { t = (t << 7) | (in[x] & 0x7F); if (!(in[x++] & 0x80)) { /* store t */ if (y >= *outlen) { return CRYPT_BUFFER_OVERFLOW; } if (y == 0) { words[0] = t / 40; words[1] = t % 40; y = 2; } else { words[y++] = t; } t = 0; } } *outlen = y; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/object_identifier/der_decode_object_identifier.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/boolean/0000755000175100001440000000000010621351501016757 5ustar tomuserslibtomcrypt-1.17/src/pk/asn1/der/boolean/der_decode_boolean.c0000644000175100001440000000224610621351501022703 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_decode_boolean.c ASN.1 DER, decode a BOOLEAN, Tom St Denis */ #ifdef LTC_DER /** Read a BOOLEAN @param in The destination for the DER encoded BOOLEAN @param inlen The size of the DER BOOLEAN @param out [out] The boolean to decode @return CRYPT_OK if successful */ int der_decode_boolean(const unsigned char *in, unsigned long inlen, int *out) { LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); if (inlen != 3 || in[0] != 0x01 || in[1] != 0x01 || (in[2] != 0x00 && in[2] != 0xFF)) { return CRYPT_INVALID_ARG; } *out = (in[2]==0xFF) ? 1 : 0; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/boolean/der_decode_boolean.c,v $ */ /* $Revision: 1.2 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/boolean/der_encode_boolean.c0000644000175100001440000000230010621351501022704 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_encode_boolean.c ASN.1 DER, encode a BOOLEAN, Tom St Denis */ #ifdef LTC_DER /** Store a BOOLEAN @param in The boolean to encode @param out [out] The destination for the DER encoded BOOLEAN @param outlen [in/out] The max size and resulting size of the DER BOOLEAN @return CRYPT_OK if successful */ int der_encode_boolean(int in, unsigned char *out, unsigned long *outlen) { LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(out != NULL); if (*outlen < 3) { *outlen = 3; return CRYPT_BUFFER_OVERFLOW; } *outlen = 3; out[0] = 0x01; out[1] = 0x01; out[2] = in ? 0xFF : 0x00; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/boolean/der_encode_boolean.c,v $ */ /* $Revision: 1.4 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/boolean/der_length_boolean.c0000644000175100001440000000154510621351501022742 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_length_boolean.c ASN.1 DER, get length of a BOOLEAN, Tom St Denis */ #ifdef LTC_DER /** Gets length of DER encoding of a BOOLEAN @param outlen [out] The length of the DER encoding @return CRYPT_OK if successful */ int der_length_boolean(unsigned long *outlen) { LTC_ARGCHK(outlen != NULL); *outlen = 3; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/boolean/der_length_boolean.c,v $ */ /* $Revision: 1.3 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/integer/0000755000175100001440000000000010621351501016775 5ustar tomuserslibtomcrypt-1.17/src/pk/asn1/der/integer/der_decode_integer.c0000644000175100001440000000501010621351501022727 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_decode_integer.c ASN.1 DER, decode an integer, Tom St Denis */ #ifdef LTC_DER /** Read a mp_int integer @param in The DER encoded data @param inlen Size of DER encoded data @param num The first mp_int to decode @return CRYPT_OK if successful */ int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num) { unsigned long x, y, z; int err; LTC_ARGCHK(num != NULL); LTC_ARGCHK(in != NULL); /* min DER INTEGER is 0x02 01 00 == 0 */ if (inlen < (1 + 1 + 1)) { return CRYPT_INVALID_PACKET; } /* ok expect 0x02 when we AND with 0001 1111 [1F] */ x = 0; if ((in[x++] & 0x1F) != 0x02) { return CRYPT_INVALID_PACKET; } /* now decode the len stuff */ z = in[x++]; if ((z & 0x80) == 0x00) { /* short form */ /* will it overflow? */ if (x + z > inlen) { return CRYPT_INVALID_PACKET; } /* no so read it */ if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, z)) != CRYPT_OK) { return err; } } else { /* long form */ z &= 0x7F; /* will number of length bytes overflow? (or > 4) */ if (((x + z) > inlen) || (z > 4) || (z == 0)) { return CRYPT_INVALID_PACKET; } /* now read it in */ y = 0; while (z--) { y = ((unsigned long)(in[x++])) | (y << 8); } /* now will reading y bytes overrun? */ if ((x + y) > inlen) { return CRYPT_INVALID_PACKET; } /* no so read it */ if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, y)) != CRYPT_OK) { return err; } } /* see if it's negative */ if (in[x] & 0x80) { void *tmp; if (mp_init(&tmp) != CRYPT_OK) { return CRYPT_MEM; } if (mp_2expt(tmp, mp_count_bits(num)) != CRYPT_OK || mp_sub(num, tmp, num) != CRYPT_OK) { mp_clear(tmp); return CRYPT_MEM; } mp_clear(tmp); } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_decode_integer.c,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/integer/der_encode_integer.c0000644000175100001440000000704310621351501022751 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_encode_integer.c ASN.1 DER, encode an integer, Tom St Denis */ #ifdef LTC_DER /* Exports a positive bignum as DER format (upto 2^32 bytes in size) */ /** Store a mp_int integer @param num The first mp_int to encode @param out [out] The destination for the DER encoded integers @param outlen [in/out] The max size and resulting size of the DER encoded integers @return CRYPT_OK if successful */ int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen) { unsigned long tmplen, y; int err, leading_zero; LTC_ARGCHK(num != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* find out how big this will be */ if ((err = der_length_integer(num, &tmplen)) != CRYPT_OK) { return err; } if (*outlen < tmplen) { *outlen = tmplen; return CRYPT_BUFFER_OVERFLOW; } if (mp_cmp_d(num, 0) != LTC_MP_LT) { /* we only need a leading zero if the msb of the first byte is one */ if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == LTC_MP_YES) { leading_zero = 1; } else { leading_zero = 0; } /* get length of num in bytes (plus 1 since we force the msbyte to zero) */ y = mp_unsigned_bin_size(num) + leading_zero; } else { leading_zero = 0; y = mp_count_bits(num); y = y + (8 - (y & 7)); y = y >> 3; if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) --y; } /* now store initial data */ *out++ = 0x02; if (y < 128) { /* short form */ *out++ = (unsigned char)y; } else if (y < 256) { *out++ = 0x81; *out++ = (unsigned char)y; } else if (y < 65536UL) { *out++ = 0x82; *out++ = (unsigned char)((y>>8)&255); *out++ = (unsigned char)y; } else if (y < 16777216UL) { *out++ = 0x83; *out++ = (unsigned char)((y>>16)&255); *out++ = (unsigned char)((y>>8)&255); *out++ = (unsigned char)y; } else { return CRYPT_INVALID_ARG; } /* now store msbyte of zero if num is non-zero */ if (leading_zero) { *out++ = 0x00; } /* if it's not zero store it as big endian */ if (mp_cmp_d(num, 0) == LTC_MP_GT) { /* now store the mpint */ if ((err = mp_to_unsigned_bin(num, out)) != CRYPT_OK) { return err; } } else if (mp_iszero(num) != LTC_MP_YES) { void *tmp; /* negative */ if (mp_init(&tmp) != CRYPT_OK) { return CRYPT_MEM; } /* 2^roundup and subtract */ y = mp_count_bits(num); y = y + (8 - (y & 7)); if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) y -= 8; if (mp_2expt(tmp, y) != CRYPT_OK || mp_add(tmp, num, tmp) != CRYPT_OK) { mp_clear(tmp); return CRYPT_MEM; } if ((err = mp_to_unsigned_bin(tmp, out)) != CRYPT_OK) { mp_clear(tmp); return err; } mp_clear(tmp); } /* we good */ *outlen = tmplen; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_encode_integer.c,v $ */ /* $Revision: 1.9 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/asn1/der/integer/der_length_integer.c0000644000175100001440000000401710621351501022773 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file der_length_integer.c ASN.1 DER, get length of encoding, Tom St Denis */ #ifdef LTC_DER /** Gets length of DER encoding of num @param num The int to get the size of @param outlen [out] The length of the DER encoding for the given integer @return CRYPT_OK if successful */ int der_length_integer(void *num, unsigned long *outlen) { unsigned long z, len; int leading_zero; LTC_ARGCHK(num != NULL); LTC_ARGCHK(outlen != NULL); if (mp_cmp_d(num, 0) != LTC_MP_LT) { /* positive */ /* we only need a leading zero if the msb of the first byte is one */ if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == LTC_MP_YES) { leading_zero = 1; } else { leading_zero = 0; } /* size for bignum */ z = len = leading_zero + mp_unsigned_bin_size(num); } else { /* it's negative */ /* find power of 2 that is a multiple of eight and greater than count bits */ leading_zero = 0; z = mp_count_bits(num); z = z + (8 - (z & 7)); if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) --z; len = z = z >> 3; } /* now we need a length */ if (z < 128) { /* short form */ ++len; } else { /* long form (relies on z != 0), assumes length bytes < 128 */ ++len; while (z) { ++len; z >>= 8; } } /* we need a 0x02 to indicate it's INTEGER */ ++len; /* return length */ *outlen = len; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/asn1/der/integer/der_length_integer.c,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/katja/0000755000175100001440000000000010621351501015016 5ustar tomuserslibtomcrypt-1.17/src/pk/katja/katja_import.c0000644000175100001440000000511610621351501017651 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file katja_import.c Import a LTC_PKCS-style Katja key, Tom St Denis */ #ifdef MKAT /** Import an KatjaPublicKey or KatjaPrivateKey [two-prime only, only support >= 1024-bit keys, defined in LTC_PKCS #1 v2.1] @param in The packet to import from @param inlen It's length (octets) @param key [out] Destination for newly imported key @return CRYPT_OK if successful, upon error allocated memory is freed */ int katja_import(const unsigned char *in, unsigned long inlen, katja_key *key) { int err; void *zero; LTC_ARGCHK(in != NULL); LTC_ARGCHK(key != NULL); LTC_ARGCHK(ltc_mp.name != NULL); /* init key */ if ((err = mp_init_multi(&zero, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, &key->pq, NULL)) != CRYPT_OK) { return err; } if ((err = der_decode_sequence_multi(in, inlen, LTC_ASN1_INTEGER, 1UL, key->N, LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto LBL_ERR; } if (mp_cmp_d(key->N, 0) == LTC_MP_EQ) { /* it's a private key */ if ((err = der_decode_sequence_multi(in, inlen, LTC_ASN1_INTEGER, 1UL, zero, LTC_ASN1_INTEGER, 1UL, key->N, LTC_ASN1_INTEGER, 1UL, key->d, LTC_ASN1_INTEGER, 1UL, key->p, LTC_ASN1_INTEGER, 1UL, key->q, LTC_ASN1_INTEGER, 1UL, key->dP, LTC_ASN1_INTEGER, 1UL, key->dQ, LTC_ASN1_INTEGER, 1UL, key->qP, LTC_ASN1_INTEGER, 1UL, key->pq, LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto LBL_ERR; } key->type = PK_PRIVATE; } else { /* public we have N */ key->type = PK_PUBLIC; } mp_clear(zero); return CRYPT_OK; LBL_ERR: mp_clear_multi(zero, key->d, key->N, key->dQ, key->dP, key->qP, key->p, key->q, key->pq, NULL); return err; } #endif /* LTC_MRSA */ /* $Source: /cvs/libtom/libtomcrypt/src/pk/katja/katja_import.c,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/katja/katja_exptmod.c0000644000175100001440000000740710621351501020024 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file katja_exptmod.c Katja LTC_PKCS-style exptmod, Tom St Denis */ #ifdef MKAT /** Compute an RSA modular exponentiation @param in The input data to send into RSA @param inlen The length of the input (octets) @param out [out] The destination @param outlen [in/out] The max size and resulting size of the output @param which Which exponent to use, e.g. PK_PRIVATE or PK_PUBLIC @param key The RSA key to use @return CRYPT_OK if successful */ int katja_exptmod(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, int which, katja_key *key) { void *tmp, *tmpa, *tmpb; unsigned long x; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); /* is the key of the right type for the operation? */ if (which == PK_PRIVATE && (key->type != PK_PRIVATE)) { return CRYPT_PK_NOT_PRIVATE; } /* must be a private or public operation */ if (which != PK_PRIVATE && which != PK_PUBLIC) { return CRYPT_PK_INVALID_TYPE; } /* init and copy into tmp */ if ((err = mp_init_multi(&tmp, &tmpa, &tmpb, NULL)) != CRYPT_OK) { return err; } if ((err = mp_read_unsigned_bin(tmp, (unsigned char *)in, (int)inlen)) != CRYPT_OK) { goto error; } /* sanity check on the input */ if (mp_cmp(key->N, tmp) == LTC_MP_LT) { err = CRYPT_PK_INVALID_SIZE; goto done; } /* are we using the private exponent and is the key optimized? */ if (which == PK_PRIVATE) { /* tmpa = tmp^dP mod p */ if ((err = mp_exptmod(tmp, key->dP, key->p, tmpa)) != CRYPT_OK) { goto error; } /* tmpb = tmp^dQ mod q */ if ((err = mp_exptmod(tmp, key->dQ, key->q, tmpb)) != CRYPT_OK) { goto error; } /* tmp = (tmpa - tmpb) * qInv (mod p) */ if ((err = mp_sub(tmpa, tmpb, tmp)) != CRYPT_OK) { goto error; } if ((err = mp_mulmod(tmp, key->qP, key->p, tmp)) != CRYPT_OK) { goto error; } /* tmp = tmpb + q * tmp */ if ((err = mp_mul(tmp, key->q, tmp)) != CRYPT_OK) { goto error; } if ((err = mp_add(tmp, tmpb, tmp)) != CRYPT_OK) { goto error; } } else { /* exptmod it */ if ((err = mp_exptmod(tmp, key->N, key->N, tmp)) != CRYPT_OK) { goto error; } } /* read it back */ x = (unsigned long)mp_unsigned_bin_size(key->N); if (x > *outlen) { *outlen = x; err = CRYPT_BUFFER_OVERFLOW; goto done; } /* this should never happen ... */ if (mp_unsigned_bin_size(tmp) > mp_unsigned_bin_size(key->N)) { err = CRYPT_ERROR; goto done; } *outlen = x; /* convert it */ zeromem(out, x); if ((err = mp_to_unsigned_bin(tmp, out+(x-mp_unsigned_bin_size(tmp)))) != CRYPT_OK) { goto error; } /* clean up and return */ err = CRYPT_OK; goto done; error: done: mp_clear_multi(tmp, tmpa, tmpb, NULL); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/katja/katja_exptmod.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/katja/katja_decrypt_key.c0000644000175100001440000000577610621351501020675 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file katja_decrypt_key.c Katja LTC_PKCS #1 OAEP Decryption, Tom St Denis */ #ifdef MKAT /** (LTC_PKCS #1 v2.0) decrypt then OAEP depad @param in The ciphertext @param inlen The length of the ciphertext (octets) @param out [out] The plaintext @param outlen [in/out] The max size and resulting size of the plaintext (octets) @param lparam The system "lparam" value @param lparamlen The length of the lparam value (octets) @param hash_idx The index of the hash desired @param stat [out] Result of the decryption, 1==valid, 0==invalid @param key The corresponding private Katja key @return CRYPT_OK if succcessul (even if invalid) */ int katja_decrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, const unsigned char *lparam, unsigned long lparamlen, int hash_idx, int *stat, katja_key *key) { unsigned long modulus_bitlen, modulus_bytelen, x; int err; unsigned char *tmp; LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); LTC_ARGCHK(stat != NULL); /* default to invalid */ *stat = 0; /* valid hash ? */ if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { return err; } /* get modulus len in bits */ modulus_bitlen = mp_count_bits( (key->N)); /* payload is upto pq, so we know q is 1/3rd the size of N and therefore pq is 2/3th the size */ modulus_bitlen = ((modulus_bitlen << 1) / 3); /* round down to next byte */ modulus_bitlen -= (modulus_bitlen & 7) + 8; /* outlen must be at least the size of the modulus */ modulus_bytelen = mp_unsigned_bin_size( (key->N)); if (modulus_bytelen != inlen) { return CRYPT_INVALID_PACKET; } /* allocate ram */ tmp = XMALLOC(inlen); if (tmp == NULL) { return CRYPT_MEM; } /* rsa decode the packet */ x = inlen; if ((err = katja_exptmod(in, inlen, tmp, &x, PK_PRIVATE, key)) != CRYPT_OK) { XFREE(tmp); return err; } /* shift right by modulus_bytelen - modulus_bitlen/8 bytes */ for (x = 0; x < (modulus_bitlen >> 3); x++) { tmp[x] = tmp[x+(modulus_bytelen-(modulus_bitlen>>3))]; } /* now OAEP decode the packet */ err = pkcs_1_oaep_decode(tmp, x, lparam, lparamlen, modulus_bitlen, hash_idx, out, outlen, stat); XFREE(tmp); return err; } #endif /* LTC_MRSA */ /* $Source: /cvs/libtom/libtomcrypt/src/pk/katja/katja_decrypt_key.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/katja/katja_make_key.c0000644000175100001440000000720210621351501020122 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file katja_make_key.c Katja key generation, Tom St Denis */ #ifdef MKAT /** Create a Katja key @param prng An active PRNG state @param wprng The index of the PRNG desired @param size The size of the modulus (key size) desired (octets) @param key [out] Destination of a newly created private key pair @return CRYPT_OK if successful, upon error all allocated ram is freed */ int katja_make_key(prng_state *prng, int wprng, int size, katja_key *key) { void *p, *q, *tmp1, *tmp2; int err; LTC_ARGCHK(key != NULL); LTC_ARGCHK(ltc_mp.name != NULL); if ((size < (MIN_KAT_SIZE/8)) || (size > (MAX_KAT_SIZE/8))) { return CRYPT_INVALID_KEYSIZE; } if ((err = prng_is_valid(wprng)) != CRYPT_OK) { return err; } if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, NULL)) != CRYPT_OK) { return err; } /* divide size by three */ size = (((size << 3) / 3) + 7) >> 3; /* make prime "q" (we negate size to make q == 3 mod 4) */ if ((err = rand_prime(q, -size, prng, wprng)) != CRYPT_OK) { goto done; } if ((err = mp_sub_d(q, 1, tmp1)) != CRYPT_OK) { goto done; } /* make prime "p" */ do { if ((err = rand_prime(p, size+1, prng, wprng)) != CRYPT_OK) { goto done; } if ((err = mp_gcd(p, tmp1, tmp2)) != CRYPT_OK) { goto done; } } while (mp_cmp_d(tmp2, 1) != LTC_MP_EQ); /* make key */ if ((err = mp_init_multi(&key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, &key->pq, NULL)) != CRYPT_OK) { goto error; } /* n=p^2q and 1/n mod pq */ if ((err = mp_copy( p, key->p)) != CRYPT_OK) { goto error2; } if ((err = mp_copy( q, key->q)) != CRYPT_OK) { goto error2; } if ((err = mp_mul(key->p, key->q, key->pq)) != CRYPT_OK) { goto error2; } /* tmp1 = pq */ if ((err = mp_mul(key->pq, key->p, key->N)) != CRYPT_OK) { goto error2; } /* N = p^2q */ if ((err = mp_sub_d( p, 1, tmp1)) != CRYPT_OK) { goto error2; } /* tmp1 = q-1 */ if ((err = mp_sub_d( q, 1, tmp2)) != CRYPT_OK) { goto error2; } /* tmp2 = p-1 */ if ((err = mp_lcm(tmp1, tmp2, key->d)) != CRYPT_OK) { goto error2; } /* tmp1 = lcd(p-1,q-1) */ if ((err = mp_invmod( key->N, key->d, key->d)) != CRYPT_OK) { goto error2; } /* key->d = 1/N mod pq */ /* optimize for CRT now */ /* find d mod q-1 and d mod p-1 */ if ((err = mp_mod( key->d, tmp1, key->dP)) != CRYPT_OK) { goto error2; } /* dP = d mod p-1 */ if ((err = mp_mod( key->d, tmp2, key->dQ)) != CRYPT_OK) { goto error2; } /* dQ = d mod q-1 */ if ((err = mp_invmod( q, p, key->qP)) != CRYPT_OK) { goto error2; } /* qP = 1/q mod p */ /* set key type (in this case it's CRT optimized) */ key->type = PK_PRIVATE; /* return ok and free temps */ err = CRYPT_OK; goto done; error2: mp_clear_multi( key->d, key->N, key->dQ, key->dP, key->qP, key->p, key->q, key->pq, NULL); error: done: mp_clear_multi( tmp2, tmp1, p, q, NULL); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/katja/katja_make_key.c,v $ */ /* $Revision: 1.11 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/katja/katja_export.c0000644000175100001440000000462310621351501017662 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file katja_export.c Export Katja LTC_PKCS-style keys, Tom St Denis */ #ifdef MKAT /** This will export either an KatjaPublicKey or KatjaPrivateKey @param out [out] Destination of the packet @param outlen [in/out] The max size and resulting size of the packet @param type The type of exported key (PK_PRIVATE or PK_PUBLIC) @param key The Katja key to export @return CRYPT_OK if successful */ int katja_export(unsigned char *out, unsigned long *outlen, int type, katja_key *key) { int err; unsigned long zero=0; LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); /* type valid? */ if (!(key->type == PK_PRIVATE) && (type == PK_PRIVATE)) { return CRYPT_PK_INVALID_TYPE; } if (type == PK_PRIVATE) { /* private key */ /* output is Version, n, d, p, q, d mod (p-1), d mod (q - 1), 1/q mod p, pq */ if ((err = der_encode_sequence_multi(out, outlen, LTC_ASN1_SHORT_INTEGER, 1UL, &zero, LTC_ASN1_INTEGER, 1UL, key->N, LTC_ASN1_INTEGER, 1UL, key->d, LTC_ASN1_INTEGER, 1UL, key->p, LTC_ASN1_INTEGER, 1UL, key->q, LTC_ASN1_INTEGER, 1UL, key->dP, LTC_ASN1_INTEGER, 1UL, key->dQ, LTC_ASN1_INTEGER, 1UL, key->qP, LTC_ASN1_INTEGER, 1UL, key->pq, LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { return err; } /* clear zero and return */ return CRYPT_OK; } else { /* public key */ return der_encode_sequence_multi(out, outlen, LTC_ASN1_INTEGER, 1UL, key->N, LTC_ASN1_EOL, 0UL, NULL); } } #endif /* LTC_MRSA */ /* $Source: /cvs/libtom/libtomcrypt/src/pk/katja/katja_export.c,v $ */ /* $Revision: 1.4 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/katja/katja_encrypt_key.c0000644000175100001440000000541110621351501020671 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file katja_encrypt_key.c Katja LTC_PKCS-style OAEP encryption, Tom St Denis */ #ifdef MKAT /** (LTC_PKCS #1 v2.0) OAEP pad then encrypt @param in The plaintext @param inlen The length of the plaintext (octets) @param out [out] The ciphertext @param outlen [in/out] The max size and resulting size of the ciphertext @param lparam The system "lparam" for the encryption @param lparamlen The length of lparam (octets) @param prng An active PRNG @param prng_idx The index of the desired prng @param hash_idx The index of the desired hash @param key The Katja key to encrypt to @return CRYPT_OK if successful */ int katja_encrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, const unsigned char *lparam, unsigned long lparamlen, prng_state *prng, int prng_idx, int hash_idx, katja_key *key) { unsigned long modulus_bitlen, modulus_bytelen, x; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(key != NULL); /* valid prng and hash ? */ if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { return err; } if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { return err; } /* get modulus len in bits */ modulus_bitlen = mp_count_bits((key->N)); /* payload is upto pq, so we know q is 1/3rd the size of N and therefore pq is 2/3th the size */ modulus_bitlen = ((modulus_bitlen << 1) / 3); /* round down to next byte */ modulus_bitlen -= (modulus_bitlen & 7) + 8; /* outlen must be at least the size of the modulus */ modulus_bytelen = mp_unsigned_bin_size((key->N)); if (modulus_bytelen > *outlen) { *outlen = modulus_bytelen; return CRYPT_BUFFER_OVERFLOW; } /* OAEP pad the key */ x = *outlen; if ((err = pkcs_1_oaep_encode(in, inlen, lparam, lparamlen, modulus_bitlen, prng, prng_idx, hash_idx, out, &x)) != CRYPT_OK) { return err; } /* Katja exptmod the OAEP pad */ return katja_exptmod(out, x, out, outlen, PK_PUBLIC, key); } #endif /* LTC_MRSA */ /* $Source: /cvs/libtom/libtomcrypt/src/pk/katja/katja_encrypt_key.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/katja/katja_free.c0000644000175100001440000000147310621351501017262 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file katja_free.c Free an Katja key, Tom St Denis */ #ifdef MKAT /** Free an Katja key from memory @param key The RSA key to free */ void katja_free(katja_key *key) { LTC_ARGCHK(key != NULL); mp_clear_multi( key->d, key->N, key->dQ, key->dP, key->qP, key->p, key->q, key->pq, NULL); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/pk/katja/katja_free.c,v $ */ /* $Revision: 1.3 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/pk/pkcs1/0000755000175100001440000000000010621351501014745 5ustar tomuserslibtomcrypt-1.17/src/pk/pkcs1/pkcs_1_oaep_encode.c0000644000175100001440000001120110621351501020605 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file pkcs_1_oaep_encode.c OAEP Padding for LTC_PKCS #1, Tom St Denis */ #ifdef LTC_PKCS_1 /** LTC_PKCS #1 v2.00 OAEP encode @param msg The data to encode @param msglen The length of the data to encode (octets) @param lparam A session or system parameter (can be NULL) @param lparamlen The length of the lparam data @param modulus_bitlen The bit length of the RSA modulus @param prng An active PRNG state @param prng_idx The index of the PRNG desired @param hash_idx The index of the hash desired @param out [out] The destination for the encoded data @param outlen [in/out] The max size and resulting size of the encoded data @return CRYPT_OK if successful */ int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, const unsigned char *lparam, unsigned long lparamlen, unsigned long modulus_bitlen, prng_state *prng, int prng_idx, int hash_idx, unsigned char *out, unsigned long *outlen) { unsigned char *DB, *seed, *mask; unsigned long hLen, x, y, modulus_len; int err; LTC_ARGCHK(msg != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* test valid hash */ if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { return err; } /* valid prng */ if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { return err; } hLen = hash_descriptor[hash_idx].hashsize; modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); /* test message size */ if ((2*hLen >= (modulus_len - 2)) || (msglen > (modulus_len - 2*hLen - 2))) { return CRYPT_PK_INVALID_SIZE; } /* allocate ram for DB/mask/salt of size modulus_len */ DB = XMALLOC(modulus_len); mask = XMALLOC(modulus_len); seed = XMALLOC(hLen); if (DB == NULL || mask == NULL || seed == NULL) { if (DB != NULL) { XFREE(DB); } if (mask != NULL) { XFREE(mask); } if (seed != NULL) { XFREE(seed); } return CRYPT_MEM; } /* get lhash */ /* DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes */ x = modulus_len; if (lparam != NULL) { if ((err = hash_memory(hash_idx, lparam, lparamlen, DB, &x)) != CRYPT_OK) { goto LBL_ERR; } } else { /* can't pass hash_memory a NULL so use DB with zero length */ if ((err = hash_memory(hash_idx, DB, 0, DB, &x)) != CRYPT_OK) { goto LBL_ERR; } } /* append PS then 0x01 (to lhash) */ x = hLen; y = modulus_len - msglen - 2*hLen - 2; XMEMSET(DB+x, 0, y); x += y; /* 0x01 byte */ DB[x++] = 0x01; /* message (length = msglen) */ XMEMCPY(DB+x, msg, msglen); x += msglen; /* now choose a random seed */ if (prng_descriptor[prng_idx].read(seed, hLen, prng) != hLen) { err = CRYPT_ERROR_READPRNG; goto LBL_ERR; } /* compute MGF1 of seed (k - hlen - 1) */ if ((err = pkcs_1_mgf1(hash_idx, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { goto LBL_ERR; } /* xor against DB */ for (y = 0; y < (modulus_len - hLen - 1); y++) { DB[y] ^= mask[y]; } /* compute MGF1 of maskedDB (hLen) */ if ((err = pkcs_1_mgf1(hash_idx, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) { goto LBL_ERR; } /* XOR against seed */ for (y = 0; y < hLen; y++) { seed[y] ^= mask[y]; } /* create string of length modulus_len */ if (*outlen < modulus_len) { *outlen = modulus_len; err = CRYPT_BUFFER_OVERFLOW; goto LBL_ERR; } /* start output which is 0x00 || maskedSeed || maskedDB */ x = 0; out[x++] = 0x00; XMEMCPY(out+x, seed, hLen); x += hLen; XMEMCPY(out+x, DB, modulus_len - hLen - 1); x += modulus_len - hLen - 1; *outlen = x; err = CRYPT_OK; LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(DB, modulus_len); zeromem(seed, hLen); zeromem(mask, modulus_len); #endif XFREE(seed); XFREE(mask); XFREE(DB); return err; } #endif /* LTC_PKCS_1 */ /* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_encode.c,v $ */ /* $Revision: 1.9 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/pkcs1/pkcs_1_oaep_decode.c0000644000175100001440000001203210621351501020576 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file pkcs_1_oaep_decode.c OAEP Padding for LTC_PKCS #1, Tom St Denis */ #ifdef LTC_PKCS_1 /** LTC_PKCS #1 v2.00 OAEP decode @param msg The encoded data to decode @param msglen The length of the encoded data (octets) @param lparam The session or system data (can be NULL) @param lparamlen The length of the lparam @param modulus_bitlen The bit length of the RSA modulus @param hash_idx The index of the hash desired @param out [out] Destination of decoding @param outlen [in/out] The max size and resulting size of the decoding @param res [out] Result of decoding, 1==valid, 0==invalid @return CRYPT_OK if successful (even if invalid) */ int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, const unsigned char *lparam, unsigned long lparamlen, unsigned long modulus_bitlen, int hash_idx, unsigned char *out, unsigned long *outlen, int *res) { unsigned char *DB, *seed, *mask; unsigned long hLen, x, y, modulus_len; int err; LTC_ARGCHK(msg != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(res != NULL); /* default to invalid packet */ *res = 0; /* test valid hash */ if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { return err; } hLen = hash_descriptor[hash_idx].hashsize; modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); /* test hash/message size */ if ((2*hLen >= (modulus_len - 2)) || (msglen != modulus_len)) { return CRYPT_PK_INVALID_SIZE; } /* allocate ram for DB/mask/salt of size modulus_len */ DB = XMALLOC(modulus_len); mask = XMALLOC(modulus_len); seed = XMALLOC(hLen); if (DB == NULL || mask == NULL || seed == NULL) { if (DB != NULL) { XFREE(DB); } if (mask != NULL) { XFREE(mask); } if (seed != NULL) { XFREE(seed); } return CRYPT_MEM; } /* ok so it's now in the form 0x00 || maskedseed || maskedDB 1 || hLen || modulus_len - hLen - 1 */ /* must have leading 0x00 byte */ if (msg[0] != 0x00) { err = CRYPT_OK; goto LBL_ERR; } /* now read the masked seed */ x = 1; XMEMCPY(seed, msg + x, hLen); x += hLen; /* now read the masked DB */ XMEMCPY(DB, msg + x, modulus_len - hLen - 1); x += modulus_len - hLen - 1; /* compute MGF1 of maskedDB (hLen) */ if ((err = pkcs_1_mgf1(hash_idx, DB, modulus_len - hLen - 1, mask, hLen)) != CRYPT_OK) { goto LBL_ERR; } /* XOR against seed */ for (y = 0; y < hLen; y++) { seed[y] ^= mask[y]; } /* compute MGF1 of seed (k - hlen - 1) */ if ((err = pkcs_1_mgf1(hash_idx, seed, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { goto LBL_ERR; } /* xor against DB */ for (y = 0; y < (modulus_len - hLen - 1); y++) { DB[y] ^= mask[y]; } /* now DB == lhash || PS || 0x01 || M, PS == k - mlen - 2hlen - 2 zeroes */ /* compute lhash and store it in seed [reuse temps!] */ x = modulus_len; if (lparam != NULL) { if ((err = hash_memory(hash_idx, lparam, lparamlen, seed, &x)) != CRYPT_OK) { goto LBL_ERR; } } else { /* can't pass hash_memory a NULL so use DB with zero length */ if ((err = hash_memory(hash_idx, DB, 0, seed, &x)) != CRYPT_OK) { goto LBL_ERR; } } /* compare the lhash'es */ if (XMEMCMP(seed, DB, hLen) != 0) { err = CRYPT_OK; goto LBL_ERR; } /* now zeroes before a 0x01 */ for (x = hLen; x < (modulus_len - hLen - 1) && DB[x] == 0x00; x++) { /* step... */ } /* error out if wasn't 0x01 */ if (x == (modulus_len - hLen - 1) || DB[x] != 0x01) { err = CRYPT_INVALID_PACKET; goto LBL_ERR; } /* rest is the message (and skip 0x01) */ if ((modulus_len - hLen - 1 - ++x) > *outlen) { *outlen = modulus_len - hLen - 1 - x; err = CRYPT_BUFFER_OVERFLOW; goto LBL_ERR; } /* copy message */ *outlen = modulus_len - hLen - 1 - x; XMEMCPY(out, DB + x, modulus_len - hLen - 1 - x); x += modulus_len - hLen - 1; /* valid packet */ *res = 1; err = CRYPT_OK; LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(DB, modulus_len); zeromem(seed, hLen); zeromem(mask, modulus_len); #endif XFREE(seed); XFREE(mask); XFREE(DB); return err; } #endif /* LTC_PKCS_1 */ /* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_oaep_decode.c,v $ */ /* $Revision: 1.13 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/pkcs1/pkcs_1_os2ip.c0000644000175100001440000000166010621351501017410 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file pkcs_1_os2ip.c Octet to Integer OS2IP, Tom St Denis */ #ifdef LTC_PKCS_1 /** Read a binary string into an mp_int @param n [out] The mp_int destination @param in The binary string to read @param inlen The length of the binary string @return CRYPT_OK if successful */ int pkcs_1_os2ip(void *n, unsigned char *in, unsigned long inlen) { return mp_read_unsigned_bin(n, in, inlen); } #endif /* LTC_PKCS_1 */ /* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_os2ip.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/pkcs1/pkcs_1_pss_encode.c0000644000175100001440000001164210621351501020477 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file pkcs_1_pss_encode.c LTC_PKCS #1 PSS Signature Padding, Tom St Denis */ #ifdef LTC_PKCS_1 /** LTC_PKCS #1 v2.00 Signature Encoding @param msghash The hash to encode @param msghashlen The length of the hash (octets) @param saltlen The length of the salt desired (octets) @param prng An active PRNG context @param prng_idx The index of the PRNG desired @param hash_idx The index of the hash desired @param modulus_bitlen The bit length of the RSA modulus @param out [out] The destination of the encoding @param outlen [in/out] The max size and resulting size of the encoded data @return CRYPT_OK if successful */ int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, unsigned long saltlen, prng_state *prng, int prng_idx, int hash_idx, unsigned long modulus_bitlen, unsigned char *out, unsigned long *outlen) { unsigned char *DB, *mask, *salt, *hash; unsigned long x, y, hLen, modulus_len; int err; hash_state md; LTC_ARGCHK(msghash != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* ensure hash and PRNG are valid */ if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { return err; } if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) { return err; } hLen = hash_descriptor[hash_idx].hashsize; modulus_len = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0); /* check sizes */ if ((saltlen > modulus_len) || (modulus_len < hLen + saltlen + 2)) { return CRYPT_PK_INVALID_SIZE; } /* allocate ram for DB/mask/salt/hash of size modulus_len */ DB = XMALLOC(modulus_len); mask = XMALLOC(modulus_len); salt = XMALLOC(modulus_len); hash = XMALLOC(modulus_len); if (DB == NULL || mask == NULL || salt == NULL || hash == NULL) { if (DB != NULL) { XFREE(DB); } if (mask != NULL) { XFREE(mask); } if (salt != NULL) { XFREE(salt); } if (hash != NULL) { XFREE(hash); } return CRYPT_MEM; } /* generate random salt */ if (saltlen > 0) { if (prng_descriptor[prng_idx].read(salt, saltlen, prng) != saltlen) { err = CRYPT_ERROR_READPRNG; goto LBL_ERR; } } /* M = (eight) 0x00 || msghash || salt, hash = H(M) */ if ((err = hash_descriptor[hash_idx].init(&md)) != CRYPT_OK) { goto LBL_ERR; } zeromem(DB, 8); if ((err = hash_descriptor[hash_idx].process(&md, DB, 8)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hash_descriptor[hash_idx].process(&md, msghash, msghashlen)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hash_descriptor[hash_idx].process(&md, salt, saltlen)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hash_descriptor[hash_idx].done(&md, hash)) != CRYPT_OK) { goto LBL_ERR; } /* generate DB = PS || 0x01 || salt, PS == modulus_len - saltlen - hLen - 2 zero bytes */ x = 0; XMEMSET(DB + x, 0, modulus_len - saltlen - hLen - 2); x += modulus_len - saltlen - hLen - 2; DB[x++] = 0x01; XMEMCPY(DB + x, salt, saltlen); x += saltlen; /* generate mask of length modulus_len - hLen - 1 from hash */ if ((err = pkcs_1_mgf1(hash_idx, hash, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { goto LBL_ERR; } /* xor against DB */ for (y = 0; y < (modulus_len - hLen - 1); y++) { DB[y] ^= mask[y]; } /* output is DB || hash || 0xBC */ if (*outlen < modulus_len) { *outlen = modulus_len; err = CRYPT_BUFFER_OVERFLOW; goto LBL_ERR; } /* DB len = modulus_len - hLen - 1 */ y = 0; XMEMCPY(out + y, DB, modulus_len - hLen - 1); y += modulus_len - hLen - 1; /* hash */ XMEMCPY(out + y, hash, hLen); y += hLen; /* 0xBC */ out[y] = 0xBC; /* now clear the 8*modulus_len - modulus_bitlen most significant bits */ out[0] &= 0xFF >> ((modulus_len<<3) - (modulus_bitlen-1)); /* store output size */ *outlen = modulus_len; err = CRYPT_OK; LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(DB, modulus_len); zeromem(mask, modulus_len); zeromem(salt, modulus_len); zeromem(hash, modulus_len); #endif XFREE(hash); XFREE(salt); XFREE(mask); XFREE(DB); return err; } #endif /* LTC_PKCS_1 */ /* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_encode.c,v $ */ /* $Revision: 1.9 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/pkcs1/pkcs_1_v1_5_encode.c0000644000175100001440000000645110621351501020446 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /*! \file pkcs_1_v1_5_encode.c * * LTC_PKCS #1 v1.5 Padding (Andreas Lange) */ #ifdef LTC_PKCS_1 /*! \brief LTC_PKCS #1 v1.5 encode. * * \param msg The data to encode * \param msglen The length of the data to encode (octets) * \param block_type Block type to use in padding (\sa ltc_pkcs_1_v1_5_blocks) * \param modulus_bitlen The bit length of the RSA modulus * \param prng An active PRNG state (only for LTC_LTC_PKCS_1_EME) * \param prng_idx The index of the PRNG desired (only for LTC_LTC_PKCS_1_EME) * \param out [out] The destination for the encoded data * \param outlen [in/out] The max size and resulting size of the encoded data * * \return CRYPT_OK if successful */ int pkcs_1_v1_5_encode(const unsigned char *msg, unsigned long msglen, int block_type, unsigned long modulus_bitlen, prng_state *prng, int prng_idx, unsigned char *out, unsigned long *outlen) { unsigned long modulus_len, ps_len, i; unsigned char *ps; int result; /* valid block_type? */ if ((block_type != LTC_LTC_PKCS_1_EMSA) && (block_type != LTC_LTC_PKCS_1_EME)) { return CRYPT_PK_INVALID_PADDING; } if (block_type == LTC_LTC_PKCS_1_EME) { /* encryption padding, we need a valid PRNG */ if ((result = prng_is_valid(prng_idx)) != CRYPT_OK) { return result; } } modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); /* test message size */ if ((msglen + 11) > modulus_len) { return CRYPT_PK_INVALID_SIZE; } if (*outlen < modulus_len) { *outlen = modulus_len; result = CRYPT_BUFFER_OVERFLOW; goto bail; } /* generate an octets string PS */ ps = &out[2]; ps_len = modulus_len - msglen - 3; if (block_type == LTC_LTC_PKCS_1_EME) { /* now choose a random ps */ if (prng_descriptor[prng_idx].read(ps, ps_len, prng) != ps_len) { result = CRYPT_ERROR_READPRNG; goto bail; } /* transform zero bytes (if any) to non-zero random bytes */ for (i = 0; i < ps_len; i++) { while (ps[i] == 0) { if (prng_descriptor[prng_idx].read(&ps[i], 1, prng) != 1) { result = CRYPT_ERROR_READPRNG; goto bail; } } } } else { XMEMSET(ps, 0xFF, ps_len); } /* create string of length modulus_len */ out[0] = 0x00; out[1] = (unsigned char)block_type; /* block_type 1 or 2 */ out[2 + ps_len] = 0x00; XMEMCPY(&out[2 + ps_len + 1], msg, msglen); *outlen = modulus_len; result = CRYPT_OK; bail: return result; } /* pkcs_1_v1_5_encode */ #endif /* #ifdef LTC_PKCS_1 */ /* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_encode.c,v $ */ /* $Revision: 1.4 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/pkcs1/pkcs_1_pss_decode.c0000644000175100001440000001153210621351501020463 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file pkcs_1_pss_decode.c LTC_PKCS #1 PSS Signature Padding, Tom St Denis */ #ifdef LTC_PKCS_1 /** LTC_PKCS #1 v2.00 PSS decode @param msghash The hash to verify @param msghashlen The length of the hash (octets) @param sig The signature data (encoded data) @param siglen The length of the signature data (octets) @param saltlen The length of the salt used (octets) @param hash_idx The index of the hash desired @param modulus_bitlen The bit length of the RSA modulus @param res [out] The result of the comparison, 1==valid, 0==invalid @return CRYPT_OK if successful (even if the comparison failed) */ int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, const unsigned char *sig, unsigned long siglen, unsigned long saltlen, int hash_idx, unsigned long modulus_bitlen, int *res) { unsigned char *DB, *mask, *salt, *hash; unsigned long x, y, hLen, modulus_len; int err; hash_state md; LTC_ARGCHK(msghash != NULL); LTC_ARGCHK(res != NULL); /* default to invalid */ *res = 0; /* ensure hash is valid */ if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { return err; } hLen = hash_descriptor[hash_idx].hashsize; modulus_len = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0); /* check sizes */ if ((saltlen > modulus_len) || (modulus_len < hLen + saltlen + 2) || (siglen != modulus_len)) { return CRYPT_PK_INVALID_SIZE; } /* allocate ram for DB/mask/salt/hash of size modulus_len */ DB = XMALLOC(modulus_len); mask = XMALLOC(modulus_len); salt = XMALLOC(modulus_len); hash = XMALLOC(modulus_len); if (DB == NULL || mask == NULL || salt == NULL || hash == NULL) { if (DB != NULL) { XFREE(DB); } if (mask != NULL) { XFREE(mask); } if (salt != NULL) { XFREE(salt); } if (hash != NULL) { XFREE(hash); } return CRYPT_MEM; } /* ensure the 0xBC byte */ if (sig[siglen-1] != 0xBC) { err = CRYPT_INVALID_PACKET; goto LBL_ERR; } /* copy out the DB */ x = 0; XMEMCPY(DB, sig + x, modulus_len - hLen - 1); x += modulus_len - hLen - 1; /* copy out the hash */ XMEMCPY(hash, sig + x, hLen); x += hLen; /* check the MSB */ if ((sig[0] & ~(0xFF >> ((modulus_len<<3) - (modulus_bitlen-1)))) != 0) { err = CRYPT_INVALID_PACKET; goto LBL_ERR; } /* generate mask of length modulus_len - hLen - 1 from hash */ if ((err = pkcs_1_mgf1(hash_idx, hash, hLen, mask, modulus_len - hLen - 1)) != CRYPT_OK) { goto LBL_ERR; } /* xor against DB */ for (y = 0; y < (modulus_len - hLen - 1); y++) { DB[y] ^= mask[y]; } /* now clear the first byte [make sure smaller than modulus] */ DB[0] &= 0xFF >> ((modulus_len<<3) - (modulus_bitlen-1)); /* DB = PS || 0x01 || salt, PS == modulus_len - saltlen - hLen - 2 zero bytes */ /* check for zeroes and 0x01 */ for (x = 0; x < modulus_len - saltlen - hLen - 2; x++) { if (DB[x] != 0x00) { err = CRYPT_INVALID_PACKET; goto LBL_ERR; } } /* check for the 0x01 */ if (DB[x++] != 0x01) { err = CRYPT_INVALID_PACKET; goto LBL_ERR; } /* M = (eight) 0x00 || msghash || salt, mask = H(M) */ if ((err = hash_descriptor[hash_idx].init(&md)) != CRYPT_OK) { goto LBL_ERR; } zeromem(mask, 8); if ((err = hash_descriptor[hash_idx].process(&md, mask, 8)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hash_descriptor[hash_idx].process(&md, msghash, msghashlen)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hash_descriptor[hash_idx].process(&md, DB+x, saltlen)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hash_descriptor[hash_idx].done(&md, mask)) != CRYPT_OK) { goto LBL_ERR; } /* mask == hash means valid signature */ if (XMEMCMP(mask, hash, hLen) == 0) { *res = 1; } err = CRYPT_OK; LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(DB, modulus_len); zeromem(mask, modulus_len); zeromem(salt, modulus_len); zeromem(hash, modulus_len); #endif XFREE(hash); XFREE(salt); XFREE(mask); XFREE(DB); return err; } #endif /* LTC_PKCS_1 */ /* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_pss_decode.c,v $ */ /* $Revision: 1.11 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/pkcs1/pkcs_1_mgf1.c0000644000175100001440000000515310621351501017207 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file pkcs_1_mgf1.c The Mask Generation Function (MGF1) for LTC_PKCS #1, Tom St Denis */ #ifdef LTC_PKCS_1 /** Perform LTC_PKCS #1 MGF1 (internal) @param seed The seed for MGF1 @param seedlen The length of the seed @param hash_idx The index of the hash desired @param mask [out] The destination @param masklen The length of the mask desired @return CRYPT_OK if successful */ int pkcs_1_mgf1(int hash_idx, const unsigned char *seed, unsigned long seedlen, unsigned char *mask, unsigned long masklen) { unsigned long hLen, x; ulong32 counter; int err; hash_state *md; unsigned char *buf; LTC_ARGCHK(seed != NULL); LTC_ARGCHK(mask != NULL); /* ensure valid hash */ if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { return err; } /* get hash output size */ hLen = hash_descriptor[hash_idx].hashsize; /* allocate memory */ md = XMALLOC(sizeof(hash_state)); buf = XMALLOC(hLen); if (md == NULL || buf == NULL) { if (md != NULL) { XFREE(md); } if (buf != NULL) { XFREE(buf); } return CRYPT_MEM; } /* start counter */ counter = 0; while (masklen > 0) { /* handle counter */ STORE32H(counter, buf); ++counter; /* get hash of seed || counter */ if ((err = hash_descriptor[hash_idx].init(md)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hash_descriptor[hash_idx].process(md, seed, seedlen)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hash_descriptor[hash_idx].process(md, buf, 4)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hash_descriptor[hash_idx].done(md, buf)) != CRYPT_OK) { goto LBL_ERR; } /* store it */ for (x = 0; x < hLen && masklen > 0; x++, masklen--) { *mask++ = buf[x]; } } err = CRYPT_OK; LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(buf, hLen); zeromem(md, sizeof(hash_state)); #endif XFREE(buf); XFREE(md); return err; } #endif /* LTC_PKCS_1 */ /* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_mgf1.c,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/pkcs1/pkcs_1_v1_5_decode.c0000644000175100001440000000606310621351501020433 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file pkcs_1_v1_5_decode.c * * LTC_PKCS #1 v1.5 Padding. (Andreas Lange) */ #ifdef LTC_PKCS_1 /** @brief LTC_PKCS #1 v1.5 decode. * * @param msg The encoded data to decode * @param msglen The length of the encoded data (octets) * @param block_type Block type to use in padding (\sa ltc_pkcs_1_v1_5_blocks) * @param modulus_bitlen The bit length of the RSA modulus * @param out [out] Destination of decoding * @param outlen [in/out] The max size and resulting size of the decoding * @param is_valid [out] Boolean whether the padding was valid * * @return CRYPT_OK if successful (even if invalid) */ int pkcs_1_v1_5_decode(const unsigned char *msg, unsigned long msglen, int block_type, unsigned long modulus_bitlen, unsigned char *out, unsigned long *outlen, int *is_valid) { unsigned long modulus_len, ps_len, i; int result; /* default to invalid packet */ *is_valid = 0; modulus_len = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0); /* test message size */ if ((msglen > modulus_len) || (modulus_len < 11)) { return CRYPT_PK_INVALID_SIZE; } /* separate encoded message */ if ((msg[0] != 0x00) || (msg[1] != (unsigned char)block_type)) { result = CRYPT_INVALID_PACKET; goto bail; } if (block_type == LTC_LTC_PKCS_1_EME) { for (i = 2; i < modulus_len; i++) { /* separator */ if (msg[i] == 0x00) { break; } } ps_len = i++ - 2; if ((i >= modulus_len) || (ps_len < 8)) { /* There was no octet with hexadecimal value 0x00 to separate ps from m, * or the length of ps is less than 8 octets. */ result = CRYPT_INVALID_PACKET; goto bail; } } else { for (i = 2; i < modulus_len - 1; i++) { if (msg[i] != 0xFF) { break; } } /* separator check */ if (msg[i] != 0) { /* There was no octet with hexadecimal value 0x00 to separate ps from m. */ result = CRYPT_INVALID_PACKET; goto bail; } ps_len = i - 2; } if (*outlen < (msglen - (2 + ps_len + 1))) { *outlen = msglen - (2 + ps_len + 1); result = CRYPT_BUFFER_OVERFLOW; goto bail; } *outlen = (msglen - (2 + ps_len + 1)); XMEMCPY(out, &msg[2 + ps_len + 1], *outlen); /* valid packet */ *is_valid = 1; result = CRYPT_OK; bail: return result; } /* pkcs_1_v1_5_decode */ #endif /* #ifdef LTC_PKCS_1 */ /* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_v1_5_decode.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/pk/pkcs1/pkcs_1_i2osp.c0000644000175100001440000000232710621351501017411 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file pkcs_1_i2osp.c Integer to Octet I2OSP, Tom St Denis */ #ifdef LTC_PKCS_1 /* always stores the same # of bytes, pads with leading zero bytes as required */ /** LTC_PKCS #1 Integer to binary @param n The integer to store @param modulus_len The length of the RSA modulus @param out [out] The destination for the integer @return CRYPT_OK if successful */ int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out) { unsigned long size; size = mp_unsigned_bin_size(n); if (size > modulus_len) { return CRYPT_BUFFER_OVERFLOW; } /* store it */ zeromem(out, modulus_len); return mp_to_unsigned_bin(n, out+(modulus_len-size)); } #endif /* LTC_PKCS_1 */ /* $Source: /cvs/libtom/libtomcrypt/src/pk/pkcs1/pkcs_1_i2osp.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/mac/0000755000175100001440000000000010621351501014052 5ustar tomuserslibtomcrypt-1.17/src/mac/f9/0000755000175100001440000000000010621351501014370 5ustar tomuserslibtomcrypt-1.17/src/mac/f9/f9_done.c0000644000175100001440000000370610621351501016065 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file f9_done.c f9 Support, terminate the state */ #ifdef LTC_F9_MODE /** Terminate the f9-MAC state @param f9 f9 state to terminate @param out [out] Destination for the MAC tag @param outlen [in/out] Destination size and final tag size Return CRYPT_OK on success */ int f9_done(f9_state *f9, unsigned char *out, unsigned long *outlen) { int err, x; LTC_ARGCHK(f9 != NULL); LTC_ARGCHK(out != NULL); /* check structure */ if ((err = cipher_is_valid(f9->cipher)) != CRYPT_OK) { return err; } if ((f9->blocksize > cipher_descriptor[f9->cipher].block_length) || (f9->blocksize < 0) || (f9->buflen > f9->blocksize) || (f9->buflen < 0)) { return CRYPT_INVALID_ARG; } if (f9->buflen != 0) { /* encrypt */ cipher_descriptor[f9->cipher].ecb_encrypt(f9->IV, f9->IV, &f9->key); f9->buflen = 0; for (x = 0; x < f9->blocksize; x++) { f9->ACC[x] ^= f9->IV[x]; } } /* schedule modified key */ if ((err = cipher_descriptor[f9->cipher].setup(f9->akey, f9->keylen, 0, &f9->key)) != CRYPT_OK) { return err; } /* encrypt the ACC */ cipher_descriptor[f9->cipher].ecb_encrypt(f9->ACC, f9->ACC, &f9->key); cipher_descriptor[f9->cipher].done(&f9->key); /* extract tag */ for (x = 0; x < f9->blocksize && (unsigned long)x < *outlen; x++) { out[x] = f9->ACC[x]; } *outlen = x; #ifdef LTC_CLEAN_STACK zeromem(f9, sizeof(*f9)); #endif return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/f9/f9_done.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/mac/f9/f9_file.c0000644000175100001440000000377410621351501016064 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file f9_file.c f9 support, process a file, Tom St Denis */ #ifdef LTC_F9_MODE /** f9 a file @param cipher The index of the cipher desired @param key The secret key @param keylen The length of the secret key (octets) @param filename The name of the file you wish to f9 @param out [out] Where the authentication tag is to be stored @param outlen [in/out] The max size and resulting size of the authentication tag @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled */ int f9_file(int cipher, const unsigned char *key, unsigned long keylen, const char *filename, unsigned char *out, unsigned long *outlen) { #ifdef LTC_NO_FILE return CRYPT_NOP; #else int err, x; f9_state f9; FILE *in; unsigned char buf[512]; LTC_ARGCHK(key != NULL); LTC_ARGCHK(filename != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); in = fopen(filename, "rb"); if (in == NULL) { return CRYPT_FILE_NOTFOUND; } if ((err = f9_init(&f9, cipher, key, keylen)) != CRYPT_OK) { fclose(in); return err; } do { x = fread(buf, 1, sizeof(buf), in); if ((err = f9_process(&f9, buf, x)) != CRYPT_OK) { fclose(in); return err; } } while (x == sizeof(buf)); fclose(in); if ((err = f9_done(&f9, out, outlen)) != CRYPT_OK) { return err; } #ifdef LTC_CLEAN_STACK zeromem(buf, sizeof(buf)); #endif return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/f9/f9_file.c,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/mac/f9/f9_init.c0000644000175100001440000000331110621351501016073 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file f9_init.c F9 Support, start an F9 state */ #ifdef LTC_F9_MODE /** Initialize F9-MAC state @param f9 [out] f9 state to initialize @param cipher Index of cipher to use @param key [in] Secret key @param keylen Length of secret key in octets Return CRYPT_OK on success */ int f9_init(f9_state *f9, int cipher, const unsigned char *key, unsigned long keylen) { int x, err; LTC_ARGCHK(f9 != NULL); LTC_ARGCHK(key != NULL); /* schedule the key */ if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { return err; } #ifdef LTC_FAST if (cipher_descriptor[cipher].block_length % sizeof(LTC_FAST_TYPE)) { return CRYPT_INVALID_ARG; } #endif if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &f9->key)) != CRYPT_OK) { goto done; } /* make the second key */ for (x = 0; (unsigned)x < keylen; x++) { f9->akey[x] = key[x] ^ 0xAA; } /* setup struct */ zeromem(f9->IV, cipher_descriptor[cipher].block_length); zeromem(f9->ACC, cipher_descriptor[cipher].block_length); f9->blocksize = cipher_descriptor[cipher].block_length; f9->cipher = cipher; f9->buflen = 0; f9->keylen = keylen; done: return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/f9/f9_init.c,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/mac/f9/f9_memory.c0000644000175100001440000000345410621351501016450 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file f9_process.c f9 Support, Process a block through F9-MAC */ #ifdef LTC_F9_MODE /** f9-MAC a block of memory @param cipher Index of cipher to use @param key [in] Secret key @param keylen Length of key in octets @param in [in] Message to MAC @param inlen Length of input in octets @param out [out] Destination for the MAC tag @param outlen [in/out] Output size and final tag size Return CRYPT_OK on success. */ int f9_memory(int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { f9_state *f9; int err; /* is the cipher valid? */ if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { return err; } /* Use accelerator if found */ if (cipher_descriptor[cipher].f9_memory != NULL) { return cipher_descriptor[cipher].f9_memory(key, keylen, in, inlen, out, outlen); } f9 = XCALLOC(1, sizeof(*f9)); if (f9 == NULL) { return CRYPT_MEM; } if ((err = f9_init(f9, cipher, key, keylen)) != CRYPT_OK) { goto done; } if ((err = f9_process(f9, in, inlen)) != CRYPT_OK) { goto done; } err = f9_done(f9, out, outlen); done: XFREE(f9); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/f9/f9_memory.c,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/mac/f9/f9_test.c0000644000175100001440000000450410621351501016114 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file f9_test.c f9 Support, Test F9 mode */ #ifdef LTC_F9_MODE /** Test f9-MAC mode Return CRYPT_OK on succes */ int f9_test(void) { #ifdef LTC_NO_TEST return CRYPT_NOP; #else static const struct { int msglen; unsigned char K[16], M[128], T[4]; } tests[] = { { 20, { 0x2B, 0xD6, 0x45, 0x9F, 0x82, 0xC5, 0xB3, 0x00, 0x95, 0x2C, 0x49, 0x10, 0x48, 0x81, 0xFF, 0x48 }, { 0x38, 0xA6, 0xF0, 0x56, 0xB8, 0xAE, 0xFD, 0xA9, 0x33, 0x32, 0x34, 0x62, 0x63, 0x39, 0x38, 0x61, 0x37, 0x34, 0x79, 0x40 }, { 0x46, 0xE0, 0x0D, 0x4B } }, { 105, { 0x83, 0xFD, 0x23, 0xA2, 0x44, 0xA7, 0x4C, 0xF3, 0x58, 0xDA, 0x30, 0x19, 0xF1, 0x72, 0x26, 0x35 }, { 0x36, 0xAF, 0x61, 0x44, 0x4F, 0x30, 0x2A, 0xD2, 0x35, 0xC6, 0x87, 0x16, 0x63, 0x3C, 0x66, 0xFB, 0x75, 0x0C, 0x26, 0x68, 0x65, 0xD5, 0x3C, 0x11, 0xEA, 0x05, 0xB1, 0xE9, 0xFA, 0x49, 0xC8, 0x39, 0x8D, 0x48, 0xE1, 0xEF, 0xA5, 0x90, 0x9D, 0x39, 0x47, 0x90, 0x28, 0x37, 0xF5, 0xAE, 0x96, 0xD5, 0xA0, 0x5B, 0xC8, 0xD6, 0x1C, 0xA8, 0xDB, 0xEF, 0x1B, 0x13, 0xA4, 0xB4, 0xAB, 0xFE, 0x4F, 0xB1, 0x00, 0x60, 0x45, 0xB6, 0x74, 0xBB, 0x54, 0x72, 0x93, 0x04, 0xC3, 0x82, 0xBE, 0x53, 0xA5, 0xAF, 0x05, 0x55, 0x61, 0x76, 0xF6, 0xEA, 0xA2, 0xEF, 0x1D, 0x05, 0xE4, 0xB0, 0x83, 0x18, 0x1E, 0xE6, 0x74, 0xCD, 0xA5, 0xA4, 0x85, 0xF7, 0x4D, 0x7A, 0x40|0x80 }, { 0x95, 0xAE, 0x41, 0xBA }, } }; unsigned char T[16]; unsigned long taglen; int err, x, idx; /* find kasumi */ if ((idx = find_cipher("kasumi")) == -1) { return CRYPT_NOP; } for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { taglen = 4; if ((err = f9_memory(idx, tests[x].K, 16, tests[x].M, tests[x].msglen, T, &taglen)) != CRYPT_OK) { return err; } if (taglen != 4 || XMEMCMP(T, tests[x].T, 4)) { return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/f9/f9_test.c,v $ */ /* $Revision: 1.9 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/mac/f9/f9_process.c0000644000175100001440000000415210621351501016612 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file f9_process.c f9 Support, process blocks with f9 */ #ifdef LTC_F9_MODE /** Process data through f9-MAC @param f9 The f9-MAC state @param in Input data to process @param inlen Length of input in octets Return CRYPT_OK on success */ int f9_process(f9_state *f9, const unsigned char *in, unsigned long inlen) { int err, x; LTC_ARGCHK(f9 != NULL); LTC_ARGCHK(in != NULL); /* check structure */ if ((err = cipher_is_valid(f9->cipher)) != CRYPT_OK) { return err; } if ((f9->blocksize > cipher_descriptor[f9->cipher].block_length) || (f9->blocksize < 0) || (f9->buflen > f9->blocksize) || (f9->buflen < 0)) { return CRYPT_INVALID_ARG; } #ifdef LTC_FAST if (f9->buflen == 0) { while (inlen >= (unsigned long)f9->blocksize) { for (x = 0; x < f9->blocksize; x += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE*)&(f9->IV[x])) ^= *((LTC_FAST_TYPE*)&(in[x])); } cipher_descriptor[f9->cipher].ecb_encrypt(f9->IV, f9->IV, &f9->key); for (x = 0; x < f9->blocksize; x += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE*)&(f9->ACC[x])) ^= *((LTC_FAST_TYPE*)&(f9->IV[x])); } in += f9->blocksize; inlen -= f9->blocksize; } } #endif while (inlen) { if (f9->buflen == f9->blocksize) { cipher_descriptor[f9->cipher].ecb_encrypt(f9->IV, f9->IV, &f9->key); for (x = 0; x < f9->blocksize; x++) { f9->ACC[x] ^= f9->IV[x]; } f9->buflen = 0; } f9->IV[f9->buflen++] ^= *in++; --inlen; } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/f9/f9_process.c,v $ */ /* $Revision: 1.4 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/mac/f9/f9_memory_multi.c0000644000175100001440000000477410621351501017670 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" #include /** @file f9_memory_multi.c f9 support, process multiple blocks of memory, Tom St Denis */ #ifdef LTC_F9_MODE /** f9 multiple blocks of memory @param cipher The index of the desired cipher @param key The secret key @param keylen The length of the secret key (octets) @param out [out] The destination of the authentication tag @param outlen [in/out] The max size and resulting size of the authentication tag (octets) @param in The data to send through f9 @param inlen The length of the data to send through f9 (octets) @param ... tuples of (data,len) pairs to f9, terminated with a (NULL,x) (x=don't care) @return CRYPT_OK if successful */ int f9_memory_multi(int cipher, const unsigned char *key, unsigned long keylen, unsigned char *out, unsigned long *outlen, const unsigned char *in, unsigned long inlen, ...) { int err; f9_state *f9; va_list args; const unsigned char *curptr; unsigned long curlen; LTC_ARGCHK(key != NULL); LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* allocate ram for f9 state */ f9 = XMALLOC(sizeof(f9_state)); if (f9 == NULL) { return CRYPT_MEM; } /* f9 process the message */ if ((err = f9_init(f9, cipher, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } va_start(args, inlen); curptr = in; curlen = inlen; for (;;) { /* process buf */ if ((err = f9_process(f9, curptr, curlen)) != CRYPT_OK) { goto LBL_ERR; } /* step to next */ curptr = va_arg(args, const unsigned char*); if (curptr == NULL) { break; } curlen = va_arg(args, unsigned long); } if ((err = f9_done(f9, out, outlen)) != CRYPT_OK) { goto LBL_ERR; } LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(f9, sizeof(f9_state)); #endif XFREE(f9); va_end(args); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/f9/f9_memory_multi.c,v $ */ /* $Revision: 1.3 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/mac/hmac/0000755000175100001440000000000010621351501014762 5ustar tomuserslibtomcrypt-1.17/src/mac/hmac/hmac_process.c0000644000175100001440000000215610621351501017600 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file hmac_process.c LTC_HMAC support, process data, Tom St Denis/Dobes Vandermeer */ #ifdef LTC_HMAC /** Process data through LTC_HMAC @param hmac The hmac state @param in The data to send through LTC_HMAC @param inlen The length of the data to LTC_HMAC (octets) @return CRYPT_OK if successful */ int hmac_process(hmac_state *hmac, const unsigned char *in, unsigned long inlen) { int err; LTC_ARGCHK(hmac != NULL); LTC_ARGCHK(in != NULL); if ((err = hash_is_valid(hmac->hash)) != CRYPT_OK) { return err; } return hash_descriptor[hmac->hash].process(&hmac->md, in, inlen); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/hmac/hmac_process.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:37:41 $ */ libtomcrypt-1.17/src/mac/hmac/hmac_done.c0000644000175100001440000000543710621351501017054 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file hmac_done.c LTC_HMAC support, terminate stream, Tom St Denis/Dobes Vandermeer */ #ifdef LTC_HMAC #define LTC_HMAC_BLOCKSIZE hash_descriptor[hash].blocksize /** Terminate an LTC_HMAC session @param hmac The LTC_HMAC state @param out [out] The destination of the LTC_HMAC authentication tag @param outlen [in/out] The max size and resulting size of the LTC_HMAC authentication tag @return CRYPT_OK if successful */ int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen) { unsigned char *buf, *isha; unsigned long hashsize, i; int hash, err; LTC_ARGCHK(hmac != NULL); LTC_ARGCHK(out != NULL); /* test hash */ hash = hmac->hash; if((err = hash_is_valid(hash)) != CRYPT_OK) { return err; } /* get the hash message digest size */ hashsize = hash_descriptor[hash].hashsize; /* allocate buffers */ buf = XMALLOC(LTC_HMAC_BLOCKSIZE); isha = XMALLOC(hashsize); if (buf == NULL || isha == NULL) { if (buf != NULL) { XFREE(buf); } if (isha != NULL) { XFREE(isha); } return CRYPT_MEM; } /* Get the hash of the first LTC_HMAC vector plus the data */ if ((err = hash_descriptor[hash].done(&hmac->md, isha)) != CRYPT_OK) { goto LBL_ERR; } /* Create the second LTC_HMAC vector vector for step (3) */ for(i=0; i < LTC_HMAC_BLOCKSIZE; i++) { buf[i] = hmac->key[i] ^ 0x5C; } /* Now calculate the "outer" hash for step (5), (6), and (7) */ if ((err = hash_descriptor[hash].init(&hmac->md)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hash_descriptor[hash].process(&hmac->md, buf, LTC_HMAC_BLOCKSIZE)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hash_descriptor[hash].process(&hmac->md, isha, hashsize)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hash_descriptor[hash].done(&hmac->md, buf)) != CRYPT_OK) { goto LBL_ERR; } /* copy to output */ for (i = 0; i < hashsize && i < *outlen; i++) { out[i] = buf[i]; } *outlen = i; err = CRYPT_OK; LBL_ERR: XFREE(hmac->key); #ifdef LTC_CLEAN_STACK zeromem(isha, hashsize); zeromem(buf, hashsize); zeromem(hmac, sizeof(*hmac)); #endif XFREE(isha); XFREE(buf); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/hmac/hmac_done.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:37:41 $ */ libtomcrypt-1.17/src/mac/hmac/hmac_file.c0000644000175100001440000000443710621351501017045 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file hmac_file.c LTC_HMAC support, process a file, Tom St Denis/Dobes Vandermeer */ #ifdef LTC_HMAC /** LTC_HMAC a file @param hash The index of the hash you wish to use @param fname The name of the file you wish to LTC_HMAC @param key The secret key @param keylen The length of the secret key @param out [out] The LTC_HMAC authentication tag @param outlen [in/out] The max size and resulting size of the authentication tag @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled */ int hmac_file(int hash, const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *out, unsigned long *outlen) { #ifdef LTC_NO_FILE return CRYPT_NOP; #else hmac_state hmac; FILE *in; unsigned char buf[512]; size_t x; int err; LTC_ARGCHK(fname != NULL); LTC_ARGCHK(key != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); if((err = hash_is_valid(hash)) != CRYPT_OK) { return err; } if ((err = hmac_init(&hmac, hash, key, keylen)) != CRYPT_OK) { return err; } in = fopen(fname, "rb"); if (in == NULL) { return CRYPT_FILE_NOTFOUND; } /* process the file contents */ do { x = fread(buf, 1, sizeof(buf), in); if ((err = hmac_process(&hmac, buf, (unsigned long)x)) != CRYPT_OK) { /* we don't trap this error since we're already returning an error! */ fclose(in); return err; } } while (x == sizeof(buf)); if (fclose(in) != 0) { return CRYPT_ERROR; } /* get final hmac */ if ((err = hmac_done(&hmac, out, outlen)) != CRYPT_OK) { return err; } #ifdef LTC_CLEAN_STACK /* clear memory */ zeromem(buf, sizeof(buf)); #endif return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/hmac/hmac_file.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:37:41 $ */ libtomcrypt-1.17/src/mac/hmac/hmac_init.c0000644000175100001440000000556110621351501017070 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file hmac_init.c LTC_HMAC support, initialize state, Tom St Denis/Dobes Vandermeer */ #ifdef LTC_HMAC #define LTC_HMAC_BLOCKSIZE hash_descriptor[hash].blocksize /** Initialize an LTC_HMAC context. @param hmac The LTC_HMAC state @param hash The index of the hash you want to use @param key The secret key @param keylen The length of the secret key (octets) @return CRYPT_OK if successful */ int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen) { unsigned char *buf; unsigned long hashsize; unsigned long i, z; int err; LTC_ARGCHK(hmac != NULL); LTC_ARGCHK(key != NULL); /* valid hash? */ if ((err = hash_is_valid(hash)) != CRYPT_OK) { return err; } hmac->hash = hash; hashsize = hash_descriptor[hash].hashsize; /* valid key length? */ if (keylen == 0) { return CRYPT_INVALID_KEYSIZE; } /* allocate ram for buf */ buf = XMALLOC(LTC_HMAC_BLOCKSIZE); if (buf == NULL) { return CRYPT_MEM; } /* allocate memory for key */ hmac->key = XMALLOC(LTC_HMAC_BLOCKSIZE); if (hmac->key == NULL) { XFREE(buf); return CRYPT_MEM; } /* (1) make sure we have a large enough key */ if(keylen > LTC_HMAC_BLOCKSIZE) { z = LTC_HMAC_BLOCKSIZE; if ((err = hash_memory(hash, key, keylen, hmac->key, &z)) != CRYPT_OK) { goto LBL_ERR; } if(hashsize < LTC_HMAC_BLOCKSIZE) { zeromem((hmac->key) + hashsize, (size_t)(LTC_HMAC_BLOCKSIZE - hashsize)); } keylen = hashsize; } else { XMEMCPY(hmac->key, key, (size_t)keylen); if(keylen < LTC_HMAC_BLOCKSIZE) { zeromem((hmac->key) + keylen, (size_t)(LTC_HMAC_BLOCKSIZE - keylen)); } } /* Create the initial vector for step (3) */ for(i=0; i < LTC_HMAC_BLOCKSIZE; i++) { buf[i] = hmac->key[i] ^ 0x36; } /* Pre-pend that to the hash data */ if ((err = hash_descriptor[hash].init(&hmac->md)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hash_descriptor[hash].process(&hmac->md, buf, LTC_HMAC_BLOCKSIZE)) != CRYPT_OK) { goto LBL_ERR; } goto done; LBL_ERR: /* free the key since we failed */ XFREE(hmac->key); done: #ifdef LTC_CLEAN_STACK zeromem(buf, LTC_HMAC_BLOCKSIZE); #endif XFREE(buf); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/hmac/hmac_init.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:37:41 $ */ libtomcrypt-1.17/src/mac/hmac/hmac_test.c0000644000175100001440000003004110621351501017073 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file hmac_test.c LTC_HMAC support, self-test, Tom St Denis/Dobes Vandermeer */ #ifdef LTC_HMAC #define LTC_HMAC_BLOCKSIZE hash_descriptor[hash].blocksize /* TEST CASES SOURCE: Network Working Group P. Cheng Request for Comments: 2202 IBM Category: Informational R. Glenn NIST September 1997 Test Cases for LTC_HMAC-LTC_MD5 and LTC_HMAC-LTC_SHA-1 */ /** LTC_HMAC self-test @return CRYPT_OK if successful, CRYPT_NOP if tests have been disabled. */ int hmac_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else unsigned char digest[MAXBLOCKSIZE]; int i; static const struct hmac_test_case { int num; char *algo; unsigned char key[128]; unsigned long keylen; unsigned char data[128]; unsigned long datalen; unsigned char digest[MAXBLOCKSIZE]; } cases[] = { /* 3. Test Cases for LTC_HMAC-LTC_SHA-1 test_case = 1 key = 0x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c key_len = 20 data = "Hi Ther 20 digest = 0x4c1a03424b55e07fe7f27be1d58bb9324a9a5a04 digest-96 = 0x4c1a03424b55e07fe7f27be1 */ { 5, "sha1", {0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c}, 20, "Test With Truncation", 20, {0x4c, 0x1a, 0x03, 0x42, 0x4b, 0x55, 0xe0, 0x7f, 0xe7, 0xf2, 0x7b, 0xe1, 0xd5, 0x8b, 0xb9, 0x32, 0x4a, 0x9a, 0x5a, 0x04} }, /* test_case = 6 key = 0xaa repeated 80 times key_len = 80 data = "Test Using Larger Than Block-Size Key - Hash Key First" data_len = 54 digest = 0xaa4ae5e15272d00e95705637ce8a3b55ed402112 */ { 6, "sha1", {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80, "Test Using Larger Than Block-Size Key - Hash Key First", 54, {0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e, 0x95, 0x70, 0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55, 0xed, 0x40, 0x21, 0x12} }, /* test_case = 7 key = 0xaa repeated 80 times key_len = 80 data = "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data" data_len = 73 digest = 0xe8e99d0f45237d786d6bbaa7965c7808bbff1a91 */ { 7, "sha1", {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80, "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73, {0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78, 0x6d, 0x6b, 0xba, 0xa7, 0x96, 0x5c, 0x78, 0x08, 0xbb, 0xff, 0x1a, 0x91} }, /* 2. Test Cases for LTC_HMAC-LTC_MD5 test_case = 1 key = 0x0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b key_len = 16 data = "Hi There" data_len = 8 digest = 0x92 94 72 7a 36 38 bb 1c 13 f4 8e f8 15 8b fc 9d */ { 1, "md5", {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b}, 16, "Hi There", 8, {0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c, 0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d} }, /* test_case = 2 key = "Jefe" key_len = 4 data = "what do ya want for nothing?" data_len = 28 digest = 0x750c783e6ab0b503eaa86e310a5db738 */ { 2, "md5", "Jefe", 4, "what do ya want for nothing?", 28, {0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03, 0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38} }, /* test_case = 3 key = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa key_len 16 data = 0xdd repeated 50 times data_len = 50 digest = 0x56be34521d144c88dbb8c733f0e8b3f6 */ { 3, "md5", {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 16, {0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd}, 50, {0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88, 0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6} }, /* test_case = 4 key = 0x0102030405060708090a0b0c0d0e0f10111213141516171819 key_len 25 data = 0xcd repeated 50 times data_len = 50 digest = 0x697eaf0aca3a3aea3a75164746ffaa79 */ { 4, "md5", {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19}, 25, {0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd}, 50, {0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea, 0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79} }, /* test_case = 5 key = 0x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c key_len = 16 data = "Test With Truncation" data_len = 20 digest = 0x56461ef2342edc00f9bab995690efd4c digest-96 0x56461ef2342edc00f9bab995 */ { 5, "md5", {0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c}, 16, "Test With Truncation", 20, {0x56, 0x46, 0x1e, 0xf2, 0x34, 0x2e, 0xdc, 0x00, 0xf9, 0xba, 0xb9, 0x95, 0x69, 0x0e, 0xfd, 0x4c} }, /* test_case = 6 key = 0xaa repeated 80 times key_len = 80 data = "Test Using Larger Than Block-Size Key - Hash Key First" data_len = 54 digest = 0x6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd */ { 6, "md5", {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80, "Test Using Larger Than Block-Size Key - Hash Key First", 54, {0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f, 0x0b, 0x62, 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd} }, /* test_case = 7 key = 0xaa repeated 80 times key_len = 80 data = "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data" data_len = 73 digest = 0x6f630fad67cda0ee1fb1f562db3aa53e */ { 7, "md5", {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80, "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73, {0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee, 0x1f, 0xb1, 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e} } }; unsigned long outlen; int err; int tested=0,failed=0; for(i=0; i < (int)(sizeof(cases) / sizeof(cases[0])); i++) { int hash = find_hash(cases[i].algo); if (hash == -1) continue; ++tested; outlen = sizeof(digest); if((err = hmac_memory(hash, cases[i].key, cases[i].keylen, cases[i].data, cases[i].datalen, digest, &outlen)) != CRYPT_OK) { #if 0 printf("LTC_HMAC-%s test #%d, %s\n", cases[i].algo, cases[i].num, error_to_string(err)); #endif return err; } if(XMEMCMP(digest, cases[i].digest, (size_t)hash_descriptor[hash].hashsize) != 0) { failed++; #if 0 unsigned int j; printf("\nLTC_HMAC-%s test #%d:\n", cases[i].algo, cases[i].num); printf( "Result: 0x"); for(j=0; j < hash_descriptor[hash].hashsize; j++) { printf("%2x ", digest[j]); } printf("\nCorrect: 0x"); for(j=0; j < hash_descriptor[hash].hashsize; j++) { printf("%2x ", cases[i].digest[j]); } printf("\n"); return CRYPT_ERROR; #endif } else { /* printf("LTC_HMAC-%s test #%d: Passed\n", cases[i].algo, cases[i].num); */ } } if (failed != 0) { return CRYPT_FAIL_TESTVECTOR; } else if (tested == 0) { return CRYPT_NOP; } else { return CRYPT_OK; } #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/hmac/hmac_test.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2007/05/12 14:37:41 $ */ libtomcrypt-1.17/src/mac/hmac/hmac_memory.c0000644000175100001440000000453410621351501017434 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file hmac_memory.c LTC_HMAC support, process a block of memory, Tom St Denis/Dobes Vandermeer */ #ifdef LTC_HMAC /** LTC_HMAC a block of memory to produce the authentication tag @param hash The index of the hash to use @param key The secret key @param keylen The length of the secret key (octets) @param in The data to LTC_HMAC @param inlen The length of the data to LTC_HMAC (octets) @param out [out] Destination of the authentication tag @param outlen [in/out] Max size and resulting size of authentication tag @return CRYPT_OK if successful */ int hmac_memory(int hash, const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { hmac_state *hmac; int err; LTC_ARGCHK(key != NULL); LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* make sure hash descriptor is valid */ if ((err = hash_is_valid(hash)) != CRYPT_OK) { return err; } /* is there a descriptor? */ if (hash_descriptor[hash].hmac_block != NULL) { return hash_descriptor[hash].hmac_block(key, keylen, in, inlen, out, outlen); } /* nope, so call the hmac functions */ /* allocate ram for hmac state */ hmac = XMALLOC(sizeof(hmac_state)); if (hmac == NULL) { return CRYPT_MEM; } if ((err = hmac_init(hmac, hash, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hmac_process(hmac, in, inlen)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hmac_done(hmac, out, outlen)) != CRYPT_OK) { goto LBL_ERR; } err = CRYPT_OK; LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(hmac, sizeof(hmac_state)); #endif XFREE(hmac); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/hmac/hmac_memory.c,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2007/05/12 14:37:41 $ */ libtomcrypt-1.17/src/mac/hmac/hmac_memory_multi.c0000644000175100001440000000510310621351501020637 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" #include /** @file hmac_memory_multi.c LTC_HMAC support, process multiple blocks of memory, Tom St Denis/Dobes Vandermeer */ #ifdef LTC_HMAC /** LTC_HMAC multiple blocks of memory to produce the authentication tag @param hash The index of the hash to use @param key The secret key @param keylen The length of the secret key (octets) @param out [out] Destination of the authentication tag @param outlen [in/out] Max size and resulting size of authentication tag @param in The data to LTC_HMAC @param inlen The length of the data to LTC_HMAC (octets) @param ... tuples of (data,len) pairs to LTC_HMAC, terminated with a (NULL,x) (x=don't care) @return CRYPT_OK if successful */ int hmac_memory_multi(int hash, const unsigned char *key, unsigned long keylen, unsigned char *out, unsigned long *outlen, const unsigned char *in, unsigned long inlen, ...) { hmac_state *hmac; int err; va_list args; const unsigned char *curptr; unsigned long curlen; LTC_ARGCHK(key != NULL); LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* allocate ram for hmac state */ hmac = XMALLOC(sizeof(hmac_state)); if (hmac == NULL) { return CRYPT_MEM; } if ((err = hmac_init(hmac, hash, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } va_start(args, inlen); curptr = in; curlen = inlen; for (;;) { /* process buf */ if ((err = hmac_process(hmac, curptr, curlen)) != CRYPT_OK) { goto LBL_ERR; } /* step to next */ curptr = va_arg(args, const unsigned char*); if (curptr == NULL) { break; } curlen = va_arg(args, unsigned long); } if ((err = hmac_done(hmac, out, outlen)) != CRYPT_OK) { goto LBL_ERR; } LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(hmac, sizeof(hmac_state)); #endif XFREE(hmac); va_end(args); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/hmac/hmac_memory_multi.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:37:41 $ */ libtomcrypt-1.17/src/mac/omac/0000755000175100001440000000000010621351501014771 5ustar tomuserslibtomcrypt-1.17/src/mac/omac/omac_process.c0000644000175100001440000000504710621351501017620 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file omac_process.c LTC_OMAC1 support, process data, Tom St Denis */ #ifdef LTC_OMAC /** Process data through LTC_OMAC @param omac The LTC_OMAC state @param in The input data to send through LTC_OMAC @param inlen The length of the input (octets) @return CRYPT_OK if successful */ int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen) { unsigned long n, x, blklen; int err; LTC_ARGCHK(omac != NULL); LTC_ARGCHK(in != NULL); if ((err = cipher_is_valid(omac->cipher_idx)) != CRYPT_OK) { return err; } if ((omac->buflen > (int)sizeof(omac->block)) || (omac->buflen < 0) || (omac->blklen > (int)sizeof(omac->block)) || (omac->buflen > omac->blklen)) { return CRYPT_INVALID_ARG; } #ifdef LTC_FAST blklen = cipher_descriptor[omac->cipher_idx].block_length; if (omac->buflen == 0 && inlen > blklen) { unsigned long y; for (x = 0; x < (inlen - blklen); x += blklen) { for (y = 0; y < blklen; y += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE*)(&omac->prev[y])) ^= *((LTC_FAST_TYPE*)(&in[y])); } in += blklen; if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->prev, omac->prev, &omac->key)) != CRYPT_OK) { return err; } } inlen -= x; } #endif while (inlen != 0) { /* ok if the block is full we xor in prev, encrypt and replace prev */ if (omac->buflen == omac->blklen) { for (x = 0; x < (unsigned long)omac->blklen; x++) { omac->block[x] ^= omac->prev[x]; } if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->prev, &omac->key)) != CRYPT_OK) { return err; } omac->buflen = 0; } /* add bytes */ n = MIN(inlen, (unsigned long)(omac->blklen - omac->buflen)); XMEMCPY(omac->block + omac->buflen, in, n); omac->buflen += n; inlen -= n; in += n; } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/omac/omac_process.c,v $ */ /* $Revision: 1.13 $ */ /* $Date: 2007/05/12 14:37:41 $ */ libtomcrypt-1.17/src/mac/omac/omac_memory.c0000644000175100001440000000445510621351501017454 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file omac_memory.c LTC_OMAC1 support, process a block of memory, Tom St Denis */ #ifdef LTC_OMAC /** LTC_OMAC a block of memory @param cipher The index of the desired cipher @param key The secret key @param keylen The length of the secret key (octets) @param in The data to send through LTC_OMAC @param inlen The length of the data to send through LTC_OMAC (octets) @param out [out] The destination of the authentication tag @param outlen [in/out] The max size and resulting size of the authentication tag (octets) @return CRYPT_OK if successful */ int omac_memory(int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { int err; omac_state *omac; LTC_ARGCHK(key != NULL); LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* is the cipher valid? */ if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { return err; } /* Use accelerator if found */ if (cipher_descriptor[cipher].omac_memory != NULL) { return cipher_descriptor[cipher].omac_memory(key, keylen, in, inlen, out, outlen); } /* allocate ram for omac state */ omac = XMALLOC(sizeof(omac_state)); if (omac == NULL) { return CRYPT_MEM; } /* omac process the message */ if ((err = omac_init(omac, cipher, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } if ((err = omac_process(omac, in, inlen)) != CRYPT_OK) { goto LBL_ERR; } if ((err = omac_done(omac, out, outlen)) != CRYPT_OK) { goto LBL_ERR; } err = CRYPT_OK; LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(omac, sizeof(omac_state)); #endif XFREE(omac); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/omac/omac_memory.c,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2007/05/12 14:37:41 $ */ libtomcrypt-1.17/src/mac/omac/omac_done.c0000644000175100001440000000430010621351501017056 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file omac_done.c LTC_OMAC1 support, terminate a stream, Tom St Denis */ #ifdef LTC_OMAC /** Terminate an LTC_OMAC stream @param omac The LTC_OMAC state @param out [out] Destination for the authentication tag @param outlen [in/out] The max size and resulting size of the authentication tag @return CRYPT_OK if successful */ int omac_done(omac_state *omac, unsigned char *out, unsigned long *outlen) { int err, mode; unsigned x; LTC_ARGCHK(omac != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); if ((err = cipher_is_valid(omac->cipher_idx)) != CRYPT_OK) { return err; } if ((omac->buflen > (int)sizeof(omac->block)) || (omac->buflen < 0) || (omac->blklen > (int)sizeof(omac->block)) || (omac->buflen > omac->blklen)) { return CRYPT_INVALID_ARG; } /* figure out mode */ if (omac->buflen != omac->blklen) { /* add the 0x80 byte */ omac->block[omac->buflen++] = 0x80; /* pad with 0x00 */ while (omac->buflen < omac->blklen) { omac->block[omac->buflen++] = 0x00; } mode = 1; } else { mode = 0; } /* now xor prev + Lu[mode] */ for (x = 0; x < (unsigned)omac->blklen; x++) { omac->block[x] ^= omac->prev[x] ^ omac->Lu[mode][x]; } /* encrypt it */ if ((err = cipher_descriptor[omac->cipher_idx].ecb_encrypt(omac->block, omac->block, &omac->key)) != CRYPT_OK) { return err; } cipher_descriptor[omac->cipher_idx].done(&omac->key); /* output it */ for (x = 0; x < (unsigned)omac->blklen && x < *outlen; x++) { out[x] = omac->block[x]; } *outlen = x; #ifdef LTC_CLEAN_STACK zeromem(omac, sizeof(*omac)); #endif return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/omac/omac_done.c,v $ */ /* $Revision: 1.9 $ */ /* $Date: 2007/05/12 14:37:41 $ */ libtomcrypt-1.17/src/mac/omac/omac_file.c0000644000175100001440000000404210621351501017053 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file omac_file.c LTC_OMAC1 support, process a file, Tom St Denis */ #ifdef LTC_OMAC /** LTC_OMAC a file @param cipher The index of the cipher desired @param key The secret key @param keylen The length of the secret key (octets) @param filename The name of the file you wish to LTC_OMAC @param out [out] Where the authentication tag is to be stored @param outlen [in/out] The max size and resulting size of the authentication tag @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled */ int omac_file(int cipher, const unsigned char *key, unsigned long keylen, const char *filename, unsigned char *out, unsigned long *outlen) { #ifdef LTC_NO_FILE return CRYPT_NOP; #else int err, x; omac_state omac; FILE *in; unsigned char buf[512]; LTC_ARGCHK(key != NULL); LTC_ARGCHK(filename != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); in = fopen(filename, "rb"); if (in == NULL) { return CRYPT_FILE_NOTFOUND; } if ((err = omac_init(&omac, cipher, key, keylen)) != CRYPT_OK) { fclose(in); return err; } do { x = fread(buf, 1, sizeof(buf), in); if ((err = omac_process(&omac, buf, x)) != CRYPT_OK) { fclose(in); return err; } } while (x == sizeof(buf)); fclose(in); if ((err = omac_done(&omac, out, outlen)) != CRYPT_OK) { return err; } #ifdef LTC_CLEAN_STACK zeromem(buf, sizeof(buf)); #endif return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/omac/omac_file.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:37:41 $ */ libtomcrypt-1.17/src/mac/omac/omac_init.c0000644000175100001440000000532310621351501017102 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file omac_init.c LTC_OMAC1 support, initialize state, by Tom St Denis */ #ifdef LTC_OMAC /** Initialize an LTC_OMAC state @param omac The LTC_OMAC state to initialize @param cipher The index of the desired cipher @param key The secret key @param keylen The length of the secret key (octets) @return CRYPT_OK if successful */ int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned long keylen) { int err, x, y, mask, msb, len; LTC_ARGCHK(omac != NULL); LTC_ARGCHK(key != NULL); /* schedule the key */ if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { return err; } #ifdef LTC_FAST if (cipher_descriptor[cipher].block_length % sizeof(LTC_FAST_TYPE)) { return CRYPT_INVALID_ARG; } #endif /* now setup the system */ switch (cipher_descriptor[cipher].block_length) { case 8: mask = 0x1B; len = 8; break; case 16: mask = 0x87; len = 16; break; default: return CRYPT_INVALID_ARG; } if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &omac->key)) != CRYPT_OK) { return err; } /* ok now we need Lu and Lu^2 [calc one from the other] */ /* first calc L which is Ek(0) */ zeromem(omac->Lu[0], cipher_descriptor[cipher].block_length); if ((err = cipher_descriptor[cipher].ecb_encrypt(omac->Lu[0], omac->Lu[0], &omac->key)) != CRYPT_OK) { return err; } /* now do the mults, whoopy! */ for (x = 0; x < 2; x++) { /* if msb(L * u^(x+1)) = 0 then just shift, otherwise shift and xor constant mask */ msb = omac->Lu[x][0] >> 7; /* shift left */ for (y = 0; y < (len - 1); y++) { omac->Lu[x][y] = ((omac->Lu[x][y] << 1) | (omac->Lu[x][y+1] >> 7)) & 255; } omac->Lu[x][len - 1] = ((omac->Lu[x][len - 1] << 1) ^ (msb ? mask : 0)) & 255; /* copy up as require */ if (x == 0) { XMEMCPY(omac->Lu[1], omac->Lu[0], sizeof(omac->Lu[0])); } } /* setup state */ omac->cipher_idx = cipher; omac->buflen = 0; omac->blklen = len; zeromem(omac->prev, sizeof(omac->prev)); zeromem(omac->block, sizeof(omac->block)); return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/omac/omac_init.c,v $ */ /* $Revision: 1.12 $ */ /* $Date: 2007/05/12 14:37:41 $ */ libtomcrypt-1.17/src/mac/omac/omac_test.c0000644000175100001440000000674310621351501017125 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file omac_test.c LTC_OMAC1 support, self-test, by Tom St Denis */ #ifdef LTC_OMAC /** Test the LTC_OMAC setup @return CRYPT_OK if successful, CRYPT_NOP if tests have been disabled */ int omac_test(void) { #if !defined(LTC_TEST) return CRYPT_NOP; #else static const struct { int keylen, msglen; unsigned char key[16], msg[64], tag[16]; } tests[] = { { 16, 0, { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, { 0x00 }, { 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28, 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46 } }, { 16, 16, { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a }, { 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44, 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c } }, { 16, 40, { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11 }, { 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30, 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27 } }, { 16, 64, { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }, { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 }, { 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92, 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe } } }; unsigned char out[16]; int x, err, idx; unsigned long len; /* AES can be under rijndael or aes... try to find it */ if ((idx = find_cipher("aes")) == -1) { if ((idx = find_cipher("rijndael")) == -1) { return CRYPT_NOP; } } for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { len = sizeof(out); if ((err = omac_memory(idx, tests[x].key, tests[x].keylen, tests[x].msg, tests[x].msglen, out, &len)) != CRYPT_OK) { return err; } if (XMEMCMP(out, tests[x].tag, 16) != 0) { #if 0 int y; printf("\n\nTag: "); for (y = 0; y < 16; y++) printf("%02x", out[y]); printf("\n\n"); #endif return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/omac/omac_test.c,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2007/05/12 14:37:41 $ */ libtomcrypt-1.17/src/mac/omac/omac_memory_multi.c0000644000175100001440000000510010621351501020652 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" #include /** @file omac_memory_multi.c LTC_OMAC1 support, process multiple blocks of memory, Tom St Denis */ #ifdef LTC_OMAC /** LTC_OMAC multiple blocks of memory @param cipher The index of the desired cipher @param key The secret key @param keylen The length of the secret key (octets) @param out [out] The destination of the authentication tag @param outlen [in/out] The max size and resulting size of the authentication tag (octets) @param in The data to send through LTC_OMAC @param inlen The length of the data to send through LTC_OMAC (octets) @param ... tuples of (data,len) pairs to LTC_OMAC, terminated with a (NULL,x) (x=don't care) @return CRYPT_OK if successful */ int omac_memory_multi(int cipher, const unsigned char *key, unsigned long keylen, unsigned char *out, unsigned long *outlen, const unsigned char *in, unsigned long inlen, ...) { int err; omac_state *omac; va_list args; const unsigned char *curptr; unsigned long curlen; LTC_ARGCHK(key != NULL); LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* allocate ram for omac state */ omac = XMALLOC(sizeof(omac_state)); if (omac == NULL) { return CRYPT_MEM; } /* omac process the message */ if ((err = omac_init(omac, cipher, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } va_start(args, inlen); curptr = in; curlen = inlen; for (;;) { /* process buf */ if ((err = omac_process(omac, curptr, curlen)) != CRYPT_OK) { goto LBL_ERR; } /* step to next */ curptr = va_arg(args, const unsigned char*); if (curptr == NULL) { break; } curlen = va_arg(args, unsigned long); } if ((err = omac_done(omac, out, outlen)) != CRYPT_OK) { goto LBL_ERR; } LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(omac, sizeof(omac_state)); #endif XFREE(omac); va_end(args); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/omac/omac_memory_multi.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:37:41 $ */ libtomcrypt-1.17/src/mac/pmac/0000755000175100001440000000000010621351501014772 5ustar tomuserslibtomcrypt-1.17/src/mac/pmac/pmac_shift_xor.c0000644000175100001440000000214410621351501020144 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file pmac_shift_xor.c PMAC implementation, internal function, by Tom St Denis */ #ifdef LTC_PMAC /** Internal function. Performs the state update (adding correct multiple) @param pmac The PMAC state. */ void pmac_shift_xor(pmac_state *pmac) { int x, y; y = pmac_ntz(pmac->block_index++); #ifdef LTC_FAST for (x = 0; x < pmac->block_len; x += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE*)((unsigned char *)pmac->Li + x)) ^= *((LTC_FAST_TYPE*)((unsigned char *)pmac->Ls[y] + x)); } #else for (x = 0; x < pmac->block_len; x++) { pmac->Li[x] ^= pmac->Ls[y][x]; } #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_shift_xor.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/mac/pmac/pmac_test.c0000644000175100001440000001037310621351501017121 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file pmac_test.c PMAC implementation, self-test, by Tom St Denis */ #ifdef LTC_PMAC /** Test the LTC_OMAC implementation @return CRYPT_OK if successful, CRYPT_NOP if testing has been disabled */ int pmac_test(void) { #if !defined(LTC_TEST) return CRYPT_NOP; #else static const struct { int msglen; unsigned char key[16], msg[34], tag[16]; } tests[] = { /* PMAC-AES-128-0B */ { 0, /* key */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* msg */ { 0x00 }, /* tag */ { 0x43, 0x99, 0x57, 0x2c, 0xd6, 0xea, 0x53, 0x41, 0xb8, 0xd3, 0x58, 0x76, 0xa7, 0x09, 0x8a, 0xf7 } }, /* PMAC-AES-128-3B */ { 3, /* key */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* msg */ { 0x00, 0x01, 0x02 }, /* tag */ { 0x25, 0x6b, 0xa5, 0x19, 0x3c, 0x1b, 0x99, 0x1b, 0x4d, 0xf0, 0xc5, 0x1f, 0x38, 0x8a, 0x9e, 0x27 } }, /* PMAC-AES-128-16B */ { 16, /* key */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* msg */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* tag */ { 0xeb, 0xbd, 0x82, 0x2f, 0xa4, 0x58, 0xda, 0xf6, 0xdf, 0xda, 0xd7, 0xc2, 0x7d, 0xa7, 0x63, 0x38 } }, /* PMAC-AES-128-20B */ { 20, /* key */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* msg */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13 }, /* tag */ { 0x04, 0x12, 0xca, 0x15, 0x0b, 0xbf, 0x79, 0x05, 0x8d, 0x8c, 0x75, 0xa5, 0x8c, 0x99, 0x3f, 0x55 } }, /* PMAC-AES-128-32B */ { 32, /* key */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* msg */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, /* tag */ { 0xe9, 0x7a, 0xc0, 0x4e, 0x9e, 0x5e, 0x33, 0x99, 0xce, 0x53, 0x55, 0xcd, 0x74, 0x07, 0xbc, 0x75 } }, /* PMAC-AES-128-34B */ { 34, /* key */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* msg */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21 }, /* tag */ { 0x5c, 0xba, 0x7d, 0x5e, 0xb2, 0x4f, 0x7c, 0x86, 0xcc, 0xc5, 0x46, 0x04, 0xe5, 0x3d, 0x55, 0x12 } } }; int err, x, idx; unsigned long len; unsigned char outtag[MAXBLOCKSIZE]; /* AES can be under rijndael or aes... try to find it */ if ((idx = find_cipher("aes")) == -1) { if ((idx = find_cipher("rijndael")) == -1) { return CRYPT_NOP; } } for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { len = sizeof(outtag); if ((err = pmac_memory(idx, tests[x].key, 16, tests[x].msg, tests[x].msglen, outtag, &len)) != CRYPT_OK) { return err; } if (XMEMCMP(outtag, tests[x].tag, len)) { #if 0 unsigned long y; printf("\nTAG:\n"); for (y = 0; y < len; ) { printf("0x%02x", outtag[y]); if (y < len-1) printf(", "); if (!(++y % 8)) printf("\n"); } #endif return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif /* LTC_TEST */ } #endif /* PMAC_MODE */ /* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_test.c,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2007/05/12 14:37:41 $ */ libtomcrypt-1.17/src/mac/pmac/pmac_memory_multi.c0000644000175100001440000000502310621351501020660 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" #include /** @file pmac_memory_multi.c PMAC implementation, process multiple blocks of memory, by Tom St Denis */ #ifdef LTC_PMAC /** PMAC multiple blocks of memory @param cipher The index of the cipher desired @param key The secret key @param keylen The length of the secret key (octets) @param out [out] Destination for the authentication tag @param outlen [in/out] The max size and resulting size of the authentication tag @param in The data you wish to send through PMAC @param inlen The length of data you wish to send through PMAC (octets) @param ... tuples of (data,len) pairs to PMAC, terminated with a (NULL,x) (x=don't care) @return CRYPT_OK if successful */ int pmac_memory_multi(int cipher, const unsigned char *key, unsigned long keylen, unsigned char *out, unsigned long *outlen, const unsigned char *in, unsigned long inlen, ...) { int err; pmac_state *pmac; va_list args; const unsigned char *curptr; unsigned long curlen; LTC_ARGCHK(key != NULL); LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* allocate ram for pmac state */ pmac = XMALLOC(sizeof(pmac_state)); if (pmac == NULL) { return CRYPT_MEM; } if ((err = pmac_init(pmac, cipher, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } va_start(args, inlen); curptr = in; curlen = inlen; for (;;) { /* process buf */ if ((err = pmac_process(pmac, curptr, curlen)) != CRYPT_OK) { goto LBL_ERR; } /* step to next */ curptr = va_arg(args, const unsigned char*); if (curptr == NULL) { break; } curlen = va_arg(args, unsigned long); } if ((err = pmac_done(pmac, out, outlen)) != CRYPT_OK) { goto LBL_ERR; } LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(pmac, sizeof(pmac_state)); #endif XFREE(pmac); va_end(args); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_memory_multi.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/mac/pmac/pmac_ntz.c0000644000175100001440000000140710621351501016753 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file pmac_ntz.c PMAC implementation, internal function, by Tom St Denis */ #ifdef LTC_PMAC /** Internal PMAC function */ int pmac_ntz(unsigned long x) { int c; x &= 0xFFFFFFFFUL; c = 0; while ((x & 1) == 0) { ++c; x >>= 1; } return c; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_ntz.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/mac/pmac/pmac_memory.c0000644000175100001440000000373410621351501017455 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file pmac_memory.c PMAC implementation, process a block of memory, by Tom St Denis */ #ifdef LTC_PMAC /** PMAC a block of memory @param cipher The index of the cipher desired @param key The secret key @param keylen The length of the secret key (octets) @param in The data you wish to send through PMAC @param inlen The length of data you wish to send through PMAC (octets) @param out [out] Destination for the authentication tag @param outlen [in/out] The max size and resulting size of the authentication tag @return CRYPT_OK if successful */ int pmac_memory(int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { int err; pmac_state *pmac; LTC_ARGCHK(key != NULL); LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* allocate ram for pmac state */ pmac = XMALLOC(sizeof(pmac_state)); if (pmac == NULL) { return CRYPT_MEM; } if ((err = pmac_init(pmac, cipher, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } if ((err = pmac_process(pmac, in, inlen)) != CRYPT_OK) { goto LBL_ERR; } if ((err = pmac_done(pmac, out, outlen)) != CRYPT_OK) { goto LBL_ERR; } err = CRYPT_OK; LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(pmac, sizeof(pmac_state)); #endif XFREE(pmac); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_memory.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/mac/pmac/pmac_process.c0000644000175100001440000000556510621351501017627 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file pmac_process.c PMAC implementation, process data, by Tom St Denis */ #ifdef LTC_PMAC /** Process data in a PMAC stream @param pmac The PMAC state @param in The data to send through PMAC @param inlen The length of the data to send through PMAC @return CRYPT_OK if successful */ int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen) { int err, n; unsigned long x; unsigned char Z[MAXBLOCKSIZE]; LTC_ARGCHK(pmac != NULL); LTC_ARGCHK(in != NULL); if ((err = cipher_is_valid(pmac->cipher_idx)) != CRYPT_OK) { return err; } if ((pmac->buflen > (int)sizeof(pmac->block)) || (pmac->buflen < 0) || (pmac->block_len > (int)sizeof(pmac->block)) || (pmac->buflen > pmac->block_len)) { return CRYPT_INVALID_ARG; } #ifdef LTC_FAST if (pmac->buflen == 0 && inlen > 16) { unsigned long y; for (x = 0; x < (inlen - 16); x += 16) { pmac_shift_xor(pmac); for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE*)(&Z[y])) = *((LTC_FAST_TYPE*)(&in[y])) ^ *((LTC_FAST_TYPE*)(&pmac->Li[y])); } if ((err = cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key)) != CRYPT_OK) { return err; } for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE*)(&pmac->checksum[y])) ^= *((LTC_FAST_TYPE*)(&Z[y])); } in += 16; } inlen -= x; } #endif while (inlen != 0) { /* ok if the block is full we xor in prev, encrypt and replace prev */ if (pmac->buflen == pmac->block_len) { pmac_shift_xor(pmac); for (x = 0; x < (unsigned long)pmac->block_len; x++) { Z[x] = pmac->Li[x] ^ pmac->block[x]; } if ((err = cipher_descriptor[pmac->cipher_idx].ecb_encrypt(Z, Z, &pmac->key)) != CRYPT_OK) { return err; } for (x = 0; x < (unsigned long)pmac->block_len; x++) { pmac->checksum[x] ^= Z[x]; } pmac->buflen = 0; } /* add bytes */ n = MIN(inlen, (unsigned long)(pmac->block_len - pmac->buflen)); XMEMCPY(pmac->block + pmac->buflen, in, n); pmac->buflen += n; inlen -= n; in += n; } #ifdef LTC_CLEAN_STACK zeromem(Z, sizeof(Z)); #endif return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_process.c,v $ */ /* $Revision: 1.9 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/mac/pmac/pmac_done.c0000644000175100001440000000366710621351501017077 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file pmac_done.c PMAC implementation, terminate a session, by Tom St Denis */ #ifdef LTC_PMAC int pmac_done(pmac_state *state, unsigned char *out, unsigned long *outlen) { int err, x; LTC_ARGCHK(state != NULL); LTC_ARGCHK(out != NULL); if ((err = cipher_is_valid(state->cipher_idx)) != CRYPT_OK) { return err; } if ((state->buflen > (int)sizeof(state->block)) || (state->buflen < 0) || (state->block_len > (int)sizeof(state->block)) || (state->buflen > state->block_len)) { return CRYPT_INVALID_ARG; } /* handle padding. If multiple xor in L/x */ if (state->buflen == state->block_len) { /* xor Lr against the checksum */ for (x = 0; x < state->block_len; x++) { state->checksum[x] ^= state->block[x] ^ state->Lr[x]; } } else { /* otherwise xor message bytes then the 0x80 byte */ for (x = 0; x < state->buflen; x++) { state->checksum[x] ^= state->block[x]; } state->checksum[x] ^= 0x80; } /* encrypt it */ if ((err = cipher_descriptor[state->cipher_idx].ecb_encrypt(state->checksum, state->checksum, &state->key)) != CRYPT_OK) { return err; } cipher_descriptor[state->cipher_idx].done(&state->key); /* store it */ for (x = 0; x < state->block_len && x < (int)*outlen; x++) { out[x] = state->checksum[x]; } *outlen = x; #ifdef LTC_CLEAN_STACK zeromem(state, sizeof(*state)); #endif return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_done.c,v $ */ /* $Revision: 1.9 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/mac/pmac/pmac_file.c0000644000175100001440000000406610621351501017063 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file pmac_file.c PMAC implementation, process a file, by Tom St Denis */ #ifdef LTC_PMAC /** PMAC a file @param cipher The index of the cipher desired @param key The secret key @param keylen The length of the secret key (octets) @param filename The name of the file to send through PMAC @param out [out] Destination for the authentication tag @param outlen [in/out] Max size and resulting size of the authentication tag @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled */ int pmac_file(int cipher, const unsigned char *key, unsigned long keylen, const char *filename, unsigned char *out, unsigned long *outlen) { #ifdef LTC_NO_FILE return CRYPT_NOP; #else int err, x; pmac_state pmac; FILE *in; unsigned char buf[512]; LTC_ARGCHK(key != NULL); LTC_ARGCHK(filename != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); in = fopen(filename, "rb"); if (in == NULL) { return CRYPT_FILE_NOTFOUND; } if ((err = pmac_init(&pmac, cipher, key, keylen)) != CRYPT_OK) { fclose(in); return err; } do { x = fread(buf, 1, sizeof(buf), in); if ((err = pmac_process(&pmac, buf, x)) != CRYPT_OK) { fclose(in); return err; } } while (x == sizeof(buf)); fclose(in); if ((err = pmac_done(&pmac, out, outlen)) != CRYPT_OK) { return err; } #ifdef LTC_CLEAN_STACK zeromem(buf, sizeof(buf)); #endif return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_file.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/mac/pmac/pmac_init.c0000644000175100001440000000736510621351501017114 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file pmac_init.c PMAC implementation, initialize state, by Tom St Denis */ #ifdef LTC_PMAC static const struct { int len; unsigned char poly_div[MAXBLOCKSIZE], poly_mul[MAXBLOCKSIZE]; } polys[] = { { 8, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B } }, { 16, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 } } }; /** Initialize a PMAC state @param pmac The PMAC state to initialize @param cipher The index of the desired cipher @param key The secret key @param keylen The length of the secret key (octets) @return CRYPT_OK if successful */ int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned long keylen) { int poly, x, y, m, err; unsigned char *L; LTC_ARGCHK(pmac != NULL); LTC_ARGCHK(key != NULL); /* valid cipher? */ if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { return err; } /* determine which polys to use */ pmac->block_len = cipher_descriptor[cipher].block_length; for (poly = 0; poly < (int)(sizeof(polys)/sizeof(polys[0])); poly++) { if (polys[poly].len == pmac->block_len) { break; } } if (polys[poly].len != pmac->block_len) { return CRYPT_INVALID_ARG; } #ifdef LTC_FAST if (pmac->block_len % sizeof(LTC_FAST_TYPE)) { return CRYPT_INVALID_ARG; } #endif /* schedule the key */ if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &pmac->key)) != CRYPT_OK) { return err; } /* allocate L */ L = XMALLOC(pmac->block_len); if (L == NULL) { return CRYPT_MEM; } /* find L = E[0] */ zeromem(L, pmac->block_len); if ((err = cipher_descriptor[cipher].ecb_encrypt(L, L, &pmac->key)) != CRYPT_OK) { goto error; } /* find Ls[i] = L << i for i == 0..31 */ XMEMCPY(pmac->Ls[0], L, pmac->block_len); for (x = 1; x < 32; x++) { m = pmac->Ls[x-1][0] >> 7; for (y = 0; y < pmac->block_len-1; y++) { pmac->Ls[x][y] = ((pmac->Ls[x-1][y] << 1) | (pmac->Ls[x-1][y+1] >> 7)) & 255; } pmac->Ls[x][pmac->block_len-1] = (pmac->Ls[x-1][pmac->block_len-1] << 1) & 255; if (m == 1) { for (y = 0; y < pmac->block_len; y++) { pmac->Ls[x][y] ^= polys[poly].poly_mul[y]; } } } /* find Lr = L / x */ m = L[pmac->block_len-1] & 1; /* shift right */ for (x = pmac->block_len - 1; x > 0; x--) { pmac->Lr[x] = ((L[x] >> 1) | (L[x-1] << 7)) & 255; } pmac->Lr[0] = L[0] >> 1; if (m == 1) { for (x = 0; x < pmac->block_len; x++) { pmac->Lr[x] ^= polys[poly].poly_div[x]; } } /* zero buffer, counters, etc... */ pmac->block_index = 1; pmac->cipher_idx = cipher; pmac->buflen = 0; zeromem(pmac->block, sizeof(pmac->block)); zeromem(pmac->Li, sizeof(pmac->Li)); zeromem(pmac->checksum, sizeof(pmac->checksum)); err = CRYPT_OK; error: #ifdef LTC_CLEAN_STACK zeromem(L, pmac->block_len); #endif XFREE(L); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/pmac/pmac_init.c,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/mac/xcbc/0000755000175100001440000000000010621351501014771 5ustar tomuserslibtomcrypt-1.17/src/mac/xcbc/xcbc_memory.c0000644000175100001440000000351510621351501017450 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file xcbc_process.c XCBC Support, XCBC-MAC a block of memory */ #ifdef LTC_XCBC /** XCBC-MAC a block of memory @param cipher Index of cipher to use @param key [in] Secret key @param keylen Length of key in octets @param in [in] Message to MAC @param inlen Length of input in octets @param out [out] Destination for the MAC tag @param outlen [in/out] Output size and final tag size Return CRYPT_OK on success. */ int xcbc_memory(int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { xcbc_state *xcbc; int err; /* is the cipher valid? */ if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { return err; } /* Use accelerator if found */ if (cipher_descriptor[cipher].xcbc_memory != NULL) { return cipher_descriptor[cipher].xcbc_memory(key, keylen, in, inlen, out, outlen); } xcbc = XCALLOC(1, sizeof(*xcbc)); if (xcbc == NULL) { return CRYPT_MEM; } if ((err = xcbc_init(xcbc, cipher, key, keylen)) != CRYPT_OK) { goto done; } if ((err = xcbc_process(xcbc, in, inlen)) != CRYPT_OK) { goto done; } err = xcbc_done(xcbc, out, outlen); done: XFREE(xcbc); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/xcbc/xcbc_memory.c,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/mac/xcbc/xcbc_test.c0000644000175100001440000000613010621351501017113 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file xcbc_test.c XCBC Support, Test XCBC-MAC mode */ #ifdef LTC_XCBC /** Test XCBC-MAC mode Return CRYPT_OK on succes */ int xcbc_test(void) { #ifdef LTC_NO_TEST return CRYPT_NOP; #else static const struct { int msglen; unsigned char K[16], M[34], T[16]; } tests[] = { { 0, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, { 0 }, { 0x75, 0xf0, 0x25, 0x1d, 0x52, 0x8a, 0xc0, 0x1c, 0x45, 0x73, 0xdf, 0xd5, 0x84, 0xd7, 0x9f, 0x29 } }, { 3, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, { 0x00, 0x01, 0x02 }, { 0x5b, 0x37, 0x65, 0x80, 0xae, 0x2f, 0x19, 0xaf, 0xe7, 0x21, 0x9c, 0xee, 0xf1, 0x72, 0x75, 0x6f } }, { 16, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, { 0xd2, 0xa2, 0x46, 0xfa, 0x34, 0x9b, 0x68, 0xa7, 0x99, 0x98, 0xa4, 0x39, 0x4f, 0xf7, 0xa2, 0x63 } }, { 32, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, { 0xf5, 0x4f, 0x0e, 0xc8, 0xd2, 0xb9, 0xf3, 0xd3, 0x68, 0x07, 0x73, 0x4b, 0xd5, 0x28, 0x3f, 0xd4 } }, { 34, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21 }, { 0xbe, 0xcb, 0xb3, 0xbc, 0xcd, 0xb5, 0x18, 0xa3, 0x06, 0x77, 0xd5, 0x48, 0x1f, 0xb6, 0xb4, 0xd8 }, }, }; unsigned char T[16]; unsigned long taglen; int err, x, idx; /* AES can be under rijndael or aes... try to find it */ if ((idx = find_cipher("aes")) == -1) { if ((idx = find_cipher("rijndael")) == -1) { return CRYPT_NOP; } } for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { taglen = 16; if ((err = xcbc_memory(idx, tests[x].K, 16, tests[x].M, tests[x].msglen, T, &taglen)) != CRYPT_OK) { return err; } if (taglen != 16 || XMEMCMP(T, tests[x].T, 16)) { return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/xcbc/xcbc_test.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/mac/xcbc/xcbc_memory_multi.c0000644000175100001440000000505310621351501020661 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" #include /** @file xcbc_memory_multi.c XCBC support, process multiple blocks of memory, Tom St Denis */ #ifdef LTC_XCBC /** XCBC multiple blocks of memory @param cipher The index of the desired cipher @param key The secret key @param keylen The length of the secret key (octets) @param out [out] The destination of the authentication tag @param outlen [in/out] The max size and resulting size of the authentication tag (octets) @param in The data to send through XCBC @param inlen The length of the data to send through XCBC (octets) @param ... tuples of (data,len) pairs to XCBC, terminated with a (NULL,x) (x=don't care) @return CRYPT_OK if successful */ int xcbc_memory_multi(int cipher, const unsigned char *key, unsigned long keylen, unsigned char *out, unsigned long *outlen, const unsigned char *in, unsigned long inlen, ...) { int err; xcbc_state *xcbc; va_list args; const unsigned char *curptr; unsigned long curlen; LTC_ARGCHK(key != NULL); LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* allocate ram for xcbc state */ xcbc = XMALLOC(sizeof(xcbc_state)); if (xcbc == NULL) { return CRYPT_MEM; } /* xcbc process the message */ if ((err = xcbc_init(xcbc, cipher, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } va_start(args, inlen); curptr = in; curlen = inlen; for (;;) { /* process buf */ if ((err = xcbc_process(xcbc, curptr, curlen)) != CRYPT_OK) { goto LBL_ERR; } /* step to next */ curptr = va_arg(args, const unsigned char*); if (curptr == NULL) { break; } curlen = va_arg(args, unsigned long); } if ((err = xcbc_done(xcbc, out, outlen)) != CRYPT_OK) { goto LBL_ERR; } LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(xcbc, sizeof(xcbc_state)); #endif XFREE(xcbc); va_end(args); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/xcbc/xcbc_memory_multi.c,v $ */ /* $Revision: 1.2 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/mac/xcbc/xcbc_process.c0000644000175100001440000000371010621351501017613 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file xcbc_process.c XCBC Support, process blocks with XCBC */ #ifdef LTC_XCBC /** Process data through XCBC-MAC @param xcbc The XCBC-MAC state @param in Input data to process @param inlen Length of input in octets Return CRYPT_OK on success */ int xcbc_process(xcbc_state *xcbc, const unsigned char *in, unsigned long inlen) { int err; #ifdef LTC_FAST int x; #endif LTC_ARGCHK(xcbc != NULL); LTC_ARGCHK(in != NULL); /* check structure */ if ((err = cipher_is_valid(xcbc->cipher)) != CRYPT_OK) { return err; } if ((xcbc->blocksize > cipher_descriptor[xcbc->cipher].block_length) || (xcbc->blocksize < 0) || (xcbc->buflen > xcbc->blocksize) || (xcbc->buflen < 0)) { return CRYPT_INVALID_ARG; } #ifdef LTC_FAST if (xcbc->buflen == 0) { while (inlen > (unsigned long)xcbc->blocksize) { for (x = 0; x < xcbc->blocksize; x += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE*)&(xcbc->IV[x])) ^= *((LTC_FAST_TYPE*)&(in[x])); } cipher_descriptor[xcbc->cipher].ecb_encrypt(xcbc->IV, xcbc->IV, &xcbc->key); in += xcbc->blocksize; inlen -= xcbc->blocksize; } } #endif while (inlen) { if (xcbc->buflen == xcbc->blocksize) { cipher_descriptor[xcbc->cipher].ecb_encrypt(xcbc->IV, xcbc->IV, &xcbc->key); xcbc->buflen = 0; } xcbc->IV[xcbc->buflen++] ^= *in++; --inlen; } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/xcbc/xcbc_process.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/mac/xcbc/xcbc_done.c0000644000175100001440000000370110621351501017062 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file xcbc_done.c XCBC Support, terminate the state */ #ifdef LTC_XCBC /** Terminate the XCBC-MAC state @param xcbc XCBC state to terminate @param out [out] Destination for the MAC tag @param outlen [in/out] Destination size and final tag size Return CRYPT_OK on success */ int xcbc_done(xcbc_state *xcbc, unsigned char *out, unsigned long *outlen) { int err, x; LTC_ARGCHK(xcbc != NULL); LTC_ARGCHK(out != NULL); /* check structure */ if ((err = cipher_is_valid(xcbc->cipher)) != CRYPT_OK) { return err; } if ((xcbc->blocksize > cipher_descriptor[xcbc->cipher].block_length) || (xcbc->blocksize < 0) || (xcbc->buflen > xcbc->blocksize) || (xcbc->buflen < 0)) { return CRYPT_INVALID_ARG; } /* which key do we use? */ if (xcbc->buflen == xcbc->blocksize) { /* k2 */ for (x = 0; x < xcbc->blocksize; x++) { xcbc->IV[x] ^= xcbc->K[1][x]; } } else { xcbc->IV[xcbc->buflen] ^= 0x80; /* k3 */ for (x = 0; x < xcbc->blocksize; x++) { xcbc->IV[x] ^= xcbc->K[2][x]; } } /* encrypt */ cipher_descriptor[xcbc->cipher].ecb_encrypt(xcbc->IV, xcbc->IV, &xcbc->key); cipher_descriptor[xcbc->cipher].done(&xcbc->key); /* extract tag */ for (x = 0; x < xcbc->blocksize && (unsigned long)x < *outlen; x++) { out[x] = xcbc->IV[x]; } *outlen = x; #ifdef LTC_CLEAN_STACK zeromem(xcbc, sizeof(*xcbc)); #endif return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/xcbc/xcbc_done.c,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/mac/xcbc/xcbc_file.c0000644000175100001440000000402510621351501017054 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file xcbc_file.c XCBC support, process a file, Tom St Denis */ #ifdef LTC_XCBC /** XCBC a file @param cipher The index of the cipher desired @param key The secret key @param keylen The length of the secret key (octets) @param filename The name of the file you wish to XCBC @param out [out] Where the authentication tag is to be stored @param outlen [in/out] The max size and resulting size of the authentication tag @return CRYPT_OK if successful, CRYPT_NOP if file support has been disabled */ int xcbc_file(int cipher, const unsigned char *key, unsigned long keylen, const char *filename, unsigned char *out, unsigned long *outlen) { #ifdef LTC_NO_FILE return CRYPT_NOP; #else int err, x; xcbc_state xcbc; FILE *in; unsigned char buf[512]; LTC_ARGCHK(key != NULL); LTC_ARGCHK(filename != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); in = fopen(filename, "rb"); if (in == NULL) { return CRYPT_FILE_NOTFOUND; } if ((err = xcbc_init(&xcbc, cipher, key, keylen)) != CRYPT_OK) { fclose(in); return err; } do { x = fread(buf, 1, sizeof(buf), in); if ((err = xcbc_process(&xcbc, buf, x)) != CRYPT_OK) { fclose(in); return err; } } while (x == sizeof(buf)); fclose(in); if ((err = xcbc_done(&xcbc, out, outlen)) != CRYPT_OK) { return err; } #ifdef LTC_CLEAN_STACK zeromem(buf, sizeof(buf)); #endif return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/xcbc/xcbc_file.c,v $ */ /* $Revision: 1.2 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/mac/xcbc/xcbc_init.c0000644000175100001440000000554110621351501017104 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file xcbc_init.c XCBC Support, start an XCBC state */ #ifdef LTC_XCBC /** Initialize XCBC-MAC state @param xcbc [out] XCBC state to initialize @param cipher Index of cipher to use @param key [in] Secret key @param keylen Length of secret key in octets Return CRYPT_OK on success */ int xcbc_init(xcbc_state *xcbc, int cipher, const unsigned char *key, unsigned long keylen) { int x, y, err; symmetric_key *skey; unsigned long k1; LTC_ARGCHK(xcbc != NULL); LTC_ARGCHK(key != NULL); /* schedule the key */ if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { return err; } #ifdef LTC_FAST if (cipher_descriptor[cipher].block_length % sizeof(LTC_FAST_TYPE)) { return CRYPT_INVALID_ARG; } #endif skey = NULL; /* are we in pure XCBC mode with three keys? */ if (keylen & LTC_XCBC_PURE) { keylen &= ~LTC_XCBC_PURE; if (keylen < 2UL*cipher_descriptor[cipher].block_length) { return CRYPT_INVALID_ARG; } k1 = keylen - 2*cipher_descriptor[cipher].block_length; XMEMCPY(xcbc->K[0], key, k1); XMEMCPY(xcbc->K[1], key+k1, cipher_descriptor[cipher].block_length); XMEMCPY(xcbc->K[2], key+k1 + cipher_descriptor[cipher].block_length, cipher_descriptor[cipher].block_length); } else { /* use the key expansion */ k1 = cipher_descriptor[cipher].block_length; /* schedule the user key */ skey = XCALLOC(1, sizeof(*skey)); if (skey == NULL) { return CRYPT_MEM; } if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, skey)) != CRYPT_OK) { goto done; } /* make the three keys */ for (y = 0; y < 3; y++) { for (x = 0; x < cipher_descriptor[cipher].block_length; x++) { xcbc->K[y][x] = y + 1; } cipher_descriptor[cipher].ecb_encrypt(xcbc->K[y], xcbc->K[y], skey); } } /* setup K1 */ err = cipher_descriptor[cipher].setup(xcbc->K[0], k1, 0, &xcbc->key); /* setup struct */ zeromem(xcbc->IV, cipher_descriptor[cipher].block_length); xcbc->blocksize = cipher_descriptor[cipher].block_length; xcbc->cipher = cipher; xcbc->buflen = 0; done: cipher_descriptor[cipher].done(skey); if (skey != NULL) { #ifdef LTC_CLEAN_STACK zeromem(skey, sizeof(*skey)); #endif XFREE(skey); } return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/xcbc/xcbc_init.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/02/20 13:07:58 $ */ libtomcrypt-1.17/src/mac/pelican/0000755000175100001440000000000010621351501015465 5ustar tomuserslibtomcrypt-1.17/src/mac/pelican/pelican_memory.c0000644000175100001440000000266410621351501020644 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file pelican_memory.c Pelican MAC, MAC a block of memory, by Tom St Denis */ #ifdef LTC_PELICAN /** Pelican block of memory @param key The key for the MAC @param keylen The length of the key (octets) @param in The input to MAC @param inlen The length of the input (octets) @param out [out] The output TAG @return CRYPT_OK on success */ int pelican_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out) { pelican_state *pel; int err; pel = XMALLOC(sizeof(*pel)); if (pel == NULL) { return CRYPT_MEM; } if ((err = pelican_init(pel, key, keylen)) != CRYPT_OK) { XFREE(pel); return err; } if ((err = pelican_process(pel, in ,inlen)) != CRYPT_OK) { XFREE(pel); return err; } err = pelican_done(pel, out); XFREE(pel); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/pelican/pelican_memory.c,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/mac/pelican/pelican_test.c0000644000175100001440000000650510621351501020311 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file pelican_test.c Pelican MAC, test, by Tom St Denis */ #ifdef LTC_PELICAN int pelican_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { unsigned char K[32], MSG[64], T[16]; int keylen, ptlen; } tests[] = { /* K=16, M=0 */ { { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, { 0 }, { 0xeb, 0x58, 0x37, 0x15, 0xf8, 0x34, 0xde, 0xe5, 0xa4, 0xd1, 0x6e, 0xe4, 0xb9, 0xd7, 0x76, 0x0e, }, 16, 0 }, /* K=16, M=3 */ { { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, { 0x00, 0x01, 0x02 }, { 0x1c, 0x97, 0x40, 0x60, 0x6c, 0x58, 0x17, 0x2d, 0x03, 0x94, 0x19, 0x70, 0x81, 0xc4, 0x38, 0x54, }, 16, 3 }, /* K=16, M=16 */ { { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, { 0x03, 0xcc, 0x46, 0xb8, 0xac, 0xa7, 0x9c, 0x36, 0x1e, 0x8c, 0x6e, 0xa6, 0x7b, 0x89, 0x32, 0x49, }, 16, 16 }, /* K=16, M=32 */ { { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, { 0x89, 0xcc, 0x36, 0x58, 0x1b, 0xdd, 0x4d, 0xb5, 0x78, 0xbb, 0xac, 0xf0, 0xff, 0x8b, 0x08, 0x15, }, 16, 32 }, /* K=16, M=35 */ { { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x23 }, { 0x4a, 0x7d, 0x45, 0x4d, 0xcd, 0xb5, 0xda, 0x8d, 0x48, 0x78, 0x16, 0x48, 0x5d, 0x45, 0x95, 0x99, }, 16, 35 }, }; int x, err; unsigned char out[16]; pelican_state pel; for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { if ((err = pelican_init(&pel, tests[x].K, tests[x].keylen)) != CRYPT_OK) { return err; } if ((err = pelican_process(&pel, tests[x].MSG, tests[x].ptlen)) != CRYPT_OK) { return err; } if ((err = pelican_done(&pel, out)) != CRYPT_OK) { return err; } if (XMEMCMP(out, tests[x].T, 16)) { #if 0 int y; printf("\nFailed test %d\n", x); printf("{ "); for (y = 0; y < 16; ) { printf("0x%02x, ", out[y]); if (!(++y & 7)) printf("\n"); } printf(" }\n"); #endif return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/pelican/pelican_test.c,v $ */ /* $Revision: 1.14 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/mac/pelican/pelican.c0000644000175100001440000001004010621351501017237 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file pelican.c Pelican MAC, initialize state, by Tom St Denis */ #ifdef LTC_PELICAN #define ENCRYPT_ONLY #define PELI_TAB #include "../../ciphers/aes/aes_tab.c" /** Initialize a Pelican state @param pelmac The Pelican state to initialize @param key The secret key @param keylen The length of the secret key (octets) @return CRYPT_OK if successful */ int pelican_init(pelican_state *pelmac, const unsigned char *key, unsigned long keylen) { int err; LTC_ARGCHK(pelmac != NULL); LTC_ARGCHK(key != NULL); #ifdef LTC_FAST if (16 % sizeof(LTC_FAST_TYPE)) { return CRYPT_INVALID_ARG; } #endif if ((err = aes_setup(key, keylen, 0, &pelmac->K)) != CRYPT_OK) { return err; } zeromem(pelmac->state, 16); aes_ecb_encrypt(pelmac->state, pelmac->state, &pelmac->K); pelmac->buflen = 0; return CRYPT_OK; } static void four_rounds(pelican_state *pelmac) { ulong32 s0, s1, s2, s3, t0, t1, t2, t3; int r; LOAD32H(s0, pelmac->state ); LOAD32H(s1, pelmac->state + 4); LOAD32H(s2, pelmac->state + 8); LOAD32H(s3, pelmac->state + 12); for (r = 0; r < 4; r++) { t0 = Te0(byte(s0, 3)) ^ Te1(byte(s1, 2)) ^ Te2(byte(s2, 1)) ^ Te3(byte(s3, 0)); t1 = Te0(byte(s1, 3)) ^ Te1(byte(s2, 2)) ^ Te2(byte(s3, 1)) ^ Te3(byte(s0, 0)); t2 = Te0(byte(s2, 3)) ^ Te1(byte(s3, 2)) ^ Te2(byte(s0, 1)) ^ Te3(byte(s1, 0)); t3 = Te0(byte(s3, 3)) ^ Te1(byte(s0, 2)) ^ Te2(byte(s1, 1)) ^ Te3(byte(s2, 0)); s0 = t0; s1 = t1; s2 = t2; s3 = t3; } STORE32H(s0, pelmac->state ); STORE32H(s1, pelmac->state + 4); STORE32H(s2, pelmac->state + 8); STORE32H(s3, pelmac->state + 12); } /** Process a block of text through Pelican @param pelmac The Pelican MAC state @param in The input @param inlen The length input (octets) @return CRYPT_OK on success */ int pelican_process(pelican_state *pelmac, const unsigned char *in, unsigned long inlen) { LTC_ARGCHK(pelmac != NULL); LTC_ARGCHK(in != NULL); /* check range */ if (pelmac->buflen < 0 || pelmac->buflen > 15) { return CRYPT_INVALID_ARG; } #ifdef LTC_FAST if (pelmac->buflen == 0) { while (inlen & ~15) { int x; for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE*)((unsigned char *)pelmac->state + x)) ^= *((LTC_FAST_TYPE*)((unsigned char *)in + x)); } four_rounds(pelmac); in += 16; inlen -= 16; } } #endif while (inlen--) { pelmac->state[pelmac->buflen++] ^= *in++; if (pelmac->buflen == 16) { four_rounds(pelmac); pelmac->buflen = 0; } } return CRYPT_OK; } /** Terminate Pelican MAC @param pelmac The Pelican MAC state @param out [out] The TAG @return CRYPT_OK on sucess */ int pelican_done(pelican_state *pelmac, unsigned char *out) { LTC_ARGCHK(pelmac != NULL); LTC_ARGCHK(out != NULL); /* check range */ if (pelmac->buflen < 0 || pelmac->buflen > 16) { return CRYPT_INVALID_ARG; } if (pelmac->buflen == 16) { four_rounds(pelmac); pelmac->buflen = 0; } pelmac->state[pelmac->buflen++] ^= 0x80; aes_ecb_encrypt(pelmac->state, out, &pelmac->K); aes_done(&pelmac->K); return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/mac/pelican/pelican.c,v $ */ /* $Revision: 1.20 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/math/0000755000175100001440000000000010621351501014243 5ustar tomuserslibtomcrypt-1.17/src/math/fp/0000755000175100001440000000000010621351501014650 5ustar tomuserslibtomcrypt-1.17/src/math/fp/ltc_ecc_fp_mulmod.c0000644000175100001440000032117510621351501020463 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file ltc_ecc_fp_mulmod.c ECC Crypto, Tom St Denis */ #if defined(LTC_MECC) && defined(LTC_MECC_FP) #include /* number of entries in the cache */ #ifndef FP_ENTRIES #define FP_ENTRIES 16 #endif /* number of bits in LUT */ #ifndef FP_LUT #define FP_LUT 8U #endif #if (FP_LUT > 12) || (FP_LUT < 2) #error FP_LUT must be between 2 and 12 inclusively #endif /** Our FP cache */ static struct { ecc_point *g, /* cached COPY of base point */ *LUT[1U< 6 { 1, 0, 0 }, { 2, 1, 64 }, { 2, 2, 64 }, { 3, 3, 64 }, { 2, 4, 64 }, { 3, 5, 64 }, { 3, 6, 64 }, { 4, 7, 64 }, { 2, 8, 64 }, { 3, 9, 64 }, { 3, 10, 64 }, { 4, 11, 64 }, { 3, 12, 64 }, { 4, 13, 64 }, { 4, 14, 64 }, { 5, 15, 64 }, { 2, 16, 64 }, { 3, 17, 64 }, { 3, 18, 64 }, { 4, 19, 64 }, { 3, 20, 64 }, { 4, 21, 64 }, { 4, 22, 64 }, { 5, 23, 64 }, { 3, 24, 64 }, { 4, 25, 64 }, { 4, 26, 64 }, { 5, 27, 64 }, { 4, 28, 64 }, { 5, 29, 64 }, { 5, 30, 64 }, { 6, 31, 64 }, { 2, 32, 64 }, { 3, 33, 64 }, { 3, 34, 64 }, { 4, 35, 64 }, { 3, 36, 64 }, { 4, 37, 64 }, { 4, 38, 64 }, { 5, 39, 64 }, { 3, 40, 64 }, { 4, 41, 64 }, { 4, 42, 64 }, { 5, 43, 64 }, { 4, 44, 64 }, { 5, 45, 64 }, { 5, 46, 64 }, { 6, 47, 64 }, { 3, 48, 64 }, { 4, 49, 64 }, { 4, 50, 64 }, { 5, 51, 64 }, { 4, 52, 64 }, { 5, 53, 64 }, { 5, 54, 64 }, { 6, 55, 64 }, { 4, 56, 64 }, { 5, 57, 64 }, { 5, 58, 64 }, { 6, 59, 64 }, { 5, 60, 64 }, { 6, 61, 64 }, { 6, 62, 64 }, { 7, 63, 64 }, #if FP_LUT > 7 { 1, 0, 0 }, { 2, 1, 128 }, { 2, 2, 128 }, { 3, 3, 128 }, { 2, 4, 128 }, { 3, 5, 128 }, { 3, 6, 128 }, { 4, 7, 128 }, { 2, 8, 128 }, { 3, 9, 128 }, { 3, 10, 128 }, { 4, 11, 128 }, { 3, 12, 128 }, { 4, 13, 128 }, { 4, 14, 128 }, { 5, 15, 128 }, { 2, 16, 128 }, { 3, 17, 128 }, { 3, 18, 128 }, { 4, 19, 128 }, { 3, 20, 128 }, { 4, 21, 128 }, { 4, 22, 128 }, { 5, 23, 128 }, { 3, 24, 128 }, { 4, 25, 128 }, { 4, 26, 128 }, { 5, 27, 128 }, { 4, 28, 128 }, { 5, 29, 128 }, { 5, 30, 128 }, { 6, 31, 128 }, { 2, 32, 128 }, { 3, 33, 128 }, { 3, 34, 128 }, { 4, 35, 128 }, { 3, 36, 128 }, { 4, 37, 128 }, { 4, 38, 128 }, { 5, 39, 128 }, { 3, 40, 128 }, { 4, 41, 128 }, { 4, 42, 128 }, { 5, 43, 128 }, { 4, 44, 128 }, { 5, 45, 128 }, { 5, 46, 128 }, { 6, 47, 128 }, { 3, 48, 128 }, { 4, 49, 128 }, { 4, 50, 128 }, { 5, 51, 128 }, { 4, 52, 128 }, { 5, 53, 128 }, { 5, 54, 128 }, { 6, 55, 128 }, { 4, 56, 128 }, { 5, 57, 128 }, { 5, 58, 128 }, { 6, 59, 128 }, { 5, 60, 128 }, { 6, 61, 128 }, { 6, 62, 128 }, { 7, 63, 128 }, { 2, 64, 128 }, { 3, 65, 128 }, { 3, 66, 128 }, { 4, 67, 128 }, { 3, 68, 128 }, { 4, 69, 128 }, { 4, 70, 128 }, { 5, 71, 128 }, { 3, 72, 128 }, { 4, 73, 128 }, { 4, 74, 128 }, { 5, 75, 128 }, { 4, 76, 128 }, { 5, 77, 128 }, { 5, 78, 128 }, { 6, 79, 128 }, { 3, 80, 128 }, { 4, 81, 128 }, { 4, 82, 128 }, { 5, 83, 128 }, { 4, 84, 128 }, { 5, 85, 128 }, { 5, 86, 128 }, { 6, 87, 128 }, { 4, 88, 128 }, { 5, 89, 128 }, { 5, 90, 128 }, { 6, 91, 128 }, { 5, 92, 128 }, { 6, 93, 128 }, { 6, 94, 128 }, { 7, 95, 128 }, { 3, 96, 128 }, { 4, 97, 128 }, { 4, 98, 128 }, { 5, 99, 128 }, { 4, 100, 128 }, { 5, 101, 128 }, { 5, 102, 128 }, { 6, 103, 128 }, { 4, 104, 128 }, { 5, 105, 128 }, { 5, 106, 128 }, { 6, 107, 128 }, { 5, 108, 128 }, { 6, 109, 128 }, { 6, 110, 128 }, { 7, 111, 128 }, { 4, 112, 128 }, { 5, 113, 128 }, { 5, 114, 128 }, { 6, 115, 128 }, { 5, 116, 128 }, { 6, 117, 128 }, { 6, 118, 128 }, { 7, 119, 128 }, { 5, 120, 128 }, { 6, 121, 128 }, { 6, 122, 128 }, { 7, 123, 128 }, { 6, 124, 128 }, { 7, 125, 128 }, { 7, 126, 128 }, { 8, 127, 128 }, #if FP_LUT > 8 { 1, 0, 0 }, { 2, 1, 256 }, { 2, 2, 256 }, { 3, 3, 256 }, { 2, 4, 256 }, { 3, 5, 256 }, { 3, 6, 256 }, { 4, 7, 256 }, { 2, 8, 256 }, { 3, 9, 256 }, { 3, 10, 256 }, { 4, 11, 256 }, { 3, 12, 256 }, { 4, 13, 256 }, { 4, 14, 256 }, { 5, 15, 256 }, { 2, 16, 256 }, { 3, 17, 256 }, { 3, 18, 256 }, { 4, 19, 256 }, { 3, 20, 256 }, { 4, 21, 256 }, { 4, 22, 256 }, { 5, 23, 256 }, { 3, 24, 256 }, { 4, 25, 256 }, { 4, 26, 256 }, { 5, 27, 256 }, { 4, 28, 256 }, { 5, 29, 256 }, { 5, 30, 256 }, { 6, 31, 256 }, { 2, 32, 256 }, { 3, 33, 256 }, { 3, 34, 256 }, { 4, 35, 256 }, { 3, 36, 256 }, { 4, 37, 256 }, { 4, 38, 256 }, { 5, 39, 256 }, { 3, 40, 256 }, { 4, 41, 256 }, { 4, 42, 256 }, { 5, 43, 256 }, { 4, 44, 256 }, { 5, 45, 256 }, { 5, 46, 256 }, { 6, 47, 256 }, { 3, 48, 256 }, { 4, 49, 256 }, { 4, 50, 256 }, { 5, 51, 256 }, { 4, 52, 256 }, { 5, 53, 256 }, { 5, 54, 256 }, { 6, 55, 256 }, { 4, 56, 256 }, { 5, 57, 256 }, { 5, 58, 256 }, { 6, 59, 256 }, { 5, 60, 256 }, { 6, 61, 256 }, { 6, 62, 256 }, { 7, 63, 256 }, { 2, 64, 256 }, { 3, 65, 256 }, { 3, 66, 256 }, { 4, 67, 256 }, { 3, 68, 256 }, { 4, 69, 256 }, { 4, 70, 256 }, { 5, 71, 256 }, { 3, 72, 256 }, { 4, 73, 256 }, { 4, 74, 256 }, { 5, 75, 256 }, { 4, 76, 256 }, { 5, 77, 256 }, { 5, 78, 256 }, { 6, 79, 256 }, { 3, 80, 256 }, { 4, 81, 256 }, { 4, 82, 256 }, { 5, 83, 256 }, { 4, 84, 256 }, { 5, 85, 256 }, { 5, 86, 256 }, { 6, 87, 256 }, { 4, 88, 256 }, { 5, 89, 256 }, { 5, 90, 256 }, { 6, 91, 256 }, { 5, 92, 256 }, { 6, 93, 256 }, { 6, 94, 256 }, { 7, 95, 256 }, { 3, 96, 256 }, { 4, 97, 256 }, { 4, 98, 256 }, { 5, 99, 256 }, { 4, 100, 256 }, { 5, 101, 256 }, { 5, 102, 256 }, { 6, 103, 256 }, { 4, 104, 256 }, { 5, 105, 256 }, { 5, 106, 256 }, { 6, 107, 256 }, { 5, 108, 256 }, { 6, 109, 256 }, { 6, 110, 256 }, { 7, 111, 256 }, { 4, 112, 256 }, { 5, 113, 256 }, { 5, 114, 256 }, { 6, 115, 256 }, { 5, 116, 256 }, { 6, 117, 256 }, { 6, 118, 256 }, { 7, 119, 256 }, { 5, 120, 256 }, { 6, 121, 256 }, { 6, 122, 256 }, { 7, 123, 256 }, { 6, 124, 256 }, { 7, 125, 256 }, { 7, 126, 256 }, { 8, 127, 256 }, { 2, 128, 256 }, { 3, 129, 256 }, { 3, 130, 256 }, { 4, 131, 256 }, { 3, 132, 256 }, { 4, 133, 256 }, { 4, 134, 256 }, { 5, 135, 256 }, { 3, 136, 256 }, { 4, 137, 256 }, { 4, 138, 256 }, { 5, 139, 256 }, { 4, 140, 256 }, { 5, 141, 256 }, { 5, 142, 256 }, { 6, 143, 256 }, { 3, 144, 256 }, { 4, 145, 256 }, { 4, 146, 256 }, { 5, 147, 256 }, { 4, 148, 256 }, { 5, 149, 256 }, { 5, 150, 256 }, { 6, 151, 256 }, { 4, 152, 256 }, { 5, 153, 256 }, { 5, 154, 256 }, { 6, 155, 256 }, { 5, 156, 256 }, { 6, 157, 256 }, { 6, 158, 256 }, { 7, 159, 256 }, { 3, 160, 256 }, { 4, 161, 256 }, { 4, 162, 256 }, { 5, 163, 256 }, { 4, 164, 256 }, { 5, 165, 256 }, { 5, 166, 256 }, { 6, 167, 256 }, { 4, 168, 256 }, { 5, 169, 256 }, { 5, 170, 256 }, { 6, 171, 256 }, { 5, 172, 256 }, { 6, 173, 256 }, { 6, 174, 256 }, { 7, 175, 256 }, { 4, 176, 256 }, { 5, 177, 256 }, { 5, 178, 256 }, { 6, 179, 256 }, { 5, 180, 256 }, { 6, 181, 256 }, { 6, 182, 256 }, { 7, 183, 256 }, { 5, 184, 256 }, { 6, 185, 256 }, { 6, 186, 256 }, { 7, 187, 256 }, { 6, 188, 256 }, { 7, 189, 256 }, { 7, 190, 256 }, { 8, 191, 256 }, { 3, 192, 256 }, { 4, 193, 256 }, { 4, 194, 256 }, { 5, 195, 256 }, { 4, 196, 256 }, { 5, 197, 256 }, { 5, 198, 256 }, { 6, 199, 256 }, { 4, 200, 256 }, { 5, 201, 256 }, { 5, 202, 256 }, { 6, 203, 256 }, { 5, 204, 256 }, { 6, 205, 256 }, { 6, 206, 256 }, { 7, 207, 256 }, { 4, 208, 256 }, { 5, 209, 256 }, { 5, 210, 256 }, { 6, 211, 256 }, { 5, 212, 256 }, { 6, 213, 256 }, { 6, 214, 256 }, { 7, 215, 256 }, { 5, 216, 256 }, { 6, 217, 256 }, { 6, 218, 256 }, { 7, 219, 256 }, { 6, 220, 256 }, { 7, 221, 256 }, { 7, 222, 256 }, { 8, 223, 256 }, { 4, 224, 256 }, { 5, 225, 256 }, { 5, 226, 256 }, { 6, 227, 256 }, { 5, 228, 256 }, { 6, 229, 256 }, { 6, 230, 256 }, { 7, 231, 256 }, { 5, 232, 256 }, { 6, 233, 256 }, { 6, 234, 256 }, { 7, 235, 256 }, { 6, 236, 256 }, { 7, 237, 256 }, { 7, 238, 256 }, { 8, 239, 256 }, { 5, 240, 256 }, { 6, 241, 256 }, { 6, 242, 256 }, { 7, 243, 256 }, { 6, 244, 256 }, { 7, 245, 256 }, { 7, 246, 256 }, { 8, 247, 256 }, { 6, 248, 256 }, { 7, 249, 256 }, { 7, 250, 256 }, { 8, 251, 256 }, { 7, 252, 256 }, { 8, 253, 256 }, { 8, 254, 256 }, { 9, 255, 256 }, #if FP_LUT > 9 { 1, 0, 0 }, { 2, 1, 512 }, { 2, 2, 512 }, { 3, 3, 512 }, { 2, 4, 512 }, { 3, 5, 512 }, { 3, 6, 512 }, { 4, 7, 512 }, { 2, 8, 512 }, { 3, 9, 512 }, { 3, 10, 512 }, { 4, 11, 512 }, { 3, 12, 512 }, { 4, 13, 512 }, { 4, 14, 512 }, { 5, 15, 512 }, { 2, 16, 512 }, { 3, 17, 512 }, { 3, 18, 512 }, { 4, 19, 512 }, { 3, 20, 512 }, { 4, 21, 512 }, { 4, 22, 512 }, { 5, 23, 512 }, { 3, 24, 512 }, { 4, 25, 512 }, { 4, 26, 512 }, { 5, 27, 512 }, { 4, 28, 512 }, { 5, 29, 512 }, { 5, 30, 512 }, { 6, 31, 512 }, { 2, 32, 512 }, { 3, 33, 512 }, { 3, 34, 512 }, { 4, 35, 512 }, { 3, 36, 512 }, { 4, 37, 512 }, { 4, 38, 512 }, { 5, 39, 512 }, { 3, 40, 512 }, { 4, 41, 512 }, { 4, 42, 512 }, { 5, 43, 512 }, { 4, 44, 512 }, { 5, 45, 512 }, { 5, 46, 512 }, { 6, 47, 512 }, { 3, 48, 512 }, { 4, 49, 512 }, { 4, 50, 512 }, { 5, 51, 512 }, { 4, 52, 512 }, { 5, 53, 512 }, { 5, 54, 512 }, { 6, 55, 512 }, { 4, 56, 512 }, { 5, 57, 512 }, { 5, 58, 512 }, { 6, 59, 512 }, { 5, 60, 512 }, { 6, 61, 512 }, { 6, 62, 512 }, { 7, 63, 512 }, { 2, 64, 512 }, { 3, 65, 512 }, { 3, 66, 512 }, { 4, 67, 512 }, { 3, 68, 512 }, { 4, 69, 512 }, { 4, 70, 512 }, { 5, 71, 512 }, { 3, 72, 512 }, { 4, 73, 512 }, { 4, 74, 512 }, { 5, 75, 512 }, { 4, 76, 512 }, { 5, 77, 512 }, { 5, 78, 512 }, { 6, 79, 512 }, { 3, 80, 512 }, { 4, 81, 512 }, { 4, 82, 512 }, { 5, 83, 512 }, { 4, 84, 512 }, { 5, 85, 512 }, { 5, 86, 512 }, { 6, 87, 512 }, { 4, 88, 512 }, { 5, 89, 512 }, { 5, 90, 512 }, { 6, 91, 512 }, { 5, 92, 512 }, { 6, 93, 512 }, { 6, 94, 512 }, { 7, 95, 512 }, { 3, 96, 512 }, { 4, 97, 512 }, { 4, 98, 512 }, { 5, 99, 512 }, { 4, 100, 512 }, { 5, 101, 512 }, { 5, 102, 512 }, { 6, 103, 512 }, { 4, 104, 512 }, { 5, 105, 512 }, { 5, 106, 512 }, { 6, 107, 512 }, { 5, 108, 512 }, { 6, 109, 512 }, { 6, 110, 512 }, { 7, 111, 512 }, { 4, 112, 512 }, { 5, 113, 512 }, { 5, 114, 512 }, { 6, 115, 512 }, { 5, 116, 512 }, { 6, 117, 512 }, { 6, 118, 512 }, { 7, 119, 512 }, { 5, 120, 512 }, { 6, 121, 512 }, { 6, 122, 512 }, { 7, 123, 512 }, { 6, 124, 512 }, { 7, 125, 512 }, { 7, 126, 512 }, { 8, 127, 512 }, { 2, 128, 512 }, { 3, 129, 512 }, { 3, 130, 512 }, { 4, 131, 512 }, { 3, 132, 512 }, { 4, 133, 512 }, { 4, 134, 512 }, { 5, 135, 512 }, { 3, 136, 512 }, { 4, 137, 512 }, { 4, 138, 512 }, { 5, 139, 512 }, { 4, 140, 512 }, { 5, 141, 512 }, { 5, 142, 512 }, { 6, 143, 512 }, { 3, 144, 512 }, { 4, 145, 512 }, { 4, 146, 512 }, { 5, 147, 512 }, { 4, 148, 512 }, { 5, 149, 512 }, { 5, 150, 512 }, { 6, 151, 512 }, { 4, 152, 512 }, { 5, 153, 512 }, { 5, 154, 512 }, { 6, 155, 512 }, { 5, 156, 512 }, { 6, 157, 512 }, { 6, 158, 512 }, { 7, 159, 512 }, { 3, 160, 512 }, { 4, 161, 512 }, { 4, 162, 512 }, { 5, 163, 512 }, { 4, 164, 512 }, { 5, 165, 512 }, { 5, 166, 512 }, { 6, 167, 512 }, { 4, 168, 512 }, { 5, 169, 512 }, { 5, 170, 512 }, { 6, 171, 512 }, { 5, 172, 512 }, { 6, 173, 512 }, { 6, 174, 512 }, { 7, 175, 512 }, { 4, 176, 512 }, { 5, 177, 512 }, { 5, 178, 512 }, { 6, 179, 512 }, { 5, 180, 512 }, { 6, 181, 512 }, { 6, 182, 512 }, { 7, 183, 512 }, { 5, 184, 512 }, { 6, 185, 512 }, { 6, 186, 512 }, { 7, 187, 512 }, { 6, 188, 512 }, { 7, 189, 512 }, { 7, 190, 512 }, { 8, 191, 512 }, { 3, 192, 512 }, { 4, 193, 512 }, { 4, 194, 512 }, { 5, 195, 512 }, { 4, 196, 512 }, { 5, 197, 512 }, { 5, 198, 512 }, { 6, 199, 512 }, { 4, 200, 512 }, { 5, 201, 512 }, { 5, 202, 512 }, { 6, 203, 512 }, { 5, 204, 512 }, { 6, 205, 512 }, { 6, 206, 512 }, { 7, 207, 512 }, { 4, 208, 512 }, { 5, 209, 512 }, { 5, 210, 512 }, { 6, 211, 512 }, { 5, 212, 512 }, { 6, 213, 512 }, { 6, 214, 512 }, { 7, 215, 512 }, { 5, 216, 512 }, { 6, 217, 512 }, { 6, 218, 512 }, { 7, 219, 512 }, { 6, 220, 512 }, { 7, 221, 512 }, { 7, 222, 512 }, { 8, 223, 512 }, { 4, 224, 512 }, { 5, 225, 512 }, { 5, 226, 512 }, { 6, 227, 512 }, { 5, 228, 512 }, { 6, 229, 512 }, { 6, 230, 512 }, { 7, 231, 512 }, { 5, 232, 512 }, { 6, 233, 512 }, { 6, 234, 512 }, { 7, 235, 512 }, { 6, 236, 512 }, { 7, 237, 512 }, { 7, 238, 512 }, { 8, 239, 512 }, { 5, 240, 512 }, { 6, 241, 512 }, { 6, 242, 512 }, { 7, 243, 512 }, { 6, 244, 512 }, { 7, 245, 512 }, { 7, 246, 512 }, { 8, 247, 512 }, { 6, 248, 512 }, { 7, 249, 512 }, { 7, 250, 512 }, { 8, 251, 512 }, { 7, 252, 512 }, { 8, 253, 512 }, { 8, 254, 512 }, { 9, 255, 512 }, { 2, 256, 512 }, { 3, 257, 512 }, { 3, 258, 512 }, { 4, 259, 512 }, { 3, 260, 512 }, { 4, 261, 512 }, { 4, 262, 512 }, { 5, 263, 512 }, { 3, 264, 512 }, { 4, 265, 512 }, { 4, 266, 512 }, { 5, 267, 512 }, { 4, 268, 512 }, { 5, 269, 512 }, { 5, 270, 512 }, { 6, 271, 512 }, { 3, 272, 512 }, { 4, 273, 512 }, { 4, 274, 512 }, { 5, 275, 512 }, { 4, 276, 512 }, { 5, 277, 512 }, { 5, 278, 512 }, { 6, 279, 512 }, { 4, 280, 512 }, { 5, 281, 512 }, { 5, 282, 512 }, { 6, 283, 512 }, { 5, 284, 512 }, { 6, 285, 512 }, { 6, 286, 512 }, { 7, 287, 512 }, { 3, 288, 512 }, { 4, 289, 512 }, { 4, 290, 512 }, { 5, 291, 512 }, { 4, 292, 512 }, { 5, 293, 512 }, { 5, 294, 512 }, { 6, 295, 512 }, { 4, 296, 512 }, { 5, 297, 512 }, { 5, 298, 512 }, { 6, 299, 512 }, { 5, 300, 512 }, { 6, 301, 512 }, { 6, 302, 512 }, { 7, 303, 512 }, { 4, 304, 512 }, { 5, 305, 512 }, { 5, 306, 512 }, { 6, 307, 512 }, { 5, 308, 512 }, { 6, 309, 512 }, { 6, 310, 512 }, { 7, 311, 512 }, { 5, 312, 512 }, { 6, 313, 512 }, { 6, 314, 512 }, { 7, 315, 512 }, { 6, 316, 512 }, { 7, 317, 512 }, { 7, 318, 512 }, { 8, 319, 512 }, { 3, 320, 512 }, { 4, 321, 512 }, { 4, 322, 512 }, { 5, 323, 512 }, { 4, 324, 512 }, { 5, 325, 512 }, { 5, 326, 512 }, { 6, 327, 512 }, { 4, 328, 512 }, { 5, 329, 512 }, { 5, 330, 512 }, { 6, 331, 512 }, { 5, 332, 512 }, { 6, 333, 512 }, { 6, 334, 512 }, { 7, 335, 512 }, { 4, 336, 512 }, { 5, 337, 512 }, { 5, 338, 512 }, { 6, 339, 512 }, { 5, 340, 512 }, { 6, 341, 512 }, { 6, 342, 512 }, { 7, 343, 512 }, { 5, 344, 512 }, { 6, 345, 512 }, { 6, 346, 512 }, { 7, 347, 512 }, { 6, 348, 512 }, { 7, 349, 512 }, { 7, 350, 512 }, { 8, 351, 512 }, { 4, 352, 512 }, { 5, 353, 512 }, { 5, 354, 512 }, { 6, 355, 512 }, { 5, 356, 512 }, { 6, 357, 512 }, { 6, 358, 512 }, { 7, 359, 512 }, { 5, 360, 512 }, { 6, 361, 512 }, { 6, 362, 512 }, { 7, 363, 512 }, { 6, 364, 512 }, { 7, 365, 512 }, { 7, 366, 512 }, { 8, 367, 512 }, { 5, 368, 512 }, { 6, 369, 512 }, { 6, 370, 512 }, { 7, 371, 512 }, { 6, 372, 512 }, { 7, 373, 512 }, { 7, 374, 512 }, { 8, 375, 512 }, { 6, 376, 512 }, { 7, 377, 512 }, { 7, 378, 512 }, { 8, 379, 512 }, { 7, 380, 512 }, { 8, 381, 512 }, { 8, 382, 512 }, { 9, 383, 512 }, { 3, 384, 512 }, { 4, 385, 512 }, { 4, 386, 512 }, { 5, 387, 512 }, { 4, 388, 512 }, { 5, 389, 512 }, { 5, 390, 512 }, { 6, 391, 512 }, { 4, 392, 512 }, { 5, 393, 512 }, { 5, 394, 512 }, { 6, 395, 512 }, { 5, 396, 512 }, { 6, 397, 512 }, { 6, 398, 512 }, { 7, 399, 512 }, { 4, 400, 512 }, { 5, 401, 512 }, { 5, 402, 512 }, { 6, 403, 512 }, { 5, 404, 512 }, { 6, 405, 512 }, { 6, 406, 512 }, { 7, 407, 512 }, { 5, 408, 512 }, { 6, 409, 512 }, { 6, 410, 512 }, { 7, 411, 512 }, { 6, 412, 512 }, { 7, 413, 512 }, { 7, 414, 512 }, { 8, 415, 512 }, { 4, 416, 512 }, { 5, 417, 512 }, { 5, 418, 512 }, { 6, 419, 512 }, { 5, 420, 512 }, { 6, 421, 512 }, { 6, 422, 512 }, { 7, 423, 512 }, { 5, 424, 512 }, { 6, 425, 512 }, { 6, 426, 512 }, { 7, 427, 512 }, { 6, 428, 512 }, { 7, 429, 512 }, { 7, 430, 512 }, { 8, 431, 512 }, { 5, 432, 512 }, { 6, 433, 512 }, { 6, 434, 512 }, { 7, 435, 512 }, { 6, 436, 512 }, { 7, 437, 512 }, { 7, 438, 512 }, { 8, 439, 512 }, { 6, 440, 512 }, { 7, 441, 512 }, { 7, 442, 512 }, { 8, 443, 512 }, { 7, 444, 512 }, { 8, 445, 512 }, { 8, 446, 512 }, { 9, 447, 512 }, { 4, 448, 512 }, { 5, 449, 512 }, { 5, 450, 512 }, { 6, 451, 512 }, { 5, 452, 512 }, { 6, 453, 512 }, { 6, 454, 512 }, { 7, 455, 512 }, { 5, 456, 512 }, { 6, 457, 512 }, { 6, 458, 512 }, { 7, 459, 512 }, { 6, 460, 512 }, { 7, 461, 512 }, { 7, 462, 512 }, { 8, 463, 512 }, { 5, 464, 512 }, { 6, 465, 512 }, { 6, 466, 512 }, { 7, 467, 512 }, { 6, 468, 512 }, { 7, 469, 512 }, { 7, 470, 512 }, { 8, 471, 512 }, { 6, 472, 512 }, { 7, 473, 512 }, { 7, 474, 512 }, { 8, 475, 512 }, { 7, 476, 512 }, { 8, 477, 512 }, { 8, 478, 512 }, { 9, 479, 512 }, { 5, 480, 512 }, { 6, 481, 512 }, { 6, 482, 512 }, { 7, 483, 512 }, { 6, 484, 512 }, { 7, 485, 512 }, { 7, 486, 512 }, { 8, 487, 512 }, { 6, 488, 512 }, { 7, 489, 512 }, { 7, 490, 512 }, { 8, 491, 512 }, { 7, 492, 512 }, { 8, 493, 512 }, { 8, 494, 512 }, { 9, 495, 512 }, { 6, 496, 512 }, { 7, 497, 512 }, { 7, 498, 512 }, { 8, 499, 512 }, { 7, 500, 512 }, { 8, 501, 512 }, { 8, 502, 512 }, { 9, 503, 512 }, { 7, 504, 512 }, { 8, 505, 512 }, { 8, 506, 512 }, { 9, 507, 512 }, { 8, 508, 512 }, { 9, 509, 512 }, { 9, 510, 512 }, { 10, 511, 512 }, #if FP_LUT > 10 { 1, 0, 0 }, { 2, 1, 1024 }, { 2, 2, 1024 }, { 3, 3, 1024 }, { 2, 4, 1024 }, { 3, 5, 1024 }, { 3, 6, 1024 }, { 4, 7, 1024 }, { 2, 8, 1024 }, { 3, 9, 1024 }, { 3, 10, 1024 }, { 4, 11, 1024 }, { 3, 12, 1024 }, { 4, 13, 1024 }, { 4, 14, 1024 }, { 5, 15, 1024 }, { 2, 16, 1024 }, { 3, 17, 1024 }, { 3, 18, 1024 }, { 4, 19, 1024 }, { 3, 20, 1024 }, { 4, 21, 1024 }, { 4, 22, 1024 }, { 5, 23, 1024 }, { 3, 24, 1024 }, { 4, 25, 1024 }, { 4, 26, 1024 }, { 5, 27, 1024 }, { 4, 28, 1024 }, { 5, 29, 1024 }, { 5, 30, 1024 }, { 6, 31, 1024 }, { 2, 32, 1024 }, { 3, 33, 1024 }, { 3, 34, 1024 }, { 4, 35, 1024 }, { 3, 36, 1024 }, { 4, 37, 1024 }, { 4, 38, 1024 }, { 5, 39, 1024 }, { 3, 40, 1024 }, { 4, 41, 1024 }, { 4, 42, 1024 }, { 5, 43, 1024 }, { 4, 44, 1024 }, { 5, 45, 1024 }, { 5, 46, 1024 }, { 6, 47, 1024 }, { 3, 48, 1024 }, { 4, 49, 1024 }, { 4, 50, 1024 }, { 5, 51, 1024 }, { 4, 52, 1024 }, { 5, 53, 1024 }, { 5, 54, 1024 }, { 6, 55, 1024 }, { 4, 56, 1024 }, { 5, 57, 1024 }, { 5, 58, 1024 }, { 6, 59, 1024 }, { 5, 60, 1024 }, { 6, 61, 1024 }, { 6, 62, 1024 }, { 7, 63, 1024 }, { 2, 64, 1024 }, { 3, 65, 1024 }, { 3, 66, 1024 }, { 4, 67, 1024 }, { 3, 68, 1024 }, { 4, 69, 1024 }, { 4, 70, 1024 }, { 5, 71, 1024 }, { 3, 72, 1024 }, { 4, 73, 1024 }, { 4, 74, 1024 }, { 5, 75, 1024 }, { 4, 76, 1024 }, { 5, 77, 1024 }, { 5, 78, 1024 }, { 6, 79, 1024 }, { 3, 80, 1024 }, { 4, 81, 1024 }, { 4, 82, 1024 }, { 5, 83, 1024 }, { 4, 84, 1024 }, { 5, 85, 1024 }, { 5, 86, 1024 }, { 6, 87, 1024 }, { 4, 88, 1024 }, { 5, 89, 1024 }, { 5, 90, 1024 }, { 6, 91, 1024 }, { 5, 92, 1024 }, { 6, 93, 1024 }, { 6, 94, 1024 }, { 7, 95, 1024 }, { 3, 96, 1024 }, { 4, 97, 1024 }, { 4, 98, 1024 }, { 5, 99, 1024 }, { 4, 100, 1024 }, { 5, 101, 1024 }, { 5, 102, 1024 }, { 6, 103, 1024 }, { 4, 104, 1024 }, { 5, 105, 1024 }, { 5, 106, 1024 }, { 6, 107, 1024 }, { 5, 108, 1024 }, { 6, 109, 1024 }, { 6, 110, 1024 }, { 7, 111, 1024 }, { 4, 112, 1024 }, { 5, 113, 1024 }, { 5, 114, 1024 }, { 6, 115, 1024 }, { 5, 116, 1024 }, { 6, 117, 1024 }, { 6, 118, 1024 }, { 7, 119, 1024 }, { 5, 120, 1024 }, { 6, 121, 1024 }, { 6, 122, 1024 }, { 7, 123, 1024 }, { 6, 124, 1024 }, { 7, 125, 1024 }, { 7, 126, 1024 }, { 8, 127, 1024 }, { 2, 128, 1024 }, { 3, 129, 1024 }, { 3, 130, 1024 }, { 4, 131, 1024 }, { 3, 132, 1024 }, { 4, 133, 1024 }, { 4, 134, 1024 }, { 5, 135, 1024 }, { 3, 136, 1024 }, { 4, 137, 1024 }, { 4, 138, 1024 }, { 5, 139, 1024 }, { 4, 140, 1024 }, { 5, 141, 1024 }, { 5, 142, 1024 }, { 6, 143, 1024 }, { 3, 144, 1024 }, { 4, 145, 1024 }, { 4, 146, 1024 }, { 5, 147, 1024 }, { 4, 148, 1024 }, { 5, 149, 1024 }, { 5, 150, 1024 }, { 6, 151, 1024 }, { 4, 152, 1024 }, { 5, 153, 1024 }, { 5, 154, 1024 }, { 6, 155, 1024 }, { 5, 156, 1024 }, { 6, 157, 1024 }, { 6, 158, 1024 }, { 7, 159, 1024 }, { 3, 160, 1024 }, { 4, 161, 1024 }, { 4, 162, 1024 }, { 5, 163, 1024 }, { 4, 164, 1024 }, { 5, 165, 1024 }, { 5, 166, 1024 }, { 6, 167, 1024 }, { 4, 168, 1024 }, { 5, 169, 1024 }, { 5, 170, 1024 }, { 6, 171, 1024 }, { 5, 172, 1024 }, { 6, 173, 1024 }, { 6, 174, 1024 }, { 7, 175, 1024 }, { 4, 176, 1024 }, { 5, 177, 1024 }, { 5, 178, 1024 }, { 6, 179, 1024 }, { 5, 180, 1024 }, { 6, 181, 1024 }, { 6, 182, 1024 }, { 7, 183, 1024 }, { 5, 184, 1024 }, { 6, 185, 1024 }, { 6, 186, 1024 }, { 7, 187, 1024 }, { 6, 188, 1024 }, { 7, 189, 1024 }, { 7, 190, 1024 }, { 8, 191, 1024 }, { 3, 192, 1024 }, { 4, 193, 1024 }, { 4, 194, 1024 }, { 5, 195, 1024 }, { 4, 196, 1024 }, { 5, 197, 1024 }, { 5, 198, 1024 }, { 6, 199, 1024 }, { 4, 200, 1024 }, { 5, 201, 1024 }, { 5, 202, 1024 }, { 6, 203, 1024 }, { 5, 204, 1024 }, { 6, 205, 1024 }, { 6, 206, 1024 }, { 7, 207, 1024 }, { 4, 208, 1024 }, { 5, 209, 1024 }, { 5, 210, 1024 }, { 6, 211, 1024 }, { 5, 212, 1024 }, { 6, 213, 1024 }, { 6, 214, 1024 }, { 7, 215, 1024 }, { 5, 216, 1024 }, { 6, 217, 1024 }, { 6, 218, 1024 }, { 7, 219, 1024 }, { 6, 220, 1024 }, { 7, 221, 1024 }, { 7, 222, 1024 }, { 8, 223, 1024 }, { 4, 224, 1024 }, { 5, 225, 1024 }, { 5, 226, 1024 }, { 6, 227, 1024 }, { 5, 228, 1024 }, { 6, 229, 1024 }, { 6, 230, 1024 }, { 7, 231, 1024 }, { 5, 232, 1024 }, { 6, 233, 1024 }, { 6, 234, 1024 }, { 7, 235, 1024 }, { 6, 236, 1024 }, { 7, 237, 1024 }, { 7, 238, 1024 }, { 8, 239, 1024 }, { 5, 240, 1024 }, { 6, 241, 1024 }, { 6, 242, 1024 }, { 7, 243, 1024 }, { 6, 244, 1024 }, { 7, 245, 1024 }, { 7, 246, 1024 }, { 8, 247, 1024 }, { 6, 248, 1024 }, { 7, 249, 1024 }, { 7, 250, 1024 }, { 8, 251, 1024 }, { 7, 252, 1024 }, { 8, 253, 1024 }, { 8, 254, 1024 }, { 9, 255, 1024 }, { 2, 256, 1024 }, { 3, 257, 1024 }, { 3, 258, 1024 }, { 4, 259, 1024 }, { 3, 260, 1024 }, { 4, 261, 1024 }, { 4, 262, 1024 }, { 5, 263, 1024 }, { 3, 264, 1024 }, { 4, 265, 1024 }, { 4, 266, 1024 }, { 5, 267, 1024 }, { 4, 268, 1024 }, { 5, 269, 1024 }, { 5, 270, 1024 }, { 6, 271, 1024 }, { 3, 272, 1024 }, { 4, 273, 1024 }, { 4, 274, 1024 }, { 5, 275, 1024 }, { 4, 276, 1024 }, { 5, 277, 1024 }, { 5, 278, 1024 }, { 6, 279, 1024 }, { 4, 280, 1024 }, { 5, 281, 1024 }, { 5, 282, 1024 }, { 6, 283, 1024 }, { 5, 284, 1024 }, { 6, 285, 1024 }, { 6, 286, 1024 }, { 7, 287, 1024 }, { 3, 288, 1024 }, { 4, 289, 1024 }, { 4, 290, 1024 }, { 5, 291, 1024 }, { 4, 292, 1024 }, { 5, 293, 1024 }, { 5, 294, 1024 }, { 6, 295, 1024 }, { 4, 296, 1024 }, { 5, 297, 1024 }, { 5, 298, 1024 }, { 6, 299, 1024 }, { 5, 300, 1024 }, { 6, 301, 1024 }, { 6, 302, 1024 }, { 7, 303, 1024 }, { 4, 304, 1024 }, { 5, 305, 1024 }, { 5, 306, 1024 }, { 6, 307, 1024 }, { 5, 308, 1024 }, { 6, 309, 1024 }, { 6, 310, 1024 }, { 7, 311, 1024 }, { 5, 312, 1024 }, { 6, 313, 1024 }, { 6, 314, 1024 }, { 7, 315, 1024 }, { 6, 316, 1024 }, { 7, 317, 1024 }, { 7, 318, 1024 }, { 8, 319, 1024 }, { 3, 320, 1024 }, { 4, 321, 1024 }, { 4, 322, 1024 }, { 5, 323, 1024 }, { 4, 324, 1024 }, { 5, 325, 1024 }, { 5, 326, 1024 }, { 6, 327, 1024 }, { 4, 328, 1024 }, { 5, 329, 1024 }, { 5, 330, 1024 }, { 6, 331, 1024 }, { 5, 332, 1024 }, { 6, 333, 1024 }, { 6, 334, 1024 }, { 7, 335, 1024 }, { 4, 336, 1024 }, { 5, 337, 1024 }, { 5, 338, 1024 }, { 6, 339, 1024 }, { 5, 340, 1024 }, { 6, 341, 1024 }, { 6, 342, 1024 }, { 7, 343, 1024 }, { 5, 344, 1024 }, { 6, 345, 1024 }, { 6, 346, 1024 }, { 7, 347, 1024 }, { 6, 348, 1024 }, { 7, 349, 1024 }, { 7, 350, 1024 }, { 8, 351, 1024 }, { 4, 352, 1024 }, { 5, 353, 1024 }, { 5, 354, 1024 }, { 6, 355, 1024 }, { 5, 356, 1024 }, { 6, 357, 1024 }, { 6, 358, 1024 }, { 7, 359, 1024 }, { 5, 360, 1024 }, { 6, 361, 1024 }, { 6, 362, 1024 }, { 7, 363, 1024 }, { 6, 364, 1024 }, { 7, 365, 1024 }, { 7, 366, 1024 }, { 8, 367, 1024 }, { 5, 368, 1024 }, { 6, 369, 1024 }, { 6, 370, 1024 }, { 7, 371, 1024 }, { 6, 372, 1024 }, { 7, 373, 1024 }, { 7, 374, 1024 }, { 8, 375, 1024 }, { 6, 376, 1024 }, { 7, 377, 1024 }, { 7, 378, 1024 }, { 8, 379, 1024 }, { 7, 380, 1024 }, { 8, 381, 1024 }, { 8, 382, 1024 }, { 9, 383, 1024 }, { 3, 384, 1024 }, { 4, 385, 1024 }, { 4, 386, 1024 }, { 5, 387, 1024 }, { 4, 388, 1024 }, { 5, 389, 1024 }, { 5, 390, 1024 }, { 6, 391, 1024 }, { 4, 392, 1024 }, { 5, 393, 1024 }, { 5, 394, 1024 }, { 6, 395, 1024 }, { 5, 396, 1024 }, { 6, 397, 1024 }, { 6, 398, 1024 }, { 7, 399, 1024 }, { 4, 400, 1024 }, { 5, 401, 1024 }, { 5, 402, 1024 }, { 6, 403, 1024 }, { 5, 404, 1024 }, { 6, 405, 1024 }, { 6, 406, 1024 }, { 7, 407, 1024 }, { 5, 408, 1024 }, { 6, 409, 1024 }, { 6, 410, 1024 }, { 7, 411, 1024 }, { 6, 412, 1024 }, { 7, 413, 1024 }, { 7, 414, 1024 }, { 8, 415, 1024 }, { 4, 416, 1024 }, { 5, 417, 1024 }, { 5, 418, 1024 }, { 6, 419, 1024 }, { 5, 420, 1024 }, { 6, 421, 1024 }, { 6, 422, 1024 }, { 7, 423, 1024 }, { 5, 424, 1024 }, { 6, 425, 1024 }, { 6, 426, 1024 }, { 7, 427, 1024 }, { 6, 428, 1024 }, { 7, 429, 1024 }, { 7, 430, 1024 }, { 8, 431, 1024 }, { 5, 432, 1024 }, { 6, 433, 1024 }, { 6, 434, 1024 }, { 7, 435, 1024 }, { 6, 436, 1024 }, { 7, 437, 1024 }, { 7, 438, 1024 }, { 8, 439, 1024 }, { 6, 440, 1024 }, { 7, 441, 1024 }, { 7, 442, 1024 }, { 8, 443, 1024 }, { 7, 444, 1024 }, { 8, 445, 1024 }, { 8, 446, 1024 }, { 9, 447, 1024 }, { 4, 448, 1024 }, { 5, 449, 1024 }, { 5, 450, 1024 }, { 6, 451, 1024 }, { 5, 452, 1024 }, { 6, 453, 1024 }, { 6, 454, 1024 }, { 7, 455, 1024 }, { 5, 456, 1024 }, { 6, 457, 1024 }, { 6, 458, 1024 }, { 7, 459, 1024 }, { 6, 460, 1024 }, { 7, 461, 1024 }, { 7, 462, 1024 }, { 8, 463, 1024 }, { 5, 464, 1024 }, { 6, 465, 1024 }, { 6, 466, 1024 }, { 7, 467, 1024 }, { 6, 468, 1024 }, { 7, 469, 1024 }, { 7, 470, 1024 }, { 8, 471, 1024 }, { 6, 472, 1024 }, { 7, 473, 1024 }, { 7, 474, 1024 }, { 8, 475, 1024 }, { 7, 476, 1024 }, { 8, 477, 1024 }, { 8, 478, 1024 }, { 9, 479, 1024 }, { 5, 480, 1024 }, { 6, 481, 1024 }, { 6, 482, 1024 }, { 7, 483, 1024 }, { 6, 484, 1024 }, { 7, 485, 1024 }, { 7, 486, 1024 }, { 8, 487, 1024 }, { 6, 488, 1024 }, { 7, 489, 1024 }, { 7, 490, 1024 }, { 8, 491, 1024 }, { 7, 492, 1024 }, { 8, 493, 1024 }, { 8, 494, 1024 }, { 9, 495, 1024 }, { 6, 496, 1024 }, { 7, 497, 1024 }, { 7, 498, 1024 }, { 8, 499, 1024 }, { 7, 500, 1024 }, { 8, 501, 1024 }, { 8, 502, 1024 }, { 9, 503, 1024 }, { 7, 504, 1024 }, { 8, 505, 1024 }, { 8, 506, 1024 }, { 9, 507, 1024 }, { 8, 508, 1024 }, { 9, 509, 1024 }, { 9, 510, 1024 }, { 10, 511, 1024 }, { 2, 512, 1024 }, { 3, 513, 1024 }, { 3, 514, 1024 }, { 4, 515, 1024 }, { 3, 516, 1024 }, { 4, 517, 1024 }, { 4, 518, 1024 }, { 5, 519, 1024 }, { 3, 520, 1024 }, { 4, 521, 1024 }, { 4, 522, 1024 }, { 5, 523, 1024 }, { 4, 524, 1024 }, { 5, 525, 1024 }, { 5, 526, 1024 }, { 6, 527, 1024 }, { 3, 528, 1024 }, { 4, 529, 1024 }, { 4, 530, 1024 }, { 5, 531, 1024 }, { 4, 532, 1024 }, { 5, 533, 1024 }, { 5, 534, 1024 }, { 6, 535, 1024 }, { 4, 536, 1024 }, { 5, 537, 1024 }, { 5, 538, 1024 }, { 6, 539, 1024 }, { 5, 540, 1024 }, { 6, 541, 1024 }, { 6, 542, 1024 }, { 7, 543, 1024 }, { 3, 544, 1024 }, { 4, 545, 1024 }, { 4, 546, 1024 }, { 5, 547, 1024 }, { 4, 548, 1024 }, { 5, 549, 1024 }, { 5, 550, 1024 }, { 6, 551, 1024 }, { 4, 552, 1024 }, { 5, 553, 1024 }, { 5, 554, 1024 }, { 6, 555, 1024 }, { 5, 556, 1024 }, { 6, 557, 1024 }, { 6, 558, 1024 }, { 7, 559, 1024 }, { 4, 560, 1024 }, { 5, 561, 1024 }, { 5, 562, 1024 }, { 6, 563, 1024 }, { 5, 564, 1024 }, { 6, 565, 1024 }, { 6, 566, 1024 }, { 7, 567, 1024 }, { 5, 568, 1024 }, { 6, 569, 1024 }, { 6, 570, 1024 }, { 7, 571, 1024 }, { 6, 572, 1024 }, { 7, 573, 1024 }, { 7, 574, 1024 }, { 8, 575, 1024 }, { 3, 576, 1024 }, { 4, 577, 1024 }, { 4, 578, 1024 }, { 5, 579, 1024 }, { 4, 580, 1024 }, { 5, 581, 1024 }, { 5, 582, 1024 }, { 6, 583, 1024 }, { 4, 584, 1024 }, { 5, 585, 1024 }, { 5, 586, 1024 }, { 6, 587, 1024 }, { 5, 588, 1024 }, { 6, 589, 1024 }, { 6, 590, 1024 }, { 7, 591, 1024 }, { 4, 592, 1024 }, { 5, 593, 1024 }, { 5, 594, 1024 }, { 6, 595, 1024 }, { 5, 596, 1024 }, { 6, 597, 1024 }, { 6, 598, 1024 }, { 7, 599, 1024 }, { 5, 600, 1024 }, { 6, 601, 1024 }, { 6, 602, 1024 }, { 7, 603, 1024 }, { 6, 604, 1024 }, { 7, 605, 1024 }, { 7, 606, 1024 }, { 8, 607, 1024 }, { 4, 608, 1024 }, { 5, 609, 1024 }, { 5, 610, 1024 }, { 6, 611, 1024 }, { 5, 612, 1024 }, { 6, 613, 1024 }, { 6, 614, 1024 }, { 7, 615, 1024 }, { 5, 616, 1024 }, { 6, 617, 1024 }, { 6, 618, 1024 }, { 7, 619, 1024 }, { 6, 620, 1024 }, { 7, 621, 1024 }, { 7, 622, 1024 }, { 8, 623, 1024 }, { 5, 624, 1024 }, { 6, 625, 1024 }, { 6, 626, 1024 }, { 7, 627, 1024 }, { 6, 628, 1024 }, { 7, 629, 1024 }, { 7, 630, 1024 }, { 8, 631, 1024 }, { 6, 632, 1024 }, { 7, 633, 1024 }, { 7, 634, 1024 }, { 8, 635, 1024 }, { 7, 636, 1024 }, { 8, 637, 1024 }, { 8, 638, 1024 }, { 9, 639, 1024 }, { 3, 640, 1024 }, { 4, 641, 1024 }, { 4, 642, 1024 }, { 5, 643, 1024 }, { 4, 644, 1024 }, { 5, 645, 1024 }, { 5, 646, 1024 }, { 6, 647, 1024 }, { 4, 648, 1024 }, { 5, 649, 1024 }, { 5, 650, 1024 }, { 6, 651, 1024 }, { 5, 652, 1024 }, { 6, 653, 1024 }, { 6, 654, 1024 }, { 7, 655, 1024 }, { 4, 656, 1024 }, { 5, 657, 1024 }, { 5, 658, 1024 }, { 6, 659, 1024 }, { 5, 660, 1024 }, { 6, 661, 1024 }, { 6, 662, 1024 }, { 7, 663, 1024 }, { 5, 664, 1024 }, { 6, 665, 1024 }, { 6, 666, 1024 }, { 7, 667, 1024 }, { 6, 668, 1024 }, { 7, 669, 1024 }, { 7, 670, 1024 }, { 8, 671, 1024 }, { 4, 672, 1024 }, { 5, 673, 1024 }, { 5, 674, 1024 }, { 6, 675, 1024 }, { 5, 676, 1024 }, { 6, 677, 1024 }, { 6, 678, 1024 }, { 7, 679, 1024 }, { 5, 680, 1024 }, { 6, 681, 1024 }, { 6, 682, 1024 }, { 7, 683, 1024 }, { 6, 684, 1024 }, { 7, 685, 1024 }, { 7, 686, 1024 }, { 8, 687, 1024 }, { 5, 688, 1024 }, { 6, 689, 1024 }, { 6, 690, 1024 }, { 7, 691, 1024 }, { 6, 692, 1024 }, { 7, 693, 1024 }, { 7, 694, 1024 }, { 8, 695, 1024 }, { 6, 696, 1024 }, { 7, 697, 1024 }, { 7, 698, 1024 }, { 8, 699, 1024 }, { 7, 700, 1024 }, { 8, 701, 1024 }, { 8, 702, 1024 }, { 9, 703, 1024 }, { 4, 704, 1024 }, { 5, 705, 1024 }, { 5, 706, 1024 }, { 6, 707, 1024 }, { 5, 708, 1024 }, { 6, 709, 1024 }, { 6, 710, 1024 }, { 7, 711, 1024 }, { 5, 712, 1024 }, { 6, 713, 1024 }, { 6, 714, 1024 }, { 7, 715, 1024 }, { 6, 716, 1024 }, { 7, 717, 1024 }, { 7, 718, 1024 }, { 8, 719, 1024 }, { 5, 720, 1024 }, { 6, 721, 1024 }, { 6, 722, 1024 }, { 7, 723, 1024 }, { 6, 724, 1024 }, { 7, 725, 1024 }, { 7, 726, 1024 }, { 8, 727, 1024 }, { 6, 728, 1024 }, { 7, 729, 1024 }, { 7, 730, 1024 }, { 8, 731, 1024 }, { 7, 732, 1024 }, { 8, 733, 1024 }, { 8, 734, 1024 }, { 9, 735, 1024 }, { 5, 736, 1024 }, { 6, 737, 1024 }, { 6, 738, 1024 }, { 7, 739, 1024 }, { 6, 740, 1024 }, { 7, 741, 1024 }, { 7, 742, 1024 }, { 8, 743, 1024 }, { 6, 744, 1024 }, { 7, 745, 1024 }, { 7, 746, 1024 }, { 8, 747, 1024 }, { 7, 748, 1024 }, { 8, 749, 1024 }, { 8, 750, 1024 }, { 9, 751, 1024 }, { 6, 752, 1024 }, { 7, 753, 1024 }, { 7, 754, 1024 }, { 8, 755, 1024 }, { 7, 756, 1024 }, { 8, 757, 1024 }, { 8, 758, 1024 }, { 9, 759, 1024 }, { 7, 760, 1024 }, { 8, 761, 1024 }, { 8, 762, 1024 }, { 9, 763, 1024 }, { 8, 764, 1024 }, { 9, 765, 1024 }, { 9, 766, 1024 }, { 10, 767, 1024 }, { 3, 768, 1024 }, { 4, 769, 1024 }, { 4, 770, 1024 }, { 5, 771, 1024 }, { 4, 772, 1024 }, { 5, 773, 1024 }, { 5, 774, 1024 }, { 6, 775, 1024 }, { 4, 776, 1024 }, { 5, 777, 1024 }, { 5, 778, 1024 }, { 6, 779, 1024 }, { 5, 780, 1024 }, { 6, 781, 1024 }, { 6, 782, 1024 }, { 7, 783, 1024 }, { 4, 784, 1024 }, { 5, 785, 1024 }, { 5, 786, 1024 }, { 6, 787, 1024 }, { 5, 788, 1024 }, { 6, 789, 1024 }, { 6, 790, 1024 }, { 7, 791, 1024 }, { 5, 792, 1024 }, { 6, 793, 1024 }, { 6, 794, 1024 }, { 7, 795, 1024 }, { 6, 796, 1024 }, { 7, 797, 1024 }, { 7, 798, 1024 }, { 8, 799, 1024 }, { 4, 800, 1024 }, { 5, 801, 1024 }, { 5, 802, 1024 }, { 6, 803, 1024 }, { 5, 804, 1024 }, { 6, 805, 1024 }, { 6, 806, 1024 }, { 7, 807, 1024 }, { 5, 808, 1024 }, { 6, 809, 1024 }, { 6, 810, 1024 }, { 7, 811, 1024 }, { 6, 812, 1024 }, { 7, 813, 1024 }, { 7, 814, 1024 }, { 8, 815, 1024 }, { 5, 816, 1024 }, { 6, 817, 1024 }, { 6, 818, 1024 }, { 7, 819, 1024 }, { 6, 820, 1024 }, { 7, 821, 1024 }, { 7, 822, 1024 }, { 8, 823, 1024 }, { 6, 824, 1024 }, { 7, 825, 1024 }, { 7, 826, 1024 }, { 8, 827, 1024 }, { 7, 828, 1024 }, { 8, 829, 1024 }, { 8, 830, 1024 }, { 9, 831, 1024 }, { 4, 832, 1024 }, { 5, 833, 1024 }, { 5, 834, 1024 }, { 6, 835, 1024 }, { 5, 836, 1024 }, { 6, 837, 1024 }, { 6, 838, 1024 }, { 7, 839, 1024 }, { 5, 840, 1024 }, { 6, 841, 1024 }, { 6, 842, 1024 }, { 7, 843, 1024 }, { 6, 844, 1024 }, { 7, 845, 1024 }, { 7, 846, 1024 }, { 8, 847, 1024 }, { 5, 848, 1024 }, { 6, 849, 1024 }, { 6, 850, 1024 }, { 7, 851, 1024 }, { 6, 852, 1024 }, { 7, 853, 1024 }, { 7, 854, 1024 }, { 8, 855, 1024 }, { 6, 856, 1024 }, { 7, 857, 1024 }, { 7, 858, 1024 }, { 8, 859, 1024 }, { 7, 860, 1024 }, { 8, 861, 1024 }, { 8, 862, 1024 }, { 9, 863, 1024 }, { 5, 864, 1024 }, { 6, 865, 1024 }, { 6, 866, 1024 }, { 7, 867, 1024 }, { 6, 868, 1024 }, { 7, 869, 1024 }, { 7, 870, 1024 }, { 8, 871, 1024 }, { 6, 872, 1024 }, { 7, 873, 1024 }, { 7, 874, 1024 }, { 8, 875, 1024 }, { 7, 876, 1024 }, { 8, 877, 1024 }, { 8, 878, 1024 }, { 9, 879, 1024 }, { 6, 880, 1024 }, { 7, 881, 1024 }, { 7, 882, 1024 }, { 8, 883, 1024 }, { 7, 884, 1024 }, { 8, 885, 1024 }, { 8, 886, 1024 }, { 9, 887, 1024 }, { 7, 888, 1024 }, { 8, 889, 1024 }, { 8, 890, 1024 }, { 9, 891, 1024 }, { 8, 892, 1024 }, { 9, 893, 1024 }, { 9, 894, 1024 }, { 10, 895, 1024 }, { 4, 896, 1024 }, { 5, 897, 1024 }, { 5, 898, 1024 }, { 6, 899, 1024 }, { 5, 900, 1024 }, { 6, 901, 1024 }, { 6, 902, 1024 }, { 7, 903, 1024 }, { 5, 904, 1024 }, { 6, 905, 1024 }, { 6, 906, 1024 }, { 7, 907, 1024 }, { 6, 908, 1024 }, { 7, 909, 1024 }, { 7, 910, 1024 }, { 8, 911, 1024 }, { 5, 912, 1024 }, { 6, 913, 1024 }, { 6, 914, 1024 }, { 7, 915, 1024 }, { 6, 916, 1024 }, { 7, 917, 1024 }, { 7, 918, 1024 }, { 8, 919, 1024 }, { 6, 920, 1024 }, { 7, 921, 1024 }, { 7, 922, 1024 }, { 8, 923, 1024 }, { 7, 924, 1024 }, { 8, 925, 1024 }, { 8, 926, 1024 }, { 9, 927, 1024 }, { 5, 928, 1024 }, { 6, 929, 1024 }, { 6, 930, 1024 }, { 7, 931, 1024 }, { 6, 932, 1024 }, { 7, 933, 1024 }, { 7, 934, 1024 }, { 8, 935, 1024 }, { 6, 936, 1024 }, { 7, 937, 1024 }, { 7, 938, 1024 }, { 8, 939, 1024 }, { 7, 940, 1024 }, { 8, 941, 1024 }, { 8, 942, 1024 }, { 9, 943, 1024 }, { 6, 944, 1024 }, { 7, 945, 1024 }, { 7, 946, 1024 }, { 8, 947, 1024 }, { 7, 948, 1024 }, { 8, 949, 1024 }, { 8, 950, 1024 }, { 9, 951, 1024 }, { 7, 952, 1024 }, { 8, 953, 1024 }, { 8, 954, 1024 }, { 9, 955, 1024 }, { 8, 956, 1024 }, { 9, 957, 1024 }, { 9, 958, 1024 }, { 10, 959, 1024 }, { 5, 960, 1024 }, { 6, 961, 1024 }, { 6, 962, 1024 }, { 7, 963, 1024 }, { 6, 964, 1024 }, { 7, 965, 1024 }, { 7, 966, 1024 }, { 8, 967, 1024 }, { 6, 968, 1024 }, { 7, 969, 1024 }, { 7, 970, 1024 }, { 8, 971, 1024 }, { 7, 972, 1024 }, { 8, 973, 1024 }, { 8, 974, 1024 }, { 9, 975, 1024 }, { 6, 976, 1024 }, { 7, 977, 1024 }, { 7, 978, 1024 }, { 8, 979, 1024 }, { 7, 980, 1024 }, { 8, 981, 1024 }, { 8, 982, 1024 }, { 9, 983, 1024 }, { 7, 984, 1024 }, { 8, 985, 1024 }, { 8, 986, 1024 }, { 9, 987, 1024 }, { 8, 988, 1024 }, { 9, 989, 1024 }, { 9, 990, 1024 }, { 10, 991, 1024 }, { 6, 992, 1024 }, { 7, 993, 1024 }, { 7, 994, 1024 }, { 8, 995, 1024 }, { 7, 996, 1024 }, { 8, 997, 1024 }, { 8, 998, 1024 }, { 9, 999, 1024 }, { 7, 1000, 1024 }, { 8, 1001, 1024 }, { 8, 1002, 1024 }, { 9, 1003, 1024 }, { 8, 1004, 1024 }, { 9, 1005, 1024 }, { 9, 1006, 1024 }, { 10, 1007, 1024 }, { 7, 1008, 1024 }, { 8, 1009, 1024 }, { 8, 1010, 1024 }, { 9, 1011, 1024 }, { 8, 1012, 1024 }, { 9, 1013, 1024 }, { 9, 1014, 1024 }, { 10, 1015, 1024 }, { 8, 1016, 1024 }, { 9, 1017, 1024 }, { 9, 1018, 1024 }, { 10, 1019, 1024 }, { 9, 1020, 1024 }, { 10, 1021, 1024 }, { 10, 1022, 1024 }, { 11, 1023, 1024 }, #if FP_LUT > 11 { 1, 0, 0 }, { 2, 1, 2048 }, { 2, 2, 2048 }, { 3, 3, 2048 }, { 2, 4, 2048 }, { 3, 5, 2048 }, { 3, 6, 2048 }, { 4, 7, 2048 }, { 2, 8, 2048 }, { 3, 9, 2048 }, { 3, 10, 2048 }, { 4, 11, 2048 }, { 3, 12, 2048 }, { 4, 13, 2048 }, { 4, 14, 2048 }, { 5, 15, 2048 }, { 2, 16, 2048 }, { 3, 17, 2048 }, { 3, 18, 2048 }, { 4, 19, 2048 }, { 3, 20, 2048 }, { 4, 21, 2048 }, { 4, 22, 2048 }, { 5, 23, 2048 }, { 3, 24, 2048 }, { 4, 25, 2048 }, { 4, 26, 2048 }, { 5, 27, 2048 }, { 4, 28, 2048 }, { 5, 29, 2048 }, { 5, 30, 2048 }, { 6, 31, 2048 }, { 2, 32, 2048 }, { 3, 33, 2048 }, { 3, 34, 2048 }, { 4, 35, 2048 }, { 3, 36, 2048 }, { 4, 37, 2048 }, { 4, 38, 2048 }, { 5, 39, 2048 }, { 3, 40, 2048 }, { 4, 41, 2048 }, { 4, 42, 2048 }, { 5, 43, 2048 }, { 4, 44, 2048 }, { 5, 45, 2048 }, { 5, 46, 2048 }, { 6, 47, 2048 }, { 3, 48, 2048 }, { 4, 49, 2048 }, { 4, 50, 2048 }, { 5, 51, 2048 }, { 4, 52, 2048 }, { 5, 53, 2048 }, { 5, 54, 2048 }, { 6, 55, 2048 }, { 4, 56, 2048 }, { 5, 57, 2048 }, { 5, 58, 2048 }, { 6, 59, 2048 }, { 5, 60, 2048 }, { 6, 61, 2048 }, { 6, 62, 2048 }, { 7, 63, 2048 }, { 2, 64, 2048 }, { 3, 65, 2048 }, { 3, 66, 2048 }, { 4, 67, 2048 }, { 3, 68, 2048 }, { 4, 69, 2048 }, { 4, 70, 2048 }, { 5, 71, 2048 }, { 3, 72, 2048 }, { 4, 73, 2048 }, { 4, 74, 2048 }, { 5, 75, 2048 }, { 4, 76, 2048 }, { 5, 77, 2048 }, { 5, 78, 2048 }, { 6, 79, 2048 }, { 3, 80, 2048 }, { 4, 81, 2048 }, { 4, 82, 2048 }, { 5, 83, 2048 }, { 4, 84, 2048 }, { 5, 85, 2048 }, { 5, 86, 2048 }, { 6, 87, 2048 }, { 4, 88, 2048 }, { 5, 89, 2048 }, { 5, 90, 2048 }, { 6, 91, 2048 }, { 5, 92, 2048 }, { 6, 93, 2048 }, { 6, 94, 2048 }, { 7, 95, 2048 }, { 3, 96, 2048 }, { 4, 97, 2048 }, { 4, 98, 2048 }, { 5, 99, 2048 }, { 4, 100, 2048 }, { 5, 101, 2048 }, { 5, 102, 2048 }, { 6, 103, 2048 }, { 4, 104, 2048 }, { 5, 105, 2048 }, { 5, 106, 2048 }, { 6, 107, 2048 }, { 5, 108, 2048 }, { 6, 109, 2048 }, { 6, 110, 2048 }, { 7, 111, 2048 }, { 4, 112, 2048 }, { 5, 113, 2048 }, { 5, 114, 2048 }, { 6, 115, 2048 }, { 5, 116, 2048 }, { 6, 117, 2048 }, { 6, 118, 2048 }, { 7, 119, 2048 }, { 5, 120, 2048 }, { 6, 121, 2048 }, { 6, 122, 2048 }, { 7, 123, 2048 }, { 6, 124, 2048 }, { 7, 125, 2048 }, { 7, 126, 2048 }, { 8, 127, 2048 }, { 2, 128, 2048 }, { 3, 129, 2048 }, { 3, 130, 2048 }, { 4, 131, 2048 }, { 3, 132, 2048 }, { 4, 133, 2048 }, { 4, 134, 2048 }, { 5, 135, 2048 }, { 3, 136, 2048 }, { 4, 137, 2048 }, { 4, 138, 2048 }, { 5, 139, 2048 }, { 4, 140, 2048 }, { 5, 141, 2048 }, { 5, 142, 2048 }, { 6, 143, 2048 }, { 3, 144, 2048 }, { 4, 145, 2048 }, { 4, 146, 2048 }, { 5, 147, 2048 }, { 4, 148, 2048 }, { 5, 149, 2048 }, { 5, 150, 2048 }, { 6, 151, 2048 }, { 4, 152, 2048 }, { 5, 153, 2048 }, { 5, 154, 2048 }, { 6, 155, 2048 }, { 5, 156, 2048 }, { 6, 157, 2048 }, { 6, 158, 2048 }, { 7, 159, 2048 }, { 3, 160, 2048 }, { 4, 161, 2048 }, { 4, 162, 2048 }, { 5, 163, 2048 }, { 4, 164, 2048 }, { 5, 165, 2048 }, { 5, 166, 2048 }, { 6, 167, 2048 }, { 4, 168, 2048 }, { 5, 169, 2048 }, { 5, 170, 2048 }, { 6, 171, 2048 }, { 5, 172, 2048 }, { 6, 173, 2048 }, { 6, 174, 2048 }, { 7, 175, 2048 }, { 4, 176, 2048 }, { 5, 177, 2048 }, { 5, 178, 2048 }, { 6, 179, 2048 }, { 5, 180, 2048 }, { 6, 181, 2048 }, { 6, 182, 2048 }, { 7, 183, 2048 }, { 5, 184, 2048 }, { 6, 185, 2048 }, { 6, 186, 2048 }, { 7, 187, 2048 }, { 6, 188, 2048 }, { 7, 189, 2048 }, { 7, 190, 2048 }, { 8, 191, 2048 }, { 3, 192, 2048 }, { 4, 193, 2048 }, { 4, 194, 2048 }, { 5, 195, 2048 }, { 4, 196, 2048 }, { 5, 197, 2048 }, { 5, 198, 2048 }, { 6, 199, 2048 }, { 4, 200, 2048 }, { 5, 201, 2048 }, { 5, 202, 2048 }, { 6, 203, 2048 }, { 5, 204, 2048 }, { 6, 205, 2048 }, { 6, 206, 2048 }, { 7, 207, 2048 }, { 4, 208, 2048 }, { 5, 209, 2048 }, { 5, 210, 2048 }, { 6, 211, 2048 }, { 5, 212, 2048 }, { 6, 213, 2048 }, { 6, 214, 2048 }, { 7, 215, 2048 }, { 5, 216, 2048 }, { 6, 217, 2048 }, { 6, 218, 2048 }, { 7, 219, 2048 }, { 6, 220, 2048 }, { 7, 221, 2048 }, { 7, 222, 2048 }, { 8, 223, 2048 }, { 4, 224, 2048 }, { 5, 225, 2048 }, { 5, 226, 2048 }, { 6, 227, 2048 }, { 5, 228, 2048 }, { 6, 229, 2048 }, { 6, 230, 2048 }, { 7, 231, 2048 }, { 5, 232, 2048 }, { 6, 233, 2048 }, { 6, 234, 2048 }, { 7, 235, 2048 }, { 6, 236, 2048 }, { 7, 237, 2048 }, { 7, 238, 2048 }, { 8, 239, 2048 }, { 5, 240, 2048 }, { 6, 241, 2048 }, { 6, 242, 2048 }, { 7, 243, 2048 }, { 6, 244, 2048 }, { 7, 245, 2048 }, { 7, 246, 2048 }, { 8, 247, 2048 }, { 6, 248, 2048 }, { 7, 249, 2048 }, { 7, 250, 2048 }, { 8, 251, 2048 }, { 7, 252, 2048 }, { 8, 253, 2048 }, { 8, 254, 2048 }, { 9, 255, 2048 }, { 2, 256, 2048 }, { 3, 257, 2048 }, { 3, 258, 2048 }, { 4, 259, 2048 }, { 3, 260, 2048 }, { 4, 261, 2048 }, { 4, 262, 2048 }, { 5, 263, 2048 }, { 3, 264, 2048 }, { 4, 265, 2048 }, { 4, 266, 2048 }, { 5, 267, 2048 }, { 4, 268, 2048 }, { 5, 269, 2048 }, { 5, 270, 2048 }, { 6, 271, 2048 }, { 3, 272, 2048 }, { 4, 273, 2048 }, { 4, 274, 2048 }, { 5, 275, 2048 }, { 4, 276, 2048 }, { 5, 277, 2048 }, { 5, 278, 2048 }, { 6, 279, 2048 }, { 4, 280, 2048 }, { 5, 281, 2048 }, { 5, 282, 2048 }, { 6, 283, 2048 }, { 5, 284, 2048 }, { 6, 285, 2048 }, { 6, 286, 2048 }, { 7, 287, 2048 }, { 3, 288, 2048 }, { 4, 289, 2048 }, { 4, 290, 2048 }, { 5, 291, 2048 }, { 4, 292, 2048 }, { 5, 293, 2048 }, { 5, 294, 2048 }, { 6, 295, 2048 }, { 4, 296, 2048 }, { 5, 297, 2048 }, { 5, 298, 2048 }, { 6, 299, 2048 }, { 5, 300, 2048 }, { 6, 301, 2048 }, { 6, 302, 2048 }, { 7, 303, 2048 }, { 4, 304, 2048 }, { 5, 305, 2048 }, { 5, 306, 2048 }, { 6, 307, 2048 }, { 5, 308, 2048 }, { 6, 309, 2048 }, { 6, 310, 2048 }, { 7, 311, 2048 }, { 5, 312, 2048 }, { 6, 313, 2048 }, { 6, 314, 2048 }, { 7, 315, 2048 }, { 6, 316, 2048 }, { 7, 317, 2048 }, { 7, 318, 2048 }, { 8, 319, 2048 }, { 3, 320, 2048 }, { 4, 321, 2048 }, { 4, 322, 2048 }, { 5, 323, 2048 }, { 4, 324, 2048 }, { 5, 325, 2048 }, { 5, 326, 2048 }, { 6, 327, 2048 }, { 4, 328, 2048 }, { 5, 329, 2048 }, { 5, 330, 2048 }, { 6, 331, 2048 }, { 5, 332, 2048 }, { 6, 333, 2048 }, { 6, 334, 2048 }, { 7, 335, 2048 }, { 4, 336, 2048 }, { 5, 337, 2048 }, { 5, 338, 2048 }, { 6, 339, 2048 }, { 5, 340, 2048 }, { 6, 341, 2048 }, { 6, 342, 2048 }, { 7, 343, 2048 }, { 5, 344, 2048 }, { 6, 345, 2048 }, { 6, 346, 2048 }, { 7, 347, 2048 }, { 6, 348, 2048 }, { 7, 349, 2048 }, { 7, 350, 2048 }, { 8, 351, 2048 }, { 4, 352, 2048 }, { 5, 353, 2048 }, { 5, 354, 2048 }, { 6, 355, 2048 }, { 5, 356, 2048 }, { 6, 357, 2048 }, { 6, 358, 2048 }, { 7, 359, 2048 }, { 5, 360, 2048 }, { 6, 361, 2048 }, { 6, 362, 2048 }, { 7, 363, 2048 }, { 6, 364, 2048 }, { 7, 365, 2048 }, { 7, 366, 2048 }, { 8, 367, 2048 }, { 5, 368, 2048 }, { 6, 369, 2048 }, { 6, 370, 2048 }, { 7, 371, 2048 }, { 6, 372, 2048 }, { 7, 373, 2048 }, { 7, 374, 2048 }, { 8, 375, 2048 }, { 6, 376, 2048 }, { 7, 377, 2048 }, { 7, 378, 2048 }, { 8, 379, 2048 }, { 7, 380, 2048 }, { 8, 381, 2048 }, { 8, 382, 2048 }, { 9, 383, 2048 }, { 3, 384, 2048 }, { 4, 385, 2048 }, { 4, 386, 2048 }, { 5, 387, 2048 }, { 4, 388, 2048 }, { 5, 389, 2048 }, { 5, 390, 2048 }, { 6, 391, 2048 }, { 4, 392, 2048 }, { 5, 393, 2048 }, { 5, 394, 2048 }, { 6, 395, 2048 }, { 5, 396, 2048 }, { 6, 397, 2048 }, { 6, 398, 2048 }, { 7, 399, 2048 }, { 4, 400, 2048 }, { 5, 401, 2048 }, { 5, 402, 2048 }, { 6, 403, 2048 }, { 5, 404, 2048 }, { 6, 405, 2048 }, { 6, 406, 2048 }, { 7, 407, 2048 }, { 5, 408, 2048 }, { 6, 409, 2048 }, { 6, 410, 2048 }, { 7, 411, 2048 }, { 6, 412, 2048 }, { 7, 413, 2048 }, { 7, 414, 2048 }, { 8, 415, 2048 }, { 4, 416, 2048 }, { 5, 417, 2048 }, { 5, 418, 2048 }, { 6, 419, 2048 }, { 5, 420, 2048 }, { 6, 421, 2048 }, { 6, 422, 2048 }, { 7, 423, 2048 }, { 5, 424, 2048 }, { 6, 425, 2048 }, { 6, 426, 2048 }, { 7, 427, 2048 }, { 6, 428, 2048 }, { 7, 429, 2048 }, { 7, 430, 2048 }, { 8, 431, 2048 }, { 5, 432, 2048 }, { 6, 433, 2048 }, { 6, 434, 2048 }, { 7, 435, 2048 }, { 6, 436, 2048 }, { 7, 437, 2048 }, { 7, 438, 2048 }, { 8, 439, 2048 }, { 6, 440, 2048 }, { 7, 441, 2048 }, { 7, 442, 2048 }, { 8, 443, 2048 }, { 7, 444, 2048 }, { 8, 445, 2048 }, { 8, 446, 2048 }, { 9, 447, 2048 }, { 4, 448, 2048 }, { 5, 449, 2048 }, { 5, 450, 2048 }, { 6, 451, 2048 }, { 5, 452, 2048 }, { 6, 453, 2048 }, { 6, 454, 2048 }, { 7, 455, 2048 }, { 5, 456, 2048 }, { 6, 457, 2048 }, { 6, 458, 2048 }, { 7, 459, 2048 }, { 6, 460, 2048 }, { 7, 461, 2048 }, { 7, 462, 2048 }, { 8, 463, 2048 }, { 5, 464, 2048 }, { 6, 465, 2048 }, { 6, 466, 2048 }, { 7, 467, 2048 }, { 6, 468, 2048 }, { 7, 469, 2048 }, { 7, 470, 2048 }, { 8, 471, 2048 }, { 6, 472, 2048 }, { 7, 473, 2048 }, { 7, 474, 2048 }, { 8, 475, 2048 }, { 7, 476, 2048 }, { 8, 477, 2048 }, { 8, 478, 2048 }, { 9, 479, 2048 }, { 5, 480, 2048 }, { 6, 481, 2048 }, { 6, 482, 2048 }, { 7, 483, 2048 }, { 6, 484, 2048 }, { 7, 485, 2048 }, { 7, 486, 2048 }, { 8, 487, 2048 }, { 6, 488, 2048 }, { 7, 489, 2048 }, { 7, 490, 2048 }, { 8, 491, 2048 }, { 7, 492, 2048 }, { 8, 493, 2048 }, { 8, 494, 2048 }, { 9, 495, 2048 }, { 6, 496, 2048 }, { 7, 497, 2048 }, { 7, 498, 2048 }, { 8, 499, 2048 }, { 7, 500, 2048 }, { 8, 501, 2048 }, { 8, 502, 2048 }, { 9, 503, 2048 }, { 7, 504, 2048 }, { 8, 505, 2048 }, { 8, 506, 2048 }, { 9, 507, 2048 }, { 8, 508, 2048 }, { 9, 509, 2048 }, { 9, 510, 2048 }, { 10, 511, 2048 }, { 2, 512, 2048 }, { 3, 513, 2048 }, { 3, 514, 2048 }, { 4, 515, 2048 }, { 3, 516, 2048 }, { 4, 517, 2048 }, { 4, 518, 2048 }, { 5, 519, 2048 }, { 3, 520, 2048 }, { 4, 521, 2048 }, { 4, 522, 2048 }, { 5, 523, 2048 }, { 4, 524, 2048 }, { 5, 525, 2048 }, { 5, 526, 2048 }, { 6, 527, 2048 }, { 3, 528, 2048 }, { 4, 529, 2048 }, { 4, 530, 2048 }, { 5, 531, 2048 }, { 4, 532, 2048 }, { 5, 533, 2048 }, { 5, 534, 2048 }, { 6, 535, 2048 }, { 4, 536, 2048 }, { 5, 537, 2048 }, { 5, 538, 2048 }, { 6, 539, 2048 }, { 5, 540, 2048 }, { 6, 541, 2048 }, { 6, 542, 2048 }, { 7, 543, 2048 }, { 3, 544, 2048 }, { 4, 545, 2048 }, { 4, 546, 2048 }, { 5, 547, 2048 }, { 4, 548, 2048 }, { 5, 549, 2048 }, { 5, 550, 2048 }, { 6, 551, 2048 }, { 4, 552, 2048 }, { 5, 553, 2048 }, { 5, 554, 2048 }, { 6, 555, 2048 }, { 5, 556, 2048 }, { 6, 557, 2048 }, { 6, 558, 2048 }, { 7, 559, 2048 }, { 4, 560, 2048 }, { 5, 561, 2048 }, { 5, 562, 2048 }, { 6, 563, 2048 }, { 5, 564, 2048 }, { 6, 565, 2048 }, { 6, 566, 2048 }, { 7, 567, 2048 }, { 5, 568, 2048 }, { 6, 569, 2048 }, { 6, 570, 2048 }, { 7, 571, 2048 }, { 6, 572, 2048 }, { 7, 573, 2048 }, { 7, 574, 2048 }, { 8, 575, 2048 }, { 3, 576, 2048 }, { 4, 577, 2048 }, { 4, 578, 2048 }, { 5, 579, 2048 }, { 4, 580, 2048 }, { 5, 581, 2048 }, { 5, 582, 2048 }, { 6, 583, 2048 }, { 4, 584, 2048 }, { 5, 585, 2048 }, { 5, 586, 2048 }, { 6, 587, 2048 }, { 5, 588, 2048 }, { 6, 589, 2048 }, { 6, 590, 2048 }, { 7, 591, 2048 }, { 4, 592, 2048 }, { 5, 593, 2048 }, { 5, 594, 2048 }, { 6, 595, 2048 }, { 5, 596, 2048 }, { 6, 597, 2048 }, { 6, 598, 2048 }, { 7, 599, 2048 }, { 5, 600, 2048 }, { 6, 601, 2048 }, { 6, 602, 2048 }, { 7, 603, 2048 }, { 6, 604, 2048 }, { 7, 605, 2048 }, { 7, 606, 2048 }, { 8, 607, 2048 }, { 4, 608, 2048 }, { 5, 609, 2048 }, { 5, 610, 2048 }, { 6, 611, 2048 }, { 5, 612, 2048 }, { 6, 613, 2048 }, { 6, 614, 2048 }, { 7, 615, 2048 }, { 5, 616, 2048 }, { 6, 617, 2048 }, { 6, 618, 2048 }, { 7, 619, 2048 }, { 6, 620, 2048 }, { 7, 621, 2048 }, { 7, 622, 2048 }, { 8, 623, 2048 }, { 5, 624, 2048 }, { 6, 625, 2048 }, { 6, 626, 2048 }, { 7, 627, 2048 }, { 6, 628, 2048 }, { 7, 629, 2048 }, { 7, 630, 2048 }, { 8, 631, 2048 }, { 6, 632, 2048 }, { 7, 633, 2048 }, { 7, 634, 2048 }, { 8, 635, 2048 }, { 7, 636, 2048 }, { 8, 637, 2048 }, { 8, 638, 2048 }, { 9, 639, 2048 }, { 3, 640, 2048 }, { 4, 641, 2048 }, { 4, 642, 2048 }, { 5, 643, 2048 }, { 4, 644, 2048 }, { 5, 645, 2048 }, { 5, 646, 2048 }, { 6, 647, 2048 }, { 4, 648, 2048 }, { 5, 649, 2048 }, { 5, 650, 2048 }, { 6, 651, 2048 }, { 5, 652, 2048 }, { 6, 653, 2048 }, { 6, 654, 2048 }, { 7, 655, 2048 }, { 4, 656, 2048 }, { 5, 657, 2048 }, { 5, 658, 2048 }, { 6, 659, 2048 }, { 5, 660, 2048 }, { 6, 661, 2048 }, { 6, 662, 2048 }, { 7, 663, 2048 }, { 5, 664, 2048 }, { 6, 665, 2048 }, { 6, 666, 2048 }, { 7, 667, 2048 }, { 6, 668, 2048 }, { 7, 669, 2048 }, { 7, 670, 2048 }, { 8, 671, 2048 }, { 4, 672, 2048 }, { 5, 673, 2048 }, { 5, 674, 2048 }, { 6, 675, 2048 }, { 5, 676, 2048 }, { 6, 677, 2048 }, { 6, 678, 2048 }, { 7, 679, 2048 }, { 5, 680, 2048 }, { 6, 681, 2048 }, { 6, 682, 2048 }, { 7, 683, 2048 }, { 6, 684, 2048 }, { 7, 685, 2048 }, { 7, 686, 2048 }, { 8, 687, 2048 }, { 5, 688, 2048 }, { 6, 689, 2048 }, { 6, 690, 2048 }, { 7, 691, 2048 }, { 6, 692, 2048 }, { 7, 693, 2048 }, { 7, 694, 2048 }, { 8, 695, 2048 }, { 6, 696, 2048 }, { 7, 697, 2048 }, { 7, 698, 2048 }, { 8, 699, 2048 }, { 7, 700, 2048 }, { 8, 701, 2048 }, { 8, 702, 2048 }, { 9, 703, 2048 }, { 4, 704, 2048 }, { 5, 705, 2048 }, { 5, 706, 2048 }, { 6, 707, 2048 }, { 5, 708, 2048 }, { 6, 709, 2048 }, { 6, 710, 2048 }, { 7, 711, 2048 }, { 5, 712, 2048 }, { 6, 713, 2048 }, { 6, 714, 2048 }, { 7, 715, 2048 }, { 6, 716, 2048 }, { 7, 717, 2048 }, { 7, 718, 2048 }, { 8, 719, 2048 }, { 5, 720, 2048 }, { 6, 721, 2048 }, { 6, 722, 2048 }, { 7, 723, 2048 }, { 6, 724, 2048 }, { 7, 725, 2048 }, { 7, 726, 2048 }, { 8, 727, 2048 }, { 6, 728, 2048 }, { 7, 729, 2048 }, { 7, 730, 2048 }, { 8, 731, 2048 }, { 7, 732, 2048 }, { 8, 733, 2048 }, { 8, 734, 2048 }, { 9, 735, 2048 }, { 5, 736, 2048 }, { 6, 737, 2048 }, { 6, 738, 2048 }, { 7, 739, 2048 }, { 6, 740, 2048 }, { 7, 741, 2048 }, { 7, 742, 2048 }, { 8, 743, 2048 }, { 6, 744, 2048 }, { 7, 745, 2048 }, { 7, 746, 2048 }, { 8, 747, 2048 }, { 7, 748, 2048 }, { 8, 749, 2048 }, { 8, 750, 2048 }, { 9, 751, 2048 }, { 6, 752, 2048 }, { 7, 753, 2048 }, { 7, 754, 2048 }, { 8, 755, 2048 }, { 7, 756, 2048 }, { 8, 757, 2048 }, { 8, 758, 2048 }, { 9, 759, 2048 }, { 7, 760, 2048 }, { 8, 761, 2048 }, { 8, 762, 2048 }, { 9, 763, 2048 }, { 8, 764, 2048 }, { 9, 765, 2048 }, { 9, 766, 2048 }, { 10, 767, 2048 }, { 3, 768, 2048 }, { 4, 769, 2048 }, { 4, 770, 2048 }, { 5, 771, 2048 }, { 4, 772, 2048 }, { 5, 773, 2048 }, { 5, 774, 2048 }, { 6, 775, 2048 }, { 4, 776, 2048 }, { 5, 777, 2048 }, { 5, 778, 2048 }, { 6, 779, 2048 }, { 5, 780, 2048 }, { 6, 781, 2048 }, { 6, 782, 2048 }, { 7, 783, 2048 }, { 4, 784, 2048 }, { 5, 785, 2048 }, { 5, 786, 2048 }, { 6, 787, 2048 }, { 5, 788, 2048 }, { 6, 789, 2048 }, { 6, 790, 2048 }, { 7, 791, 2048 }, { 5, 792, 2048 }, { 6, 793, 2048 }, { 6, 794, 2048 }, { 7, 795, 2048 }, { 6, 796, 2048 }, { 7, 797, 2048 }, { 7, 798, 2048 }, { 8, 799, 2048 }, { 4, 800, 2048 }, { 5, 801, 2048 }, { 5, 802, 2048 }, { 6, 803, 2048 }, { 5, 804, 2048 }, { 6, 805, 2048 }, { 6, 806, 2048 }, { 7, 807, 2048 }, { 5, 808, 2048 }, { 6, 809, 2048 }, { 6, 810, 2048 }, { 7, 811, 2048 }, { 6, 812, 2048 }, { 7, 813, 2048 }, { 7, 814, 2048 }, { 8, 815, 2048 }, { 5, 816, 2048 }, { 6, 817, 2048 }, { 6, 818, 2048 }, { 7, 819, 2048 }, { 6, 820, 2048 }, { 7, 821, 2048 }, { 7, 822, 2048 }, { 8, 823, 2048 }, { 6, 824, 2048 }, { 7, 825, 2048 }, { 7, 826, 2048 }, { 8, 827, 2048 }, { 7, 828, 2048 }, { 8, 829, 2048 }, { 8, 830, 2048 }, { 9, 831, 2048 }, { 4, 832, 2048 }, { 5, 833, 2048 }, { 5, 834, 2048 }, { 6, 835, 2048 }, { 5, 836, 2048 }, { 6, 837, 2048 }, { 6, 838, 2048 }, { 7, 839, 2048 }, { 5, 840, 2048 }, { 6, 841, 2048 }, { 6, 842, 2048 }, { 7, 843, 2048 }, { 6, 844, 2048 }, { 7, 845, 2048 }, { 7, 846, 2048 }, { 8, 847, 2048 }, { 5, 848, 2048 }, { 6, 849, 2048 }, { 6, 850, 2048 }, { 7, 851, 2048 }, { 6, 852, 2048 }, { 7, 853, 2048 }, { 7, 854, 2048 }, { 8, 855, 2048 }, { 6, 856, 2048 }, { 7, 857, 2048 }, { 7, 858, 2048 }, { 8, 859, 2048 }, { 7, 860, 2048 }, { 8, 861, 2048 }, { 8, 862, 2048 }, { 9, 863, 2048 }, { 5, 864, 2048 }, { 6, 865, 2048 }, { 6, 866, 2048 }, { 7, 867, 2048 }, { 6, 868, 2048 }, { 7, 869, 2048 }, { 7, 870, 2048 }, { 8, 871, 2048 }, { 6, 872, 2048 }, { 7, 873, 2048 }, { 7, 874, 2048 }, { 8, 875, 2048 }, { 7, 876, 2048 }, { 8, 877, 2048 }, { 8, 878, 2048 }, { 9, 879, 2048 }, { 6, 880, 2048 }, { 7, 881, 2048 }, { 7, 882, 2048 }, { 8, 883, 2048 }, { 7, 884, 2048 }, { 8, 885, 2048 }, { 8, 886, 2048 }, { 9, 887, 2048 }, { 7, 888, 2048 }, { 8, 889, 2048 }, { 8, 890, 2048 }, { 9, 891, 2048 }, { 8, 892, 2048 }, { 9, 893, 2048 }, { 9, 894, 2048 }, { 10, 895, 2048 }, { 4, 896, 2048 }, { 5, 897, 2048 }, { 5, 898, 2048 }, { 6, 899, 2048 }, { 5, 900, 2048 }, { 6, 901, 2048 }, { 6, 902, 2048 }, { 7, 903, 2048 }, { 5, 904, 2048 }, { 6, 905, 2048 }, { 6, 906, 2048 }, { 7, 907, 2048 }, { 6, 908, 2048 }, { 7, 909, 2048 }, { 7, 910, 2048 }, { 8, 911, 2048 }, { 5, 912, 2048 }, { 6, 913, 2048 }, { 6, 914, 2048 }, { 7, 915, 2048 }, { 6, 916, 2048 }, { 7, 917, 2048 }, { 7, 918, 2048 }, { 8, 919, 2048 }, { 6, 920, 2048 }, { 7, 921, 2048 }, { 7, 922, 2048 }, { 8, 923, 2048 }, { 7, 924, 2048 }, { 8, 925, 2048 }, { 8, 926, 2048 }, { 9, 927, 2048 }, { 5, 928, 2048 }, { 6, 929, 2048 }, { 6, 930, 2048 }, { 7, 931, 2048 }, { 6, 932, 2048 }, { 7, 933, 2048 }, { 7, 934, 2048 }, { 8, 935, 2048 }, { 6, 936, 2048 }, { 7, 937, 2048 }, { 7, 938, 2048 }, { 8, 939, 2048 }, { 7, 940, 2048 }, { 8, 941, 2048 }, { 8, 942, 2048 }, { 9, 943, 2048 }, { 6, 944, 2048 }, { 7, 945, 2048 }, { 7, 946, 2048 }, { 8, 947, 2048 }, { 7, 948, 2048 }, { 8, 949, 2048 }, { 8, 950, 2048 }, { 9, 951, 2048 }, { 7, 952, 2048 }, { 8, 953, 2048 }, { 8, 954, 2048 }, { 9, 955, 2048 }, { 8, 956, 2048 }, { 9, 957, 2048 }, { 9, 958, 2048 }, { 10, 959, 2048 }, { 5, 960, 2048 }, { 6, 961, 2048 }, { 6, 962, 2048 }, { 7, 963, 2048 }, { 6, 964, 2048 }, { 7, 965, 2048 }, { 7, 966, 2048 }, { 8, 967, 2048 }, { 6, 968, 2048 }, { 7, 969, 2048 }, { 7, 970, 2048 }, { 8, 971, 2048 }, { 7, 972, 2048 }, { 8, 973, 2048 }, { 8, 974, 2048 }, { 9, 975, 2048 }, { 6, 976, 2048 }, { 7, 977, 2048 }, { 7, 978, 2048 }, { 8, 979, 2048 }, { 7, 980, 2048 }, { 8, 981, 2048 }, { 8, 982, 2048 }, { 9, 983, 2048 }, { 7, 984, 2048 }, { 8, 985, 2048 }, { 8, 986, 2048 }, { 9, 987, 2048 }, { 8, 988, 2048 }, { 9, 989, 2048 }, { 9, 990, 2048 }, { 10, 991, 2048 }, { 6, 992, 2048 }, { 7, 993, 2048 }, { 7, 994, 2048 }, { 8, 995, 2048 }, { 7, 996, 2048 }, { 8, 997, 2048 }, { 8, 998, 2048 }, { 9, 999, 2048 }, { 7, 1000, 2048 }, { 8, 1001, 2048 }, { 8, 1002, 2048 }, { 9, 1003, 2048 }, { 8, 1004, 2048 }, { 9, 1005, 2048 }, { 9, 1006, 2048 }, { 10, 1007, 2048 }, { 7, 1008, 2048 }, { 8, 1009, 2048 }, { 8, 1010, 2048 }, { 9, 1011, 2048 }, { 8, 1012, 2048 }, { 9, 1013, 2048 }, { 9, 1014, 2048 }, { 10, 1015, 2048 }, { 8, 1016, 2048 }, { 9, 1017, 2048 }, { 9, 1018, 2048 }, { 10, 1019, 2048 }, { 9, 1020, 2048 }, { 10, 1021, 2048 }, { 10, 1022, 2048 }, { 11, 1023, 2048 }, { 2, 1024, 2048 }, { 3, 1025, 2048 }, { 3, 1026, 2048 }, { 4, 1027, 2048 }, { 3, 1028, 2048 }, { 4, 1029, 2048 }, { 4, 1030, 2048 }, { 5, 1031, 2048 }, { 3, 1032, 2048 }, { 4, 1033, 2048 }, { 4, 1034, 2048 }, { 5, 1035, 2048 }, { 4, 1036, 2048 }, { 5, 1037, 2048 }, { 5, 1038, 2048 }, { 6, 1039, 2048 }, { 3, 1040, 2048 }, { 4, 1041, 2048 }, { 4, 1042, 2048 }, { 5, 1043, 2048 }, { 4, 1044, 2048 }, { 5, 1045, 2048 }, { 5, 1046, 2048 }, { 6, 1047, 2048 }, { 4, 1048, 2048 }, { 5, 1049, 2048 }, { 5, 1050, 2048 }, { 6, 1051, 2048 }, { 5, 1052, 2048 }, { 6, 1053, 2048 }, { 6, 1054, 2048 }, { 7, 1055, 2048 }, { 3, 1056, 2048 }, { 4, 1057, 2048 }, { 4, 1058, 2048 }, { 5, 1059, 2048 }, { 4, 1060, 2048 }, { 5, 1061, 2048 }, { 5, 1062, 2048 }, { 6, 1063, 2048 }, { 4, 1064, 2048 }, { 5, 1065, 2048 }, { 5, 1066, 2048 }, { 6, 1067, 2048 }, { 5, 1068, 2048 }, { 6, 1069, 2048 }, { 6, 1070, 2048 }, { 7, 1071, 2048 }, { 4, 1072, 2048 }, { 5, 1073, 2048 }, { 5, 1074, 2048 }, { 6, 1075, 2048 }, { 5, 1076, 2048 }, { 6, 1077, 2048 }, { 6, 1078, 2048 }, { 7, 1079, 2048 }, { 5, 1080, 2048 }, { 6, 1081, 2048 }, { 6, 1082, 2048 }, { 7, 1083, 2048 }, { 6, 1084, 2048 }, { 7, 1085, 2048 }, { 7, 1086, 2048 }, { 8, 1087, 2048 }, { 3, 1088, 2048 }, { 4, 1089, 2048 }, { 4, 1090, 2048 }, { 5, 1091, 2048 }, { 4, 1092, 2048 }, { 5, 1093, 2048 }, { 5, 1094, 2048 }, { 6, 1095, 2048 }, { 4, 1096, 2048 }, { 5, 1097, 2048 }, { 5, 1098, 2048 }, { 6, 1099, 2048 }, { 5, 1100, 2048 }, { 6, 1101, 2048 }, { 6, 1102, 2048 }, { 7, 1103, 2048 }, { 4, 1104, 2048 }, { 5, 1105, 2048 }, { 5, 1106, 2048 }, { 6, 1107, 2048 }, { 5, 1108, 2048 }, { 6, 1109, 2048 }, { 6, 1110, 2048 }, { 7, 1111, 2048 }, { 5, 1112, 2048 }, { 6, 1113, 2048 }, { 6, 1114, 2048 }, { 7, 1115, 2048 }, { 6, 1116, 2048 }, { 7, 1117, 2048 }, { 7, 1118, 2048 }, { 8, 1119, 2048 }, { 4, 1120, 2048 }, { 5, 1121, 2048 }, { 5, 1122, 2048 }, { 6, 1123, 2048 }, { 5, 1124, 2048 }, { 6, 1125, 2048 }, { 6, 1126, 2048 }, { 7, 1127, 2048 }, { 5, 1128, 2048 }, { 6, 1129, 2048 }, { 6, 1130, 2048 }, { 7, 1131, 2048 }, { 6, 1132, 2048 }, { 7, 1133, 2048 }, { 7, 1134, 2048 }, { 8, 1135, 2048 }, { 5, 1136, 2048 }, { 6, 1137, 2048 }, { 6, 1138, 2048 }, { 7, 1139, 2048 }, { 6, 1140, 2048 }, { 7, 1141, 2048 }, { 7, 1142, 2048 }, { 8, 1143, 2048 }, { 6, 1144, 2048 }, { 7, 1145, 2048 }, { 7, 1146, 2048 }, { 8, 1147, 2048 }, { 7, 1148, 2048 }, { 8, 1149, 2048 }, { 8, 1150, 2048 }, { 9, 1151, 2048 }, { 3, 1152, 2048 }, { 4, 1153, 2048 }, { 4, 1154, 2048 }, { 5, 1155, 2048 }, { 4, 1156, 2048 }, { 5, 1157, 2048 }, { 5, 1158, 2048 }, { 6, 1159, 2048 }, { 4, 1160, 2048 }, { 5, 1161, 2048 }, { 5, 1162, 2048 }, { 6, 1163, 2048 }, { 5, 1164, 2048 }, { 6, 1165, 2048 }, { 6, 1166, 2048 }, { 7, 1167, 2048 }, { 4, 1168, 2048 }, { 5, 1169, 2048 }, { 5, 1170, 2048 }, { 6, 1171, 2048 }, { 5, 1172, 2048 }, { 6, 1173, 2048 }, { 6, 1174, 2048 }, { 7, 1175, 2048 }, { 5, 1176, 2048 }, { 6, 1177, 2048 }, { 6, 1178, 2048 }, { 7, 1179, 2048 }, { 6, 1180, 2048 }, { 7, 1181, 2048 }, { 7, 1182, 2048 }, { 8, 1183, 2048 }, { 4, 1184, 2048 }, { 5, 1185, 2048 }, { 5, 1186, 2048 }, { 6, 1187, 2048 }, { 5, 1188, 2048 }, { 6, 1189, 2048 }, { 6, 1190, 2048 }, { 7, 1191, 2048 }, { 5, 1192, 2048 }, { 6, 1193, 2048 }, { 6, 1194, 2048 }, { 7, 1195, 2048 }, { 6, 1196, 2048 }, { 7, 1197, 2048 }, { 7, 1198, 2048 }, { 8, 1199, 2048 }, { 5, 1200, 2048 }, { 6, 1201, 2048 }, { 6, 1202, 2048 }, { 7, 1203, 2048 }, { 6, 1204, 2048 }, { 7, 1205, 2048 }, { 7, 1206, 2048 }, { 8, 1207, 2048 }, { 6, 1208, 2048 }, { 7, 1209, 2048 }, { 7, 1210, 2048 }, { 8, 1211, 2048 }, { 7, 1212, 2048 }, { 8, 1213, 2048 }, { 8, 1214, 2048 }, { 9, 1215, 2048 }, { 4, 1216, 2048 }, { 5, 1217, 2048 }, { 5, 1218, 2048 }, { 6, 1219, 2048 }, { 5, 1220, 2048 }, { 6, 1221, 2048 }, { 6, 1222, 2048 }, { 7, 1223, 2048 }, { 5, 1224, 2048 }, { 6, 1225, 2048 }, { 6, 1226, 2048 }, { 7, 1227, 2048 }, { 6, 1228, 2048 }, { 7, 1229, 2048 }, { 7, 1230, 2048 }, { 8, 1231, 2048 }, { 5, 1232, 2048 }, { 6, 1233, 2048 }, { 6, 1234, 2048 }, { 7, 1235, 2048 }, { 6, 1236, 2048 }, { 7, 1237, 2048 }, { 7, 1238, 2048 }, { 8, 1239, 2048 }, { 6, 1240, 2048 }, { 7, 1241, 2048 }, { 7, 1242, 2048 }, { 8, 1243, 2048 }, { 7, 1244, 2048 }, { 8, 1245, 2048 }, { 8, 1246, 2048 }, { 9, 1247, 2048 }, { 5, 1248, 2048 }, { 6, 1249, 2048 }, { 6, 1250, 2048 }, { 7, 1251, 2048 }, { 6, 1252, 2048 }, { 7, 1253, 2048 }, { 7, 1254, 2048 }, { 8, 1255, 2048 }, { 6, 1256, 2048 }, { 7, 1257, 2048 }, { 7, 1258, 2048 }, { 8, 1259, 2048 }, { 7, 1260, 2048 }, { 8, 1261, 2048 }, { 8, 1262, 2048 }, { 9, 1263, 2048 }, { 6, 1264, 2048 }, { 7, 1265, 2048 }, { 7, 1266, 2048 }, { 8, 1267, 2048 }, { 7, 1268, 2048 }, { 8, 1269, 2048 }, { 8, 1270, 2048 }, { 9, 1271, 2048 }, { 7, 1272, 2048 }, { 8, 1273, 2048 }, { 8, 1274, 2048 }, { 9, 1275, 2048 }, { 8, 1276, 2048 }, { 9, 1277, 2048 }, { 9, 1278, 2048 }, { 10, 1279, 2048 }, { 3, 1280, 2048 }, { 4, 1281, 2048 }, { 4, 1282, 2048 }, { 5, 1283, 2048 }, { 4, 1284, 2048 }, { 5, 1285, 2048 }, { 5, 1286, 2048 }, { 6, 1287, 2048 }, { 4, 1288, 2048 }, { 5, 1289, 2048 }, { 5, 1290, 2048 }, { 6, 1291, 2048 }, { 5, 1292, 2048 }, { 6, 1293, 2048 }, { 6, 1294, 2048 }, { 7, 1295, 2048 }, { 4, 1296, 2048 }, { 5, 1297, 2048 }, { 5, 1298, 2048 }, { 6, 1299, 2048 }, { 5, 1300, 2048 }, { 6, 1301, 2048 }, { 6, 1302, 2048 }, { 7, 1303, 2048 }, { 5, 1304, 2048 }, { 6, 1305, 2048 }, { 6, 1306, 2048 }, { 7, 1307, 2048 }, { 6, 1308, 2048 }, { 7, 1309, 2048 }, { 7, 1310, 2048 }, { 8, 1311, 2048 }, { 4, 1312, 2048 }, { 5, 1313, 2048 }, { 5, 1314, 2048 }, { 6, 1315, 2048 }, { 5, 1316, 2048 }, { 6, 1317, 2048 }, { 6, 1318, 2048 }, { 7, 1319, 2048 }, { 5, 1320, 2048 }, { 6, 1321, 2048 }, { 6, 1322, 2048 }, { 7, 1323, 2048 }, { 6, 1324, 2048 }, { 7, 1325, 2048 }, { 7, 1326, 2048 }, { 8, 1327, 2048 }, { 5, 1328, 2048 }, { 6, 1329, 2048 }, { 6, 1330, 2048 }, { 7, 1331, 2048 }, { 6, 1332, 2048 }, { 7, 1333, 2048 }, { 7, 1334, 2048 }, { 8, 1335, 2048 }, { 6, 1336, 2048 }, { 7, 1337, 2048 }, { 7, 1338, 2048 }, { 8, 1339, 2048 }, { 7, 1340, 2048 }, { 8, 1341, 2048 }, { 8, 1342, 2048 }, { 9, 1343, 2048 }, { 4, 1344, 2048 }, { 5, 1345, 2048 }, { 5, 1346, 2048 }, { 6, 1347, 2048 }, { 5, 1348, 2048 }, { 6, 1349, 2048 }, { 6, 1350, 2048 }, { 7, 1351, 2048 }, { 5, 1352, 2048 }, { 6, 1353, 2048 }, { 6, 1354, 2048 }, { 7, 1355, 2048 }, { 6, 1356, 2048 }, { 7, 1357, 2048 }, { 7, 1358, 2048 }, { 8, 1359, 2048 }, { 5, 1360, 2048 }, { 6, 1361, 2048 }, { 6, 1362, 2048 }, { 7, 1363, 2048 }, { 6, 1364, 2048 }, { 7, 1365, 2048 }, { 7, 1366, 2048 }, { 8, 1367, 2048 }, { 6, 1368, 2048 }, { 7, 1369, 2048 }, { 7, 1370, 2048 }, { 8, 1371, 2048 }, { 7, 1372, 2048 }, { 8, 1373, 2048 }, { 8, 1374, 2048 }, { 9, 1375, 2048 }, { 5, 1376, 2048 }, { 6, 1377, 2048 }, { 6, 1378, 2048 }, { 7, 1379, 2048 }, { 6, 1380, 2048 }, { 7, 1381, 2048 }, { 7, 1382, 2048 }, { 8, 1383, 2048 }, { 6, 1384, 2048 }, { 7, 1385, 2048 }, { 7, 1386, 2048 }, { 8, 1387, 2048 }, { 7, 1388, 2048 }, { 8, 1389, 2048 }, { 8, 1390, 2048 }, { 9, 1391, 2048 }, { 6, 1392, 2048 }, { 7, 1393, 2048 }, { 7, 1394, 2048 }, { 8, 1395, 2048 }, { 7, 1396, 2048 }, { 8, 1397, 2048 }, { 8, 1398, 2048 }, { 9, 1399, 2048 }, { 7, 1400, 2048 }, { 8, 1401, 2048 }, { 8, 1402, 2048 }, { 9, 1403, 2048 }, { 8, 1404, 2048 }, { 9, 1405, 2048 }, { 9, 1406, 2048 }, { 10, 1407, 2048 }, { 4, 1408, 2048 }, { 5, 1409, 2048 }, { 5, 1410, 2048 }, { 6, 1411, 2048 }, { 5, 1412, 2048 }, { 6, 1413, 2048 }, { 6, 1414, 2048 }, { 7, 1415, 2048 }, { 5, 1416, 2048 }, { 6, 1417, 2048 }, { 6, 1418, 2048 }, { 7, 1419, 2048 }, { 6, 1420, 2048 }, { 7, 1421, 2048 }, { 7, 1422, 2048 }, { 8, 1423, 2048 }, { 5, 1424, 2048 }, { 6, 1425, 2048 }, { 6, 1426, 2048 }, { 7, 1427, 2048 }, { 6, 1428, 2048 }, { 7, 1429, 2048 }, { 7, 1430, 2048 }, { 8, 1431, 2048 }, { 6, 1432, 2048 }, { 7, 1433, 2048 }, { 7, 1434, 2048 }, { 8, 1435, 2048 }, { 7, 1436, 2048 }, { 8, 1437, 2048 }, { 8, 1438, 2048 }, { 9, 1439, 2048 }, { 5, 1440, 2048 }, { 6, 1441, 2048 }, { 6, 1442, 2048 }, { 7, 1443, 2048 }, { 6, 1444, 2048 }, { 7, 1445, 2048 }, { 7, 1446, 2048 }, { 8, 1447, 2048 }, { 6, 1448, 2048 }, { 7, 1449, 2048 }, { 7, 1450, 2048 }, { 8, 1451, 2048 }, { 7, 1452, 2048 }, { 8, 1453, 2048 }, { 8, 1454, 2048 }, { 9, 1455, 2048 }, { 6, 1456, 2048 }, { 7, 1457, 2048 }, { 7, 1458, 2048 }, { 8, 1459, 2048 }, { 7, 1460, 2048 }, { 8, 1461, 2048 }, { 8, 1462, 2048 }, { 9, 1463, 2048 }, { 7, 1464, 2048 }, { 8, 1465, 2048 }, { 8, 1466, 2048 }, { 9, 1467, 2048 }, { 8, 1468, 2048 }, { 9, 1469, 2048 }, { 9, 1470, 2048 }, { 10, 1471, 2048 }, { 5, 1472, 2048 }, { 6, 1473, 2048 }, { 6, 1474, 2048 }, { 7, 1475, 2048 }, { 6, 1476, 2048 }, { 7, 1477, 2048 }, { 7, 1478, 2048 }, { 8, 1479, 2048 }, { 6, 1480, 2048 }, { 7, 1481, 2048 }, { 7, 1482, 2048 }, { 8, 1483, 2048 }, { 7, 1484, 2048 }, { 8, 1485, 2048 }, { 8, 1486, 2048 }, { 9, 1487, 2048 }, { 6, 1488, 2048 }, { 7, 1489, 2048 }, { 7, 1490, 2048 }, { 8, 1491, 2048 }, { 7, 1492, 2048 }, { 8, 1493, 2048 }, { 8, 1494, 2048 }, { 9, 1495, 2048 }, { 7, 1496, 2048 }, { 8, 1497, 2048 }, { 8, 1498, 2048 }, { 9, 1499, 2048 }, { 8, 1500, 2048 }, { 9, 1501, 2048 }, { 9, 1502, 2048 }, { 10, 1503, 2048 }, { 6, 1504, 2048 }, { 7, 1505, 2048 }, { 7, 1506, 2048 }, { 8, 1507, 2048 }, { 7, 1508, 2048 }, { 8, 1509, 2048 }, { 8, 1510, 2048 }, { 9, 1511, 2048 }, { 7, 1512, 2048 }, { 8, 1513, 2048 }, { 8, 1514, 2048 }, { 9, 1515, 2048 }, { 8, 1516, 2048 }, { 9, 1517, 2048 }, { 9, 1518, 2048 }, { 10, 1519, 2048 }, { 7, 1520, 2048 }, { 8, 1521, 2048 }, { 8, 1522, 2048 }, { 9, 1523, 2048 }, { 8, 1524, 2048 }, { 9, 1525, 2048 }, { 9, 1526, 2048 }, { 10, 1527, 2048 }, { 8, 1528, 2048 }, { 9, 1529, 2048 }, { 9, 1530, 2048 }, { 10, 1531, 2048 }, { 9, 1532, 2048 }, { 10, 1533, 2048 }, { 10, 1534, 2048 }, { 11, 1535, 2048 }, { 3, 1536, 2048 }, { 4, 1537, 2048 }, { 4, 1538, 2048 }, { 5, 1539, 2048 }, { 4, 1540, 2048 }, { 5, 1541, 2048 }, { 5, 1542, 2048 }, { 6, 1543, 2048 }, { 4, 1544, 2048 }, { 5, 1545, 2048 }, { 5, 1546, 2048 }, { 6, 1547, 2048 }, { 5, 1548, 2048 }, { 6, 1549, 2048 }, { 6, 1550, 2048 }, { 7, 1551, 2048 }, { 4, 1552, 2048 }, { 5, 1553, 2048 }, { 5, 1554, 2048 }, { 6, 1555, 2048 }, { 5, 1556, 2048 }, { 6, 1557, 2048 }, { 6, 1558, 2048 }, { 7, 1559, 2048 }, { 5, 1560, 2048 }, { 6, 1561, 2048 }, { 6, 1562, 2048 }, { 7, 1563, 2048 }, { 6, 1564, 2048 }, { 7, 1565, 2048 }, { 7, 1566, 2048 }, { 8, 1567, 2048 }, { 4, 1568, 2048 }, { 5, 1569, 2048 }, { 5, 1570, 2048 }, { 6, 1571, 2048 }, { 5, 1572, 2048 }, { 6, 1573, 2048 }, { 6, 1574, 2048 }, { 7, 1575, 2048 }, { 5, 1576, 2048 }, { 6, 1577, 2048 }, { 6, 1578, 2048 }, { 7, 1579, 2048 }, { 6, 1580, 2048 }, { 7, 1581, 2048 }, { 7, 1582, 2048 }, { 8, 1583, 2048 }, { 5, 1584, 2048 }, { 6, 1585, 2048 }, { 6, 1586, 2048 }, { 7, 1587, 2048 }, { 6, 1588, 2048 }, { 7, 1589, 2048 }, { 7, 1590, 2048 }, { 8, 1591, 2048 }, { 6, 1592, 2048 }, { 7, 1593, 2048 }, { 7, 1594, 2048 }, { 8, 1595, 2048 }, { 7, 1596, 2048 }, { 8, 1597, 2048 }, { 8, 1598, 2048 }, { 9, 1599, 2048 }, { 4, 1600, 2048 }, { 5, 1601, 2048 }, { 5, 1602, 2048 }, { 6, 1603, 2048 }, { 5, 1604, 2048 }, { 6, 1605, 2048 }, { 6, 1606, 2048 }, { 7, 1607, 2048 }, { 5, 1608, 2048 }, { 6, 1609, 2048 }, { 6, 1610, 2048 }, { 7, 1611, 2048 }, { 6, 1612, 2048 }, { 7, 1613, 2048 }, { 7, 1614, 2048 }, { 8, 1615, 2048 }, { 5, 1616, 2048 }, { 6, 1617, 2048 }, { 6, 1618, 2048 }, { 7, 1619, 2048 }, { 6, 1620, 2048 }, { 7, 1621, 2048 }, { 7, 1622, 2048 }, { 8, 1623, 2048 }, { 6, 1624, 2048 }, { 7, 1625, 2048 }, { 7, 1626, 2048 }, { 8, 1627, 2048 }, { 7, 1628, 2048 }, { 8, 1629, 2048 }, { 8, 1630, 2048 }, { 9, 1631, 2048 }, { 5, 1632, 2048 }, { 6, 1633, 2048 }, { 6, 1634, 2048 }, { 7, 1635, 2048 }, { 6, 1636, 2048 }, { 7, 1637, 2048 }, { 7, 1638, 2048 }, { 8, 1639, 2048 }, { 6, 1640, 2048 }, { 7, 1641, 2048 }, { 7, 1642, 2048 }, { 8, 1643, 2048 }, { 7, 1644, 2048 }, { 8, 1645, 2048 }, { 8, 1646, 2048 }, { 9, 1647, 2048 }, { 6, 1648, 2048 }, { 7, 1649, 2048 }, { 7, 1650, 2048 }, { 8, 1651, 2048 }, { 7, 1652, 2048 }, { 8, 1653, 2048 }, { 8, 1654, 2048 }, { 9, 1655, 2048 }, { 7, 1656, 2048 }, { 8, 1657, 2048 }, { 8, 1658, 2048 }, { 9, 1659, 2048 }, { 8, 1660, 2048 }, { 9, 1661, 2048 }, { 9, 1662, 2048 }, { 10, 1663, 2048 }, { 4, 1664, 2048 }, { 5, 1665, 2048 }, { 5, 1666, 2048 }, { 6, 1667, 2048 }, { 5, 1668, 2048 }, { 6, 1669, 2048 }, { 6, 1670, 2048 }, { 7, 1671, 2048 }, { 5, 1672, 2048 }, { 6, 1673, 2048 }, { 6, 1674, 2048 }, { 7, 1675, 2048 }, { 6, 1676, 2048 }, { 7, 1677, 2048 }, { 7, 1678, 2048 }, { 8, 1679, 2048 }, { 5, 1680, 2048 }, { 6, 1681, 2048 }, { 6, 1682, 2048 }, { 7, 1683, 2048 }, { 6, 1684, 2048 }, { 7, 1685, 2048 }, { 7, 1686, 2048 }, { 8, 1687, 2048 }, { 6, 1688, 2048 }, { 7, 1689, 2048 }, { 7, 1690, 2048 }, { 8, 1691, 2048 }, { 7, 1692, 2048 }, { 8, 1693, 2048 }, { 8, 1694, 2048 }, { 9, 1695, 2048 }, { 5, 1696, 2048 }, { 6, 1697, 2048 }, { 6, 1698, 2048 }, { 7, 1699, 2048 }, { 6, 1700, 2048 }, { 7, 1701, 2048 }, { 7, 1702, 2048 }, { 8, 1703, 2048 }, { 6, 1704, 2048 }, { 7, 1705, 2048 }, { 7, 1706, 2048 }, { 8, 1707, 2048 }, { 7, 1708, 2048 }, { 8, 1709, 2048 }, { 8, 1710, 2048 }, { 9, 1711, 2048 }, { 6, 1712, 2048 }, { 7, 1713, 2048 }, { 7, 1714, 2048 }, { 8, 1715, 2048 }, { 7, 1716, 2048 }, { 8, 1717, 2048 }, { 8, 1718, 2048 }, { 9, 1719, 2048 }, { 7, 1720, 2048 }, { 8, 1721, 2048 }, { 8, 1722, 2048 }, { 9, 1723, 2048 }, { 8, 1724, 2048 }, { 9, 1725, 2048 }, { 9, 1726, 2048 }, { 10, 1727, 2048 }, { 5, 1728, 2048 }, { 6, 1729, 2048 }, { 6, 1730, 2048 }, { 7, 1731, 2048 }, { 6, 1732, 2048 }, { 7, 1733, 2048 }, { 7, 1734, 2048 }, { 8, 1735, 2048 }, { 6, 1736, 2048 }, { 7, 1737, 2048 }, { 7, 1738, 2048 }, { 8, 1739, 2048 }, { 7, 1740, 2048 }, { 8, 1741, 2048 }, { 8, 1742, 2048 }, { 9, 1743, 2048 }, { 6, 1744, 2048 }, { 7, 1745, 2048 }, { 7, 1746, 2048 }, { 8, 1747, 2048 }, { 7, 1748, 2048 }, { 8, 1749, 2048 }, { 8, 1750, 2048 }, { 9, 1751, 2048 }, { 7, 1752, 2048 }, { 8, 1753, 2048 }, { 8, 1754, 2048 }, { 9, 1755, 2048 }, { 8, 1756, 2048 }, { 9, 1757, 2048 }, { 9, 1758, 2048 }, { 10, 1759, 2048 }, { 6, 1760, 2048 }, { 7, 1761, 2048 }, { 7, 1762, 2048 }, { 8, 1763, 2048 }, { 7, 1764, 2048 }, { 8, 1765, 2048 }, { 8, 1766, 2048 }, { 9, 1767, 2048 }, { 7, 1768, 2048 }, { 8, 1769, 2048 }, { 8, 1770, 2048 }, { 9, 1771, 2048 }, { 8, 1772, 2048 }, { 9, 1773, 2048 }, { 9, 1774, 2048 }, { 10, 1775, 2048 }, { 7, 1776, 2048 }, { 8, 1777, 2048 }, { 8, 1778, 2048 }, { 9, 1779, 2048 }, { 8, 1780, 2048 }, { 9, 1781, 2048 }, { 9, 1782, 2048 }, { 10, 1783, 2048 }, { 8, 1784, 2048 }, { 9, 1785, 2048 }, { 9, 1786, 2048 }, { 10, 1787, 2048 }, { 9, 1788, 2048 }, { 10, 1789, 2048 }, { 10, 1790, 2048 }, { 11, 1791, 2048 }, { 4, 1792, 2048 }, { 5, 1793, 2048 }, { 5, 1794, 2048 }, { 6, 1795, 2048 }, { 5, 1796, 2048 }, { 6, 1797, 2048 }, { 6, 1798, 2048 }, { 7, 1799, 2048 }, { 5, 1800, 2048 }, { 6, 1801, 2048 }, { 6, 1802, 2048 }, { 7, 1803, 2048 }, { 6, 1804, 2048 }, { 7, 1805, 2048 }, { 7, 1806, 2048 }, { 8, 1807, 2048 }, { 5, 1808, 2048 }, { 6, 1809, 2048 }, { 6, 1810, 2048 }, { 7, 1811, 2048 }, { 6, 1812, 2048 }, { 7, 1813, 2048 }, { 7, 1814, 2048 }, { 8, 1815, 2048 }, { 6, 1816, 2048 }, { 7, 1817, 2048 }, { 7, 1818, 2048 }, { 8, 1819, 2048 }, { 7, 1820, 2048 }, { 8, 1821, 2048 }, { 8, 1822, 2048 }, { 9, 1823, 2048 }, { 5, 1824, 2048 }, { 6, 1825, 2048 }, { 6, 1826, 2048 }, { 7, 1827, 2048 }, { 6, 1828, 2048 }, { 7, 1829, 2048 }, { 7, 1830, 2048 }, { 8, 1831, 2048 }, { 6, 1832, 2048 }, { 7, 1833, 2048 }, { 7, 1834, 2048 }, { 8, 1835, 2048 }, { 7, 1836, 2048 }, { 8, 1837, 2048 }, { 8, 1838, 2048 }, { 9, 1839, 2048 }, { 6, 1840, 2048 }, { 7, 1841, 2048 }, { 7, 1842, 2048 }, { 8, 1843, 2048 }, { 7, 1844, 2048 }, { 8, 1845, 2048 }, { 8, 1846, 2048 }, { 9, 1847, 2048 }, { 7, 1848, 2048 }, { 8, 1849, 2048 }, { 8, 1850, 2048 }, { 9, 1851, 2048 }, { 8, 1852, 2048 }, { 9, 1853, 2048 }, { 9, 1854, 2048 }, { 10, 1855, 2048 }, { 5, 1856, 2048 }, { 6, 1857, 2048 }, { 6, 1858, 2048 }, { 7, 1859, 2048 }, { 6, 1860, 2048 }, { 7, 1861, 2048 }, { 7, 1862, 2048 }, { 8, 1863, 2048 }, { 6, 1864, 2048 }, { 7, 1865, 2048 }, { 7, 1866, 2048 }, { 8, 1867, 2048 }, { 7, 1868, 2048 }, { 8, 1869, 2048 }, { 8, 1870, 2048 }, { 9, 1871, 2048 }, { 6, 1872, 2048 }, { 7, 1873, 2048 }, { 7, 1874, 2048 }, { 8, 1875, 2048 }, { 7, 1876, 2048 }, { 8, 1877, 2048 }, { 8, 1878, 2048 }, { 9, 1879, 2048 }, { 7, 1880, 2048 }, { 8, 1881, 2048 }, { 8, 1882, 2048 }, { 9, 1883, 2048 }, { 8, 1884, 2048 }, { 9, 1885, 2048 }, { 9, 1886, 2048 }, { 10, 1887, 2048 }, { 6, 1888, 2048 }, { 7, 1889, 2048 }, { 7, 1890, 2048 }, { 8, 1891, 2048 }, { 7, 1892, 2048 }, { 8, 1893, 2048 }, { 8, 1894, 2048 }, { 9, 1895, 2048 }, { 7, 1896, 2048 }, { 8, 1897, 2048 }, { 8, 1898, 2048 }, { 9, 1899, 2048 }, { 8, 1900, 2048 }, { 9, 1901, 2048 }, { 9, 1902, 2048 }, { 10, 1903, 2048 }, { 7, 1904, 2048 }, { 8, 1905, 2048 }, { 8, 1906, 2048 }, { 9, 1907, 2048 }, { 8, 1908, 2048 }, { 9, 1909, 2048 }, { 9, 1910, 2048 }, { 10, 1911, 2048 }, { 8, 1912, 2048 }, { 9, 1913, 2048 }, { 9, 1914, 2048 }, { 10, 1915, 2048 }, { 9, 1916, 2048 }, { 10, 1917, 2048 }, { 10, 1918, 2048 }, { 11, 1919, 2048 }, { 5, 1920, 2048 }, { 6, 1921, 2048 }, { 6, 1922, 2048 }, { 7, 1923, 2048 }, { 6, 1924, 2048 }, { 7, 1925, 2048 }, { 7, 1926, 2048 }, { 8, 1927, 2048 }, { 6, 1928, 2048 }, { 7, 1929, 2048 }, { 7, 1930, 2048 }, { 8, 1931, 2048 }, { 7, 1932, 2048 }, { 8, 1933, 2048 }, { 8, 1934, 2048 }, { 9, 1935, 2048 }, { 6, 1936, 2048 }, { 7, 1937, 2048 }, { 7, 1938, 2048 }, { 8, 1939, 2048 }, { 7, 1940, 2048 }, { 8, 1941, 2048 }, { 8, 1942, 2048 }, { 9, 1943, 2048 }, { 7, 1944, 2048 }, { 8, 1945, 2048 }, { 8, 1946, 2048 }, { 9, 1947, 2048 }, { 8, 1948, 2048 }, { 9, 1949, 2048 }, { 9, 1950, 2048 }, { 10, 1951, 2048 }, { 6, 1952, 2048 }, { 7, 1953, 2048 }, { 7, 1954, 2048 }, { 8, 1955, 2048 }, { 7, 1956, 2048 }, { 8, 1957, 2048 }, { 8, 1958, 2048 }, { 9, 1959, 2048 }, { 7, 1960, 2048 }, { 8, 1961, 2048 }, { 8, 1962, 2048 }, { 9, 1963, 2048 }, { 8, 1964, 2048 }, { 9, 1965, 2048 }, { 9, 1966, 2048 }, { 10, 1967, 2048 }, { 7, 1968, 2048 }, { 8, 1969, 2048 }, { 8, 1970, 2048 }, { 9, 1971, 2048 }, { 8, 1972, 2048 }, { 9, 1973, 2048 }, { 9, 1974, 2048 }, { 10, 1975, 2048 }, { 8, 1976, 2048 }, { 9, 1977, 2048 }, { 9, 1978, 2048 }, { 10, 1979, 2048 }, { 9, 1980, 2048 }, { 10, 1981, 2048 }, { 10, 1982, 2048 }, { 11, 1983, 2048 }, { 6, 1984, 2048 }, { 7, 1985, 2048 }, { 7, 1986, 2048 }, { 8, 1987, 2048 }, { 7, 1988, 2048 }, { 8, 1989, 2048 }, { 8, 1990, 2048 }, { 9, 1991, 2048 }, { 7, 1992, 2048 }, { 8, 1993, 2048 }, { 8, 1994, 2048 }, { 9, 1995, 2048 }, { 8, 1996, 2048 }, { 9, 1997, 2048 }, { 9, 1998, 2048 }, { 10, 1999, 2048 }, { 7, 2000, 2048 }, { 8, 2001, 2048 }, { 8, 2002, 2048 }, { 9, 2003, 2048 }, { 8, 2004, 2048 }, { 9, 2005, 2048 }, { 9, 2006, 2048 }, { 10, 2007, 2048 }, { 8, 2008, 2048 }, { 9, 2009, 2048 }, { 9, 2010, 2048 }, { 10, 2011, 2048 }, { 9, 2012, 2048 }, { 10, 2013, 2048 }, { 10, 2014, 2048 }, { 11, 2015, 2048 }, { 7, 2016, 2048 }, { 8, 2017, 2048 }, { 8, 2018, 2048 }, { 9, 2019, 2048 }, { 8, 2020, 2048 }, { 9, 2021, 2048 }, { 9, 2022, 2048 }, { 10, 2023, 2048 }, { 8, 2024, 2048 }, { 9, 2025, 2048 }, { 9, 2026, 2048 }, { 10, 2027, 2048 }, { 9, 2028, 2048 }, { 10, 2029, 2048 }, { 10, 2030, 2048 }, { 11, 2031, 2048 }, { 8, 2032, 2048 }, { 9, 2033, 2048 }, { 9, 2034, 2048 }, { 10, 2035, 2048 }, { 9, 2036, 2048 }, { 10, 2037, 2048 }, { 10, 2038, 2048 }, { 11, 2039, 2048 }, { 9, 2040, 2048 }, { 10, 2041, 2048 }, { 10, 2042, 2048 }, { 11, 2043, 2048 }, { 10, 2044, 2048 }, { 11, 2045, 2048 }, { 11, 2046, 2048 }, { 12, 2047, 2048 }, #endif #endif #endif #endif #endif #endif }; /* find a hole and free as required, return -1 if no hole found */ static int find_hole(void) { unsigned x; int y, z; for (z = -1, y = INT_MAX, x = 0; x < FP_ENTRIES; x++) { if (fp_cache[x].lru_count < y && fp_cache[x].lock == 0) { z = x; y = fp_cache[x].lru_count; } } /* decrease all */ for (x = 0; x < FP_ENTRIES; x++) { if (fp_cache[x].lru_count > 3) { --(fp_cache[x].lru_count); } } /* free entry z */ if (z >= 0 && fp_cache[z].g) { if (fp_cache[z].mu != NULL) { mp_clear(fp_cache[z].mu); fp_cache[z].mu = NULL; } ltc_ecc_del_point(fp_cache[z].g); fp_cache[z].g = NULL; for (x = 0; x < (1U<x, g->x) == LTC_MP_EQ && mp_cmp(fp_cache[x].g->y, g->y) == LTC_MP_EQ && mp_cmp(fp_cache[x].g->z, g->z) == LTC_MP_EQ) { break; } } if (x == FP_ENTRIES) { x = -1; } return x; } /* add a new base to the cache */ static int add_entry(int idx, ecc_point *g) { unsigned x, y; /* allocate base and LUT */ fp_cache[idx].g = ltc_ecc_new_point(); if (fp_cache[idx].g == NULL) { return CRYPT_MEM; } /* copy x and y */ if ((mp_copy(g->x, fp_cache[idx].g->x) != CRYPT_OK) || (mp_copy(g->y, fp_cache[idx].g->y) != CRYPT_OK) || (mp_copy(g->z, fp_cache[idx].g->z) != CRYPT_OK)) { ltc_ecc_del_point(fp_cache[idx].g); fp_cache[idx].g = NULL; return CRYPT_MEM; } for (x = 0; x < (1U<x, mu, modulus, fp_cache[idx].LUT[1]->x) != CRYPT_OK) || (mp_mulmod(fp_cache[idx].g->y, mu, modulus, fp_cache[idx].LUT[1]->y) != CRYPT_OK) || (mp_mulmod(fp_cache[idx].g->z, mu, modulus, fp_cache[idx].LUT[1]->z) != CRYPT_OK)) { goto ERR; } /* make all single bit entries */ for (x = 1; x < FP_LUT; x++) { if ((mp_copy(fp_cache[idx].LUT[1<<(x-1)]->x, fp_cache[idx].LUT[1<x) != CRYPT_OK) || (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->y, fp_cache[idx].LUT[1<y) != CRYPT_OK) || (mp_copy(fp_cache[idx].LUT[1<<(x-1)]->z, fp_cache[idx].LUT[1<z) != CRYPT_OK)) { goto ERR; } /* now double it bitlen/FP_LUT times */ for (y = 0; y < lut_gap; y++) { if ((err = ltc_mp.ecc_ptdbl(fp_cache[idx].LUT[1<z, modulus, mp)) != CRYPT_OK) { goto ERR; } /* invert it */ if ((err = mp_invmod(fp_cache[idx].LUT[x]->z, modulus, fp_cache[idx].LUT[x]->z)) != CRYPT_OK) { goto ERR; } /* now square it */ if ((err = mp_sqrmod(fp_cache[idx].LUT[x]->z, modulus, tmp)) != CRYPT_OK) { goto ERR; } /* fix x */ if ((err = mp_mulmod(fp_cache[idx].LUT[x]->x, tmp, modulus, fp_cache[idx].LUT[x]->x)) != CRYPT_OK) { goto ERR; } /* get 1/z^3 */ if ((err = mp_mulmod(tmp, fp_cache[idx].LUT[x]->z, modulus, tmp)) != CRYPT_OK) { goto ERR; } /* fix y */ if ((err = mp_mulmod(fp_cache[idx].LUT[x]->y, tmp, modulus, fp_cache[idx].LUT[x]->y)) != CRYPT_OK) { goto ERR; } /* free z */ mp_clear(fp_cache[idx].LUT[x]->z); fp_cache[idx].LUT[x]->z = NULL; } mp_clear(tmp); return CRYPT_OK; ERR: err = CRYPT_MEM; DONE: for (y = 0; y < (1U< mp_unsigned_bin_size(modulus)) { /* find order */ y = mp_unsigned_bin_size(modulus); for (x = 0; ltc_ecc_sets[x].size; x++) { if (y <= (unsigned)ltc_ecc_sets[x].size) break; } /* back off if we are on the 521 bit curve */ if (y == 66) --x; if ((err = mp_init(&order)) != CRYPT_OK) { return err; } if ((err = mp_read_radix(order, ltc_ecc_sets[x].order, 16)) != CRYPT_OK) { mp_clear(&order); return err; } /* k must be less than modulus */ if (mp_cmp(k, order) != LTC_MP_LT) { if ((err = mp_init(&tk)) != CRYPT_OK) { mp_clear(order); return err; } if ((err = mp_mod(k, order, tk)) != CRYPT_OK) { mp_clear(tk); mp_clear(order); return err; } } else { tk = k; } mp_clear(order); } else { tk = k; } /* get bitlen and round up to next multiple of FP_LUT */ bitlen = mp_unsigned_bin_size(modulus) << 3; x = bitlen % FP_LUT; if (x) { bitlen += FP_LUT - x; } lut_gap = bitlen / FP_LUT; /* get the k value */ if (mp_unsigned_bin_size(tk) > (sizeof(kb) - 2)) { if (tk != k) { mp_clear(tk); } return CRYPT_BUFFER_OVERFLOW; } /* store k */ zeromem(kb, sizeof(kb)); if ((err = mp_to_unsigned_bin(tk, kb)) != CRYPT_OK) { if (tk != k) { mp_clear(tk); } return err; } /* let's reverse kb so it's little endian */ x = 0; y = mp_unsigned_bin_size(tk) - 1; if (tk != k) { mp_clear(tk); } while ((unsigned)x < y) { z = kb[x]; kb[x] = kb[y]; kb[y] = z; ++x; --y; } /* at this point we can start, yipee */ first = 1; for (x = lut_gap-1; x >= 0; x--) { /* extract FP_LUT bits from kb spread out by lut_gap bits and offset by x bits from the start */ bitpos = x; for (y = z = 0; y < FP_LUT; y++) { z |= ((kb[bitpos>>3] >> (bitpos&7)) & 1) << y; bitpos += lut_gap; /* it's y*lut_gap + x, but here we can avoid the mult in each loop */ } /* double if not first */ if (!first) { if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { return err; } } /* add if not first, otherwise copy */ if (!first && z) { if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx].LUT[z], R, modulus, mp)) != CRYPT_OK) { return err; } } else if (z) { if ((mp_copy(fp_cache[idx].LUT[z]->x, R->x) != CRYPT_OK) || (mp_copy(fp_cache[idx].LUT[z]->y, R->y) != CRYPT_OK) || (mp_copy(fp_cache[idx].mu, R->z) != CRYPT_OK)) { return CRYPT_MEM; } first = 0; } } z = 0; zeromem(kb, sizeof(kb)); /* map R back from projective space */ if (map) { err = ltc_ecc_map(R, modulus, mp); } else { err = CRYPT_OK; } return err; } #ifdef LTC_ECC_SHAMIR /* perform a fixed point ECC mulmod */ static int accel_fp_mul2add(int idx1, int idx2, void *kA, void *kB, ecc_point *R, void *modulus, void *mp) { unsigned char kb[2][128]; int x; unsigned y, z, err, bitlen, bitpos, lut_gap, first, zA, zB; void *tka, *tkb, *order; /* if it's smaller than modulus we fine */ if (mp_unsigned_bin_size(kA) > mp_unsigned_bin_size(modulus)) { /* find order */ y = mp_unsigned_bin_size(modulus); for (x = 0; ltc_ecc_sets[x].size; x++) { if (y <= (unsigned)ltc_ecc_sets[x].size) break; } /* back off if we are on the 521 bit curve */ if (y == 66) --x; if ((err = mp_init(&order)) != CRYPT_OK) { return err; } if ((err = mp_read_radix(order, ltc_ecc_sets[x].order, 16)) != CRYPT_OK) { mp_clear(&order); return err; } /* kA must be less than modulus */ if (mp_cmp(kA, order) != LTC_MP_LT) { if ((err = mp_init(&tka)) != CRYPT_OK) { mp_clear(order); return err; } if ((err = mp_mod(kA, order, tka)) != CRYPT_OK) { mp_clear(tka); mp_clear(order); return err; } } else { tka = kA; } mp_clear(order); } else { tka = kA; } /* if it's smaller than modulus we fine */ if (mp_unsigned_bin_size(kB) > mp_unsigned_bin_size(modulus)) { /* find order */ y = mp_unsigned_bin_size(modulus); for (x = 0; ltc_ecc_sets[x].size; x++) { if (y <= (unsigned)ltc_ecc_sets[x].size) break; } /* back off if we are on the 521 bit curve */ if (y == 66) --x; if ((err = mp_init(&order)) != CRYPT_OK) { return err; } if ((err = mp_read_radix(order, ltc_ecc_sets[x].order, 16)) != CRYPT_OK) { mp_clear(&order); return err; } /* kB must be less than modulus */ if (mp_cmp(kB, order) != LTC_MP_LT) { if ((err = mp_init(&tkb)) != CRYPT_OK) { mp_clear(order); return err; } if ((err = mp_mod(kB, order, tkb)) != CRYPT_OK) { mp_clear(tkb); mp_clear(order); return err; } } else { tkb = kB; } mp_clear(order); } else { tkb = kB; } /* get bitlen and round up to next multiple of FP_LUT */ bitlen = mp_unsigned_bin_size(modulus) << 3; x = bitlen % FP_LUT; if (x) { bitlen += FP_LUT - x; } lut_gap = bitlen / FP_LUT; /* get the k value */ if ((mp_unsigned_bin_size(tka) > (sizeof(kb[0]) - 2)) || (mp_unsigned_bin_size(tkb) > (sizeof(kb[0]) - 2)) ) { if (tka != kA) { mp_clear(tka); } if (tkb != kB) { mp_clear(tkb); } return CRYPT_BUFFER_OVERFLOW; } /* store k */ zeromem(kb, sizeof(kb)); if ((err = mp_to_unsigned_bin(tka, kb[0])) != CRYPT_OK) { if (tka != kA) { mp_clear(tka); } if (tkb != kB) { mp_clear(tkb); } return err; } /* let's reverse kb so it's little endian */ x = 0; y = mp_unsigned_bin_size(tka) - 1; if (tka != kA) { mp_clear(tka); } while ((unsigned)x < y) { z = kb[0][x]; kb[0][x] = kb[0][y]; kb[0][y] = z; ++x; --y; } /* store b */ if ((err = mp_to_unsigned_bin(tkb, kb[1])) != CRYPT_OK) { if (tkb != kB) { mp_clear(tkb); } return err; } x = 0; y = mp_unsigned_bin_size(tkb) - 1; if (tkb != kB) { mp_clear(tkb); } while ((unsigned)x < y) { z = kb[1][x]; kb[1][x] = kb[1][y]; kb[1][y] = z; ++x; --y; } /* at this point we can start, yipee */ first = 1; for (x = lut_gap-1; x >= 0; x--) { /* extract FP_LUT bits from kb spread out by lut_gap bits and offset by x bits from the start */ bitpos = x; for (y = zA = zB = 0; y < FP_LUT; y++) { zA |= ((kb[0][bitpos>>3] >> (bitpos&7)) & 1) << y; zB |= ((kb[1][bitpos>>3] >> (bitpos&7)) & 1) << y; bitpos += lut_gap; /* it's y*lut_gap + x, but here we can avoid the mult in each loop */ } /* double if not first */ if (!first) { if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { return err; } } /* add if not first, otherwise copy */ if (!first) { if (zA) { if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx1].LUT[zA], R, modulus, mp)) != CRYPT_OK) { return err; } } if (zB) { if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx2].LUT[zB], R, modulus, mp)) != CRYPT_OK) { return err; } } } else { if (zA) { if ((mp_copy(fp_cache[idx1].LUT[zA]->x, R->x) != CRYPT_OK) || (mp_copy(fp_cache[idx1].LUT[zA]->y, R->y) != CRYPT_OK) || (mp_copy(fp_cache[idx1].mu, R->z) != CRYPT_OK)) { return CRYPT_MEM; } first = 0; } if (zB && first == 0) { if (zB) { if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx2].LUT[zB], R, modulus, mp)) != CRYPT_OK) { return err; } } } else if (zB && first == 1) { if ((mp_copy(fp_cache[idx2].LUT[zB]->x, R->x) != CRYPT_OK) || (mp_copy(fp_cache[idx2].LUT[zB]->y, R->y) != CRYPT_OK) || (mp_copy(fp_cache[idx2].mu, R->z) != CRYPT_OK)) { return CRYPT_MEM; } first = 0; } } } zeromem(kb, sizeof(kb)); return ltc_ecc_map(R, modulus, mp); } /** ECC Fixed Point mulmod global Computes kA*A + kB*B = C using Shamir's Trick @param A First point to multiply @param kA What to multiple A by @param B Second point to multiply @param kB What to multiple B by @param C [out] Destination point (can overlap with A or B) @param modulus Modulus for curve @return CRYPT_OK on success */ int ltc_ecc_fp_mul2add(ecc_point *A, void *kA, ecc_point *B, void *kB, ecc_point *C, void *modulus) { int idx1, idx2, err; void *mp, *mu; mp = NULL; mu = NULL; LTC_MUTEX_LOCK(<c_ecc_fp_lock); /* find point */ idx1 = find_base(A); /* no entry? */ if (idx1 == -1) { /* find hole and add it */ if ((idx1 = find_hole()) >= 0) { if ((err = add_entry(idx1, A)) != CRYPT_OK) { goto LBL_ERR; } } } if (idx1 != -1) { /* increment LRU */ ++(fp_cache[idx1].lru_count); } /* find point */ idx2 = find_base(B); /* no entry? */ if (idx2 == -1) { /* find hole and add it */ if ((idx2 = find_hole()) >= 0) { if ((err = add_entry(idx2, B)) != CRYPT_OK) { goto LBL_ERR; } } } if (idx2 != -1) { /* increment LRU */ ++(fp_cache[idx2].lru_count); } /* if it's 2 build the LUT, if it's higher just use the LUT */ if (idx1 >= 0 && fp_cache[idx1].lru_count == 2) { /* compute mp */ if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } /* compute mu */ if ((err = mp_init(&mu)) != CRYPT_OK) { goto LBL_ERR; } if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { goto LBL_ERR; } /* build the LUT */ if ((err = build_lut(idx1, modulus, mp, mu)) != CRYPT_OK) { goto LBL_ERR;; } } /* if it's 2 build the LUT, if it's higher just use the LUT */ if (idx2 >= 0 && fp_cache[idx2].lru_count == 2) { if (mp == NULL) { /* compute mp */ if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } /* compute mu */ if ((err = mp_init(&mu)) != CRYPT_OK) { goto LBL_ERR; } if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { goto LBL_ERR; } } /* build the LUT */ if ((err = build_lut(idx2, modulus, mp, mu)) != CRYPT_OK) { goto LBL_ERR;; } } if (idx1 >=0 && idx2 >= 0 && fp_cache[idx1].lru_count >= 2 && fp_cache[idx2].lru_count >= 2) { if (mp == NULL) { /* compute mp */ if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } } err = accel_fp_mul2add(idx1, idx2, kA, kB, C, modulus, mp); } else { err = ltc_ecc_mul2add(A, kA, B, kB, C, modulus); } LBL_ERR: LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); if (mp != NULL) { mp_montgomery_free(mp); } if (mu != NULL) { mp_clear(mu); } return err; } #endif /** ECC Fixed Point mulmod global @param k The multiplicand @param G Base point to multiply @param R [out] Destination of product @param modulus The modulus for the curve @param map [boolean] If non-zero maps the point back to affine co-ordinates, otherwise it's left in jacobian-montgomery form @return CRYPT_OK if successful */ int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map) { int idx, err; void *mp, *mu; mp = NULL; mu = NULL; LTC_MUTEX_LOCK(<c_ecc_fp_lock); /* find point */ idx = find_base(G); /* no entry? */ if (idx == -1) { /* find hole and add it */ idx = find_hole(); if (idx >= 0) { if ((err = add_entry(idx, G)) != CRYPT_OK) { goto LBL_ERR; } } } if (idx != -1) { /* increment LRU */ ++(fp_cache[idx].lru_count); } /* if it's 2 build the LUT, if it's higher just use the LUT */ if (idx >= 0 && fp_cache[idx].lru_count == 2) { /* compute mp */ if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } /* compute mu */ if ((err = mp_init(&mu)) != CRYPT_OK) { goto LBL_ERR; } if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { goto LBL_ERR; } /* build the LUT */ if ((err = build_lut(idx, modulus, mp, mu)) != CRYPT_OK) { goto LBL_ERR;; } } if (idx >= 0 && fp_cache[idx].lru_count >= 2) { if (mp == NULL) { /* compute mp */ if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } } err = accel_fp_mul(idx, k, R, modulus, mp, map); } else { err = ltc_ecc_mulmod(k, G, R, modulus, map); } LBL_ERR: LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); if (mp != NULL) { mp_montgomery_free(mp); } if (mu != NULL) { mp_clear(mu); } return err; } /* helper function for freeing the cache ... must be called with the cache mutex locked */ static void ltc_ecc_fp_free_cache(void) { unsigned x, y; for (x = 0; x < FP_ENTRIES; x++) { if (fp_cache[x].g != NULL) { for (y = 0; y < (1U<= 0) { /* it is already in the cache ... just check that the LUT is initialized */ if(fp_cache[idx].lru_count >= 2) { LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); return CRYPT_OK; } } if(idx == -1 && (idx = find_hole()) == -1) { err = CRYPT_BUFFER_OVERFLOW; goto LBL_ERR; } if ((err = add_entry(idx, g)) != CRYPT_OK) { goto LBL_ERR; } /* compute mp */ if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } /* compute mu */ if ((err = mp_init(&mu)) != CRYPT_OK) { goto LBL_ERR; } if ((err = mp_montgomery_normalization(mu, modulus)) != CRYPT_OK) { goto LBL_ERR; } /* build the LUT */ if ((err = build_lut(idx, modulus, mp, mu)) != CRYPT_OK) { goto LBL_ERR; } fp_cache[idx].lru_count = 2; fp_cache[idx].lock = lock; LBL_ERR: LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); if (mp != NULL) { mp_montgomery_free(mp); } if (mu != NULL) { mp_clear(mu); } return err; } /** Prevent/permit the FP cache from being updated @param flag If flag is 0, remove cache lock (unlock), otherwise lock it */ void ltc_ecc_fp_tablelock(int lock) { int i; LTC_MUTEX_LOCK(<c_ecc_fp_lock); for (i = 0; i < FP_ENTRIES; i++) { fp_cache[i].lock = lock; } LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); } /** Export the current cache as a binary packet @param out [out] pointer to malloc'ed space containing the packet @param outlen [out] size of exported packet @return CRYPT_OK if successful */ int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen) { ltc_asn1_list *cache_entry; unsigned int i, j, k; unsigned long fp_entries, fp_lut, num_entries; int err; LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); fp_entries = FP_ENTRIES; fp_lut = FP_LUT; num_entries = 0; LTC_MUTEX_LOCK(<c_ecc_fp_lock); /* * build the list; Cache DEFINITIONS ::= BEGIN CacheDump ::= SEQUENCE { numEntries SHORTINTEGER, maxEntries SHORTINTEGER, numLUT SHORTINTEGER, cache SEQUENCE OF INTEGER } END * */ /* * The cache itself is a point (3 INTEGERS), * the LUT as pairs of INTEGERS (2 * 1<x, 1); LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].g->y, 1); LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].g->z, 1); for (k = 0; k < (1U<x, 1); LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].LUT[k]->y, 1); } LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_INTEGER, fp_cache[i].mu, 1); } LTC_SET_ASN1(cache_entry, j++, LTC_ASN1_EOL, 0, 0); LTC_SET_ASN1(cache_entry, 0, LTC_ASN1_SHORT_INTEGER, &num_entries, 1); if ((err = der_length_sequence(cache_entry, j, outlen)) != CRYPT_OK) { goto save_err; } if ((*out = XMALLOC(*outlen)) == NULL) { err = CRYPT_MEM; goto save_err; } err = der_encode_sequence(cache_entry, j, *out, outlen); save_err: XFREE(cache_entry); LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); return err; } /** Import a binary packet into the current cache @param in [in] pointer to packet @param inlen [in] size of packet (bytes) @return CRYPT_OK if successful */ int ltc_ecc_fp_restore_state(unsigned char *in, unsigned long inlen) { int err; ltc_asn1_list *asn1_list; unsigned long num_entries, fp_entries, fp_lut; unsigned long i, j; unsigned int x; LTC_ARGCHK(in != NULL); if (inlen == 0) { return CRYPT_INVALID_ARG; } /* zero indecies */ i = 0; j = 0; asn1_list = NULL; LTC_MUTEX_LOCK(<c_ecc_fp_lock); /* * start with an empty cache */ ltc_ecc_fp_free_cache(); /* * decode the input packet: It consists of a sequence with a few * integers (including the FP_ENTRIES and FP_LUT sizes), followed by a * SEQUENCE which is the cache itself. * * use standard decoding for the first part, then flexible for the second */ if((err = der_decode_sequence_multi(in, inlen, LTC_ASN1_SHORT_INTEGER, 1, &num_entries, LTC_ASN1_SHORT_INTEGER, 1, &fp_entries, LTC_ASN1_SHORT_INTEGER, 1, &fp_lut, LTC_ASN1_EOL, 0, 0)) != CRYPT_OK) { goto ERR_OUT; } if (fp_entries != FP_ENTRIES || fp_lut != FP_LUT || num_entries > fp_entries) { err = CRYPT_INVALID_PACKET; goto ERR_OUT; } if ((asn1_list = XCALLOC(3+num_entries*(4+2*(1<x, 1); LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, fp_cache[i].g->y, 1); LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, fp_cache[i].g->z, 1); for (x = 0; x < (1U<x, &p->y, NULL)) != CRYPT_OK) { goto ERR_OUT; } p->z = NULL; LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, p->x, 1); LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, p->y, 1); } if((err = mp_init(&fp_cache[i].mu)) != CRYPT_OK) { goto ERR_OUT; } LTC_SET_ASN1(asn1_list, j++, LTC_ASN1_INTEGER, fp_cache[i].mu, 1); fp_cache[i].lru_count = 3; fp_cache[i].lock = 1; } if ((err = der_decode_sequence(in, inlen, asn1_list, j)) != CRYPT_OK) { goto ERR_OUT; } XFREE(asn1_list); LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); return CRYPT_OK; ERR_OUT: if(asn1_list) XFREE(asn1_list); ltc_ecc_fp_free_cache(); LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/math/fp/ltc_ecc_fp_mulmod.c,v $ */ /* $Revision: 1.33 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/math/rand_prime.c0000644000175100001440000000355410621351501016536 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file rand_prime.c Generate a random prime, Tom St Denis */ #define USE_BBS 1 int rand_prime(void *N, long len, prng_state *prng, int wprng) { int err, res, type; unsigned char *buf; LTC_ARGCHK(N != NULL); /* get type */ if (len < 0) { type = USE_BBS; len = -len; } else { type = 0; } /* allow sizes between 2 and 512 bytes for a prime size */ if (len < 2 || len > 512) { return CRYPT_INVALID_PRIME_SIZE; } /* valid PRNG? Better be! */ if ((err = prng_is_valid(wprng)) != CRYPT_OK) { return err; } /* allocate buffer to work with */ buf = XCALLOC(1, len); if (buf == NULL) { return CRYPT_MEM; } do { /* generate value */ if (prng_descriptor[wprng].read(buf, len, prng) != (unsigned long)len) { XFREE(buf); return CRYPT_ERROR_READPRNG; } /* munge bits */ buf[0] |= 0x80 | 0x40; buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00); /* load value */ if ((err = mp_read_unsigned_bin(N, buf, len)) != CRYPT_OK) { XFREE(buf); return err; } /* test */ if ((err = mp_prime_is_prime(N, 8, &res)) != CRYPT_OK) { XFREE(buf); return err; } } while (res == LTC_MP_NO); #ifdef LTC_CLEAN_STACK zeromem(buf, len); #endif XFREE(buf); return CRYPT_OK; } /* $Source: /cvs/libtom/libtomcrypt/src/math/rand_prime.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/math/gmp_desc.c0000644000175100001440000002044610621351501016176 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #define DESC_DEF_ONLY #include "tomcrypt.h" #ifdef GMP_DESC #include #include static int init(void **a) { LTC_ARGCHK(a != NULL); *a = XCALLOC(1, sizeof(__mpz_struct)); if (*a == NULL) { return CRYPT_MEM; } mpz_init(((__mpz_struct *)*a)); return CRYPT_OK; } static void deinit(void *a) { LTC_ARGCHKVD(a != NULL); mpz_clear(a); XFREE(a); } static int neg(void *a, void *b) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); mpz_neg(b, a); return CRYPT_OK; } static int copy(void *a, void *b) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); mpz_set(b, a); return CRYPT_OK; } static int init_copy(void **a, void *b) { if (init(a) != CRYPT_OK) { return CRYPT_MEM; } return copy(b, *a); } /* ---- trivial ---- */ static int set_int(void *a, unsigned long b) { LTC_ARGCHK(a != NULL); mpz_set_ui(((__mpz_struct *)a), b); return CRYPT_OK; } static unsigned long get_int(void *a) { LTC_ARGCHK(a != NULL); return mpz_get_ui(a); } static unsigned long get_digit(void *a, int n) { LTC_ARGCHK(a != NULL); return mpz_getlimbn(a, n); } static int get_digit_count(void *a) { LTC_ARGCHK(a != NULL); return mpz_size(a); } static int compare(void *a, void *b) { int ret; LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); ret = mpz_cmp(a, b); if (ret < 0) { return LTC_MP_LT; } else if (ret > 0) { return LTC_MP_GT; } else { return LTC_MP_EQ; } } static int compare_d(void *a, unsigned long b) { int ret; LTC_ARGCHK(a != NULL); ret = mpz_cmp_ui(((__mpz_struct *)a), b); if (ret < 0) { return LTC_MP_LT; } else if (ret > 0) { return LTC_MP_GT; } else { return LTC_MP_EQ; } } static int count_bits(void *a) { LTC_ARGCHK(a != NULL); return mpz_sizeinbase(a, 2); } static int count_lsb_bits(void *a) { LTC_ARGCHK(a != NULL); return mpz_scan1(a, 0); } static int twoexpt(void *a, int n) { LTC_ARGCHK(a != NULL); mpz_set_ui(a, 0); mpz_setbit(a, n); return CRYPT_OK; } /* ---- conversions ---- */ /* read ascii string */ static int read_radix(void *a, const char *b, int radix) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); mpz_set_str(a, b, radix); return CRYPT_OK; } /* write one */ static int write_radix(void *a, char *b, int radix) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); mpz_get_str(b, radix, a); return CRYPT_OK; } /* get size as unsigned char string */ static unsigned long unsigned_size(void *a) { unsigned long t; LTC_ARGCHK(a != NULL); t = mpz_sizeinbase(a, 2); if (mpz_cmp_ui(((__mpz_struct *)a), 0) == 0) return 0; return (t>>3) + ((t&7)?1:0); } /* store */ static int unsigned_write(void *a, unsigned char *b) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); mpz_export(b, NULL, 1, 1, 1, 0, ((__mpz_struct*)a)); return CRYPT_OK; } /* read */ static int unsigned_read(void *a, unsigned char *b, unsigned long len) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); mpz_import(a, len, 1, 1, 1, 0, b); return CRYPT_OK; } /* add */ static int add(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); mpz_add(c, a, b); return CRYPT_OK; } static int addi(void *a, unsigned long b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(c != NULL); mpz_add_ui(c, a, b); return CRYPT_OK; } /* sub */ static int sub(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); mpz_sub(c, a, b); return CRYPT_OK; } static int subi(void *a, unsigned long b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(c != NULL); mpz_sub_ui(c, a, b); return CRYPT_OK; } /* mul */ static int mul(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); mpz_mul(c, a, b); return CRYPT_OK; } static int muli(void *a, unsigned long b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(c != NULL); mpz_mul_ui(c, a, b); return CRYPT_OK; } /* sqr */ static int sqr(void *a, void *b) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); mpz_mul(b, a, a); return CRYPT_OK; } /* div */ static int divide(void *a, void *b, void *c, void *d) { mpz_t tmp; LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); if (c != NULL) { mpz_init(tmp); mpz_divexact(tmp, a, b); } if (d != NULL) { mpz_mod(d, a, b); } if (c != NULL) { mpz_set(c, tmp); mpz_clear(tmp); } return CRYPT_OK; } static int div_2(void *a, void *b) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); mpz_divexact_ui(b, a, 2); return CRYPT_OK; } /* modi */ static int modi(void *a, unsigned long b, unsigned long *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(c != NULL); *c = mpz_fdiv_ui(a, b); return CRYPT_OK; } /* gcd */ static int gcd(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); mpz_gcd(c, a, b); return CRYPT_OK; } /* lcm */ static int lcm(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); mpz_lcm(c, a, b); return CRYPT_OK; } static int mulmod(void *a, void *b, void *c, void *d) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); LTC_ARGCHK(d != NULL); mpz_mul(d, a, b); mpz_mod(d, d, c); return CRYPT_OK; } static int sqrmod(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); mpz_mul(c, a, a); mpz_mod(c, c, b); return CRYPT_OK; } /* invmod */ static int invmod(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); mpz_invert(c, a, b); return CRYPT_OK; } /* setup */ static int montgomery_setup(void *a, void **b) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); *b = (void *)1; return CRYPT_OK; } /* get normalization value */ static int montgomery_normalization(void *a, void *b) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); mpz_set_ui(a, 1); return CRYPT_OK; } /* reduce */ static int montgomery_reduce(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); mpz_mod(a, a, b); return CRYPT_OK; } /* clean up */ static void montgomery_deinit(void *a) { } static int exptmod(void *a, void *b, void *c, void *d) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); LTC_ARGCHK(d != NULL); mpz_powm(d, a, b, c); return CRYPT_OK; } static int isprime(void *a, int *b) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); *b = mpz_probab_prime_p(a, 8) > 0 ? LTC_MP_YES : LTC_MP_NO; return CRYPT_OK; } const ltc_math_descriptor gmp_desc = { "GNU MP", sizeof(mp_limb_t) * CHAR_BIT - GMP_NAIL_BITS, &init, &init_copy, &deinit, &neg, ©, &set_int, &get_int, &get_digit, &get_digit_count, &compare, &compare_d, &count_bits, &count_lsb_bits, &twoexpt, &read_radix, &write_radix, &unsigned_size, &unsigned_write, &unsigned_read, &add, &addi, &sub, &subi, &mul, &muli, &sqr, ÷, &div_2, &modi, &gcd, &lcm, &mulmod, &sqrmod, &invmod, &montgomery_setup, &montgomery_normalization, &montgomery_reduce, &montgomery_deinit, &exptmod, &isprime, #ifdef LTC_MECC #ifdef LTC_MECC_FP <c_ecc_fp_mulmod, #else <c_ecc_mulmod, #endif /* LTC_MECC_FP */ <c_ecc_projective_add_point, <c_ecc_projective_dbl_point, <c_ecc_map, #ifdef LTC_ECC_SHAMIR #ifdef LTC_MECC_FP <c_ecc_fp_mul2add, #else <c_ecc_mul2add, #endif /* LTC_MECC_FP */ #else NULL, #endif /* LTC_ECC_SHAMIR */ #else NULL, NULL, NULL, NULL, NULL #endif /* LTC_MECC */ #ifdef LTC_MRSA &rsa_make_key, &rsa_exptmod, #else NULL, NULL #endif }; #endif /* $Source: /cvs/libtom/libtomcrypt/src/math/gmp_desc.c,v $ */ /* $Revision: 1.16 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/math/multi.c0000644000175100001440000000242010621351501015537 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" #ifdef MPI #include int ltc_init_multi(void **a, ...) { void **cur = a; int np = 0; va_list args; va_start(args, a); while (cur != NULL) { if (mp_init(cur) != CRYPT_OK) { /* failed */ va_list clean_list; va_start(clean_list, a); cur = a; while (np--) { mp_clear(*cur); cur = va_arg(clean_list, void**); } va_end(clean_list); return CRYPT_MEM; } ++np; cur = va_arg(args, void**); } va_end(args); return CRYPT_OK; } void ltc_deinit_multi(void *a, ...) { void *cur = a; va_list args; va_start(args, a); while (cur != NULL) { mp_clear(cur); cur = va_arg(args, void *); } va_end(args); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/math/multi.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/math/ltm_desc.c0000644000175100001440000002213310621351501016202 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #define DESC_DEF_ONLY #include "tomcrypt.h" #ifdef LTM_DESC #include static const struct { int mpi_code, ltc_code; } mpi_to_ltc_codes[] = { { MP_OKAY , CRYPT_OK}, { MP_MEM , CRYPT_MEM}, { MP_VAL , CRYPT_INVALID_ARG}, }; /** Convert a MPI error to a LTC error (Possibly the most powerful function ever! Oh wait... no) @param err The error to convert @return The equivalent LTC error code or CRYPT_ERROR if none found */ static int mpi_to_ltc_error(int err) { int x; for (x = 0; x < (int)(sizeof(mpi_to_ltc_codes)/sizeof(mpi_to_ltc_codes[0])); x++) { if (err == mpi_to_ltc_codes[x].mpi_code) { return mpi_to_ltc_codes[x].ltc_code; } } return CRYPT_ERROR; } static int init(void **a) { int err; LTC_ARGCHK(a != NULL); *a = XCALLOC(1, sizeof(mp_int)); if (*a == NULL) { return CRYPT_MEM; } if ((err = mpi_to_ltc_error(mp_init(*a))) != CRYPT_OK) { XFREE(*a); } return err; } static void deinit(void *a) { LTC_ARGCHKVD(a != NULL); mp_clear(a); XFREE(a); } static int neg(void *a, void *b) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); return mpi_to_ltc_error(mp_neg(a, b)); } static int copy(void *a, void *b) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); return mpi_to_ltc_error(mp_copy(a, b)); } static int init_copy(void **a, void *b) { if (init(a) != CRYPT_OK) { return CRYPT_MEM; } return copy(b, *a); } /* ---- trivial ---- */ static int set_int(void *a, unsigned long b) { LTC_ARGCHK(a != NULL); return mpi_to_ltc_error(mp_set_int(a, b)); } static unsigned long get_int(void *a) { LTC_ARGCHK(a != NULL); return mp_get_int(a); } static unsigned long get_digit(void *a, int n) { mp_int *A; LTC_ARGCHK(a != NULL); A = a; return (n >= A->used || n < 0) ? 0 : A->dp[n]; } static int get_digit_count(void *a) { mp_int *A; LTC_ARGCHK(a != NULL); A = a; return A->used; } static int compare(void *a, void *b) { int ret; LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); ret = mp_cmp(a, b); switch (ret) { case MP_LT: return LTC_MP_LT; case MP_EQ: return LTC_MP_EQ; case MP_GT: return LTC_MP_GT; } return 0; } static int compare_d(void *a, unsigned long b) { int ret; LTC_ARGCHK(a != NULL); ret = mp_cmp_d(a, b); switch (ret) { case MP_LT: return LTC_MP_LT; case MP_EQ: return LTC_MP_EQ; case MP_GT: return LTC_MP_GT; } return 0; } static int count_bits(void *a) { LTC_ARGCHK(a != NULL); return mp_count_bits(a); } static int count_lsb_bits(void *a) { LTC_ARGCHK(a != NULL); return mp_cnt_lsb(a); } static int twoexpt(void *a, int n) { LTC_ARGCHK(a != NULL); return mpi_to_ltc_error(mp_2expt(a, n)); } /* ---- conversions ---- */ /* read ascii string */ static int read_radix(void *a, const char *b, int radix) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); return mpi_to_ltc_error(mp_read_radix(a, b, radix)); } /* write one */ static int write_radix(void *a, char *b, int radix) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); return mpi_to_ltc_error(mp_toradix(a, b, radix)); } /* get size as unsigned char string */ static unsigned long unsigned_size(void *a) { LTC_ARGCHK(a != NULL); return mp_unsigned_bin_size(a); } /* store */ static int unsigned_write(void *a, unsigned char *b) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); return mpi_to_ltc_error(mp_to_unsigned_bin(a, b)); } /* read */ static int unsigned_read(void *a, unsigned char *b, unsigned long len) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); return mpi_to_ltc_error(mp_read_unsigned_bin(a, b, len)); } /* add */ static int add(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); return mpi_to_ltc_error(mp_add(a, b, c)); } static int addi(void *a, unsigned long b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(c != NULL); return mpi_to_ltc_error(mp_add_d(a, b, c)); } /* sub */ static int sub(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); return mpi_to_ltc_error(mp_sub(a, b, c)); } static int subi(void *a, unsigned long b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(c != NULL); return mpi_to_ltc_error(mp_sub_d(a, b, c)); } /* mul */ static int mul(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); return mpi_to_ltc_error(mp_mul(a, b, c)); } static int muli(void *a, unsigned long b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(c != NULL); return mpi_to_ltc_error(mp_mul_d(a, b, c)); } /* sqr */ static int sqr(void *a, void *b) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); return mpi_to_ltc_error(mp_sqr(a, b)); } /* div */ static int divide(void *a, void *b, void *c, void *d) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); return mpi_to_ltc_error(mp_div(a, b, c, d)); } static int div_2(void *a, void *b) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); return mpi_to_ltc_error(mp_div_2(a, b)); } /* modi */ static int modi(void *a, unsigned long b, unsigned long *c) { mp_digit tmp; int err; LTC_ARGCHK(a != NULL); LTC_ARGCHK(c != NULL); if ((err = mpi_to_ltc_error(mp_mod_d(a, b, &tmp))) != CRYPT_OK) { return err; } *c = tmp; return CRYPT_OK; } /* gcd */ static int gcd(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); return mpi_to_ltc_error(mp_gcd(a, b, c)); } /* lcm */ static int lcm(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); return mpi_to_ltc_error(mp_lcm(a, b, c)); } static int mulmod(void *a, void *b, void *c, void *d) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); LTC_ARGCHK(d != NULL); return mpi_to_ltc_error(mp_mulmod(a,b,c,d)); } static int sqrmod(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); return mpi_to_ltc_error(mp_sqrmod(a,b,c)); } /* invmod */ static int invmod(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); return mpi_to_ltc_error(mp_invmod(a, b, c)); } /* setup */ static int montgomery_setup(void *a, void **b) { int err; LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); *b = XCALLOC(1, sizeof(mp_digit)); if (*b == NULL) { return CRYPT_MEM; } if ((err = mpi_to_ltc_error(mp_montgomery_setup(a, (mp_digit *)*b))) != CRYPT_OK) { XFREE(*b); } return err; } /* get normalization value */ static int montgomery_normalization(void *a, void *b) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); return mpi_to_ltc_error(mp_montgomery_calc_normalization(a, b)); } /* reduce */ static int montgomery_reduce(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); return mpi_to_ltc_error(mp_montgomery_reduce(a, b, *((mp_digit *)c))); } /* clean up */ static void montgomery_deinit(void *a) { XFREE(a); } static int exptmod(void *a, void *b, void *c, void *d) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); LTC_ARGCHK(d != NULL); return mpi_to_ltc_error(mp_exptmod(a,b,c,d)); } static int isprime(void *a, int *b) { int err; LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); err = mpi_to_ltc_error(mp_prime_is_prime(a, 8, b)); *b = (*b == MP_YES) ? LTC_MP_YES : LTC_MP_NO; return err; } const ltc_math_descriptor ltm_desc = { "LibTomMath", (int)DIGIT_BIT, &init, &init_copy, &deinit, &neg, ©, &set_int, &get_int, &get_digit, &get_digit_count, &compare, &compare_d, &count_bits, &count_lsb_bits, &twoexpt, &read_radix, &write_radix, &unsigned_size, &unsigned_write, &unsigned_read, &add, &addi, &sub, &subi, &mul, &muli, &sqr, ÷, &div_2, &modi, &gcd, &lcm, &mulmod, &sqrmod, &invmod, &montgomery_setup, &montgomery_normalization, &montgomery_reduce, &montgomery_deinit, &exptmod, &isprime, #ifdef LTC_MECC #ifdef LTC_MECC_FP <c_ecc_fp_mulmod, #else <c_ecc_mulmod, #endif <c_ecc_projective_add_point, <c_ecc_projective_dbl_point, <c_ecc_map, #ifdef LTC_ECC_SHAMIR #ifdef LTC_MECC_FP <c_ecc_fp_mul2add, #else <c_ecc_mul2add, #endif /* LTC_MECC_FP */ #else NULL, #endif /* LTC_ECC_SHAMIR */ #else NULL, NULL, NULL, NULL, NULL, #endif /* LTC_MECC */ #ifdef LTC_MRSA &rsa_make_key, &rsa_exptmod, #else NULL, NULL #endif }; #endif /* $Source: /cvs/libtom/libtomcrypt/src/math/ltm_desc.c,v $ */ /* $Revision: 1.31 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/math/tfm_desc.c0000644000175100001440000003706010621351501016201 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #define DESC_DEF_ONLY #include "tomcrypt.h" #ifdef TFM_DESC #include static const struct { int tfm_code, ltc_code; } tfm_to_ltc_codes[] = { { FP_OKAY , CRYPT_OK}, { FP_MEM , CRYPT_MEM}, { FP_VAL , CRYPT_INVALID_ARG}, }; /** Convert a tfm error to a LTC error (Possibly the most powerful function ever! Oh wait... no) @param err The error to convert @return The equivalent LTC error code or CRYPT_ERROR if none found */ static int tfm_to_ltc_error(int err) { int x; for (x = 0; x < (int)(sizeof(tfm_to_ltc_codes)/sizeof(tfm_to_ltc_codes[0])); x++) { if (err == tfm_to_ltc_codes[x].tfm_code) { return tfm_to_ltc_codes[x].ltc_code; } } return CRYPT_ERROR; } static int init(void **a) { LTC_ARGCHK(a != NULL); *a = XCALLOC(1, sizeof(fp_int)); if (*a == NULL) { return CRYPT_MEM; } fp_init(*a); return CRYPT_OK; } static void deinit(void *a) { LTC_ARGCHKVD(a != NULL); XFREE(a); } static int neg(void *a, void *b) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); fp_neg(((fp_int*)a), ((fp_int*)b)); return CRYPT_OK; } static int copy(void *a, void *b) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); fp_copy(a, b); return CRYPT_OK; } static int init_copy(void **a, void *b) { if (init(a) != CRYPT_OK) { return CRYPT_MEM; } return copy(b, *a); } /* ---- trivial ---- */ static int set_int(void *a, unsigned long b) { LTC_ARGCHK(a != NULL); fp_set(a, b); return CRYPT_OK; } static unsigned long get_int(void *a) { fp_int *A; LTC_ARGCHK(a != NULL); A = a; return A->used > 0 ? A->dp[0] : 0; } static unsigned long get_digit(void *a, int n) { fp_int *A; LTC_ARGCHK(a != NULL); A = a; return (n >= A->used || n < 0) ? 0 : A->dp[n]; } static int get_digit_count(void *a) { fp_int *A; LTC_ARGCHK(a != NULL); A = a; return A->used; } static int compare(void *a, void *b) { int ret; LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); ret = fp_cmp(a, b); switch (ret) { case FP_LT: return LTC_MP_LT; case FP_EQ: return LTC_MP_EQ; case FP_GT: return LTC_MP_GT; } return 0; } static int compare_d(void *a, unsigned long b) { int ret; LTC_ARGCHK(a != NULL); ret = fp_cmp_d(a, b); switch (ret) { case FP_LT: return LTC_MP_LT; case FP_EQ: return LTC_MP_EQ; case FP_GT: return LTC_MP_GT; } return 0; } static int count_bits(void *a) { LTC_ARGCHK(a != NULL); return fp_count_bits(a); } static int count_lsb_bits(void *a) { LTC_ARGCHK(a != NULL); return fp_cnt_lsb(a); } static int twoexpt(void *a, int n) { LTC_ARGCHK(a != NULL); fp_2expt(a, n); return CRYPT_OK; } /* ---- conversions ---- */ /* read ascii string */ static int read_radix(void *a, const char *b, int radix) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); return tfm_to_ltc_error(fp_read_radix(a, (char *)b, radix)); } /* write one */ static int write_radix(void *a, char *b, int radix) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); return tfm_to_ltc_error(fp_toradix(a, b, radix)); } /* get size as unsigned char string */ static unsigned long unsigned_size(void *a) { LTC_ARGCHK(a != NULL); return fp_unsigned_bin_size(a); } /* store */ static int unsigned_write(void *a, unsigned char *b) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); fp_to_unsigned_bin(a, b); return CRYPT_OK; } /* read */ static int unsigned_read(void *a, unsigned char *b, unsigned long len) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); fp_read_unsigned_bin(a, b, len); return CRYPT_OK; } /* add */ static int add(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); fp_add(a, b, c); return CRYPT_OK; } static int addi(void *a, unsigned long b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(c != NULL); fp_add_d(a, b, c); return CRYPT_OK; } /* sub */ static int sub(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); fp_sub(a, b, c); return CRYPT_OK; } static int subi(void *a, unsigned long b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(c != NULL); fp_sub_d(a, b, c); return CRYPT_OK; } /* mul */ static int mul(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); fp_mul(a, b, c); return CRYPT_OK; } static int muli(void *a, unsigned long b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(c != NULL); fp_mul_d(a, b, c); return CRYPT_OK; } /* sqr */ static int sqr(void *a, void *b) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); fp_sqr(a, b); return CRYPT_OK; } /* div */ static int divide(void *a, void *b, void *c, void *d) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); return tfm_to_ltc_error(fp_div(a, b, c, d)); } static int div_2(void *a, void *b) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); fp_div_2(a, b); return CRYPT_OK; } /* modi */ static int modi(void *a, unsigned long b, unsigned long *c) { fp_digit tmp; int err; LTC_ARGCHK(a != NULL); LTC_ARGCHK(c != NULL); if ((err = tfm_to_ltc_error(fp_mod_d(a, b, &tmp))) != CRYPT_OK) { return err; } *c = tmp; return CRYPT_OK; } /* gcd */ static int gcd(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); fp_gcd(a, b, c); return CRYPT_OK; } /* lcm */ static int lcm(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); fp_lcm(a, b, c); return CRYPT_OK; } static int mulmod(void *a, void *b, void *c, void *d) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); LTC_ARGCHK(d != NULL); return tfm_to_ltc_error(fp_mulmod(a,b,c,d)); } static int sqrmod(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); return tfm_to_ltc_error(fp_sqrmod(a,b,c)); } /* invmod */ static int invmod(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); return tfm_to_ltc_error(fp_invmod(a, b, c)); } /* setup */ static int montgomery_setup(void *a, void **b) { int err; LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); *b = XCALLOC(1, sizeof(fp_digit)); if (*b == NULL) { return CRYPT_MEM; } if ((err = tfm_to_ltc_error(fp_montgomery_setup(a, (fp_digit *)*b))) != CRYPT_OK) { XFREE(*b); } return err; } /* get normalization value */ static int montgomery_normalization(void *a, void *b) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); fp_montgomery_calc_normalization(a, b); return CRYPT_OK; } /* reduce */ static int montgomery_reduce(void *a, void *b, void *c) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); fp_montgomery_reduce(a, b, *((fp_digit *)c)); return CRYPT_OK; } /* clean up */ static void montgomery_deinit(void *a) { XFREE(a); } static int exptmod(void *a, void *b, void *c, void *d) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(c != NULL); LTC_ARGCHK(d != NULL); return tfm_to_ltc_error(fp_exptmod(a,b,c,d)); } static int isprime(void *a, int *b) { LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); *b = (fp_isprime(a) == FP_YES) ? LTC_MP_YES : LTC_MP_NO; return CRYPT_OK; } #if defined(LTC_MECC) && defined(LTC_MECC_ACCEL) static int tfm_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *Mp) { fp_int t1, t2; fp_digit mp; LTC_ARGCHK(P != NULL); LTC_ARGCHK(R != NULL); LTC_ARGCHK(modulus != NULL); LTC_ARGCHK(Mp != NULL); mp = *((fp_digit*)Mp); fp_init(&t1); fp_init(&t2); if (P != R) { fp_copy(P->x, R->x); fp_copy(P->y, R->y); fp_copy(P->z, R->z); } /* t1 = Z * Z */ fp_sqr(R->z, &t1); fp_montgomery_reduce(&t1, modulus, mp); /* Z = Y * Z */ fp_mul(R->z, R->y, R->z); fp_montgomery_reduce(R->z, modulus, mp); /* Z = 2Z */ fp_add(R->z, R->z, R->z); if (fp_cmp(R->z, modulus) != FP_LT) { fp_sub(R->z, modulus, R->z); } /* &t2 = X - T1 */ fp_sub(R->x, &t1, &t2); if (fp_cmp_d(&t2, 0) == FP_LT) { fp_add(&t2, modulus, &t2); } /* T1 = X + T1 */ fp_add(&t1, R->x, &t1); if (fp_cmp(&t1, modulus) != FP_LT) { fp_sub(&t1, modulus, &t1); } /* T2 = T1 * T2 */ fp_mul(&t1, &t2, &t2); fp_montgomery_reduce(&t2, modulus, mp); /* T1 = 2T2 */ fp_add(&t2, &t2, &t1); if (fp_cmp(&t1, modulus) != FP_LT) { fp_sub(&t1, modulus, &t1); } /* T1 = T1 + T2 */ fp_add(&t1, &t2, &t1); if (fp_cmp(&t1, modulus) != FP_LT) { fp_sub(&t1, modulus, &t1); } /* Y = 2Y */ fp_add(R->y, R->y, R->y); if (fp_cmp(R->y, modulus) != FP_LT) { fp_sub(R->y, modulus, R->y); } /* Y = Y * Y */ fp_sqr(R->y, R->y); fp_montgomery_reduce(R->y, modulus, mp); /* T2 = Y * Y */ fp_sqr(R->y, &t2); fp_montgomery_reduce(&t2, modulus, mp); /* T2 = T2/2 */ if (fp_isodd(&t2)) { fp_add(&t2, modulus, &t2); } fp_div_2(&t2, &t2); /* Y = Y * X */ fp_mul(R->y, R->x, R->y); fp_montgomery_reduce(R->y, modulus, mp); /* X = T1 * T1 */ fp_sqr(&t1, R->x); fp_montgomery_reduce(R->x, modulus, mp); /* X = X - Y */ fp_sub(R->x, R->y, R->x); if (fp_cmp_d(R->x, 0) == FP_LT) { fp_add(R->x, modulus, R->x); } /* X = X - Y */ fp_sub(R->x, R->y, R->x); if (fp_cmp_d(R->x, 0) == FP_LT) { fp_add(R->x, modulus, R->x); } /* Y = Y - X */ fp_sub(R->y, R->x, R->y); if (fp_cmp_d(R->y, 0) == FP_LT) { fp_add(R->y, modulus, R->y); } /* Y = Y * T1 */ fp_mul(R->y, &t1, R->y); fp_montgomery_reduce(R->y, modulus, mp); /* Y = Y - T2 */ fp_sub(R->y, &t2, R->y); if (fp_cmp_d(R->y, 0) == FP_LT) { fp_add(R->y, modulus, R->y); } return CRYPT_OK; } /** Add two ECC points @param P The point to add @param Q The point to add @param R [out] The destination of the double @param modulus The modulus of the field the ECC curve is in @param mp The "b" value from montgomery_setup() @return CRYPT_OK on success */ static int tfm_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *Mp) { fp_int t1, t2, x, y, z; fp_digit mp; LTC_ARGCHK(P != NULL); LTC_ARGCHK(Q != NULL); LTC_ARGCHK(R != NULL); LTC_ARGCHK(modulus != NULL); LTC_ARGCHK(Mp != NULL); mp = *((fp_digit*)Mp); fp_init(&t1); fp_init(&t2); fp_init(&x); fp_init(&y); fp_init(&z); /* should we dbl instead? */ fp_sub(modulus, Q->y, &t1); if ( (fp_cmp(P->x, Q->x) == FP_EQ) && (Q->z != NULL && fp_cmp(P->z, Q->z) == FP_EQ) && (fp_cmp(P->y, Q->y) == FP_EQ || fp_cmp(P->y, &t1) == FP_EQ)) { return tfm_ecc_projective_dbl_point(P, R, modulus, Mp); } fp_copy(P->x, &x); fp_copy(P->y, &y); fp_copy(P->z, &z); /* if Z is one then these are no-operations */ if (Q->z != NULL) { /* T1 = Z' * Z' */ fp_sqr(Q->z, &t1); fp_montgomery_reduce(&t1, modulus, mp); /* X = X * T1 */ fp_mul(&t1, &x, &x); fp_montgomery_reduce(&x, modulus, mp); /* T1 = Z' * T1 */ fp_mul(Q->z, &t1, &t1); fp_montgomery_reduce(&t1, modulus, mp); /* Y = Y * T1 */ fp_mul(&t1, &y, &y); fp_montgomery_reduce(&y, modulus, mp); } /* T1 = Z*Z */ fp_sqr(&z, &t1); fp_montgomery_reduce(&t1, modulus, mp); /* T2 = X' * T1 */ fp_mul(Q->x, &t1, &t2); fp_montgomery_reduce(&t2, modulus, mp); /* T1 = Z * T1 */ fp_mul(&z, &t1, &t1); fp_montgomery_reduce(&t1, modulus, mp); /* T1 = Y' * T1 */ fp_mul(Q->y, &t1, &t1); fp_montgomery_reduce(&t1, modulus, mp); /* Y = Y - T1 */ fp_sub(&y, &t1, &y); if (fp_cmp_d(&y, 0) == FP_LT) { fp_add(&y, modulus, &y); } /* T1 = 2T1 */ fp_add(&t1, &t1, &t1); if (fp_cmp(&t1, modulus) != FP_LT) { fp_sub(&t1, modulus, &t1); } /* T1 = Y + T1 */ fp_add(&t1, &y, &t1); if (fp_cmp(&t1, modulus) != FP_LT) { fp_sub(&t1, modulus, &t1); } /* X = X - T2 */ fp_sub(&x, &t2, &x); if (fp_cmp_d(&x, 0) == FP_LT) { fp_add(&x, modulus, &x); } /* T2 = 2T2 */ fp_add(&t2, &t2, &t2); if (fp_cmp(&t2, modulus) != FP_LT) { fp_sub(&t2, modulus, &t2); } /* T2 = X + T2 */ fp_add(&t2, &x, &t2); if (fp_cmp(&t2, modulus) != FP_LT) { fp_sub(&t2, modulus, &t2); } /* if Z' != 1 */ if (Q->z != NULL) { /* Z = Z * Z' */ fp_mul(&z, Q->z, &z); fp_montgomery_reduce(&z, modulus, mp); } /* Z = Z * X */ fp_mul(&z, &x, &z); fp_montgomery_reduce(&z, modulus, mp); /* T1 = T1 * X */ fp_mul(&t1, &x, &t1); fp_montgomery_reduce(&t1, modulus, mp); /* X = X * X */ fp_sqr(&x, &x); fp_montgomery_reduce(&x, modulus, mp); /* T2 = T2 * x */ fp_mul(&t2, &x, &t2); fp_montgomery_reduce(&t2, modulus, mp); /* T1 = T1 * X */ fp_mul(&t1, &x, &t1); fp_montgomery_reduce(&t1, modulus, mp); /* X = Y*Y */ fp_sqr(&y, &x); fp_montgomery_reduce(&x, modulus, mp); /* X = X - T2 */ fp_sub(&x, &t2, &x); if (fp_cmp_d(&x, 0) == FP_LT) { fp_add(&x, modulus, &x); } /* T2 = T2 - X */ fp_sub(&t2, &x, &t2); if (fp_cmp_d(&t2, 0) == FP_LT) { fp_add(&t2, modulus, &t2); } /* T2 = T2 - X */ fp_sub(&t2, &x, &t2); if (fp_cmp_d(&t2, 0) == FP_LT) { fp_add(&t2, modulus, &t2); } /* T2 = T2 * Y */ fp_mul(&t2, &y, &t2); fp_montgomery_reduce(&t2, modulus, mp); /* Y = T2 - T1 */ fp_sub(&t2, &t1, &y); if (fp_cmp_d(&y, 0) == FP_LT) { fp_add(&y, modulus, &y); } /* Y = Y/2 */ if (fp_isodd(&y)) { fp_add(&y, modulus, &y); } fp_div_2(&y, &y); fp_copy(&x, R->x); fp_copy(&y, R->y); fp_copy(&z, R->z); return CRYPT_OK; } #endif const ltc_math_descriptor tfm_desc = { "TomsFastMath", (int)DIGIT_BIT, &init, &init_copy, &deinit, &neg, ©, &set_int, &get_int, &get_digit, &get_digit_count, &compare, &compare_d, &count_bits, &count_lsb_bits, &twoexpt, &read_radix, &write_radix, &unsigned_size, &unsigned_write, &unsigned_read, &add, &addi, &sub, &subi, &mul, &muli, &sqr, ÷, &div_2, &modi, &gcd, &lcm, &mulmod, &sqrmod, &invmod, &montgomery_setup, &montgomery_normalization, &montgomery_reduce, &montgomery_deinit, &exptmod, &isprime, #ifdef LTC_MECC #ifdef LTC_MECC_FP <c_ecc_fp_mulmod, #else <c_ecc_mulmod, #endif /* LTC_MECC_FP */ #ifdef LTC_MECC_ACCEL &tfm_ecc_projective_add_point, &tfm_ecc_projective_dbl_point, #else <c_ecc_projective_add_point, <c_ecc_projective_dbl_point, #endif /* LTC_MECC_ACCEL */ <c_ecc_map, #ifdef LTC_ECC_SHAMIR #ifdef LTC_MECC_FP <c_ecc_fp_mul2add, #else <c_ecc_mul2add, #endif /* LTC_MECC_FP */ #else NULL, #endif /* LTC_ECC_SHAMIR */ #else NULL, NULL, NULL, NULL, NULL, #endif /* LTC_MECC */ #ifdef LTC_MRSA &rsa_make_key, &rsa_exptmod, #else NULL, NULL #endif }; #endif /* $Source: /cvs/libtom/libtomcrypt/src/math/tfm_desc.c,v $ */ /* $Revision: 1.28 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/misc/0000755000175100001440000000000010621351501014245 5ustar tomuserslibtomcrypt-1.17/src/misc/zeromem.c0000644000175100001440000000150710621351501016072 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file zeromem.c Zero a block of memory, Tom St Denis */ /** Zero a block of memory @param out The destination of the area to zero @param outlen The length of the area to zero (octets) */ void zeromem(void *out, size_t outlen) { unsigned char *mem = out; LTC_ARGCHKVD(out != NULL); while (outlen-- > 0) { *mem++ = 0; } } /* $Source: /cvs/libtom/libtomcrypt/src/misc/zeromem.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/misc/crypt/0000755000175100001440000000000010621351501015406 5ustar tomuserslibtomcrypt-1.17/src/misc/crypt/crypt_prng_is_valid.c0000644000175100001440000000171710621351501021621 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file crypt_prng_is_valid.c Determine if PRNG is valid, Tom St Denis */ /* Test if a PRNG index is valid @param idx The index of the PRNG to search for @return CRYPT_OK if valid */ int prng_is_valid(int idx) { LTC_MUTEX_LOCK(<c_prng_mutex); if (idx < 0 || idx >= TAB_SIZE || prng_descriptor[idx].name == NULL) { LTC_MUTEX_UNLOCK(<c_prng_mutex); return CRYPT_INVALID_PRNG; } LTC_MUTEX_UNLOCK(<c_prng_mutex); return CRYPT_OK; } /* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_prng_is_valid.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/misc/crypt/crypt_unregister_cipher.c0000644000175100001440000000236510621351501022522 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file crypt_unregister_cipher.c Unregister a cipher, Tom St Denis */ /** Unregister a cipher from the descriptor table @param cipher The cipher descriptor to remove @return CRYPT_OK on success */ int unregister_cipher(const struct ltc_cipher_descriptor *cipher) { int x; LTC_ARGCHK(cipher != NULL); /* is it already registered? */ LTC_MUTEX_LOCK(<c_cipher_mutex); for (x = 0; x < TAB_SIZE; x++) { if (XMEMCMP(&cipher_descriptor[x], cipher, sizeof(struct ltc_cipher_descriptor)) == 0) { cipher_descriptor[x].name = NULL; cipher_descriptor[x].ID = 255; LTC_MUTEX_UNLOCK(<c_cipher_mutex); return CRYPT_OK; } } LTC_MUTEX_UNLOCK(<c_cipher_mutex); return CRYPT_ERROR; } /* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_unregister_cipher.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/misc/crypt/crypt.c0000644000175100001440000001545410621351501016724 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file crypt.c Build strings, Tom St Denis */ const char *crypt_build_settings = "LibTomCrypt " SCRYPT " (Tom St Denis, tomstdenis@gmail.com)\n" "LibTomCrypt is public domain software.\n" "Built on " __DATE__ " at " __TIME__ "\n\n\n" "Endianess: " #if defined(ENDIAN_NEUTRAL) "neutral\n" #elif defined(ENDIAN_LITTLE) "little" #if defined(ENDIAN_32BITWORD) " (32-bit words)\n" #else " (64-bit words)\n" #endif #elif defined(ENDIAN_BIG) "big" #if defined(ENDIAN_32BITWORD) " (32-bit words)\n" #else " (64-bit words)\n" #endif #endif "Clean stack: " #if defined(LTC_CLEAN_STACK) "enabled\n" #else "disabled\n" #endif "Ciphers built-in:\n" #if defined(LTC_BLOWFISH) " Blowfish\n" #endif #if defined(LTC_RC2) " LTC_RC2\n" #endif #if defined(LTC_RC5) " LTC_RC5\n" #endif #if defined(LTC_RC6) " LTC_RC6\n" #endif #if defined(LTC_SAFERP) " Safer+\n" #endif #if defined(LTC_SAFER) " Safer\n" #endif #if defined(LTC_RIJNDAEL) " Rijndael\n" #endif #if defined(LTC_XTEA) " LTC_XTEA\n" #endif #if defined(LTC_TWOFISH) " Twofish " #if defined(LTC_TWOFISH_SMALL) && defined(LTC_TWOFISH_TABLES) && defined(LTC_TWOFISH_ALL_TABLES) "(small, tables, all_tables)\n" #elif defined(LTC_TWOFISH_SMALL) && defined(LTC_TWOFISH_TABLES) "(small, tables)\n" #elif defined(LTC_TWOFISH_SMALL) && defined(LTC_TWOFISH_ALL_TABLES) "(small, all_tables)\n" #elif defined(LTC_TWOFISH_TABLES) && defined(LTC_TWOFISH_ALL_TABLES) "(tables, all_tables)\n" #elif defined(LTC_TWOFISH_SMALL) "(small)\n" #elif defined(LTC_TWOFISH_TABLES) "(tables)\n" #elif defined(LTC_TWOFISH_ALL_TABLES) "(all_tables)\n" #else "\n" #endif #endif #if defined(LTC_DES) " LTC_DES\n" #endif #if defined(LTC_CAST5) " LTC_CAST5\n" #endif #if defined(LTC_NOEKEON) " Noekeon\n" #endif #if defined(LTC_SKIPJACK) " Skipjack\n" #endif #if defined(LTC_KHAZAD) " Khazad\n" #endif #if defined(LTC_ANUBIS) " Anubis " #endif #if defined(LTC_ANUBIS_TWEAK) " (tweaked)" #endif "\n" #if defined(LTC_KSEED) " LTC_KSEED\n" #endif #if defined(LTC_KASUMI) " KASUMI\n" #endif "\nHashes built-in:\n" #if defined(LTC_SHA512) " LTC_SHA-512\n" #endif #if defined(LTC_SHA384) " LTC_SHA-384\n" #endif #if defined(LTC_SHA256) " LTC_SHA-256\n" #endif #if defined(LTC_SHA224) " LTC_SHA-224\n" #endif #if defined(LTC_TIGER) " LTC_TIGER\n" #endif #if defined(LTC_SHA1) " LTC_SHA1\n" #endif #if defined(LTC_MD5) " LTC_MD5\n" #endif #if defined(LTC_MD4) " LTC_MD4\n" #endif #if defined(LTC_MD2) " LTC_MD2\n" #endif #if defined(LTC_RIPEMD128) " LTC_RIPEMD128\n" #endif #if defined(LTC_RIPEMD160) " LTC_RIPEMD160\n" #endif #if defined(LTC_RIPEMD256) " LTC_RIPEMD256\n" #endif #if defined(LTC_RIPEMD320) " LTC_RIPEMD320\n" #endif #if defined(LTC_WHIRLPOOL) " LTC_WHIRLPOOL\n" #endif #if defined(LTC_CHC_HASH) " LTC_CHC_HASH \n" #endif "\nBlock Chaining Modes:\n" #if defined(LTC_CFB_MODE) " CFB\n" #endif #if defined(LTC_OFB_MODE) " OFB\n" #endif #if defined(LTC_ECB_MODE) " ECB\n" #endif #if defined(LTC_CBC_MODE) " CBC\n" #endif #if defined(LTC_CTR_MODE) " CTR " #endif #if defined(LTC_CTR_OLD) " (CTR_OLD) " #endif "\n" #if defined(LRW_MODE) " LRW_MODE" #if defined(LRW_TABLES) " (LRW_TABLES) " #endif "\n" #endif #if defined(LTC_F8_MODE) " F8 MODE\n" #endif #if defined(LTC_XTS_MODE) " LTC_XTS_MODE\n" #endif "\nMACs:\n" #if defined(LTC_HMAC) " LTC_HMAC\n" #endif #if defined(LTC_OMAC) " LTC_OMAC\n" #endif #if defined(LTC_PMAC) " PMAC\n" #endif #if defined(LTC_PELICAN) " LTC_PELICAN\n" #endif #if defined(LTC_XCBC) " XCBC-MAC\n" #endif #if defined(LTC_F9_MODE) " F9-MAC\n" #endif "\nENC + AUTH modes:\n" #if defined(LTC_EAX_MODE) " LTC_EAX_MODE\n" #endif #if defined(LTC_OCB_MODE) " LTC_OCB_MODE\n" #endif #if defined(LTC_CCM_MODE) " LTC_CCM_MODE\n" #endif #if defined(LTC_GCM_MODE) " LTC_GCM_MODE " #endif #if defined(LTC_GCM_TABLES) " (LTC_GCM_TABLES) " #endif "\n" "\nPRNG:\n" #if defined(LTC_YARROW) " Yarrow\n" #endif #if defined(LTC_SPRNG) " LTC_SPRNG\n" #endif #if defined(LTC_RC4) " LTC_RC4\n" #endif #if defined(LTC_FORTUNA) " Fortuna\n" #endif #if defined(LTC_SOBER128) " LTC_SOBER128\n" #endif "\nPK Algs:\n" #if defined(LTC_MRSA) " RSA \n" #endif #if defined(LTC_MECC) " ECC\n" #endif #if defined(LTC_MDSA) " DSA\n" #endif #if defined(MKAT) " Katja\n" #endif "\nCompiler:\n" #if defined(WIN32) " WIN32 platform detected.\n" #endif #if defined(__CYGWIN__) " CYGWIN Detected.\n" #endif #if defined(__DJGPP__) " DJGPP Detected.\n" #endif #if defined(_MSC_VER) " MSVC compiler detected.\n" #endif #if defined(__GNUC__) " GCC compiler detected.\n" #endif #if defined(INTEL_CC) " Intel C Compiler detected.\n" #endif #if defined(__x86_64__) " x86-64 detected.\n" #endif #if defined(LTC_PPC32) " LTC_PPC32 defined \n" #endif "\nVarious others: " #if defined(LTC_BASE64) " LTC_BASE64 " #endif #if defined(MPI) " MPI " #endif #if defined(TRY_UNRANDOM_FIRST) " TRY_UNRANDOM_FIRST " #endif #if defined(LTC_TEST) " LTC_TEST " #endif #if defined(LTC_PKCS_1) " LTC_PKCS#1 " #endif #if defined(LTC_PKCS_5) " LTC_PKCS#5 " #endif #if defined(LTC_SMALL_CODE) " LTC_SMALL_CODE " #endif #if defined(LTC_NO_FILE) " LTC_NO_FILE " #endif #if defined(LTC_DER) " LTC_DER " #endif #if defined(LTC_FAST) " LTC_FAST " #endif #if defined(LTC_NO_FAST) " LTC_NO_FAST " #endif #if defined(LTC_NO_BSWAP) " LTC_NO_BSWAP " #endif #if defined(LTC_NO_ASM) " LTC_NO_ASM " #endif #if defined(LTC_NO_TEST) " LTC_NO_TEST " #endif #if defined(LTC_NO_TABLES) " LTC_NO_TABLES " #endif #if defined(LTC_PTHREAD) " LTC_PTHREAD " #endif #if defined(LTM_LTC_DESC) " LTM_DESC " #endif #if defined(TFM_LTC_DESC) " TFM_DESC " #endif #if defined(LTC_MECC_ACCEL) " LTC_MECC_ACCEL " #endif #if defined(GMP_LTC_DESC) " GMP_DESC " #endif #if defined(LTC_EASY) " (easy) " #endif #if defined(LTC_MECC_FP) " LTC_MECC_FP " #endif #if defined(LTC_ECC_SHAMIR) " LTC_ECC_SHAMIR " #endif "\n" "\n\n\n" ; /* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt.c,v $ */ /* $Revision: 1.36 $ */ /* $Date: 2007/05/12 14:46:12 $ */ libtomcrypt-1.17/src/misc/crypt/crypt_ltc_mp_descriptor.c0000644000175100001440000000060110621351501022504 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" ltc_math_descriptor ltc_mp; libtomcrypt-1.17/src/misc/crypt/crypt_find_hash.c0000644000175100001440000000204410621351501020716 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file crypt_find_hash.c Find a hash, Tom St Denis */ /** Find a registered hash by name @param name The name of the hash to look for @return >= 0 if found, -1 if not present */ int find_hash(const char *name) { int x; LTC_ARGCHK(name != NULL); LTC_MUTEX_LOCK(<c_hash_mutex); for (x = 0; x < TAB_SIZE; x++) { if (hash_descriptor[x].name != NULL && XSTRCMP(hash_descriptor[x].name, name) == 0) { LTC_MUTEX_UNLOCK(<c_hash_mutex); return x; } } LTC_MUTEX_UNLOCK(<c_hash_mutex); return -1; } /* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_hash.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/misc/crypt/crypt_unregister_hash.c0000644000175100001440000000225010621351501022164 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file crypt_unregister_hash.c Unregister a hash, Tom St Denis */ /** Unregister a hash from the descriptor table @param hash The hash descriptor to remove @return CRYPT_OK on success */ int unregister_hash(const struct ltc_hash_descriptor *hash) { int x; LTC_ARGCHK(hash != NULL); /* is it already registered? */ LTC_MUTEX_LOCK(<c_hash_mutex); for (x = 0; x < TAB_SIZE; x++) { if (XMEMCMP(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)) == 0) { hash_descriptor[x].name = NULL; LTC_MUTEX_UNLOCK(<c_hash_mutex); return CRYPT_OK; } } LTC_MUTEX_UNLOCK(<c_hash_mutex); return CRYPT_ERROR; } /* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_unregister_hash.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/misc/crypt/crypt_cipher_is_valid.c0000644000175100001440000000174510621351501022126 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file crypt_cipher_is_valid.c Determine if cipher is valid, Tom St Denis */ /* Test if a cipher index is valid @param idx The index of the cipher to search for @return CRYPT_OK if valid */ int cipher_is_valid(int idx) { LTC_MUTEX_LOCK(<c_cipher_mutex); if (idx < 0 || idx >= TAB_SIZE || cipher_descriptor[idx].name == NULL) { LTC_MUTEX_UNLOCK(<c_cipher_mutex); return CRYPT_INVALID_CIPHER; } LTC_MUTEX_UNLOCK(<c_cipher_mutex); return CRYPT_OK; } /* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_cipher_is_valid.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/misc/crypt/crypt_find_hash_id.c0000644000175100001440000000204010621351501021366 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file crypt_find_hash_id.c Find hash by ID, Tom St Denis */ /** Find a hash by ID number @param ID The ID (not same as index) of the hash to find @return >= 0 if found, -1 if not present */ int find_hash_id(unsigned char ID) { int x; LTC_MUTEX_LOCK(<c_hash_mutex); for (x = 0; x < TAB_SIZE; x++) { if (hash_descriptor[x].ID == ID) { x = (hash_descriptor[x].name == NULL) ? -1 : x; LTC_MUTEX_UNLOCK(<c_hash_mutex); return x; } } LTC_MUTEX_UNLOCK(<c_hash_mutex); return -1; } /* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_hash_id.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/misc/crypt/crypt_find_cipher_id.c0000644000175100001440000000207010621351501021720 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file crypt_find_cipher_id.c Find cipher by ID, Tom St Denis */ /** Find a cipher by ID number @param ID The ID (not same as index) of the cipher to find @return >= 0 if found, -1 if not present */ int find_cipher_id(unsigned char ID) { int x; LTC_MUTEX_LOCK(<c_cipher_mutex); for (x = 0; x < TAB_SIZE; x++) { if (cipher_descriptor[x].ID == ID) { x = (cipher_descriptor[x].name == NULL) ? -1 : x; LTC_MUTEX_UNLOCK(<c_cipher_mutex); return x; } } LTC_MUTEX_UNLOCK(<c_cipher_mutex); return -1; } /* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_cipher_id.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/misc/crypt/crypt_find_prng.c0000644000175100001440000000204710621351501020744 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file crypt_find_prng.c Find a PRNG, Tom St Denis */ /** Find a registered PRNG by name @param name The name of the PRNG to look for @return >= 0 if found, -1 if not present */ int find_prng(const char *name) { int x; LTC_ARGCHK(name != NULL); LTC_MUTEX_LOCK(<c_prng_mutex); for (x = 0; x < TAB_SIZE; x++) { if ((prng_descriptor[x].name != NULL) && XSTRCMP(prng_descriptor[x].name, name) == 0) { LTC_MUTEX_UNLOCK(<c_prng_mutex); return x; } } LTC_MUTEX_UNLOCK(<c_prng_mutex); return -1; } /* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_prng.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/misc/crypt/crypt_cipher_descriptor.c0000644000175100001440000000147410621351501022511 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file crypt_cipher_descriptor.c Stores the cipher descriptor table, Tom St Denis */ struct ltc_cipher_descriptor cipher_descriptor[TAB_SIZE] = { { NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } }; LTC_MUTEX_GLOBAL(ltc_cipher_mutex) /* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_cipher_descriptor.c,v $ */ /* $Revision: 1.13 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/misc/crypt/crypt_find_hash_any.c0000644000175100001440000000252610621351501021572 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file crypt_find_hash_any.c Find a hash, Tom St Denis */ /** Find a hash flexibly. First by name then if not present by digest size @param name The name of the hash desired @param digestlen The minimum length of the digest size (octets) @return >= 0 if found, -1 if not present */int find_hash_any(const char *name, int digestlen) { int x, y, z; LTC_ARGCHK(name != NULL); x = find_hash(name); if (x != -1) return x; LTC_MUTEX_LOCK(<c_hash_mutex); y = MAXBLOCKSIZE+1; z = -1; for (x = 0; x < TAB_SIZE; x++) { if (hash_descriptor[x].name == NULL) { continue; } if ((int)hash_descriptor[x].hashsize >= digestlen && (int)hash_descriptor[x].hashsize < y) { z = x; y = hash_descriptor[x].hashsize; } } LTC_MUTEX_UNLOCK(<c_hash_mutex); return z; } /* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_hash_any.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/misc/crypt/crypt_unregister_prng.c0000644000175100001440000000225110621351501022210 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file crypt_unregister_prng.c Unregister a PRNG, Tom St Denis */ /** Unregister a PRNG from the descriptor table @param prng The PRNG descriptor to remove @return CRYPT_OK on success */ int unregister_prng(const struct ltc_prng_descriptor *prng) { int x; LTC_ARGCHK(prng != NULL); /* is it already registered? */ LTC_MUTEX_LOCK(<c_prng_mutex); for (x = 0; x < TAB_SIZE; x++) { if (XMEMCMP(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)) != 0) { prng_descriptor[x].name = NULL; LTC_MUTEX_UNLOCK(<c_prng_mutex); return CRYPT_OK; } } LTC_MUTEX_UNLOCK(<c_prng_mutex); return CRYPT_ERROR; } /* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_unregister_prng.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/misc/crypt/crypt_find_hash_oid.c0000644000175100001440000000200110621351501021542 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file crypt_find_hash_oid.c Find a hash, Tom St Denis */ int find_hash_oid(const unsigned long *ID, unsigned long IDlen) { int x; LTC_ARGCHK(ID != NULL); LTC_MUTEX_LOCK(<c_hash_mutex); for (x = 0; x < TAB_SIZE; x++) { if (hash_descriptor[x].name != NULL && hash_descriptor[x].OIDlen == IDlen && !XMEMCMP(hash_descriptor[x].OID, ID, sizeof(unsigned long) * IDlen)) { LTC_MUTEX_UNLOCK(<c_hash_mutex); return x; } } LTC_MUTEX_UNLOCK(<c_hash_mutex); return -1; } /* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_hash_oid.c,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/misc/crypt/crypt_hash_descriptor.c0000644000175100001440000000134710621351501022161 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file crypt_hash_descriptor.c Stores the hash descriptor table, Tom St Denis */ struct ltc_hash_descriptor hash_descriptor[TAB_SIZE] = { { NULL, 0, 0, 0, { 0 }, 0, NULL, NULL, NULL, NULL, NULL } }; LTC_MUTEX_GLOBAL(ltc_hash_mutex) /* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_hash_descriptor.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/misc/crypt/crypt_fsa.c0000644000175100001440000000255510621351501017553 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" #include /** @file crypt_fsa.c LibTomCrypt FULL SPEED AHEAD!, Tom St Denis */ /* format is ltc_mp, cipher_desc, [cipher_desc], NULL, hash_desc, [hash_desc], NULL, prng_desc, [prng_desc], NULL */ int crypt_fsa(void *mp, ...) { int err; va_list args; void *p; va_start(args, mp); if (mp != NULL) { XMEMCPY(<c_mp, mp, sizeof(ltc_mp)); } while ((p = va_arg(args, void*)) != NULL) { if ((err = register_cipher(p)) != CRYPT_OK) { va_end(args); return err; } } while ((p = va_arg(args, void*)) != NULL) { if ((err = register_hash(p)) != CRYPT_OK) { va_end(args); return err; } } while ((p = va_arg(args, void*)) != NULL) { if ((err = register_prng(p)) != CRYPT_OK) { va_end(args); return err; } } va_end(args); return CRYPT_OK; } /* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_fsa.c,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/misc/crypt/crypt_find_cipher_any.c0000644000175100001440000000273510621351501022123 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file crypt_find_cipher_any.c Find a cipher in the descriptor tables, Tom St Denis */ /** Find a cipher flexibly. First by name then if not present by block and key size @param name The name of the cipher desired @param blocklen The minimum length of the block cipher desired (octets) @param keylen The minimum length of the key size desired (octets) @return >= 0 if found, -1 if not present */ int find_cipher_any(const char *name, int blocklen, int keylen) { int x; LTC_ARGCHK(name != NULL); x = find_cipher(name); if (x != -1) return x; LTC_MUTEX_LOCK(<c_cipher_mutex); for (x = 0; x < TAB_SIZE; x++) { if (cipher_descriptor[x].name == NULL) { continue; } if (blocklen <= (int)cipher_descriptor[x].block_length && keylen <= (int)cipher_descriptor[x].max_key_length) { LTC_MUTEX_UNLOCK(<c_cipher_mutex); return x; } } LTC_MUTEX_UNLOCK(<c_cipher_mutex); return -1; } /* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_cipher_any.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/misc/crypt/crypt_find_cipher.c0000644000175100001440000000212010621351501021240 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file crypt_find_cipher.c Find a cipher in the descriptor tables, Tom St Denis */ /** Find a registered cipher by name @param name The name of the cipher to look for @return >= 0 if found, -1 if not present */ int find_cipher(const char *name) { int x; LTC_ARGCHK(name != NULL); LTC_MUTEX_LOCK(<c_cipher_mutex); for (x = 0; x < TAB_SIZE; x++) { if (cipher_descriptor[x].name != NULL && !XSTRCMP(cipher_descriptor[x].name, name)) { LTC_MUTEX_UNLOCK(<c_cipher_mutex); return x; } } LTC_MUTEX_UNLOCK(<c_cipher_mutex); return -1; } /* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_find_cipher.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/misc/crypt/crypt_prng_descriptor.c0000644000175100001440000000134210621351501022177 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file crypt_prng_descriptor.c Stores the PRNG descriptors, Tom St Denis */ struct ltc_prng_descriptor prng_descriptor[TAB_SIZE] = { { NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } }; LTC_MUTEX_GLOBAL(ltc_prng_mutex) /* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_prng_descriptor.c,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/misc/crypt/crypt_hash_is_valid.c0000644000175100001440000000172110621351501021571 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file crypt_hash_is_valid.c Determine if hash is valid, Tom St Denis */ /* Test if a hash index is valid @param idx The index of the hash to search for @return CRYPT_OK if valid */ int hash_is_valid(int idx) { LTC_MUTEX_LOCK(<c_hash_mutex); if (idx < 0 || idx >= TAB_SIZE || hash_descriptor[idx].name == NULL) { LTC_MUTEX_UNLOCK(<c_hash_mutex); return CRYPT_INVALID_HASH; } LTC_MUTEX_UNLOCK(<c_hash_mutex); return CRYPT_OK; } /* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_hash_is_valid.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/misc/crypt/crypt_register_cipher.c0000644000175100001440000000274110621351501022155 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file crypt_register_cipher.c Register a cipher, Tom St Denis */ /** Register a cipher with the descriptor table @param cipher The cipher you wish to register @return value >= 0 if successfully added (or already present), -1 if unsuccessful */ int register_cipher(const struct ltc_cipher_descriptor *cipher) { int x; LTC_ARGCHK(cipher != NULL); /* is it already registered? */ LTC_MUTEX_LOCK(<c_cipher_mutex); for (x = 0; x < TAB_SIZE; x++) { if (cipher_descriptor[x].name != NULL && cipher_descriptor[x].ID == cipher->ID) { LTC_MUTEX_UNLOCK(<c_cipher_mutex); return x; } } /* find a blank spot */ for (x = 0; x < TAB_SIZE; x++) { if (cipher_descriptor[x].name == NULL) { XMEMCPY(&cipher_descriptor[x], cipher, sizeof(struct ltc_cipher_descriptor)); LTC_MUTEX_UNLOCK(<c_cipher_mutex); return x; } } /* no spot */ LTC_MUTEX_UNLOCK(<c_cipher_mutex); return -1; } /* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_register_cipher.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/misc/crypt/crypt_argchk.c0000644000175100001440000000137710621351501020242 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" #include /** @file crypt_argchk.c Perform argument checking, Tom St Denis */ #if (ARGTYPE == 0) void crypt_argchk(char *v, char *s, int d) { fprintf(stderr, "LTC_ARGCHK '%s' failure on line %d of file %s\n", v, d, s); (void)raise(SIGABRT); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_argchk.c,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/misc/crypt/crypt_register_hash.c0000644000175100001440000000267610621351501021635 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file crypt_register_hash.c Register a HASH, Tom St Denis */ /** Register a hash with the descriptor table @param hash The hash you wish to register @return value >= 0 if successfully added (or already present), -1 if unsuccessful */ int register_hash(const struct ltc_hash_descriptor *hash) { int x; LTC_ARGCHK(hash != NULL); /* is it already registered? */ LTC_MUTEX_LOCK(<c_hash_mutex); for (x = 0; x < TAB_SIZE; x++) { if (XMEMCMP(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)) == 0) { LTC_MUTEX_UNLOCK(<c_hash_mutex); return x; } } /* find a blank spot */ for (x = 0; x < TAB_SIZE; x++) { if (hash_descriptor[x].name == NULL) { XMEMCPY(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)); LTC_MUTEX_UNLOCK(<c_hash_mutex); return x; } } /* no spot */ LTC_MUTEX_UNLOCK(<c_hash_mutex); return -1; } /* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_register_hash.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/misc/crypt/crypt_register_prng.c0000644000175100001440000000270010621351501021644 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file crypt_register_prng.c Register a PRNG, Tom St Denis */ /** Register a PRNG with the descriptor table @param prng The PRNG you wish to register @return value >= 0 if successfully added (or already present), -1 if unsuccessful */ int register_prng(const struct ltc_prng_descriptor *prng) { int x; LTC_ARGCHK(prng != NULL); /* is it already registered? */ LTC_MUTEX_LOCK(<c_prng_mutex); for (x = 0; x < TAB_SIZE; x++) { if (XMEMCMP(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)) == 0) { LTC_MUTEX_UNLOCK(<c_prng_mutex); return x; } } /* find a blank spot */ for (x = 0; x < TAB_SIZE; x++) { if (prng_descriptor[x].name == NULL) { XMEMCPY(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)); LTC_MUTEX_UNLOCK(<c_prng_mutex); return x; } } /* no spot */ LTC_MUTEX_UNLOCK(<c_prng_mutex); return -1; } /* $Source: /cvs/libtom/libtomcrypt/src/misc/crypt/crypt_register_prng.c,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/misc/pkcs5/0000755000175100001440000000000010621351501015272 5ustar tomuserslibtomcrypt-1.17/src/misc/pkcs5/pkcs_5_1.c0000644000175100001440000000556410621351501017054 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include /** @file pkcs_5_1.c LTC_PKCS #5, Algorithm #1, Tom St Denis */ #ifdef LTC_PKCS_5 /** Execute LTC_PKCS #5 v1 @param password The password (or key) @param password_len The length of the password (octet) @param salt The salt (or nonce) which is 8 octets long @param iteration_count The LTC_PKCS #5 v1 iteration count @param hash_idx The index of the hash desired @param out [out] The destination for this algorithm @param outlen [in/out] The max size and resulting size of the algorithm output @return CRYPT_OK if successful */ int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, const unsigned char *salt, int iteration_count, int hash_idx, unsigned char *out, unsigned long *outlen) { int err; unsigned long x; hash_state *md; unsigned char *buf; LTC_ARGCHK(password != NULL); LTC_ARGCHK(salt != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* test hash IDX */ if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { return err; } /* allocate memory */ md = XMALLOC(sizeof(hash_state)); buf = XMALLOC(MAXBLOCKSIZE); if (md == NULL || buf == NULL) { if (md != NULL) { XFREE(md); } if (buf != NULL) { XFREE(buf); } return CRYPT_MEM; } /* hash initial password + salt */ if ((err = hash_descriptor[hash_idx].init(md)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hash_descriptor[hash_idx].process(md, password, password_len)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hash_descriptor[hash_idx].process(md, salt, 8)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hash_descriptor[hash_idx].done(md, buf)) != CRYPT_OK) { goto LBL_ERR; } while (--iteration_count) { /* code goes here. */ x = MAXBLOCKSIZE; if ((err = hash_memory(hash_idx, buf, hash_descriptor[hash_idx].hashsize, buf, &x)) != CRYPT_OK) { goto LBL_ERR; } } /* copy upto outlen bytes */ for (x = 0; x < hash_descriptor[hash_idx].hashsize && x < *outlen; x++) { out[x] = buf[x]; } *outlen = x; err = CRYPT_OK; LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(buf, MAXBLOCKSIZE); zeromem(md, sizeof(hash_state)); #endif XFREE(buf); XFREE(md); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/misc/pkcs5/pkcs_5_1.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/misc/pkcs5/pkcs_5_2.c0000644000175100001440000000721610621351501017051 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include /** @file pkcs_5_2.c LTC_PKCS #5, Algorithm #2, Tom St Denis */ #ifdef LTC_PKCS_5 /** Execute LTC_PKCS #5 v2 @param password The input password (or key) @param password_len The length of the password (octets) @param salt The salt (or nonce) @param salt_len The length of the salt (octets) @param iteration_count # of iterations desired for LTC_PKCS #5 v2 [read specs for more] @param hash_idx The index of the hash desired @param out [out] The destination for this algorithm @param outlen [in/out] The max size and resulting size of the algorithm output @return CRYPT_OK if successful */ int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, const unsigned char *salt, unsigned long salt_len, int iteration_count, int hash_idx, unsigned char *out, unsigned long *outlen) { int err, itts; ulong32 blkno; unsigned long stored, left, x, y; unsigned char *buf[2]; hmac_state *hmac; LTC_ARGCHK(password != NULL); LTC_ARGCHK(salt != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* test hash IDX */ if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { return err; } buf[0] = XMALLOC(MAXBLOCKSIZE * 2); hmac = XMALLOC(sizeof(hmac_state)); if (hmac == NULL || buf[0] == NULL) { if (hmac != NULL) { XFREE(hmac); } if (buf[0] != NULL) { XFREE(buf[0]); } return CRYPT_MEM; } /* buf[1] points to the second block of MAXBLOCKSIZE bytes */ buf[1] = buf[0] + MAXBLOCKSIZE; left = *outlen; blkno = 1; stored = 0; while (left != 0) { /* process block number blkno */ zeromem(buf[0], MAXBLOCKSIZE*2); /* store current block number and increment for next pass */ STORE32H(blkno, buf[1]); ++blkno; /* get PRF(P, S||int(blkno)) */ if ((err = hmac_init(hmac, hash_idx, password, password_len)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hmac_process(hmac, salt, salt_len)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hmac_process(hmac, buf[1], 4)) != CRYPT_OK) { goto LBL_ERR; } x = MAXBLOCKSIZE; if ((err = hmac_done(hmac, buf[0], &x)) != CRYPT_OK) { goto LBL_ERR; } /* now compute repeated and XOR it in buf[1] */ XMEMCPY(buf[1], buf[0], x); for (itts = 1; itts < iteration_count; ++itts) { if ((err = hmac_memory(hash_idx, password, password_len, buf[0], x, buf[0], &x)) != CRYPT_OK) { goto LBL_ERR; } for (y = 0; y < x; y++) { buf[1][y] ^= buf[0][y]; } } /* now emit upto x bytes of buf[1] to output */ for (y = 0; y < x && left != 0; ++y) { out[stored++] = buf[1][y]; --left; } } *outlen = stored; err = CRYPT_OK; LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(buf[0], MAXBLOCKSIZE*2); zeromem(hmac, sizeof(hmac_state)); #endif XFREE(hmac); XFREE(buf[0]); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/misc/pkcs5/pkcs_5_2.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/misc/base64/0000755000175100001440000000000010621351501015331 5ustar tomuserslibtomcrypt-1.17/src/misc/base64/base64_encode.c0000644000175100001440000000422310621351501020077 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file base64_encode.c Compliant base64 encoder donated by Wayne Scott (wscott@bitmover.com) */ #ifdef LTC_BASE64 static const char *codes = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /** base64 Encode a buffer (NUL terminated) @param in The input buffer to encode @param inlen The length of the input buffer @param out [out] The destination of the base64 encoded data @param outlen [in/out] The max size and resulting size @return CRYPT_OK if successful */ int base64_encode(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { unsigned long i, len2, leven; unsigned char *p; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); /* valid output size ? */ len2 = 4 * ((inlen + 2) / 3); if (*outlen < len2 + 1) { *outlen = len2 + 1; return CRYPT_BUFFER_OVERFLOW; } p = out; leven = 3*(inlen / 3); for (i = 0; i < leven; i += 3) { *p++ = codes[(in[0] >> 2) & 0x3F]; *p++ = codes[(((in[0] & 3) << 4) + (in[1] >> 4)) & 0x3F]; *p++ = codes[(((in[1] & 0xf) << 2) + (in[2] >> 6)) & 0x3F]; *p++ = codes[in[2] & 0x3F]; in += 3; } /* Pad it if necessary... */ if (i < inlen) { unsigned a = in[0]; unsigned b = (i+1 < inlen) ? in[1] : 0; *p++ = codes[(a >> 2) & 0x3F]; *p++ = codes[(((a & 3) << 4) + (b >> 4)) & 0x3F]; *p++ = (i+1 < inlen) ? codes[(((b & 0xf) << 2)) & 0x3F] : '='; *p++ = '='; } /* append a NULL byte */ *p = '\0'; /* return ok */ *outlen = p - out; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/misc/base64/base64_encode.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/misc/base64/base64_decode.c0000644000175100001440000000667110621351501020076 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file base64_decode.c Compliant base64 code donated by Wayne Scott (wscott@bitmover.com) */ #ifdef LTC_BASE64 static const unsigned char map[256] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }; /** base64 decode a block of memory @param in The base64 data to decode @param inlen The length of the base64 data @param out [out] The destination of the binary decoded data @param outlen [in/out] The max size and resulting size of the decoded data @return CRYPT_OK if successful */ int base64_decode(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { unsigned long t, x, y, z; unsigned char c; int g; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); g = 3; for (x = y = z = t = 0; x < inlen; x++) { c = map[in[x]&0xFF]; if (c == 255) continue; /* the final = symbols are read and used to trim the remaining bytes */ if (c == 254) { c = 0; /* prevent g < 0 which would potentially allow an overflow later */ if (--g < 0) { return CRYPT_INVALID_PACKET; } } else if (g != 3) { /* we only allow = to be at the end */ return CRYPT_INVALID_PACKET; } t = (t<<6)|c; if (++y == 4) { if (z + g > *outlen) { return CRYPT_BUFFER_OVERFLOW; } out[z++] = (unsigned char)((t>>16)&255); if (g > 1) out[z++] = (unsigned char)((t>>8)&255); if (g > 2) out[z++] = (unsigned char)(t&255); y = t = 0; } } if (y != 0) { return CRYPT_INVALID_PACKET; } *outlen = z; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/misc/base64/base64_decode.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/misc/burn_stack.c0000644000175100001440000000143210621351501016544 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file burn_stack.c Burn stack, Tom St Denis */ /** Burn some stack memory @param len amount of stack to burn in bytes */ void burn_stack(unsigned long len) { unsigned char buf[32]; zeromem(buf, sizeof(buf)); if (len > (unsigned long)sizeof(buf)) burn_stack(len - sizeof(buf)); } /* $Source: /cvs/libtom/libtomcrypt/src/misc/burn_stack.c,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/misc/error_to_string.c0000644000175100001440000000340010621351501017627 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file error_to_string.c Convert error codes to ASCII strings, Tom St Denis */ static const char *err_2_str[] = { "CRYPT_OK", "CRYPT_ERROR", "Non-fatal 'no-operation' requested.", "Invalid keysize for block cipher.", "Invalid number of rounds for block cipher.", "Algorithm failed test vectors.", "Buffer overflow.", "Invalid input packet.", "Invalid number of bits for a PRNG.", "Error reading the PRNG.", "Invalid cipher specified.", "Invalid hash specified.", "Invalid PRNG specified.", "Out of memory.", "Invalid PK key or key type specified for function.", "A private PK key is required.", "Invalid argument provided.", "File Not Found", "Invalid PK type.", "Invalid PK system.", "Duplicate PK key found on keyring.", "Key not found in keyring.", "Invalid sized parameter.", "Invalid size for prime.", }; /** Convert an LTC error code to ASCII @param err The error code @return A pointer to the ASCII NUL terminated string for the error or "Invalid error code." if the err code was not valid. */ const char *error_to_string(int err) { if (err < 0 || err >= (int)(sizeof(err_2_str)/sizeof(err_2_str[0]))) { return "Invalid error code."; } else { return err_2_str[err]; } } /* $Source: /cvs/libtom/libtomcrypt/src/misc/error_to_string.c,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/0000755000175100001440000000000010621351501014421 5ustar tomuserslibtomcrypt-1.17/src/modes/f8/0000755000175100001440000000000010621351501014736 5ustar tomuserslibtomcrypt-1.17/src/modes/f8/f8_setiv.c0000644000175100001440000000225510621351501016635 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file f8_setiv.c F8 implementation, set IV, Tom St Denis */ #ifdef LTC_F8_MODE /** Set an initial vector @param IV The initial vector @param len The length of the vector (in octets) @param f8 The F8 state @return CRYPT_OK if successful */ int f8_setiv(const unsigned char *IV, unsigned long len, symmetric_F8 *f8) { int err; LTC_ARGCHK(IV != NULL); LTC_ARGCHK(f8 != NULL); if ((err = cipher_is_valid(f8->cipher)) != CRYPT_OK) { return err; } if (len != (unsigned long)f8->blocklen) { return CRYPT_INVALID_ARG; } /* force next block */ f8->padlen = 0; return cipher_descriptor[f8->cipher].ecb_encrypt(IV, f8->IV, &f8->key); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/f8/f8_setiv.c,v $ */ /* $Revision: 1.3 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/f8/f8_encrypt.c0000644000175100001440000000603110621351501017163 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file f8_encrypt.c F8 implementation, encrypt data, Tom St Denis */ #ifdef LTC_F8_MODE /** F8 encrypt @param pt Plaintext @param ct [out] Ciphertext @param len Length of plaintext (octets) @param f8 F8 state @return CRYPT_OK if successful */ int f8_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_F8 *f8) { int err, x; unsigned char buf[MAXBLOCKSIZE]; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(f8 != NULL); if ((err = cipher_is_valid(f8->cipher)) != CRYPT_OK) { return err; } /* is blocklen/padlen valid? */ if (f8->blocklen < 0 || f8->blocklen > (int)sizeof(f8->IV) || f8->padlen < 0 || f8->padlen > (int)sizeof(f8->IV)) { return CRYPT_INVALID_ARG; } zeromem(buf, sizeof(buf)); /* make sure the pad is empty */ if (f8->padlen == f8->blocklen) { /* xor of IV, MIV and blockcnt == what goes into cipher */ STORE32H(f8->blockcnt, (buf+(f8->blocklen-4))); ++(f8->blockcnt); for (x = 0; x < f8->blocklen; x++) { f8->IV[x] ^= f8->MIV[x] ^ buf[x]; } if ((err = cipher_descriptor[f8->cipher].ecb_encrypt(f8->IV, f8->IV, &f8->key)) != CRYPT_OK) { return err; } f8->padlen = 0; } #ifdef LTC_FAST if (f8->padlen == 0) { while (len >= (unsigned long)f8->blocklen) { STORE32H(f8->blockcnt, (buf+(f8->blocklen-4))); ++(f8->blockcnt); for (x = 0; x < f8->blocklen; x += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE*)(&ct[x])) = *((LTC_FAST_TYPE*)(&pt[x])) ^ *((LTC_FAST_TYPE*)(&f8->IV[x])); *((LTC_FAST_TYPE*)(&f8->IV[x])) ^= *((LTC_FAST_TYPE*)(&f8->MIV[x])) ^ *((LTC_FAST_TYPE*)(&buf[x])); } if ((err = cipher_descriptor[f8->cipher].ecb_encrypt(f8->IV, f8->IV, &f8->key)) != CRYPT_OK) { return err; } len -= x; pt += x; ct += x; } } #endif while (len > 0) { if (f8->padlen == f8->blocklen) { /* xor of IV, MIV and blockcnt == what goes into cipher */ STORE32H(f8->blockcnt, (buf+(f8->blocklen-4))); ++(f8->blockcnt); for (x = 0; x < f8->blocklen; x++) { f8->IV[x] ^= f8->MIV[x] ^ buf[x]; } if ((err = cipher_descriptor[f8->cipher].ecb_encrypt(f8->IV, f8->IV, &f8->key)) != CRYPT_OK) { return err; } f8->padlen = 0; } *ct++ = *pt++ ^ f8->IV[f8->padlen++]; --len; } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/f8/f8_encrypt.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/f8/f8_decrypt.c0000644000175100001440000000175710621351501017163 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file f8_decrypt.c F8 implementation, decrypt data, Tom St Denis */ #ifdef LTC_F8_MODE /** F8 decrypt @param ct Ciphertext @param pt [out] Plaintext @param len Length of ciphertext (octets) @param f8 F8 state @return CRYPT_OK if successful */ int f8_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_F8 *f8) { LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(f8 != NULL); return f8_encrypt(ct, pt, len, f8); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/f8/f8_decrypt.c,v $ */ /* $Revision: 1.3 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/f8/f8_done.c0000644000175100001440000000162110621351501016424 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file f8_done.c F8 implementation, finish chain, Tom St Denis */ #ifdef LTC_F8_MODE /** Terminate the chain @param f8 The F8 chain to terminate @return CRYPT_OK on success */ int f8_done(symmetric_F8 *f8) { int err; LTC_ARGCHK(f8 != NULL); if ((err = cipher_is_valid(f8->cipher)) != CRYPT_OK) { return err; } cipher_descriptor[f8->cipher].done(&f8->key); return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/f8/f8_done.c,v $ */ /* $Revision: 1.3 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/f8/f8_start.c0000644000175100001440000000565310621351501016645 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file f8_start.c F8 implementation, start chain, Tom St Denis */ #ifdef LTC_F8_MODE /** Initialize an F8 context @param cipher The index of the cipher desired @param IV The initial vector @param key The secret key @param keylen The length of the secret key (octets) @param salt_key The salting key for the IV @param skeylen The length of the salting key (octets) @param num_rounds Number of rounds in the cipher desired (0 for default) @param f8 The F8 state to initialize @return CRYPT_OK if successful */ int f8_start( int cipher, const unsigned char *IV, const unsigned char *key, int keylen, const unsigned char *salt_key, int skeylen, int num_rounds, symmetric_F8 *f8) { int x, err; unsigned char tkey[MAXBLOCKSIZE]; LTC_ARGCHK(IV != NULL); LTC_ARGCHK(key != NULL); LTC_ARGCHK(salt_key != NULL); LTC_ARGCHK(f8 != NULL); if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { return err; } #ifdef LTC_FAST if (cipher_descriptor[cipher].block_length % sizeof(LTC_FAST_TYPE)) { return CRYPT_INVALID_ARG; } #endif /* copy details */ f8->blockcnt = 0; f8->cipher = cipher; f8->blocklen = cipher_descriptor[cipher].block_length; f8->padlen = f8->blocklen; /* now get key ^ salt_key [extend salt_ket with 0x55 as required to match length] */ zeromem(tkey, sizeof(tkey)); for (x = 0; x < keylen && x < (int)sizeof(tkey); x++) { tkey[x] = key[x]; } for (x = 0; x < skeylen && x < (int)sizeof(tkey); x++) { tkey[x] ^= salt_key[x]; } for (; x < keylen && x < (int)sizeof(tkey); x++) { tkey[x] ^= 0x55; } /* now encrypt with tkey[0..keylen-1] the IV and use that as the IV */ if ((err = cipher_descriptor[cipher].setup(tkey, keylen, num_rounds, &f8->key)) != CRYPT_OK) { return err; } /* encrypt IV */ if ((err = cipher_descriptor[f8->cipher].ecb_encrypt(IV, f8->MIV, &f8->key)) != CRYPT_OK) { cipher_descriptor[f8->cipher].done(&f8->key); return err; } zeromem(tkey, sizeof(tkey)); zeromem(f8->IV, sizeof(f8->IV)); /* terminate this cipher */ cipher_descriptor[f8->cipher].done(&f8->key); /* init the cipher */ return cipher_descriptor[cipher].setup(key, keylen, num_rounds, &f8->key); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/f8/f8_start.c,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/f8/f8_test_mode.c0000644000175100001440000000515010621351501017463 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file f8_test_mode.c F8 implementation, test, Tom St Denis */ #ifdef LTC_F8_MODE int f8_test_mode(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const unsigned char key[16] = { 0x23, 0x48, 0x29, 0x00, 0x84, 0x67, 0xbe, 0x18, 0x6c, 0x3d, 0xe1, 0x4a, 0xae, 0x72, 0xd6, 0x2c }; static const unsigned char salt[4] = { 0x32, 0xf2, 0x87, 0x0d }; static const unsigned char IV[16] = { 0x00, 0x6e, 0x5c, 0xba, 0x50, 0x68, 0x1d, 0xe5, 0x5c, 0x62, 0x15, 0x99, 0xd4, 0x62, 0x56, 0x4a }; static const unsigned char pt[39] = { 0x70, 0x73, 0x65, 0x75, 0x64, 0x6f, 0x72, 0x61, 0x6e, 0x64, 0x6f, 0x6d, 0x6e, 0x65, 0x73, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x6e, 0x65, 0x78, 0x74, 0x20, 0x62, 0x65, 0x73, 0x74, 0x20, 0x74, 0x68, 0x69, 0x6e, 0x67 }; static const unsigned char ct[39] = { 0x01, 0x9c, 0xe7, 0xa2, 0x6e, 0x78, 0x54, 0x01, 0x4a, 0x63, 0x66, 0xaa, 0x95, 0xd4, 0xee, 0xfd, 0x1a, 0xd4, 0x17, 0x2a, 0x14, 0xf9, 0xfa, 0xf4, 0x55, 0xb7, 0xf1, 0xd4, 0xb6, 0x2b, 0xd0, 0x8f, 0x56, 0x2c, 0x0e, 0xef, 0x7c, 0x48, 0x02 }; unsigned char buf[39]; symmetric_F8 f8; int err, idx; idx = find_cipher("aes"); if (idx == -1) { idx = find_cipher("rijndael"); if (idx == -1) return CRYPT_NOP; } /* initialize the context */ if ((err = f8_start(idx, IV, key, sizeof(key), salt, sizeof(salt), 0, &f8)) != CRYPT_OK) { return err; } /* encrypt block */ if ((err = f8_encrypt(pt, buf, sizeof(pt), &f8)) != CRYPT_OK) { f8_done(&f8); return err; } f8_done(&f8); /* compare */ if (XMEMCMP(buf, ct, sizeof(ct))) { return CRYPT_FAIL_TESTVECTOR; } return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/f8/f8_test_mode.c,v $ */ /* $Revision: 1.4 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/f8/f8_getiv.c0000644000175100001440000000223210621351501016614 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file ofb_getiv.c F8 implementation, get IV, Tom St Denis */ #ifdef LTC_F8_MODE /** Get the current initial vector @param IV [out] The destination of the initial vector @param len [in/out] The max size and resulting size of the initial vector @param f8 The F8 state @return CRYPT_OK if successful */ int f8_getiv(unsigned char *IV, unsigned long *len, symmetric_F8 *f8) { LTC_ARGCHK(IV != NULL); LTC_ARGCHK(len != NULL); LTC_ARGCHK(f8 != NULL); if ((unsigned long)f8->blocklen > *len) { *len = f8->blocklen; return CRYPT_BUFFER_OVERFLOW; } XMEMCPY(IV, f8->IV, f8->blocklen); *len = f8->blocklen; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/f8/f8_getiv.c,v $ */ /* $Revision: 1.3 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/cbc/0000755000175100001440000000000010621351501015150 5ustar tomuserslibtomcrypt-1.17/src/modes/cbc/cbc_setiv.c0000644000175100001440000000202210621351501017251 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file cbc_setiv.c CBC implementation, set IV, Tom St Denis */ #ifdef LTC_CBC_MODE /** Set an initial vector @param IV The initial vector @param len The length of the vector (in octets) @param cbc The CBC state @return CRYPT_OK if successful */ int cbc_setiv(const unsigned char *IV, unsigned long len, symmetric_CBC *cbc) { LTC_ARGCHK(IV != NULL); LTC_ARGCHK(cbc != NULL); if (len != (unsigned long)cbc->blocklen) { return CRYPT_INVALID_ARG; } XMEMCPY(cbc->IV, IV, len); return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/cbc/cbc_setiv.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/cbc/cbc_encrypt.c0000644000175100001440000000523210621351501017611 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file cbc_encrypt.c CBC implementation, encrypt block, Tom St Denis */ #ifdef LTC_CBC_MODE /** CBC encrypt @param pt Plaintext @param ct [out] Ciphertext @param len The number of bytes to process (must be multiple of block length) @param cbc CBC state @return CRYPT_OK if successful */ int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CBC *cbc) { int x, err; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(cbc != NULL); if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) { return err; } /* is blocklen valid? */ if (cbc->blocklen < 1 || cbc->blocklen > (int)sizeof(cbc->IV)) { return CRYPT_INVALID_ARG; } if (len % cbc->blocklen) { return CRYPT_INVALID_ARG; } #ifdef LTC_FAST if (cbc->blocklen % sizeof(LTC_FAST_TYPE)) { return CRYPT_INVALID_ARG; } #endif if (cipher_descriptor[cbc->cipher].accel_cbc_encrypt != NULL) { return cipher_descriptor[cbc->cipher].accel_cbc_encrypt(pt, ct, len / cbc->blocklen, cbc->IV, &cbc->key); } else { while (len) { /* xor IV against plaintext */ #if defined(LTC_FAST) for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) ^= *((LTC_FAST_TYPE*)((unsigned char *)pt + x)); } #else for (x = 0; x < cbc->blocklen; x++) { cbc->IV[x] ^= pt[x]; } #endif /* encrypt */ if ((err = cipher_descriptor[cbc->cipher].ecb_encrypt(cbc->IV, ct, &cbc->key)) != CRYPT_OK) { return err; } /* store IV [ciphertext] for a future block */ #if defined(LTC_FAST) for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) = *((LTC_FAST_TYPE*)((unsigned char *)ct + x)); } #else for (x = 0; x < cbc->blocklen; x++) { cbc->IV[x] = ct[x]; } #endif ct += cbc->blocklen; pt += cbc->blocklen; len -= cbc->blocklen; } } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/cbc/cbc_encrypt.c,v $ */ /* $Revision: 1.14 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/cbc/cbc_done.c0000644000175100001440000000163710621351501017057 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file cbc_done.c CBC implementation, finish chain, Tom St Denis */ #ifdef LTC_CBC_MODE /** Terminate the chain @param cbc The CBC chain to terminate @return CRYPT_OK on success */ int cbc_done(symmetric_CBC *cbc) { int err; LTC_ARGCHK(cbc != NULL); if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) { return err; } cipher_descriptor[cbc->cipher].done(&cbc->key); return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/cbc/cbc_done.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/cbc/cbc_decrypt.c0000644000175100001440000000517210621351501017602 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file cbc_decrypt.c CBC implementation, encrypt block, Tom St Denis */ #ifdef LTC_CBC_MODE /** CBC decrypt @param ct Ciphertext @param pt [out] Plaintext @param len The number of bytes to process (must be multiple of block length) @param cbc CBC state @return CRYPT_OK if successful */ int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CBC *cbc) { int x, err; unsigned char tmp[16]; #ifdef LTC_FAST LTC_FAST_TYPE tmpy; #else unsigned char tmpy; #endif LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(cbc != NULL); if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) { return err; } /* is blocklen valid? */ if (cbc->blocklen < 1 || cbc->blocklen > (int)sizeof(cbc->IV)) { return CRYPT_INVALID_ARG; } if (len % cbc->blocklen) { return CRYPT_INVALID_ARG; } #ifdef LTC_FAST if (cbc->blocklen % sizeof(LTC_FAST_TYPE)) { return CRYPT_INVALID_ARG; } #endif if (cipher_descriptor[cbc->cipher].accel_cbc_decrypt != NULL) { return cipher_descriptor[cbc->cipher].accel_cbc_decrypt(ct, pt, len / cbc->blocklen, cbc->IV, &cbc->key); } else { while (len) { /* decrypt */ if ((err = cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key)) != CRYPT_OK) { return err; } /* xor IV against plaintext */ #if defined(LTC_FAST) for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) { tmpy = *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) ^ *((LTC_FAST_TYPE*)((unsigned char *)tmp + x)); *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) = *((LTC_FAST_TYPE*)((unsigned char *)ct + x)); *((LTC_FAST_TYPE*)((unsigned char *)pt + x)) = tmpy; } #else for (x = 0; x < cbc->blocklen; x++) { tmpy = tmp[x] ^ cbc->IV[x]; cbc->IV[x] = ct[x]; pt[x] = tmpy; } #endif ct += cbc->blocklen; pt += cbc->blocklen; len -= cbc->blocklen; } } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/cbc/cbc_decrypt.c,v $ */ /* $Revision: 1.16 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/cbc/cbc_start.c0000644000175100001440000000320010621351501017253 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file cbc_start.c CBC implementation, start chain, Tom St Denis */ #ifdef LTC_CBC_MODE /** Initialize a CBC context @param cipher The index of the cipher desired @param IV The initial vector @param key The secret key @param keylen The length of the secret key (octets) @param num_rounds Number of rounds in the cipher desired (0 for default) @param cbc The CBC state to initialize @return CRYPT_OK if successful */ int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key, int keylen, int num_rounds, symmetric_CBC *cbc) { int x, err; LTC_ARGCHK(IV != NULL); LTC_ARGCHK(key != NULL); LTC_ARGCHK(cbc != NULL); /* bad param? */ if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { return err; } /* setup cipher */ if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cbc->key)) != CRYPT_OK) { return err; } /* copy IV */ cbc->blocklen = cipher_descriptor[cipher].block_length; cbc->cipher = cipher; for (x = 0; x < cbc->blocklen; x++) { cbc->IV[x] = IV[x]; } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/cbc/cbc_start.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/cbc/cbc_getiv.c0000644000175100001440000000224710621351501017246 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file cbc_getiv.c CBC implementation, get IV, Tom St Denis */ #ifdef LTC_CBC_MODE /** Get the current initial vector @param IV [out] The destination of the initial vector @param len [in/out] The max size and resulting size of the initial vector @param cbc The CBC state @return CRYPT_OK if successful */ int cbc_getiv(unsigned char *IV, unsigned long *len, symmetric_CBC *cbc) { LTC_ARGCHK(IV != NULL); LTC_ARGCHK(len != NULL); LTC_ARGCHK(cbc != NULL); if ((unsigned long)cbc->blocklen > *len) { *len = cbc->blocklen; return CRYPT_BUFFER_OVERFLOW; } XMEMCPY(IV, cbc->IV, cbc->blocklen); *len = cbc->blocklen; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/cbc/cbc_getiv.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/cfb/0000755000175100001440000000000010621351501015153 5ustar tomuserslibtomcrypt-1.17/src/modes/cfb/cfb_getiv.c0000644000175100001440000000224710621351501017254 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file cfb_getiv.c CFB implementation, get IV, Tom St Denis */ #ifdef LTC_CFB_MODE /** Get the current initial vector @param IV [out] The destination of the initial vector @param len [in/out] The max size and resulting size of the initial vector @param cfb The CFB state @return CRYPT_OK if successful */ int cfb_getiv(unsigned char *IV, unsigned long *len, symmetric_CFB *cfb) { LTC_ARGCHK(IV != NULL); LTC_ARGCHK(len != NULL); LTC_ARGCHK(cfb != NULL); if ((unsigned long)cfb->blocklen > *len) { *len = cfb->blocklen; return CRYPT_BUFFER_OVERFLOW; } XMEMCPY(IV, cfb->IV, cfb->blocklen); *len = cfb->blocklen; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/cfb/cfb_getiv.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/cfb/cfb_done.c0000644000175100001440000000163710621351501017065 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file cfb_done.c CFB implementation, finish chain, Tom St Denis */ #ifdef LTC_CFB_MODE /** Terminate the chain @param cfb The CFB chain to terminate @return CRYPT_OK on success */ int cfb_done(symmetric_CFB *cfb) { int err; LTC_ARGCHK(cfb != NULL); if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) { return err; } cipher_descriptor[cfb->cipher].done(&cfb->key); return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/cfb/cfb_done.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/cfb/cfb_encrypt.c0000644000175100001440000000320010621351501017610 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file cfb_encrypt.c CFB implementation, encrypt data, Tom St Denis */ #ifdef LTC_CFB_MODE /** CFB encrypt @param pt Plaintext @param ct [out] Ciphertext @param len Length of plaintext (octets) @param cfb CFB state @return CRYPT_OK if successful */ int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb) { int err; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(cfb != NULL); if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) { return err; } /* is blocklen/padlen valid? */ if (cfb->blocklen < 0 || cfb->blocklen > (int)sizeof(cfb->IV) || cfb->padlen < 0 || cfb->padlen > (int)sizeof(cfb->pad)) { return CRYPT_INVALID_ARG; } while (len-- > 0) { if (cfb->padlen == cfb->blocklen) { if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) { return err; } cfb->padlen = 0; } cfb->pad[cfb->padlen] = (*ct = *pt ^ cfb->IV[cfb->padlen]); ++pt; ++ct; ++(cfb->padlen); } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/cfb/cfb_encrypt.c,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/cfb/cfb_decrypt.c0000644000175100001440000000322610621351501017606 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file cfb_decrypt.c CFB implementation, decrypt data, Tom St Denis */ #ifdef LTC_CFB_MODE /** CFB decrypt @param ct Ciphertext @param pt [out] Plaintext @param len Length of ciphertext (octets) @param cfb CFB state @return CRYPT_OK if successful */ int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb) { int err; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(cfb != NULL); if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) { return err; } /* is blocklen/padlen valid? */ if (cfb->blocklen < 0 || cfb->blocklen > (int)sizeof(cfb->IV) || cfb->padlen < 0 || cfb->padlen > (int)sizeof(cfb->pad)) { return CRYPT_INVALID_ARG; } while (len-- > 0) { if (cfb->padlen == cfb->blocklen) { if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) { return err; } cfb->padlen = 0; } cfb->pad[cfb->padlen] = *ct; *pt = *ct ^ cfb->IV[cfb->padlen]; ++pt; ++ct; ++(cfb->padlen); } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/cfb/cfb_decrypt.c,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/cfb/cfb_setiv.c0000644000175100001440000000231210621351501017261 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file cfb_setiv.c CFB implementation, set IV, Tom St Denis */ #ifdef LTC_CFB_MODE /** Set an initial vector @param IV The initial vector @param len The length of the vector (in octets) @param cfb The CFB state @return CRYPT_OK if successful */ int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb) { int err; LTC_ARGCHK(IV != NULL); LTC_ARGCHK(cfb != NULL); if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) { return err; } if (len != (unsigned long)cfb->blocklen) { return CRYPT_INVALID_ARG; } /* force next block */ cfb->padlen = 0; return cipher_descriptor[cfb->cipher].ecb_encrypt(IV, cfb->IV, &cfb->key); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/cfb/cfb_setiv.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/cfb/cfb_start.c0000644000175100001440000000333010621351501017265 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file cfb_start.c CFB implementation, start chain, Tom St Denis */ #ifdef LTC_CFB_MODE /** Initialize a CFB context @param cipher The index of the cipher desired @param IV The initial vector @param key The secret key @param keylen The length of the secret key (octets) @param num_rounds Number of rounds in the cipher desired (0 for default) @param cfb The CFB state to initialize @return CRYPT_OK if successful */ int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key, int keylen, int num_rounds, symmetric_CFB *cfb) { int x, err; LTC_ARGCHK(IV != NULL); LTC_ARGCHK(key != NULL); LTC_ARGCHK(cfb != NULL); if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { return err; } /* copy data */ cfb->cipher = cipher; cfb->blocklen = cipher_descriptor[cipher].block_length; for (x = 0; x < cfb->blocklen; x++) cfb->IV[x] = IV[x]; /* init the cipher */ if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cfb->key)) != CRYPT_OK) { return err; } /* encrypt the IV */ cfb->padlen = 0; return cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->IV, cfb->IV, &cfb->key); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/cfb/cfb_start.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/ctr/0000755000175100001440000000000010621351501015211 5ustar tomuserslibtomcrypt-1.17/src/modes/ctr/ctr_setiv.c0000644000175100001440000000241310621351501017357 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file ctr_setiv.c CTR implementation, set IV, Tom St Denis */ #ifdef LTC_CTR_MODE /** Set an initial vector @param IV The initial vector @param len The length of the vector (in octets) @param ctr The CTR state @return CRYPT_OK if successful */ int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr) { int err; LTC_ARGCHK(IV != NULL); LTC_ARGCHK(ctr != NULL); /* bad param? */ if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) { return err; } if (len != (unsigned long)ctr->blocklen) { return CRYPT_INVALID_ARG; } /* set IV */ XMEMCPY(ctr->ctr, IV, len); /* force next block */ ctr->padlen = 0; return cipher_descriptor[ctr->cipher].ecb_encrypt(IV, ctr->pad, &ctr->key); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/ctr/ctr_setiv.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/ctr/ctr_start.c0000644000175100001440000000574610621351501017376 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file ctr_start.c CTR implementation, start chain, Tom St Denis */ #ifdef LTC_CTR_MODE /** Initialize a CTR context @param cipher The index of the cipher desired @param IV The initial vector @param key The secret key @param keylen The length of the secret key (octets) @param num_rounds Number of rounds in the cipher desired (0 for default) @param ctr_mode The counter mode (CTR_COUNTER_LITTLE_ENDIAN or CTR_COUNTER_BIG_ENDIAN) @param ctr The CTR state to initialize @return CRYPT_OK if successful */ int ctr_start( int cipher, const unsigned char *IV, const unsigned char *key, int keylen, int num_rounds, int ctr_mode, symmetric_CTR *ctr) { int x, err; LTC_ARGCHK(IV != NULL); LTC_ARGCHK(key != NULL); LTC_ARGCHK(ctr != NULL); /* bad param? */ if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { return err; } /* ctrlen == counter width */ ctr->ctrlen = (ctr_mode & 255) ? (ctr_mode & 255) : cipher_descriptor[cipher].block_length; if (ctr->ctrlen > cipher_descriptor[cipher].block_length) { return CRYPT_INVALID_ARG; } if ((ctr_mode & 0x1000) == CTR_COUNTER_BIG_ENDIAN) { ctr->ctrlen = cipher_descriptor[cipher].block_length - ctr->ctrlen; } /* setup cipher */ if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ctr->key)) != CRYPT_OK) { return err; } /* copy ctr */ ctr->blocklen = cipher_descriptor[cipher].block_length; ctr->cipher = cipher; ctr->padlen = 0; ctr->mode = ctr_mode & 0x1000; for (x = 0; x < ctr->blocklen; x++) { ctr->ctr[x] = IV[x]; } if (ctr_mode & LTC_CTR_RFC3686) { /* increment the IV as per RFC 3686 */ if (ctr->mode == CTR_COUNTER_LITTLE_ENDIAN) { /* little-endian */ for (x = 0; x < ctr->ctrlen; x++) { ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255; if (ctr->ctr[x] != (unsigned char)0) { break; } } } else { /* big-endian */ for (x = ctr->blocklen-1; x >= ctr->ctrlen; x--) { ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255; if (ctr->ctr[x] != (unsigned char)0) { break; } } } } return cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/ctr/ctr_start.c,v $ */ /* $Revision: 1.15 $ */ /* $Date: 2007/02/23 14:18:37 $ */ libtomcrypt-1.17/src/modes/ctr/ctr_getiv.c0000644000175100001440000000225010621351501017342 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file ctr_getiv.c CTR implementation, get IV, Tom St Denis */ #ifdef LTC_CTR_MODE /** Get the current initial vector @param IV [out] The destination of the initial vector @param len [in/out] The max size and resulting size of the initial vector @param ctr The CTR state @return CRYPT_OK if successful */ int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr) { LTC_ARGCHK(IV != NULL); LTC_ARGCHK(len != NULL); LTC_ARGCHK(ctr != NULL); if ((unsigned long)ctr->blocklen > *len) { *len = ctr->blocklen; return CRYPT_BUFFER_OVERFLOW; } XMEMCPY(IV, ctr->ctr, ctr->blocklen); *len = ctr->blocklen; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/ctr/ctr_getiv.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/ctr/ctr_done.c0000644000175100001440000000163710621351501017161 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file ctr_done.c CTR implementation, finish chain, Tom St Denis */ #ifdef LTC_CTR_MODE /** Terminate the chain @param ctr The CTR chain to terminate @return CRYPT_OK on success */ int ctr_done(symmetric_CTR *ctr) { int err; LTC_ARGCHK(ctr != NULL); if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) { return err; } cipher_descriptor[ctr->cipher].done(&ctr->key); return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/ctr/ctr_done.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/ctr/ctr_encrypt.c0000644000175100001440000000660710621351501017722 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file ctr_encrypt.c CTR implementation, encrypt data, Tom St Denis */ #ifdef LTC_CTR_MODE /** CTR encrypt @param pt Plaintext @param ct [out] Ciphertext @param len Length of plaintext (octets) @param ctr CTR state @return CRYPT_OK if successful */ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr) { int x, err; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(ctr != NULL); if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) { return err; } /* is blocklen/padlen valid? */ if (ctr->blocklen < 1 || ctr->blocklen > (int)sizeof(ctr->ctr) || ctr->padlen < 0 || ctr->padlen > (int)sizeof(ctr->pad)) { return CRYPT_INVALID_ARG; } #ifdef LTC_FAST if (ctr->blocklen % sizeof(LTC_FAST_TYPE)) { return CRYPT_INVALID_ARG; } #endif /* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */ if ((ctr->padlen == ctr->blocklen) && cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL && (len >= (unsigned long)ctr->blocklen)) { if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) { return err; } len %= ctr->blocklen; } while (len) { /* is the pad empty? */ if (ctr->padlen == ctr->blocklen) { /* increment counter */ if (ctr->mode == CTR_COUNTER_LITTLE_ENDIAN) { /* little-endian */ for (x = 0; x < ctr->ctrlen; x++) { ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255; if (ctr->ctr[x] != (unsigned char)0) { break; } } } else { /* big-endian */ for (x = ctr->blocklen-1; x >= ctr->ctrlen; x--) { ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255; if (ctr->ctr[x] != (unsigned char)0) { break; } } } /* encrypt it */ if ((err = cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key)) != CRYPT_OK) { return err; } ctr->padlen = 0; } #ifdef LTC_FAST if (ctr->padlen == 0 && len >= (unsigned long)ctr->blocklen) { for (x = 0; x < ctr->blocklen; x += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE*)((unsigned char *)ct + x)) = *((LTC_FAST_TYPE*)((unsigned char *)pt + x)) ^ *((LTC_FAST_TYPE*)((unsigned char *)ctr->pad + x)); } pt += ctr->blocklen; ct += ctr->blocklen; len -= ctr->blocklen; ctr->padlen = ctr->blocklen; continue; } #endif *ct++ = *pt++ ^ ctr->pad[ctr->padlen++]; --len; } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/ctr/ctr_encrypt.c,v $ */ /* $Revision: 1.22 $ */ /* $Date: 2007/02/22 20:26:05 $ */ libtomcrypt-1.17/src/modes/ctr/ctr_decrypt.c0000644000175100001440000000177210621351501017706 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file ctr_decrypt.c CTR implementation, decrypt data, Tom St Denis */ #ifdef LTC_CTR_MODE /** CTR decrypt @param ct Ciphertext @param pt [out] Plaintext @param len Length of ciphertext (octets) @param ctr CTR state @return CRYPT_OK if successful */ int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr) { LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(ctr != NULL); return ctr_encrypt(ct, pt, len, ctr); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/ctr/ctr_decrypt.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/ctr/ctr_test.c0000644000175100001440000000476710621351501017222 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file ctr_test.c CTR implementation, Tests again RFC 3686, Tom St Denis */ #ifdef LTC_CTR_MODE int ctr_test(void) { #ifdef LTC_NO_TEST return CRYPT_NOP; #else static const struct { int keylen, msglen; unsigned char key[32], IV[16], pt[64], ct[64]; } tests[] = { /* 128-bit key, 16-byte pt */ { 16, 16, {0xAE,0x68,0x52,0xF8,0x12,0x10,0x67,0xCC,0x4B,0xF7,0xA5,0x76,0x55,0x77,0xF3,0x9E }, {0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, {0x53,0x69,0x6E,0x67,0x6C,0x65,0x20,0x62,0x6C,0x6F,0x63,0x6B,0x20,0x6D,0x73,0x67 }, {0xE4,0x09,0x5D,0x4F,0xB7,0xA7,0xB3,0x79,0x2D,0x61,0x75,0xA3,0x26,0x13,0x11,0xB8 }, }, /* 128-bit key, 36-byte pt */ { 16, 36, {0x76,0x91,0xBE,0x03,0x5E,0x50,0x20,0xA8,0xAC,0x6E,0x61,0x85,0x29,0xF9,0xA0,0xDC }, {0x00,0xE0,0x01,0x7B,0x27,0x77,0x7F,0x3F,0x4A,0x17,0x86,0xF0,0x00,0x00,0x00,0x00 }, {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F, 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F, 0x20,0x21,0x22,0x23}, {0xC1,0xCF,0x48,0xA8,0x9F,0x2F,0xFD,0xD9,0xCF,0x46,0x52,0xE9,0xEF,0xDB,0x72,0xD7, 0x45,0x40,0xA4,0x2B,0xDE,0x6D,0x78,0x36,0xD5,0x9A,0x5C,0xEA,0xAE,0xF3,0x10,0x53, 0x25,0xB2,0x07,0x2F }, }, }; int idx, err, x; unsigned char buf[64]; symmetric_CTR ctr; /* AES can be under rijndael or aes... try to find it */ if ((idx = find_cipher("aes")) == -1) { if ((idx = find_cipher("rijndael")) == -1) { return CRYPT_NOP; } } for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { if ((err = ctr_start(idx, tests[x].IV, tests[x].key, tests[x].keylen, 0, CTR_COUNTER_BIG_ENDIAN|LTC_CTR_RFC3686, &ctr)) != CRYPT_OK) { return err; } if ((err = ctr_encrypt(tests[x].pt, buf, tests[x].msglen, &ctr)) != CRYPT_OK) { return err; } ctr_done(&ctr); if (XMEMCMP(buf, tests[x].ct, tests[x].msglen)) { return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/ctr/ctr_test.c,v $ */ /* $Revision: 1.4 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/ecb/0000755000175100001440000000000010621351501015152 5ustar tomuserslibtomcrypt-1.17/src/modes/ecb/ecb_encrypt.c0000644000175100001440000000342610621351501017620 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file ecb_encrypt.c ECB implementation, encrypt a block, Tom St Denis */ #ifdef LTC_ECB_MODE /** ECB encrypt @param pt Plaintext @param ct [out] Ciphertext @param len The number of octets to process (must be multiple of the cipher block size) @param ecb ECB state @return CRYPT_OK if successful */ int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_ECB *ecb) { int err; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(ecb != NULL); if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) { return err; } if (len % cipher_descriptor[ecb->cipher].block_length) { return CRYPT_INVALID_ARG; } /* check for accel */ if (cipher_descriptor[ecb->cipher].accel_ecb_encrypt != NULL) { return cipher_descriptor[ecb->cipher].accel_ecb_encrypt(pt, ct, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key); } else { while (len) { if ((err = cipher_descriptor[ecb->cipher].ecb_encrypt(pt, ct, &ecb->key)) != CRYPT_OK) { return err; } pt += cipher_descriptor[ecb->cipher].block_length; ct += cipher_descriptor[ecb->cipher].block_length; len -= cipher_descriptor[ecb->cipher].block_length; } } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/ecb/ecb_encrypt.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/ecb/ecb_decrypt.c0000644000175100001440000000342610621351501017606 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file ecb_decrypt.c ECB implementation, decrypt a block, Tom St Denis */ #ifdef LTC_ECB_MODE /** ECB decrypt @param ct Ciphertext @param pt [out] Plaintext @param len The number of octets to process (must be multiple of the cipher block size) @param ecb ECB state @return CRYPT_OK if successful */ int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_ECB *ecb) { int err; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(ecb != NULL); if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) { return err; } if (len % cipher_descriptor[ecb->cipher].block_length) { return CRYPT_INVALID_ARG; } /* check for accel */ if (cipher_descriptor[ecb->cipher].accel_ecb_decrypt != NULL) { return cipher_descriptor[ecb->cipher].accel_ecb_decrypt(ct, pt, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key); } else { while (len) { if ((err = cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key)) != CRYPT_OK) { return err; } pt += cipher_descriptor[ecb->cipher].block_length; ct += cipher_descriptor[ecb->cipher].block_length; len -= cipher_descriptor[ecb->cipher].block_length; } } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/ecb/ecb_decrypt.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/ecb/ecb_start.c0000644000175100001440000000251210621351501017264 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file ecb_start.c ECB implementation, start chain, Tom St Denis */ #ifdef LTC_ECB_MODE /** Initialize a ECB context @param cipher The index of the cipher desired @param key The secret key @param keylen The length of the secret key (octets) @param num_rounds Number of rounds in the cipher desired (0 for default) @param ecb The ECB state to initialize @return CRYPT_OK if successful */ int ecb_start(int cipher, const unsigned char *key, int keylen, int num_rounds, symmetric_ECB *ecb) { int err; LTC_ARGCHK(key != NULL); LTC_ARGCHK(ecb != NULL); if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { return err; } ecb->cipher = cipher; ecb->blocklen = cipher_descriptor[cipher].block_length; return cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ecb->key); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/ecb/ecb_start.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/ecb/ecb_done.c0000644000175100001440000000163710621351501017063 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file ecb_done.c ECB implementation, finish chain, Tom St Denis */ #ifdef LTC_ECB_MODE /** Terminate the chain @param ecb The ECB chain to terminate @return CRYPT_OK on success */ int ecb_done(symmetric_ECB *ecb) { int err; LTC_ARGCHK(ecb != NULL); if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) { return err; } cipher_descriptor[ecb->cipher].done(&ecb->key); return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/ecb/ecb_done.c,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/lrw/0000755000175100001440000000000010621351501015225 5ustar tomuserslibtomcrypt-1.17/src/modes/lrw/lrw_test.c0000644000175100001440000001102310621351501017231 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file lrw_test.c LRW_MODE implementation, test LRW, Tom St Denis */ #ifdef LTC_LRW_MODE /** Test LRW against specs @return CRYPT_OK if goodly */ int lrw_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { unsigned char key[16], tweak[16], IV[16], P[16], expected_tweak[16], C[16]; } tests[] = { { { 0x45, 0x62, 0xac, 0x25, 0xf8, 0x28, 0x17, 0x6d, 0x4c, 0x26, 0x84, 0x14, 0xb5, 0x68, 0x01, 0x85 }, { 0x25, 0x8e, 0x2a, 0x05, 0xe7, 0x3e, 0x9d, 0x03, 0xee, 0x5a, 0x83, 0x0c, 0xcc, 0x09, 0x4c, 0x87 }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 }, { 0x25, 0x8e, 0x2a, 0x05, 0xe7, 0x3e, 0x9d, 0x03, 0xee, 0x5a, 0x83, 0x0c, 0xcc, 0x09, 0x4c, 0x87 }, { 0xf1, 0xb2, 0x73, 0xcd, 0x65, 0xa3, 0xdf, 0x5f, 0xe9, 0x5d, 0x48, 0x92, 0x54, 0x63, 0x4e, 0xb8 } }, { { 0x59, 0x70, 0x47, 0x14, 0xf5, 0x57, 0x47, 0x8c, 0xd7, 0x79, 0xe8, 0x0f, 0x54, 0x88, 0x79, 0x44 }, { 0x35, 0x23, 0xc2, 0xde, 0xc5, 0x69, 0x4f, 0xa8, 0x72, 0xa9, 0xac, 0xa7, 0x0b, 0x2b, 0xee, 0xbc }, { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 }, { 0x1a, 0x91, 0xe1, 0x6f, 0x62, 0xb4, 0xa7, 0xd4, 0x39, 0x54, 0xd6, 0x53, 0x85, 0x95, 0xf7, 0x5e }, { 0x00, 0xc8, 0x2b, 0xae, 0x95, 0xbb, 0xcd, 0xe5, 0x27, 0x4f, 0x07, 0x69, 0xb2, 0x60, 0xe1, 0x36 }, }, { { 0x59, 0x70, 0x47, 0x14, 0xf5, 0x57, 0x47, 0x8c, 0xd7, 0x79, 0xe8, 0x0f, 0x54, 0x88, 0x79, 0x44 }, { 0x67, 0x53, 0xc9, 0x0c, 0xb7, 0xd8, 0xcd, 0xe5, 0x06, 0xa0, 0x47, 0x78, 0x1a, 0xad, 0x85, 0x11 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02 }, { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 }, { 0x1a, 0x91, 0xe1, 0x6f, 0x62, 0xb4, 0xa7, 0xd4, 0x39, 0x54, 0xd6, 0x53, 0x85, 0x95, 0xf7, 0x5e }, { 0x00, 0xc8, 0x2b, 0xae, 0x95, 0xbb, 0xcd, 0xe5, 0x27, 0x4f, 0x07, 0x69, 0xb2, 0x60, 0xe1, 0x36 }, }, { { 0xd8, 0x2a, 0x91, 0x34, 0xb2, 0x6a, 0x56, 0x50, 0x30, 0xfe, 0x69, 0xe2, 0x37, 0x7f, 0x98, 0x47 }, { 0x4e, 0xb5, 0x5d, 0x31, 0x05, 0x97, 0x3a, 0x3f, 0x5e, 0x23, 0xda, 0xfb, 0x5a, 0x45, 0xd6, 0xc0 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00 }, { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46 }, { 0x18, 0xc9, 0x1f, 0x6d, 0x60, 0x1a, 0x1a, 0x37, 0x5d, 0x0b, 0x0e, 0xf7, 0x3a, 0xd5, 0x74, 0xc4 }, { 0x76, 0x32, 0x21, 0x83, 0xed, 0x8f, 0xf1, 0x82, 0xf9, 0x59, 0x62, 0x03, 0x69, 0x0e, 0x5e, 0x01 }, } }; int idx, err, x; symmetric_LRW lrw; unsigned char buf[2][16]; idx = find_cipher("aes"); if (idx == -1) { idx = find_cipher("rijndael"); if (idx == -1) { return CRYPT_NOP; } } for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { /* schedule it */ if ((err = lrw_start(idx, tests[x].IV, tests[x].key, 16, tests[x].tweak, 0, &lrw)) != CRYPT_OK) { return err; } /* check pad against expected tweak */ if (XMEMCMP(tests[x].expected_tweak, lrw.pad, 16)) { lrw_done(&lrw); return CRYPT_FAIL_TESTVECTOR; } /* process block */ if ((err = lrw_encrypt(tests[x].P, buf[0], 16, &lrw)) != CRYPT_OK) { lrw_done(&lrw); return err; } if (XMEMCMP(buf[0], tests[x].C, 16)) { lrw_done(&lrw); return CRYPT_FAIL_TESTVECTOR; } /* process block */ if ((err = lrw_setiv(tests[x].IV, 16, &lrw)) != CRYPT_OK) { lrw_done(&lrw); return err; } if ((err = lrw_decrypt(buf[0], buf[1], 16, &lrw)) != CRYPT_OK) { lrw_done(&lrw); return err; } if (XMEMCMP(buf[1], tests[x].P, 16)) { lrw_done(&lrw); return CRYPT_FAIL_TESTVECTOR; } if ((err = lrw_done(&lrw)) != CRYPT_OK) { return err; } } return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/lrw/lrw_test.c,v $ */ /* $Revision: 1.12 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/lrw/lrw_encrypt.c0000644000175100001440000000244110621351501017742 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file lrw_encrypt.c LRW_MODE implementation, Encrypt blocks, Tom St Denis */ #ifdef LTC_LRW_MODE /** LRW encrypt blocks @param pt The plaintext @param ct [out] The ciphertext @param len The length in octets, must be a multiple of 16 @param lrw The LRW state */ int lrw_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_LRW *lrw) { int err; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(lrw != NULL); if ((err = cipher_is_valid(lrw->cipher)) != CRYPT_OK) { return err; } if (cipher_descriptor[lrw->cipher].accel_lrw_encrypt != NULL) { return cipher_descriptor[lrw->cipher].accel_lrw_encrypt(pt, ct, len, lrw->IV, lrw->tweak, &lrw->key); } return lrw_process(pt, ct, len, LRW_ENCRYPT, lrw); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/lrw/lrw_encrypt.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/lrw/lrw_setiv.c0000644000175100001440000000367010621351501017415 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file lrw_setiv.c LRW_MODE implementation, Set the current IV, Tom St Denis */ #ifdef LTC_LRW_MODE /** Set the IV for LRW @param IV The IV, must be 16 octets @param len Length ... must be 16 :-) @param lrw The LRW state to update @return CRYPT_OK if successful */ int lrw_setiv(const unsigned char *IV, unsigned long len, symmetric_LRW *lrw) { int err; #ifdef LRW_TABLES unsigned char T[16]; int x, y; #endif LTC_ARGCHK(IV != NULL); LTC_ARGCHK(lrw != NULL); if (len != 16) { return CRYPT_INVALID_ARG; } if ((err = cipher_is_valid(lrw->cipher)) != CRYPT_OK) { return err; } /* copy the IV */ XMEMCPY(lrw->IV, IV, 16); /* check if we have to actually do work */ if (cipher_descriptor[lrw->cipher].accel_lrw_encrypt != NULL && cipher_descriptor[lrw->cipher].accel_lrw_decrypt != NULL) { /* we have accelerators, let's bail since they don't use lrw->pad anyways */ return CRYPT_OK; } #ifdef LRW_TABLES XMEMCPY(T, &lrw->PC[0][IV[0]][0], 16); for (x = 1; x < 16; x++) { #ifdef LTC_FAST for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE *)(T + y)) ^= *((LTC_FAST_TYPE *)(&lrw->PC[x][IV[x]][y])); } #else for (y = 0; y < 16; y++) { T[y] ^= lrw->PC[x][IV[x]][y]; } #endif } XMEMCPY(lrw->pad, T, 16); #else gcm_gf_mult(lrw->tweak, IV, lrw->pad); #endif return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/lrw/lrw_setiv.c,v $ */ /* $Revision: 1.13 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/lrw/lrw_decrypt.c0000644000175100001440000000244010621351501017727 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file lrw_decrypt.c LRW_MODE implementation, Decrypt blocks, Tom St Denis */ #ifdef LTC_LRW_MODE /** LRW decrypt blocks @param ct The ciphertext @param pt [out] The plaintext @param len The length in octets, must be a multiple of 16 @param lrw The LRW state */ int lrw_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_LRW *lrw) { int err; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(lrw != NULL); if ((err = cipher_is_valid(lrw->cipher)) != CRYPT_OK) { return err; } if (cipher_descriptor[lrw->cipher].accel_lrw_decrypt != NULL) { return cipher_descriptor[lrw->cipher].accel_lrw_decrypt(ct, pt, len, lrw->IV, lrw->tweak, &lrw->key); } return lrw_process(ct, pt, len, LRW_DECRYPT, lrw); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/lrw/lrw_decrypt.c,v $ */ /* $Revision: 1.9 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/lrw/lrw_start.c0000644000175100001440000000546310621351501017422 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file lrw_start.c LRW_MODE implementation, start mode, Tom St Denis */ #ifdef LTC_LRW_MODE /** Initialize the LRW context @param cipher The cipher desired, must be a 128-bit block cipher @param IV The index value, must be 128-bits @param key The cipher key @param keylen The length of the cipher key in octets @param tweak The tweak value (second key), must be 128-bits @param num_rounds The number of rounds for the cipher (0 == default) @param lrw [out] The LRW state @return CRYPT_OK on success. */ int lrw_start( int cipher, const unsigned char *IV, const unsigned char *key, int keylen, const unsigned char *tweak, int num_rounds, symmetric_LRW *lrw) { int err; #ifdef LRW_TABLES unsigned char B[16]; int x, y, z, t; #endif LTC_ARGCHK(IV != NULL); LTC_ARGCHK(key != NULL); LTC_ARGCHK(tweak != NULL); LTC_ARGCHK(lrw != NULL); #ifdef LTC_FAST if (16 % sizeof(LTC_FAST_TYPE)) { return CRYPT_INVALID_ARG; } #endif /* is cipher valid? */ if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { return err; } if (cipher_descriptor[cipher].block_length != 16) { return CRYPT_INVALID_CIPHER; } /* schedule key */ if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &lrw->key)) != CRYPT_OK) { return err; } lrw->cipher = cipher; /* copy the IV and tweak */ XMEMCPY(lrw->tweak, tweak, 16); #ifdef LRW_TABLES /* setup tables */ /* generate the first table as it has no shifting (from which we make the other tables) */ zeromem(B, 16); for (y = 0; y < 256; y++) { B[0] = y; gcm_gf_mult(tweak, B, &lrw->PC[0][y][0]); } /* now generate the rest of the tables based the previous table */ for (x = 1; x < 16; x++) { for (y = 0; y < 256; y++) { /* now shift it right by 8 bits */ t = lrw->PC[x-1][y][15]; for (z = 15; z > 0; z--) { lrw->PC[x][y][z] = lrw->PC[x-1][y][z-1]; } lrw->PC[x][y][0] = gcm_shift_table[t<<1]; lrw->PC[x][y][1] ^= gcm_shift_table[(t<<1)+1]; } } #endif /* generate first pad */ return lrw_setiv(IV, 16, lrw); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/lrw/lrw_start.c,v $ */ /* $Revision: 1.12 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/lrw/lrw_getiv.c0000644000175100001440000000213210621351501017371 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file lrw_getiv.c LRW_MODE implementation, Retrieve the current IV, Tom St Denis */ #ifdef LTC_LRW_MODE /** Get the IV for LRW @param IV [out] The IV, must be 16 octets @param len Length ... must be at least 16 :-) @param lrw The LRW state to read @return CRYPT_OK if successful */ int lrw_getiv(unsigned char *IV, unsigned long *len, symmetric_LRW *lrw) { LTC_ARGCHK(IV != NULL); LTC_ARGCHK(len != NULL); LTC_ARGCHK(lrw != NULL); if (*len < 16) { *len = 16; return CRYPT_BUFFER_OVERFLOW; } XMEMCPY(IV, lrw->IV, 16); *len = 16; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/lrw/lrw_getiv.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/lrw/lrw_process.c0000644000175100001440000000634310621351501017741 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file lrw_process.c LRW_MODE implementation, Encrypt/decrypt blocks, Tom St Denis */ #ifdef LTC_LRW_MODE /** Process blocks with LRW, since decrypt/encrypt are largely the same they share this code. @param pt The "input" data @param ct [out] The "output" data @param len The length of the input, must be a multiple of 128-bits (16 octets) @param mode LRW_ENCRYPT or LRW_DECRYPT @param lrw The LRW state @return CRYPT_OK if successful */ int lrw_process(const unsigned char *pt, unsigned char *ct, unsigned long len, int mode, symmetric_LRW *lrw) { unsigned char prod[16]; int x, err; #ifdef LRW_TABLES int y; #endif LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(lrw != NULL); if (len & 15) { return CRYPT_INVALID_ARG; } while (len) { /* copy pad */ XMEMCPY(prod, lrw->pad, 16); /* increment IV */ for (x = 15; x >= 0; x--) { lrw->IV[x] = (lrw->IV[x] + 1) & 255; if (lrw->IV[x]) { break; } } /* update pad */ #ifdef LRW_TABLES /* for each byte changed we undo it's affect on the pad then add the new product */ for (; x < 16; x++) { #ifdef LTC_FAST for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE *)(lrw->pad + y)) ^= *((LTC_FAST_TYPE *)(&lrw->PC[x][lrw->IV[x]][y])) ^ *((LTC_FAST_TYPE *)(&lrw->PC[x][(lrw->IV[x]-1)&255][y])); } #else for (y = 0; y < 16; y++) { lrw->pad[y] ^= lrw->PC[x][lrw->IV[x]][y] ^ lrw->PC[x][(lrw->IV[x]-1)&255][y]; } #endif } #else gcm_gf_mult(lrw->tweak, lrw->IV, lrw->pad); #endif /* xor prod */ #ifdef LTC_FAST for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE *)(ct + x)) = *((LTC_FAST_TYPE *)(pt + x)) ^ *((LTC_FAST_TYPE *)(prod + x)); } #else for (x = 0; x < 16; x++) { ct[x] = pt[x] ^ prod[x]; } #endif /* send through cipher */ if (mode == LRW_ENCRYPT) { if ((err = cipher_descriptor[lrw->cipher].ecb_encrypt(ct, ct, &lrw->key)) != CRYPT_OK) { return err; } } else { if ((err = cipher_descriptor[lrw->cipher].ecb_decrypt(ct, ct, &lrw->key)) != CRYPT_OK) { return err; } } /* xor prod */ #ifdef LTC_FAST for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE *)(ct + x)) = *((LTC_FAST_TYPE *)(ct + x)) ^ *((LTC_FAST_TYPE *)(prod + x)); } #else for (x = 0; x < 16; x++) { ct[x] = ct[x] ^ prod[x]; } #endif /* move to next */ pt += 16; ct += 16; len -= 16; } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/lrw/lrw_process.c,v $ */ /* $Revision: 1.11 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/lrw/lrw_done.c0000644000175100001440000000164610621351501017211 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file lrw_done.c LRW_MODE implementation, Free resources, Tom St Denis */ #ifdef LTC_LRW_MODE /** Terminate a LRW state @param lrw The state to terminate @return CRYPT_OK if successful */ int lrw_done(symmetric_LRW *lrw) { int err; LTC_ARGCHK(lrw != NULL); if ((err = cipher_is_valid(lrw->cipher)) != CRYPT_OK) { return err; } cipher_descriptor[lrw->cipher].done(&lrw->key); return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/lrw/lrw_done.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/ofb/0000755000175100001440000000000010621351501015167 5ustar tomuserslibtomcrypt-1.17/src/modes/ofb/ofb_done.c0000644000175100001440000000163710621351501017115 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file ofb_done.c OFB implementation, finish chain, Tom St Denis */ #ifdef LTC_OFB_MODE /** Terminate the chain @param ofb The OFB chain to terminate @return CRYPT_OK on success */ int ofb_done(symmetric_OFB *ofb) { int err; LTC_ARGCHK(ofb != NULL); if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) { return err; } cipher_descriptor[ofb->cipher].done(&ofb->key); return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/ofb/ofb_done.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/ofb/ofb_encrypt.c0000644000175100001440000000307510621351501017652 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file ofb_encrypt.c OFB implementation, encrypt data, Tom St Denis */ #ifdef LTC_OFB_MODE /** OFB encrypt @param pt Plaintext @param ct [out] Ciphertext @param len Length of plaintext (octets) @param ofb OFB state @return CRYPT_OK if successful */ int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_OFB *ofb) { int err; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(ofb != NULL); if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) { return err; } /* is blocklen/padlen valid? */ if (ofb->blocklen < 0 || ofb->blocklen > (int)sizeof(ofb->IV) || ofb->padlen < 0 || ofb->padlen > (int)sizeof(ofb->IV)) { return CRYPT_INVALID_ARG; } while (len-- > 0) { if (ofb->padlen == ofb->blocklen) { if ((err = cipher_descriptor[ofb->cipher].ecb_encrypt(ofb->IV, ofb->IV, &ofb->key)) != CRYPT_OK) { return err; } ofb->padlen = 0; } *ct++ = *pt++ ^ ofb->IV[(ofb->padlen)++]; } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/ofb/ofb_encrypt.c,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/ofb/ofb_decrypt.c0000644000175100001440000000177410621351501017644 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file ofb_decrypt.c OFB implementation, decrypt data, Tom St Denis */ #ifdef LTC_OFB_MODE /** OFB decrypt @param ct Ciphertext @param pt [out] Plaintext @param len Length of ciphertext (octets) @param ofb OFB state @return CRYPT_OK if successful */ int ofb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_OFB *ofb) { LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(ofb != NULL); return ofb_encrypt(ct, pt, len, ofb); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/ofb/ofb_decrypt.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/ofb/ofb_setiv.c0000644000175100001440000000227610621351501017322 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file ofb_setiv.c OFB implementation, set IV, Tom St Denis */ #ifdef LTC_OFB_MODE /** Set an initial vector @param IV The initial vector @param len The length of the vector (in octets) @param ofb The OFB state @return CRYPT_OK if successful */ int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb) { int err; LTC_ARGCHK(IV != NULL); LTC_ARGCHK(ofb != NULL); if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) { return err; } if (len != (unsigned long)ofb->blocklen) { return CRYPT_INVALID_ARG; } /* force next block */ ofb->padlen = 0; return cipher_descriptor[ofb->cipher].ecb_encrypt(IV, ofb->IV, &ofb->key); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/ofb/ofb_setiv.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/ofb/ofb_start.c0000644000175100001440000000312410621351501017316 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file ofb_start.c OFB implementation, start chain, Tom St Denis */ #ifdef LTC_OFB_MODE /** Initialize a OFB context @param cipher The index of the cipher desired @param IV The initial vector @param key The secret key @param keylen The length of the secret key (octets) @param num_rounds Number of rounds in the cipher desired (0 for default) @param ofb The OFB state to initialize @return CRYPT_OK if successful */ int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key, int keylen, int num_rounds, symmetric_OFB *ofb) { int x, err; LTC_ARGCHK(IV != NULL); LTC_ARGCHK(key != NULL); LTC_ARGCHK(ofb != NULL); if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { return err; } /* copy details */ ofb->cipher = cipher; ofb->blocklen = cipher_descriptor[cipher].block_length; for (x = 0; x < ofb->blocklen; x++) { ofb->IV[x] = IV[x]; } /* init the cipher */ ofb->padlen = ofb->blocklen; return cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ofb->key); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/ofb/ofb_start.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/ofb/ofb_getiv.c0000644000175100001440000000224710621351501017304 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file ofb_getiv.c OFB implementation, get IV, Tom St Denis */ #ifdef LTC_OFB_MODE /** Get the current initial vector @param IV [out] The destination of the initial vector @param len [in/out] The max size and resulting size of the initial vector @param ofb The OFB state @return CRYPT_OK if successful */ int ofb_getiv(unsigned char *IV, unsigned long *len, symmetric_OFB *ofb) { LTC_ARGCHK(IV != NULL); LTC_ARGCHK(len != NULL); LTC_ARGCHK(ofb != NULL); if ((unsigned long)ofb->blocklen > *len) { *len = ofb->blocklen; return CRYPT_BUFFER_OVERFLOW; } XMEMCPY(IV, ofb->IV, ofb->blocklen); *len = ofb->blocklen; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/ofb/ofb_getiv.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/modes/xts/0000755000175100001440000000000010621351501015237 5ustar tomuserslibtomcrypt-1.17/src/modes/xts/xts_mult_x.c0000644000175100001440000000162510621351501017615 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** Source donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) to the LibTom Projects */ #ifdef LTC_XTS_MODE /** multiply by x @param I The value to multiply by x (LFSR shift) */ void xts_mult_x(unsigned char *I) { int x; unsigned char t, tt; for (x = t = 0; x < 16; x++) { tt = I[x] >> 7; I[x] = ((I[x] << 1) | t) & 0xFF; t = tt; } if (tt) { I[0] ^= 0x87; } } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/xts/xts_mult_x.c,v $ */ /* $Revision: 1.4 $ */ /* $Date: 2007/03/10 23:59:09 $ */ libtomcrypt-1.17/src/modes/xts/xts_encrypt.c0000644000175100001440000000630610621351501017772 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** Source donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) to the LibTom Projects */ #ifdef LTC_XTS_MODE static int tweak_crypt(const unsigned char *P, unsigned char *C, unsigned char *T, symmetric_xts *xts) { unsigned long x; int err; /* tweak encrypt block i */ #ifdef LTC_FAST for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE*)&C[x]) = *((LTC_FAST_TYPE*)&P[x]) ^ *((LTC_FAST_TYPE*)&T[x]); } #else for (x = 0; x < 16; x++) { C[x] = P[x] ^ T[x]; } #endif if ((err = cipher_descriptor[xts->cipher].ecb_encrypt(C, C, &xts->key1)) != CRYPT_OK) { return err; } #ifdef LTC_FAST for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE*)&C[x]) ^= *((LTC_FAST_TYPE*)&T[x]); } #else for (x = 0; x < 16; x++) { C[x] = C[x] ^ T[x]; } #endif /* LFSR the tweak */ xts_mult_x(T); return CRYPT_OK; } /** XTS Encryption @param pt [in] Plaintext @param ptlen Length of plaintext (and ciphertext) @param ct [out] Ciphertext @param tweak [in] The 128--bit encryption tweak (e.g. sector number) @param xts The XTS structure Returns CRYPT_OK upon success */ int xts_encrypt( const unsigned char *pt, unsigned long ptlen, unsigned char *ct, const unsigned char *tweak, symmetric_xts *xts) { unsigned char PP[16], CC[16], T[16]; unsigned long i, m, mo, lim; int err; /* check inputs */ LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(tweak != NULL); LTC_ARGCHK(xts != NULL); /* check if valid */ if ((err = cipher_is_valid(xts->cipher)) != CRYPT_OK) { return err; } /* get number of blocks */ m = ptlen >> 4; mo = ptlen & 15; /* must have at least one full block */ if (m == 0) { return CRYPT_INVALID_ARG; } /* encrypt the tweak */ if ((err = cipher_descriptor[xts->cipher].ecb_encrypt(tweak, T, &xts->key2)) != CRYPT_OK) { return err; } /* for i = 0 to m-2 do */ if (mo == 0) { lim = m; } else { lim = m - 1; } for (i = 0; i < lim; i++) { err = tweak_crypt(pt, ct, T, xts); ct += 16; pt += 16; } /* if ptlen not divide 16 then */ if (mo > 0) { /* CC = tweak encrypt block m-1 */ if ((err = tweak_crypt(pt, CC, T, xts)) != CRYPT_OK) { return err; } /* Cm = first ptlen % 16 bytes of CC */ for (i = 0; i < mo; i++) { PP[i] = pt[16+i]; ct[16+i] = CC[i]; } for (; i < 16; i++) { PP[i] = CC[i]; } /* Cm-1 = Tweak encrypt PP */ if ((err = tweak_crypt(PP, ct, T, xts)) != CRYPT_OK) { return err; } } return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/xts/xts_encrypt.c,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2007/05/12 14:05:56 $ */ libtomcrypt-1.17/src/modes/xts/xts_done.c0000644000175100001440000000153010621351501017225 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** Source donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) to the LibTom Projects */ #ifdef LTC_XTS_MODE /** Terminate XTS state @param XTS The state to terminate */ void xts_done(symmetric_xts *xts) { LTC_ARGCHKVD(xts != NULL); cipher_descriptor[xts->cipher].done(&xts->key1); cipher_descriptor[xts->cipher].done(&xts->key2); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/xts/xts_done.c,v $ */ /* $Revision: 1.4 $ */ /* $Date: 2007/03/10 23:59:09 $ */ libtomcrypt-1.17/src/modes/xts/xts_decrypt.c0000644000175100001440000000633110621351501017756 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** Source donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) to the LibTom Projects */ #ifdef LTC_XTS_MODE static int tweak_uncrypt(const unsigned char *C, unsigned char *P, unsigned char *T, symmetric_xts *xts) { unsigned long x; int err; /* tweak encrypt block i */ #ifdef LTC_FAST for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE*)&P[x]) = *((LTC_FAST_TYPE*)&C[x]) ^ *((LTC_FAST_TYPE*)&T[x]); } #else for (x = 0; x < 16; x++) { P[x] = C[x] ^ T[x]; } #endif err = cipher_descriptor[xts->cipher].ecb_decrypt(P, P, &xts->key1); #ifdef LTC_FAST for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE*)&P[x]) ^= *((LTC_FAST_TYPE*)&T[x]); } #else for (x = 0; x < 16; x++) { P[x] = P[x] ^ T[x]; } #endif /* LFSR the tweak */ xts_mult_x(T); return err; } /** XTS Decryption @param ct [in] Ciphertext @param ptlen Length of plaintext (and ciphertext) @param pt [out] Plaintext @param tweak [in] The 128--bit encryption tweak (e.g. sector number) @param xts The XTS structure Returns CRYPT_OK upon success */int xts_decrypt( const unsigned char *ct, unsigned long ptlen, unsigned char *pt, const unsigned char *tweak, symmetric_xts *xts) { unsigned char PP[16], CC[16], T[16]; unsigned long i, m, mo, lim; int err; /* check inputs */ LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(tweak != NULL); LTC_ARGCHK(xts != NULL); /* check if valid */ if ((err = cipher_is_valid(xts->cipher)) != CRYPT_OK) { return err; } /* get number of blocks */ m = ptlen >> 4; mo = ptlen & 15; /* must have at least one full block */ if (m == 0) { return CRYPT_INVALID_ARG; } /* encrypt the tweak */ if ((err = cipher_descriptor[xts->cipher].ecb_encrypt(tweak, T, &xts->key2)) != CRYPT_OK) { return err; } /* for i = 0 to m-2 do */ if (mo == 0) { lim = m; } else { lim = m - 1; } for (i = 0; i < lim; i++) { err = tweak_uncrypt(ct, pt, T, xts); ct += 16; pt += 16; } /* if ptlen not divide 16 then */ if (mo > 0) { XMEMCPY(CC, T, 16); xts_mult_x(CC); /* PP = tweak decrypt block m-1 */ if ((err = tweak_uncrypt(ct, PP, CC, xts)) != CRYPT_OK) { return err; } /* Pm = first ptlen % 16 bytes of PP */ for (i = 0; i < mo; i++) { CC[i] = ct[16+i]; pt[16+i] = PP[i]; } for (; i < 16; i++) { CC[i] = PP[i]; } /* Pm-1 = Tweak uncrypt CC */ if ((err = tweak_uncrypt(CC, pt, T, xts)) != CRYPT_OK) { return err; } } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/xts/xts_decrypt.c,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2007/05/12 14:05:56 $ */ libtomcrypt-1.17/src/modes/xts/xts_init.c0000644000175100001440000000354110621351501017247 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** Source donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) to the LibTom Projects */ #ifdef LTC_XTS_MODE /** Start XTS mode @param cipher The index of the cipher to use @param key1 The encrypt key @param key2 The tweak encrypt key @param keylen The length of the keys (each) in octets @param num_rounds The number of rounds for the cipher (0 == default) @param xts [out] XTS structure Returns CRYPT_OK upon success. */ int xts_start( int cipher, const unsigned char *key1, const unsigned char *key2, unsigned long keylen, int num_rounds, symmetric_xts *xts) { int err; /* check inputs */ LTC_ARGCHK(key1 != NULL); LTC_ARGCHK(key2 != NULL); LTC_ARGCHK(xts != NULL); /* check if valid */ if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { return err; } if (cipher_descriptor[cipher].block_length != 16) { return CRYPT_INVALID_ARG; } /* schedule the two ciphers */ if ((err = cipher_descriptor[cipher].setup(key1, keylen, num_rounds, &xts->key1)) != CRYPT_OK) { return err; } if ((err = cipher_descriptor[cipher].setup(key2, keylen, num_rounds, &xts->key2)) != CRYPT_OK) { return err; } xts->cipher = cipher; return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/xts/xts_init.c,v $ */ /* $Revision: 1.4 $ */ /* $Date: 2007/03/10 23:59:09 $ */ libtomcrypt-1.17/src/modes/xts/xts_test.c0000644000175100001440000002522510621351501017266 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" #ifdef LTC_XTS_MODE /** Source donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) to the LibTom Projects Returns CRYPT_OK upon success. */ int xts_test(void) { #ifdef LTC_NO_TEST return CRYPT_NOP; #else static const struct { int keylen; unsigned char key1[32]; unsigned char key2[32]; ulong64 seqnum; unsigned long PTLEN; unsigned char PTX[512], CTX[512]; } tests[] = { /* #1 32 byte key, 32 byte PTX */ { 32, { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, 32, { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, { 0x91,0x7c,0xf6,0x9e,0xbd,0x68,0xb2,0xec,0x9b,0x9f,0xe9,0xa3,0xea,0xdd,0xa6,0x92,0xcd,0x43,0xd2,0xf5,0x95,0x98,0xed,0x85,0x8c,0x02,0xc2,0x65,0x2f,0xbf,0x92,0x2e }, }, /* #2, 32 byte key, 32 byte PTX */ { 32, { 0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11 }, { 0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22 }, CONST64(0x3333333333), 32, { 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44 }, { 0xc4,0x54,0x18,0x5e,0x6a,0x16,0x93,0x6e,0x39,0x33,0x40,0x38,0xac,0xef,0x83,0x8b,0xfb,0x18,0x6f,0xff,0x74,0x80,0xad,0xc4,0x28,0x93,0x82,0xec,0xd6,0xd3,0x94,0xf0 }, }, /* #5 from xts.7, 32 byte key, 32 byte PTX */ { 32, { 0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0 }, { 0xbf,0xbe,0xbd,0xbc,0xbb,0xba,0xb9,0xb8,0xb7,0xb6,0xb5,0xb4,0xb3,0xb2,0xb1,0xb0 }, CONST64(0x123456789a), 32, { 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44 }, { 0xb0,0x1f,0x86,0xf8,0xed,0xc1,0x86,0x37,0x06,0xfa,0x8a,0x42,0x53,0xe3,0x4f,0x28,0xaf,0x31,0x9d,0xe3,0x83,0x34,0x87,0x0f,0x4d,0xd1,0xf9,0x4c,0xbe,0x98,0x32,0xf1 }, }, /* #4, 32 byte key, 512 byte PTX */ { 32, { 0x27,0x18,0x28,0x18,0x28,0x45,0x90,0x45,0x23,0x53,0x60,0x28,0x74,0x71,0x35,0x26 }, { 0x31,0x41,0x59,0x26,0x53,0x58,0x97,0x93,0x23,0x84,0x62,0x64,0x33,0x83,0x27,0x95 }, 0, 512, { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f, 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f, 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f, 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf, 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf, 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff, 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f, 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f, 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f, 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf, 0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf, 0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff, }, { 0x27,0xa7,0x47,0x9b,0xef,0xa1,0xd4,0x76,0x48,0x9f,0x30,0x8c,0xd4,0xcf,0xa6,0xe2,0xa9,0x6e,0x4b,0xbe,0x32,0x08,0xff,0x25,0x28,0x7d,0xd3,0x81,0x96,0x16,0xe8,0x9c, 0xc7,0x8c,0xf7,0xf5,0xe5,0x43,0x44,0x5f,0x83,0x33,0xd8,0xfa,0x7f,0x56,0x00,0x00,0x05,0x27,0x9f,0xa5,0xd8,0xb5,0xe4,0xad,0x40,0xe7,0x36,0xdd,0xb4,0xd3,0x54,0x12, 0x32,0x80,0x63,0xfd,0x2a,0xab,0x53,0xe5,0xea,0x1e,0x0a,0x9f,0x33,0x25,0x00,0xa5,0xdf,0x94,0x87,0xd0,0x7a,0x5c,0x92,0xcc,0x51,0x2c,0x88,0x66,0xc7,0xe8,0x60,0xce, 0x93,0xfd,0xf1,0x66,0xa2,0x49,0x12,0xb4,0x22,0x97,0x61,0x46,0xae,0x20,0xce,0x84,0x6b,0xb7,0xdc,0x9b,0xa9,0x4a,0x76,0x7a,0xae,0xf2,0x0c,0x0d,0x61,0xad,0x02,0x65, 0x5e,0xa9,0x2d,0xc4,0xc4,0xe4,0x1a,0x89,0x52,0xc6,0x51,0xd3,0x31,0x74,0xbe,0x51,0xa1,0x0c,0x42,0x11,0x10,0xe6,0xd8,0x15,0x88,0xed,0xe8,0x21,0x03,0xa2,0x52,0xd8, 0xa7,0x50,0xe8,0x76,0x8d,0xef,0xff,0xed,0x91,0x22,0x81,0x0a,0xae,0xb9,0x9f,0x91,0x72,0xaf,0x82,0xb6,0x04,0xdc,0x4b,0x8e,0x51,0xbc,0xb0,0x82,0x35,0xa6,0xf4,0x34, 0x13,0x32,0xe4,0xca,0x60,0x48,0x2a,0x4b,0xa1,0xa0,0x3b,0x3e,0x65,0x00,0x8f,0xc5,0xda,0x76,0xb7,0x0b,0xf1,0x69,0x0d,0xb4,0xea,0xe2,0x9c,0x5f,0x1b,0xad,0xd0,0x3c, 0x5c,0xcf,0x2a,0x55,0xd7,0x05,0xdd,0xcd,0x86,0xd4,0x49,0x51,0x1c,0xeb,0x7e,0xc3,0x0b,0xf1,0x2b,0x1f,0xa3,0x5b,0x91,0x3f,0x9f,0x74,0x7a,0x8a,0xfd,0x1b,0x13,0x0e, 0x94,0xbf,0xf9,0x4e,0xff,0xd0,0x1a,0x91,0x73,0x5c,0xa1,0x72,0x6a,0xcd,0x0b,0x19,0x7c,0x4e,0x5b,0x03,0x39,0x36,0x97,0xe1,0x26,0x82,0x6f,0xb6,0xbb,0xde,0x8e,0xcc, 0x1e,0x08,0x29,0x85,0x16,0xe2,0xc9,0xed,0x03,0xff,0x3c,0x1b,0x78,0x60,0xf6,0xde,0x76,0xd4,0xce,0xcd,0x94,0xc8,0x11,0x98,0x55,0xef,0x52,0x97,0xca,0x67,0xe9,0xf3, 0xe7,0xff,0x72,0xb1,0xe9,0x97,0x85,0xca,0x0a,0x7e,0x77,0x20,0xc5,0xb3,0x6d,0xc6,0xd7,0x2c,0xac,0x95,0x74,0xc8,0xcb,0xbc,0x2f,0x80,0x1e,0x23,0xe5,0x6f,0xd3,0x44, 0xb0,0x7f,0x22,0x15,0x4b,0xeb,0xa0,0xf0,0x8c,0xe8,0x89,0x1e,0x64,0x3e,0xd9,0x95,0xc9,0x4d,0x9a,0x69,0xc9,0xf1,0xb5,0xf4,0x99,0x02,0x7a,0x78,0x57,0x2a,0xee,0xbd, 0x74,0xd2,0x0c,0xc3,0x98,0x81,0xc2,0x13,0xee,0x77,0x0b,0x10,0x10,0xe4,0xbe,0xa7,0x18,0x84,0x69,0x77,0xae,0x11,0x9f,0x7a,0x02,0x3a,0xb5,0x8c,0xca,0x0a,0xd7,0x52, 0xaf,0xe6,0x56,0xbb,0x3c,0x17,0x25,0x6a,0x9f,0x6e,0x9b,0xf1,0x9f,0xdd,0x5a,0x38,0xfc,0x82,0xbb,0xe8,0x72,0xc5,0x53,0x9e,0xdb,0x60,0x9e,0xf4,0xf7,0x9c,0x20,0x3e, 0xbb,0x14,0x0f,0x2e,0x58,0x3c,0xb2,0xad,0x15,0xb4,0xaa,0x5b,0x65,0x50,0x16,0xa8,0x44,0x92,0x77,0xdb,0xd4,0x77,0xef,0x2c,0x8d,0x6c,0x01,0x7d,0xb7,0x38,0xb1,0x8d, 0xeb,0x4a,0x42,0x7d,0x19,0x23,0xce,0x3f,0xf2,0x62,0x73,0x57,0x79,0xa4,0x18,0xf2,0x0a,0x28,0x2d,0xf9,0x20,0x14,0x7b,0xea,0xbe,0x42,0x1e,0xe5,0x31,0x9d,0x05,0x68, } }, /* #7, 32 byte key, 17 byte PTX */ { 32, { 0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0 }, { 0xbf,0xbe,0xbd,0xbc,0xbb,0xba,0xb9,0xb8,0xb7,0xb6,0xb5,0xb4,0xb3,0xb2,0xb1,0xb0 }, CONST64(0x123456789a), 17, { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10 }, { 0x6c,0x16,0x25,0xdb,0x46,0x71,0x52,0x2d,0x3d,0x75,0x99,0x60,0x1d,0xe7,0xca,0x09,0xed }, }, /* #15, 32 byte key, 25 byte PTX */ { 32, { 0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0 }, { 0xbf,0xbe,0xbd,0xbc,0xbb,0xba,0xb9,0xb8,0xb7,0xb6,0xb5,0xb4,0xb3,0xb2,0xb1,0xb0 }, CONST64(0x123456789a), 25, { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18 }, { 0x8f,0x4d,0xcb,0xad,0x55,0x55,0x8d,0x7b,0x4e,0x01,0xd9,0x37,0x9c,0xd4,0xea,0x22,0xed,0xbf,0x9d,0xac,0xe4,0x5d,0x6f,0x6a,0x73 }, }, /* #21, 32 byte key, 31 byte PTX */ { 32, { 0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0 }, { 0xbf,0xbe,0xbd,0xbc,0xbb,0xba,0xb9,0xb8,0xb7,0xb6,0xb5,0xb4,0xb3,0xb2,0xb1,0xb0 }, CONST64(0x123456789a), 31, { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e }, { 0xd0,0x5b,0xc0,0x90,0xa8,0xe0,0x4f,0x1b,0x3d,0x3e,0xcd,0xd5,0xba,0xec,0x0f,0xd4,0xed,0xbf,0x9d,0xac,0xe4,0x5d,0x6f,0x6a,0x73,0x06,0xe6,0x4b,0xe5,0xdd,0x82 }, }, }; unsigned char OUT[512], T[16]; ulong64 seq; symmetric_xts xts; int i, err, idx; /* AES can be under rijndael or aes... try to find it */ if ((idx = find_cipher("aes")) == -1) { if ((idx = find_cipher("rijndael")) == -1) { return CRYPT_NOP; } } for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { err = xts_start(idx, tests[i].key1, tests[i].key2, tests[i].keylen/2, 0, &xts); if (err != CRYPT_OK) { return err; } seq = tests[i].seqnum; STORE64L(seq,T); XMEMSET(T+8, 0, 8); err = xts_encrypt(tests[i].PTX, tests[i].PTLEN, OUT, T, &xts); if (err != CRYPT_OK) { xts_done(&xts); return err; } if (XMEMCMP(OUT, tests[i].CTX, tests[i].PTLEN)) { xts_done(&xts); return CRYPT_FAIL_TESTVECTOR; } err = xts_decrypt(tests[i].CTX, tests[i].PTLEN, OUT, T, &xts); if (err != CRYPT_OK) { xts_done(&xts); return err; } if (XMEMCMP(OUT, tests[i].PTX, tests[i].PTLEN)) { xts_done(&xts); return CRYPT_FAIL_TESTVECTOR; } xts_done(&xts); } return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/modes/xts/xts_test.c,v $ */ /* $Revision: 1.4 $ */ /* $Date: 2007/03/10 23:59:09 $ */ libtomcrypt-1.17/src/prngs/0000755000175100001440000000000010621351501014443 5ustar tomuserslibtomcrypt-1.17/src/prngs/rc4.c0000644000175100001440000001332110621351501015277 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file rc4.c LTC_RC4 PRNG, Tom St Denis */ #ifdef LTC_RC4 const struct ltc_prng_descriptor rc4_desc = { "rc4", 32, &rc4_start, &rc4_add_entropy, &rc4_ready, &rc4_read, &rc4_done, &rc4_export, &rc4_import, &rc4_test }; /** Start the PRNG @param prng [out] The PRNG state to initialize @return CRYPT_OK if successful */ int rc4_start(prng_state *prng) { LTC_ARGCHK(prng != NULL); /* set keysize to zero */ prng->rc4.x = 0; return CRYPT_OK; } /** Add entropy to the PRNG state @param in The data to add @param inlen Length of the data to add @param prng PRNG state to update @return CRYPT_OK if successful */ int rc4_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) { LTC_ARGCHK(in != NULL); LTC_ARGCHK(prng != NULL); /* trim as required */ if (prng->rc4.x + inlen > 256) { if (prng->rc4.x == 256) { /* I can't possibly accept another byte, ok maybe a mint wafer... */ return CRYPT_OK; } else { /* only accept part of it */ inlen = 256 - prng->rc4.x; } } while (inlen--) { prng->rc4.buf[prng->rc4.x++] = *in++; } return CRYPT_OK; } /** Make the PRNG ready to read from @param prng The PRNG to make active @return CRYPT_OK if successful */ int rc4_ready(prng_state *prng) { unsigned char key[256], tmp, *s; int keylen, x, y, j; LTC_ARGCHK(prng != NULL); /* extract the key */ s = prng->rc4.buf; XMEMCPY(key, s, 256); keylen = prng->rc4.x; /* make LTC_RC4 perm and shuffle */ for (x = 0; x < 256; x++) { s[x] = x; } for (j = x = y = 0; x < 256; x++) { y = (y + prng->rc4.buf[x] + key[j++]) & 255; if (j == keylen) { j = 0; } tmp = s[x]; s[x] = s[y]; s[y] = tmp; } prng->rc4.x = 0; prng->rc4.y = 0; #ifdef LTC_CLEAN_STACK zeromem(key, sizeof(key)); #endif return CRYPT_OK; } /** Read from the PRNG @param out Destination @param outlen Length of output @param prng The active PRNG to read from @return Number of octets read */ unsigned long rc4_read(unsigned char *out, unsigned long outlen, prng_state *prng) { unsigned char x, y, *s, tmp; unsigned long n; LTC_ARGCHK(out != NULL); LTC_ARGCHK(prng != NULL); #ifdef LTC_VALGRIND zeromem(out, outlen); #endif n = outlen; x = prng->rc4.x; y = prng->rc4.y; s = prng->rc4.buf; while (outlen--) { x = (x + 1) & 255; y = (y + s[x]) & 255; tmp = s[x]; s[x] = s[y]; s[y] = tmp; tmp = (s[x] + s[y]) & 255; *out++ ^= s[tmp]; } prng->rc4.x = x; prng->rc4.y = y; return n; } /** Terminate the PRNG @param prng The PRNG to terminate @return CRYPT_OK if successful */ int rc4_done(prng_state *prng) { LTC_ARGCHK(prng != NULL); return CRYPT_OK; } /** Export the PRNG state @param out [out] Destination @param outlen [in/out] Max size and resulting size of the state @param prng The PRNG to export @return CRYPT_OK if successful */ int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng) { LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(prng != NULL); if (*outlen < 32) { *outlen = 32; return CRYPT_BUFFER_OVERFLOW; } if (rc4_read(out, 32, prng) != 32) { return CRYPT_ERROR_READPRNG; } *outlen = 32; return CRYPT_OK; } /** Import a PRNG state @param in The PRNG state @param inlen Size of the state @param prng The PRNG to import @return CRYPT_OK if successful */ int rc4_import(const unsigned char *in, unsigned long inlen, prng_state *prng) { int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(prng != NULL); if (inlen != 32) { return CRYPT_INVALID_ARG; } if ((err = rc4_start(prng)) != CRYPT_OK) { return err; } return rc4_add_entropy(in, 32, prng); } /** PRNG self-test @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled */ int rc4_test(void) { #if !defined(LTC_TEST) || defined(LTC_VALGRIND) return CRYPT_NOP; #else static const struct { unsigned char key[8], pt[8], ct[8]; } tests[] = { { { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }, { 0x75, 0xb7, 0x87, 0x80, 0x99, 0xe0, 0xc5, 0x96 } } }; prng_state prng; unsigned char dst[8]; int err, x; for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { if ((err = rc4_start(&prng)) != CRYPT_OK) { return err; } if ((err = rc4_add_entropy(tests[x].key, 8, &prng)) != CRYPT_OK) { return err; } if ((err = rc4_ready(&prng)) != CRYPT_OK) { return err; } XMEMCPY(dst, tests[x].pt, 8); if (rc4_read(dst, 8, &prng) != 8) { return CRYPT_ERROR_READPRNG; } rc4_done(&prng); if (XMEMCMP(dst, tests[x].ct, 8)) { #if 0 int y; printf("\n\nLTC_RC4 failed, I got:\n"); for (y = 0; y < 8; y++) printf("%02x ", dst[y]); printf("\n"); #endif return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/prngs/rc4.c,v $ */ /* $Revision: 1.11 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/prngs/sober128.c0000644000175100001440000002547310621351501016167 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file sober128.c Implementation of SOBER-128 by Tom St Denis. Based on s128fast.c reference code supplied by Greg Rose of QUALCOMM. */ #ifdef LTC_SOBER128 #include "sober128tab.c" const struct ltc_prng_descriptor sober128_desc = { "sober128", 64, &sober128_start, &sober128_add_entropy, &sober128_ready, &sober128_read, &sober128_done, &sober128_export, &sober128_import, &sober128_test }; /* don't change these... */ #define N 17 #define FOLD N /* how many iterations of folding to do */ #define INITKONST 0x6996c53a /* value of KONST to use during key loading */ #define KEYP 15 /* where to insert key words */ #define FOLDP 4 /* where to insert non-linear feedback */ #define B(x,i) ((unsigned char)(((x) >> (8*i)) & 0xFF)) static ulong32 BYTE2WORD(unsigned char *b) { ulong32 t; LOAD32L(t, b); return t; } #define WORD2BYTE(w, b) STORE32L(b, w) static void XORWORD(ulong32 w, unsigned char *b) { ulong32 t; LOAD32L(t, b); t ^= w; STORE32L(t, b); } /* give correct offset for the current position of the register, * where logically R[0] is at position "zero". */ #define OFF(zero, i) (((zero)+(i)) % N) /* step the LFSR */ /* After stepping, "zero" moves right one place */ #define STEP(R,z) \ R[OFF(z,0)] = R[OFF(z,15)] ^ R[OFF(z,4)] ^ (R[OFF(z,0)] << 8) ^ Multab[(R[OFF(z,0)] >> 24) & 0xFF]; static void cycle(ulong32 *R) { ulong32 t; int i; STEP(R,0); t = R[0]; for (i = 1; i < N; ++i) { R[i-1] = R[i]; } R[N-1] = t; } /* Return a non-linear function of some parts of the register. */ #define NLFUNC(c,z) \ { \ t = c->R[OFF(z,0)] + c->R[OFF(z,16)]; \ t ^= Sbox[(t >> 24) & 0xFF]; \ t = RORc(t, 8); \ t = ((t + c->R[OFF(z,1)]) ^ c->konst) + c->R[OFF(z,6)]; \ t ^= Sbox[(t >> 24) & 0xFF]; \ t = t + c->R[OFF(z,13)]; \ } static ulong32 nltap(struct sober128_prng *c) { ulong32 t; NLFUNC(c, 0); return t; } /** Start the PRNG @param prng [out] The PRNG state to initialize @return CRYPT_OK if successful */ int sober128_start(prng_state *prng) { int i; struct sober128_prng *c; LTC_ARGCHK(prng != NULL); c = &(prng->sober128); /* Register initialised to Fibonacci numbers */ c->R[0] = 1; c->R[1] = 1; for (i = 2; i < N; ++i) { c->R[i] = c->R[i-1] + c->R[i-2]; } c->konst = INITKONST; /* next add_entropy will be the key */ c->flag = 1; c->set = 0; return CRYPT_OK; } /* Save the current register state */ static void s128_savestate(struct sober128_prng *c) { int i; for (i = 0; i < N; ++i) { c->initR[i] = c->R[i]; } } /* initialise to previously saved register state */ static void s128_reloadstate(struct sober128_prng *c) { int i; for (i = 0; i < N; ++i) { c->R[i] = c->initR[i]; } } /* Initialise "konst" */ static void s128_genkonst(struct sober128_prng *c) { ulong32 newkonst; do { cycle(c->R); newkonst = nltap(c); } while ((newkonst & 0xFF000000) == 0); c->konst = newkonst; } /* Load key material into the register */ #define ADDKEY(k) \ c->R[KEYP] += (k); #define XORNL(nl) \ c->R[FOLDP] ^= (nl); /* nonlinear diffusion of register for key */ #define DROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); c->R[OFF((z+1),FOLDP)] ^= t; static void s128_diffuse(struct sober128_prng *c) { ulong32 t; /* relies on FOLD == N == 17! */ DROUND(0); DROUND(1); DROUND(2); DROUND(3); DROUND(4); DROUND(5); DROUND(6); DROUND(7); DROUND(8); DROUND(9); DROUND(10); DROUND(11); DROUND(12); DROUND(13); DROUND(14); DROUND(15); DROUND(16); } /** Add entropy to the PRNG state @param in The data to add @param inlen Length of the data to add @param prng PRNG state to update @return CRYPT_OK if successful */ int sober128_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) { struct sober128_prng *c; ulong32 i, k; LTC_ARGCHK(in != NULL); LTC_ARGCHK(prng != NULL); c = &(prng->sober128); if (c->flag == 1) { /* this is the first call to the add_entropy so this input is the key */ /* inlen must be multiple of 4 bytes */ if ((inlen & 3) != 0) { return CRYPT_INVALID_KEYSIZE; } for (i = 0; i < inlen; i += 4) { k = BYTE2WORD((unsigned char *)&in[i]); ADDKEY(k); cycle(c->R); XORNL(nltap(c)); } /* also fold in the length of the key */ ADDKEY(inlen); /* now diffuse */ s128_diffuse(c); s128_genkonst(c); s128_savestate(c); c->nbuf = 0; c->flag = 0; c->set = 1; } else { /* ok we are adding an IV then... */ s128_reloadstate(c); /* inlen must be multiple of 4 bytes */ if ((inlen & 3) != 0) { return CRYPT_INVALID_KEYSIZE; } for (i = 0; i < inlen; i += 4) { k = BYTE2WORD((unsigned char *)&in[i]); ADDKEY(k); cycle(c->R); XORNL(nltap(c)); } /* also fold in the length of the key */ ADDKEY(inlen); /* now diffuse */ s128_diffuse(c); c->nbuf = 0; } return CRYPT_OK; } /** Make the PRNG ready to read from @param prng The PRNG to make active @return CRYPT_OK if successful */ int sober128_ready(prng_state *prng) { return prng->sober128.set == 1 ? CRYPT_OK : CRYPT_ERROR; } /* XOR pseudo-random bytes into buffer */ #define SROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); XORWORD(t, out+(z*4)); /** Read from the PRNG @param out Destination @param outlen Length of output @param prng The active PRNG to read from @return Number of octets read */ unsigned long sober128_read(unsigned char *out, unsigned long outlen, prng_state *prng) { struct sober128_prng *c; ulong32 t, tlen; LTC_ARGCHK(out != NULL); LTC_ARGCHK(prng != NULL); #ifdef LTC_VALGRIND zeromem(out, outlen); #endif c = &(prng->sober128); t = 0; tlen = outlen; /* handle any previously buffered bytes */ while (c->nbuf != 0 && outlen != 0) { *out++ ^= c->sbuf & 0xFF; c->sbuf >>= 8; c->nbuf -= 8; --outlen; } #ifndef LTC_SMALL_CODE /* do lots at a time, if there's enough to do */ while (outlen >= N*4) { SROUND(0); SROUND(1); SROUND(2); SROUND(3); SROUND(4); SROUND(5); SROUND(6); SROUND(7); SROUND(8); SROUND(9); SROUND(10); SROUND(11); SROUND(12); SROUND(13); SROUND(14); SROUND(15); SROUND(16); out += 4*N; outlen -= 4*N; } #endif /* do small or odd size buffers the slow way */ while (4 <= outlen) { cycle(c->R); t = nltap(c); XORWORD(t, out); out += 4; outlen -= 4; } /* handle any trailing bytes */ if (outlen != 0) { cycle(c->R); c->sbuf = nltap(c); c->nbuf = 32; while (c->nbuf != 0 && outlen != 0) { *out++ ^= c->sbuf & 0xFF; c->sbuf >>= 8; c->nbuf -= 8; --outlen; } } return tlen; } /** Terminate the PRNG @param prng The PRNG to terminate @return CRYPT_OK if successful */ int sober128_done(prng_state *prng) { LTC_ARGCHK(prng != NULL); return CRYPT_OK; } /** Export the PRNG state @param out [out] Destination @param outlen [in/out] Max size and resulting size of the state @param prng The PRNG to export @return CRYPT_OK if successful */ int sober128_export(unsigned char *out, unsigned long *outlen, prng_state *prng) { LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(prng != NULL); if (*outlen < 64) { *outlen = 64; return CRYPT_BUFFER_OVERFLOW; } if (sober128_read(out, 64, prng) != 64) { return CRYPT_ERROR_READPRNG; } *outlen = 64; return CRYPT_OK; } /** Import a PRNG state @param in The PRNG state @param inlen Size of the state @param prng The PRNG to import @return CRYPT_OK if successful */ int sober128_import(const unsigned char *in, unsigned long inlen, prng_state *prng) { int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(prng != NULL); if (inlen != 64) { return CRYPT_INVALID_ARG; } if ((err = sober128_start(prng)) != CRYPT_OK) { return err; } if ((err = sober128_add_entropy(in, 64, prng)) != CRYPT_OK) { return err; } return sober128_ready(prng); } /** PRNG self-test @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled */ int sober128_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { int keylen, ivlen, len; unsigned char key[16], iv[4], out[20]; } tests[] = { { 16, 4, 20, /* key */ { 0x74, 0x65, 0x73, 0x74, 0x20, 0x6b, 0x65, 0x79, 0x20, 0x31, 0x32, 0x38, 0x62, 0x69, 0x74, 0x73 }, /* IV */ { 0x00, 0x00, 0x00, 0x00 }, /* expected output */ { 0x43, 0x50, 0x0c, 0xcf, 0x89, 0x91, 0x9f, 0x1d, 0xaa, 0x37, 0x74, 0x95, 0xf4, 0xb4, 0x58, 0xc2, 0x40, 0x37, 0x8b, 0xbb } } }; prng_state prng; unsigned char dst[20]; int err, x; for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { if ((err = sober128_start(&prng)) != CRYPT_OK) { return err; } if ((err = sober128_add_entropy(tests[x].key, tests[x].keylen, &prng)) != CRYPT_OK) { return err; } /* add IV */ if ((err = sober128_add_entropy(tests[x].iv, tests[x].ivlen, &prng)) != CRYPT_OK) { return err; } /* ready up */ if ((err = sober128_ready(&prng)) != CRYPT_OK) { return err; } XMEMSET(dst, 0, tests[x].len); if (sober128_read(dst, tests[x].len, &prng) != (unsigned long)tests[x].len) { return CRYPT_ERROR_READPRNG; } sober128_done(&prng); if (XMEMCMP(dst, tests[x].out, tests[x].len)) { #if 0 printf("\n\nLTC_SOBER128 failed, I got:\n"); for (y = 0; y < tests[x].len; y++) printf("%02x ", dst[y]); printf("\n"); #endif return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/prngs/sober128.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/prngs/sprng.c0000644000175100001440000000547110621351501015747 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file sprng.c Secure PRNG, Tom St Denis */ /* A secure PRNG using the RNG functions. Basically this is a * wrapper that allows you to use a secure RNG as a PRNG * in the various other functions. */ #ifdef LTC_SPRNG const struct ltc_prng_descriptor sprng_desc = { "sprng", 0, &sprng_start, &sprng_add_entropy, &sprng_ready, &sprng_read, &sprng_done, &sprng_export, &sprng_import, &sprng_test }; /** Start the PRNG @param prng [out] The PRNG state to initialize @return CRYPT_OK if successful */ int sprng_start(prng_state *prng) { return CRYPT_OK; } /** Add entropy to the PRNG state @param in The data to add @param inlen Length of the data to add @param prng PRNG state to update @return CRYPT_OK if successful */ int sprng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) { return CRYPT_OK; } /** Make the PRNG ready to read from @param prng The PRNG to make active @return CRYPT_OK if successful */ int sprng_ready(prng_state *prng) { return CRYPT_OK; } /** Read from the PRNG @param out Destination @param outlen Length of output @param prng The active PRNG to read from @return Number of octets read */ unsigned long sprng_read(unsigned char *out, unsigned long outlen, prng_state *prng) { LTC_ARGCHK(out != NULL); return rng_get_bytes(out, outlen, NULL); } /** Terminate the PRNG @param prng The PRNG to terminate @return CRYPT_OK if successful */ int sprng_done(prng_state *prng) { return CRYPT_OK; } /** Export the PRNG state @param out [out] Destination @param outlen [in/out] Max size and resulting size of the state @param prng The PRNG to export @return CRYPT_OK if successful */ int sprng_export(unsigned char *out, unsigned long *outlen, prng_state *prng) { LTC_ARGCHK(outlen != NULL); *outlen = 0; return CRYPT_OK; } /** Import a PRNG state @param in The PRNG state @param inlen Size of the state @param prng The PRNG to import @return CRYPT_OK if successful */ int sprng_import(const unsigned char *in, unsigned long inlen, prng_state *prng) { return CRYPT_OK; } /** PRNG self-test @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled */ int sprng_test(void) { return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/prngs/sprng.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/prngs/sober128tab.c0000644000175100001440000001736410621351501016656 0ustar tomusers/** @file sober128tab.c SOBER-128 Tables */ /* $Id: sober128tab.c,v 1.2 2005/05/05 14:35:59 tom Exp $ */ /* @(#)TuringMultab.h 1.3 (QUALCOMM) 02/09/03 */ /* Multiplication table for Turing using 0xD02B4367 */ static const ulong32 Multab[256] = { 0x00000000, 0xD02B4367, 0xED5686CE, 0x3D7DC5A9, 0x97AC41D1, 0x478702B6, 0x7AFAC71F, 0xAAD18478, 0x631582EF, 0xB33EC188, 0x8E430421, 0x5E684746, 0xF4B9C33E, 0x24928059, 0x19EF45F0, 0xC9C40697, 0xC62A4993, 0x16010AF4, 0x2B7CCF5D, 0xFB578C3A, 0x51860842, 0x81AD4B25, 0xBCD08E8C, 0x6CFBCDEB, 0xA53FCB7C, 0x7514881B, 0x48694DB2, 0x98420ED5, 0x32938AAD, 0xE2B8C9CA, 0xDFC50C63, 0x0FEE4F04, 0xC154926B, 0x117FD10C, 0x2C0214A5, 0xFC2957C2, 0x56F8D3BA, 0x86D390DD, 0xBBAE5574, 0x6B851613, 0xA2411084, 0x726A53E3, 0x4F17964A, 0x9F3CD52D, 0x35ED5155, 0xE5C61232, 0xD8BBD79B, 0x089094FC, 0x077EDBF8, 0xD755989F, 0xEA285D36, 0x3A031E51, 0x90D29A29, 0x40F9D94E, 0x7D841CE7, 0xADAF5F80, 0x646B5917, 0xB4401A70, 0x893DDFD9, 0x59169CBE, 0xF3C718C6, 0x23EC5BA1, 0x1E919E08, 0xCEBADD6F, 0xCFA869D6, 0x1F832AB1, 0x22FEEF18, 0xF2D5AC7F, 0x58042807, 0x882F6B60, 0xB552AEC9, 0x6579EDAE, 0xACBDEB39, 0x7C96A85E, 0x41EB6DF7, 0x91C02E90, 0x3B11AAE8, 0xEB3AE98F, 0xD6472C26, 0x066C6F41, 0x09822045, 0xD9A96322, 0xE4D4A68B, 0x34FFE5EC, 0x9E2E6194, 0x4E0522F3, 0x7378E75A, 0xA353A43D, 0x6A97A2AA, 0xBABCE1CD, 0x87C12464, 0x57EA6703, 0xFD3BE37B, 0x2D10A01C, 0x106D65B5, 0xC04626D2, 0x0EFCFBBD, 0xDED7B8DA, 0xE3AA7D73, 0x33813E14, 0x9950BA6C, 0x497BF90B, 0x74063CA2, 0xA42D7FC5, 0x6DE97952, 0xBDC23A35, 0x80BFFF9C, 0x5094BCFB, 0xFA453883, 0x2A6E7BE4, 0x1713BE4D, 0xC738FD2A, 0xC8D6B22E, 0x18FDF149, 0x258034E0, 0xF5AB7787, 0x5F7AF3FF, 0x8F51B098, 0xB22C7531, 0x62073656, 0xABC330C1, 0x7BE873A6, 0x4695B60F, 0x96BEF568, 0x3C6F7110, 0xEC443277, 0xD139F7DE, 0x0112B4B9, 0xD31DD2E1, 0x03369186, 0x3E4B542F, 0xEE601748, 0x44B19330, 0x949AD057, 0xA9E715FE, 0x79CC5699, 0xB008500E, 0x60231369, 0x5D5ED6C0, 0x8D7595A7, 0x27A411DF, 0xF78F52B8, 0xCAF29711, 0x1AD9D476, 0x15379B72, 0xC51CD815, 0xF8611DBC, 0x284A5EDB, 0x829BDAA3, 0x52B099C4, 0x6FCD5C6D, 0xBFE61F0A, 0x7622199D, 0xA6095AFA, 0x9B749F53, 0x4B5FDC34, 0xE18E584C, 0x31A51B2B, 0x0CD8DE82, 0xDCF39DE5, 0x1249408A, 0xC26203ED, 0xFF1FC644, 0x2F348523, 0x85E5015B, 0x55CE423C, 0x68B38795, 0xB898C4F2, 0x715CC265, 0xA1778102, 0x9C0A44AB, 0x4C2107CC, 0xE6F083B4, 0x36DBC0D3, 0x0BA6057A, 0xDB8D461D, 0xD4630919, 0x04484A7E, 0x39358FD7, 0xE91ECCB0, 0x43CF48C8, 0x93E40BAF, 0xAE99CE06, 0x7EB28D61, 0xB7768BF6, 0x675DC891, 0x5A200D38, 0x8A0B4E5F, 0x20DACA27, 0xF0F18940, 0xCD8C4CE9, 0x1DA70F8E, 0x1CB5BB37, 0xCC9EF850, 0xF1E33DF9, 0x21C87E9E, 0x8B19FAE6, 0x5B32B981, 0x664F7C28, 0xB6643F4F, 0x7FA039D8, 0xAF8B7ABF, 0x92F6BF16, 0x42DDFC71, 0xE80C7809, 0x38273B6E, 0x055AFEC7, 0xD571BDA0, 0xDA9FF2A4, 0x0AB4B1C3, 0x37C9746A, 0xE7E2370D, 0x4D33B375, 0x9D18F012, 0xA06535BB, 0x704E76DC, 0xB98A704B, 0x69A1332C, 0x54DCF685, 0x84F7B5E2, 0x2E26319A, 0xFE0D72FD, 0xC370B754, 0x135BF433, 0xDDE1295C, 0x0DCA6A3B, 0x30B7AF92, 0xE09CECF5, 0x4A4D688D, 0x9A662BEA, 0xA71BEE43, 0x7730AD24, 0xBEF4ABB3, 0x6EDFE8D4, 0x53A22D7D, 0x83896E1A, 0x2958EA62, 0xF973A905, 0xC40E6CAC, 0x14252FCB, 0x1BCB60CF, 0xCBE023A8, 0xF69DE601, 0x26B6A566, 0x8C67211E, 0x5C4C6279, 0x6131A7D0, 0xB11AE4B7, 0x78DEE220, 0xA8F5A147, 0x958864EE, 0x45A32789, 0xEF72A3F1, 0x3F59E096, 0x0224253F, 0xD20F6658, }; /* $Id: sober128tab.c,v 1.2 2005/05/05 14:35:59 tom Exp $ */ /* Sbox for SOBER-128 */ /* * This is really the combination of two SBoxes; the least significant * 24 bits comes from: * 8->32 Sbox generated by Millan et. al. at Queensland University of * Technology. See: E. Dawson, W. Millan, L. Burnett, G. Carter, * "On the Design of 8*32 S-boxes". Unpublished report, by the * Information Systems Research Centre, * Queensland University of Technology, 1999. * * The most significant 8 bits are the Skipjack "F table", which can be * found at http://csrc.nist.gov/CryptoToolkit/skipjack/skipjack.pdf . * In this optimised table, though, the intent is to XOR the word from * the table selected by the high byte with the input word. Thus, the * high byte is actually the Skipjack F-table entry XORED with its * table index. */ static const ulong32 Sbox[256] = { 0xa3aa1887, 0xd65e435c, 0x0b65c042, 0x800e6ef4, 0xfc57ee20, 0x4d84fed3, 0xf066c502, 0xf354e8ae, 0xbb2ee9d9, 0x281f38d4, 0x1f829b5d, 0x735cdf3c, 0x95864249, 0xbc2e3963, 0xa1f4429f, 0xf6432c35, 0xf7f40325, 0x3cc0dd70, 0x5f973ded, 0x9902dc5e, 0xda175b42, 0x590012bf, 0xdc94d78c, 0x39aab26b, 0x4ac11b9a, 0x8c168146, 0xc3ea8ec5, 0x058ac28f, 0x52ed5c0f, 0x25b4101c, 0x5a2db082, 0x370929e1, 0x2a1843de, 0xfe8299fc, 0x202fbc4b, 0x833915dd, 0x33a803fa, 0xd446b2de, 0x46233342, 0x4fcee7c3, 0x3ad607ef, 0x9e97ebab, 0x507f859b, 0xe81f2e2f, 0xc55b71da, 0xd7e2269a, 0x1339c3d1, 0x7ca56b36, 0xa6c9def2, 0xb5c9fc5f, 0x5927b3a3, 0x89a56ddf, 0xc625b510, 0x560f85a7, 0xace82e71, 0x2ecb8816, 0x44951e2a, 0x97f5f6af, 0xdfcbc2b3, 0xce4ff55d, 0xcb6b6214, 0x2b0b83e3, 0x549ea6f5, 0x9de041af, 0x792f1f17, 0xf73b99ee, 0x39a65ec0, 0x4c7016c6, 0x857709a4, 0xd6326e01, 0xc7b280d9, 0x5cfb1418, 0xa6aff227, 0xfd548203, 0x506b9d96, 0xa117a8c0, 0x9cd5bf6e, 0xdcee7888, 0x61fcfe64, 0xf7a193cd, 0x050d0184, 0xe8ae4930, 0x88014f36, 0xd6a87088, 0x6bad6c2a, 0x1422c678, 0xe9204de7, 0xb7c2e759, 0x0200248e, 0x013b446b, 0xda0d9fc2, 0x0414a895, 0x3a6cc3a1, 0x56fef170, 0x86c19155, 0xcf7b8a66, 0x551b5e69, 0xb4a8623e, 0xa2bdfa35, 0xc4f068cc, 0x573a6acd, 0x6355e936, 0x03602db9, 0x0edf13c1, 0x2d0bb16d, 0x6980b83c, 0xfeb23763, 0x3dd8a911, 0x01b6bc13, 0xf55579d7, 0xf55c2fa8, 0x19f4196e, 0xe7db5476, 0x8d64a866, 0xc06e16ad, 0xb17fc515, 0xc46feb3c, 0x8bc8a306, 0xad6799d9, 0x571a9133, 0x992466dd, 0x92eb5dcd, 0xac118f50, 0x9fafb226, 0xa1b9cef3, 0x3ab36189, 0x347a19b1, 0x62c73084, 0xc27ded5c, 0x6c8bc58f, 0x1cdde421, 0xed1e47fb, 0xcdcc715e, 0xb9c0ff99, 0x4b122f0f, 0xc4d25184, 0xaf7a5e6c, 0x5bbf18bc, 0x8dd7c6e0, 0x5fb7e420, 0x521f523f, 0x4ad9b8a2, 0xe9da1a6b, 0x97888c02, 0x19d1e354, 0x5aba7d79, 0xa2cc7753, 0x8c2d9655, 0x19829da1, 0x531590a7, 0x19c1c149, 0x3d537f1c, 0x50779b69, 0xed71f2b7, 0x463c58fa, 0x52dc4418, 0xc18c8c76, 0xc120d9f0, 0xafa80d4d, 0x3b74c473, 0xd09410e9, 0x290e4211, 0xc3c8082b, 0x8f6b334a, 0x3bf68ed2, 0xa843cc1b, 0x8d3c0ff3, 0x20e564a0, 0xf8f55a4f, 0x2b40f8e7, 0xfea7f15f, 0xcf00fe21, 0x8a6d37d6, 0xd0d506f1, 0xade00973, 0xefbbde36, 0x84670fa8, 0xfa31ab9e, 0xaedab618, 0xc01f52f5, 0x6558eb4f, 0x71b9e343, 0x4b8d77dd, 0x8cb93da6, 0x740fd52d, 0x425412f8, 0xc5a63360, 0x10e53ad0, 0x5a700f1c, 0x8324ed0b, 0xe53dc1ec, 0x1a366795, 0x6d549d15, 0xc5ce46d7, 0xe17abe76, 0x5f48e0a0, 0xd0f07c02, 0x941249b7, 0xe49ed6ba, 0x37a47f78, 0xe1cfffbd, 0xb007ca84, 0xbb65f4da, 0xb59f35da, 0x33d2aa44, 0x417452ac, 0xc0d674a7, 0x2d61a46a, 0xdc63152a, 0x3e12b7aa, 0x6e615927, 0xa14fb118, 0xa151758d, 0xba81687b, 0xe152f0b3, 0x764254ed, 0x34c77271, 0x0a31acab, 0x54f94aec, 0xb9e994cd, 0x574d9e81, 0x5b623730, 0xce8a21e8, 0x37917f0b, 0xe8a9b5d6, 0x9697adf8, 0xf3d30431, 0x5dcac921, 0x76b35d46, 0xaa430a36, 0xc2194022, 0x22bca65e, 0xdaec70ba, 0xdfaea8cc, 0x777bae8b, 0x242924d5, 0x1f098a5a, 0x4b396b81, 0x55de2522, 0x435c1cb8, 0xaeb8fe1d, 0x9db3c697, 0x5b164f83, 0xe0c16376, 0xa319224c, 0xd0203b35, 0x433ac0fe, 0x1466a19a, 0x45f0b24f, 0x51fda998, 0xc0d52d71, 0xfa0896a8, 0xf9e6053f, 0xa4b0d300, 0xd499cbcc, 0xb95e3d40, }; /* $Source: /cvs/libtom/libtomcrypt/src/prngs/sober128tab.c,v $ */ /* $Revision: 1.2 $ */ /* $Date: 2005/05/05 14:35:59 $ */ libtomcrypt-1.17/src/prngs/rng_get_bytes.c0000644000175100001440000000716610621351501017454 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file rng_get_bytes.c portable way to get secure random bits to feed a PRNG (Tom St Denis) */ #ifdef LTC_DEVRANDOM /* on *NIX read /dev/random */ static unsigned long rng_nix(unsigned char *buf, unsigned long len, void (*callback)(void)) { #ifdef LTC_NO_FILE return 0; #else FILE *f; unsigned long x; #ifdef TRY_URANDOM_FIRST f = fopen("/dev/urandom", "rb"); if (f == NULL) #endif /* TRY_URANDOM_FIRST */ f = fopen("/dev/random", "rb"); if (f == NULL) { return 0; } /* disable buffering */ if (setvbuf(f, NULL, _IONBF, 0) != 0) { fclose(f); return 0; } x = (unsigned long)fread(buf, 1, (size_t)len, f); fclose(f); return x; #endif /* LTC_NO_FILE */ } #endif /* LTC_DEVRANDOM */ /* on ANSI C platforms with 100 < CLOCKS_PER_SEC < 10000 */ #if defined(CLOCKS_PER_SEC) && !defined(WINCE) #define ANSI_RNG static unsigned long rng_ansic(unsigned char *buf, unsigned long len, void (*callback)(void)) { clock_t t1; int l, acc, bits, a, b; if (XCLOCKS_PER_SEC < 100 || XCLOCKS_PER_SEC > 10000) { return 0; } l = len; bits = 8; acc = a = b = 0; while (len--) { if (callback != NULL) callback(); while (bits--) { do { t1 = XCLOCK(); while (t1 == XCLOCK()) a ^= 1; t1 = XCLOCK(); while (t1 == XCLOCK()) b ^= 1; } while (a == b); acc = (acc << 1) | a; } *buf++ = acc; acc = 0; bits = 8; } acc = bits = a = b = 0; return l; } #endif /* Try the Microsoft CSP */ #if defined(WIN32) || defined(WINCE) #define _WIN32_WINNT 0x0400 #ifdef WINCE #define UNDER_CE #define ARM #endif #include #include static unsigned long rng_win32(unsigned char *buf, unsigned long len, void (*callback)(void)) { HCRYPTPROV hProv = 0; if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, (CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) && !CryptAcquireContext (&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET)) return 0; if (CryptGenRandom(hProv, len, buf) == TRUE) { CryptReleaseContext(hProv, 0); return len; } else { CryptReleaseContext(hProv, 0); return 0; } } #endif /* WIN32 */ /** Read the system RNG @param out Destination @param outlen Length desired (octets) @param callback Pointer to void function to act as "callback" when RNG is slow. This can be NULL @return Number of octets read */ unsigned long rng_get_bytes(unsigned char *out, unsigned long outlen, void (*callback)(void)) { unsigned long x; LTC_ARGCHK(out != NULL); #if defined(LTC_DEVRANDOM) x = rng_nix(out, outlen, callback); if (x != 0) { return x; } #endif #ifdef WIN32 x = rng_win32(out, outlen, callback); if (x != 0) { return x; } #endif #ifdef ANSI_RNG x = rng_ansic(out, outlen, callback); if (x != 0) { return x; } #endif return 0; } /* $Source: /cvs/libtom/libtomcrypt/src/prngs/rng_get_bytes.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/prngs/fortuna.c0000644000175100001440000002532710621351501016276 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file fortuna.c Fortuna PRNG, Tom St Denis */ /* Implementation of Fortuna by Tom St Denis We deviate slightly here for reasons of simplicity [and to fit in the API]. First all "sources" in the AddEntropy function are fixed to 0. Second since no reliable timer is provided we reseed automatically when len(pool0) >= 64 or every LTC_FORTUNA_WD calls to the read function */ #ifdef LTC_FORTUNA /* requries LTC_SHA256 and AES */ #if !(defined(LTC_RIJNDAEL) && defined(LTC_SHA256)) #error LTC_FORTUNA requires LTC_SHA256 and LTC_RIJNDAEL (AES) #endif #ifndef LTC_FORTUNA_POOLS #warning LTC_FORTUNA_POOLS was not previously defined (old headers?) #define LTC_FORTUNA_POOLS 32 #endif #if LTC_FORTUNA_POOLS < 4 || LTC_FORTUNA_POOLS > 32 #error LTC_FORTUNA_POOLS must be in [4..32] #endif const struct ltc_prng_descriptor fortuna_desc = { "fortuna", 1024, &fortuna_start, &fortuna_add_entropy, &fortuna_ready, &fortuna_read, &fortuna_done, &fortuna_export, &fortuna_import, &fortuna_test }; /* update the IV */ static void fortuna_update_iv(prng_state *prng) { int x; unsigned char *IV; /* update IV */ IV = prng->fortuna.IV; for (x = 0; x < 16; x++) { IV[x] = (IV[x] + 1) & 255; if (IV[x] != 0) break; } } /* reseed the PRNG */ static int fortuna_reseed(prng_state *prng) { unsigned char tmp[MAXBLOCKSIZE]; hash_state md; int err, x; ++prng->fortuna.reset_cnt; /* new K == LTC_SHA256(K || s) where s == LTC_SHA256(P0) || LTC_SHA256(P1) ... */ sha256_init(&md); if ((err = sha256_process(&md, prng->fortuna.K, 32)) != CRYPT_OK) { sha256_done(&md, tmp); return err; } for (x = 0; x < LTC_FORTUNA_POOLS; x++) { if (x == 0 || ((prng->fortuna.reset_cnt >> (x-1)) & 1) == 0) { /* terminate this hash */ if ((err = sha256_done(&prng->fortuna.pool[x], tmp)) != CRYPT_OK) { sha256_done(&md, tmp); return err; } /* add it to the string */ if ((err = sha256_process(&md, tmp, 32)) != CRYPT_OK) { sha256_done(&md, tmp); return err; } /* reset this pool */ if ((err = sha256_init(&prng->fortuna.pool[x])) != CRYPT_OK) { sha256_done(&md, tmp); return err; } } else { break; } } /* finish key */ if ((err = sha256_done(&md, prng->fortuna.K)) != CRYPT_OK) { return err; } if ((err = rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey)) != CRYPT_OK) { return err; } fortuna_update_iv(prng); /* reset pool len */ prng->fortuna.pool0_len = 0; prng->fortuna.wd = 0; #ifdef LTC_CLEAN_STACK zeromem(&md, sizeof(md)); zeromem(tmp, sizeof(tmp)); #endif return CRYPT_OK; } /** Start the PRNG @param prng [out] The PRNG state to initialize @return CRYPT_OK if successful */ int fortuna_start(prng_state *prng) { int err, x, y; unsigned char tmp[MAXBLOCKSIZE]; LTC_ARGCHK(prng != NULL); /* initialize the pools */ for (x = 0; x < LTC_FORTUNA_POOLS; x++) { if ((err = sha256_init(&prng->fortuna.pool[x])) != CRYPT_OK) { for (y = 0; y < x; y++) { sha256_done(&prng->fortuna.pool[y], tmp); } return err; } } prng->fortuna.pool_idx = prng->fortuna.pool0_len = prng->fortuna.wd = 0; prng->fortuna.reset_cnt = 0; /* reset bufs */ zeromem(prng->fortuna.K, 32); if ((err = rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey)) != CRYPT_OK) { for (x = 0; x < LTC_FORTUNA_POOLS; x++) { sha256_done(&prng->fortuna.pool[x], tmp); } return err; } zeromem(prng->fortuna.IV, 16); LTC_MUTEX_INIT(&prng->fortuna.prng_lock) return CRYPT_OK; } /** Add entropy to the PRNG state @param in The data to add @param inlen Length of the data to add @param prng PRNG state to update @return CRYPT_OK if successful */ int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) { unsigned char tmp[2]; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(prng != NULL); LTC_MUTEX_LOCK(&prng->fortuna.prng_lock); /* ensure inlen <= 32 */ if (inlen > 32) { LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); return CRYPT_INVALID_ARG; } /* add s || length(in) || in to pool[pool_idx] */ tmp[0] = 0; tmp[1] = (unsigned char)inlen; if ((err = sha256_process(&prng->fortuna.pool[prng->fortuna.pool_idx], tmp, 2)) != CRYPT_OK) { LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); return err; } if ((err = sha256_process(&prng->fortuna.pool[prng->fortuna.pool_idx], in, inlen)) != CRYPT_OK) { LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); return err; } if (prng->fortuna.pool_idx == 0) { prng->fortuna.pool0_len += inlen; } if (++(prng->fortuna.pool_idx) == LTC_FORTUNA_POOLS) { prng->fortuna.pool_idx = 0; } LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); return CRYPT_OK; } /** Make the PRNG ready to read from @param prng The PRNG to make active @return CRYPT_OK if successful */ int fortuna_ready(prng_state *prng) { return fortuna_reseed(prng); } /** Read from the PRNG @param out Destination @param outlen Length of output @param prng The active PRNG to read from @return Number of octets read */ unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state *prng) { unsigned char tmp[16]; int err; unsigned long tlen; LTC_ARGCHK(out != NULL); LTC_ARGCHK(prng != NULL); LTC_MUTEX_LOCK(&prng->fortuna.prng_lock); /* do we have to reseed? */ if (++prng->fortuna.wd == LTC_FORTUNA_WD || prng->fortuna.pool0_len >= 64) { if ((err = fortuna_reseed(prng)) != CRYPT_OK) { LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); return 0; } } /* now generate the blocks required */ tlen = outlen; /* handle whole blocks without the extra XMEMCPY */ while (outlen >= 16) { /* encrypt the IV and store it */ rijndael_ecb_encrypt(prng->fortuna.IV, out, &prng->fortuna.skey); out += 16; outlen -= 16; fortuna_update_iv(prng); } /* left over bytes? */ if (outlen > 0) { rijndael_ecb_encrypt(prng->fortuna.IV, tmp, &prng->fortuna.skey); XMEMCPY(out, tmp, outlen); fortuna_update_iv(prng); } /* generate new key */ rijndael_ecb_encrypt(prng->fortuna.IV, prng->fortuna.K , &prng->fortuna.skey); fortuna_update_iv(prng); rijndael_ecb_encrypt(prng->fortuna.IV, prng->fortuna.K+16, &prng->fortuna.skey); fortuna_update_iv(prng); if ((err = rijndael_setup(prng->fortuna.K, 32, 0, &prng->fortuna.skey)) != CRYPT_OK) { LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); return 0; } #ifdef LTC_CLEAN_STACK zeromem(tmp, sizeof(tmp)); #endif LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); return tlen; } /** Terminate the PRNG @param prng The PRNG to terminate @return CRYPT_OK if successful */ int fortuna_done(prng_state *prng) { int err, x; unsigned char tmp[32]; LTC_ARGCHK(prng != NULL); LTC_MUTEX_LOCK(&prng->fortuna.prng_lock); /* terminate all the hashes */ for (x = 0; x < LTC_FORTUNA_POOLS; x++) { if ((err = sha256_done(&(prng->fortuna.pool[x]), tmp)) != CRYPT_OK) { LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); return err; } } /* call cipher done when we invent one ;-) */ #ifdef LTC_CLEAN_STACK zeromem(tmp, sizeof(tmp)); #endif LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); return CRYPT_OK; } /** Export the PRNG state @param out [out] Destination @param outlen [in/out] Max size and resulting size of the state @param prng The PRNG to export @return CRYPT_OK if successful */ int fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng) { int x, err; hash_state *md; LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(prng != NULL); LTC_MUTEX_LOCK(&prng->fortuna.prng_lock); /* we'll write bytes for s&g's */ if (*outlen < 32*LTC_FORTUNA_POOLS) { LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); *outlen = 32*LTC_FORTUNA_POOLS; return CRYPT_BUFFER_OVERFLOW; } md = XMALLOC(sizeof(hash_state)); if (md == NULL) { LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); return CRYPT_MEM; } /* to emit the state we copy each pool, terminate it then hash it again so * an attacker who sees the state can't determine the current state of the PRNG */ for (x = 0; x < LTC_FORTUNA_POOLS; x++) { /* copy the PRNG */ XMEMCPY(md, &(prng->fortuna.pool[x]), sizeof(*md)); /* terminate it */ if ((err = sha256_done(md, out+x*32)) != CRYPT_OK) { goto LBL_ERR; } /* now hash it */ if ((err = sha256_init(md)) != CRYPT_OK) { goto LBL_ERR; } if ((err = sha256_process(md, out+x*32, 32)) != CRYPT_OK) { goto LBL_ERR; } if ((err = sha256_done(md, out+x*32)) != CRYPT_OK) { goto LBL_ERR; } } *outlen = 32*LTC_FORTUNA_POOLS; err = CRYPT_OK; LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(md, sizeof(*md)); #endif XFREE(md); LTC_MUTEX_UNLOCK(&prng->fortuna.prng_lock); return err; } /** Import a PRNG state @param in The PRNG state @param inlen Size of the state @param prng The PRNG to import @return CRYPT_OK if successful */ int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng) { int err, x; LTC_ARGCHK(in != NULL); LTC_ARGCHK(prng != NULL); if (inlen != 32*LTC_FORTUNA_POOLS) { return CRYPT_INVALID_ARG; } if ((err = fortuna_start(prng)) != CRYPT_OK) { return err; } for (x = 0; x < LTC_FORTUNA_POOLS; x++) { if ((err = fortuna_add_entropy(in+x*32, 32, prng)) != CRYPT_OK) { return err; } } return err; } /** PRNG self-test @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled */ int fortuna_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else int err; if ((err = sha256_test()) != CRYPT_OK) { return err; } return rijndael_test(); #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/prngs/fortuna.c,v $ */ /* $Revision: 1.16 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/prngs/yarrow.c0000644000175100001440000002323710621351501016141 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file yarrow.c Yarrow PRNG, Tom St Denis */ #ifdef LTC_YARROW const struct ltc_prng_descriptor yarrow_desc = { "yarrow", 64, &yarrow_start, &yarrow_add_entropy, &yarrow_ready, &yarrow_read, &yarrow_done, &yarrow_export, &yarrow_import, &yarrow_test }; /** Start the PRNG @param prng [out] The PRNG state to initialize @return CRYPT_OK if successful */ int yarrow_start(prng_state *prng) { int err; LTC_ARGCHK(prng != NULL); /* these are the default hash/cipher combo used */ #ifdef LTC_RIJNDAEL #if LTC_YARROW_AES==0 prng->yarrow.cipher = register_cipher(&rijndael_enc_desc); #elif LTC_YARROW_AES==1 prng->yarrow.cipher = register_cipher(&aes_enc_desc); #elif LTC_YARROW_AES==2 prng->yarrow.cipher = register_cipher(&rijndael_desc); #elif LTC_YARROW_AES==3 prng->yarrow.cipher = register_cipher(&aes_desc); #endif #elif defined(LTC_BLOWFISH) prng->yarrow.cipher = register_cipher(&blowfish_desc); #elif defined(LTC_TWOFISH) prng->yarrow.cipher = register_cipher(&twofish_desc); #elif defined(LTC_RC6) prng->yarrow.cipher = register_cipher(&rc6_desc); #elif defined(LTC_RC5) prng->yarrow.cipher = register_cipher(&rc5_desc); #elif defined(LTC_SAFERP) prng->yarrow.cipher = register_cipher(&saferp_desc); #elif defined(LTC_RC2) prng->yarrow.cipher = register_cipher(&rc2_desc); #elif defined(LTC_NOEKEON) prng->yarrow.cipher = register_cipher(&noekeon_desc); #elif defined(LTC_ANUBIS) prng->yarrow.cipher = register_cipher(&anubis_desc); #elif defined(LTC_KSEED) prng->yarrow.cipher = register_cipher(&kseed_desc); #elif defined(LTC_KHAZAD) prng->yarrow.cipher = register_cipher(&khazad_desc); #elif defined(LTC_CAST5) prng->yarrow.cipher = register_cipher(&cast5_desc); #elif defined(LTC_XTEA) prng->yarrow.cipher = register_cipher(&xtea_desc); #elif defined(LTC_SAFER) prng->yarrow.cipher = register_cipher(&safer_sk128_desc); #elif defined(LTC_DES) prng->yarrow.cipher = register_cipher(&des3_desc); #else #error LTC_YARROW needs at least one CIPHER #endif if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) { return err; } #ifdef LTC_SHA256 prng->yarrow.hash = register_hash(&sha256_desc); #elif defined(LTC_SHA512) prng->yarrow.hash = register_hash(&sha512_desc); #elif defined(LTC_TIGER) prng->yarrow.hash = register_hash(&tiger_desc); #elif defined(LTC_SHA1) prng->yarrow.hash = register_hash(&sha1_desc); #elif defined(LTC_RIPEMD320) prng->yarrow.hash = register_hash(&rmd320_desc); #elif defined(LTC_RIPEMD256) prng->yarrow.hash = register_hash(&rmd256_desc); #elif defined(LTC_RIPEMD160) prng->yarrow.hash = register_hash(&rmd160_desc); #elif defined(LTC_RIPEMD128) prng->yarrow.hash = register_hash(&rmd128_desc); #elif defined(LTC_MD5) prng->yarrow.hash = register_hash(&md5_desc); #elif defined(LTC_MD4) prng->yarrow.hash = register_hash(&md4_desc); #elif defined(LTC_MD2) prng->yarrow.hash = register_hash(&md2_desc); #elif defined(LTC_WHIRLPOOL) prng->yarrow.hash = register_hash(&whirlpool_desc); #else #error LTC_YARROW needs at least one HASH #endif if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { return err; } /* zero the memory used */ zeromem(prng->yarrow.pool, sizeof(prng->yarrow.pool)); LTC_MUTEX_INIT(&prng->yarrow.prng_lock) return CRYPT_OK; } /** Add entropy to the PRNG state @param in The data to add @param inlen Length of the data to add @param prng PRNG state to update @return CRYPT_OK if successful */ int yarrow_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng) { hash_state md; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(prng != NULL); LTC_MUTEX_LOCK(&prng->yarrow.prng_lock); if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); return err; } /* start the hash */ if ((err = hash_descriptor[prng->yarrow.hash].init(&md)) != CRYPT_OK) { LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); return err; } /* hash the current pool */ if ((err = hash_descriptor[prng->yarrow.hash].process(&md, prng->yarrow.pool, hash_descriptor[prng->yarrow.hash].hashsize)) != CRYPT_OK) { LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); return err; } /* add the new entropy */ if ((err = hash_descriptor[prng->yarrow.hash].process(&md, in, inlen)) != CRYPT_OK) { LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); return err; } /* store result */ if ((err = hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool)) != CRYPT_OK) { LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); return err; } LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); return CRYPT_OK; } /** Make the PRNG ready to read from @param prng The PRNG to make active @return CRYPT_OK if successful */ int yarrow_ready(prng_state *prng) { int ks, err; LTC_ARGCHK(prng != NULL); LTC_MUTEX_LOCK(&prng->yarrow.prng_lock); if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) { LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); return err; } if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) { LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); return err; } /* setup CTR mode using the "pool" as the key */ ks = (int)hash_descriptor[prng->yarrow.hash].hashsize; if ((err = cipher_descriptor[prng->yarrow.cipher].keysize(&ks)) != CRYPT_OK) { LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); return err; } if ((err = ctr_start(prng->yarrow.cipher, /* what cipher to use */ prng->yarrow.pool, /* IV */ prng->yarrow.pool, ks, /* KEY and key size */ 0, /* number of rounds */ CTR_COUNTER_LITTLE_ENDIAN, /* little endian counter */ &prng->yarrow.ctr)) != CRYPT_OK) { LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); return err; } LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); return CRYPT_OK; } /** Read from the PRNG @param out Destination @param outlen Length of output @param prng The active PRNG to read from @return Number of octets read */ unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state *prng) { LTC_ARGCHK(out != NULL); LTC_ARGCHK(prng != NULL); LTC_MUTEX_LOCK(&prng->yarrow.prng_lock); /* put out in predictable state first */ zeromem(out, outlen); /* now randomize it */ if (ctr_encrypt(out, out, outlen, &prng->yarrow.ctr) != CRYPT_OK) { LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); return 0; } LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); return outlen; } /** Terminate the PRNG @param prng The PRNG to terminate @return CRYPT_OK if successful */ int yarrow_done(prng_state *prng) { int err; LTC_ARGCHK(prng != NULL); LTC_MUTEX_LOCK(&prng->yarrow.prng_lock); /* call cipher done when we invent one ;-) */ /* we invented one */ err = ctr_done(&prng->yarrow.ctr); LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); return err; } /** Export the PRNG state @param out [out] Destination @param outlen [in/out] Max size and resulting size of the state @param prng The PRNG to export @return CRYPT_OK if successful */ int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng) { LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(prng != NULL); LTC_MUTEX_LOCK(&prng->yarrow.prng_lock); /* we'll write 64 bytes for s&g's */ if (*outlen < 64) { LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); *outlen = 64; return CRYPT_BUFFER_OVERFLOW; } if (yarrow_read(out, 64, prng) != 64) { LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); return CRYPT_ERROR_READPRNG; } *outlen = 64; return CRYPT_OK; } /** Import a PRNG state @param in The PRNG state @param inlen Size of the state @param prng The PRNG to import @return CRYPT_OK if successful */ int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng) { int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(prng != NULL); LTC_MUTEX_LOCK(&prng->yarrow.prng_lock); if (inlen != 64) { LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); return CRYPT_INVALID_ARG; } if ((err = yarrow_start(prng)) != CRYPT_OK) { LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); return err; } err = yarrow_add_entropy(in, 64, prng); LTC_MUTEX_UNLOCK(&prng->yarrow.prng_lock); return err; } /** PRNG self-test @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled */ int yarrow_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else int err; prng_state prng; if ((err = yarrow_start(&prng)) != CRYPT_OK) { return err; } /* now let's test the hash/cipher that was chosen */ if ((err = cipher_descriptor[prng.yarrow.cipher].test()) != CRYPT_OK) { return err; } if ((err = hash_descriptor[prng.yarrow.hash].test()) != CRYPT_OK) { return err; } return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/prngs/yarrow.c,v $ */ /* $Revision: 1.16 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/prngs/rng_make_prng.c0000644000175100001440000000343710621351501017427 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file rng_make_prng.c portable way to get secure random bits to feed a PRNG (Tom St Denis) */ /** Create a PRNG from a RNG @param bits Number of bits of entropy desired (64 ... 1024) @param wprng Index of which PRNG to setup @param prng [out] PRNG state to initialize @param callback A pointer to a void function for when the RNG is slow, this can be NULL @return CRYPT_OK if successful */ int rng_make_prng(int bits, int wprng, prng_state *prng, void (*callback)(void)) { unsigned char buf[256]; int err; LTC_ARGCHK(prng != NULL); /* check parameter */ if ((err = prng_is_valid(wprng)) != CRYPT_OK) { return err; } if (bits < 64 || bits > 1024) { return CRYPT_INVALID_PRNGSIZE; } if ((err = prng_descriptor[wprng].start(prng)) != CRYPT_OK) { return err; } bits = ((bits/8)+((bits&7)!=0?1:0)) * 2; if (rng_get_bytes(buf, (unsigned long)bits, callback) != (unsigned long)bits) { return CRYPT_ERROR_READPRNG; } if ((err = prng_descriptor[wprng].add_entropy(buf, (unsigned long)bits, prng)) != CRYPT_OK) { return err; } if ((err = prng_descriptor[wprng].ready(prng)) != CRYPT_OK) { return err; } #ifdef LTC_CLEAN_STACK zeromem(buf, sizeof(buf)); #endif return CRYPT_OK; } /* $Source: /cvs/libtom/libtomcrypt/src/prngs/rng_make_prng.c,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2006/12/28 01:27:24 $ */ libtomcrypt-1.17/src/encauth/0000755000175100001440000000000010621351501014741 5ustar tomuserslibtomcrypt-1.17/src/encauth/ccm/0000755000175100001440000000000010621351501015503 5ustar tomuserslibtomcrypt-1.17/src/encauth/ccm/ccm_test.c0000644000175100001440000001230210621351501017446 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file ccm_test.c CCM support, process a block of memory, Tom St Denis */ #ifdef LTC_CCM_MODE int ccm_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { unsigned char key[16]; unsigned char nonce[16]; int noncelen; unsigned char header[64]; int headerlen; unsigned char pt[64]; int ptlen; unsigned char ct[64]; unsigned char tag[16]; int taglen; } tests[] = { /* 13 byte nonce, 8 byte auth, 23 byte pt */ { { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF }, { 0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5 }, 13, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }, 8, { 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E }, 23, { 0x58, 0x8C, 0x97, 0x9A, 0x61, 0xC6, 0x63, 0xD2, 0xF0, 0x66, 0xD0, 0xC2, 0xC0, 0xF9, 0x89, 0x80, 0x6D, 0x5F, 0x6B, 0x61, 0xDA, 0xC3, 0x84 }, { 0x17, 0xe8, 0xd1, 0x2c, 0xfd, 0xf9, 0x26, 0xe0 }, 8 }, /* 13 byte nonce, 12 byte header, 19 byte pt */ { { 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF }, { 0x00, 0x00, 0x00, 0x06, 0x05, 0x04, 0x03, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5 }, 13, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B }, 12, { 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E }, 19, { 0xA2, 0x8C, 0x68, 0x65, 0x93, 0x9A, 0x9A, 0x79, 0xFA, 0xAA, 0x5C, 0x4C, 0x2A, 0x9D, 0x4A, 0x91, 0xCD, 0xAC, 0x8C }, { 0x96, 0xC8, 0x61, 0xB9, 0xC9, 0xE6, 0x1E, 0xF1 }, 8 }, /* supplied by Brian Gladman */ { { 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f }, { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 }, 7, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }, 8, { 0x20, 0x21, 0x22, 0x23 }, 4, { 0x71, 0x62, 0x01, 0x5b }, { 0x4d, 0xac, 0x25, 0x5d }, 4 }, { { 0xc9, 0x7c, 0x1f, 0x67, 0xce, 0x37, 0x11, 0x85, 0x51, 0x4a, 0x8a, 0x19, 0xf2, 0xbd, 0xd5, 0x2f }, { 0x00, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08, 0xb5, 0x03, 0x97, 0x76, 0xe7, 0x0c }, 13, { 0x08, 0x40, 0x0f, 0xd2, 0xe1, 0x28, 0xa5, 0x7c, 0x50, 0x30, 0xf1, 0x84, 0x44, 0x08, 0xab, 0xae, 0xa5, 0xb8, 0xfc, 0xba, 0x00, 0x00 }, 22, { 0xf8, 0xba, 0x1a, 0x55, 0xd0, 0x2f, 0x85, 0xae, 0x96, 0x7b, 0xb6, 0x2f, 0xb6, 0xcd, 0xa8, 0xeb, 0x7e, 0x78, 0xa0, 0x50 }, 20, { 0xf3, 0xd0, 0xa2, 0xfe, 0x9a, 0x3d, 0xbf, 0x23, 0x42, 0xa6, 0x43, 0xe4, 0x32, 0x46, 0xe8, 0x0c, 0x3c, 0x04, 0xd0, 0x19 }, { 0x78, 0x45, 0xce, 0x0b, 0x16, 0xf9, 0x76, 0x23 }, 8 }, }; unsigned long taglen, x; unsigned char buf[64], buf2[64], tag2[16], tag[16]; int err, idx; symmetric_key skey; idx = find_cipher("aes"); if (idx == -1) { idx = find_cipher("rijndael"); if (idx == -1) { return CRYPT_NOP; } } for (x = 0; x < (sizeof(tests)/sizeof(tests[0])); x++) { taglen = tests[x].taglen; if ((err = cipher_descriptor[idx].setup(tests[x].key, 16, 0, &skey)) != CRYPT_OK) { return err; } if ((err = ccm_memory(idx, tests[x].key, 16, &skey, tests[x].nonce, tests[x].noncelen, tests[x].header, tests[x].headerlen, (unsigned char*)tests[x].pt, tests[x].ptlen, buf, tag, &taglen, 0)) != CRYPT_OK) { return err; } if (XMEMCMP(buf, tests[x].ct, tests[x].ptlen)) { return CRYPT_FAIL_TESTVECTOR; } if (XMEMCMP(tag, tests[x].tag, tests[x].taglen)) { return CRYPT_FAIL_TESTVECTOR; } if ((err = ccm_memory(idx, tests[x].key, 16, NULL, tests[x].nonce, tests[x].noncelen, tests[x].header, tests[x].headerlen, buf2, tests[x].ptlen, buf, tag2, &taglen, 1 )) != CRYPT_OK) { return err; } if (XMEMCMP(buf2, tests[x].pt, tests[x].ptlen)) { return CRYPT_FAIL_TESTVECTOR; } if (XMEMCMP(tag2, tests[x].tag, tests[x].taglen)) { return CRYPT_FAIL_TESTVECTOR; } cipher_descriptor[idx].done(&skey); } return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/ccm/ccm_test.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/ccm/ccm_memory.c0000644000175100001440000002270210621351501020004 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file ccm_memory.c CCM support, process a block of memory, Tom St Denis */ #ifdef LTC_CCM_MODE /** CCM encrypt/decrypt and produce an authentication tag @param cipher The index of the cipher desired @param key The secret key to use @param keylen The length of the secret key (octets) @param uskey A previously scheduled key [optional can be NULL] @param nonce The session nonce [use once] @param noncelen The length of the nonce @param header The header for the session @param headerlen The length of the header (octets) @param pt [out] The plaintext @param ptlen The length of the plaintext (octets) @param ct [out] The ciphertext @param tag [out] The destination tag @param taglen [in/out] The max size and resulting size of the authentication tag @param direction Encrypt or Decrypt direction (0 or 1) @return CRYPT_OK if successful */ int ccm_memory(int cipher, const unsigned char *key, unsigned long keylen, symmetric_key *uskey, const unsigned char *nonce, unsigned long noncelen, const unsigned char *header, unsigned long headerlen, unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tag, unsigned long *taglen, int direction) { unsigned char PAD[16], ctr[16], CTRPAD[16], b; symmetric_key *skey; int err; unsigned long len, L, x, y, z, CTRlen; if (uskey == NULL) { LTC_ARGCHK(key != NULL); } LTC_ARGCHK(nonce != NULL); if (headerlen > 0) { LTC_ARGCHK(header != NULL); } LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(tag != NULL); LTC_ARGCHK(taglen != NULL); #ifdef LTC_FAST if (16 % sizeof(LTC_FAST_TYPE)) { return CRYPT_INVALID_ARG; } #endif /* check cipher input */ if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { return err; } if (cipher_descriptor[cipher].block_length != 16) { return CRYPT_INVALID_CIPHER; } /* make sure the taglen is even and <= 16 */ *taglen &= ~1; if (*taglen > 16) { *taglen = 16; } /* can't use < 4 */ if (*taglen < 4) { return CRYPT_INVALID_ARG; } /* is there an accelerator? */ if (cipher_descriptor[cipher].accel_ccm_memory != NULL) { return cipher_descriptor[cipher].accel_ccm_memory( key, keylen, uskey, nonce, noncelen, header, headerlen, pt, ptlen, ct, tag, taglen, direction); } /* let's get the L value */ len = ptlen; L = 0; while (len) { ++L; len >>= 8; } if (L <= 1) { L = 2; } /* increase L to match the nonce len */ noncelen = (noncelen > 13) ? 13 : noncelen; if ((15 - noncelen) > L) { L = 15 - noncelen; } /* decrease noncelen to match L */ if ((noncelen + L) > 15) { noncelen = 15 - L; } /* allocate mem for the symmetric key */ if (uskey == NULL) { skey = XMALLOC(sizeof(*skey)); if (skey == NULL) { return CRYPT_MEM; } /* initialize the cipher */ if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, skey)) != CRYPT_OK) { XFREE(skey); return err; } } else { skey = uskey; } /* form B_0 == flags | Nonce N | l(m) */ x = 0; PAD[x++] = (unsigned char)(((headerlen > 0) ? (1<<6) : 0) | (((*taglen - 2)>>1)<<3) | (L-1)); /* nonce */ for (y = 0; y < (16 - (L + 1)); y++) { PAD[x++] = nonce[y]; } /* store len */ len = ptlen; /* shift len so the upper bytes of len are the contents of the length */ for (y = L; y < 4; y++) { len <<= 8; } /* store l(m) (only store 32-bits) */ for (y = 0; L > 4 && (L-y)>4; y++) { PAD[x++] = 0; } for (; y < L; y++) { PAD[x++] = (unsigned char)((len >> 24) & 255); len <<= 8; } /* encrypt PAD */ if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { goto error; } /* handle header */ if (headerlen > 0) { x = 0; /* store length */ if (headerlen < ((1UL<<16) - (1UL<<8))) { PAD[x++] ^= (headerlen>>8) & 255; PAD[x++] ^= headerlen & 255; } else { PAD[x++] ^= 0xFF; PAD[x++] ^= 0xFE; PAD[x++] ^= (headerlen>>24) & 255; PAD[x++] ^= (headerlen>>16) & 255; PAD[x++] ^= (headerlen>>8) & 255; PAD[x++] ^= headerlen & 255; } /* now add the data */ for (y = 0; y < headerlen; y++) { if (x == 16) { /* full block so let's encrypt it */ if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { goto error; } x = 0; } PAD[x++] ^= header[y]; } /* remainder? */ if (x != 0) { if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { goto error; } } } /* setup the ctr counter */ x = 0; /* flags */ ctr[x++] = (unsigned char)L-1; /* nonce */ for (y = 0; y < (16 - (L+1)); ++y) { ctr[x++] = nonce[y]; } /* offset */ while (x < 16) { ctr[x++] = 0; } x = 0; CTRlen = 16; /* now handle the PT */ if (ptlen > 0) { y = 0; #ifdef LTC_FAST if (ptlen & ~15) { if (direction == CCM_ENCRYPT) { for (; y < (ptlen & ~15); y += 16) { /* increment the ctr? */ for (z = 15; z > 15-L; z--) { ctr[z] = (ctr[z] + 1) & 255; if (ctr[z]) break; } if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) { goto error; } /* xor the PT against the pad first */ for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE*)(&PAD[z])) ^= *((LTC_FAST_TYPE*)(&pt[y+z])); *((LTC_FAST_TYPE*)(&ct[y+z])) = *((LTC_FAST_TYPE*)(&pt[y+z])) ^ *((LTC_FAST_TYPE*)(&CTRPAD[z])); } if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { goto error; } } } else { for (; y < (ptlen & ~15); y += 16) { /* increment the ctr? */ for (z = 15; z > 15-L; z--) { ctr[z] = (ctr[z] + 1) & 255; if (ctr[z]) break; } if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) { goto error; } /* xor the PT against the pad last */ for (z = 0; z < 16; z += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE*)(&pt[y+z])) = *((LTC_FAST_TYPE*)(&ct[y+z])) ^ *((LTC_FAST_TYPE*)(&CTRPAD[z])); *((LTC_FAST_TYPE*)(&PAD[z])) ^= *((LTC_FAST_TYPE*)(&pt[y+z])); } if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { goto error; } } } } #endif for (; y < ptlen; y++) { /* increment the ctr? */ if (CTRlen == 16) { for (z = 15; z > 15-L; z--) { ctr[z] = (ctr[z] + 1) & 255; if (ctr[z]) break; } if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) { goto error; } CTRlen = 0; } /* if we encrypt we add the bytes to the MAC first */ if (direction == CCM_ENCRYPT) { b = pt[y]; ct[y] = b ^ CTRPAD[CTRlen++]; } else { b = ct[y] ^ CTRPAD[CTRlen++]; pt[y] = b; } if (x == 16) { if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { goto error; } x = 0; } PAD[x++] ^= b; } if (x != 0) { if ((err = cipher_descriptor[cipher].ecb_encrypt(PAD, PAD, skey)) != CRYPT_OK) { goto error; } } } /* setup CTR for the TAG (zero the count) */ for (y = 15; y > 15 - L; y--) { ctr[y] = 0x00; } if ((err = cipher_descriptor[cipher].ecb_encrypt(ctr, CTRPAD, skey)) != CRYPT_OK) { goto error; } if (skey != uskey) { cipher_descriptor[cipher].done(skey); } /* store the TAG */ for (x = 0; x < 16 && x < *taglen; x++) { tag[x] = PAD[x] ^ CTRPAD[x]; } *taglen = x; #ifdef LTC_CLEAN_STACK zeromem(skey, sizeof(*skey)); zeromem(PAD, sizeof(PAD)); zeromem(CTRPAD, sizeof(CTRPAD)); #endif error: if (skey != uskey) { XFREE(skey); } return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/ccm/ccm_memory.c,v $ */ /* $Revision: 1.20 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/eax/0000755000175100001440000000000010621351501015516 5ustar tomuserslibtomcrypt-1.17/src/encauth/eax/eax_init.c0000644000175100001440000000721710621351501017471 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file eax_init.c EAX implementation, initialized EAX state, by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_EAX_MODE /** Initialized an EAX state @param eax [out] The EAX state to initialize @param cipher The index of the desired cipher @param key The secret key @param keylen The length of the secret key (octets) @param nonce The use-once nonce for the session @param noncelen The length of the nonce (octets) @param header The header for the EAX state @param headerlen The header length (octets) @return CRYPT_OK if successful */ int eax_init(eax_state *eax, int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *nonce, unsigned long noncelen, const unsigned char *header, unsigned long headerlen) { unsigned char *buf; int err, blklen; omac_state *omac; unsigned long len; LTC_ARGCHK(eax != NULL); LTC_ARGCHK(key != NULL); LTC_ARGCHK(nonce != NULL); if (headerlen > 0) { LTC_ARGCHK(header != NULL); } if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { return err; } blklen = cipher_descriptor[cipher].block_length; /* allocate ram */ buf = XMALLOC(MAXBLOCKSIZE); omac = XMALLOC(sizeof(*omac)); if (buf == NULL || omac == NULL) { if (buf != NULL) { XFREE(buf); } if (omac != NULL) { XFREE(omac); } return CRYPT_MEM; } /* N = LTC_OMAC_0K(nonce) */ zeromem(buf, MAXBLOCKSIZE); if ((err = omac_init(omac, cipher, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } /* omac the [0]_n */ if ((err = omac_process(omac, buf, blklen)) != CRYPT_OK) { goto LBL_ERR; } /* omac the nonce */ if ((err = omac_process(omac, nonce, noncelen)) != CRYPT_OK) { goto LBL_ERR; } /* store result */ len = sizeof(eax->N); if ((err = omac_done(omac, eax->N, &len)) != CRYPT_OK) { goto LBL_ERR; } /* H = LTC_OMAC_1K(header) */ zeromem(buf, MAXBLOCKSIZE); buf[blklen - 1] = 1; if ((err = omac_init(&eax->headeromac, cipher, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } /* omac the [1]_n */ if ((err = omac_process(&eax->headeromac, buf, blklen)) != CRYPT_OK) { goto LBL_ERR; } /* omac the header */ if (headerlen != 0) { if ((err = omac_process(&eax->headeromac, header, headerlen)) != CRYPT_OK) { goto LBL_ERR; } } /* note we don't finish the headeromac, this allows us to add more header later */ /* setup the CTR mode */ if ((err = ctr_start(cipher, eax->N, key, keylen, 0, CTR_COUNTER_BIG_ENDIAN, &eax->ctr)) != CRYPT_OK) { goto LBL_ERR; } /* setup the LTC_OMAC for the ciphertext */ if ((err = omac_init(&eax->ctomac, cipher, key, keylen)) != CRYPT_OK) { goto LBL_ERR; } /* omac [2]_n */ zeromem(buf, MAXBLOCKSIZE); buf[blklen-1] = 2; if ((err = omac_process(&eax->ctomac, buf, blklen)) != CRYPT_OK) { goto LBL_ERR; } err = CRYPT_OK; LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(buf, MAXBLOCKSIZE); zeromem(omac, sizeof(*omac)); #endif XFREE(omac); XFREE(buf); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/eax/eax_init.c,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2007/05/12 14:37:41 $ */ libtomcrypt-1.17/src/encauth/eax/eax_encrypt_authenticate_memory.c0000644000175100001440000000450610621351501024336 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file eax_encrypt_authenticate_memory.c EAX implementation, encrypt a block of memory, by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_EAX_MODE /** EAX encrypt and produce an authentication tag @param cipher The index of the cipher desired @param key The secret key to use @param keylen The length of the secret key (octets) @param nonce The session nonce [use once] @param noncelen The length of the nonce @param header The header for the session @param headerlen The length of the header (octets) @param pt The plaintext @param ptlen The length of the plaintext (octets) @param ct [out] The ciphertext @param tag [out] The destination tag @param taglen [in/out] The max size and resulting size of the authentication tag @return CRYPT_OK if successful */ int eax_encrypt_authenticate_memory(int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *nonce, unsigned long noncelen, const unsigned char *header, unsigned long headerlen, const unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tag, unsigned long *taglen) { int err; eax_state *eax; LTC_ARGCHK(key != NULL); LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(tag != NULL); LTC_ARGCHK(taglen != NULL); eax = XMALLOC(sizeof(*eax)); if ((err = eax_init(eax, cipher, key, keylen, nonce, noncelen, header, headerlen)) != CRYPT_OK) { goto LBL_ERR; } if ((err = eax_encrypt(eax, pt, ct, ptlen)) != CRYPT_OK) { goto LBL_ERR; } if ((err = eax_done(eax, tag, taglen)) != CRYPT_OK) { goto LBL_ERR; } err = CRYPT_OK; LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(eax, sizeof(*eax)); #endif XFREE(eax); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/eax/eax_encrypt_authenticate_memory.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/eax/eax_encrypt.c0000644000175100001440000000240110621351501020200 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file eax_encrypt.c EAX implementation, encrypt block by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_EAX_MODE /** Encrypt with EAX a block of data. @param eax The EAX state @param pt The plaintext to encrypt @param ct [out] The ciphertext as encrypted @param length The length of the plaintext (octets) @return CRYPT_OK if successful */ int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, unsigned long length) { int err; LTC_ARGCHK(eax != NULL); LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); /* encrypt */ if ((err = ctr_encrypt(pt, ct, length, &eax->ctr)) != CRYPT_OK) { return err; } /* omac ciphertext */ return omac_process(&eax->ctomac, ct, length); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/eax/eax_encrypt.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/eax/eax_decrypt_verify_memory.c0000644000175100001440000000570410621351501023153 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file eax_decrypt_verify_memory.c EAX implementation, decrypt block of memory, by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_EAX_MODE /** Decrypt a block of memory and verify the provided MAC tag with EAX @param cipher The index of the cipher desired @param key The secret key @param keylen The length of the key (octets) @param nonce The nonce data (use once) for the session @param noncelen The length of the nonce data. @param header The session header data @param headerlen The length of the header (octets) @param ct The ciphertext @param ctlen The length of the ciphertext (octets) @param pt [out] The plaintext @param tag The authentication tag provided by the encoder @param taglen [in/out] The length of the tag (octets) @param stat [out] The result of the decryption (1==valid tag, 0==invalid) @return CRYPT_OK if successful regardless of the resulting tag comparison */ int eax_decrypt_verify_memory(int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *nonce, unsigned long noncelen, const unsigned char *header, unsigned long headerlen, const unsigned char *ct, unsigned long ctlen, unsigned char *pt, unsigned char *tag, unsigned long taglen, int *stat) { int err; eax_state *eax; unsigned char *buf; unsigned long buflen; LTC_ARGCHK(stat != NULL); LTC_ARGCHK(key != NULL); LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(tag != NULL); /* default to zero */ *stat = 0; /* allocate ram */ buf = XMALLOC(taglen); eax = XMALLOC(sizeof(*eax)); if (eax == NULL || buf == NULL) { if (eax != NULL) { XFREE(eax); } if (buf != NULL) { XFREE(buf); } return CRYPT_MEM; } if ((err = eax_init(eax, cipher, key, keylen, nonce, noncelen, header, headerlen)) != CRYPT_OK) { goto LBL_ERR; } if ((err = eax_decrypt(eax, ct, pt, ctlen)) != CRYPT_OK) { goto LBL_ERR; } buflen = taglen; if ((err = eax_done(eax, buf, &buflen)) != CRYPT_OK) { goto LBL_ERR; } /* compare tags */ if (buflen >= taglen && XMEMCMP(buf, tag, taglen) == 0) { *stat = 1; } err = CRYPT_OK; LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(buf, taglen); zeromem(eax, sizeof(*eax)); #endif XFREE(eax); XFREE(buf); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/eax/eax_decrypt_verify_memory.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/eax/eax_decrypt.c0000644000175100001440000000234410621351501020174 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file eax_decrypt.c EAX implementation, decrypt block, by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_EAX_MODE /** Decrypt data with the EAX protocol @param eax The EAX state @param ct The ciphertext @param pt [out] The plaintext @param length The length (octets) of the ciphertext @return CRYPT_OK if successful */ int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, unsigned long length) { int err; LTC_ARGCHK(eax != NULL); LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); /* omac ciphertext */ if ((err = omac_process(&eax->ctomac, ct, length)) != CRYPT_OK) { return err; } /* decrypt */ return ctr_decrypt(ct, pt, length, &eax->ctr); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/eax/eax_decrypt.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/eax/eax_test.c0000644000175100001440000002053210621351501017500 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file eax_test.c EAX implementation, self-test, by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_EAX_MODE /** Test the EAX implementation @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled */ int eax_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { int keylen, noncelen, headerlen, msglen; unsigned char key[MAXBLOCKSIZE], nonce[MAXBLOCKSIZE], header[MAXBLOCKSIZE], plaintext[MAXBLOCKSIZE], ciphertext[MAXBLOCKSIZE], tag[MAXBLOCKSIZE]; } tests[] = { /* NULL message */ { 16, 0, 0, 0, /* key */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* nonce */ { 0 }, /* header */ { 0 }, /* plaintext */ { 0 }, /* ciphertext */ { 0 }, /* tag */ { 0x9a, 0xd0, 0x7e, 0x7d, 0xbf, 0xf3, 0x01, 0xf5, 0x05, 0xde, 0x59, 0x6b, 0x96, 0x15, 0xdf, 0xff } }, /* test with nonce */ { 16, 16, 0, 0, /* key */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* nonce */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* header */ { 0 }, /* plaintext */ { 0 }, /* ciphertext */ { 0 }, /* tag */ { 0x1c, 0xe1, 0x0d, 0x3e, 0xff, 0xd4, 0xca, 0xdb, 0xe2, 0xe4, 0x4b, 0x58, 0xd6, 0x0a, 0xb9, 0xec } }, /* test with header [no nonce] */ { 16, 0, 16, 0, /* key */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* nonce */ { 0 }, /* header */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* plaintext */ { 0 }, /* ciphertext */ { 0 }, /* tag */ { 0x3a, 0x69, 0x8f, 0x7a, 0x27, 0x0e, 0x51, 0xb0, 0xf6, 0x5b, 0x3d, 0x3e, 0x47, 0x19, 0x3c, 0xff } }, /* test with header + nonce + plaintext */ { 16, 16, 16, 32, /* key */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* nonce */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* header */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* plaintext */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, /* ciphertext */ { 0x29, 0xd8, 0x78, 0xd1, 0xa3, 0xbe, 0x85, 0x7b, 0x6f, 0xb8, 0xc8, 0xea, 0x59, 0x50, 0xa7, 0x78, 0x33, 0x1f, 0xbf, 0x2c, 0xcf, 0x33, 0x98, 0x6f, 0x35, 0xe8, 0xcf, 0x12, 0x1d, 0xcb, 0x30, 0xbc }, /* tag */ { 0x4f, 0xbe, 0x03, 0x38, 0xbe, 0x1c, 0x8c, 0x7e, 0x1d, 0x7a, 0xe7, 0xe4, 0x5b, 0x92, 0xc5, 0x87 } }, /* test with header + nonce + plaintext [not even sizes!] */ { 16, 15, 14, 29, /* key */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* nonce */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e }, /* header */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d }, /* plaintext */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c }, /* ciphertext */ { 0xdd, 0x25, 0xc7, 0x54, 0xc5, 0xb1, 0x7c, 0x59, 0x28, 0xb6, 0x9b, 0x73, 0x15, 0x5f, 0x7b, 0xb8, 0x88, 0x8f, 0xaf, 0x37, 0x09, 0x1a, 0xd9, 0x2c, 0x8a, 0x24, 0xdb, 0x86, 0x8b }, /* tag */ { 0x0d, 0x1a, 0x14, 0xe5, 0x22, 0x24, 0xff, 0xd2, 0x3a, 0x05, 0xfa, 0x02, 0xcd, 0xef, 0x52, 0xda } }, /* Vectors from Brian Gladman */ { 16, 16, 8, 0, /* key */ { 0x23, 0x39, 0x52, 0xde, 0xe4, 0xd5, 0xed, 0x5f, 0x9b, 0x9c, 0x6d, 0x6f, 0xf8, 0x0f, 0xf4, 0x78 }, /* nonce */ { 0x62, 0xec, 0x67, 0xf9, 0xc3, 0xa4, 0xa4, 0x07, 0xfc, 0xb2, 0xa8, 0xc4, 0x90, 0x31, 0xa8, 0xb3 }, /* header */ { 0x6b, 0xfb, 0x91, 0x4f, 0xd0, 0x7e, 0xae, 0x6b }, /* PT */ { 0x00 }, /* CT */ { 0x00 }, /* tag */ { 0xe0, 0x37, 0x83, 0x0e, 0x83, 0x89, 0xf2, 0x7b, 0x02, 0x5a, 0x2d, 0x65, 0x27, 0xe7, 0x9d, 0x01 } }, { 16, 16, 8, 2, /* key */ { 0x91, 0x94, 0x5d, 0x3f, 0x4d, 0xcb, 0xee, 0x0b, 0xf4, 0x5e, 0xf5, 0x22, 0x55, 0xf0, 0x95, 0xa4 }, /* nonce */ { 0xbe, 0xca, 0xf0, 0x43, 0xb0, 0xa2, 0x3d, 0x84, 0x31, 0x94, 0xba, 0x97, 0x2c, 0x66, 0xde, 0xbd }, /* header */ { 0xfa, 0x3b, 0xfd, 0x48, 0x06, 0xeb, 0x53, 0xfa }, /* PT */ { 0xf7, 0xfb }, /* CT */ { 0x19, 0xdd }, /* tag */ { 0x5c, 0x4c, 0x93, 0x31, 0x04, 0x9d, 0x0b, 0xda, 0xb0, 0x27, 0x74, 0x08, 0xf6, 0x79, 0x67, 0xe5 } }, { 16, 16, 8, 5, /* key */ { 0x01, 0xf7, 0x4a, 0xd6, 0x40, 0x77, 0xf2, 0xe7, 0x04, 0xc0, 0xf6, 0x0a, 0xda, 0x3d, 0xd5, 0x23 }, /* nonce */ { 0x70, 0xc3, 0xdb, 0x4f, 0x0d, 0x26, 0x36, 0x84, 0x00, 0xa1, 0x0e, 0xd0, 0x5d, 0x2b, 0xff, 0x5e }, /* header */ { 0x23, 0x4a, 0x34, 0x63, 0xc1, 0x26, 0x4a, 0xc6 }, /* PT */ { 0x1a, 0x47, 0xcb, 0x49, 0x33 }, /* CT */ { 0xd8, 0x51, 0xd5, 0xba, 0xe0 }, /* Tag */ { 0x3a, 0x59, 0xf2, 0x38, 0xa2, 0x3e, 0x39, 0x19, 0x9d, 0xc9, 0x26, 0x66, 0x26, 0xc4, 0x0f, 0x80 } } }; int err, x, idx, res; unsigned long len; unsigned char outct[MAXBLOCKSIZE], outtag[MAXBLOCKSIZE]; /* AES can be under rijndael or aes... try to find it */ if ((idx = find_cipher("aes")) == -1) { if ((idx = find_cipher("rijndael")) == -1) { return CRYPT_NOP; } } for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { len = sizeof(outtag); if ((err = eax_encrypt_authenticate_memory(idx, tests[x].key, tests[x].keylen, tests[x].nonce, tests[x].noncelen, tests[x].header, tests[x].headerlen, tests[x].plaintext, tests[x].msglen, outct, outtag, &len)) != CRYPT_OK) { return err; } if (XMEMCMP(outct, tests[x].ciphertext, tests[x].msglen) || XMEMCMP(outtag, tests[x].tag, len)) { #if 0 unsigned long y; printf("\n\nFailure: \nCT:\n"); for (y = 0; y < (unsigned long)tests[x].msglen; ) { printf("0x%02x", outct[y]); if (y < (unsigned long)(tests[x].msglen-1)) printf(", "); if (!(++y % 8)) printf("\n"); } printf("\nTAG:\n"); for (y = 0; y < len; ) { printf("0x%02x", outtag[y]); if (y < len-1) printf(", "); if (!(++y % 8)) printf("\n"); } #endif return CRYPT_FAIL_TESTVECTOR; } /* test decrypt */ if ((err = eax_decrypt_verify_memory(idx, tests[x].key, tests[x].keylen, tests[x].nonce, tests[x].noncelen, tests[x].header, tests[x].headerlen, outct, tests[x].msglen, outct, outtag, len, &res)) != CRYPT_OK) { return err; } if ((res != 1) || XMEMCMP(outct, tests[x].plaintext, tests[x].msglen)) { #if 0 unsigned long y; printf("\n\nFailure (res == %d): \nPT:\n", res); for (y = 0; y < (unsigned long)tests[x].msglen; ) { printf("0x%02x", outct[y]); if (y < (unsigned long)(tests[x].msglen-1)) printf(", "); if (!(++y % 8)) printf("\n"); } printf("\n\n"); #endif return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif /* LTC_TEST */ } #endif /* LTC_EAX_MODE */ /* $Source: /cvs/libtom/libtomcrypt/src/encauth/eax/eax_test.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/eax/eax_addheader.c0000644000175100001440000000207510621351501020424 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file eax_addheader.c EAX implementation, add meta-data, by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_EAX_MODE /** add header (metadata) to the stream @param eax The current EAX state @param header The header (meta-data) data you wish to add to the state @param length The length of the header data @return CRYPT_OK if successful */ int eax_addheader(eax_state *eax, const unsigned char *header, unsigned long length) { LTC_ARGCHK(eax != NULL); LTC_ARGCHK(header != NULL); return omac_process(&eax->headeromac, header, length); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/eax/eax_addheader.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/eax/eax_done.c0000644000175100001440000000432710621351501017452 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file eax_done.c EAX implementation, terminate session, by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_EAX_MODE /** Terminate an EAX session and get the tag. @param eax The EAX state @param tag [out] The destination of the authentication tag @param taglen [in/out] The max length and resulting length of the authentication tag @return CRYPT_OK if successful */ int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen) { int err; unsigned char *headermac, *ctmac; unsigned long x, len; LTC_ARGCHK(eax != NULL); LTC_ARGCHK(tag != NULL); LTC_ARGCHK(taglen != NULL); /* allocate ram */ headermac = XMALLOC(MAXBLOCKSIZE); ctmac = XMALLOC(MAXBLOCKSIZE); if (headermac == NULL || ctmac == NULL) { if (headermac != NULL) { XFREE(headermac); } if (ctmac != NULL) { XFREE(ctmac); } return CRYPT_MEM; } /* finish ctomac */ len = MAXBLOCKSIZE; if ((err = omac_done(&eax->ctomac, ctmac, &len)) != CRYPT_OK) { goto LBL_ERR; } /* finish headeromac */ /* note we specifically don't reset len so the two lens are minimal */ if ((err = omac_done(&eax->headeromac, headermac, &len)) != CRYPT_OK) { goto LBL_ERR; } /* terminate the CTR chain */ if ((err = ctr_done(&eax->ctr)) != CRYPT_OK) { goto LBL_ERR; } /* compute N xor H xor C */ for (x = 0; x < len && x < *taglen; x++) { tag[x] = eax->N[x] ^ headermac[x] ^ ctmac[x]; } *taglen = x; err = CRYPT_OK; LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(ctmac, MAXBLOCKSIZE); zeromem(headermac, MAXBLOCKSIZE); zeromem(eax, sizeof(*eax)); #endif XFREE(ctmac); XFREE(headermac); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/eax/eax_done.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/gcm/0000755000175100001440000000000010621351501015507 5ustar tomuserslibtomcrypt-1.17/src/encauth/gcm/gcm_reset.c0000644000175100001440000000207610621351501017630 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file gcm_reset.c GCM implementation, reset a used state so it can accept IV data, by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_GCM_MODE /** Reset a GCM state to as if you just called gcm_init(). This saves the initialization time. @param gcm The GCM state to reset @return CRYPT_OK on success */ int gcm_reset(gcm_state *gcm) { LTC_ARGCHK(gcm != NULL); zeromem(gcm->buf, sizeof(gcm->buf)); zeromem(gcm->X, sizeof(gcm->X)); gcm->mode = LTC_GCM_MODE_IV; gcm->ivmode = 0; gcm->buflen = 0; gcm->totlen = 0; gcm->pttotlen = 0; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_reset.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/gcm/gcm_test.c0000644000175100001440000002703410621351501017466 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file gcm_test.c GCM implementation, testing, by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_GCM_MODE /** Test the GCM code @return CRYPT_OK on success */ int gcm_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { unsigned char K[32]; int keylen; unsigned char P[128]; unsigned long ptlen; unsigned char A[128]; unsigned long alen; unsigned char IV[128]; unsigned long IVlen; unsigned char C[128]; unsigned char T[16]; } tests[] = { /* test case #1 */ { /* key */ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 16, /* plaintext */ { 0 }, 0, /* AAD data */ { 0 }, 0, /* IV */ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 12, /* ciphertext */ { 0 }, /* tag */ { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a } }, /* test case #2 */ { /* key */ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 16, /* PT */ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 16, /* ADATA */ { 0 }, 0, /* IV */ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 12, /* CT */ { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 }, /* TAG */ { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf } }, /* test case #3 */ { /* key */ { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, }, 16, /* PT */ { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, }, 64, /* ADATA */ { 0 }, 0, /* IV */ { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88, }, 12, /* CT */ { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85, }, /* TAG */ { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4, } }, /* test case #4 */ { /* key */ { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, }, 16, /* PT */ { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, 0xba, 0x63, 0x7b, 0x39, }, 60, /* ADATA */ { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2, }, 20, /* IV */ { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, 0xde, 0xca, 0xf8, 0x88, }, 12, /* CT */ { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, 0x3d, 0x58, 0xe0, 0x91, }, /* TAG */ { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47, } }, /* test case #5 */ { /* key */ { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, }, 16, /* PT */ { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, 0xba, 0x63, 0x7b, 0x39, }, 60, /* ADATA */ { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2, }, 20, /* IV */ { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, }, 8, /* CT */ { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55, 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23, 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2, 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42, 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07, 0xc2, 0x3f, 0x45, 0x98, }, /* TAG */ { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85, 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb, } }, /* test case #6 */ { /* key */ { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, }, 16, /* PT */ { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, 0xba, 0x63, 0x7b, 0x39, }, 60, /* ADATA */ { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, 0xab, 0xad, 0xda, 0xd2, }, 20, /* IV */ { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, 0xa6, 0x37, 0xb3, 0x9b, }, 60, /* CT */ { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94, 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7, 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90, 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f, 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03, 0x4c, 0x34, 0xae, 0xe5, }, /* TAG */ { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa, 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50, } }, /* test case #46 from BG (catches the LTC bug of v1.15) */ { /* key */ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 16, /* PT */ { 0xa2, 0xaa, 0xb3, 0xad, 0x8b, 0x17, 0xac, 0xdd, 0xa2, 0x88, 0x42, 0x6c, 0xd7, 0xc4, 0x29, 0xb7, 0xca, 0x86, 0xb7, 0xac, 0xa0, 0x58, 0x09, 0xc7, 0x0c, 0xe8, 0x2d, 0xb2, 0x57, 0x11, 0xcb, 0x53, 0x02, 0xeb, 0x27, 0x43, 0xb0, 0x36, 0xf3, 0xd7, 0x50, 0xd6, 0xcf, 0x0d, 0xc0, 0xac, 0xb9, 0x29, 0x50, 0xd5, 0x46, 0xdb, 0x30, 0x8f, 0x93, 0xb4, 0xff, 0x24, 0x4a, 0xfa, 0x9d, 0xc7, 0x2b, 0xcd, 0x75, 0x8d, 0x2c }, 67, /* ADATA */ { 0x68, 0x8e, 0x1a, 0xa9, 0x84, 0xde, 0x92, 0x6d, 0xc7, 0xb4, 0xc4, 0x7f, 0x44 }, 13, /* IV */ { 0xb7, 0x21, 0x38, 0xb5, 0xa0, 0x5f, 0xf5, 0x07, 0x0e, 0x8c, 0xd9, 0x41, 0x83, 0xf7, 0x61, 0xd8 }, 16, /* CT */ { 0xcb, 0xc8, 0xd2, 0xf1, 0x54, 0x81, 0xa4, 0xcc, 0x7d, 0xd1, 0xe1, 0x9a, 0xaa, 0x83, 0xde, 0x56, 0x78, 0x48, 0x3e, 0xc3, 0x59, 0xae, 0x7d, 0xec, 0x2a, 0xb8, 0xd5, 0x34, 0xe0, 0x90, 0x6f, 0x4b, 0x46, 0x63, 0xfa, 0xff, 0x58, 0xa8, 0xb2, 0xd7, 0x33, 0xb8, 0x45, 0xee, 0xf7, 0xc9, 0xb3, 0x31, 0xe9, 0xe1, 0x0e, 0xb2, 0x61, 0x2c, 0x99, 0x5f, 0xeb, 0x1a, 0xc1, 0x5a, 0x62, 0x86, 0xcc, 0xe8, 0xb2, 0x97, 0xa8 }, /* TAG */ { 0x8d, 0x2d, 0x2a, 0x93, 0x72, 0x62, 0x6f, 0x6b, 0xee, 0x85, 0x80, 0x27, 0x6a, 0x63, 0x66, 0xbf } } /* rest of test cases are the same except AES key size changes... ignored... */ }; int idx, err; unsigned long x, y; unsigned char out[2][128], T[2][16]; /* find aes */ idx = find_cipher("aes"); if (idx == -1) { idx = find_cipher("rijndael"); if (idx == -1) { return CRYPT_NOP; } } for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { y = sizeof(T[0]); if ((err = gcm_memory(idx, tests[x].K, tests[x].keylen, tests[x].IV, tests[x].IVlen, tests[x].A, tests[x].alen, (unsigned char*)tests[x].P, tests[x].ptlen, out[0], T[0], &y, GCM_ENCRYPT)) != CRYPT_OK) { return err; } if (XMEMCMP(out[0], tests[x].C, tests[x].ptlen)) { #if 0 printf("\nCiphertext wrong %lu\n", x); for (y = 0; y < tests[x].ptlen; y++) { printf("%02x", out[0][y] & 255); } printf("\n"); #endif return CRYPT_FAIL_TESTVECTOR; } if (XMEMCMP(T[0], tests[x].T, 16)) { #if 0 printf("\nTag on plaintext wrong %lu\n", x); for (y = 0; y < 16; y++) { printf("%02x", T[0][y] & 255); } printf("\n"); #endif return CRYPT_FAIL_TESTVECTOR; } y = sizeof(T[1]); if ((err = gcm_memory(idx, tests[x].K, tests[x].keylen, tests[x].IV, tests[x].IVlen, tests[x].A, tests[x].alen, out[1], tests[x].ptlen, out[0], T[1], &y, GCM_DECRYPT)) != CRYPT_OK) { return err; } if (XMEMCMP(out[1], tests[x].P, tests[x].ptlen)) { #if 0 printf("\nplaintext wrong %lu\n", x); for (y = 0; y < tests[x].ptlen; y++) { printf("%02x", out[0][y] & 255); } printf("\n"); #endif return CRYPT_FAIL_TESTVECTOR; } if (XMEMCMP(T[1], tests[x].T, 16)) { #if 0 printf("\nTag on ciphertext wrong %lu\n", x); for (y = 0; y < 16; y++) { printf("%02x", T[1][y] & 255); } printf("\n"); #endif return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_test.c,v $ */ /* $Revision: 1.22 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/gcm/gcm_add_iv.c0000644000175100001440000000412710621351501017733 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file gcm_add_iv.c GCM implementation, add IV data to the state, by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_GCM_MODE /** Add IV data to the GCM state @param gcm The GCM state @param IV The initial value data to add @param IVlen The length of the IV @return CRYPT_OK on success */ int gcm_add_iv(gcm_state *gcm, const unsigned char *IV, unsigned long IVlen) { unsigned long x, y; int err; LTC_ARGCHK(gcm != NULL); if (IVlen > 0) { LTC_ARGCHK(IV != NULL); } /* must be in IV mode */ if (gcm->mode != LTC_GCM_MODE_IV) { return CRYPT_INVALID_ARG; } if (gcm->buflen >= 16 || gcm->buflen < 0) { return CRYPT_INVALID_ARG; } if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) { return err; } /* trip the ivmode flag */ if (IVlen + gcm->buflen > 12) { gcm->ivmode |= 1; } x = 0; #ifdef LTC_FAST if (gcm->buflen == 0) { for (x = 0; x < (IVlen & ~15); x += 16) { for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE*)(&gcm->X[y])) ^= *((LTC_FAST_TYPE*)(&IV[x + y])); } gcm_mult_h(gcm, gcm->X); gcm->totlen += 128; } IV += x; } #endif /* start adding IV data to the state */ for (; x < IVlen; x++) { gcm->buf[gcm->buflen++] = *IV++; if (gcm->buflen == 16) { /* GF mult it */ for (y = 0; y < 16; y++) { gcm->X[y] ^= gcm->buf[y]; } gcm_mult_h(gcm, gcm->X); gcm->buflen = 0; gcm->totlen += 128; } } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_add_iv.c,v $ */ /* $Revision: 1.9 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/gcm/gcm_process.c0000644000175100001440000001064410621351501020164 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file gcm_process.c GCM implementation, process message data, by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_GCM_MODE /** Process plaintext/ciphertext through GCM @param gcm The GCM state @param pt The plaintext @param ptlen The plaintext length (ciphertext length is the same) @param ct The ciphertext @param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT) @return CRYPT_OK on success */ int gcm_process(gcm_state *gcm, unsigned char *pt, unsigned long ptlen, unsigned char *ct, int direction) { unsigned long x; int y, err; unsigned char b; LTC_ARGCHK(gcm != NULL); if (ptlen > 0) { LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); } if (gcm->buflen > 16 || gcm->buflen < 0) { return CRYPT_INVALID_ARG; } if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) { return err; } /* in AAD mode? */ if (gcm->mode == LTC_GCM_MODE_AAD) { /* let's process the AAD */ if (gcm->buflen) { gcm->totlen += gcm->buflen * CONST64(8); gcm_mult_h(gcm, gcm->X); } /* increment counter */ for (y = 15; y >= 12; y--) { if (++gcm->Y[y] & 255) { break; } } /* encrypt the counter */ if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) { return err; } gcm->buflen = 0; gcm->mode = LTC_GCM_MODE_TEXT; } if (gcm->mode != LTC_GCM_MODE_TEXT) { return CRYPT_INVALID_ARG; } x = 0; #ifdef LTC_FAST if (gcm->buflen == 0) { if (direction == GCM_ENCRYPT) { for (x = 0; x < (ptlen & ~15); x += 16) { /* ctr encrypt */ for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE*)(&ct[x + y])) = *((LTC_FAST_TYPE*)(&pt[x+y])) ^ *((LTC_FAST_TYPE*)(&gcm->buf[y])); *((LTC_FAST_TYPE*)(&gcm->X[y])) ^= *((LTC_FAST_TYPE*)(&ct[x+y])); } /* GMAC it */ gcm->pttotlen += 128; gcm_mult_h(gcm, gcm->X); /* increment counter */ for (y = 15; y >= 12; y--) { if (++gcm->Y[y] & 255) { break; } } if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) { return err; } } } else { for (x = 0; x < (ptlen & ~15); x += 16) { /* ctr encrypt */ for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE*)(&gcm->X[y])) ^= *((LTC_FAST_TYPE*)(&ct[x+y])); *((LTC_FAST_TYPE*)(&pt[x + y])) = *((LTC_FAST_TYPE*)(&ct[x+y])) ^ *((LTC_FAST_TYPE*)(&gcm->buf[y])); } /* GMAC it */ gcm->pttotlen += 128; gcm_mult_h(gcm, gcm->X); /* increment counter */ for (y = 15; y >= 12; y--) { if (++gcm->Y[y] & 255) { break; } } if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) { return err; } } } } #endif /* process text */ for (; x < ptlen; x++) { if (gcm->buflen == 16) { gcm->pttotlen += 128; gcm_mult_h(gcm, gcm->X); /* increment counter */ for (y = 15; y >= 12; y--) { if (++gcm->Y[y] & 255) { break; } } if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y, gcm->buf, &gcm->K)) != CRYPT_OK) { return err; } gcm->buflen = 0; } if (direction == GCM_ENCRYPT) { b = ct[x] = pt[x] ^ gcm->buf[gcm->buflen]; } else { b = ct[x]; pt[x] = ct[x] ^ gcm->buf[gcm->buflen]; } gcm->X[gcm->buflen++] ^= b; } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_process.c,v $ */ /* $Revision: 1.16 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/gcm/gcm_add_aad.c0000644000175100001440000000601610621351501020041 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file gcm_add_aad.c GCM implementation, Add AAD data to the stream, by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_GCM_MODE /** Add AAD to the GCM state @param gcm The GCM state @param adata The additional authentication data to add to the GCM state @param adatalen The length of the AAD data. @return CRYPT_OK on success */ int gcm_add_aad(gcm_state *gcm, const unsigned char *adata, unsigned long adatalen) { unsigned long x; int err; #ifdef LTC_FAST unsigned long y; #endif LTC_ARGCHK(gcm != NULL); if (adatalen > 0) { LTC_ARGCHK(adata != NULL); } if (gcm->buflen > 16 || gcm->buflen < 0) { return CRYPT_INVALID_ARG; } if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) { return err; } /* in IV mode? */ if (gcm->mode == LTC_GCM_MODE_IV) { /* let's process the IV */ if (gcm->ivmode || gcm->buflen != 12) { for (x = 0; x < (unsigned long)gcm->buflen; x++) { gcm->X[x] ^= gcm->buf[x]; } if (gcm->buflen) { gcm->totlen += gcm->buflen * CONST64(8); gcm_mult_h(gcm, gcm->X); } /* mix in the length */ zeromem(gcm->buf, 8); STORE64H(gcm->totlen, gcm->buf+8); for (x = 0; x < 16; x++) { gcm->X[x] ^= gcm->buf[x]; } gcm_mult_h(gcm, gcm->X); /* copy counter out */ XMEMCPY(gcm->Y, gcm->X, 16); zeromem(gcm->X, 16); } else { XMEMCPY(gcm->Y, gcm->buf, 12); gcm->Y[12] = 0; gcm->Y[13] = 0; gcm->Y[14] = 0; gcm->Y[15] = 1; } XMEMCPY(gcm->Y_0, gcm->Y, 16); zeromem(gcm->buf, 16); gcm->buflen = 0; gcm->totlen = 0; gcm->mode = LTC_GCM_MODE_AAD; } if (gcm->mode != LTC_GCM_MODE_AAD || gcm->buflen >= 16) { return CRYPT_INVALID_ARG; } x = 0; #ifdef LTC_FAST if (gcm->buflen == 0) { for (x = 0; x < (adatalen & ~15); x += 16) { for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE*)(&gcm->X[y])) ^= *((LTC_FAST_TYPE*)(&adata[x + y])); } gcm_mult_h(gcm, gcm->X); gcm->totlen += 128; } adata += x; } #endif /* start adding AAD data to the state */ for (; x < adatalen; x++) { gcm->X[gcm->buflen++] ^= *adata++; if (gcm->buflen == 16) { /* GF mult it */ gcm_mult_h(gcm, gcm->X); gcm->buflen = 0; gcm->totlen += 128; } } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_add_aad.c,v $ */ /* $Revision: 1.18 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/gcm/gcm_gf_mult.c0000644000175100001440000002031110621351501020133 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file gcm_gf_mult.c GCM implementation, do the GF mult, by Tom St Denis */ #include "tomcrypt.h" #if defined(LTC_GCM_TABLES) || defined(LRW_TABLES) || ((defined(LTC_GCM_MODE) || defined(LTC_GCM_MODE)) && defined(LTC_FAST)) /* this is x*2^128 mod p(x) ... the results are 16 bytes each stored in a packed format. Since only the * lower 16 bits are not zero'ed I removed the upper 14 bytes */ const unsigned char gcm_shift_table[256*2] = { 0x00, 0x00, 0x01, 0xc2, 0x03, 0x84, 0x02, 0x46, 0x07, 0x08, 0x06, 0xca, 0x04, 0x8c, 0x05, 0x4e, 0x0e, 0x10, 0x0f, 0xd2, 0x0d, 0x94, 0x0c, 0x56, 0x09, 0x18, 0x08, 0xda, 0x0a, 0x9c, 0x0b, 0x5e, 0x1c, 0x20, 0x1d, 0xe2, 0x1f, 0xa4, 0x1e, 0x66, 0x1b, 0x28, 0x1a, 0xea, 0x18, 0xac, 0x19, 0x6e, 0x12, 0x30, 0x13, 0xf2, 0x11, 0xb4, 0x10, 0x76, 0x15, 0x38, 0x14, 0xfa, 0x16, 0xbc, 0x17, 0x7e, 0x38, 0x40, 0x39, 0x82, 0x3b, 0xc4, 0x3a, 0x06, 0x3f, 0x48, 0x3e, 0x8a, 0x3c, 0xcc, 0x3d, 0x0e, 0x36, 0x50, 0x37, 0x92, 0x35, 0xd4, 0x34, 0x16, 0x31, 0x58, 0x30, 0x9a, 0x32, 0xdc, 0x33, 0x1e, 0x24, 0x60, 0x25, 0xa2, 0x27, 0xe4, 0x26, 0x26, 0x23, 0x68, 0x22, 0xaa, 0x20, 0xec, 0x21, 0x2e, 0x2a, 0x70, 0x2b, 0xb2, 0x29, 0xf4, 0x28, 0x36, 0x2d, 0x78, 0x2c, 0xba, 0x2e, 0xfc, 0x2f, 0x3e, 0x70, 0x80, 0x71, 0x42, 0x73, 0x04, 0x72, 0xc6, 0x77, 0x88, 0x76, 0x4a, 0x74, 0x0c, 0x75, 0xce, 0x7e, 0x90, 0x7f, 0x52, 0x7d, 0x14, 0x7c, 0xd6, 0x79, 0x98, 0x78, 0x5a, 0x7a, 0x1c, 0x7b, 0xde, 0x6c, 0xa0, 0x6d, 0x62, 0x6f, 0x24, 0x6e, 0xe6, 0x6b, 0xa8, 0x6a, 0x6a, 0x68, 0x2c, 0x69, 0xee, 0x62, 0xb0, 0x63, 0x72, 0x61, 0x34, 0x60, 0xf6, 0x65, 0xb8, 0x64, 0x7a, 0x66, 0x3c, 0x67, 0xfe, 0x48, 0xc0, 0x49, 0x02, 0x4b, 0x44, 0x4a, 0x86, 0x4f, 0xc8, 0x4e, 0x0a, 0x4c, 0x4c, 0x4d, 0x8e, 0x46, 0xd0, 0x47, 0x12, 0x45, 0x54, 0x44, 0x96, 0x41, 0xd8, 0x40, 0x1a, 0x42, 0x5c, 0x43, 0x9e, 0x54, 0xe0, 0x55, 0x22, 0x57, 0x64, 0x56, 0xa6, 0x53, 0xe8, 0x52, 0x2a, 0x50, 0x6c, 0x51, 0xae, 0x5a, 0xf0, 0x5b, 0x32, 0x59, 0x74, 0x58, 0xb6, 0x5d, 0xf8, 0x5c, 0x3a, 0x5e, 0x7c, 0x5f, 0xbe, 0xe1, 0x00, 0xe0, 0xc2, 0xe2, 0x84, 0xe3, 0x46, 0xe6, 0x08, 0xe7, 0xca, 0xe5, 0x8c, 0xe4, 0x4e, 0xef, 0x10, 0xee, 0xd2, 0xec, 0x94, 0xed, 0x56, 0xe8, 0x18, 0xe9, 0xda, 0xeb, 0x9c, 0xea, 0x5e, 0xfd, 0x20, 0xfc, 0xe2, 0xfe, 0xa4, 0xff, 0x66, 0xfa, 0x28, 0xfb, 0xea, 0xf9, 0xac, 0xf8, 0x6e, 0xf3, 0x30, 0xf2, 0xf2, 0xf0, 0xb4, 0xf1, 0x76, 0xf4, 0x38, 0xf5, 0xfa, 0xf7, 0xbc, 0xf6, 0x7e, 0xd9, 0x40, 0xd8, 0x82, 0xda, 0xc4, 0xdb, 0x06, 0xde, 0x48, 0xdf, 0x8a, 0xdd, 0xcc, 0xdc, 0x0e, 0xd7, 0x50, 0xd6, 0x92, 0xd4, 0xd4, 0xd5, 0x16, 0xd0, 0x58, 0xd1, 0x9a, 0xd3, 0xdc, 0xd2, 0x1e, 0xc5, 0x60, 0xc4, 0xa2, 0xc6, 0xe4, 0xc7, 0x26, 0xc2, 0x68, 0xc3, 0xaa, 0xc1, 0xec, 0xc0, 0x2e, 0xcb, 0x70, 0xca, 0xb2, 0xc8, 0xf4, 0xc9, 0x36, 0xcc, 0x78, 0xcd, 0xba, 0xcf, 0xfc, 0xce, 0x3e, 0x91, 0x80, 0x90, 0x42, 0x92, 0x04, 0x93, 0xc6, 0x96, 0x88, 0x97, 0x4a, 0x95, 0x0c, 0x94, 0xce, 0x9f, 0x90, 0x9e, 0x52, 0x9c, 0x14, 0x9d, 0xd6, 0x98, 0x98, 0x99, 0x5a, 0x9b, 0x1c, 0x9a, 0xde, 0x8d, 0xa0, 0x8c, 0x62, 0x8e, 0x24, 0x8f, 0xe6, 0x8a, 0xa8, 0x8b, 0x6a, 0x89, 0x2c, 0x88, 0xee, 0x83, 0xb0, 0x82, 0x72, 0x80, 0x34, 0x81, 0xf6, 0x84, 0xb8, 0x85, 0x7a, 0x87, 0x3c, 0x86, 0xfe, 0xa9, 0xc0, 0xa8, 0x02, 0xaa, 0x44, 0xab, 0x86, 0xae, 0xc8, 0xaf, 0x0a, 0xad, 0x4c, 0xac, 0x8e, 0xa7, 0xd0, 0xa6, 0x12, 0xa4, 0x54, 0xa5, 0x96, 0xa0, 0xd8, 0xa1, 0x1a, 0xa3, 0x5c, 0xa2, 0x9e, 0xb5, 0xe0, 0xb4, 0x22, 0xb6, 0x64, 0xb7, 0xa6, 0xb2, 0xe8, 0xb3, 0x2a, 0xb1, 0x6c, 0xb0, 0xae, 0xbb, 0xf0, 0xba, 0x32, 0xb8, 0x74, 0xb9, 0xb6, 0xbc, 0xf8, 0xbd, 0x3a, 0xbf, 0x7c, 0xbe, 0xbe }; #endif #if defined(LTC_GCM_MODE) || defined(LRW_MODE) #ifndef LTC_FAST /* right shift */ static void gcm_rightshift(unsigned char *a) { int x; for (x = 15; x > 0; x--) { a[x] = (a[x]>>1) | ((a[x-1]<<7)&0x80); } a[0] >>= 1; } /* c = b*a */ static const unsigned char mask[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; static const unsigned char poly[] = { 0x00, 0xE1 }; /** GCM GF multiplier (internal use only) bitserial @param a First value @param b Second value @param c Destination for a * b */ void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c) { unsigned char Z[16], V[16]; unsigned x, y, z; zeromem(Z, 16); XMEMCPY(V, a, 16); for (x = 0; x < 128; x++) { if (b[x>>3] & mask[x&7]) { for (y = 0; y < 16; y++) { Z[y] ^= V[y]; } } z = V[15] & 0x01; gcm_rightshift(V); V[0] ^= poly[z]; } XMEMCPY(c, Z, 16); } #else /* map normal numbers to "ieee" way ... e.g. bit reversed */ #define M(x) ( ((x&8)>>3) | ((x&4)>>1) | ((x&2)<<1) | ((x&1)<<3) ) #define BPD (sizeof(LTC_FAST_TYPE) * 8) #define WPV (1 + (16 / sizeof(LTC_FAST_TYPE))) /** GCM GF multiplier (internal use only) word oriented @param a First value @param b Second value @param c Destination for a * b */ void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c) { int i, j, k, u; LTC_FAST_TYPE B[16][WPV], tmp[32 / sizeof(LTC_FAST_TYPE)], pB[16 / sizeof(LTC_FAST_TYPE)], zz, z; unsigned char pTmp[32]; /* create simple tables */ zeromem(B[0], sizeof(B[0])); zeromem(B[M(1)], sizeof(B[M(1)])); #ifdef ENDIAN_32BITWORD for (i = 0; i < 4; i++) { LOAD32H(B[M(1)][i], a + (i<<2)); LOAD32L(pB[i], b + (i<<2)); } #else for (i = 0; i < 2; i++) { LOAD64H(B[M(1)][i], a + (i<<3)); LOAD64L(pB[i], b + (i<<3)); } #endif /* now create 2, 4 and 8 */ B[M(2)][0] = B[M(1)][0] >> 1; B[M(4)][0] = B[M(1)][0] >> 2; B[M(8)][0] = B[M(1)][0] >> 3; for (i = 1; i < (int)WPV; i++) { B[M(2)][i] = (B[M(1)][i-1] << (BPD-1)) | (B[M(1)][i] >> 1); B[M(4)][i] = (B[M(1)][i-1] << (BPD-2)) | (B[M(1)][i] >> 2); B[M(8)][i] = (B[M(1)][i-1] << (BPD-3)) | (B[M(1)][i] >> 3); } /* now all values with two bits which are 3, 5, 6, 9, 10, 12 */ for (i = 0; i < (int)WPV; i++) { B[M(3)][i] = B[M(1)][i] ^ B[M(2)][i]; B[M(5)][i] = B[M(1)][i] ^ B[M(4)][i]; B[M(6)][i] = B[M(2)][i] ^ B[M(4)][i]; B[M(9)][i] = B[M(1)][i] ^ B[M(8)][i]; B[M(10)][i] = B[M(2)][i] ^ B[M(8)][i]; B[M(12)][i] = B[M(8)][i] ^ B[M(4)][i]; /* now all 3 bit values and the only 4 bit value: 7, 11, 13, 14, 15 */ B[M(7)][i] = B[M(3)][i] ^ B[M(4)][i]; B[M(11)][i] = B[M(3)][i] ^ B[M(8)][i]; B[M(13)][i] = B[M(1)][i] ^ B[M(12)][i]; B[M(14)][i] = B[M(6)][i] ^ B[M(8)][i]; B[M(15)][i] = B[M(7)][i] ^ B[M(8)][i]; } zeromem(tmp, sizeof(tmp)); /* compute product four bits of each word at a time */ /* for each nibble */ for (i = (BPD/4)-1; i >= 0; i--) { /* for each word */ for (j = 0; j < (int)(WPV-1); j++) { /* grab the 4 bits recall the nibbles are backwards so it's a shift by (i^1)*4 */ u = (pB[j] >> ((i^1)<<2)) & 15; /* add offset by the word count the table looked up value to the result */ for (k = 0; k < (int)WPV; k++) { tmp[k+j] ^= B[u][k]; } } /* shift result up by 4 bits */ if (i != 0) { for (z = j = 0; j < (int)(32 / sizeof(LTC_FAST_TYPE)); j++) { zz = tmp[j] << (BPD-4); tmp[j] = (tmp[j] >> 4) | z; z = zz; } } } /* store product */ #ifdef ENDIAN_32BITWORD for (i = 0; i < 8; i++) { STORE32H(tmp[i], pTmp + (i<<2)); } #else for (i = 0; i < 4; i++) { STORE64H(tmp[i], pTmp + (i<<3)); } #endif /* reduce by taking most significant byte and adding the appropriate two byte sequence 16 bytes down */ for (i = 31; i >= 16; i--) { pTmp[i-16] ^= gcm_shift_table[((unsigned)pTmp[i]<<1)]; pTmp[i-15] ^= gcm_shift_table[((unsigned)pTmp[i]<<1)+1]; } for (i = 0; i < 16; i++) { c[i] = pTmp[i]; } } #endif #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_gf_mult.c,v $ */ /* $Revision: 1.25 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/gcm/gcm_memory.c0000644000175100001440000000676610621351501020030 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file gcm_memory.c GCM implementation, process a packet, by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_GCM_MODE /** Process an entire GCM packet in one call. @param cipher Index of cipher to use @param key The secret key @param keylen The length of the secret key @param IV The initial vector @param IVlen The length of the initial vector @param adata The additional authentication data (header) @param adatalen The length of the adata @param pt The plaintext @param ptlen The length of the plaintext (ciphertext length is the same) @param ct The ciphertext @param tag [out] The MAC tag @param taglen [in/out] The MAC tag length @param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT) @return CRYPT_OK on success */ int gcm_memory( int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *IV, unsigned long IVlen, const unsigned char *adata, unsigned long adatalen, unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tag, unsigned long *taglen, int direction) { void *orig; gcm_state *gcm; int err; if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { return err; } if (cipher_descriptor[cipher].accel_gcm_memory != NULL) { return cipher_descriptor[cipher].accel_gcm_memory (key, keylen, IV, IVlen, adata, adatalen, pt, ptlen, ct, tag, taglen, direction); } #ifndef LTC_GCM_TABLES_SSE2 orig = gcm = XMALLOC(sizeof(*gcm)); #else orig = gcm = XMALLOC(sizeof(*gcm) + 16); #endif if (gcm == NULL) { return CRYPT_MEM; } /* Force GCM to be on a multiple of 16 so we can use 128-bit aligned operations * note that we only modify gcm and keep orig intact. This code is not portable * but again it's only for SSE2 anyways, so who cares? */ #ifdef LTC_GCM_TABLES_SSE2 if ((unsigned long)gcm & 15) { gcm = (gcm_state *)((unsigned long)gcm + (16 - ((unsigned long)gcm & 15))); } #endif if ((err = gcm_init(gcm, cipher, key, keylen)) != CRYPT_OK) { goto LTC_ERR; } if ((err = gcm_add_iv(gcm, IV, IVlen)) != CRYPT_OK) { goto LTC_ERR; } if ((err = gcm_add_aad(gcm, adata, adatalen)) != CRYPT_OK) { goto LTC_ERR; } if ((err = gcm_process(gcm, pt, ptlen, ct, direction)) != CRYPT_OK) { goto LTC_ERR; } err = gcm_done(gcm, tag, taglen); LTC_ERR: XFREE(orig); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_memory.c,v $ */ /* $Revision: 1.25 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/gcm/gcm_mult_h.c0000644000175100001440000000276310621351501020001 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file gcm_mult_h.c GCM implementation, do the GF mult, by Tom St Denis */ #include "tomcrypt.h" #if defined(LTC_GCM_MODE) /** GCM multiply by H @param gcm The GCM state which holds the H value @param I The value to multiply H by */ void gcm_mult_h(gcm_state *gcm, unsigned char *I) { unsigned char T[16]; #ifdef LTC_GCM_TABLES int x, y; #ifdef LTC_GCM_TABLES_SSE2 asm("movdqa (%0),%%xmm0"::"r"(&gcm->PC[0][I[0]][0])); for (x = 1; x < 16; x++) { asm("pxor (%0),%%xmm0"::"r"(&gcm->PC[x][I[x]][0])); } asm("movdqa %%xmm0,(%0)"::"r"(&T)); #else XMEMCPY(T, &gcm->PC[0][I[0]][0], 16); for (x = 1; x < 16; x++) { #ifdef LTC_FAST for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE *)(T + y)) ^= *((LTC_FAST_TYPE *)(&gcm->PC[x][I[x]][y])); } #else for (y = 0; y < 16; y++) { T[y] ^= gcm->PC[x][I[x]][y]; } #endif /* LTC_FAST */ } #endif /* LTC_GCM_TABLES_SSE2 */ #else gcm_gf_mult(gcm->H, I, T); #endif XMEMCPY(I, T, 16); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_mult_h.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/gcm/gcm_done.c0000644000175100001440000000364510621351501017436 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file gcm_done.c GCM implementation, Terminate the stream, by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_GCM_MODE /** Terminate a GCM stream @param gcm The GCM state @param tag [out] The destination for the MAC tag @param taglen [in/out] The length of the MAC tag @return CRYPT_OK on success */ int gcm_done(gcm_state *gcm, unsigned char *tag, unsigned long *taglen) { unsigned long x; int err; LTC_ARGCHK(gcm != NULL); LTC_ARGCHK(tag != NULL); LTC_ARGCHK(taglen != NULL); if (gcm->buflen > 16 || gcm->buflen < 0) { return CRYPT_INVALID_ARG; } if ((err = cipher_is_valid(gcm->cipher)) != CRYPT_OK) { return err; } if (gcm->mode != LTC_GCM_MODE_TEXT) { return CRYPT_INVALID_ARG; } /* handle remaining ciphertext */ if (gcm->buflen) { gcm->pttotlen += gcm->buflen * CONST64(8); gcm_mult_h(gcm, gcm->X); } /* length */ STORE64H(gcm->totlen, gcm->buf); STORE64H(gcm->pttotlen, gcm->buf+8); for (x = 0; x < 16; x++) { gcm->X[x] ^= gcm->buf[x]; } gcm_mult_h(gcm, gcm->X); /* encrypt original counter */ if ((err = cipher_descriptor[gcm->cipher].ecb_encrypt(gcm->Y_0, gcm->buf, &gcm->K)) != CRYPT_OK) { return err; } for (x = 0; x < 16 && x < *taglen; x++) { tag[x] = gcm->buf[x] ^ gcm->X[x]; } *taglen = x; cipher_descriptor[gcm->cipher].done(&gcm->K); return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_done.c,v $ */ /* $Revision: 1.11 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/gcm/gcm_init.c0000644000175100001440000000513110621351501017444 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file gcm_init.c GCM implementation, initialize state, by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_GCM_MODE /** Initialize a GCM state @param gcm The GCM state to initialize @param cipher The index of the cipher to use @param key The secret key @param keylen The length of the secret key @return CRYPT_OK on success */ int gcm_init(gcm_state *gcm, int cipher, const unsigned char *key, int keylen) { int err; unsigned char B[16]; #ifdef LTC_GCM_TABLES int x, y, z, t; #endif LTC_ARGCHK(gcm != NULL); LTC_ARGCHK(key != NULL); #ifdef LTC_FAST if (16 % sizeof(LTC_FAST_TYPE)) { return CRYPT_INVALID_ARG; } #endif /* is cipher valid? */ if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { return err; } if (cipher_descriptor[cipher].block_length != 16) { return CRYPT_INVALID_CIPHER; } /* schedule key */ if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &gcm->K)) != CRYPT_OK) { return err; } /* H = E(0) */ zeromem(B, 16); if ((err = cipher_descriptor[cipher].ecb_encrypt(B, gcm->H, &gcm->K)) != CRYPT_OK) { return err; } /* setup state */ zeromem(gcm->buf, sizeof(gcm->buf)); zeromem(gcm->X, sizeof(gcm->X)); gcm->cipher = cipher; gcm->mode = LTC_GCM_MODE_IV; gcm->ivmode = 0; gcm->buflen = 0; gcm->totlen = 0; gcm->pttotlen = 0; #ifdef LTC_GCM_TABLES /* setup tables */ /* generate the first table as it has no shifting (from which we make the other tables) */ zeromem(B, 16); for (y = 0; y < 256; y++) { B[0] = y; gcm_gf_mult(gcm->H, B, &gcm->PC[0][y][0]); } /* now generate the rest of the tables based the previous table */ for (x = 1; x < 16; x++) { for (y = 0; y < 256; y++) { /* now shift it right by 8 bits */ t = gcm->PC[x-1][y][15]; for (z = 15; z > 0; z--) { gcm->PC[x][y][z] = gcm->PC[x-1][y][z-1]; } gcm->PC[x][y][0] = gcm_shift_table[t<<1]; gcm->PC[x][y][1] ^= gcm_shift_table[(t<<1)+1]; } } #endif return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/gcm/gcm_init.c,v $ */ /* $Revision: 1.20 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/ocb/0000755000175100001440000000000010621351501015504 5ustar tomuserslibtomcrypt-1.17/src/encauth/ocb/ocb_ntz.c0000644000175100001440000000162210621351501017307 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file ocb_ntz.c OCB implementation, internal function, by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_OCB_MODE /** Returns the number of leading zero bits [from lsb up] @param x The 32-bit value to observe @return The number of bits [from the lsb up] that are zero */ int ocb_ntz(unsigned long x) { int c; x &= 0xFFFFFFFFUL; c = 0; while ((x & 1) == 0) { ++c; x >>= 1; } return c; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_ntz.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/ocb/ocb_init.c0000644000175100001440000000735010621351501017443 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file ocb_init.c OCB implementation, initialize state, by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_OCB_MODE static const struct { int len; unsigned char poly_div[MAXBLOCKSIZE], poly_mul[MAXBLOCKSIZE]; } polys[] = { { 8, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B } }, { 16, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 } } }; /** Initialize an OCB context. @param ocb [out] The destination of the OCB state @param cipher The index of the desired cipher @param key The secret key @param keylen The length of the secret key (octets) @param nonce The session nonce (length of the block size of the cipher) @return CRYPT_OK if successful */ int ocb_init(ocb_state *ocb, int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *nonce) { int poly, x, y, m, err; LTC_ARGCHK(ocb != NULL); LTC_ARGCHK(key != NULL); LTC_ARGCHK(nonce != NULL); /* valid cipher? */ if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { return err; } /* determine which polys to use */ ocb->block_len = cipher_descriptor[cipher].block_length; for (poly = 0; poly < (int)(sizeof(polys)/sizeof(polys[0])); poly++) { if (polys[poly].len == ocb->block_len) { break; } } if (polys[poly].len != ocb->block_len) { return CRYPT_INVALID_ARG; } /* schedule the key */ if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &ocb->key)) != CRYPT_OK) { return err; } /* find L = E[0] */ zeromem(ocb->L, ocb->block_len); if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->L, ocb->L, &ocb->key)) != CRYPT_OK) { return err; } /* find R = E[N xor L] */ for (x = 0; x < ocb->block_len; x++) { ocb->R[x] = ocb->L[x] ^ nonce[x]; } if ((err = cipher_descriptor[cipher].ecb_encrypt(ocb->R, ocb->R, &ocb->key)) != CRYPT_OK) { return err; } /* find Ls[i] = L << i for i == 0..31 */ XMEMCPY(ocb->Ls[0], ocb->L, ocb->block_len); for (x = 1; x < 32; x++) { m = ocb->Ls[x-1][0] >> 7; for (y = 0; y < ocb->block_len-1; y++) { ocb->Ls[x][y] = ((ocb->Ls[x-1][y] << 1) | (ocb->Ls[x-1][y+1] >> 7)) & 255; } ocb->Ls[x][ocb->block_len-1] = (ocb->Ls[x-1][ocb->block_len-1] << 1) & 255; if (m == 1) { for (y = 0; y < ocb->block_len; y++) { ocb->Ls[x][y] ^= polys[poly].poly_mul[y]; } } } /* find Lr = L / x */ m = ocb->L[ocb->block_len-1] & 1; /* shift right */ for (x = ocb->block_len - 1; x > 0; x--) { ocb->Lr[x] = ((ocb->L[x] >> 1) | (ocb->L[x-1] << 7)) & 255; } ocb->Lr[0] = ocb->L[0] >> 1; if (m == 1) { for (x = 0; x < ocb->block_len; x++) { ocb->Lr[x] ^= polys[poly].poly_div[x]; } } /* set Li, checksum */ zeromem(ocb->Li, ocb->block_len); zeromem(ocb->checksum, ocb->block_len); /* set other params */ ocb->block_index = 1; ocb->cipher = cipher; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_init.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/ocb/ocb_shift_xor.c0000644000175100001440000000172410621351501020504 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file ocb_shift_xor.c OCB implementation, internal function, by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_OCB_MODE /** Compute the shift/xor for OCB (internal function) @param ocb The OCB state @param Z The destination of the shift */ void ocb_shift_xor(ocb_state *ocb, unsigned char *Z) { int x, y; y = ocb_ntz(ocb->block_index++); for (x = 0; x < ocb->block_len; x++) { ocb->Li[x] ^= ocb->Ls[y][x]; Z[x] = ocb->Li[x] ^ ocb->R[x]; } } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_shift_xor.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/ocb/ocb_test.c0000644000175100001440000001563210621351501017461 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file ocb_test.c OCB implementation, self-test by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_OCB_MODE /** Test the OCB protocol @return CRYPT_OK if successful */ int ocb_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { int ptlen; unsigned char key[16], nonce[16], pt[34], ct[34], tag[16]; } tests[] = { /* OCB-AES-128-0B */ { 0, /* key */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* nonce */ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, /* pt */ { 0 }, /* ct */ { 0 }, /* tag */ { 0x15, 0xd3, 0x7d, 0xd7, 0xc8, 0x90, 0xd5, 0xd6, 0xac, 0xab, 0x92, 0x7b, 0xc0, 0xdc, 0x60, 0xee }, }, /* OCB-AES-128-3B */ { 3, /* key */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* nonce */ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, /* pt */ { 0x00, 0x01, 0x02 }, /* ct */ { 0xfc, 0xd3, 0x7d }, /* tag */ { 0x02, 0x25, 0x47, 0x39, 0xa5, 0xe3, 0x56, 0x5a, 0xe2, 0xdc, 0xd6, 0x2c, 0x65, 0x97, 0x46, 0xba }, }, /* OCB-AES-128-16B */ { 16, /* key */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* nonce */ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, /* pt */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* ct */ { 0x37, 0xdf, 0x8c, 0xe1, 0x5b, 0x48, 0x9b, 0xf3, 0x1d, 0x0f, 0xc4, 0x4d, 0xa1, 0xfa, 0xf6, 0xd6 }, /* tag */ { 0xdf, 0xb7, 0x63, 0xeb, 0xdb, 0x5f, 0x0e, 0x71, 0x9c, 0x7b, 0x41, 0x61, 0x80, 0x80, 0x04, 0xdf }, }, /* OCB-AES-128-20B */ { 20, /* key */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* nonce */ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, /* pt */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13 }, /* ct */ { 0x01, 0xa0, 0x75, 0xf0, 0xd8, 0x15, 0xb1, 0xa4, 0xe9, 0xc8, 0x81, 0xa1, 0xbc, 0xff, 0xc3, 0xeb, 0x70, 0x03, 0xeb, 0x55}, /* tag */ { 0x75, 0x30, 0x84, 0x14, 0x4e, 0xb6, 0x3b, 0x77, 0x0b, 0x06, 0x3c, 0x2e, 0x23, 0xcd, 0xa0, 0xbb }, }, /* OCB-AES-128-32B */ { 32, /* key */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* nonce */ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, /* pt */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, /* ct */ { 0x01, 0xa0, 0x75, 0xf0, 0xd8, 0x15, 0xb1, 0xa4, 0xe9, 0xc8, 0x81, 0xa1, 0xbc, 0xff, 0xc3, 0xeb, 0x4a, 0xfc, 0xbb, 0x7f, 0xed, 0xc0, 0x8c, 0xa8, 0x65, 0x4c, 0x6d, 0x30, 0x4d, 0x16, 0x12, 0xfa }, /* tag */ { 0xc1, 0x4c, 0xbf, 0x2c, 0x1a, 0x1f, 0x1c, 0x3c, 0x13, 0x7e, 0xad, 0xea, 0x1f, 0x2f, 0x2f, 0xcf }, }, /* OCB-AES-128-34B */ { 34, /* key */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, /* nonce */ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, /* pt */ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21 }, /* ct */ { 0x01, 0xa0, 0x75, 0xf0, 0xd8, 0x15, 0xb1, 0xa4, 0xe9, 0xc8, 0x81, 0xa1, 0xbc, 0xff, 0xc3, 0xeb, 0xd4, 0x90, 0x3d, 0xd0, 0x02, 0x5b, 0xa4, 0xaa, 0x83, 0x7c, 0x74, 0xf1, 0x21, 0xb0, 0x26, 0x0f, 0xa9, 0x5d }, /* tag */ { 0xcf, 0x83, 0x41, 0xbb, 0x10, 0x82, 0x0c, 0xcf, 0x14, 0xbd, 0xec, 0x56, 0xb8, 0xd7, 0xd6, 0xab }, }, }; int err, x, idx, res; unsigned long len; unsigned char outct[MAXBLOCKSIZE], outtag[MAXBLOCKSIZE]; /* AES can be under rijndael or aes... try to find it */ if ((idx = find_cipher("aes")) == -1) { if ((idx = find_cipher("rijndael")) == -1) { return CRYPT_NOP; } } for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { len = sizeof(outtag); if ((err = ocb_encrypt_authenticate_memory(idx, tests[x].key, 16, tests[x].nonce, tests[x].pt, tests[x].ptlen, outct, outtag, &len)) != CRYPT_OK) { return err; } if (XMEMCMP(outtag, tests[x].tag, len) || XMEMCMP(outct, tests[x].ct, tests[x].ptlen)) { #if 0 unsigned long y; printf("\n\nFailure: \nCT:\n"); for (y = 0; y < (unsigned long)tests[x].ptlen; ) { printf("0x%02x", outct[y]); if (y < (unsigned long)(tests[x].ptlen-1)) printf(", "); if (!(++y % 8)) printf("\n"); } printf("\nTAG:\n"); for (y = 0; y < len; ) { printf("0x%02x", outtag[y]); if (y < len-1) printf(", "); if (!(++y % 8)) printf("\n"); } #endif return CRYPT_FAIL_TESTVECTOR; } if ((err = ocb_decrypt_verify_memory(idx, tests[x].key, 16, tests[x].nonce, outct, tests[x].ptlen, outct, tests[x].tag, len, &res)) != CRYPT_OK) { return err; } if ((res != 1) || XMEMCMP(tests[x].pt, outct, tests[x].ptlen)) { #if 0 unsigned long y; printf("\n\nFailure-decrypt: \nPT:\n"); for (y = 0; y < (unsigned long)tests[x].ptlen; ) { printf("0x%02x", outct[y]); if (y < (unsigned long)(tests[x].ptlen-1)) printf(", "); if (!(++y % 8)) printf("\n"); } printf("\nres = %d\n\n", res); #endif } } return CRYPT_OK; #endif /* LTC_TEST */ } #endif /* LTC_OCB_MODE */ /* some comments -- it's hard to seek -- hard to stream [you can't emit ciphertext until full block] -- The setup is somewhat complicated... */ /* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_test.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/ocb/ocb_encrypt.c0000644000175100001440000000346510621351501020167 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file ocb_encrypt.c OCB implementation, encrypt data, by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_OCB_MODE /** Encrypt a block of data with OCB. @param ocb The OCB state @param pt The plaintext (length of the block size of the block cipher) @param ct [out] The ciphertext (same size as the pt) @return CRYPT_OK if successful */ int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct) { unsigned char Z[MAXBLOCKSIZE], tmp[MAXBLOCKSIZE]; int err, x; LTC_ARGCHK(ocb != NULL); LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) { return err; } if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) { return CRYPT_INVALID_ARG; } /* compute checksum */ for (x = 0; x < ocb->block_len; x++) { ocb->checksum[x] ^= pt[x]; } /* Get Z[i] value */ ocb_shift_xor(ocb, Z); /* xor pt in, encrypt, xor Z out */ for (x = 0; x < ocb->block_len; x++) { tmp[x] = pt[x] ^ Z[x]; } if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, ct, &ocb->key)) != CRYPT_OK) { return err; } for (x = 0; x < ocb->block_len; x++) { ct[x] ^= Z[x]; } #ifdef LTC_CLEAN_STACK zeromem(Z, sizeof(Z)); zeromem(tmp, sizeof(tmp)); #endif return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_encrypt.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/ocb/ocb_encrypt_authenticate_memory.c0000644000175100001440000000453410621351501024313 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file ocb_encrypt_authenticate_memory.c OCB implementation, encrypt block of memory, by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_OCB_MODE /** Encrypt and generate an authentication code for a buffer of memory @param cipher The index of the cipher desired @param key The secret key @param keylen The length of the secret key (octets) @param nonce The session nonce (length of the block ciphers block size) @param pt The plaintext @param ptlen The length of the plaintext (octets) @param ct [out] The ciphertext @param tag [out] The authentication tag @param taglen [in/out] The max size and resulting size of the authentication tag @return CRYPT_OK if successful */ int ocb_encrypt_authenticate_memory(int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *nonce, const unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tag, unsigned long *taglen) { int err; ocb_state *ocb; LTC_ARGCHK(key != NULL); LTC_ARGCHK(nonce != NULL); LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(tag != NULL); LTC_ARGCHK(taglen != NULL); /* allocate ram */ ocb = XMALLOC(sizeof(ocb_state)); if (ocb == NULL) { return CRYPT_MEM; } if ((err = ocb_init(ocb, cipher, key, keylen, nonce)) != CRYPT_OK) { goto LBL_ERR; } while (ptlen > (unsigned long)ocb->block_len) { if ((err = ocb_encrypt(ocb, pt, ct)) != CRYPT_OK) { goto LBL_ERR; } ptlen -= ocb->block_len; pt += ocb->block_len; ct += ocb->block_len; } err = ocb_done_encrypt(ocb, pt, ptlen, ct, tag, taglen); LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(ocb, sizeof(ocb_state)); #endif XFREE(ocb); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_encrypt_authenticate_memory.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/ocb/ocb_decrypt.c0000644000175100001440000000363510621351501020154 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file ocb_decrypt.c OCB implementation, decrypt data, by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_OCB_MODE /** Decrypt a block with OCB. @param ocb The OCB state @param ct The ciphertext (length of the block size of the block cipher) @param pt [out] The plaintext (length of ct) @return CRYPT_OK if successful */ int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt) { unsigned char Z[MAXBLOCKSIZE], tmp[MAXBLOCKSIZE]; int err, x; LTC_ARGCHK(ocb != NULL); LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); /* check if valid cipher */ if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) { return err; } LTC_ARGCHK(cipher_descriptor[ocb->cipher].ecb_decrypt != NULL); /* check length */ if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) { return CRYPT_INVALID_ARG; } /* Get Z[i] value */ ocb_shift_xor(ocb, Z); /* xor ct in, encrypt, xor Z out */ for (x = 0; x < ocb->block_len; x++) { tmp[x] = ct[x] ^ Z[x]; } if ((err = cipher_descriptor[ocb->cipher].ecb_decrypt(tmp, pt, &ocb->key)) != CRYPT_OK) { return err; } for (x = 0; x < ocb->block_len; x++) { pt[x] ^= Z[x]; } /* compute checksum */ for (x = 0; x < ocb->block_len; x++) { ocb->checksum[x] ^= pt[x]; } #ifdef LTC_CLEAN_STACK zeromem(Z, sizeof(Z)); zeromem(tmp, sizeof(tmp)); #endif return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_decrypt.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/ocb/ocb_decrypt_verify_memory.c0000644000175100001440000000467110621351501023131 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file ocb_decrypt_verify_memory.c OCB implementation, helper to decrypt block of memory, by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_OCB_MODE /** Decrypt and compare the tag with OCB. @param cipher The index of the cipher desired @param key The secret key @param keylen The length of the secret key (octets) @param nonce The session nonce (length of the block size of the block cipher) @param ct The ciphertext @param ctlen The length of the ciphertext (octets) @param pt [out] The plaintext @param tag The tag to compare against @param taglen The length of the tag (octets) @param stat [out] The result of the tag comparison (1==valid, 0==invalid) @return CRYPT_OK if successful regardless of the tag comparison */ int ocb_decrypt_verify_memory(int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *nonce, const unsigned char *ct, unsigned long ctlen, unsigned char *pt, const unsigned char *tag, unsigned long taglen, int *stat) { int err; ocb_state *ocb; LTC_ARGCHK(key != NULL); LTC_ARGCHK(nonce != NULL); LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(tag != NULL); LTC_ARGCHK(stat != NULL); /* allocate memory */ ocb = XMALLOC(sizeof(ocb_state)); if (ocb == NULL) { return CRYPT_MEM; } if ((err = ocb_init(ocb, cipher, key, keylen, nonce)) != CRYPT_OK) { goto LBL_ERR; } while (ctlen > (unsigned long)ocb->block_len) { if ((err = ocb_decrypt(ocb, ct, pt)) != CRYPT_OK) { goto LBL_ERR; } ctlen -= ocb->block_len; pt += ocb->block_len; ct += ocb->block_len; } err = ocb_done_decrypt(ocb, ct, ctlen, pt, tag, taglen, stat); LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(ocb, sizeof(ocb_state)); #endif XFREE(ocb); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_decrypt_verify_memory.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/ocb/s_ocb_done.c0000644000175100001440000000760510621351501017752 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file s_ocb_done.c OCB implementation, internal helper, by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_OCB_MODE /* Since the last block is encrypted in CTR mode the same code can * be used to finish a decrypt or encrypt stream. The only difference * is we XOR the final ciphertext into the checksum so we have to xor it * before we CTR [decrypt] or after [encrypt] * * the names pt/ptlen/ct really just mean in/inlen/out but this is the way I wrote it... */ /** Shared code to finish an OCB stream @param ocb The OCB state @param pt The remaining plaintext [or input] @param ptlen The length of the input (octets) @param ct [out] The output buffer @param tag [out] The destination for the authentication tag @param taglen [in/out] The max size and resulting size of the authentication tag @param mode The mode we are terminating, 0==encrypt, 1==decrypt @return CRYPT_OK if successful */ int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tag, unsigned long *taglen, int mode) { unsigned char *Z, *Y, *X; int err, x; LTC_ARGCHK(ocb != NULL); LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(tag != NULL); LTC_ARGCHK(taglen != NULL); if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) { return err; } if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length || (int)ptlen > ocb->block_len || (int)ptlen < 0) { return CRYPT_INVALID_ARG; } /* allocate ram */ Z = XMALLOC(MAXBLOCKSIZE); Y = XMALLOC(MAXBLOCKSIZE); X = XMALLOC(MAXBLOCKSIZE); if (X == NULL || Y == NULL || Z == NULL) { if (X != NULL) { XFREE(X); } if (Y != NULL) { XFREE(Y); } if (Z != NULL) { XFREE(Z); } return CRYPT_MEM; } /* compute X[m] = len(pt[m]) XOR Lr XOR Z[m] */ ocb_shift_xor(ocb, X); XMEMCPY(Z, X, ocb->block_len); X[ocb->block_len-1] ^= (ptlen*8)&255; X[ocb->block_len-2] ^= ((ptlen*8)>>8)&255; for (x = 0; x < ocb->block_len; x++) { X[x] ^= ocb->Lr[x]; } /* Y[m] = E(X[m])) */ if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(X, Y, &ocb->key)) != CRYPT_OK) { goto error; } if (mode == 1) { /* decrypt mode, so let's xor it first */ /* xor C[m] into checksum */ for (x = 0; x < (int)ptlen; x++) { ocb->checksum[x] ^= ct[x]; } } /* C[m] = P[m] xor Y[m] */ for (x = 0; x < (int)ptlen; x++) { ct[x] = pt[x] ^ Y[x]; } if (mode == 0) { /* encrypt mode */ /* xor C[m] into checksum */ for (x = 0; x < (int)ptlen; x++) { ocb->checksum[x] ^= ct[x]; } } /* xor Y[m] and Z[m] into checksum */ for (x = 0; x < ocb->block_len; x++) { ocb->checksum[x] ^= Y[x] ^ Z[x]; } /* encrypt checksum, er... tag!! */ if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->checksum, X, &ocb->key)) != CRYPT_OK) { goto error; } cipher_descriptor[ocb->cipher].done(&ocb->key); /* now store it */ for (x = 0; x < ocb->block_len && x < (int)*taglen; x++) { tag[x] = X[x]; } *taglen = x; #ifdef LTC_CLEAN_STACK zeromem(X, MAXBLOCKSIZE); zeromem(Y, MAXBLOCKSIZE); zeromem(Z, MAXBLOCKSIZE); zeromem(ocb, sizeof(*ocb)); #endif error: XFREE(X); XFREE(Y); XFREE(Z); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/s_ocb_done.c,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/ocb/ocb_done_encrypt.c0000644000175100001440000000256710621351501021176 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file ocb_done_encrypt.c OCB implementation, terminate encryption, by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_OCB_MODE /** Terminate an encryption OCB state @param ocb The OCB state @param pt Remaining plaintext (if any) @param ptlen The length of the plaintext (octets) @param ct [out] The ciphertext (if any) @param tag [out] The tag for the OCB stream @param taglen [in/out] The max size and resulting size of the tag @return CRYPT_OK if successful */ int ocb_done_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tag, unsigned long *taglen) { LTC_ARGCHK(ocb != NULL); LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(tag != NULL); LTC_ARGCHK(taglen != NULL); return s_ocb_done(ocb, pt, ptlen, ct, tag, taglen, 0); } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_done_encrypt.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/encauth/ocb/ocb_done_decrypt.c0000644000175100001440000000400610621351501021152 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file ocb_done_decrypt.c OCB implementation, terminate decryption, by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_OCB_MODE /** Terminate a decrypting OCB state @param ocb The OCB state @param ct The ciphertext (if any) @param ctlen The length of the ciphertext (octets) @param pt [out] The plaintext @param tag The authentication tag (to compare against) @param taglen The length of the authentication tag provided @param stat [out] The result of the tag comparison @return CRYPT_OK if the process was successful regardless if the tag is valid */ int ocb_done_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt, const unsigned char *tag, unsigned long taglen, int *stat) { int err; unsigned char *tagbuf; unsigned long tagbuflen; LTC_ARGCHK(ocb != NULL); LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(tag != NULL); LTC_ARGCHK(stat != NULL); /* default to failed */ *stat = 0; /* allocate memory */ tagbuf = XMALLOC(MAXBLOCKSIZE); if (tagbuf == NULL) { return CRYPT_MEM; } tagbuflen = MAXBLOCKSIZE; if ((err = s_ocb_done(ocb, ct, ctlen, pt, tagbuf, &tagbuflen, 1)) != CRYPT_OK) { goto LBL_ERR; } if (taglen <= tagbuflen && XMEMCMP(tagbuf, tag, taglen) == 0) { *stat = 1; } err = CRYPT_OK; LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(tagbuf, MAXBLOCKSIZE); #endif XFREE(tagbuf); return err; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/encauth/ocb/ocb_done_decrypt.c,v $ */ /* $Revision: 1.7 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/hashes/0000755000175100001440000000000010621351501014565 5ustar tomuserslibtomcrypt-1.17/src/hashes/chc/0000755000175100001440000000000010621351501015322 5ustar tomuserslibtomcrypt-1.17/src/hashes/chc/chc.c0000644000175100001440000001672710621351501016240 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file chc.c CHC support. (Tom St Denis) */ #ifdef LTC_CHC_HASH #define UNDEFED_HASH -17 /* chc settings */ static int cipher_idx=UNDEFED_HASH, /* which cipher */ cipher_blocksize; /* blocksize of cipher */ const struct ltc_hash_descriptor chc_desc = { "chc_hash", 12, 0, 0, { 0 }, 0, &chc_init, &chc_process, &chc_done, &chc_test, NULL }; /** Initialize the CHC state with a given cipher @param cipher The index of the cipher you wish to bind @return CRYPT_OK if successful */ int chc_register(int cipher) { int err, kl, idx; if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { return err; } /* will it be valid? */ kl = cipher_descriptor[cipher].block_length; /* must be >64 bit block */ if (kl <= 8) { return CRYPT_INVALID_CIPHER; } /* can we use the ideal keysize? */ if ((err = cipher_descriptor[cipher].keysize(&kl)) != CRYPT_OK) { return err; } /* we require that key size == block size be a valid choice */ if (kl != cipher_descriptor[cipher].block_length) { return CRYPT_INVALID_CIPHER; } /* determine if chc_hash has been register_hash'ed already */ if ((err = hash_is_valid(idx = find_hash("chc_hash"))) != CRYPT_OK) { return err; } /* store into descriptor */ hash_descriptor[idx].hashsize = hash_descriptor[idx].blocksize = cipher_descriptor[cipher].block_length; /* store the idx and block size */ cipher_idx = cipher; cipher_blocksize = cipher_descriptor[cipher].block_length; return CRYPT_OK; } /** Initialize the hash state @param md The hash state you wish to initialize @return CRYPT_OK if successful */ int chc_init(hash_state *md) { symmetric_key *key; unsigned char buf[MAXBLOCKSIZE]; int err; LTC_ARGCHK(md != NULL); /* is the cipher valid? */ if ((err = cipher_is_valid(cipher_idx)) != CRYPT_OK) { return err; } if (cipher_blocksize != cipher_descriptor[cipher_idx].block_length) { return CRYPT_INVALID_CIPHER; } if ((key = XMALLOC(sizeof(*key))) == NULL) { return CRYPT_MEM; } /* zero key and what not */ zeromem(buf, cipher_blocksize); if ((err = cipher_descriptor[cipher_idx].setup(buf, cipher_blocksize, 0, key)) != CRYPT_OK) { XFREE(key); return err; } /* encrypt zero block */ cipher_descriptor[cipher_idx].ecb_encrypt(buf, md->chc.state, key); /* zero other members */ md->chc.length = 0; md->chc.curlen = 0; zeromem(md->chc.buf, sizeof(md->chc.buf)); XFREE(key); return CRYPT_OK; } /* key <= state T0,T1 <= block T0 <= encrypt T0 state <= state xor T0 xor T1 */ static int chc_compress(hash_state *md, unsigned char *buf) { unsigned char T[2][MAXBLOCKSIZE]; symmetric_key *key; int err, x; if ((key = XMALLOC(sizeof(*key))) == NULL) { return CRYPT_MEM; } if ((err = cipher_descriptor[cipher_idx].setup(md->chc.state, cipher_blocksize, 0, key)) != CRYPT_OK) { XFREE(key); return err; } XMEMCPY(T[1], buf, cipher_blocksize); cipher_descriptor[cipher_idx].ecb_encrypt(buf, T[0], key); for (x = 0; x < cipher_blocksize; x++) { md->chc.state[x] ^= T[0][x] ^ T[1][x]; } XFREE(key); #ifdef LTC_CLEAN_STACK zeromem(T, sizeof(T)); zeromem(&key, sizeof(key)); #endif return CRYPT_OK; } /* function for processing blocks */ int _chc_process(hash_state * md, const unsigned char *buf, unsigned long len); HASH_PROCESS(_chc_process, chc_compress, chc, (unsigned long)cipher_blocksize) /** Process a block of memory though the hash @param md The hash state @param in The data to hash @param inlen The length of the data (octets) @return CRYPT_OK if successful */ int chc_process(hash_state * md, const unsigned char *in, unsigned long inlen) { int err; LTC_ARGCHK(md != NULL); LTC_ARGCHK(in != NULL); /* is the cipher valid? */ if ((err = cipher_is_valid(cipher_idx)) != CRYPT_OK) { return err; } if (cipher_blocksize != cipher_descriptor[cipher_idx].block_length) { return CRYPT_INVALID_CIPHER; } return _chc_process(md, in, inlen); } /** Terminate the hash to get the digest @param md The hash state @param out [out] The destination of the hash (length of the block size of the block cipher) @return CRYPT_OK if successful */ int chc_done(hash_state *md, unsigned char *out) { int err; LTC_ARGCHK(md != NULL); LTC_ARGCHK(out != NULL); /* is the cipher valid? */ if ((err = cipher_is_valid(cipher_idx)) != CRYPT_OK) { return err; } if (cipher_blocksize != cipher_descriptor[cipher_idx].block_length) { return CRYPT_INVALID_CIPHER; } if (md->chc.curlen >= sizeof(md->chc.buf)) { return CRYPT_INVALID_ARG; } /* increase the length of the message */ md->chc.length += md->chc.curlen * 8; /* append the '1' bit */ md->chc.buf[md->chc.curlen++] = (unsigned char)0x80; /* if the length is currently above l-8 bytes we append zeros * then compress. Then we can fall back to padding zeros and length * encoding like normal. */ if (md->chc.curlen > (unsigned long)(cipher_blocksize - 8)) { while (md->chc.curlen < (unsigned long)cipher_blocksize) { md->chc.buf[md->chc.curlen++] = (unsigned char)0; } chc_compress(md, md->chc.buf); md->chc.curlen = 0; } /* pad upto l-8 bytes of zeroes */ while (md->chc.curlen < (unsigned long)(cipher_blocksize - 8)) { md->chc.buf[md->chc.curlen++] = (unsigned char)0; } /* store length */ STORE64L(md->chc.length, md->chc.buf+(cipher_blocksize-8)); chc_compress(md, md->chc.buf); /* copy output */ XMEMCPY(out, md->chc.state, cipher_blocksize); #ifdef LTC_CLEAN_STACK zeromem(md, sizeof(hash_state)); #endif return CRYPT_OK; } /** Self-test the hash @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled */ int chc_test(void) { static const struct { unsigned char *msg, md[MAXBLOCKSIZE]; int len; } tests[] = { { (unsigned char *)"hello world", { 0xcf, 0x57, 0x9d, 0xc3, 0x0a, 0x0e, 0xea, 0x61, 0x0d, 0x54, 0x47, 0xc4, 0x3c, 0x06, 0xf5, 0x4e }, 16 } }; int x, oldhashidx, idx; unsigned char out[MAXBLOCKSIZE]; hash_state md; /* AES can be under rijndael or aes... try to find it */ if ((idx = find_cipher("aes")) == -1) { if ((idx = find_cipher("rijndael")) == -1) { return CRYPT_NOP; } } oldhashidx = cipher_idx; chc_register(idx); for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { chc_init(&md); chc_process(&md, tests[x].msg, strlen((char *)tests[x].msg)); chc_done(&md, out); if (XMEMCMP(out, tests[x].md, tests[x].len)) { return CRYPT_FAIL_TESTVECTOR; } } if (oldhashidx != UNDEFED_HASH) { chc_register(oldhashidx); } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/hashes/chc/chc.c,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/hashes/sha2/0000755000175100001440000000000010621351501015422 5ustar tomuserslibtomcrypt-1.17/src/hashes/sha2/sha224.c0000644000175100001440000000601310621351501016571 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @param sha224.c LTC_SHA-224 new NIST standard based off of LTC_SHA-256 truncated to 224 bits (Tom St Denis) */ const struct ltc_hash_descriptor sha224_desc = { "sha224", 10, 28, 64, /* OID */ { 2, 16, 840, 1, 101, 3, 4, 2, 4, }, 9, &sha224_init, &sha256_process, &sha224_done, &sha224_test, NULL }; /* init the sha256 er... sha224 state ;-) */ /** Initialize the hash state @param md The hash state you wish to initialize @return CRYPT_OK if successful */ int sha224_init(hash_state * md) { LTC_ARGCHK(md != NULL); md->sha256.curlen = 0; md->sha256.length = 0; md->sha256.state[0] = 0xc1059ed8UL; md->sha256.state[1] = 0x367cd507UL; md->sha256.state[2] = 0x3070dd17UL; md->sha256.state[3] = 0xf70e5939UL; md->sha256.state[4] = 0xffc00b31UL; md->sha256.state[5] = 0x68581511UL; md->sha256.state[6] = 0x64f98fa7UL; md->sha256.state[7] = 0xbefa4fa4UL; return CRYPT_OK; } /** Terminate the hash to get the digest @param md The hash state @param out [out] The destination of the hash (28 bytes) @return CRYPT_OK if successful */ int sha224_done(hash_state * md, unsigned char *out) { unsigned char buf[32]; int err; LTC_ARGCHK(md != NULL); LTC_ARGCHK(out != NULL); err = sha256_done(md, buf); XMEMCPY(out, buf, 28); #ifdef LTC_CLEAN_STACK zeromem(buf, sizeof(buf)); #endif return err; } /** Self-test the hash @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled */ int sha224_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { char *msg; unsigned char hash[28]; } tests[] = { { "abc", { 0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8, 0x22, 0x86, 0x42, 0xa4, 0x77, 0xbd, 0xa2, 0x55, 0xb3, 0x2a, 0xad, 0xbc, 0xe4, 0xbd, 0xa0, 0xb3, 0xf7, 0xe3, 0x6c, 0x9d, 0xa7 } }, { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", { 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76, 0xcc, 0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89, 0x01, 0x50, 0xb0, 0xc6, 0x45, 0x5c, 0xb4, 0xf5, 0x8b, 0x19, 0x52, 0x52, 0x25, 0x25 } }, }; int i; unsigned char tmp[28]; hash_state md; for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { sha224_init(&md); sha224_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); sha224_done(&md, tmp); if (XMEMCMP(tmp, tests[i].hash, 28) != 0) { return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } /* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha2/sha224.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2007/05/12 14:25:28 $ */ libtomcrypt-1.17/src/hashes/sha2/sha256.c0000644000175100001440000002671310621351501016607 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file sha256.c LTC_SHA256 by Tom St Denis */ #ifdef LTC_SHA256 const struct ltc_hash_descriptor sha256_desc = { "sha256", 0, 32, 64, /* OID */ { 2, 16, 840, 1, 101, 3, 4, 2, 1, }, 9, &sha256_init, &sha256_process, &sha256_done, &sha256_test, NULL }; #ifdef LTC_SMALL_CODE /* the K array */ static const ulong32 K[64] = { 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL }; #endif /* Various logical functions */ #define Ch(x,y,z) (z ^ (x & (y ^ z))) #define Maj(x,y,z) (((x | y) & z) | (x & y)) #define S(x, n) RORc((x),(n)) #define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) #define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22)) #define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25)) #define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3)) #define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10)) /* compress 512-bits */ #ifdef LTC_CLEAN_STACK static int _sha256_compress(hash_state * md, unsigned char *buf) #else static int sha256_compress(hash_state * md, unsigned char *buf) #endif { ulong32 S[8], W[64], t0, t1; #ifdef LTC_SMALL_CODE ulong32 t; #endif int i; /* copy state into S */ for (i = 0; i < 8; i++) { S[i] = md->sha256.state[i]; } /* copy the state into 512-bits into W[0..15] */ for (i = 0; i < 16; i++) { LOAD32H(W[i], buf + (4*i)); } /* fill W[16..63] */ for (i = 16; i < 64; i++) { W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; } /* Compress */ #ifdef LTC_SMALL_CODE #define RND(a,b,c,d,e,f,g,h,i) \ t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ t1 = Sigma0(a) + Maj(a, b, c); \ d += t0; \ h = t0 + t1; for (i = 0; i < 64; ++i) { RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i); t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t; } #else #define RND(a,b,c,d,e,f,g,h,i,ki) \ t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \ t1 = Sigma0(a) + Maj(a, b, c); \ d += t0; \ h = t0 + t1; RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98); RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491); RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf); RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5); RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b); RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1); RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4); RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5); RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98); RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01); RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be); RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3); RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74); RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe); RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7); RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174); RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1); RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786); RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6); RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc); RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f); RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa); RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc); RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da); RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152); RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d); RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8); RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7); RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3); RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147); RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351); RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967); RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85); RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138); RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc); RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13); RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354); RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb); RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e); RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85); RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1); RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b); RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70); RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3); RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819); RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624); RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585); RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070); RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116); RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08); RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c); RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5); RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3); RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a); RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f); RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3); RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee); RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f); RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814); RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208); RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa); RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb); RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7); RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2); #undef RND #endif /* feedback */ for (i = 0; i < 8; i++) { md->sha256.state[i] = md->sha256.state[i] + S[i]; } return CRYPT_OK; } #ifdef LTC_CLEAN_STACK static int sha256_compress(hash_state * md, unsigned char *buf) { int err; err = _sha256_compress(md, buf); burn_stack(sizeof(ulong32) * 74); return err; } #endif /** Initialize the hash state @param md The hash state you wish to initialize @return CRYPT_OK if successful */ int sha256_init(hash_state * md) { LTC_ARGCHK(md != NULL); md->sha256.curlen = 0; md->sha256.length = 0; md->sha256.state[0] = 0x6A09E667UL; md->sha256.state[1] = 0xBB67AE85UL; md->sha256.state[2] = 0x3C6EF372UL; md->sha256.state[3] = 0xA54FF53AUL; md->sha256.state[4] = 0x510E527FUL; md->sha256.state[5] = 0x9B05688CUL; md->sha256.state[6] = 0x1F83D9ABUL; md->sha256.state[7] = 0x5BE0CD19UL; return CRYPT_OK; } /** Process a block of memory though the hash @param md The hash state @param in The data to hash @param inlen The length of the data (octets) @return CRYPT_OK if successful */ HASH_PROCESS(sha256_process, sha256_compress, sha256, 64) /** Terminate the hash to get the digest @param md The hash state @param out [out] The destination of the hash (32 bytes) @return CRYPT_OK if successful */ int sha256_done(hash_state * md, unsigned char *out) { int i; LTC_ARGCHK(md != NULL); LTC_ARGCHK(out != NULL); if (md->sha256.curlen >= sizeof(md->sha256.buf)) { return CRYPT_INVALID_ARG; } /* increase the length of the message */ md->sha256.length += md->sha256.curlen * 8; /* append the '1' bit */ md->sha256.buf[md->sha256.curlen++] = (unsigned char)0x80; /* if the length is currently above 56 bytes we append zeros * then compress. Then we can fall back to padding zeros and length * encoding like normal. */ if (md->sha256.curlen > 56) { while (md->sha256.curlen < 64) { md->sha256.buf[md->sha256.curlen++] = (unsigned char)0; } sha256_compress(md, md->sha256.buf); md->sha256.curlen = 0; } /* pad upto 56 bytes of zeroes */ while (md->sha256.curlen < 56) { md->sha256.buf[md->sha256.curlen++] = (unsigned char)0; } /* store length */ STORE64H(md->sha256.length, md->sha256.buf+56); sha256_compress(md, md->sha256.buf); /* copy output */ for (i = 0; i < 8; i++) { STORE32H(md->sha256.state[i], out+(4*i)); } #ifdef LTC_CLEAN_STACK zeromem(md, sizeof(hash_state)); #endif return CRYPT_OK; } /** Self-test the hash @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled */ int sha256_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { char *msg; unsigned char hash[32]; } tests[] = { { "abc", { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad } }, { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 } }, }; int i; unsigned char tmp[32]; hash_state md; for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { sha256_init(&md); sha256_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); sha256_done(&md, tmp); if (XMEMCMP(tmp, tests[i].hash, 32) != 0) { return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } #ifdef LTC_SHA224 #include "sha224.c" #endif #endif /* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha2/sha256.c,v $ */ /* $Revision: 1.11 $ */ /* $Date: 2007/05/12 14:25:28 $ */ libtomcrypt-1.17/src/hashes/sha2/sha384.c0000644000175100001440000000670310621351501016606 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @param sha384.c LTC_SHA384 hash included in sha512.c, Tom St Denis */ const struct ltc_hash_descriptor sha384_desc = { "sha384", 4, 48, 128, /* OID */ { 2, 16, 840, 1, 101, 3, 4, 2, 2, }, 9, &sha384_init, &sha512_process, &sha384_done, &sha384_test, NULL }; /** Initialize the hash state @param md The hash state you wish to initialize @return CRYPT_OK if successful */ int sha384_init(hash_state * md) { LTC_ARGCHK(md != NULL); md->sha512.curlen = 0; md->sha512.length = 0; md->sha512.state[0] = CONST64(0xcbbb9d5dc1059ed8); md->sha512.state[1] = CONST64(0x629a292a367cd507); md->sha512.state[2] = CONST64(0x9159015a3070dd17); md->sha512.state[3] = CONST64(0x152fecd8f70e5939); md->sha512.state[4] = CONST64(0x67332667ffc00b31); md->sha512.state[5] = CONST64(0x8eb44a8768581511); md->sha512.state[6] = CONST64(0xdb0c2e0d64f98fa7); md->sha512.state[7] = CONST64(0x47b5481dbefa4fa4); return CRYPT_OK; } /** Terminate the hash to get the digest @param md The hash state @param out [out] The destination of the hash (48 bytes) @return CRYPT_OK if successful */ int sha384_done(hash_state * md, unsigned char *out) { unsigned char buf[64]; LTC_ARGCHK(md != NULL); LTC_ARGCHK(out != NULL); if (md->sha512.curlen >= sizeof(md->sha512.buf)) { return CRYPT_INVALID_ARG; } sha512_done(md, buf); XMEMCPY(out, buf, 48); #ifdef LTC_CLEAN_STACK zeromem(buf, sizeof(buf)); #endif return CRYPT_OK; } /** Self-test the hash @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled */ int sha384_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { char *msg; unsigned char hash[48]; } tests[] = { { "abc", { 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07, 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63, 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23, 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 } }, { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", { 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8, 0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47, 0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2, 0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12, 0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9, 0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39 } }, }; int i; unsigned char tmp[48]; hash_state md; for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { sha384_init(&md); sha384_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); sha384_done(&md, tmp); if (XMEMCMP(tmp, tests[i].hash, 48) != 0) { return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } /* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha2/sha384.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2007/05/12 14:25:28 $ */ libtomcrypt-1.17/src/hashes/sha2/sha512.c0000644000175100001440000002361610621351501016601 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @param sha512.c LTC_SHA512 by Tom St Denis */ #ifdef LTC_SHA512 const struct ltc_hash_descriptor sha512_desc = { "sha512", 5, 64, 128, /* OID */ { 2, 16, 840, 1, 101, 3, 4, 2, 3, }, 9, &sha512_init, &sha512_process, &sha512_done, &sha512_test, NULL }; /* the K array */ static const ulong64 K[80] = { CONST64(0x428a2f98d728ae22), CONST64(0x7137449123ef65cd), CONST64(0xb5c0fbcfec4d3b2f), CONST64(0xe9b5dba58189dbbc), CONST64(0x3956c25bf348b538), CONST64(0x59f111f1b605d019), CONST64(0x923f82a4af194f9b), CONST64(0xab1c5ed5da6d8118), CONST64(0xd807aa98a3030242), CONST64(0x12835b0145706fbe), CONST64(0x243185be4ee4b28c), CONST64(0x550c7dc3d5ffb4e2), CONST64(0x72be5d74f27b896f), CONST64(0x80deb1fe3b1696b1), CONST64(0x9bdc06a725c71235), CONST64(0xc19bf174cf692694), CONST64(0xe49b69c19ef14ad2), CONST64(0xefbe4786384f25e3), CONST64(0x0fc19dc68b8cd5b5), CONST64(0x240ca1cc77ac9c65), CONST64(0x2de92c6f592b0275), CONST64(0x4a7484aa6ea6e483), CONST64(0x5cb0a9dcbd41fbd4), CONST64(0x76f988da831153b5), CONST64(0x983e5152ee66dfab), CONST64(0xa831c66d2db43210), CONST64(0xb00327c898fb213f), CONST64(0xbf597fc7beef0ee4), CONST64(0xc6e00bf33da88fc2), CONST64(0xd5a79147930aa725), CONST64(0x06ca6351e003826f), CONST64(0x142929670a0e6e70), CONST64(0x27b70a8546d22ffc), CONST64(0x2e1b21385c26c926), CONST64(0x4d2c6dfc5ac42aed), CONST64(0x53380d139d95b3df), CONST64(0x650a73548baf63de), CONST64(0x766a0abb3c77b2a8), CONST64(0x81c2c92e47edaee6), CONST64(0x92722c851482353b), CONST64(0xa2bfe8a14cf10364), CONST64(0xa81a664bbc423001), CONST64(0xc24b8b70d0f89791), CONST64(0xc76c51a30654be30), CONST64(0xd192e819d6ef5218), CONST64(0xd69906245565a910), CONST64(0xf40e35855771202a), CONST64(0x106aa07032bbd1b8), CONST64(0x19a4c116b8d2d0c8), CONST64(0x1e376c085141ab53), CONST64(0x2748774cdf8eeb99), CONST64(0x34b0bcb5e19b48a8), CONST64(0x391c0cb3c5c95a63), CONST64(0x4ed8aa4ae3418acb), CONST64(0x5b9cca4f7763e373), CONST64(0x682e6ff3d6b2b8a3), CONST64(0x748f82ee5defb2fc), CONST64(0x78a5636f43172f60), CONST64(0x84c87814a1f0ab72), CONST64(0x8cc702081a6439ec), CONST64(0x90befffa23631e28), CONST64(0xa4506cebde82bde9), CONST64(0xbef9a3f7b2c67915), CONST64(0xc67178f2e372532b), CONST64(0xca273eceea26619c), CONST64(0xd186b8c721c0c207), CONST64(0xeada7dd6cde0eb1e), CONST64(0xf57d4f7fee6ed178), CONST64(0x06f067aa72176fba), CONST64(0x0a637dc5a2c898a6), CONST64(0x113f9804bef90dae), CONST64(0x1b710b35131c471b), CONST64(0x28db77f523047d84), CONST64(0x32caab7b40c72493), CONST64(0x3c9ebe0a15c9bebc), CONST64(0x431d67c49c100d4c), CONST64(0x4cc5d4becb3e42b6), CONST64(0x597f299cfc657e2a), CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817) }; /* Various logical functions */ #define Ch(x,y,z) (z ^ (x & (y ^ z))) #define Maj(x,y,z) (((x | y) & z) | (x & y)) #define S(x, n) ROR64c(x, n) #define R(x, n) (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)n)) #define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39)) #define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41)) #define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7)) #define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6)) /* compress 1024-bits */ #ifdef LTC_CLEAN_STACK static int _sha512_compress(hash_state * md, unsigned char *buf) #else static int sha512_compress(hash_state * md, unsigned char *buf) #endif { ulong64 S[8], W[80], t0, t1; int i; /* copy state into S */ for (i = 0; i < 8; i++) { S[i] = md->sha512.state[i]; } /* copy the state into 1024-bits into W[0..15] */ for (i = 0; i < 16; i++) { LOAD64H(W[i], buf + (8*i)); } /* fill W[16..79] */ for (i = 16; i < 80; i++) { W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16]; } /* Compress */ #ifdef LTC_SMALL_CODE for (i = 0; i < 80; i++) { t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i]; t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]); S[7] = S[6]; S[6] = S[5]; S[5] = S[4]; S[4] = S[3] + t0; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t0 + t1; } #else #define RND(a,b,c,d,e,f,g,h,i) \ t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ t1 = Sigma0(a) + Maj(a, b, c); \ d += t0; \ h = t0 + t1; for (i = 0; i < 80; i += 8) { RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0); RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1); RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2); RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3); RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4); RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5); RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6); RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7); } #endif /* feedback */ for (i = 0; i < 8; i++) { md->sha512.state[i] = md->sha512.state[i] + S[i]; } return CRYPT_OK; } /* compress 1024-bits */ #ifdef LTC_CLEAN_STACK static int sha512_compress(hash_state * md, unsigned char *buf) { int err; err = _sha512_compress(md, buf); burn_stack(sizeof(ulong64) * 90 + sizeof(int)); return err; } #endif /** Initialize the hash state @param md The hash state you wish to initialize @return CRYPT_OK if successful */ int sha512_init(hash_state * md) { LTC_ARGCHK(md != NULL); md->sha512.curlen = 0; md->sha512.length = 0; md->sha512.state[0] = CONST64(0x6a09e667f3bcc908); md->sha512.state[1] = CONST64(0xbb67ae8584caa73b); md->sha512.state[2] = CONST64(0x3c6ef372fe94f82b); md->sha512.state[3] = CONST64(0xa54ff53a5f1d36f1); md->sha512.state[4] = CONST64(0x510e527fade682d1); md->sha512.state[5] = CONST64(0x9b05688c2b3e6c1f); md->sha512.state[6] = CONST64(0x1f83d9abfb41bd6b); md->sha512.state[7] = CONST64(0x5be0cd19137e2179); return CRYPT_OK; } /** Process a block of memory though the hash @param md The hash state @param in The data to hash @param inlen The length of the data (octets) @return CRYPT_OK if successful */ HASH_PROCESS(sha512_process, sha512_compress, sha512, 128) /** Terminate the hash to get the digest @param md The hash state @param out [out] The destination of the hash (64 bytes) @return CRYPT_OK if successful */ int sha512_done(hash_state * md, unsigned char *out) { int i; LTC_ARGCHK(md != NULL); LTC_ARGCHK(out != NULL); if (md->sha512.curlen >= sizeof(md->sha512.buf)) { return CRYPT_INVALID_ARG; } /* increase the length of the message */ md->sha512.length += md->sha512.curlen * CONST64(8); /* append the '1' bit */ md->sha512.buf[md->sha512.curlen++] = (unsigned char)0x80; /* if the length is currently above 112 bytes we append zeros * then compress. Then we can fall back to padding zeros and length * encoding like normal. */ if (md->sha512.curlen > 112) { while (md->sha512.curlen < 128) { md->sha512.buf[md->sha512.curlen++] = (unsigned char)0; } sha512_compress(md, md->sha512.buf); md->sha512.curlen = 0; } /* pad upto 120 bytes of zeroes * note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash * > 2^64 bits of data... :-) */ while (md->sha512.curlen < 120) { md->sha512.buf[md->sha512.curlen++] = (unsigned char)0; } /* store length */ STORE64H(md->sha512.length, md->sha512.buf+120); sha512_compress(md, md->sha512.buf); /* copy output */ for (i = 0; i < 8; i++) { STORE64H(md->sha512.state[i], out+(8*i)); } #ifdef LTC_CLEAN_STACK zeromem(md, sizeof(hash_state)); #endif return CRYPT_OK; } /** Self-test the hash @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled */ int sha512_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { char *msg; unsigned char hash[64]; } tests[] = { { "abc", { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd, 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f } }, { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", { 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda, 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f, 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1, 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18, 0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4, 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a, 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54, 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 } }, }; int i; unsigned char tmp[64]; hash_state md; for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { sha512_init(&md); sha512_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg)); sha512_done(&md, tmp); if (XMEMCMP(tmp, tests[i].hash, 64) != 0) { return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } #ifdef LTC_SHA384 #include "sha384.c" #endif #endif /* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha2/sha512.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2007/05/12 14:25:28 $ */ libtomcrypt-1.17/src/hashes/rmd128.c0000644000175100001440000002714210621351501015754 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @param rmd128.c RMD128 Hash function */ /* Implementation of LTC_RIPEMD-128 based on the source by Antoon Bosselaers, ESAT-COSIC * * This source has been radically overhauled to be portable and work within * the LibTomCrypt API by Tom St Denis */ #ifdef LTC_RIPEMD128 const struct ltc_hash_descriptor rmd128_desc = { "rmd128", 8, 16, 64, /* OID */ { 1, 0, 10118, 3, 0, 50 }, 6, &rmd128_init, &rmd128_process, &rmd128_done, &rmd128_test, NULL }; /* the four basic functions F(), G() and H() */ #define F(x, y, z) ((x) ^ (y) ^ (z)) #define G(x, y, z) (((x) & (y)) | (~(x) & (z))) #define H(x, y, z) (((x) | ~(y)) ^ (z)) #define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) /* the eight basic operations FF() through III() */ #define FF(a, b, c, d, x, s) \ (a) += F((b), (c), (d)) + (x);\ (a) = ROLc((a), (s)); #define GG(a, b, c, d, x, s) \ (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ (a) = ROLc((a), (s)); #define HH(a, b, c, d, x, s) \ (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ (a) = ROLc((a), (s)); #define II(a, b, c, d, x, s) \ (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ (a) = ROLc((a), (s)); #define FFF(a, b, c, d, x, s) \ (a) += F((b), (c), (d)) + (x);\ (a) = ROLc((a), (s)); #define GGG(a, b, c, d, x, s) \ (a) += G((b), (c), (d)) + (x) + 0x6d703ef3UL;\ (a) = ROLc((a), (s)); #define HHH(a, b, c, d, x, s) \ (a) += H((b), (c), (d)) + (x) + 0x5c4dd124UL;\ (a) = ROLc((a), (s)); #define III(a, b, c, d, x, s) \ (a) += I((b), (c), (d)) + (x) + 0x50a28be6UL;\ (a) = ROLc((a), (s)); #ifdef LTC_CLEAN_STACK static int _rmd128_compress(hash_state *md, unsigned char *buf) #else static int rmd128_compress(hash_state *md, unsigned char *buf) #endif { ulong32 aa,bb,cc,dd,aaa,bbb,ccc,ddd,X[16]; int i; /* load words X */ for (i = 0; i < 16; i++){ LOAD32L(X[i], buf + (4 * i)); } /* load state */ aa = aaa = md->rmd128.state[0]; bb = bbb = md->rmd128.state[1]; cc = ccc = md->rmd128.state[2]; dd = ddd = md->rmd128.state[3]; /* round 1 */ FF(aa, bb, cc, dd, X[ 0], 11); FF(dd, aa, bb, cc, X[ 1], 14); FF(cc, dd, aa, bb, X[ 2], 15); FF(bb, cc, dd, aa, X[ 3], 12); FF(aa, bb, cc, dd, X[ 4], 5); FF(dd, aa, bb, cc, X[ 5], 8); FF(cc, dd, aa, bb, X[ 6], 7); FF(bb, cc, dd, aa, X[ 7], 9); FF(aa, bb, cc, dd, X[ 8], 11); FF(dd, aa, bb, cc, X[ 9], 13); FF(cc, dd, aa, bb, X[10], 14); FF(bb, cc, dd, aa, X[11], 15); FF(aa, bb, cc, dd, X[12], 6); FF(dd, aa, bb, cc, X[13], 7); FF(cc, dd, aa, bb, X[14], 9); FF(bb, cc, dd, aa, X[15], 8); /* round 2 */ GG(aa, bb, cc, dd, X[ 7], 7); GG(dd, aa, bb, cc, X[ 4], 6); GG(cc, dd, aa, bb, X[13], 8); GG(bb, cc, dd, aa, X[ 1], 13); GG(aa, bb, cc, dd, X[10], 11); GG(dd, aa, bb, cc, X[ 6], 9); GG(cc, dd, aa, bb, X[15], 7); GG(bb, cc, dd, aa, X[ 3], 15); GG(aa, bb, cc, dd, X[12], 7); GG(dd, aa, bb, cc, X[ 0], 12); GG(cc, dd, aa, bb, X[ 9], 15); GG(bb, cc, dd, aa, X[ 5], 9); GG(aa, bb, cc, dd, X[ 2], 11); GG(dd, aa, bb, cc, X[14], 7); GG(cc, dd, aa, bb, X[11], 13); GG(bb, cc, dd, aa, X[ 8], 12); /* round 3 */ HH(aa, bb, cc, dd, X[ 3], 11); HH(dd, aa, bb, cc, X[10], 13); HH(cc, dd, aa, bb, X[14], 6); HH(bb, cc, dd, aa, X[ 4], 7); HH(aa, bb, cc, dd, X[ 9], 14); HH(dd, aa, bb, cc, X[15], 9); HH(cc, dd, aa, bb, X[ 8], 13); HH(bb, cc, dd, aa, X[ 1], 15); HH(aa, bb, cc, dd, X[ 2], 14); HH(dd, aa, bb, cc, X[ 7], 8); HH(cc, dd, aa, bb, X[ 0], 13); HH(bb, cc, dd, aa, X[ 6], 6); HH(aa, bb, cc, dd, X[13], 5); HH(dd, aa, bb, cc, X[11], 12); HH(cc, dd, aa, bb, X[ 5], 7); HH(bb, cc, dd, aa, X[12], 5); /* round 4 */ II(aa, bb, cc, dd, X[ 1], 11); II(dd, aa, bb, cc, X[ 9], 12); II(cc, dd, aa, bb, X[11], 14); II(bb, cc, dd, aa, X[10], 15); II(aa, bb, cc, dd, X[ 0], 14); II(dd, aa, bb, cc, X[ 8], 15); II(cc, dd, aa, bb, X[12], 9); II(bb, cc, dd, aa, X[ 4], 8); II(aa, bb, cc, dd, X[13], 9); II(dd, aa, bb, cc, X[ 3], 14); II(cc, dd, aa, bb, X[ 7], 5); II(bb, cc, dd, aa, X[15], 6); II(aa, bb, cc, dd, X[14], 8); II(dd, aa, bb, cc, X[ 5], 6); II(cc, dd, aa, bb, X[ 6], 5); II(bb, cc, dd, aa, X[ 2], 12); /* parallel round 1 */ III(aaa, bbb, ccc, ddd, X[ 5], 8); III(ddd, aaa, bbb, ccc, X[14], 9); III(ccc, ddd, aaa, bbb, X[ 7], 9); III(bbb, ccc, ddd, aaa, X[ 0], 11); III(aaa, bbb, ccc, ddd, X[ 9], 13); III(ddd, aaa, bbb, ccc, X[ 2], 15); III(ccc, ddd, aaa, bbb, X[11], 15); III(bbb, ccc, ddd, aaa, X[ 4], 5); III(aaa, bbb, ccc, ddd, X[13], 7); III(ddd, aaa, bbb, ccc, X[ 6], 7); III(ccc, ddd, aaa, bbb, X[15], 8); III(bbb, ccc, ddd, aaa, X[ 8], 11); III(aaa, bbb, ccc, ddd, X[ 1], 14); III(ddd, aaa, bbb, ccc, X[10], 14); III(ccc, ddd, aaa, bbb, X[ 3], 12); III(bbb, ccc, ddd, aaa, X[12], 6); /* parallel round 2 */ HHH(aaa, bbb, ccc, ddd, X[ 6], 9); HHH(ddd, aaa, bbb, ccc, X[11], 13); HHH(ccc, ddd, aaa, bbb, X[ 3], 15); HHH(bbb, ccc, ddd, aaa, X[ 7], 7); HHH(aaa, bbb, ccc, ddd, X[ 0], 12); HHH(ddd, aaa, bbb, ccc, X[13], 8); HHH(ccc, ddd, aaa, bbb, X[ 5], 9); HHH(bbb, ccc, ddd, aaa, X[10], 11); HHH(aaa, bbb, ccc, ddd, X[14], 7); HHH(ddd, aaa, bbb, ccc, X[15], 7); HHH(ccc, ddd, aaa, bbb, X[ 8], 12); HHH(bbb, ccc, ddd, aaa, X[12], 7); HHH(aaa, bbb, ccc, ddd, X[ 4], 6); HHH(ddd, aaa, bbb, ccc, X[ 9], 15); HHH(ccc, ddd, aaa, bbb, X[ 1], 13); HHH(bbb, ccc, ddd, aaa, X[ 2], 11); /* parallel round 3 */ GGG(aaa, bbb, ccc, ddd, X[15], 9); GGG(ddd, aaa, bbb, ccc, X[ 5], 7); GGG(ccc, ddd, aaa, bbb, X[ 1], 15); GGG(bbb, ccc, ddd, aaa, X[ 3], 11); GGG(aaa, bbb, ccc, ddd, X[ 7], 8); GGG(ddd, aaa, bbb, ccc, X[14], 6); GGG(ccc, ddd, aaa, bbb, X[ 6], 6); GGG(bbb, ccc, ddd, aaa, X[ 9], 14); GGG(aaa, bbb, ccc, ddd, X[11], 12); GGG(ddd, aaa, bbb, ccc, X[ 8], 13); GGG(ccc, ddd, aaa, bbb, X[12], 5); GGG(bbb, ccc, ddd, aaa, X[ 2], 14); GGG(aaa, bbb, ccc, ddd, X[10], 13); GGG(ddd, aaa, bbb, ccc, X[ 0], 13); GGG(ccc, ddd, aaa, bbb, X[ 4], 7); GGG(bbb, ccc, ddd, aaa, X[13], 5); /* parallel round 4 */ FFF(aaa, bbb, ccc, ddd, X[ 8], 15); FFF(ddd, aaa, bbb, ccc, X[ 6], 5); FFF(ccc, ddd, aaa, bbb, X[ 4], 8); FFF(bbb, ccc, ddd, aaa, X[ 1], 11); FFF(aaa, bbb, ccc, ddd, X[ 3], 14); FFF(ddd, aaa, bbb, ccc, X[11], 14); FFF(ccc, ddd, aaa, bbb, X[15], 6); FFF(bbb, ccc, ddd, aaa, X[ 0], 14); FFF(aaa, bbb, ccc, ddd, X[ 5], 6); FFF(ddd, aaa, bbb, ccc, X[12], 9); FFF(ccc, ddd, aaa, bbb, X[ 2], 12); FFF(bbb, ccc, ddd, aaa, X[13], 9); FFF(aaa, bbb, ccc, ddd, X[ 9], 12); FFF(ddd, aaa, bbb, ccc, X[ 7], 5); FFF(ccc, ddd, aaa, bbb, X[10], 15); FFF(bbb, ccc, ddd, aaa, X[14], 8); /* combine results */ ddd += cc + md->rmd128.state[1]; /* final result for MDbuf[0] */ md->rmd128.state[1] = md->rmd128.state[2] + dd + aaa; md->rmd128.state[2] = md->rmd128.state[3] + aa + bbb; md->rmd128.state[3] = md->rmd128.state[0] + bb + ccc; md->rmd128.state[0] = ddd; return CRYPT_OK; } #ifdef LTC_CLEAN_STACK static int rmd128_compress(hash_state *md, unsigned char *buf) { int err; err = _rmd128_compress(md, buf); burn_stack(sizeof(ulong32) * 24 + sizeof(int)); return err; } #endif /** Initialize the hash state @param md The hash state you wish to initialize @return CRYPT_OK if successful */ int rmd128_init(hash_state * md) { LTC_ARGCHK(md != NULL); md->rmd128.state[0] = 0x67452301UL; md->rmd128.state[1] = 0xefcdab89UL; md->rmd128.state[2] = 0x98badcfeUL; md->rmd128.state[3] = 0x10325476UL; md->rmd128.curlen = 0; md->rmd128.length = 0; return CRYPT_OK; } /** Process a block of memory though the hash @param md The hash state @param in The data to hash @param inlen The length of the data (octets) @return CRYPT_OK if successful */ HASH_PROCESS(rmd128_process, rmd128_compress, rmd128, 64) /** Terminate the hash to get the digest @param md The hash state @param out [out] The destination of the hash (16 bytes) @return CRYPT_OK if successful */ int rmd128_done(hash_state * md, unsigned char *out) { int i; LTC_ARGCHK(md != NULL); LTC_ARGCHK(out != NULL); if (md->rmd128.curlen >= sizeof(md->rmd128.buf)) { return CRYPT_INVALID_ARG; } /* increase the length of the message */ md->rmd128.length += md->rmd128.curlen * 8; /* append the '1' bit */ md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0x80; /* if the length is currently above 56 bytes we append zeros * then compress. Then we can fall back to padding zeros and length * encoding like normal. */ if (md->rmd128.curlen > 56) { while (md->rmd128.curlen < 64) { md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0; } rmd128_compress(md, md->rmd128.buf); md->rmd128.curlen = 0; } /* pad upto 56 bytes of zeroes */ while (md->rmd128.curlen < 56) { md->rmd128.buf[md->rmd128.curlen++] = (unsigned char)0; } /* store length */ STORE64L(md->rmd128.length, md->rmd128.buf+56); rmd128_compress(md, md->rmd128.buf); /* copy output */ for (i = 0; i < 4; i++) { STORE32L(md->rmd128.state[i], out+(4*i)); } #ifdef LTC_CLEAN_STACK zeromem(md, sizeof(hash_state)); #endif return CRYPT_OK; } /** Self-test the hash @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled */ int rmd128_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { char *msg; unsigned char md[16]; } tests[] = { { "", { 0xcd, 0xf2, 0x62, 0x13, 0xa1, 0x50, 0xdc, 0x3e, 0xcb, 0x61, 0x0f, 0x18, 0xf6, 0xb3, 0x8b, 0x46 } }, { "a", { 0x86, 0xbe, 0x7a, 0xfa, 0x33, 0x9d, 0x0f, 0xc7, 0xcf, 0xc7, 0x85, 0xe7, 0x2f, 0x57, 0x8d, 0x33 } }, { "abc", { 0xc1, 0x4a, 0x12, 0x19, 0x9c, 0x66, 0xe4, 0xba, 0x84, 0x63, 0x6b, 0x0f, 0x69, 0x14, 0x4c, 0x77 } }, { "message digest", { 0x9e, 0x32, 0x7b, 0x3d, 0x6e, 0x52, 0x30, 0x62, 0xaf, 0xc1, 0x13, 0x2d, 0x7d, 0xf9, 0xd1, 0xb8 } }, { "abcdefghijklmnopqrstuvwxyz", { 0xfd, 0x2a, 0xa6, 0x07, 0xf7, 0x1d, 0xc8, 0xf5, 0x10, 0x71, 0x49, 0x22, 0xb3, 0x71, 0x83, 0x4e } }, { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", { 0xd1, 0xe9, 0x59, 0xeb, 0x17, 0x9c, 0x91, 0x1f, 0xae, 0xa4, 0x62, 0x4c, 0x60, 0xc5, 0xc7, 0x02 } } }; int x; unsigned char buf[16]; hash_state md; for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { rmd128_init(&md); rmd128_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg)); rmd128_done(&md, buf); if (XMEMCMP(buf, tests[x].md, 16) != 0) { #if 0 printf("Failed test %d\n", x); #endif return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/hashes/rmd128.c,v $ */ /* $Revision: 1.11 $ */ /* $Date: 2007/05/12 14:25:28 $ */ libtomcrypt-1.17/src/hashes/rmd160.c0000644000175100001440000003463210621351501015752 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file rmd160.c RMD160 hash function */ /* Implementation of LTC_RIPEMD-160 based on the source by Antoon Bosselaers, ESAT-COSIC * * This source has been radically overhauled to be portable and work within * the LibTomCrypt API by Tom St Denis */ #ifdef LTC_RIPEMD160 const struct ltc_hash_descriptor rmd160_desc = { "rmd160", 9, 20, 64, /* OID */ { 1, 3, 36, 3, 2, 1, }, 6, &rmd160_init, &rmd160_process, &rmd160_done, &rmd160_test, NULL }; /* the five basic functions F(), G() and H() */ #define F(x, y, z) ((x) ^ (y) ^ (z)) #define G(x, y, z) (((x) & (y)) | (~(x) & (z))) #define H(x, y, z) (((x) | ~(y)) ^ (z)) #define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) #define J(x, y, z) ((x) ^ ((y) | ~(z))) /* the ten basic operations FF() through III() */ #define FF(a, b, c, d, e, x, s) \ (a) += F((b), (c), (d)) + (x);\ (a) = ROLc((a), (s)) + (e);\ (c) = ROLc((c), 10); #define GG(a, b, c, d, e, x, s) \ (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ (a) = ROLc((a), (s)) + (e);\ (c) = ROLc((c), 10); #define HH(a, b, c, d, e, x, s) \ (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ (a) = ROLc((a), (s)) + (e);\ (c) = ROLc((c), 10); #define II(a, b, c, d, e, x, s) \ (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ (a) = ROLc((a), (s)) + (e);\ (c) = ROLc((c), 10); #define JJ(a, b, c, d, e, x, s) \ (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\ (a) = ROLc((a), (s)) + (e);\ (c) = ROLc((c), 10); #define FFF(a, b, c, d, e, x, s) \ (a) += F((b), (c), (d)) + (x);\ (a) = ROLc((a), (s)) + (e);\ (c) = ROLc((c), 10); #define GGG(a, b, c, d, e, x, s) \ (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\ (a) = ROLc((a), (s)) + (e);\ (c) = ROLc((c), 10); #define HHH(a, b, c, d, e, x, s) \ (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\ (a) = ROLc((a), (s)) + (e);\ (c) = ROLc((c), 10); #define III(a, b, c, d, e, x, s) \ (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\ (a) = ROLc((a), (s)) + (e);\ (c) = ROLc((c), 10); #define JJJ(a, b, c, d, e, x, s) \ (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\ (a) = ROLc((a), (s)) + (e);\ (c) = ROLc((c), 10); #ifdef LTC_CLEAN_STACK static int _rmd160_compress(hash_state *md, unsigned char *buf) #else static int rmd160_compress(hash_state *md, unsigned char *buf) #endif { ulong32 aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,X[16]; int i; /* load words X */ for (i = 0; i < 16; i++){ LOAD32L(X[i], buf + (4 * i)); } /* load state */ aa = aaa = md->rmd160.state[0]; bb = bbb = md->rmd160.state[1]; cc = ccc = md->rmd160.state[2]; dd = ddd = md->rmd160.state[3]; ee = eee = md->rmd160.state[4]; /* round 1 */ FF(aa, bb, cc, dd, ee, X[ 0], 11); FF(ee, aa, bb, cc, dd, X[ 1], 14); FF(dd, ee, aa, bb, cc, X[ 2], 15); FF(cc, dd, ee, aa, bb, X[ 3], 12); FF(bb, cc, dd, ee, aa, X[ 4], 5); FF(aa, bb, cc, dd, ee, X[ 5], 8); FF(ee, aa, bb, cc, dd, X[ 6], 7); FF(dd, ee, aa, bb, cc, X[ 7], 9); FF(cc, dd, ee, aa, bb, X[ 8], 11); FF(bb, cc, dd, ee, aa, X[ 9], 13); FF(aa, bb, cc, dd, ee, X[10], 14); FF(ee, aa, bb, cc, dd, X[11], 15); FF(dd, ee, aa, bb, cc, X[12], 6); FF(cc, dd, ee, aa, bb, X[13], 7); FF(bb, cc, dd, ee, aa, X[14], 9); FF(aa, bb, cc, dd, ee, X[15], 8); /* round 2 */ GG(ee, aa, bb, cc, dd, X[ 7], 7); GG(dd, ee, aa, bb, cc, X[ 4], 6); GG(cc, dd, ee, aa, bb, X[13], 8); GG(bb, cc, dd, ee, aa, X[ 1], 13); GG(aa, bb, cc, dd, ee, X[10], 11); GG(ee, aa, bb, cc, dd, X[ 6], 9); GG(dd, ee, aa, bb, cc, X[15], 7); GG(cc, dd, ee, aa, bb, X[ 3], 15); GG(bb, cc, dd, ee, aa, X[12], 7); GG(aa, bb, cc, dd, ee, X[ 0], 12); GG(ee, aa, bb, cc, dd, X[ 9], 15); GG(dd, ee, aa, bb, cc, X[ 5], 9); GG(cc, dd, ee, aa, bb, X[ 2], 11); GG(bb, cc, dd, ee, aa, X[14], 7); GG(aa, bb, cc, dd, ee, X[11], 13); GG(ee, aa, bb, cc, dd, X[ 8], 12); /* round 3 */ HH(dd, ee, aa, bb, cc, X[ 3], 11); HH(cc, dd, ee, aa, bb, X[10], 13); HH(bb, cc, dd, ee, aa, X[14], 6); HH(aa, bb, cc, dd, ee, X[ 4], 7); HH(ee, aa, bb, cc, dd, X[ 9], 14); HH(dd, ee, aa, bb, cc, X[15], 9); HH(cc, dd, ee, aa, bb, X[ 8], 13); HH(bb, cc, dd, ee, aa, X[ 1], 15); HH(aa, bb, cc, dd, ee, X[ 2], 14); HH(ee, aa, bb, cc, dd, X[ 7], 8); HH(dd, ee, aa, bb, cc, X[ 0], 13); HH(cc, dd, ee, aa, bb, X[ 6], 6); HH(bb, cc, dd, ee, aa, X[13], 5); HH(aa, bb, cc, dd, ee, X[11], 12); HH(ee, aa, bb, cc, dd, X[ 5], 7); HH(dd, ee, aa, bb, cc, X[12], 5); /* round 4 */ II(cc, dd, ee, aa, bb, X[ 1], 11); II(bb, cc, dd, ee, aa, X[ 9], 12); II(aa, bb, cc, dd, ee, X[11], 14); II(ee, aa, bb, cc, dd, X[10], 15); II(dd, ee, aa, bb, cc, X[ 0], 14); II(cc, dd, ee, aa, bb, X[ 8], 15); II(bb, cc, dd, ee, aa, X[12], 9); II(aa, bb, cc, dd, ee, X[ 4], 8); II(ee, aa, bb, cc, dd, X[13], 9); II(dd, ee, aa, bb, cc, X[ 3], 14); II(cc, dd, ee, aa, bb, X[ 7], 5); II(bb, cc, dd, ee, aa, X[15], 6); II(aa, bb, cc, dd, ee, X[14], 8); II(ee, aa, bb, cc, dd, X[ 5], 6); II(dd, ee, aa, bb, cc, X[ 6], 5); II(cc, dd, ee, aa, bb, X[ 2], 12); /* round 5 */ JJ(bb, cc, dd, ee, aa, X[ 4], 9); JJ(aa, bb, cc, dd, ee, X[ 0], 15); JJ(ee, aa, bb, cc, dd, X[ 5], 5); JJ(dd, ee, aa, bb, cc, X[ 9], 11); JJ(cc, dd, ee, aa, bb, X[ 7], 6); JJ(bb, cc, dd, ee, aa, X[12], 8); JJ(aa, bb, cc, dd, ee, X[ 2], 13); JJ(ee, aa, bb, cc, dd, X[10], 12); JJ(dd, ee, aa, bb, cc, X[14], 5); JJ(cc, dd, ee, aa, bb, X[ 1], 12); JJ(bb, cc, dd, ee, aa, X[ 3], 13); JJ(aa, bb, cc, dd, ee, X[ 8], 14); JJ(ee, aa, bb, cc, dd, X[11], 11); JJ(dd, ee, aa, bb, cc, X[ 6], 8); JJ(cc, dd, ee, aa, bb, X[15], 5); JJ(bb, cc, dd, ee, aa, X[13], 6); /* parallel round 1 */ JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8); JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9); JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9); JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11); JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13); JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15); JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15); JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5); JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7); JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7); JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8); JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11); JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14); JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14); JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12); JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6); /* parallel round 2 */ III(eee, aaa, bbb, ccc, ddd, X[ 6], 9); III(ddd, eee, aaa, bbb, ccc, X[11], 13); III(ccc, ddd, eee, aaa, bbb, X[ 3], 15); III(bbb, ccc, ddd, eee, aaa, X[ 7], 7); III(aaa, bbb, ccc, ddd, eee, X[ 0], 12); III(eee, aaa, bbb, ccc, ddd, X[13], 8); III(ddd, eee, aaa, bbb, ccc, X[ 5], 9); III(ccc, ddd, eee, aaa, bbb, X[10], 11); III(bbb, ccc, ddd, eee, aaa, X[14], 7); III(aaa, bbb, ccc, ddd, eee, X[15], 7); III(eee, aaa, bbb, ccc, ddd, X[ 8], 12); III(ddd, eee, aaa, bbb, ccc, X[12], 7); III(ccc, ddd, eee, aaa, bbb, X[ 4], 6); III(bbb, ccc, ddd, eee, aaa, X[ 9], 15); III(aaa, bbb, ccc, ddd, eee, X[ 1], 13); III(eee, aaa, bbb, ccc, ddd, X[ 2], 11); /* parallel round 3 */ HHH(ddd, eee, aaa, bbb, ccc, X[15], 9); HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7); HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15); HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11); HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8); HHH(ddd, eee, aaa, bbb, ccc, X[14], 6); HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6); HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14); HHH(aaa, bbb, ccc, ddd, eee, X[11], 12); HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13); HHH(ddd, eee, aaa, bbb, ccc, X[12], 5); HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14); HHH(bbb, ccc, ddd, eee, aaa, X[10], 13); HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13); HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7); HHH(ddd, eee, aaa, bbb, ccc, X[13], 5); /* parallel round 4 */ GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15); GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5); GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8); GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11); GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14); GGG(ccc, ddd, eee, aaa, bbb, X[11], 14); GGG(bbb, ccc, ddd, eee, aaa, X[15], 6); GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14); GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6); GGG(ddd, eee, aaa, bbb, ccc, X[12], 9); GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12); GGG(bbb, ccc, ddd, eee, aaa, X[13], 9); GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12); GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5); GGG(ddd, eee, aaa, bbb, ccc, X[10], 15); GGG(ccc, ddd, eee, aaa, bbb, X[14], 8); /* parallel round 5 */ FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8); FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5); FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12); FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9); FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12); FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5); FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14); FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6); FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8); FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13); FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6); FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5); FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15); FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13); FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11); FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11); /* combine results */ ddd += cc + md->rmd160.state[1]; /* final result for md->rmd160.state[0] */ md->rmd160.state[1] = md->rmd160.state[2] + dd + eee; md->rmd160.state[2] = md->rmd160.state[3] + ee + aaa; md->rmd160.state[3] = md->rmd160.state[4] + aa + bbb; md->rmd160.state[4] = md->rmd160.state[0] + bb + ccc; md->rmd160.state[0] = ddd; return CRYPT_OK; } #ifdef LTC_CLEAN_STACK static int rmd160_compress(hash_state *md, unsigned char *buf) { int err; err = _rmd160_compress(md, buf); burn_stack(sizeof(ulong32) * 26 + sizeof(int)); return err; } #endif /** Initialize the hash state @param md The hash state you wish to initialize @return CRYPT_OK if successful */ int rmd160_init(hash_state * md) { LTC_ARGCHK(md != NULL); md->rmd160.state[0] = 0x67452301UL; md->rmd160.state[1] = 0xefcdab89UL; md->rmd160.state[2] = 0x98badcfeUL; md->rmd160.state[3] = 0x10325476UL; md->rmd160.state[4] = 0xc3d2e1f0UL; md->rmd160.curlen = 0; md->rmd160.length = 0; return CRYPT_OK; } /** Process a block of memory though the hash @param md The hash state @param in The data to hash @param inlen The length of the data (octets) @return CRYPT_OK if successful */ HASH_PROCESS(rmd160_process, rmd160_compress, rmd160, 64) /** Terminate the hash to get the digest @param md The hash state @param out [out] The destination of the hash (20 bytes) @return CRYPT_OK if successful */ int rmd160_done(hash_state * md, unsigned char *out) { int i; LTC_ARGCHK(md != NULL); LTC_ARGCHK(out != NULL); if (md->rmd160.curlen >= sizeof(md->rmd160.buf)) { return CRYPT_INVALID_ARG; } /* increase the length of the message */ md->rmd160.length += md->rmd160.curlen * 8; /* append the '1' bit */ md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0x80; /* if the length is currently above 56 bytes we append zeros * then compress. Then we can fall back to padding zeros and length * encoding like normal. */ if (md->rmd160.curlen > 56) { while (md->rmd160.curlen < 64) { md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0; } rmd160_compress(md, md->rmd160.buf); md->rmd160.curlen = 0; } /* pad upto 56 bytes of zeroes */ while (md->rmd160.curlen < 56) { md->rmd160.buf[md->rmd160.curlen++] = (unsigned char)0; } /* store length */ STORE64L(md->rmd160.length, md->rmd160.buf+56); rmd160_compress(md, md->rmd160.buf); /* copy output */ for (i = 0; i < 5; i++) { STORE32L(md->rmd160.state[i], out+(4*i)); } #ifdef LTC_CLEAN_STACK zeromem(md, sizeof(hash_state)); #endif return CRYPT_OK; } /** Self-test the hash @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled */ int rmd160_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { char *msg; unsigned char md[20]; } tests[] = { { "", { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28, 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 } }, { "a", { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae, 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe } }, { "abc", { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04, 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc } }, { "message digest", { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8, 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 } }, { "abcdefghijklmnopqrstuvwxyz", { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb, 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc } }, { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05, 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b } } }; int x; unsigned char buf[20]; hash_state md; for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { rmd160_init(&md); rmd160_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg)); rmd160_done(&md, buf); if (XMEMCMP(buf, tests[x].md, 20) != 0) { #if 0 printf("Failed test %d\n", x); #endif return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/hashes/rmd160.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2007/05/12 14:25:28 $ */ libtomcrypt-1.17/src/hashes/rmd256.c0000644000175100001440000003033410621351501015753 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @param rmd256.c RLTC_MD256 Hash function */ #ifdef LTC_RIPEMD256 const struct ltc_hash_descriptor rmd256_desc = { "rmd256", 8, 32, 64, /* OID */ { 1, 3, 36, 3, 2, 3 }, 6, &rmd256_init, &rmd256_process, &rmd256_done, &rmd256_test, NULL }; /* the four basic functions F(), G() and H() */ #define F(x, y, z) ((x) ^ (y) ^ (z)) #define G(x, y, z) (((x) & (y)) | (~(x) & (z))) #define H(x, y, z) (((x) | ~(y)) ^ (z)) #define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) /* the eight basic operations FF() through III() */ #define FF(a, b, c, d, x, s) \ (a) += F((b), (c), (d)) + (x);\ (a) = ROLc((a), (s)); #define GG(a, b, c, d, x, s) \ (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ (a) = ROLc((a), (s)); #define HH(a, b, c, d, x, s) \ (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ (a) = ROLc((a), (s)); #define II(a, b, c, d, x, s) \ (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ (a) = ROLc((a), (s)); #define FFF(a, b, c, d, x, s) \ (a) += F((b), (c), (d)) + (x);\ (a) = ROLc((a), (s)); #define GGG(a, b, c, d, x, s) \ (a) += G((b), (c), (d)) + (x) + 0x6d703ef3UL;\ (a) = ROLc((a), (s)); #define HHH(a, b, c, d, x, s) \ (a) += H((b), (c), (d)) + (x) + 0x5c4dd124UL;\ (a) = ROLc((a), (s)); #define III(a, b, c, d, x, s) \ (a) += I((b), (c), (d)) + (x) + 0x50a28be6UL;\ (a) = ROLc((a), (s)); #ifdef LTC_CLEAN_STACK static int _rmd256_compress(hash_state *md, unsigned char *buf) #else static int rmd256_compress(hash_state *md, unsigned char *buf) #endif { ulong32 aa,bb,cc,dd,aaa,bbb,ccc,ddd,tmp,X[16]; int i; /* load words X */ for (i = 0; i < 16; i++){ LOAD32L(X[i], buf + (4 * i)); } /* load state */ aa = md->rmd256.state[0]; bb = md->rmd256.state[1]; cc = md->rmd256.state[2]; dd = md->rmd256.state[3]; aaa = md->rmd256.state[4]; bbb = md->rmd256.state[5]; ccc = md->rmd256.state[6]; ddd = md->rmd256.state[7]; /* round 1 */ FF(aa, bb, cc, dd, X[ 0], 11); FF(dd, aa, bb, cc, X[ 1], 14); FF(cc, dd, aa, bb, X[ 2], 15); FF(bb, cc, dd, aa, X[ 3], 12); FF(aa, bb, cc, dd, X[ 4], 5); FF(dd, aa, bb, cc, X[ 5], 8); FF(cc, dd, aa, bb, X[ 6], 7); FF(bb, cc, dd, aa, X[ 7], 9); FF(aa, bb, cc, dd, X[ 8], 11); FF(dd, aa, bb, cc, X[ 9], 13); FF(cc, dd, aa, bb, X[10], 14); FF(bb, cc, dd, aa, X[11], 15); FF(aa, bb, cc, dd, X[12], 6); FF(dd, aa, bb, cc, X[13], 7); FF(cc, dd, aa, bb, X[14], 9); FF(bb, cc, dd, aa, X[15], 8); /* parallel round 1 */ III(aaa, bbb, ccc, ddd, X[ 5], 8); III(ddd, aaa, bbb, ccc, X[14], 9); III(ccc, ddd, aaa, bbb, X[ 7], 9); III(bbb, ccc, ddd, aaa, X[ 0], 11); III(aaa, bbb, ccc, ddd, X[ 9], 13); III(ddd, aaa, bbb, ccc, X[ 2], 15); III(ccc, ddd, aaa, bbb, X[11], 15); III(bbb, ccc, ddd, aaa, X[ 4], 5); III(aaa, bbb, ccc, ddd, X[13], 7); III(ddd, aaa, bbb, ccc, X[ 6], 7); III(ccc, ddd, aaa, bbb, X[15], 8); III(bbb, ccc, ddd, aaa, X[ 8], 11); III(aaa, bbb, ccc, ddd, X[ 1], 14); III(ddd, aaa, bbb, ccc, X[10], 14); III(ccc, ddd, aaa, bbb, X[ 3], 12); III(bbb, ccc, ddd, aaa, X[12], 6); tmp = aa; aa = aaa; aaa = tmp; /* round 2 */ GG(aa, bb, cc, dd, X[ 7], 7); GG(dd, aa, bb, cc, X[ 4], 6); GG(cc, dd, aa, bb, X[13], 8); GG(bb, cc, dd, aa, X[ 1], 13); GG(aa, bb, cc, dd, X[10], 11); GG(dd, aa, bb, cc, X[ 6], 9); GG(cc, dd, aa, bb, X[15], 7); GG(bb, cc, dd, aa, X[ 3], 15); GG(aa, bb, cc, dd, X[12], 7); GG(dd, aa, bb, cc, X[ 0], 12); GG(cc, dd, aa, bb, X[ 9], 15); GG(bb, cc, dd, aa, X[ 5], 9); GG(aa, bb, cc, dd, X[ 2], 11); GG(dd, aa, bb, cc, X[14], 7); GG(cc, dd, aa, bb, X[11], 13); GG(bb, cc, dd, aa, X[ 8], 12); /* parallel round 2 */ HHH(aaa, bbb, ccc, ddd, X[ 6], 9); HHH(ddd, aaa, bbb, ccc, X[11], 13); HHH(ccc, ddd, aaa, bbb, X[ 3], 15); HHH(bbb, ccc, ddd, aaa, X[ 7], 7); HHH(aaa, bbb, ccc, ddd, X[ 0], 12); HHH(ddd, aaa, bbb, ccc, X[13], 8); HHH(ccc, ddd, aaa, bbb, X[ 5], 9); HHH(bbb, ccc, ddd, aaa, X[10], 11); HHH(aaa, bbb, ccc, ddd, X[14], 7); HHH(ddd, aaa, bbb, ccc, X[15], 7); HHH(ccc, ddd, aaa, bbb, X[ 8], 12); HHH(bbb, ccc, ddd, aaa, X[12], 7); HHH(aaa, bbb, ccc, ddd, X[ 4], 6); HHH(ddd, aaa, bbb, ccc, X[ 9], 15); HHH(ccc, ddd, aaa, bbb, X[ 1], 13); HHH(bbb, ccc, ddd, aaa, X[ 2], 11); tmp = bb; bb = bbb; bbb = tmp; /* round 3 */ HH(aa, bb, cc, dd, X[ 3], 11); HH(dd, aa, bb, cc, X[10], 13); HH(cc, dd, aa, bb, X[14], 6); HH(bb, cc, dd, aa, X[ 4], 7); HH(aa, bb, cc, dd, X[ 9], 14); HH(dd, aa, bb, cc, X[15], 9); HH(cc, dd, aa, bb, X[ 8], 13); HH(bb, cc, dd, aa, X[ 1], 15); HH(aa, bb, cc, dd, X[ 2], 14); HH(dd, aa, bb, cc, X[ 7], 8); HH(cc, dd, aa, bb, X[ 0], 13); HH(bb, cc, dd, aa, X[ 6], 6); HH(aa, bb, cc, dd, X[13], 5); HH(dd, aa, bb, cc, X[11], 12); HH(cc, dd, aa, bb, X[ 5], 7); HH(bb, cc, dd, aa, X[12], 5); /* parallel round 3 */ GGG(aaa, bbb, ccc, ddd, X[15], 9); GGG(ddd, aaa, bbb, ccc, X[ 5], 7); GGG(ccc, ddd, aaa, bbb, X[ 1], 15); GGG(bbb, ccc, ddd, aaa, X[ 3], 11); GGG(aaa, bbb, ccc, ddd, X[ 7], 8); GGG(ddd, aaa, bbb, ccc, X[14], 6); GGG(ccc, ddd, aaa, bbb, X[ 6], 6); GGG(bbb, ccc, ddd, aaa, X[ 9], 14); GGG(aaa, bbb, ccc, ddd, X[11], 12); GGG(ddd, aaa, bbb, ccc, X[ 8], 13); GGG(ccc, ddd, aaa, bbb, X[12], 5); GGG(bbb, ccc, ddd, aaa, X[ 2], 14); GGG(aaa, bbb, ccc, ddd, X[10], 13); GGG(ddd, aaa, bbb, ccc, X[ 0], 13); GGG(ccc, ddd, aaa, bbb, X[ 4], 7); GGG(bbb, ccc, ddd, aaa, X[13], 5); tmp = cc; cc = ccc; ccc = tmp; /* round 4 */ II(aa, bb, cc, dd, X[ 1], 11); II(dd, aa, bb, cc, X[ 9], 12); II(cc, dd, aa, bb, X[11], 14); II(bb, cc, dd, aa, X[10], 15); II(aa, bb, cc, dd, X[ 0], 14); II(dd, aa, bb, cc, X[ 8], 15); II(cc, dd, aa, bb, X[12], 9); II(bb, cc, dd, aa, X[ 4], 8); II(aa, bb, cc, dd, X[13], 9); II(dd, aa, bb, cc, X[ 3], 14); II(cc, dd, aa, bb, X[ 7], 5); II(bb, cc, dd, aa, X[15], 6); II(aa, bb, cc, dd, X[14], 8); II(dd, aa, bb, cc, X[ 5], 6); II(cc, dd, aa, bb, X[ 6], 5); II(bb, cc, dd, aa, X[ 2], 12); /* parallel round 4 */ FFF(aaa, bbb, ccc, ddd, X[ 8], 15); FFF(ddd, aaa, bbb, ccc, X[ 6], 5); FFF(ccc, ddd, aaa, bbb, X[ 4], 8); FFF(bbb, ccc, ddd, aaa, X[ 1], 11); FFF(aaa, bbb, ccc, ddd, X[ 3], 14); FFF(ddd, aaa, bbb, ccc, X[11], 14); FFF(ccc, ddd, aaa, bbb, X[15], 6); FFF(bbb, ccc, ddd, aaa, X[ 0], 14); FFF(aaa, bbb, ccc, ddd, X[ 5], 6); FFF(ddd, aaa, bbb, ccc, X[12], 9); FFF(ccc, ddd, aaa, bbb, X[ 2], 12); FFF(bbb, ccc, ddd, aaa, X[13], 9); FFF(aaa, bbb, ccc, ddd, X[ 9], 12); FFF(ddd, aaa, bbb, ccc, X[ 7], 5); FFF(ccc, ddd, aaa, bbb, X[10], 15); FFF(bbb, ccc, ddd, aaa, X[14], 8); tmp = dd; dd = ddd; ddd = tmp; /* combine results */ md->rmd256.state[0] += aa; md->rmd256.state[1] += bb; md->rmd256.state[2] += cc; md->rmd256.state[3] += dd; md->rmd256.state[4] += aaa; md->rmd256.state[5] += bbb; md->rmd256.state[6] += ccc; md->rmd256.state[7] += ddd; return CRYPT_OK; } #ifdef LTC_CLEAN_STACK static int rmd256_compress(hash_state *md, unsigned char *buf) { int err; err = _rmd256_compress(md, buf); burn_stack(sizeof(ulong32) * 25 + sizeof(int)); return err; } #endif /** Initialize the hash state @param md The hash state you wish to initialize @return CRYPT_OK if successful */ int rmd256_init(hash_state * md) { LTC_ARGCHK(md != NULL); md->rmd256.state[0] = 0x67452301UL; md->rmd256.state[1] = 0xefcdab89UL; md->rmd256.state[2] = 0x98badcfeUL; md->rmd256.state[3] = 0x10325476UL; md->rmd256.state[4] = 0x76543210UL; md->rmd256.state[5] = 0xfedcba98UL; md->rmd256.state[6] = 0x89abcdefUL; md->rmd256.state[7] = 0x01234567UL; md->rmd256.curlen = 0; md->rmd256.length = 0; return CRYPT_OK; } /** Process a block of memory though the hash @param md The hash state @param in The data to hash @param inlen The length of the data (octets) @return CRYPT_OK if successful */ HASH_PROCESS(rmd256_process, rmd256_compress, rmd256, 64) /** Terminate the hash to get the digest @param md The hash state @param out [out] The destination of the hash (16 bytes) @return CRYPT_OK if successful */ int rmd256_done(hash_state * md, unsigned char *out) { int i; LTC_ARGCHK(md != NULL); LTC_ARGCHK(out != NULL); if (md->rmd256.curlen >= sizeof(md->rmd256.buf)) { return CRYPT_INVALID_ARG; } /* increase the length of the message */ md->rmd256.length += md->rmd256.curlen * 8; /* append the '1' bit */ md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0x80; /* if the length is currently above 56 bytes we append zeros * then compress. Then we can fall back to padding zeros and length * encoding like normal. */ if (md->rmd256.curlen > 56) { while (md->rmd256.curlen < 64) { md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0; } rmd256_compress(md, md->rmd256.buf); md->rmd256.curlen = 0; } /* pad upto 56 bytes of zeroes */ while (md->rmd256.curlen < 56) { md->rmd256.buf[md->rmd256.curlen++] = (unsigned char)0; } /* store length */ STORE64L(md->rmd256.length, md->rmd256.buf+56); rmd256_compress(md, md->rmd256.buf); /* copy output */ for (i = 0; i < 8; i++) { STORE32L(md->rmd256.state[i], out+(4*i)); } #ifdef LTC_CLEAN_STACK zeromem(md, sizeof(hash_state)); #endif return CRYPT_OK; } /** Self-test the hash @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled */ int rmd256_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { char *msg; unsigned char md[32]; } tests[] = { { "", { 0x02, 0xba, 0x4c, 0x4e, 0x5f, 0x8e, 0xcd, 0x18, 0x77, 0xfc, 0x52, 0xd6, 0x4d, 0x30, 0xe3, 0x7a, 0x2d, 0x97, 0x74, 0xfb, 0x1e, 0x5d, 0x02, 0x63, 0x80, 0xae, 0x01, 0x68, 0xe3, 0xc5, 0x52, 0x2d } }, { "a", { 0xf9, 0x33, 0x3e, 0x45, 0xd8, 0x57, 0xf5, 0xd9, 0x0a, 0x91, 0xba, 0xb7, 0x0a, 0x1e, 0xba, 0x0c, 0xfb, 0x1b, 0xe4, 0xb0, 0x78, 0x3c, 0x9a, 0xcf, 0xcd, 0x88, 0x3a, 0x91, 0x34, 0x69, 0x29, 0x25 } }, { "abc", { 0xaf, 0xbd, 0x6e, 0x22, 0x8b, 0x9d, 0x8c, 0xbb, 0xce, 0xf5, 0xca, 0x2d, 0x03, 0xe6, 0xdb, 0xa1, 0x0a, 0xc0, 0xbc, 0x7d, 0xcb, 0xe4, 0x68, 0x0e, 0x1e, 0x42, 0xd2, 0xe9, 0x75, 0x45, 0x9b, 0x65 } }, { "message digest", { 0x87, 0xe9, 0x71, 0x75, 0x9a, 0x1c, 0xe4, 0x7a, 0x51, 0x4d, 0x5c, 0x91, 0x4c, 0x39, 0x2c, 0x90, 0x18, 0xc7, 0xc4, 0x6b, 0xc1, 0x44, 0x65, 0x55, 0x4a, 0xfc, 0xdf, 0x54, 0xa5, 0x07, 0x0c, 0x0e } }, { "abcdefghijklmnopqrstuvwxyz", { 0x64, 0x9d, 0x30, 0x34, 0x75, 0x1e, 0xa2, 0x16, 0x77, 0x6b, 0xf9, 0xa1, 0x8a, 0xcc, 0x81, 0xbc, 0x78, 0x96, 0x11, 0x8a, 0x51, 0x97, 0x96, 0x87, 0x82, 0xdd, 0x1f, 0xd9, 0x7d, 0x8d, 0x51, 0x33 } }, { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", { 0x57, 0x40, 0xa4, 0x08, 0xac, 0x16, 0xb7, 0x20, 0xb8, 0x44, 0x24, 0xae, 0x93, 0x1c, 0xbb, 0x1f, 0xe3, 0x63, 0xd1, 0xd0, 0xbf, 0x40, 0x17, 0xf1, 0xa8, 0x9f, 0x7e, 0xa6, 0xde, 0x77, 0xa0, 0xb8 } } }; int x; unsigned char buf[32]; hash_state md; for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { rmd256_init(&md); rmd256_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg)); rmd256_done(&md, buf); if (XMEMCMP(buf, tests[x].md, 32) != 0) { #if 0 printf("Failed test %d\n", x); #endif return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } #endif libtomcrypt-1.17/src/hashes/rmd320.c0000644000175100001440000003636310621351501015753 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file rmd320.c RMD320 hash function */ #ifdef LTC_RIPEMD320 const struct ltc_hash_descriptor rmd320_desc = { "rmd320", 9, 40, 64, /* OID */ { 0 }, 0, &rmd320_init, &rmd320_process, &rmd320_done, &rmd320_test, NULL }; /* the five basic functions F(), G() and H() */ #define F(x, y, z) ((x) ^ (y) ^ (z)) #define G(x, y, z) (((x) & (y)) | (~(x) & (z))) #define H(x, y, z) (((x) | ~(y)) ^ (z)) #define I(x, y, z) (((x) & (z)) | ((y) & ~(z))) #define J(x, y, z) ((x) ^ ((y) | ~(z))) /* the ten basic operations FF() through III() */ #define FF(a, b, c, d, e, x, s) \ (a) += F((b), (c), (d)) + (x);\ (a) = ROLc((a), (s)) + (e);\ (c) = ROLc((c), 10); #define GG(a, b, c, d, e, x, s) \ (a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\ (a) = ROLc((a), (s)) + (e);\ (c) = ROLc((c), 10); #define HH(a, b, c, d, e, x, s) \ (a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\ (a) = ROLc((a), (s)) + (e);\ (c) = ROLc((c), 10); #define II(a, b, c, d, e, x, s) \ (a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\ (a) = ROLc((a), (s)) + (e);\ (c) = ROLc((c), 10); #define JJ(a, b, c, d, e, x, s) \ (a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\ (a) = ROLc((a), (s)) + (e);\ (c) = ROLc((c), 10); #define FFF(a, b, c, d, e, x, s) \ (a) += F((b), (c), (d)) + (x);\ (a) = ROLc((a), (s)) + (e);\ (c) = ROLc((c), 10); #define GGG(a, b, c, d, e, x, s) \ (a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\ (a) = ROLc((a), (s)) + (e);\ (c) = ROLc((c), 10); #define HHH(a, b, c, d, e, x, s) \ (a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\ (a) = ROLc((a), (s)) + (e);\ (c) = ROLc((c), 10); #define III(a, b, c, d, e, x, s) \ (a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\ (a) = ROLc((a), (s)) + (e);\ (c) = ROLc((c), 10); #define JJJ(a, b, c, d, e, x, s) \ (a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\ (a) = ROLc((a), (s)) + (e);\ (c) = ROLc((c), 10); #ifdef LTC_CLEAN_STACK static int _rmd320_compress(hash_state *md, unsigned char *buf) #else static int rmd320_compress(hash_state *md, unsigned char *buf) #endif { ulong32 aa,bb,cc,dd,ee,aaa,bbb,ccc,ddd,eee,tmp,X[16]; int i; /* load words X */ for (i = 0; i < 16; i++){ LOAD32L(X[i], buf + (4 * i)); } /* load state */ aa = md->rmd320.state[0]; bb = md->rmd320.state[1]; cc = md->rmd320.state[2]; dd = md->rmd320.state[3]; ee = md->rmd320.state[4]; aaa = md->rmd320.state[5]; bbb = md->rmd320.state[6]; ccc = md->rmd320.state[7]; ddd = md->rmd320.state[8]; eee = md->rmd320.state[9]; /* round 1 */ FF(aa, bb, cc, dd, ee, X[ 0], 11); FF(ee, aa, bb, cc, dd, X[ 1], 14); FF(dd, ee, aa, bb, cc, X[ 2], 15); FF(cc, dd, ee, aa, bb, X[ 3], 12); FF(bb, cc, dd, ee, aa, X[ 4], 5); FF(aa, bb, cc, dd, ee, X[ 5], 8); FF(ee, aa, bb, cc, dd, X[ 6], 7); FF(dd, ee, aa, bb, cc, X[ 7], 9); FF(cc, dd, ee, aa, bb, X[ 8], 11); FF(bb, cc, dd, ee, aa, X[ 9], 13); FF(aa, bb, cc, dd, ee, X[10], 14); FF(ee, aa, bb, cc, dd, X[11], 15); FF(dd, ee, aa, bb, cc, X[12], 6); FF(cc, dd, ee, aa, bb, X[13], 7); FF(bb, cc, dd, ee, aa, X[14], 9); FF(aa, bb, cc, dd, ee, X[15], 8); /* parallel round 1 */ JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8); JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9); JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9); JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11); JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13); JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15); JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15); JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5); JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7); JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7); JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8); JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11); JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14); JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14); JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12); JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6); tmp = aa; aa = aaa; aaa = tmp; /* round 2 */ GG(ee, aa, bb, cc, dd, X[ 7], 7); GG(dd, ee, aa, bb, cc, X[ 4], 6); GG(cc, dd, ee, aa, bb, X[13], 8); GG(bb, cc, dd, ee, aa, X[ 1], 13); GG(aa, bb, cc, dd, ee, X[10], 11); GG(ee, aa, bb, cc, dd, X[ 6], 9); GG(dd, ee, aa, bb, cc, X[15], 7); GG(cc, dd, ee, aa, bb, X[ 3], 15); GG(bb, cc, dd, ee, aa, X[12], 7); GG(aa, bb, cc, dd, ee, X[ 0], 12); GG(ee, aa, bb, cc, dd, X[ 9], 15); GG(dd, ee, aa, bb, cc, X[ 5], 9); GG(cc, dd, ee, aa, bb, X[ 2], 11); GG(bb, cc, dd, ee, aa, X[14], 7); GG(aa, bb, cc, dd, ee, X[11], 13); GG(ee, aa, bb, cc, dd, X[ 8], 12); /* parallel round 2 */ III(eee, aaa, bbb, ccc, ddd, X[ 6], 9); III(ddd, eee, aaa, bbb, ccc, X[11], 13); III(ccc, ddd, eee, aaa, bbb, X[ 3], 15); III(bbb, ccc, ddd, eee, aaa, X[ 7], 7); III(aaa, bbb, ccc, ddd, eee, X[ 0], 12); III(eee, aaa, bbb, ccc, ddd, X[13], 8); III(ddd, eee, aaa, bbb, ccc, X[ 5], 9); III(ccc, ddd, eee, aaa, bbb, X[10], 11); III(bbb, ccc, ddd, eee, aaa, X[14], 7); III(aaa, bbb, ccc, ddd, eee, X[15], 7); III(eee, aaa, bbb, ccc, ddd, X[ 8], 12); III(ddd, eee, aaa, bbb, ccc, X[12], 7); III(ccc, ddd, eee, aaa, bbb, X[ 4], 6); III(bbb, ccc, ddd, eee, aaa, X[ 9], 15); III(aaa, bbb, ccc, ddd, eee, X[ 1], 13); III(eee, aaa, bbb, ccc, ddd, X[ 2], 11); tmp = bb; bb = bbb; bbb = tmp; /* round 3 */ HH(dd, ee, aa, bb, cc, X[ 3], 11); HH(cc, dd, ee, aa, bb, X[10], 13); HH(bb, cc, dd, ee, aa, X[14], 6); HH(aa, bb, cc, dd, ee, X[ 4], 7); HH(ee, aa, bb, cc, dd, X[ 9], 14); HH(dd, ee, aa, bb, cc, X[15], 9); HH(cc, dd, ee, aa, bb, X[ 8], 13); HH(bb, cc, dd, ee, aa, X[ 1], 15); HH(aa, bb, cc, dd, ee, X[ 2], 14); HH(ee, aa, bb, cc, dd, X[ 7], 8); HH(dd, ee, aa, bb, cc, X[ 0], 13); HH(cc, dd, ee, aa, bb, X[ 6], 6); HH(bb, cc, dd, ee, aa, X[13], 5); HH(aa, bb, cc, dd, ee, X[11], 12); HH(ee, aa, bb, cc, dd, X[ 5], 7); HH(dd, ee, aa, bb, cc, X[12], 5); /* parallel round 3 */ HHH(ddd, eee, aaa, bbb, ccc, X[15], 9); HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7); HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15); HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11); HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8); HHH(ddd, eee, aaa, bbb, ccc, X[14], 6); HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6); HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14); HHH(aaa, bbb, ccc, ddd, eee, X[11], 12); HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13); HHH(ddd, eee, aaa, bbb, ccc, X[12], 5); HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14); HHH(bbb, ccc, ddd, eee, aaa, X[10], 13); HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13); HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7); HHH(ddd, eee, aaa, bbb, ccc, X[13], 5); tmp = cc; cc = ccc; ccc = tmp; /* round 4 */ II(cc, dd, ee, aa, bb, X[ 1], 11); II(bb, cc, dd, ee, aa, X[ 9], 12); II(aa, bb, cc, dd, ee, X[11], 14); II(ee, aa, bb, cc, dd, X[10], 15); II(dd, ee, aa, bb, cc, X[ 0], 14); II(cc, dd, ee, aa, bb, X[ 8], 15); II(bb, cc, dd, ee, aa, X[12], 9); II(aa, bb, cc, dd, ee, X[ 4], 8); II(ee, aa, bb, cc, dd, X[13], 9); II(dd, ee, aa, bb, cc, X[ 3], 14); II(cc, dd, ee, aa, bb, X[ 7], 5); II(bb, cc, dd, ee, aa, X[15], 6); II(aa, bb, cc, dd, ee, X[14], 8); II(ee, aa, bb, cc, dd, X[ 5], 6); II(dd, ee, aa, bb, cc, X[ 6], 5); II(cc, dd, ee, aa, bb, X[ 2], 12); /* parallel round 4 */ GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15); GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5); GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8); GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11); GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14); GGG(ccc, ddd, eee, aaa, bbb, X[11], 14); GGG(bbb, ccc, ddd, eee, aaa, X[15], 6); GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14); GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6); GGG(ddd, eee, aaa, bbb, ccc, X[12], 9); GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12); GGG(bbb, ccc, ddd, eee, aaa, X[13], 9); GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12); GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5); GGG(ddd, eee, aaa, bbb, ccc, X[10], 15); GGG(ccc, ddd, eee, aaa, bbb, X[14], 8); tmp = dd; dd = ddd; ddd = tmp; /* round 5 */ JJ(bb, cc, dd, ee, aa, X[ 4], 9); JJ(aa, bb, cc, dd, ee, X[ 0], 15); JJ(ee, aa, bb, cc, dd, X[ 5], 5); JJ(dd, ee, aa, bb, cc, X[ 9], 11); JJ(cc, dd, ee, aa, bb, X[ 7], 6); JJ(bb, cc, dd, ee, aa, X[12], 8); JJ(aa, bb, cc, dd, ee, X[ 2], 13); JJ(ee, aa, bb, cc, dd, X[10], 12); JJ(dd, ee, aa, bb, cc, X[14], 5); JJ(cc, dd, ee, aa, bb, X[ 1], 12); JJ(bb, cc, dd, ee, aa, X[ 3], 13); JJ(aa, bb, cc, dd, ee, X[ 8], 14); JJ(ee, aa, bb, cc, dd, X[11], 11); JJ(dd, ee, aa, bb, cc, X[ 6], 8); JJ(cc, dd, ee, aa, bb, X[15], 5); JJ(bb, cc, dd, ee, aa, X[13], 6); /* parallel round 5 */ FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8); FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5); FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12); FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9); FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12); FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5); FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14); FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6); FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8); FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13); FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6); FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5); FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15); FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13); FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11); FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11); tmp = ee; ee = eee; eee = tmp; /* combine results */ md->rmd320.state[0] += aa; md->rmd320.state[1] += bb; md->rmd320.state[2] += cc; md->rmd320.state[3] += dd; md->rmd320.state[4] += ee; md->rmd320.state[5] += aaa; md->rmd320.state[6] += bbb; md->rmd320.state[7] += ccc; md->rmd320.state[8] += ddd; md->rmd320.state[9] += eee; return CRYPT_OK; } #ifdef LTC_CLEAN_STACK static int rmd320_compress(hash_state *md, unsigned char *buf) { int err; err = _rmd320_compress(md, buf); burn_stack(sizeof(ulong32) * 27 + sizeof(int)); return err; } #endif /** Initialize the hash state @param md The hash state you wish to initialize @return CRYPT_OK if successful */ int rmd320_init(hash_state * md) { LTC_ARGCHK(md != NULL); md->rmd320.state[0] = 0x67452301UL; md->rmd320.state[1] = 0xefcdab89UL; md->rmd320.state[2] = 0x98badcfeUL; md->rmd320.state[3] = 0x10325476UL; md->rmd320.state[4] = 0xc3d2e1f0UL; md->rmd320.state[5] = 0x76543210UL; md->rmd320.state[6] = 0xfedcba98UL; md->rmd320.state[7] = 0x89abcdefUL; md->rmd320.state[8] = 0x01234567UL; md->rmd320.state[9] = 0x3c2d1e0fUL; md->rmd320.curlen = 0; md->rmd320.length = 0; return CRYPT_OK; } /** Process a block of memory though the hash @param md The hash state @param in The data to hash @param inlen The length of the data (octets) @return CRYPT_OK if successful */ HASH_PROCESS(rmd320_process, rmd320_compress, rmd320, 64) /** Terminate the hash to get the digest @param md The hash state @param out [out] The destination of the hash (20 bytes) @return CRYPT_OK if successful */ int rmd320_done(hash_state * md, unsigned char *out) { int i; LTC_ARGCHK(md != NULL); LTC_ARGCHK(out != NULL); if (md->rmd320.curlen >= sizeof(md->rmd320.buf)) { return CRYPT_INVALID_ARG; } /* increase the length of the message */ md->rmd320.length += md->rmd320.curlen * 8; /* append the '1' bit */ md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0x80; /* if the length is currently above 56 bytes we append zeros * then compress. Then we can fall back to padding zeros and length * encoding like normal. */ if (md->rmd320.curlen > 56) { while (md->rmd320.curlen < 64) { md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0; } rmd320_compress(md, md->rmd320.buf); md->rmd320.curlen = 0; } /* pad upto 56 bytes of zeroes */ while (md->rmd320.curlen < 56) { md->rmd320.buf[md->rmd320.curlen++] = (unsigned char)0; } /* store length */ STORE64L(md->rmd320.length, md->rmd320.buf+56); rmd320_compress(md, md->rmd320.buf); /* copy output */ for (i = 0; i < 10; i++) { STORE32L(md->rmd320.state[i], out+(4*i)); } #ifdef LTC_CLEAN_STACK zeromem(md, sizeof(hash_state)); #endif return CRYPT_OK; } /** Self-test the hash @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled */ int rmd320_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { char *msg; unsigned char md[40]; } tests[] = { { "", { 0x22, 0xd6, 0x5d, 0x56, 0x61, 0x53, 0x6c, 0xdc, 0x75, 0xc1, 0xfd, 0xf5, 0xc6, 0xde, 0x7b, 0x41, 0xb9, 0xf2, 0x73, 0x25, 0xeb, 0xc6, 0x1e, 0x85, 0x57, 0x17, 0x7d, 0x70, 0x5a, 0x0e, 0xc8, 0x80, 0x15, 0x1c, 0x3a, 0x32, 0xa0, 0x08, 0x99, 0xb8 } }, { "a", { 0xce, 0x78, 0x85, 0x06, 0x38, 0xf9, 0x26, 0x58, 0xa5, 0xa5, 0x85, 0x09, 0x75, 0x79, 0x92, 0x6d, 0xda, 0x66, 0x7a, 0x57, 0x16, 0x56, 0x2c, 0xfc, 0xf6, 0xfb, 0xe7, 0x7f, 0x63, 0x54, 0x2f, 0x99, 0xb0, 0x47, 0x05, 0xd6, 0x97, 0x0d, 0xff, 0x5d } }, { "abc", { 0xde, 0x4c, 0x01, 0xb3, 0x05, 0x4f, 0x89, 0x30, 0xa7, 0x9d, 0x09, 0xae, 0x73, 0x8e, 0x92, 0x30, 0x1e, 0x5a, 0x17, 0x08, 0x5b, 0xef, 0xfd, 0xc1, 0xb8, 0xd1, 0x16, 0x71, 0x3e, 0x74, 0xf8, 0x2f, 0xa9, 0x42, 0xd6, 0x4c, 0xdb, 0xc4, 0x68, 0x2d } }, { "message digest", { 0x3a, 0x8e, 0x28, 0x50, 0x2e, 0xd4, 0x5d, 0x42, 0x2f, 0x68, 0x84, 0x4f, 0x9d, 0xd3, 0x16, 0xe7, 0xb9, 0x85, 0x33, 0xfa, 0x3f, 0x2a, 0x91, 0xd2, 0x9f, 0x84, 0xd4, 0x25, 0xc8, 0x8d, 0x6b, 0x4e, 0xff, 0x72, 0x7d, 0xf6, 0x6a, 0x7c, 0x01, 0x97 } }, { "abcdefghijklmnopqrstuvwxyz", { 0xca, 0xbd, 0xb1, 0x81, 0x0b, 0x92, 0x47, 0x0a, 0x20, 0x93, 0xaa, 0x6b, 0xce, 0x05, 0x95, 0x2c, 0x28, 0x34, 0x8c, 0xf4, 0x3f, 0xf6, 0x08, 0x41, 0x97, 0x51, 0x66, 0xbb, 0x40, 0xed, 0x23, 0x40, 0x04, 0xb8, 0x82, 0x44, 0x63, 0xe6, 0xb0, 0x09 } }, { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", { 0xd0, 0x34, 0xa7, 0x95, 0x0c, 0xf7, 0x22, 0x02, 0x1b, 0xa4, 0xb8, 0x4d, 0xf7, 0x69, 0xa5, 0xde, 0x20, 0x60, 0xe2, 0x59, 0xdf, 0x4c, 0x9b, 0xb4, 0xa4, 0x26, 0x8c, 0x0e, 0x93, 0x5b, 0xbc, 0x74, 0x70, 0xa9, 0x69, 0xc9, 0xd0, 0x72, 0xa1, 0xac } } }; int x; unsigned char buf[40]; hash_state md; for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { rmd320_init(&md); rmd320_process(&md, (unsigned char *)tests[x].msg, strlen(tests[x].msg)); rmd320_done(&md, buf); if (XMEMCMP(buf, tests[x].md, 40) != 0) { #if 0 printf("Failed test %d\n", x); #endif return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } #endif libtomcrypt-1.17/src/hashes/md2.c0000644000175100001440000001534710621351501015425 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @param md2.c LTC_MD2 (RFC 1319) hash function implementation by Tom St Denis */ #ifdef LTC_MD2 const struct ltc_hash_descriptor md2_desc = { "md2", 7, 16, 16, /* OID */ { 1, 2, 840, 113549, 2, 2, }, 6, &md2_init, &md2_process, &md2_done, &md2_test, NULL }; static const unsigned char PI_SUBST[256] = { 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63, 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50, 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165, 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210, 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157, 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27, 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15, 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233, 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228, 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237, 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 }; /* adds 16 bytes to the checksum */ static void md2_update_chksum(hash_state *md) { int j; unsigned char L; L = md->md2.chksum[15]; for (j = 0; j < 16; j++) { /* caution, the RFC says its "C[j] = S[M[i*16+j] xor L]" but the reference source code [and test vectors] say otherwise. */ L = (md->md2.chksum[j] ^= PI_SUBST[(int)(md->md2.buf[j] ^ L)] & 255); } } static void md2_compress(hash_state *md) { int j, k; unsigned char t; /* copy block */ for (j = 0; j < 16; j++) { md->md2.X[16+j] = md->md2.buf[j]; md->md2.X[32+j] = md->md2.X[j] ^ md->md2.X[16+j]; } t = (unsigned char)0; /* do 18 rounds */ for (j = 0; j < 18; j++) { for (k = 0; k < 48; k++) { t = (md->md2.X[k] ^= PI_SUBST[(int)(t & 255)]); } t = (t + (unsigned char)j) & 255; } } /** Initialize the hash state @param md The hash state you wish to initialize @return CRYPT_OK if successful */ int md2_init(hash_state *md) { LTC_ARGCHK(md != NULL); /* LTC_MD2 uses a zero'ed state... */ zeromem(md->md2.X, sizeof(md->md2.X)); zeromem(md->md2.chksum, sizeof(md->md2.chksum)); zeromem(md->md2.buf, sizeof(md->md2.buf)); md->md2.curlen = 0; return CRYPT_OK; } /** Process a block of memory though the hash @param md The hash state @param in The data to hash @param inlen The length of the data (octets) @return CRYPT_OK if successful */ int md2_process(hash_state *md, const unsigned char *in, unsigned long inlen) { unsigned long n; LTC_ARGCHK(md != NULL); LTC_ARGCHK(in != NULL); if (md-> md2 .curlen > sizeof(md-> md2 .buf)) { return CRYPT_INVALID_ARG; } while (inlen > 0) { n = MIN(inlen, (16 - md->md2.curlen)); XMEMCPY(md->md2.buf + md->md2.curlen, in, (size_t)n); md->md2.curlen += n; in += n; inlen -= n; /* is 16 bytes full? */ if (md->md2.curlen == 16) { md2_compress(md); md2_update_chksum(md); md->md2.curlen = 0; } } return CRYPT_OK; } /** Terminate the hash to get the digest @param md The hash state @param out [out] The destination of the hash (16 bytes) @return CRYPT_OK if successful */ int md2_done(hash_state * md, unsigned char *out) { unsigned long i, k; LTC_ARGCHK(md != NULL); LTC_ARGCHK(out != NULL); if (md->md2.curlen >= sizeof(md->md2.buf)) { return CRYPT_INVALID_ARG; } /* pad the message */ k = 16 - md->md2.curlen; for (i = md->md2.curlen; i < 16; i++) { md->md2.buf[i] = (unsigned char)k; } /* hash and update */ md2_compress(md); md2_update_chksum(md); /* hash checksum */ XMEMCPY(md->md2.buf, md->md2.chksum, 16); md2_compress(md); /* output is lower 16 bytes of X */ XMEMCPY(out, md->md2.X, 16); #ifdef LTC_CLEAN_STACK zeromem(md, sizeof(hash_state)); #endif return CRYPT_OK; } /** Self-test the hash @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled */ int md2_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { char *msg; unsigned char md[16]; } tests[] = { { "", {0x83,0x50,0xe5,0xa3,0xe2,0x4c,0x15,0x3d, 0xf2,0x27,0x5c,0x9f,0x80,0x69,0x27,0x73 } }, { "a", {0x32,0xec,0x01,0xec,0x4a,0x6d,0xac,0x72, 0xc0,0xab,0x96,0xfb,0x34,0xc0,0xb5,0xd1 } }, { "message digest", {0xab,0x4f,0x49,0x6b,0xfb,0x2a,0x53,0x0b, 0x21,0x9f,0xf3,0x30,0x31,0xfe,0x06,0xb0 } }, { "abcdefghijklmnopqrstuvwxyz", {0x4e,0x8d,0xdf,0xf3,0x65,0x02,0x92,0xab, 0x5a,0x41,0x08,0xc3,0xaa,0x47,0x94,0x0b } }, { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", {0xda,0x33,0xde,0xf2,0xa4,0x2d,0xf1,0x39, 0x75,0x35,0x28,0x46,0xc3,0x03,0x38,0xcd } }, { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", {0xd5,0x97,0x6f,0x79,0xd8,0x3d,0x3a,0x0d, 0xc9,0x80,0x6c,0x3c,0x66,0xf3,0xef,0xd8 } } }; int i; hash_state md; unsigned char buf[16]; for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { md2_init(&md); md2_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); md2_done(&md, buf); if (XMEMCMP(buf, tests[i].md, 16) != 0) { return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/hashes/md2.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2007/05/12 14:25:28 $ */ libtomcrypt-1.17/src/hashes/md4.c0000644000175100001440000002066510621351501015426 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @param md4.c Submitted by Dobes Vandermeer (dobes@smartt.com) */ #ifdef LTC_MD4 const struct ltc_hash_descriptor md4_desc = { "md4", 6, 16, 64, /* OID */ { 1, 2, 840, 113549, 2, 4, }, 6, &md4_init, &md4_process, &md4_done, &md4_test, NULL }; #define S11 3 #define S12 7 #define S13 11 #define S14 19 #define S21 3 #define S22 5 #define S23 9 #define S24 13 #define S31 3 #define S32 9 #define S33 11 #define S34 15 /* F, G and H are basic LTC_MD4 functions. */ #define F(x, y, z) (z ^ (x & (y ^ z))) #define G(x, y, z) ((x & y) | (z & (x | y))) #define H(x, y, z) ((x) ^ (y) ^ (z)) /* ROTATE_LEFT rotates x left n bits. */ #define ROTATE_LEFT(x, n) ROLc(x, n) /* FF, GG and HH are transformations for rounds 1, 2 and 3 */ /* Rotation is separate from addition to prevent recomputation */ #define FF(a, b, c, d, x, s) { \ (a) += F ((b), (c), (d)) + (x); \ (a) = ROTATE_LEFT ((a), (s)); \ } #define GG(a, b, c, d, x, s) { \ (a) += G ((b), (c), (d)) + (x) + 0x5a827999UL; \ (a) = ROTATE_LEFT ((a), (s)); \ } #define HH(a, b, c, d, x, s) { \ (a) += H ((b), (c), (d)) + (x) + 0x6ed9eba1UL; \ (a) = ROTATE_LEFT ((a), (s)); \ } #ifdef LTC_CLEAN_STACK static int _md4_compress(hash_state *md, unsigned char *buf) #else static int md4_compress(hash_state *md, unsigned char *buf) #endif { ulong32 x[16], a, b, c, d; int i; /* copy state */ a = md->md4.state[0]; b = md->md4.state[1]; c = md->md4.state[2]; d = md->md4.state[3]; /* copy the state into 512-bits into W[0..15] */ for (i = 0; i < 16; i++) { LOAD32L(x[i], buf + (4*i)); } /* Round 1 */ FF (a, b, c, d, x[ 0], S11); /* 1 */ FF (d, a, b, c, x[ 1], S12); /* 2 */ FF (c, d, a, b, x[ 2], S13); /* 3 */ FF (b, c, d, a, x[ 3], S14); /* 4 */ FF (a, b, c, d, x[ 4], S11); /* 5 */ FF (d, a, b, c, x[ 5], S12); /* 6 */ FF (c, d, a, b, x[ 6], S13); /* 7 */ FF (b, c, d, a, x[ 7], S14); /* 8 */ FF (a, b, c, d, x[ 8], S11); /* 9 */ FF (d, a, b, c, x[ 9], S12); /* 10 */ FF (c, d, a, b, x[10], S13); /* 11 */ FF (b, c, d, a, x[11], S14); /* 12 */ FF (a, b, c, d, x[12], S11); /* 13 */ FF (d, a, b, c, x[13], S12); /* 14 */ FF (c, d, a, b, x[14], S13); /* 15 */ FF (b, c, d, a, x[15], S14); /* 16 */ /* Round 2 */ GG (a, b, c, d, x[ 0], S21); /* 17 */ GG (d, a, b, c, x[ 4], S22); /* 18 */ GG (c, d, a, b, x[ 8], S23); /* 19 */ GG (b, c, d, a, x[12], S24); /* 20 */ GG (a, b, c, d, x[ 1], S21); /* 21 */ GG (d, a, b, c, x[ 5], S22); /* 22 */ GG (c, d, a, b, x[ 9], S23); /* 23 */ GG (b, c, d, a, x[13], S24); /* 24 */ GG (a, b, c, d, x[ 2], S21); /* 25 */ GG (d, a, b, c, x[ 6], S22); /* 26 */ GG (c, d, a, b, x[10], S23); /* 27 */ GG (b, c, d, a, x[14], S24); /* 28 */ GG (a, b, c, d, x[ 3], S21); /* 29 */ GG (d, a, b, c, x[ 7], S22); /* 30 */ GG (c, d, a, b, x[11], S23); /* 31 */ GG (b, c, d, a, x[15], S24); /* 32 */ /* Round 3 */ HH (a, b, c, d, x[ 0], S31); /* 33 */ HH (d, a, b, c, x[ 8], S32); /* 34 */ HH (c, d, a, b, x[ 4], S33); /* 35 */ HH (b, c, d, a, x[12], S34); /* 36 */ HH (a, b, c, d, x[ 2], S31); /* 37 */ HH (d, a, b, c, x[10], S32); /* 38 */ HH (c, d, a, b, x[ 6], S33); /* 39 */ HH (b, c, d, a, x[14], S34); /* 40 */ HH (a, b, c, d, x[ 1], S31); /* 41 */ HH (d, a, b, c, x[ 9], S32); /* 42 */ HH (c, d, a, b, x[ 5], S33); /* 43 */ HH (b, c, d, a, x[13], S34); /* 44 */ HH (a, b, c, d, x[ 3], S31); /* 45 */ HH (d, a, b, c, x[11], S32); /* 46 */ HH (c, d, a, b, x[ 7], S33); /* 47 */ HH (b, c, d, a, x[15], S34); /* 48 */ /* Update our state */ md->md4.state[0] = md->md4.state[0] + a; md->md4.state[1] = md->md4.state[1] + b; md->md4.state[2] = md->md4.state[2] + c; md->md4.state[3] = md->md4.state[3] + d; return CRYPT_OK; } #ifdef LTC_CLEAN_STACK static int md4_compress(hash_state *md, unsigned char *buf) { int err; err = _md4_compress(md, buf); burn_stack(sizeof(ulong32) * 20 + sizeof(int)); return err; } #endif /** Initialize the hash state @param md The hash state you wish to initialize @return CRYPT_OK if successful */ int md4_init(hash_state * md) { LTC_ARGCHK(md != NULL); md->md4.state[0] = 0x67452301UL; md->md4.state[1] = 0xefcdab89UL; md->md4.state[2] = 0x98badcfeUL; md->md4.state[3] = 0x10325476UL; md->md4.length = 0; md->md4.curlen = 0; return CRYPT_OK; } /** Process a block of memory though the hash @param md The hash state @param in The data to hash @param inlen The length of the data (octets) @return CRYPT_OK if successful */ HASH_PROCESS(md4_process, md4_compress, md4, 64) /** Terminate the hash to get the digest @param md The hash state @param out [out] The destination of the hash (16 bytes) @return CRYPT_OK if successful */ int md4_done(hash_state * md, unsigned char *out) { int i; LTC_ARGCHK(md != NULL); LTC_ARGCHK(out != NULL); if (md->md4.curlen >= sizeof(md->md4.buf)) { return CRYPT_INVALID_ARG; } /* increase the length of the message */ md->md4.length += md->md4.curlen * 8; /* append the '1' bit */ md->md4.buf[md->md4.curlen++] = (unsigned char)0x80; /* if the length is currently above 56 bytes we append zeros * then compress. Then we can fall back to padding zeros and length * encoding like normal. */ if (md->md4.curlen > 56) { while (md->md4.curlen < 64) { md->md4.buf[md->md4.curlen++] = (unsigned char)0; } md4_compress(md, md->md4.buf); md->md4.curlen = 0; } /* pad upto 56 bytes of zeroes */ while (md->md4.curlen < 56) { md->md4.buf[md->md4.curlen++] = (unsigned char)0; } /* store length */ STORE64L(md->md4.length, md->md4.buf+56); md4_compress(md, md->md4.buf); /* copy output */ for (i = 0; i < 4; i++) { STORE32L(md->md4.state[i], out+(4*i)); } #ifdef LTC_CLEAN_STACK zeromem(md, sizeof(hash_state)); #endif return CRYPT_OK; } /** Self-test the hash @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled */ int md4_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct md4_test_case { char *input; unsigned char digest[16]; } cases[] = { { "", {0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31, 0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0} }, { "a", {0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46, 0x24, 0x5e, 0x05, 0xfb, 0xdb, 0xd6, 0xfb, 0x24} }, { "abc", {0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52, 0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d} }, { "message digest", {0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8, 0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b} }, { "abcdefghijklmnopqrstuvwxyz", {0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd, 0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9} }, { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", {0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35, 0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4} }, { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", {0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19, 0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36} }, }; int i; hash_state md; unsigned char digest[16]; for(i = 0; i < (int)(sizeof(cases) / sizeof(cases[0])); i++) { md4_init(&md); md4_process(&md, (unsigned char *)cases[i].input, (unsigned long)strlen(cases[i].input)); md4_done(&md, digest); if (XMEMCMP(digest, cases[i].digest, 16) != 0) { return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/hashes/md4.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2007/05/12 14:25:28 $ */ libtomcrypt-1.17/src/hashes/md5.c0000644000175100001440000002450710621351501015426 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file md5.c LTC_MD5 hash function by Tom St Denis */ #ifdef LTC_MD5 const struct ltc_hash_descriptor md5_desc = { "md5", 3, 16, 64, /* OID */ { 1, 2, 840, 113549, 2, 5, }, 6, &md5_init, &md5_process, &md5_done, &md5_test, NULL }; #define F(x,y,z) (z ^ (x & (y ^ z))) #define G(x,y,z) (y ^ (z & (y ^ x))) #define H(x,y,z) (x^y^z) #define I(x,y,z) (y^(x|(~z))) #ifdef LTC_SMALL_CODE #define FF(a,b,c,d,M,s,t) \ a = (a + F(b,c,d) + M + t); a = ROL(a, s) + b; #define GG(a,b,c,d,M,s,t) \ a = (a + G(b,c,d) + M + t); a = ROL(a, s) + b; #define HH(a,b,c,d,M,s,t) \ a = (a + H(b,c,d) + M + t); a = ROL(a, s) + b; #define II(a,b,c,d,M,s,t) \ a = (a + I(b,c,d) + M + t); a = ROL(a, s) + b; static const unsigned char Worder[64] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12, 5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2, 0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9 }; static const unsigned char Rorder[64] = { 7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22, 5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20, 4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23, 6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21 }; static const ulong32 Korder[64] = { 0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL, 0xf57c0fafUL, 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL, 0x698098d8UL, 0x8b44f7afUL, 0xffff5bb1UL, 0x895cd7beUL, 0x6b901122UL, 0xfd987193UL, 0xa679438eUL, 0x49b40821UL, 0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL, 0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL, 0x21e1cde6UL, 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL, 0xa9e3e905UL, 0xfcefa3f8UL, 0x676f02d9UL, 0x8d2a4c8aUL, 0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL, 0xfde5380cUL, 0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL, 0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL, 0xd9d4d039UL, 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL, 0xf4292244UL, 0x432aff97UL, 0xab9423a7UL, 0xfc93a039UL, 0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL, 0x85845dd1UL, 0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL, 0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL }; #else #define FF(a,b,c,d,M,s,t) \ a = (a + F(b,c,d) + M + t); a = ROLc(a, s) + b; #define GG(a,b,c,d,M,s,t) \ a = (a + G(b,c,d) + M + t); a = ROLc(a, s) + b; #define HH(a,b,c,d,M,s,t) \ a = (a + H(b,c,d) + M + t); a = ROLc(a, s) + b; #define II(a,b,c,d,M,s,t) \ a = (a + I(b,c,d) + M + t); a = ROLc(a, s) + b; #endif #ifdef LTC_CLEAN_STACK static int _md5_compress(hash_state *md, unsigned char *buf) #else static int md5_compress(hash_state *md, unsigned char *buf) #endif { ulong32 i, W[16], a, b, c, d; #ifdef LTC_SMALL_CODE ulong32 t; #endif /* copy the state into 512-bits into W[0..15] */ for (i = 0; i < 16; i++) { LOAD32L(W[i], buf + (4*i)); } /* copy state */ a = md->md5.state[0]; b = md->md5.state[1]; c = md->md5.state[2]; d = md->md5.state[3]; #ifdef LTC_SMALL_CODE for (i = 0; i < 16; ++i) { FF(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]); t = d; d = c; c = b; b = a; a = t; } for (; i < 32; ++i) { GG(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]); t = d; d = c; c = b; b = a; a = t; } for (; i < 48; ++i) { HH(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]); t = d; d = c; c = b; b = a; a = t; } for (; i < 64; ++i) { II(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]); t = d; d = c; c = b; b = a; a = t; } #else FF(a,b,c,d,W[0],7,0xd76aa478UL) FF(d,a,b,c,W[1],12,0xe8c7b756UL) FF(c,d,a,b,W[2],17,0x242070dbUL) FF(b,c,d,a,W[3],22,0xc1bdceeeUL) FF(a,b,c,d,W[4],7,0xf57c0fafUL) FF(d,a,b,c,W[5],12,0x4787c62aUL) FF(c,d,a,b,W[6],17,0xa8304613UL) FF(b,c,d,a,W[7],22,0xfd469501UL) FF(a,b,c,d,W[8],7,0x698098d8UL) FF(d,a,b,c,W[9],12,0x8b44f7afUL) FF(c,d,a,b,W[10],17,0xffff5bb1UL) FF(b,c,d,a,W[11],22,0x895cd7beUL) FF(a,b,c,d,W[12],7,0x6b901122UL) FF(d,a,b,c,W[13],12,0xfd987193UL) FF(c,d,a,b,W[14],17,0xa679438eUL) FF(b,c,d,a,W[15],22,0x49b40821UL) GG(a,b,c,d,W[1],5,0xf61e2562UL) GG(d,a,b,c,W[6],9,0xc040b340UL) GG(c,d,a,b,W[11],14,0x265e5a51UL) GG(b,c,d,a,W[0],20,0xe9b6c7aaUL) GG(a,b,c,d,W[5],5,0xd62f105dUL) GG(d,a,b,c,W[10],9,0x02441453UL) GG(c,d,a,b,W[15],14,0xd8a1e681UL) GG(b,c,d,a,W[4],20,0xe7d3fbc8UL) GG(a,b,c,d,W[9],5,0x21e1cde6UL) GG(d,a,b,c,W[14],9,0xc33707d6UL) GG(c,d,a,b,W[3],14,0xf4d50d87UL) GG(b,c,d,a,W[8],20,0x455a14edUL) GG(a,b,c,d,W[13],5,0xa9e3e905UL) GG(d,a,b,c,W[2],9,0xfcefa3f8UL) GG(c,d,a,b,W[7],14,0x676f02d9UL) GG(b,c,d,a,W[12],20,0x8d2a4c8aUL) HH(a,b,c,d,W[5],4,0xfffa3942UL) HH(d,a,b,c,W[8],11,0x8771f681UL) HH(c,d,a,b,W[11],16,0x6d9d6122UL) HH(b,c,d,a,W[14],23,0xfde5380cUL) HH(a,b,c,d,W[1],4,0xa4beea44UL) HH(d,a,b,c,W[4],11,0x4bdecfa9UL) HH(c,d,a,b,W[7],16,0xf6bb4b60UL) HH(b,c,d,a,W[10],23,0xbebfbc70UL) HH(a,b,c,d,W[13],4,0x289b7ec6UL) HH(d,a,b,c,W[0],11,0xeaa127faUL) HH(c,d,a,b,W[3],16,0xd4ef3085UL) HH(b,c,d,a,W[6],23,0x04881d05UL) HH(a,b,c,d,W[9],4,0xd9d4d039UL) HH(d,a,b,c,W[12],11,0xe6db99e5UL) HH(c,d,a,b,W[15],16,0x1fa27cf8UL) HH(b,c,d,a,W[2],23,0xc4ac5665UL) II(a,b,c,d,W[0],6,0xf4292244UL) II(d,a,b,c,W[7],10,0x432aff97UL) II(c,d,a,b,W[14],15,0xab9423a7UL) II(b,c,d,a,W[5],21,0xfc93a039UL) II(a,b,c,d,W[12],6,0x655b59c3UL) II(d,a,b,c,W[3],10,0x8f0ccc92UL) II(c,d,a,b,W[10],15,0xffeff47dUL) II(b,c,d,a,W[1],21,0x85845dd1UL) II(a,b,c,d,W[8],6,0x6fa87e4fUL) II(d,a,b,c,W[15],10,0xfe2ce6e0UL) II(c,d,a,b,W[6],15,0xa3014314UL) II(b,c,d,a,W[13],21,0x4e0811a1UL) II(a,b,c,d,W[4],6,0xf7537e82UL) II(d,a,b,c,W[11],10,0xbd3af235UL) II(c,d,a,b,W[2],15,0x2ad7d2bbUL) II(b,c,d,a,W[9],21,0xeb86d391UL) #endif md->md5.state[0] = md->md5.state[0] + a; md->md5.state[1] = md->md5.state[1] + b; md->md5.state[2] = md->md5.state[2] + c; md->md5.state[3] = md->md5.state[3] + d; return CRYPT_OK; } #ifdef LTC_CLEAN_STACK static int md5_compress(hash_state *md, unsigned char *buf) { int err; err = _md5_compress(md, buf); burn_stack(sizeof(ulong32) * 21); return err; } #endif /** Initialize the hash state @param md The hash state you wish to initialize @return CRYPT_OK if successful */ int md5_init(hash_state * md) { LTC_ARGCHK(md != NULL); md->md5.state[0] = 0x67452301UL; md->md5.state[1] = 0xefcdab89UL; md->md5.state[2] = 0x98badcfeUL; md->md5.state[3] = 0x10325476UL; md->md5.curlen = 0; md->md5.length = 0; return CRYPT_OK; } /** Process a block of memory though the hash @param md The hash state @param in The data to hash @param inlen The length of the data (octets) @return CRYPT_OK if successful */ HASH_PROCESS(md5_process, md5_compress, md5, 64) /** Terminate the hash to get the digest @param md The hash state @param out [out] The destination of the hash (16 bytes) @return CRYPT_OK if successful */ int md5_done(hash_state * md, unsigned char *out) { int i; LTC_ARGCHK(md != NULL); LTC_ARGCHK(out != NULL); if (md->md5.curlen >= sizeof(md->md5.buf)) { return CRYPT_INVALID_ARG; } /* increase the length of the message */ md->md5.length += md->md5.curlen * 8; /* append the '1' bit */ md->md5.buf[md->md5.curlen++] = (unsigned char)0x80; /* if the length is currently above 56 bytes we append zeros * then compress. Then we can fall back to padding zeros and length * encoding like normal. */ if (md->md5.curlen > 56) { while (md->md5.curlen < 64) { md->md5.buf[md->md5.curlen++] = (unsigned char)0; } md5_compress(md, md->md5.buf); md->md5.curlen = 0; } /* pad upto 56 bytes of zeroes */ while (md->md5.curlen < 56) { md->md5.buf[md->md5.curlen++] = (unsigned char)0; } /* store length */ STORE64L(md->md5.length, md->md5.buf+56); md5_compress(md, md->md5.buf); /* copy output */ for (i = 0; i < 4; i++) { STORE32L(md->md5.state[i], out+(4*i)); } #ifdef LTC_CLEAN_STACK zeromem(md, sizeof(hash_state)); #endif return CRYPT_OK; } /** Self-test the hash @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled */ int md5_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { char *msg; unsigned char hash[16]; } tests[] = { { "", { 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } }, { "a", {0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } }, { "abc", { 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } }, { "message digest", { 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d, 0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } }, { "abcdefghijklmnopqrstuvwxyz", { 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00, 0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } }, { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", { 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5, 0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } }, { "12345678901234567890123456789012345678901234567890123456789012345678901234567890", { 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55, 0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } }, { NULL, { 0 } } }; int i; unsigned char tmp[16]; hash_state md; for (i = 0; tests[i].msg != NULL; i++) { md5_init(&md); md5_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg)); md5_done(&md, tmp); if (XMEMCMP(tmp, tests[i].hash, 16) != 0) { return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/hashes/md5.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2007/05/12 14:25:28 $ */ libtomcrypt-1.17/src/hashes/whirl/0000755000175100001440000000000010621351501015712 5ustar tomuserslibtomcrypt-1.17/src/hashes/whirl/whirltab.c0000644000175100001440000016747510621351501017716 0ustar tomusers/** @file whirltab.c LTC_WHIRLPOOL tables, Tom St Denis */ static const ulong64 sbox0[] = { CONST64(0x18186018c07830d8), CONST64(0x23238c2305af4626), CONST64(0xc6c63fc67ef991b8), CONST64(0xe8e887e8136fcdfb), CONST64(0x878726874ca113cb), CONST64(0xb8b8dab8a9626d11), CONST64(0x0101040108050209), CONST64(0x4f4f214f426e9e0d), CONST64(0x3636d836adee6c9b), CONST64(0xa6a6a2a6590451ff), CONST64(0xd2d26fd2debdb90c), CONST64(0xf5f5f3f5fb06f70e), CONST64(0x7979f979ef80f296), CONST64(0x6f6fa16f5fcede30), CONST64(0x91917e91fcef3f6d), CONST64(0x52525552aa07a4f8), CONST64(0x60609d6027fdc047), CONST64(0xbcbccabc89766535), CONST64(0x9b9b569baccd2b37), CONST64(0x8e8e028e048c018a), CONST64(0xa3a3b6a371155bd2), CONST64(0x0c0c300c603c186c), CONST64(0x7b7bf17bff8af684), CONST64(0x3535d435b5e16a80), CONST64(0x1d1d741de8693af5), CONST64(0xe0e0a7e05347ddb3), CONST64(0xd7d77bd7f6acb321), CONST64(0xc2c22fc25eed999c), CONST64(0x2e2eb82e6d965c43), CONST64(0x4b4b314b627a9629), CONST64(0xfefedffea321e15d), CONST64(0x575741578216aed5), CONST64(0x15155415a8412abd), CONST64(0x7777c1779fb6eee8), CONST64(0x3737dc37a5eb6e92), CONST64(0xe5e5b3e57b56d79e), CONST64(0x9f9f469f8cd92313), CONST64(0xf0f0e7f0d317fd23), CONST64(0x4a4a354a6a7f9420), CONST64(0xdada4fda9e95a944), CONST64(0x58587d58fa25b0a2), CONST64(0xc9c903c906ca8fcf), CONST64(0x2929a429558d527c), CONST64(0x0a0a280a5022145a), CONST64(0xb1b1feb1e14f7f50), CONST64(0xa0a0baa0691a5dc9), CONST64(0x6b6bb16b7fdad614), CONST64(0x85852e855cab17d9), CONST64(0xbdbdcebd8173673c), CONST64(0x5d5d695dd234ba8f), CONST64(0x1010401080502090), CONST64(0xf4f4f7f4f303f507), CONST64(0xcbcb0bcb16c08bdd), CONST64(0x3e3ef83eedc67cd3), CONST64(0x0505140528110a2d), CONST64(0x676781671fe6ce78), CONST64(0xe4e4b7e47353d597), CONST64(0x27279c2725bb4e02), CONST64(0x4141194132588273), CONST64(0x8b8b168b2c9d0ba7), CONST64(0xa7a7a6a7510153f6), CONST64(0x7d7de97dcf94fab2), CONST64(0x95956e95dcfb3749), CONST64(0xd8d847d88e9fad56), CONST64(0xfbfbcbfb8b30eb70), CONST64(0xeeee9fee2371c1cd), CONST64(0x7c7ced7cc791f8bb), CONST64(0x6666856617e3cc71), CONST64(0xdddd53dda68ea77b), CONST64(0x17175c17b84b2eaf), CONST64(0x4747014702468e45), CONST64(0x9e9e429e84dc211a), CONST64(0xcaca0fca1ec589d4), CONST64(0x2d2db42d75995a58), CONST64(0xbfbfc6bf9179632e), CONST64(0x07071c07381b0e3f), CONST64(0xadad8ead012347ac), CONST64(0x5a5a755aea2fb4b0), CONST64(0x838336836cb51bef), CONST64(0x3333cc3385ff66b6), CONST64(0x636391633ff2c65c), CONST64(0x02020802100a0412), CONST64(0xaaaa92aa39384993), CONST64(0x7171d971afa8e2de), CONST64(0xc8c807c80ecf8dc6), CONST64(0x19196419c87d32d1), CONST64(0x494939497270923b), CONST64(0xd9d943d9869aaf5f), CONST64(0xf2f2eff2c31df931), CONST64(0xe3e3abe34b48dba8), CONST64(0x5b5b715be22ab6b9), CONST64(0x88881a8834920dbc), CONST64(0x9a9a529aa4c8293e), CONST64(0x262698262dbe4c0b), CONST64(0x3232c8328dfa64bf), CONST64(0xb0b0fab0e94a7d59), CONST64(0xe9e983e91b6acff2), CONST64(0x0f0f3c0f78331e77), CONST64(0xd5d573d5e6a6b733), CONST64(0x80803a8074ba1df4), CONST64(0xbebec2be997c6127), CONST64(0xcdcd13cd26de87eb), CONST64(0x3434d034bde46889), CONST64(0x48483d487a759032), CONST64(0xffffdbffab24e354), CONST64(0x7a7af57af78ff48d), CONST64(0x90907a90f4ea3d64), CONST64(0x5f5f615fc23ebe9d), CONST64(0x202080201da0403d), CONST64(0x6868bd6867d5d00f), CONST64(0x1a1a681ad07234ca), CONST64(0xaeae82ae192c41b7), CONST64(0xb4b4eab4c95e757d), CONST64(0x54544d549a19a8ce), CONST64(0x93937693ece53b7f), CONST64(0x222288220daa442f), CONST64(0x64648d6407e9c863), CONST64(0xf1f1e3f1db12ff2a), CONST64(0x7373d173bfa2e6cc), CONST64(0x12124812905a2482), CONST64(0x40401d403a5d807a), CONST64(0x0808200840281048), CONST64(0xc3c32bc356e89b95), CONST64(0xecec97ec337bc5df), CONST64(0xdbdb4bdb9690ab4d), CONST64(0xa1a1bea1611f5fc0), CONST64(0x8d8d0e8d1c830791), CONST64(0x3d3df43df5c97ac8), CONST64(0x97976697ccf1335b), CONST64(0x0000000000000000), CONST64(0xcfcf1bcf36d483f9), CONST64(0x2b2bac2b4587566e), CONST64(0x7676c57697b3ece1), CONST64(0x8282328264b019e6), CONST64(0xd6d67fd6fea9b128), CONST64(0x1b1b6c1bd87736c3), CONST64(0xb5b5eeb5c15b7774), CONST64(0xafaf86af112943be), CONST64(0x6a6ab56a77dfd41d), CONST64(0x50505d50ba0da0ea), CONST64(0x45450945124c8a57), CONST64(0xf3f3ebf3cb18fb38), CONST64(0x3030c0309df060ad), CONST64(0xefef9bef2b74c3c4), CONST64(0x3f3ffc3fe5c37eda), CONST64(0x55554955921caac7), CONST64(0xa2a2b2a2791059db), CONST64(0xeaea8fea0365c9e9), CONST64(0x656589650fecca6a), CONST64(0xbabad2bab9686903), CONST64(0x2f2fbc2f65935e4a), CONST64(0xc0c027c04ee79d8e), CONST64(0xdede5fdebe81a160), CONST64(0x1c1c701ce06c38fc), CONST64(0xfdfdd3fdbb2ee746), CONST64(0x4d4d294d52649a1f), CONST64(0x92927292e4e03976), CONST64(0x7575c9758fbceafa), CONST64(0x06061806301e0c36), CONST64(0x8a8a128a249809ae), CONST64(0xb2b2f2b2f940794b), CONST64(0xe6e6bfe66359d185), CONST64(0x0e0e380e70361c7e), CONST64(0x1f1f7c1ff8633ee7), CONST64(0x6262956237f7c455), CONST64(0xd4d477d4eea3b53a), CONST64(0xa8a89aa829324d81), CONST64(0x96966296c4f43152), CONST64(0xf9f9c3f99b3aef62), CONST64(0xc5c533c566f697a3), CONST64(0x2525942535b14a10), CONST64(0x59597959f220b2ab), CONST64(0x84842a8454ae15d0), CONST64(0x7272d572b7a7e4c5), CONST64(0x3939e439d5dd72ec), CONST64(0x4c4c2d4c5a619816), CONST64(0x5e5e655eca3bbc94), CONST64(0x7878fd78e785f09f), CONST64(0x3838e038ddd870e5), CONST64(0x8c8c0a8c14860598), CONST64(0xd1d163d1c6b2bf17), CONST64(0xa5a5aea5410b57e4), CONST64(0xe2e2afe2434dd9a1), CONST64(0x616199612ff8c24e), CONST64(0xb3b3f6b3f1457b42), CONST64(0x2121842115a54234), CONST64(0x9c9c4a9c94d62508), CONST64(0x1e1e781ef0663cee), CONST64(0x4343114322528661), CONST64(0xc7c73bc776fc93b1), CONST64(0xfcfcd7fcb32be54f), CONST64(0x0404100420140824), CONST64(0x51515951b208a2e3), CONST64(0x99995e99bcc72f25), CONST64(0x6d6da96d4fc4da22), CONST64(0x0d0d340d68391a65), CONST64(0xfafacffa8335e979), CONST64(0xdfdf5bdfb684a369), CONST64(0x7e7ee57ed79bfca9), CONST64(0x242490243db44819), CONST64(0x3b3bec3bc5d776fe), CONST64(0xabab96ab313d4b9a), CONST64(0xcece1fce3ed181f0), CONST64(0x1111441188552299), CONST64(0x8f8f068f0c890383), CONST64(0x4e4e254e4a6b9c04), CONST64(0xb7b7e6b7d1517366), CONST64(0xebeb8beb0b60cbe0), CONST64(0x3c3cf03cfdcc78c1), CONST64(0x81813e817cbf1ffd), CONST64(0x94946a94d4fe3540), CONST64(0xf7f7fbf7eb0cf31c), CONST64(0xb9b9deb9a1676f18), CONST64(0x13134c13985f268b), CONST64(0x2c2cb02c7d9c5851), CONST64(0xd3d36bd3d6b8bb05), CONST64(0xe7e7bbe76b5cd38c), CONST64(0x6e6ea56e57cbdc39), CONST64(0xc4c437c46ef395aa), CONST64(0x03030c03180f061b), CONST64(0x565645568a13acdc), CONST64(0x44440d441a49885e), CONST64(0x7f7fe17fdf9efea0), CONST64(0xa9a99ea921374f88), CONST64(0x2a2aa82a4d825467), CONST64(0xbbbbd6bbb16d6b0a), CONST64(0xc1c123c146e29f87), CONST64(0x53535153a202a6f1), CONST64(0xdcdc57dcae8ba572), CONST64(0x0b0b2c0b58271653), CONST64(0x9d9d4e9d9cd32701), CONST64(0x6c6cad6c47c1d82b), CONST64(0x3131c43195f562a4), CONST64(0x7474cd7487b9e8f3), CONST64(0xf6f6fff6e309f115), CONST64(0x464605460a438c4c), CONST64(0xacac8aac092645a5), CONST64(0x89891e893c970fb5), CONST64(0x14145014a04428b4), CONST64(0xe1e1a3e15b42dfba), CONST64(0x16165816b04e2ca6), CONST64(0x3a3ae83acdd274f7), CONST64(0x6969b9696fd0d206), CONST64(0x09092409482d1241), CONST64(0x7070dd70a7ade0d7), CONST64(0xb6b6e2b6d954716f), CONST64(0xd0d067d0ceb7bd1e), CONST64(0xeded93ed3b7ec7d6), CONST64(0xcccc17cc2edb85e2), CONST64(0x424215422a578468), CONST64(0x98985a98b4c22d2c), CONST64(0xa4a4aaa4490e55ed), CONST64(0x2828a0285d885075), CONST64(0x5c5c6d5cda31b886), CONST64(0xf8f8c7f8933fed6b), CONST64(0x8686228644a411c2) }; #ifdef LTC_SMALL_CODE #define SB0(x) sbox0[x] #define SB1(x) ROR64c(sbox0[x], 8) #define SB2(x) ROR64c(sbox0[x], 16) #define SB3(x) ROR64c(sbox0[x], 24) #define SB4(x) ROR64c(sbox0[x], 32) #define SB5(x) ROR64c(sbox0[x], 40) #define SB6(x) ROR64c(sbox0[x], 48) #define SB7(x) ROR64c(sbox0[x], 56) #else #define SB0(x) sbox0[x] #define SB1(x) sbox1[x] #define SB2(x) sbox2[x] #define SB3(x) sbox3[x] #define SB4(x) sbox4[x] #define SB5(x) sbox5[x] #define SB6(x) sbox6[x] #define SB7(x) sbox7[x] static const ulong64 sbox1[] = { CONST64(0xd818186018c07830), CONST64(0x2623238c2305af46), CONST64(0xb8c6c63fc67ef991), CONST64(0xfbe8e887e8136fcd), CONST64(0xcb878726874ca113), CONST64(0x11b8b8dab8a9626d), CONST64(0x0901010401080502), CONST64(0x0d4f4f214f426e9e), CONST64(0x9b3636d836adee6c), CONST64(0xffa6a6a2a6590451), CONST64(0x0cd2d26fd2debdb9), CONST64(0x0ef5f5f3f5fb06f7), CONST64(0x967979f979ef80f2), CONST64(0x306f6fa16f5fcede), CONST64(0x6d91917e91fcef3f), CONST64(0xf852525552aa07a4), CONST64(0x4760609d6027fdc0), CONST64(0x35bcbccabc897665), CONST64(0x379b9b569baccd2b), CONST64(0x8a8e8e028e048c01), CONST64(0xd2a3a3b6a371155b), CONST64(0x6c0c0c300c603c18), CONST64(0x847b7bf17bff8af6), CONST64(0x803535d435b5e16a), CONST64(0xf51d1d741de8693a), CONST64(0xb3e0e0a7e05347dd), CONST64(0x21d7d77bd7f6acb3), CONST64(0x9cc2c22fc25eed99), CONST64(0x432e2eb82e6d965c), CONST64(0x294b4b314b627a96), CONST64(0x5dfefedffea321e1), CONST64(0xd5575741578216ae), CONST64(0xbd15155415a8412a), CONST64(0xe87777c1779fb6ee), CONST64(0x923737dc37a5eb6e), CONST64(0x9ee5e5b3e57b56d7), CONST64(0x139f9f469f8cd923), CONST64(0x23f0f0e7f0d317fd), CONST64(0x204a4a354a6a7f94), CONST64(0x44dada4fda9e95a9), CONST64(0xa258587d58fa25b0), CONST64(0xcfc9c903c906ca8f), CONST64(0x7c2929a429558d52), CONST64(0x5a0a0a280a502214), CONST64(0x50b1b1feb1e14f7f), CONST64(0xc9a0a0baa0691a5d), CONST64(0x146b6bb16b7fdad6), CONST64(0xd985852e855cab17), CONST64(0x3cbdbdcebd817367), CONST64(0x8f5d5d695dd234ba), CONST64(0x9010104010805020), CONST64(0x07f4f4f7f4f303f5), CONST64(0xddcbcb0bcb16c08b), CONST64(0xd33e3ef83eedc67c), CONST64(0x2d0505140528110a), CONST64(0x78676781671fe6ce), CONST64(0x97e4e4b7e47353d5), CONST64(0x0227279c2725bb4e), CONST64(0x7341411941325882), CONST64(0xa78b8b168b2c9d0b), CONST64(0xf6a7a7a6a7510153), CONST64(0xb27d7de97dcf94fa), CONST64(0x4995956e95dcfb37), CONST64(0x56d8d847d88e9fad), CONST64(0x70fbfbcbfb8b30eb), CONST64(0xcdeeee9fee2371c1), CONST64(0xbb7c7ced7cc791f8), CONST64(0x716666856617e3cc), CONST64(0x7bdddd53dda68ea7), CONST64(0xaf17175c17b84b2e), CONST64(0x454747014702468e), CONST64(0x1a9e9e429e84dc21), CONST64(0xd4caca0fca1ec589), CONST64(0x582d2db42d75995a), CONST64(0x2ebfbfc6bf917963), CONST64(0x3f07071c07381b0e), CONST64(0xacadad8ead012347), CONST64(0xb05a5a755aea2fb4), CONST64(0xef838336836cb51b), CONST64(0xb63333cc3385ff66), CONST64(0x5c636391633ff2c6), CONST64(0x1202020802100a04), CONST64(0x93aaaa92aa393849), CONST64(0xde7171d971afa8e2), CONST64(0xc6c8c807c80ecf8d), CONST64(0xd119196419c87d32), CONST64(0x3b49493949727092), CONST64(0x5fd9d943d9869aaf), CONST64(0x31f2f2eff2c31df9), CONST64(0xa8e3e3abe34b48db), CONST64(0xb95b5b715be22ab6), CONST64(0xbc88881a8834920d), CONST64(0x3e9a9a529aa4c829), CONST64(0x0b262698262dbe4c), CONST64(0xbf3232c8328dfa64), CONST64(0x59b0b0fab0e94a7d), CONST64(0xf2e9e983e91b6acf), CONST64(0x770f0f3c0f78331e), CONST64(0x33d5d573d5e6a6b7), CONST64(0xf480803a8074ba1d), CONST64(0x27bebec2be997c61), CONST64(0xebcdcd13cd26de87), CONST64(0x893434d034bde468), CONST64(0x3248483d487a7590), CONST64(0x54ffffdbffab24e3), CONST64(0x8d7a7af57af78ff4), CONST64(0x6490907a90f4ea3d), CONST64(0x9d5f5f615fc23ebe), CONST64(0x3d202080201da040), CONST64(0x0f6868bd6867d5d0), CONST64(0xca1a1a681ad07234), CONST64(0xb7aeae82ae192c41), CONST64(0x7db4b4eab4c95e75), CONST64(0xce54544d549a19a8), CONST64(0x7f93937693ece53b), CONST64(0x2f222288220daa44), CONST64(0x6364648d6407e9c8), CONST64(0x2af1f1e3f1db12ff), CONST64(0xcc7373d173bfa2e6), CONST64(0x8212124812905a24), CONST64(0x7a40401d403a5d80), CONST64(0x4808082008402810), CONST64(0x95c3c32bc356e89b), CONST64(0xdfecec97ec337bc5), CONST64(0x4ddbdb4bdb9690ab), CONST64(0xc0a1a1bea1611f5f), CONST64(0x918d8d0e8d1c8307), CONST64(0xc83d3df43df5c97a), CONST64(0x5b97976697ccf133), CONST64(0x0000000000000000), CONST64(0xf9cfcf1bcf36d483), CONST64(0x6e2b2bac2b458756), CONST64(0xe17676c57697b3ec), CONST64(0xe68282328264b019), CONST64(0x28d6d67fd6fea9b1), CONST64(0xc31b1b6c1bd87736), CONST64(0x74b5b5eeb5c15b77), CONST64(0xbeafaf86af112943), CONST64(0x1d6a6ab56a77dfd4), CONST64(0xea50505d50ba0da0), CONST64(0x5745450945124c8a), CONST64(0x38f3f3ebf3cb18fb), CONST64(0xad3030c0309df060), CONST64(0xc4efef9bef2b74c3), CONST64(0xda3f3ffc3fe5c37e), CONST64(0xc755554955921caa), CONST64(0xdba2a2b2a2791059), CONST64(0xe9eaea8fea0365c9), CONST64(0x6a656589650fecca), CONST64(0x03babad2bab96869), CONST64(0x4a2f2fbc2f65935e), CONST64(0x8ec0c027c04ee79d), CONST64(0x60dede5fdebe81a1), CONST64(0xfc1c1c701ce06c38), CONST64(0x46fdfdd3fdbb2ee7), CONST64(0x1f4d4d294d52649a), CONST64(0x7692927292e4e039), CONST64(0xfa7575c9758fbcea), CONST64(0x3606061806301e0c), CONST64(0xae8a8a128a249809), CONST64(0x4bb2b2f2b2f94079), CONST64(0x85e6e6bfe66359d1), CONST64(0x7e0e0e380e70361c), CONST64(0xe71f1f7c1ff8633e), CONST64(0x556262956237f7c4), CONST64(0x3ad4d477d4eea3b5), CONST64(0x81a8a89aa829324d), CONST64(0x5296966296c4f431), CONST64(0x62f9f9c3f99b3aef), CONST64(0xa3c5c533c566f697), CONST64(0x102525942535b14a), CONST64(0xab59597959f220b2), CONST64(0xd084842a8454ae15), CONST64(0xc57272d572b7a7e4), CONST64(0xec3939e439d5dd72), CONST64(0x164c4c2d4c5a6198), CONST64(0x945e5e655eca3bbc), CONST64(0x9f7878fd78e785f0), CONST64(0xe53838e038ddd870), CONST64(0x988c8c0a8c148605), CONST64(0x17d1d163d1c6b2bf), CONST64(0xe4a5a5aea5410b57), CONST64(0xa1e2e2afe2434dd9), CONST64(0x4e616199612ff8c2), CONST64(0x42b3b3f6b3f1457b), CONST64(0x342121842115a542), CONST64(0x089c9c4a9c94d625), CONST64(0xee1e1e781ef0663c), CONST64(0x6143431143225286), CONST64(0xb1c7c73bc776fc93), CONST64(0x4ffcfcd7fcb32be5), CONST64(0x2404041004201408), CONST64(0xe351515951b208a2), CONST64(0x2599995e99bcc72f), CONST64(0x226d6da96d4fc4da), CONST64(0x650d0d340d68391a), CONST64(0x79fafacffa8335e9), CONST64(0x69dfdf5bdfb684a3), CONST64(0xa97e7ee57ed79bfc), CONST64(0x19242490243db448), CONST64(0xfe3b3bec3bc5d776), CONST64(0x9aabab96ab313d4b), CONST64(0xf0cece1fce3ed181), CONST64(0x9911114411885522), CONST64(0x838f8f068f0c8903), CONST64(0x044e4e254e4a6b9c), CONST64(0x66b7b7e6b7d15173), CONST64(0xe0ebeb8beb0b60cb), CONST64(0xc13c3cf03cfdcc78), CONST64(0xfd81813e817cbf1f), CONST64(0x4094946a94d4fe35), CONST64(0x1cf7f7fbf7eb0cf3), CONST64(0x18b9b9deb9a1676f), CONST64(0x8b13134c13985f26), CONST64(0x512c2cb02c7d9c58), CONST64(0x05d3d36bd3d6b8bb), CONST64(0x8ce7e7bbe76b5cd3), CONST64(0x396e6ea56e57cbdc), CONST64(0xaac4c437c46ef395), CONST64(0x1b03030c03180f06), CONST64(0xdc565645568a13ac), CONST64(0x5e44440d441a4988), CONST64(0xa07f7fe17fdf9efe), CONST64(0x88a9a99ea921374f), CONST64(0x672a2aa82a4d8254), CONST64(0x0abbbbd6bbb16d6b), CONST64(0x87c1c123c146e29f), CONST64(0xf153535153a202a6), CONST64(0x72dcdc57dcae8ba5), CONST64(0x530b0b2c0b582716), CONST64(0x019d9d4e9d9cd327), CONST64(0x2b6c6cad6c47c1d8), CONST64(0xa43131c43195f562), CONST64(0xf37474cd7487b9e8), CONST64(0x15f6f6fff6e309f1), CONST64(0x4c464605460a438c), CONST64(0xa5acac8aac092645), CONST64(0xb589891e893c970f), CONST64(0xb414145014a04428), CONST64(0xbae1e1a3e15b42df), CONST64(0xa616165816b04e2c), CONST64(0xf73a3ae83acdd274), CONST64(0x066969b9696fd0d2), CONST64(0x4109092409482d12), CONST64(0xd77070dd70a7ade0), CONST64(0x6fb6b6e2b6d95471), CONST64(0x1ed0d067d0ceb7bd), CONST64(0xd6eded93ed3b7ec7), CONST64(0xe2cccc17cc2edb85), CONST64(0x68424215422a5784), CONST64(0x2c98985a98b4c22d), CONST64(0xeda4a4aaa4490e55), CONST64(0x752828a0285d8850), CONST64(0x865c5c6d5cda31b8), CONST64(0x6bf8f8c7f8933fed), CONST64(0xc28686228644a411) }; static const ulong64 sbox2[] = { CONST64(0x30d818186018c078), CONST64(0x462623238c2305af), CONST64(0x91b8c6c63fc67ef9), CONST64(0xcdfbe8e887e8136f), CONST64(0x13cb878726874ca1), CONST64(0x6d11b8b8dab8a962), CONST64(0x0209010104010805), CONST64(0x9e0d4f4f214f426e), CONST64(0x6c9b3636d836adee), CONST64(0x51ffa6a6a2a65904), CONST64(0xb90cd2d26fd2debd), CONST64(0xf70ef5f5f3f5fb06), CONST64(0xf2967979f979ef80), CONST64(0xde306f6fa16f5fce), CONST64(0x3f6d91917e91fcef), CONST64(0xa4f852525552aa07), CONST64(0xc04760609d6027fd), CONST64(0x6535bcbccabc8976), CONST64(0x2b379b9b569baccd), CONST64(0x018a8e8e028e048c), CONST64(0x5bd2a3a3b6a37115), CONST64(0x186c0c0c300c603c), CONST64(0xf6847b7bf17bff8a), CONST64(0x6a803535d435b5e1), CONST64(0x3af51d1d741de869), CONST64(0xddb3e0e0a7e05347), CONST64(0xb321d7d77bd7f6ac), CONST64(0x999cc2c22fc25eed), CONST64(0x5c432e2eb82e6d96), CONST64(0x96294b4b314b627a), CONST64(0xe15dfefedffea321), CONST64(0xaed5575741578216), CONST64(0x2abd15155415a841), CONST64(0xeee87777c1779fb6), CONST64(0x6e923737dc37a5eb), CONST64(0xd79ee5e5b3e57b56), CONST64(0x23139f9f469f8cd9), CONST64(0xfd23f0f0e7f0d317), CONST64(0x94204a4a354a6a7f), CONST64(0xa944dada4fda9e95), CONST64(0xb0a258587d58fa25), CONST64(0x8fcfc9c903c906ca), CONST64(0x527c2929a429558d), CONST64(0x145a0a0a280a5022), CONST64(0x7f50b1b1feb1e14f), CONST64(0x5dc9a0a0baa0691a), CONST64(0xd6146b6bb16b7fda), CONST64(0x17d985852e855cab), CONST64(0x673cbdbdcebd8173), CONST64(0xba8f5d5d695dd234), CONST64(0x2090101040108050), CONST64(0xf507f4f4f7f4f303), CONST64(0x8bddcbcb0bcb16c0), CONST64(0x7cd33e3ef83eedc6), CONST64(0x0a2d050514052811), CONST64(0xce78676781671fe6), CONST64(0xd597e4e4b7e47353), CONST64(0x4e0227279c2725bb), CONST64(0x8273414119413258), CONST64(0x0ba78b8b168b2c9d), CONST64(0x53f6a7a7a6a75101), CONST64(0xfab27d7de97dcf94), CONST64(0x374995956e95dcfb), CONST64(0xad56d8d847d88e9f), CONST64(0xeb70fbfbcbfb8b30), CONST64(0xc1cdeeee9fee2371), CONST64(0xf8bb7c7ced7cc791), CONST64(0xcc716666856617e3), CONST64(0xa77bdddd53dda68e), CONST64(0x2eaf17175c17b84b), CONST64(0x8e45474701470246), CONST64(0x211a9e9e429e84dc), CONST64(0x89d4caca0fca1ec5), CONST64(0x5a582d2db42d7599), CONST64(0x632ebfbfc6bf9179), CONST64(0x0e3f07071c07381b), CONST64(0x47acadad8ead0123), CONST64(0xb4b05a5a755aea2f), CONST64(0x1bef838336836cb5), CONST64(0x66b63333cc3385ff), CONST64(0xc65c636391633ff2), CONST64(0x041202020802100a), CONST64(0x4993aaaa92aa3938), CONST64(0xe2de7171d971afa8), CONST64(0x8dc6c8c807c80ecf), CONST64(0x32d119196419c87d), CONST64(0x923b494939497270), CONST64(0xaf5fd9d943d9869a), CONST64(0xf931f2f2eff2c31d), CONST64(0xdba8e3e3abe34b48), CONST64(0xb6b95b5b715be22a), CONST64(0x0dbc88881a883492), CONST64(0x293e9a9a529aa4c8), CONST64(0x4c0b262698262dbe), CONST64(0x64bf3232c8328dfa), CONST64(0x7d59b0b0fab0e94a), CONST64(0xcff2e9e983e91b6a), CONST64(0x1e770f0f3c0f7833), CONST64(0xb733d5d573d5e6a6), CONST64(0x1df480803a8074ba), CONST64(0x6127bebec2be997c), CONST64(0x87ebcdcd13cd26de), CONST64(0x68893434d034bde4), CONST64(0x903248483d487a75), CONST64(0xe354ffffdbffab24), CONST64(0xf48d7a7af57af78f), CONST64(0x3d6490907a90f4ea), CONST64(0xbe9d5f5f615fc23e), CONST64(0x403d202080201da0), CONST64(0xd00f6868bd6867d5), CONST64(0x34ca1a1a681ad072), CONST64(0x41b7aeae82ae192c), CONST64(0x757db4b4eab4c95e), CONST64(0xa8ce54544d549a19), CONST64(0x3b7f93937693ece5), CONST64(0x442f222288220daa), CONST64(0xc86364648d6407e9), CONST64(0xff2af1f1e3f1db12), CONST64(0xe6cc7373d173bfa2), CONST64(0x248212124812905a), CONST64(0x807a40401d403a5d), CONST64(0x1048080820084028), CONST64(0x9b95c3c32bc356e8), CONST64(0xc5dfecec97ec337b), CONST64(0xab4ddbdb4bdb9690), CONST64(0x5fc0a1a1bea1611f), CONST64(0x07918d8d0e8d1c83), CONST64(0x7ac83d3df43df5c9), CONST64(0x335b97976697ccf1), CONST64(0x0000000000000000), CONST64(0x83f9cfcf1bcf36d4), CONST64(0x566e2b2bac2b4587), CONST64(0xece17676c57697b3), CONST64(0x19e68282328264b0), CONST64(0xb128d6d67fd6fea9), CONST64(0x36c31b1b6c1bd877), CONST64(0x7774b5b5eeb5c15b), CONST64(0x43beafaf86af1129), CONST64(0xd41d6a6ab56a77df), CONST64(0xa0ea50505d50ba0d), CONST64(0x8a5745450945124c), CONST64(0xfb38f3f3ebf3cb18), CONST64(0x60ad3030c0309df0), CONST64(0xc3c4efef9bef2b74), CONST64(0x7eda3f3ffc3fe5c3), CONST64(0xaac755554955921c), CONST64(0x59dba2a2b2a27910), CONST64(0xc9e9eaea8fea0365), CONST64(0xca6a656589650fec), CONST64(0x6903babad2bab968), CONST64(0x5e4a2f2fbc2f6593), CONST64(0x9d8ec0c027c04ee7), CONST64(0xa160dede5fdebe81), CONST64(0x38fc1c1c701ce06c), CONST64(0xe746fdfdd3fdbb2e), CONST64(0x9a1f4d4d294d5264), CONST64(0x397692927292e4e0), CONST64(0xeafa7575c9758fbc), CONST64(0x0c3606061806301e), CONST64(0x09ae8a8a128a2498), CONST64(0x794bb2b2f2b2f940), CONST64(0xd185e6e6bfe66359), CONST64(0x1c7e0e0e380e7036), CONST64(0x3ee71f1f7c1ff863), CONST64(0xc4556262956237f7), CONST64(0xb53ad4d477d4eea3), CONST64(0x4d81a8a89aa82932), CONST64(0x315296966296c4f4), CONST64(0xef62f9f9c3f99b3a), CONST64(0x97a3c5c533c566f6), CONST64(0x4a102525942535b1), CONST64(0xb2ab59597959f220), CONST64(0x15d084842a8454ae), CONST64(0xe4c57272d572b7a7), CONST64(0x72ec3939e439d5dd), CONST64(0x98164c4c2d4c5a61), CONST64(0xbc945e5e655eca3b), CONST64(0xf09f7878fd78e785), CONST64(0x70e53838e038ddd8), CONST64(0x05988c8c0a8c1486), CONST64(0xbf17d1d163d1c6b2), CONST64(0x57e4a5a5aea5410b), CONST64(0xd9a1e2e2afe2434d), CONST64(0xc24e616199612ff8), CONST64(0x7b42b3b3f6b3f145), CONST64(0x42342121842115a5), CONST64(0x25089c9c4a9c94d6), CONST64(0x3cee1e1e781ef066), CONST64(0x8661434311432252), CONST64(0x93b1c7c73bc776fc), CONST64(0xe54ffcfcd7fcb32b), CONST64(0x0824040410042014), CONST64(0xa2e351515951b208), CONST64(0x2f2599995e99bcc7), CONST64(0xda226d6da96d4fc4), CONST64(0x1a650d0d340d6839), CONST64(0xe979fafacffa8335), CONST64(0xa369dfdf5bdfb684), CONST64(0xfca97e7ee57ed79b), CONST64(0x4819242490243db4), CONST64(0x76fe3b3bec3bc5d7), CONST64(0x4b9aabab96ab313d), CONST64(0x81f0cece1fce3ed1), CONST64(0x2299111144118855), CONST64(0x03838f8f068f0c89), CONST64(0x9c044e4e254e4a6b), CONST64(0x7366b7b7e6b7d151), CONST64(0xcbe0ebeb8beb0b60), CONST64(0x78c13c3cf03cfdcc), CONST64(0x1ffd81813e817cbf), CONST64(0x354094946a94d4fe), CONST64(0xf31cf7f7fbf7eb0c), CONST64(0x6f18b9b9deb9a167), CONST64(0x268b13134c13985f), CONST64(0x58512c2cb02c7d9c), CONST64(0xbb05d3d36bd3d6b8), CONST64(0xd38ce7e7bbe76b5c), CONST64(0xdc396e6ea56e57cb), CONST64(0x95aac4c437c46ef3), CONST64(0x061b03030c03180f), CONST64(0xacdc565645568a13), CONST64(0x885e44440d441a49), CONST64(0xfea07f7fe17fdf9e), CONST64(0x4f88a9a99ea92137), CONST64(0x54672a2aa82a4d82), CONST64(0x6b0abbbbd6bbb16d), CONST64(0x9f87c1c123c146e2), CONST64(0xa6f153535153a202), CONST64(0xa572dcdc57dcae8b), CONST64(0x16530b0b2c0b5827), CONST64(0x27019d9d4e9d9cd3), CONST64(0xd82b6c6cad6c47c1), CONST64(0x62a43131c43195f5), CONST64(0xe8f37474cd7487b9), CONST64(0xf115f6f6fff6e309), CONST64(0x8c4c464605460a43), CONST64(0x45a5acac8aac0926), CONST64(0x0fb589891e893c97), CONST64(0x28b414145014a044), CONST64(0xdfbae1e1a3e15b42), CONST64(0x2ca616165816b04e), CONST64(0x74f73a3ae83acdd2), CONST64(0xd2066969b9696fd0), CONST64(0x124109092409482d), CONST64(0xe0d77070dd70a7ad), CONST64(0x716fb6b6e2b6d954), CONST64(0xbd1ed0d067d0ceb7), CONST64(0xc7d6eded93ed3b7e), CONST64(0x85e2cccc17cc2edb), CONST64(0x8468424215422a57), CONST64(0x2d2c98985a98b4c2), CONST64(0x55eda4a4aaa4490e), CONST64(0x50752828a0285d88), CONST64(0xb8865c5c6d5cda31), CONST64(0xed6bf8f8c7f8933f), CONST64(0x11c28686228644a4) }; static const ulong64 sbox3[] = { CONST64(0x7830d818186018c0), CONST64(0xaf462623238c2305), CONST64(0xf991b8c6c63fc67e), CONST64(0x6fcdfbe8e887e813), CONST64(0xa113cb878726874c), CONST64(0x626d11b8b8dab8a9), CONST64(0x0502090101040108), CONST64(0x6e9e0d4f4f214f42), CONST64(0xee6c9b3636d836ad), CONST64(0x0451ffa6a6a2a659), CONST64(0xbdb90cd2d26fd2de), CONST64(0x06f70ef5f5f3f5fb), CONST64(0x80f2967979f979ef), CONST64(0xcede306f6fa16f5f), CONST64(0xef3f6d91917e91fc), CONST64(0x07a4f852525552aa), CONST64(0xfdc04760609d6027), CONST64(0x766535bcbccabc89), CONST64(0xcd2b379b9b569bac), CONST64(0x8c018a8e8e028e04), CONST64(0x155bd2a3a3b6a371), CONST64(0x3c186c0c0c300c60), CONST64(0x8af6847b7bf17bff), CONST64(0xe16a803535d435b5), CONST64(0x693af51d1d741de8), CONST64(0x47ddb3e0e0a7e053), CONST64(0xacb321d7d77bd7f6), CONST64(0xed999cc2c22fc25e), CONST64(0x965c432e2eb82e6d), CONST64(0x7a96294b4b314b62), CONST64(0x21e15dfefedffea3), CONST64(0x16aed55757415782), CONST64(0x412abd15155415a8), CONST64(0xb6eee87777c1779f), CONST64(0xeb6e923737dc37a5), CONST64(0x56d79ee5e5b3e57b), CONST64(0xd923139f9f469f8c), CONST64(0x17fd23f0f0e7f0d3), CONST64(0x7f94204a4a354a6a), CONST64(0x95a944dada4fda9e), CONST64(0x25b0a258587d58fa), CONST64(0xca8fcfc9c903c906), CONST64(0x8d527c2929a42955), CONST64(0x22145a0a0a280a50), CONST64(0x4f7f50b1b1feb1e1), CONST64(0x1a5dc9a0a0baa069), CONST64(0xdad6146b6bb16b7f), CONST64(0xab17d985852e855c), CONST64(0x73673cbdbdcebd81), CONST64(0x34ba8f5d5d695dd2), CONST64(0x5020901010401080), CONST64(0x03f507f4f4f7f4f3), CONST64(0xc08bddcbcb0bcb16), CONST64(0xc67cd33e3ef83eed), CONST64(0x110a2d0505140528), CONST64(0xe6ce78676781671f), CONST64(0x53d597e4e4b7e473), CONST64(0xbb4e0227279c2725), CONST64(0x5882734141194132), CONST64(0x9d0ba78b8b168b2c), CONST64(0x0153f6a7a7a6a751), CONST64(0x94fab27d7de97dcf), CONST64(0xfb374995956e95dc), CONST64(0x9fad56d8d847d88e), CONST64(0x30eb70fbfbcbfb8b), CONST64(0x71c1cdeeee9fee23), CONST64(0x91f8bb7c7ced7cc7), CONST64(0xe3cc716666856617), CONST64(0x8ea77bdddd53dda6), CONST64(0x4b2eaf17175c17b8), CONST64(0x468e454747014702), CONST64(0xdc211a9e9e429e84), CONST64(0xc589d4caca0fca1e), CONST64(0x995a582d2db42d75), CONST64(0x79632ebfbfc6bf91), CONST64(0x1b0e3f07071c0738), CONST64(0x2347acadad8ead01), CONST64(0x2fb4b05a5a755aea), CONST64(0xb51bef838336836c), CONST64(0xff66b63333cc3385), CONST64(0xf2c65c636391633f), CONST64(0x0a04120202080210), CONST64(0x384993aaaa92aa39), CONST64(0xa8e2de7171d971af), CONST64(0xcf8dc6c8c807c80e), CONST64(0x7d32d119196419c8), CONST64(0x70923b4949394972), CONST64(0x9aaf5fd9d943d986), CONST64(0x1df931f2f2eff2c3), CONST64(0x48dba8e3e3abe34b), CONST64(0x2ab6b95b5b715be2), CONST64(0x920dbc88881a8834), CONST64(0xc8293e9a9a529aa4), CONST64(0xbe4c0b262698262d), CONST64(0xfa64bf3232c8328d), CONST64(0x4a7d59b0b0fab0e9), CONST64(0x6acff2e9e983e91b), CONST64(0x331e770f0f3c0f78), CONST64(0xa6b733d5d573d5e6), CONST64(0xba1df480803a8074), CONST64(0x7c6127bebec2be99), CONST64(0xde87ebcdcd13cd26), CONST64(0xe468893434d034bd), CONST64(0x75903248483d487a), CONST64(0x24e354ffffdbffab), CONST64(0x8ff48d7a7af57af7), CONST64(0xea3d6490907a90f4), CONST64(0x3ebe9d5f5f615fc2), CONST64(0xa0403d202080201d), CONST64(0xd5d00f6868bd6867), CONST64(0x7234ca1a1a681ad0), CONST64(0x2c41b7aeae82ae19), CONST64(0x5e757db4b4eab4c9), CONST64(0x19a8ce54544d549a), CONST64(0xe53b7f93937693ec), CONST64(0xaa442f222288220d), CONST64(0xe9c86364648d6407), CONST64(0x12ff2af1f1e3f1db), CONST64(0xa2e6cc7373d173bf), CONST64(0x5a24821212481290), CONST64(0x5d807a40401d403a), CONST64(0x2810480808200840), CONST64(0xe89b95c3c32bc356), CONST64(0x7bc5dfecec97ec33), CONST64(0x90ab4ddbdb4bdb96), CONST64(0x1f5fc0a1a1bea161), CONST64(0x8307918d8d0e8d1c), CONST64(0xc97ac83d3df43df5), CONST64(0xf1335b97976697cc), CONST64(0x0000000000000000), CONST64(0xd483f9cfcf1bcf36), CONST64(0x87566e2b2bac2b45), CONST64(0xb3ece17676c57697), CONST64(0xb019e68282328264), CONST64(0xa9b128d6d67fd6fe), CONST64(0x7736c31b1b6c1bd8), CONST64(0x5b7774b5b5eeb5c1), CONST64(0x2943beafaf86af11), CONST64(0xdfd41d6a6ab56a77), CONST64(0x0da0ea50505d50ba), CONST64(0x4c8a574545094512), CONST64(0x18fb38f3f3ebf3cb), CONST64(0xf060ad3030c0309d), CONST64(0x74c3c4efef9bef2b), CONST64(0xc37eda3f3ffc3fe5), CONST64(0x1caac75555495592), CONST64(0x1059dba2a2b2a279), CONST64(0x65c9e9eaea8fea03), CONST64(0xecca6a656589650f), CONST64(0x686903babad2bab9), CONST64(0x935e4a2f2fbc2f65), CONST64(0xe79d8ec0c027c04e), CONST64(0x81a160dede5fdebe), CONST64(0x6c38fc1c1c701ce0), CONST64(0x2ee746fdfdd3fdbb), CONST64(0x649a1f4d4d294d52), CONST64(0xe0397692927292e4), CONST64(0xbceafa7575c9758f), CONST64(0x1e0c360606180630), CONST64(0x9809ae8a8a128a24), CONST64(0x40794bb2b2f2b2f9), CONST64(0x59d185e6e6bfe663), CONST64(0x361c7e0e0e380e70), CONST64(0x633ee71f1f7c1ff8), CONST64(0xf7c4556262956237), CONST64(0xa3b53ad4d477d4ee), CONST64(0x324d81a8a89aa829), CONST64(0xf4315296966296c4), CONST64(0x3aef62f9f9c3f99b), CONST64(0xf697a3c5c533c566), CONST64(0xb14a102525942535), CONST64(0x20b2ab59597959f2), CONST64(0xae15d084842a8454), CONST64(0xa7e4c57272d572b7), CONST64(0xdd72ec3939e439d5), CONST64(0x6198164c4c2d4c5a), CONST64(0x3bbc945e5e655eca), CONST64(0x85f09f7878fd78e7), CONST64(0xd870e53838e038dd), CONST64(0x8605988c8c0a8c14), CONST64(0xb2bf17d1d163d1c6), CONST64(0x0b57e4a5a5aea541), CONST64(0x4dd9a1e2e2afe243), CONST64(0xf8c24e616199612f), CONST64(0x457b42b3b3f6b3f1), CONST64(0xa542342121842115), CONST64(0xd625089c9c4a9c94), CONST64(0x663cee1e1e781ef0), CONST64(0x5286614343114322), CONST64(0xfc93b1c7c73bc776), CONST64(0x2be54ffcfcd7fcb3), CONST64(0x1408240404100420), CONST64(0x08a2e351515951b2), CONST64(0xc72f2599995e99bc), CONST64(0xc4da226d6da96d4f), CONST64(0x391a650d0d340d68), CONST64(0x35e979fafacffa83), CONST64(0x84a369dfdf5bdfb6), CONST64(0x9bfca97e7ee57ed7), CONST64(0xb44819242490243d), CONST64(0xd776fe3b3bec3bc5), CONST64(0x3d4b9aabab96ab31), CONST64(0xd181f0cece1fce3e), CONST64(0x5522991111441188), CONST64(0x8903838f8f068f0c), CONST64(0x6b9c044e4e254e4a), CONST64(0x517366b7b7e6b7d1), CONST64(0x60cbe0ebeb8beb0b), CONST64(0xcc78c13c3cf03cfd), CONST64(0xbf1ffd81813e817c), CONST64(0xfe354094946a94d4), CONST64(0x0cf31cf7f7fbf7eb), CONST64(0x676f18b9b9deb9a1), CONST64(0x5f268b13134c1398), CONST64(0x9c58512c2cb02c7d), CONST64(0xb8bb05d3d36bd3d6), CONST64(0x5cd38ce7e7bbe76b), CONST64(0xcbdc396e6ea56e57), CONST64(0xf395aac4c437c46e), CONST64(0x0f061b03030c0318), CONST64(0x13acdc565645568a), CONST64(0x49885e44440d441a), CONST64(0x9efea07f7fe17fdf), CONST64(0x374f88a9a99ea921), CONST64(0x8254672a2aa82a4d), CONST64(0x6d6b0abbbbd6bbb1), CONST64(0xe29f87c1c123c146), CONST64(0x02a6f153535153a2), CONST64(0x8ba572dcdc57dcae), CONST64(0x2716530b0b2c0b58), CONST64(0xd327019d9d4e9d9c), CONST64(0xc1d82b6c6cad6c47), CONST64(0xf562a43131c43195), CONST64(0xb9e8f37474cd7487), CONST64(0x09f115f6f6fff6e3), CONST64(0x438c4c464605460a), CONST64(0x2645a5acac8aac09), CONST64(0x970fb589891e893c), CONST64(0x4428b414145014a0), CONST64(0x42dfbae1e1a3e15b), CONST64(0x4e2ca616165816b0), CONST64(0xd274f73a3ae83acd), CONST64(0xd0d2066969b9696f), CONST64(0x2d12410909240948), CONST64(0xade0d77070dd70a7), CONST64(0x54716fb6b6e2b6d9), CONST64(0xb7bd1ed0d067d0ce), CONST64(0x7ec7d6eded93ed3b), CONST64(0xdb85e2cccc17cc2e), CONST64(0x578468424215422a), CONST64(0xc22d2c98985a98b4), CONST64(0x0e55eda4a4aaa449), CONST64(0x8850752828a0285d), CONST64(0x31b8865c5c6d5cda), CONST64(0x3fed6bf8f8c7f893), CONST64(0xa411c28686228644) }; static const ulong64 sbox4[] = { CONST64(0xc07830d818186018), CONST64(0x05af462623238c23), CONST64(0x7ef991b8c6c63fc6), CONST64(0x136fcdfbe8e887e8), CONST64(0x4ca113cb87872687), CONST64(0xa9626d11b8b8dab8), CONST64(0x0805020901010401), CONST64(0x426e9e0d4f4f214f), CONST64(0xadee6c9b3636d836), CONST64(0x590451ffa6a6a2a6), CONST64(0xdebdb90cd2d26fd2), CONST64(0xfb06f70ef5f5f3f5), CONST64(0xef80f2967979f979), CONST64(0x5fcede306f6fa16f), CONST64(0xfcef3f6d91917e91), CONST64(0xaa07a4f852525552), CONST64(0x27fdc04760609d60), CONST64(0x89766535bcbccabc), CONST64(0xaccd2b379b9b569b), CONST64(0x048c018a8e8e028e), CONST64(0x71155bd2a3a3b6a3), CONST64(0x603c186c0c0c300c), CONST64(0xff8af6847b7bf17b), CONST64(0xb5e16a803535d435), CONST64(0xe8693af51d1d741d), CONST64(0x5347ddb3e0e0a7e0), CONST64(0xf6acb321d7d77bd7), CONST64(0x5eed999cc2c22fc2), CONST64(0x6d965c432e2eb82e), CONST64(0x627a96294b4b314b), CONST64(0xa321e15dfefedffe), CONST64(0x8216aed557574157), CONST64(0xa8412abd15155415), CONST64(0x9fb6eee87777c177), CONST64(0xa5eb6e923737dc37), CONST64(0x7b56d79ee5e5b3e5), CONST64(0x8cd923139f9f469f), CONST64(0xd317fd23f0f0e7f0), CONST64(0x6a7f94204a4a354a), CONST64(0x9e95a944dada4fda), CONST64(0xfa25b0a258587d58), CONST64(0x06ca8fcfc9c903c9), CONST64(0x558d527c2929a429), CONST64(0x5022145a0a0a280a), CONST64(0xe14f7f50b1b1feb1), CONST64(0x691a5dc9a0a0baa0), CONST64(0x7fdad6146b6bb16b), CONST64(0x5cab17d985852e85), CONST64(0x8173673cbdbdcebd), CONST64(0xd234ba8f5d5d695d), CONST64(0x8050209010104010), CONST64(0xf303f507f4f4f7f4), CONST64(0x16c08bddcbcb0bcb), CONST64(0xedc67cd33e3ef83e), CONST64(0x28110a2d05051405), CONST64(0x1fe6ce7867678167), CONST64(0x7353d597e4e4b7e4), CONST64(0x25bb4e0227279c27), CONST64(0x3258827341411941), CONST64(0x2c9d0ba78b8b168b), CONST64(0x510153f6a7a7a6a7), CONST64(0xcf94fab27d7de97d), CONST64(0xdcfb374995956e95), CONST64(0x8e9fad56d8d847d8), CONST64(0x8b30eb70fbfbcbfb), CONST64(0x2371c1cdeeee9fee), CONST64(0xc791f8bb7c7ced7c), CONST64(0x17e3cc7166668566), CONST64(0xa68ea77bdddd53dd), CONST64(0xb84b2eaf17175c17), CONST64(0x02468e4547470147), CONST64(0x84dc211a9e9e429e), CONST64(0x1ec589d4caca0fca), CONST64(0x75995a582d2db42d), CONST64(0x9179632ebfbfc6bf), CONST64(0x381b0e3f07071c07), CONST64(0x012347acadad8ead), CONST64(0xea2fb4b05a5a755a), CONST64(0x6cb51bef83833683), CONST64(0x85ff66b63333cc33), CONST64(0x3ff2c65c63639163), CONST64(0x100a041202020802), CONST64(0x39384993aaaa92aa), CONST64(0xafa8e2de7171d971), CONST64(0x0ecf8dc6c8c807c8), CONST64(0xc87d32d119196419), CONST64(0x7270923b49493949), CONST64(0x869aaf5fd9d943d9), CONST64(0xc31df931f2f2eff2), CONST64(0x4b48dba8e3e3abe3), CONST64(0xe22ab6b95b5b715b), CONST64(0x34920dbc88881a88), CONST64(0xa4c8293e9a9a529a), CONST64(0x2dbe4c0b26269826), CONST64(0x8dfa64bf3232c832), CONST64(0xe94a7d59b0b0fab0), CONST64(0x1b6acff2e9e983e9), CONST64(0x78331e770f0f3c0f), CONST64(0xe6a6b733d5d573d5), CONST64(0x74ba1df480803a80), CONST64(0x997c6127bebec2be), CONST64(0x26de87ebcdcd13cd), CONST64(0xbde468893434d034), CONST64(0x7a75903248483d48), CONST64(0xab24e354ffffdbff), CONST64(0xf78ff48d7a7af57a), CONST64(0xf4ea3d6490907a90), CONST64(0xc23ebe9d5f5f615f), CONST64(0x1da0403d20208020), CONST64(0x67d5d00f6868bd68), CONST64(0xd07234ca1a1a681a), CONST64(0x192c41b7aeae82ae), CONST64(0xc95e757db4b4eab4), CONST64(0x9a19a8ce54544d54), CONST64(0xece53b7f93937693), CONST64(0x0daa442f22228822), CONST64(0x07e9c86364648d64), CONST64(0xdb12ff2af1f1e3f1), CONST64(0xbfa2e6cc7373d173), CONST64(0x905a248212124812), CONST64(0x3a5d807a40401d40), CONST64(0x4028104808082008), CONST64(0x56e89b95c3c32bc3), CONST64(0x337bc5dfecec97ec), CONST64(0x9690ab4ddbdb4bdb), CONST64(0x611f5fc0a1a1bea1), CONST64(0x1c8307918d8d0e8d), CONST64(0xf5c97ac83d3df43d), CONST64(0xccf1335b97976697), CONST64(0x0000000000000000), CONST64(0x36d483f9cfcf1bcf), CONST64(0x4587566e2b2bac2b), CONST64(0x97b3ece17676c576), CONST64(0x64b019e682823282), CONST64(0xfea9b128d6d67fd6), CONST64(0xd87736c31b1b6c1b), CONST64(0xc15b7774b5b5eeb5), CONST64(0x112943beafaf86af), CONST64(0x77dfd41d6a6ab56a), CONST64(0xba0da0ea50505d50), CONST64(0x124c8a5745450945), CONST64(0xcb18fb38f3f3ebf3), CONST64(0x9df060ad3030c030), CONST64(0x2b74c3c4efef9bef), CONST64(0xe5c37eda3f3ffc3f), CONST64(0x921caac755554955), CONST64(0x791059dba2a2b2a2), CONST64(0x0365c9e9eaea8fea), CONST64(0x0fecca6a65658965), CONST64(0xb9686903babad2ba), CONST64(0x65935e4a2f2fbc2f), CONST64(0x4ee79d8ec0c027c0), CONST64(0xbe81a160dede5fde), CONST64(0xe06c38fc1c1c701c), CONST64(0xbb2ee746fdfdd3fd), CONST64(0x52649a1f4d4d294d), CONST64(0xe4e0397692927292), CONST64(0x8fbceafa7575c975), CONST64(0x301e0c3606061806), CONST64(0x249809ae8a8a128a), CONST64(0xf940794bb2b2f2b2), CONST64(0x6359d185e6e6bfe6), CONST64(0x70361c7e0e0e380e), CONST64(0xf8633ee71f1f7c1f), CONST64(0x37f7c45562629562), CONST64(0xeea3b53ad4d477d4), CONST64(0x29324d81a8a89aa8), CONST64(0xc4f4315296966296), CONST64(0x9b3aef62f9f9c3f9), CONST64(0x66f697a3c5c533c5), CONST64(0x35b14a1025259425), CONST64(0xf220b2ab59597959), CONST64(0x54ae15d084842a84), CONST64(0xb7a7e4c57272d572), CONST64(0xd5dd72ec3939e439), CONST64(0x5a6198164c4c2d4c), CONST64(0xca3bbc945e5e655e), CONST64(0xe785f09f7878fd78), CONST64(0xddd870e53838e038), CONST64(0x148605988c8c0a8c), CONST64(0xc6b2bf17d1d163d1), CONST64(0x410b57e4a5a5aea5), CONST64(0x434dd9a1e2e2afe2), CONST64(0x2ff8c24e61619961), CONST64(0xf1457b42b3b3f6b3), CONST64(0x15a5423421218421), CONST64(0x94d625089c9c4a9c), CONST64(0xf0663cee1e1e781e), CONST64(0x2252866143431143), CONST64(0x76fc93b1c7c73bc7), CONST64(0xb32be54ffcfcd7fc), CONST64(0x2014082404041004), CONST64(0xb208a2e351515951), CONST64(0xbcc72f2599995e99), CONST64(0x4fc4da226d6da96d), CONST64(0x68391a650d0d340d), CONST64(0x8335e979fafacffa), CONST64(0xb684a369dfdf5bdf), CONST64(0xd79bfca97e7ee57e), CONST64(0x3db4481924249024), CONST64(0xc5d776fe3b3bec3b), CONST64(0x313d4b9aabab96ab), CONST64(0x3ed181f0cece1fce), CONST64(0x8855229911114411), CONST64(0x0c8903838f8f068f), CONST64(0x4a6b9c044e4e254e), CONST64(0xd1517366b7b7e6b7), CONST64(0x0b60cbe0ebeb8beb), CONST64(0xfdcc78c13c3cf03c), CONST64(0x7cbf1ffd81813e81), CONST64(0xd4fe354094946a94), CONST64(0xeb0cf31cf7f7fbf7), CONST64(0xa1676f18b9b9deb9), CONST64(0x985f268b13134c13), CONST64(0x7d9c58512c2cb02c), CONST64(0xd6b8bb05d3d36bd3), CONST64(0x6b5cd38ce7e7bbe7), CONST64(0x57cbdc396e6ea56e), CONST64(0x6ef395aac4c437c4), CONST64(0x180f061b03030c03), CONST64(0x8a13acdc56564556), CONST64(0x1a49885e44440d44), CONST64(0xdf9efea07f7fe17f), CONST64(0x21374f88a9a99ea9), CONST64(0x4d8254672a2aa82a), CONST64(0xb16d6b0abbbbd6bb), CONST64(0x46e29f87c1c123c1), CONST64(0xa202a6f153535153), CONST64(0xae8ba572dcdc57dc), CONST64(0x582716530b0b2c0b), CONST64(0x9cd327019d9d4e9d), CONST64(0x47c1d82b6c6cad6c), CONST64(0x95f562a43131c431), CONST64(0x87b9e8f37474cd74), CONST64(0xe309f115f6f6fff6), CONST64(0x0a438c4c46460546), CONST64(0x092645a5acac8aac), CONST64(0x3c970fb589891e89), CONST64(0xa04428b414145014), CONST64(0x5b42dfbae1e1a3e1), CONST64(0xb04e2ca616165816), CONST64(0xcdd274f73a3ae83a), CONST64(0x6fd0d2066969b969), CONST64(0x482d124109092409), CONST64(0xa7ade0d77070dd70), CONST64(0xd954716fb6b6e2b6), CONST64(0xceb7bd1ed0d067d0), CONST64(0x3b7ec7d6eded93ed), CONST64(0x2edb85e2cccc17cc), CONST64(0x2a57846842421542), CONST64(0xb4c22d2c98985a98), CONST64(0x490e55eda4a4aaa4), CONST64(0x5d8850752828a028), CONST64(0xda31b8865c5c6d5c), CONST64(0x933fed6bf8f8c7f8), CONST64(0x44a411c286862286) }; static const ulong64 sbox5[] = { CONST64(0x18c07830d8181860), CONST64(0x2305af462623238c), CONST64(0xc67ef991b8c6c63f), CONST64(0xe8136fcdfbe8e887), CONST64(0x874ca113cb878726), CONST64(0xb8a9626d11b8b8da), CONST64(0x0108050209010104), CONST64(0x4f426e9e0d4f4f21), CONST64(0x36adee6c9b3636d8), CONST64(0xa6590451ffa6a6a2), CONST64(0xd2debdb90cd2d26f), CONST64(0xf5fb06f70ef5f5f3), CONST64(0x79ef80f2967979f9), CONST64(0x6f5fcede306f6fa1), CONST64(0x91fcef3f6d91917e), CONST64(0x52aa07a4f8525255), CONST64(0x6027fdc04760609d), CONST64(0xbc89766535bcbcca), CONST64(0x9baccd2b379b9b56), CONST64(0x8e048c018a8e8e02), CONST64(0xa371155bd2a3a3b6), CONST64(0x0c603c186c0c0c30), CONST64(0x7bff8af6847b7bf1), CONST64(0x35b5e16a803535d4), CONST64(0x1de8693af51d1d74), CONST64(0xe05347ddb3e0e0a7), CONST64(0xd7f6acb321d7d77b), CONST64(0xc25eed999cc2c22f), CONST64(0x2e6d965c432e2eb8), CONST64(0x4b627a96294b4b31), CONST64(0xfea321e15dfefedf), CONST64(0x578216aed5575741), CONST64(0x15a8412abd151554), CONST64(0x779fb6eee87777c1), CONST64(0x37a5eb6e923737dc), CONST64(0xe57b56d79ee5e5b3), CONST64(0x9f8cd923139f9f46), CONST64(0xf0d317fd23f0f0e7), CONST64(0x4a6a7f94204a4a35), CONST64(0xda9e95a944dada4f), CONST64(0x58fa25b0a258587d), CONST64(0xc906ca8fcfc9c903), CONST64(0x29558d527c2929a4), CONST64(0x0a5022145a0a0a28), CONST64(0xb1e14f7f50b1b1fe), CONST64(0xa0691a5dc9a0a0ba), CONST64(0x6b7fdad6146b6bb1), CONST64(0x855cab17d985852e), CONST64(0xbd8173673cbdbdce), CONST64(0x5dd234ba8f5d5d69), CONST64(0x1080502090101040), CONST64(0xf4f303f507f4f4f7), CONST64(0xcb16c08bddcbcb0b), CONST64(0x3eedc67cd33e3ef8), CONST64(0x0528110a2d050514), CONST64(0x671fe6ce78676781), CONST64(0xe47353d597e4e4b7), CONST64(0x2725bb4e0227279c), CONST64(0x4132588273414119), CONST64(0x8b2c9d0ba78b8b16), CONST64(0xa7510153f6a7a7a6), CONST64(0x7dcf94fab27d7de9), CONST64(0x95dcfb374995956e), CONST64(0xd88e9fad56d8d847), CONST64(0xfb8b30eb70fbfbcb), CONST64(0xee2371c1cdeeee9f), CONST64(0x7cc791f8bb7c7ced), CONST64(0x6617e3cc71666685), CONST64(0xdda68ea77bdddd53), CONST64(0x17b84b2eaf17175c), CONST64(0x4702468e45474701), CONST64(0x9e84dc211a9e9e42), CONST64(0xca1ec589d4caca0f), CONST64(0x2d75995a582d2db4), CONST64(0xbf9179632ebfbfc6), CONST64(0x07381b0e3f07071c), CONST64(0xad012347acadad8e), CONST64(0x5aea2fb4b05a5a75), CONST64(0x836cb51bef838336), CONST64(0x3385ff66b63333cc), CONST64(0x633ff2c65c636391), CONST64(0x02100a0412020208), CONST64(0xaa39384993aaaa92), CONST64(0x71afa8e2de7171d9), CONST64(0xc80ecf8dc6c8c807), CONST64(0x19c87d32d1191964), CONST64(0x497270923b494939), CONST64(0xd9869aaf5fd9d943), CONST64(0xf2c31df931f2f2ef), CONST64(0xe34b48dba8e3e3ab), CONST64(0x5be22ab6b95b5b71), CONST64(0x8834920dbc88881a), CONST64(0x9aa4c8293e9a9a52), CONST64(0x262dbe4c0b262698), CONST64(0x328dfa64bf3232c8), CONST64(0xb0e94a7d59b0b0fa), CONST64(0xe91b6acff2e9e983), CONST64(0x0f78331e770f0f3c), CONST64(0xd5e6a6b733d5d573), CONST64(0x8074ba1df480803a), CONST64(0xbe997c6127bebec2), CONST64(0xcd26de87ebcdcd13), CONST64(0x34bde468893434d0), CONST64(0x487a75903248483d), CONST64(0xffab24e354ffffdb), CONST64(0x7af78ff48d7a7af5), CONST64(0x90f4ea3d6490907a), CONST64(0x5fc23ebe9d5f5f61), CONST64(0x201da0403d202080), CONST64(0x6867d5d00f6868bd), CONST64(0x1ad07234ca1a1a68), CONST64(0xae192c41b7aeae82), CONST64(0xb4c95e757db4b4ea), CONST64(0x549a19a8ce54544d), CONST64(0x93ece53b7f939376), CONST64(0x220daa442f222288), CONST64(0x6407e9c86364648d), CONST64(0xf1db12ff2af1f1e3), CONST64(0x73bfa2e6cc7373d1), CONST64(0x12905a2482121248), CONST64(0x403a5d807a40401d), CONST64(0x0840281048080820), CONST64(0xc356e89b95c3c32b), CONST64(0xec337bc5dfecec97), CONST64(0xdb9690ab4ddbdb4b), CONST64(0xa1611f5fc0a1a1be), CONST64(0x8d1c8307918d8d0e), CONST64(0x3df5c97ac83d3df4), CONST64(0x97ccf1335b979766), CONST64(0x0000000000000000), CONST64(0xcf36d483f9cfcf1b), CONST64(0x2b4587566e2b2bac), CONST64(0x7697b3ece17676c5), CONST64(0x8264b019e6828232), CONST64(0xd6fea9b128d6d67f), CONST64(0x1bd87736c31b1b6c), CONST64(0xb5c15b7774b5b5ee), CONST64(0xaf112943beafaf86), CONST64(0x6a77dfd41d6a6ab5), CONST64(0x50ba0da0ea50505d), CONST64(0x45124c8a57454509), CONST64(0xf3cb18fb38f3f3eb), CONST64(0x309df060ad3030c0), CONST64(0xef2b74c3c4efef9b), CONST64(0x3fe5c37eda3f3ffc), CONST64(0x55921caac7555549), CONST64(0xa2791059dba2a2b2), CONST64(0xea0365c9e9eaea8f), CONST64(0x650fecca6a656589), CONST64(0xbab9686903babad2), CONST64(0x2f65935e4a2f2fbc), CONST64(0xc04ee79d8ec0c027), CONST64(0xdebe81a160dede5f), CONST64(0x1ce06c38fc1c1c70), CONST64(0xfdbb2ee746fdfdd3), CONST64(0x4d52649a1f4d4d29), CONST64(0x92e4e03976929272), CONST64(0x758fbceafa7575c9), CONST64(0x06301e0c36060618), CONST64(0x8a249809ae8a8a12), CONST64(0xb2f940794bb2b2f2), CONST64(0xe66359d185e6e6bf), CONST64(0x0e70361c7e0e0e38), CONST64(0x1ff8633ee71f1f7c), CONST64(0x6237f7c455626295), CONST64(0xd4eea3b53ad4d477), CONST64(0xa829324d81a8a89a), CONST64(0x96c4f43152969662), CONST64(0xf99b3aef62f9f9c3), CONST64(0xc566f697a3c5c533), CONST64(0x2535b14a10252594), CONST64(0x59f220b2ab595979), CONST64(0x8454ae15d084842a), CONST64(0x72b7a7e4c57272d5), CONST64(0x39d5dd72ec3939e4), CONST64(0x4c5a6198164c4c2d), CONST64(0x5eca3bbc945e5e65), CONST64(0x78e785f09f7878fd), CONST64(0x38ddd870e53838e0), CONST64(0x8c148605988c8c0a), CONST64(0xd1c6b2bf17d1d163), CONST64(0xa5410b57e4a5a5ae), CONST64(0xe2434dd9a1e2e2af), CONST64(0x612ff8c24e616199), CONST64(0xb3f1457b42b3b3f6), CONST64(0x2115a54234212184), CONST64(0x9c94d625089c9c4a), CONST64(0x1ef0663cee1e1e78), CONST64(0x4322528661434311), CONST64(0xc776fc93b1c7c73b), CONST64(0xfcb32be54ffcfcd7), CONST64(0x0420140824040410), CONST64(0x51b208a2e3515159), CONST64(0x99bcc72f2599995e), CONST64(0x6d4fc4da226d6da9), CONST64(0x0d68391a650d0d34), CONST64(0xfa8335e979fafacf), CONST64(0xdfb684a369dfdf5b), CONST64(0x7ed79bfca97e7ee5), CONST64(0x243db44819242490), CONST64(0x3bc5d776fe3b3bec), CONST64(0xab313d4b9aabab96), CONST64(0xce3ed181f0cece1f), CONST64(0x1188552299111144), CONST64(0x8f0c8903838f8f06), CONST64(0x4e4a6b9c044e4e25), CONST64(0xb7d1517366b7b7e6), CONST64(0xeb0b60cbe0ebeb8b), CONST64(0x3cfdcc78c13c3cf0), CONST64(0x817cbf1ffd81813e), CONST64(0x94d4fe354094946a), CONST64(0xf7eb0cf31cf7f7fb), CONST64(0xb9a1676f18b9b9de), CONST64(0x13985f268b13134c), CONST64(0x2c7d9c58512c2cb0), CONST64(0xd3d6b8bb05d3d36b), CONST64(0xe76b5cd38ce7e7bb), CONST64(0x6e57cbdc396e6ea5), CONST64(0xc46ef395aac4c437), CONST64(0x03180f061b03030c), CONST64(0x568a13acdc565645), CONST64(0x441a49885e44440d), CONST64(0x7fdf9efea07f7fe1), CONST64(0xa921374f88a9a99e), CONST64(0x2a4d8254672a2aa8), CONST64(0xbbb16d6b0abbbbd6), CONST64(0xc146e29f87c1c123), CONST64(0x53a202a6f1535351), CONST64(0xdcae8ba572dcdc57), CONST64(0x0b582716530b0b2c), CONST64(0x9d9cd327019d9d4e), CONST64(0x6c47c1d82b6c6cad), CONST64(0x3195f562a43131c4), CONST64(0x7487b9e8f37474cd), CONST64(0xf6e309f115f6f6ff), CONST64(0x460a438c4c464605), CONST64(0xac092645a5acac8a), CONST64(0x893c970fb589891e), CONST64(0x14a04428b4141450), CONST64(0xe15b42dfbae1e1a3), CONST64(0x16b04e2ca6161658), CONST64(0x3acdd274f73a3ae8), CONST64(0x696fd0d2066969b9), CONST64(0x09482d1241090924), CONST64(0x70a7ade0d77070dd), CONST64(0xb6d954716fb6b6e2), CONST64(0xd0ceb7bd1ed0d067), CONST64(0xed3b7ec7d6eded93), CONST64(0xcc2edb85e2cccc17), CONST64(0x422a578468424215), CONST64(0x98b4c22d2c98985a), CONST64(0xa4490e55eda4a4aa), CONST64(0x285d8850752828a0), CONST64(0x5cda31b8865c5c6d), CONST64(0xf8933fed6bf8f8c7), CONST64(0x8644a411c2868622) }; static const ulong64 sbox6[] = { CONST64(0x6018c07830d81818), CONST64(0x8c2305af46262323), CONST64(0x3fc67ef991b8c6c6), CONST64(0x87e8136fcdfbe8e8), CONST64(0x26874ca113cb8787), CONST64(0xdab8a9626d11b8b8), CONST64(0x0401080502090101), CONST64(0x214f426e9e0d4f4f), CONST64(0xd836adee6c9b3636), CONST64(0xa2a6590451ffa6a6), CONST64(0x6fd2debdb90cd2d2), CONST64(0xf3f5fb06f70ef5f5), CONST64(0xf979ef80f2967979), CONST64(0xa16f5fcede306f6f), CONST64(0x7e91fcef3f6d9191), CONST64(0x5552aa07a4f85252), CONST64(0x9d6027fdc0476060), CONST64(0xcabc89766535bcbc), CONST64(0x569baccd2b379b9b), CONST64(0x028e048c018a8e8e), CONST64(0xb6a371155bd2a3a3), CONST64(0x300c603c186c0c0c), CONST64(0xf17bff8af6847b7b), CONST64(0xd435b5e16a803535), CONST64(0x741de8693af51d1d), CONST64(0xa7e05347ddb3e0e0), CONST64(0x7bd7f6acb321d7d7), CONST64(0x2fc25eed999cc2c2), CONST64(0xb82e6d965c432e2e), CONST64(0x314b627a96294b4b), CONST64(0xdffea321e15dfefe), CONST64(0x41578216aed55757), CONST64(0x5415a8412abd1515), CONST64(0xc1779fb6eee87777), CONST64(0xdc37a5eb6e923737), CONST64(0xb3e57b56d79ee5e5), CONST64(0x469f8cd923139f9f), CONST64(0xe7f0d317fd23f0f0), CONST64(0x354a6a7f94204a4a), CONST64(0x4fda9e95a944dada), CONST64(0x7d58fa25b0a25858), CONST64(0x03c906ca8fcfc9c9), CONST64(0xa429558d527c2929), CONST64(0x280a5022145a0a0a), CONST64(0xfeb1e14f7f50b1b1), CONST64(0xbaa0691a5dc9a0a0), CONST64(0xb16b7fdad6146b6b), CONST64(0x2e855cab17d98585), CONST64(0xcebd8173673cbdbd), CONST64(0x695dd234ba8f5d5d), CONST64(0x4010805020901010), CONST64(0xf7f4f303f507f4f4), CONST64(0x0bcb16c08bddcbcb), CONST64(0xf83eedc67cd33e3e), CONST64(0x140528110a2d0505), CONST64(0x81671fe6ce786767), CONST64(0xb7e47353d597e4e4), CONST64(0x9c2725bb4e022727), CONST64(0x1941325882734141), CONST64(0x168b2c9d0ba78b8b), CONST64(0xa6a7510153f6a7a7), CONST64(0xe97dcf94fab27d7d), CONST64(0x6e95dcfb37499595), CONST64(0x47d88e9fad56d8d8), CONST64(0xcbfb8b30eb70fbfb), CONST64(0x9fee2371c1cdeeee), CONST64(0xed7cc791f8bb7c7c), CONST64(0x856617e3cc716666), CONST64(0x53dda68ea77bdddd), CONST64(0x5c17b84b2eaf1717), CONST64(0x014702468e454747), CONST64(0x429e84dc211a9e9e), CONST64(0x0fca1ec589d4caca), CONST64(0xb42d75995a582d2d), CONST64(0xc6bf9179632ebfbf), CONST64(0x1c07381b0e3f0707), CONST64(0x8ead012347acadad), CONST64(0x755aea2fb4b05a5a), CONST64(0x36836cb51bef8383), CONST64(0xcc3385ff66b63333), CONST64(0x91633ff2c65c6363), CONST64(0x0802100a04120202), CONST64(0x92aa39384993aaaa), CONST64(0xd971afa8e2de7171), CONST64(0x07c80ecf8dc6c8c8), CONST64(0x6419c87d32d11919), CONST64(0x39497270923b4949), CONST64(0x43d9869aaf5fd9d9), CONST64(0xeff2c31df931f2f2), CONST64(0xabe34b48dba8e3e3), CONST64(0x715be22ab6b95b5b), CONST64(0x1a8834920dbc8888), CONST64(0x529aa4c8293e9a9a), CONST64(0x98262dbe4c0b2626), CONST64(0xc8328dfa64bf3232), CONST64(0xfab0e94a7d59b0b0), CONST64(0x83e91b6acff2e9e9), CONST64(0x3c0f78331e770f0f), CONST64(0x73d5e6a6b733d5d5), CONST64(0x3a8074ba1df48080), CONST64(0xc2be997c6127bebe), CONST64(0x13cd26de87ebcdcd), CONST64(0xd034bde468893434), CONST64(0x3d487a7590324848), CONST64(0xdbffab24e354ffff), CONST64(0xf57af78ff48d7a7a), CONST64(0x7a90f4ea3d649090), CONST64(0x615fc23ebe9d5f5f), CONST64(0x80201da0403d2020), CONST64(0xbd6867d5d00f6868), CONST64(0x681ad07234ca1a1a), CONST64(0x82ae192c41b7aeae), CONST64(0xeab4c95e757db4b4), CONST64(0x4d549a19a8ce5454), CONST64(0x7693ece53b7f9393), CONST64(0x88220daa442f2222), CONST64(0x8d6407e9c8636464), CONST64(0xe3f1db12ff2af1f1), CONST64(0xd173bfa2e6cc7373), CONST64(0x4812905a24821212), CONST64(0x1d403a5d807a4040), CONST64(0x2008402810480808), CONST64(0x2bc356e89b95c3c3), CONST64(0x97ec337bc5dfecec), CONST64(0x4bdb9690ab4ddbdb), CONST64(0xbea1611f5fc0a1a1), CONST64(0x0e8d1c8307918d8d), CONST64(0xf43df5c97ac83d3d), CONST64(0x6697ccf1335b9797), CONST64(0x0000000000000000), CONST64(0x1bcf36d483f9cfcf), CONST64(0xac2b4587566e2b2b), CONST64(0xc57697b3ece17676), CONST64(0x328264b019e68282), CONST64(0x7fd6fea9b128d6d6), CONST64(0x6c1bd87736c31b1b), CONST64(0xeeb5c15b7774b5b5), CONST64(0x86af112943beafaf), CONST64(0xb56a77dfd41d6a6a), CONST64(0x5d50ba0da0ea5050), CONST64(0x0945124c8a574545), CONST64(0xebf3cb18fb38f3f3), CONST64(0xc0309df060ad3030), CONST64(0x9bef2b74c3c4efef), CONST64(0xfc3fe5c37eda3f3f), CONST64(0x4955921caac75555), CONST64(0xb2a2791059dba2a2), CONST64(0x8fea0365c9e9eaea), CONST64(0x89650fecca6a6565), CONST64(0xd2bab9686903baba), CONST64(0xbc2f65935e4a2f2f), CONST64(0x27c04ee79d8ec0c0), CONST64(0x5fdebe81a160dede), CONST64(0x701ce06c38fc1c1c), CONST64(0xd3fdbb2ee746fdfd), CONST64(0x294d52649a1f4d4d), CONST64(0x7292e4e039769292), CONST64(0xc9758fbceafa7575), CONST64(0x1806301e0c360606), CONST64(0x128a249809ae8a8a), CONST64(0xf2b2f940794bb2b2), CONST64(0xbfe66359d185e6e6), CONST64(0x380e70361c7e0e0e), CONST64(0x7c1ff8633ee71f1f), CONST64(0x956237f7c4556262), CONST64(0x77d4eea3b53ad4d4), CONST64(0x9aa829324d81a8a8), CONST64(0x6296c4f431529696), CONST64(0xc3f99b3aef62f9f9), CONST64(0x33c566f697a3c5c5), CONST64(0x942535b14a102525), CONST64(0x7959f220b2ab5959), CONST64(0x2a8454ae15d08484), CONST64(0xd572b7a7e4c57272), CONST64(0xe439d5dd72ec3939), CONST64(0x2d4c5a6198164c4c), CONST64(0x655eca3bbc945e5e), CONST64(0xfd78e785f09f7878), CONST64(0xe038ddd870e53838), CONST64(0x0a8c148605988c8c), CONST64(0x63d1c6b2bf17d1d1), CONST64(0xaea5410b57e4a5a5), CONST64(0xafe2434dd9a1e2e2), CONST64(0x99612ff8c24e6161), CONST64(0xf6b3f1457b42b3b3), CONST64(0x842115a542342121), CONST64(0x4a9c94d625089c9c), CONST64(0x781ef0663cee1e1e), CONST64(0x1143225286614343), CONST64(0x3bc776fc93b1c7c7), CONST64(0xd7fcb32be54ffcfc), CONST64(0x1004201408240404), CONST64(0x5951b208a2e35151), CONST64(0x5e99bcc72f259999), CONST64(0xa96d4fc4da226d6d), CONST64(0x340d68391a650d0d), CONST64(0xcffa8335e979fafa), CONST64(0x5bdfb684a369dfdf), CONST64(0xe57ed79bfca97e7e), CONST64(0x90243db448192424), CONST64(0xec3bc5d776fe3b3b), CONST64(0x96ab313d4b9aabab), CONST64(0x1fce3ed181f0cece), CONST64(0x4411885522991111), CONST64(0x068f0c8903838f8f), CONST64(0x254e4a6b9c044e4e), CONST64(0xe6b7d1517366b7b7), CONST64(0x8beb0b60cbe0ebeb), CONST64(0xf03cfdcc78c13c3c), CONST64(0x3e817cbf1ffd8181), CONST64(0x6a94d4fe35409494), CONST64(0xfbf7eb0cf31cf7f7), CONST64(0xdeb9a1676f18b9b9), CONST64(0x4c13985f268b1313), CONST64(0xb02c7d9c58512c2c), CONST64(0x6bd3d6b8bb05d3d3), CONST64(0xbbe76b5cd38ce7e7), CONST64(0xa56e57cbdc396e6e), CONST64(0x37c46ef395aac4c4), CONST64(0x0c03180f061b0303), CONST64(0x45568a13acdc5656), CONST64(0x0d441a49885e4444), CONST64(0xe17fdf9efea07f7f), CONST64(0x9ea921374f88a9a9), CONST64(0xa82a4d8254672a2a), CONST64(0xd6bbb16d6b0abbbb), CONST64(0x23c146e29f87c1c1), CONST64(0x5153a202a6f15353), CONST64(0x57dcae8ba572dcdc), CONST64(0x2c0b582716530b0b), CONST64(0x4e9d9cd327019d9d), CONST64(0xad6c47c1d82b6c6c), CONST64(0xc43195f562a43131), CONST64(0xcd7487b9e8f37474), CONST64(0xfff6e309f115f6f6), CONST64(0x05460a438c4c4646), CONST64(0x8aac092645a5acac), CONST64(0x1e893c970fb58989), CONST64(0x5014a04428b41414), CONST64(0xa3e15b42dfbae1e1), CONST64(0x5816b04e2ca61616), CONST64(0xe83acdd274f73a3a), CONST64(0xb9696fd0d2066969), CONST64(0x2409482d12410909), CONST64(0xdd70a7ade0d77070), CONST64(0xe2b6d954716fb6b6), CONST64(0x67d0ceb7bd1ed0d0), CONST64(0x93ed3b7ec7d6eded), CONST64(0x17cc2edb85e2cccc), CONST64(0x15422a5784684242), CONST64(0x5a98b4c22d2c9898), CONST64(0xaaa4490e55eda4a4), CONST64(0xa0285d8850752828), CONST64(0x6d5cda31b8865c5c), CONST64(0xc7f8933fed6bf8f8), CONST64(0x228644a411c28686) }; static const ulong64 sbox7[] = { CONST64(0x186018c07830d818), CONST64(0x238c2305af462623), CONST64(0xc63fc67ef991b8c6), CONST64(0xe887e8136fcdfbe8), CONST64(0x8726874ca113cb87), CONST64(0xb8dab8a9626d11b8), CONST64(0x0104010805020901), CONST64(0x4f214f426e9e0d4f), CONST64(0x36d836adee6c9b36), CONST64(0xa6a2a6590451ffa6), CONST64(0xd26fd2debdb90cd2), CONST64(0xf5f3f5fb06f70ef5), CONST64(0x79f979ef80f29679), CONST64(0x6fa16f5fcede306f), CONST64(0x917e91fcef3f6d91), CONST64(0x525552aa07a4f852), CONST64(0x609d6027fdc04760), CONST64(0xbccabc89766535bc), CONST64(0x9b569baccd2b379b), CONST64(0x8e028e048c018a8e), CONST64(0xa3b6a371155bd2a3), CONST64(0x0c300c603c186c0c), CONST64(0x7bf17bff8af6847b), CONST64(0x35d435b5e16a8035), CONST64(0x1d741de8693af51d), CONST64(0xe0a7e05347ddb3e0), CONST64(0xd77bd7f6acb321d7), CONST64(0xc22fc25eed999cc2), CONST64(0x2eb82e6d965c432e), CONST64(0x4b314b627a96294b), CONST64(0xfedffea321e15dfe), CONST64(0x5741578216aed557), CONST64(0x155415a8412abd15), CONST64(0x77c1779fb6eee877), CONST64(0x37dc37a5eb6e9237), CONST64(0xe5b3e57b56d79ee5), CONST64(0x9f469f8cd923139f), CONST64(0xf0e7f0d317fd23f0), CONST64(0x4a354a6a7f94204a), CONST64(0xda4fda9e95a944da), CONST64(0x587d58fa25b0a258), CONST64(0xc903c906ca8fcfc9), CONST64(0x29a429558d527c29), CONST64(0x0a280a5022145a0a), CONST64(0xb1feb1e14f7f50b1), CONST64(0xa0baa0691a5dc9a0), CONST64(0x6bb16b7fdad6146b), CONST64(0x852e855cab17d985), CONST64(0xbdcebd8173673cbd), CONST64(0x5d695dd234ba8f5d), CONST64(0x1040108050209010), CONST64(0xf4f7f4f303f507f4), CONST64(0xcb0bcb16c08bddcb), CONST64(0x3ef83eedc67cd33e), CONST64(0x05140528110a2d05), CONST64(0x6781671fe6ce7867), CONST64(0xe4b7e47353d597e4), CONST64(0x279c2725bb4e0227), CONST64(0x4119413258827341), CONST64(0x8b168b2c9d0ba78b), CONST64(0xa7a6a7510153f6a7), CONST64(0x7de97dcf94fab27d), CONST64(0x956e95dcfb374995), CONST64(0xd847d88e9fad56d8), CONST64(0xfbcbfb8b30eb70fb), CONST64(0xee9fee2371c1cdee), CONST64(0x7ced7cc791f8bb7c), CONST64(0x66856617e3cc7166), CONST64(0xdd53dda68ea77bdd), CONST64(0x175c17b84b2eaf17), CONST64(0x47014702468e4547), CONST64(0x9e429e84dc211a9e), CONST64(0xca0fca1ec589d4ca), CONST64(0x2db42d75995a582d), CONST64(0xbfc6bf9179632ebf), CONST64(0x071c07381b0e3f07), CONST64(0xad8ead012347acad), CONST64(0x5a755aea2fb4b05a), CONST64(0x8336836cb51bef83), CONST64(0x33cc3385ff66b633), CONST64(0x6391633ff2c65c63), CONST64(0x020802100a041202), CONST64(0xaa92aa39384993aa), CONST64(0x71d971afa8e2de71), CONST64(0xc807c80ecf8dc6c8), CONST64(0x196419c87d32d119), CONST64(0x4939497270923b49), CONST64(0xd943d9869aaf5fd9), CONST64(0xf2eff2c31df931f2), CONST64(0xe3abe34b48dba8e3), CONST64(0x5b715be22ab6b95b), CONST64(0x881a8834920dbc88), CONST64(0x9a529aa4c8293e9a), CONST64(0x2698262dbe4c0b26), CONST64(0x32c8328dfa64bf32), CONST64(0xb0fab0e94a7d59b0), CONST64(0xe983e91b6acff2e9), CONST64(0x0f3c0f78331e770f), CONST64(0xd573d5e6a6b733d5), CONST64(0x803a8074ba1df480), CONST64(0xbec2be997c6127be), CONST64(0xcd13cd26de87ebcd), CONST64(0x34d034bde4688934), CONST64(0x483d487a75903248), CONST64(0xffdbffab24e354ff), CONST64(0x7af57af78ff48d7a), CONST64(0x907a90f4ea3d6490), CONST64(0x5f615fc23ebe9d5f), CONST64(0x2080201da0403d20), CONST64(0x68bd6867d5d00f68), CONST64(0x1a681ad07234ca1a), CONST64(0xae82ae192c41b7ae), CONST64(0xb4eab4c95e757db4), CONST64(0x544d549a19a8ce54), CONST64(0x937693ece53b7f93), CONST64(0x2288220daa442f22), CONST64(0x648d6407e9c86364), CONST64(0xf1e3f1db12ff2af1), CONST64(0x73d173bfa2e6cc73), CONST64(0x124812905a248212), CONST64(0x401d403a5d807a40), CONST64(0x0820084028104808), CONST64(0xc32bc356e89b95c3), CONST64(0xec97ec337bc5dfec), CONST64(0xdb4bdb9690ab4ddb), CONST64(0xa1bea1611f5fc0a1), CONST64(0x8d0e8d1c8307918d), CONST64(0x3df43df5c97ac83d), CONST64(0x976697ccf1335b97), CONST64(0x0000000000000000), CONST64(0xcf1bcf36d483f9cf), CONST64(0x2bac2b4587566e2b), CONST64(0x76c57697b3ece176), CONST64(0x82328264b019e682), CONST64(0xd67fd6fea9b128d6), CONST64(0x1b6c1bd87736c31b), CONST64(0xb5eeb5c15b7774b5), CONST64(0xaf86af112943beaf), CONST64(0x6ab56a77dfd41d6a), CONST64(0x505d50ba0da0ea50), CONST64(0x450945124c8a5745), CONST64(0xf3ebf3cb18fb38f3), CONST64(0x30c0309df060ad30), CONST64(0xef9bef2b74c3c4ef), CONST64(0x3ffc3fe5c37eda3f), CONST64(0x554955921caac755), CONST64(0xa2b2a2791059dba2), CONST64(0xea8fea0365c9e9ea), CONST64(0x6589650fecca6a65), CONST64(0xbad2bab9686903ba), CONST64(0x2fbc2f65935e4a2f), CONST64(0xc027c04ee79d8ec0), CONST64(0xde5fdebe81a160de), CONST64(0x1c701ce06c38fc1c), CONST64(0xfdd3fdbb2ee746fd), CONST64(0x4d294d52649a1f4d), CONST64(0x927292e4e0397692), CONST64(0x75c9758fbceafa75), CONST64(0x061806301e0c3606), CONST64(0x8a128a249809ae8a), CONST64(0xb2f2b2f940794bb2), CONST64(0xe6bfe66359d185e6), CONST64(0x0e380e70361c7e0e), CONST64(0x1f7c1ff8633ee71f), CONST64(0x62956237f7c45562), CONST64(0xd477d4eea3b53ad4), CONST64(0xa89aa829324d81a8), CONST64(0x966296c4f4315296), CONST64(0xf9c3f99b3aef62f9), CONST64(0xc533c566f697a3c5), CONST64(0x25942535b14a1025), CONST64(0x597959f220b2ab59), CONST64(0x842a8454ae15d084), CONST64(0x72d572b7a7e4c572), CONST64(0x39e439d5dd72ec39), CONST64(0x4c2d4c5a6198164c), CONST64(0x5e655eca3bbc945e), CONST64(0x78fd78e785f09f78), CONST64(0x38e038ddd870e538), CONST64(0x8c0a8c148605988c), CONST64(0xd163d1c6b2bf17d1), CONST64(0xa5aea5410b57e4a5), CONST64(0xe2afe2434dd9a1e2), CONST64(0x6199612ff8c24e61), CONST64(0xb3f6b3f1457b42b3), CONST64(0x21842115a5423421), CONST64(0x9c4a9c94d625089c), CONST64(0x1e781ef0663cee1e), CONST64(0x4311432252866143), CONST64(0xc73bc776fc93b1c7), CONST64(0xfcd7fcb32be54ffc), CONST64(0x0410042014082404), CONST64(0x515951b208a2e351), CONST64(0x995e99bcc72f2599), CONST64(0x6da96d4fc4da226d), CONST64(0x0d340d68391a650d), CONST64(0xfacffa8335e979fa), CONST64(0xdf5bdfb684a369df), CONST64(0x7ee57ed79bfca97e), CONST64(0x2490243db4481924), CONST64(0x3bec3bc5d776fe3b), CONST64(0xab96ab313d4b9aab), CONST64(0xce1fce3ed181f0ce), CONST64(0x1144118855229911), CONST64(0x8f068f0c8903838f), CONST64(0x4e254e4a6b9c044e), CONST64(0xb7e6b7d1517366b7), CONST64(0xeb8beb0b60cbe0eb), CONST64(0x3cf03cfdcc78c13c), CONST64(0x813e817cbf1ffd81), CONST64(0x946a94d4fe354094), CONST64(0xf7fbf7eb0cf31cf7), CONST64(0xb9deb9a1676f18b9), CONST64(0x134c13985f268b13), CONST64(0x2cb02c7d9c58512c), CONST64(0xd36bd3d6b8bb05d3), CONST64(0xe7bbe76b5cd38ce7), CONST64(0x6ea56e57cbdc396e), CONST64(0xc437c46ef395aac4), CONST64(0x030c03180f061b03), CONST64(0x5645568a13acdc56), CONST64(0x440d441a49885e44), CONST64(0x7fe17fdf9efea07f), CONST64(0xa99ea921374f88a9), CONST64(0x2aa82a4d8254672a), CONST64(0xbbd6bbb16d6b0abb), CONST64(0xc123c146e29f87c1), CONST64(0x535153a202a6f153), CONST64(0xdc57dcae8ba572dc), CONST64(0x0b2c0b582716530b), CONST64(0x9d4e9d9cd327019d), CONST64(0x6cad6c47c1d82b6c), CONST64(0x31c43195f562a431), CONST64(0x74cd7487b9e8f374), CONST64(0xf6fff6e309f115f6), CONST64(0x4605460a438c4c46), CONST64(0xac8aac092645a5ac), CONST64(0x891e893c970fb589), CONST64(0x145014a04428b414), CONST64(0xe1a3e15b42dfbae1), CONST64(0x165816b04e2ca616), CONST64(0x3ae83acdd274f73a), CONST64(0x69b9696fd0d20669), CONST64(0x092409482d124109), CONST64(0x70dd70a7ade0d770), CONST64(0xb6e2b6d954716fb6), CONST64(0xd067d0ceb7bd1ed0), CONST64(0xed93ed3b7ec7d6ed), CONST64(0xcc17cc2edb85e2cc), CONST64(0x4215422a57846842), CONST64(0x985a98b4c22d2c98), CONST64(0xa4aaa4490e55eda4), CONST64(0x28a0285d88507528), CONST64(0x5c6d5cda31b8865c), CONST64(0xf8c7f8933fed6bf8), CONST64(0x86228644a411c286) }; #endif static const ulong64 cont[] = { CONST64(0x1823c6e887b8014f), CONST64(0x36a6d2f5796f9152), CONST64(0x60bc9b8ea30c7b35), CONST64(0x1de0d7c22e4bfe57), CONST64(0x157737e59ff04ada), CONST64(0x58c9290ab1a06b85), CONST64(0xbd5d10f4cb3e0567), CONST64(0xe427418ba77d95d8), CONST64(0xfbee7c66dd17479e), CONST64(0xca2dbf07ad5a8333), CONST64(0x6302aa71c81949d9), }; /* $Source: /cvs/libtom/libtomcrypt/src/hashes/whirl/whirltab.c,v $ */ /* $Revision: 1.3 $ */ /* $Date: 2007/05/12 14:21:44 $ */ libtomcrypt-1.17/src/hashes/whirl/whirl.c0000644000175100001440000002322210621351501017204 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file whirl.c LTC_WHIRLPOOL (using their new sbox) hash function by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_WHIRLPOOL const struct ltc_hash_descriptor whirlpool_desc = { "whirlpool", 11, 64, 64, /* OID */ { 1, 0, 10118, 3, 0, 55 }, 6, &whirlpool_init, &whirlpool_process, &whirlpool_done, &whirlpool_test, NULL }; /* the sboxes */ #include "whirltab.c" /* get a_{i,j} */ #define GB(a,i,j) ((a[(i) & 7] >> (8 * (j))) & 255) /* shortcut macro to perform three functions at once */ #define theta_pi_gamma(a, i) \ SB0(GB(a, i-0, 7)) ^ \ SB1(GB(a, i-1, 6)) ^ \ SB2(GB(a, i-2, 5)) ^ \ SB3(GB(a, i-3, 4)) ^ \ SB4(GB(a, i-4, 3)) ^ \ SB5(GB(a, i-5, 2)) ^ \ SB6(GB(a, i-6, 1)) ^ \ SB7(GB(a, i-7, 0)) #ifdef LTC_CLEAN_STACK static int _whirlpool_compress(hash_state *md, unsigned char *buf) #else static int whirlpool_compress(hash_state *md, unsigned char *buf) #endif { ulong64 K[2][8], T[3][8]; int x, y; /* load the block/state */ for (x = 0; x < 8; x++) { K[0][x] = md->whirlpool.state[x]; LOAD64H(T[0][x], buf + (8 * x)); T[2][x] = T[0][x]; T[0][x] ^= K[0][x]; } /* do rounds 1..10 */ for (x = 0; x < 10; x += 2) { /* odd round */ /* apply main transform to K[0] into K[1] */ for (y = 0; y < 8; y++) { K[1][y] = theta_pi_gamma(K[0], y); } /* xor the constant */ K[1][0] ^= cont[x]; /* apply main transform to T[0] into T[1] */ for (y = 0; y < 8; y++) { T[1][y] = theta_pi_gamma(T[0], y) ^ K[1][y]; } /* even round */ /* apply main transform to K[1] into K[0] */ for (y = 0; y < 8; y++) { K[0][y] = theta_pi_gamma(K[1], y); } /* xor the constant */ K[0][0] ^= cont[x+1]; /* apply main transform to T[1] into T[0] */ for (y = 0; y < 8; y++) { T[0][y] = theta_pi_gamma(T[1], y) ^ K[0][y]; } } /* store state */ for (x = 0; x < 8; x++) { md->whirlpool.state[x] ^= T[0][x] ^ T[2][x]; } return CRYPT_OK; } #ifdef LTC_CLEAN_STACK static int whirlpool_compress(hash_state *md, unsigned char *buf) { int err; err = _whirlpool_compress(md, buf); burn_stack((5 * 8 * sizeof(ulong64)) + (2 * sizeof(int))); return err; } #endif /** Initialize the hash state @param md The hash state you wish to initialize @return CRYPT_OK if successful */ int whirlpool_init(hash_state * md) { LTC_ARGCHK(md != NULL); zeromem(&md->whirlpool, sizeof(md->whirlpool)); return CRYPT_OK; } /** Process a block of memory though the hash @param md The hash state @param in The data to hash @param inlen The length of the data (octets) @return CRYPT_OK if successful */ HASH_PROCESS(whirlpool_process, whirlpool_compress, whirlpool, 64) /** Terminate the hash to get the digest @param md The hash state @param out [out] The destination of the hash (64 bytes) @return CRYPT_OK if successful */ int whirlpool_done(hash_state * md, unsigned char *out) { int i; LTC_ARGCHK(md != NULL); LTC_ARGCHK(out != NULL); if (md->whirlpool.curlen >= sizeof(md->whirlpool.buf)) { return CRYPT_INVALID_ARG; } /* increase the length of the message */ md->whirlpool.length += md->whirlpool.curlen * 8; /* append the '1' bit */ md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0x80; /* if the length is currently above 32 bytes we append zeros * then compress. Then we can fall back to padding zeros and length * encoding like normal. */ if (md->whirlpool.curlen > 32) { while (md->whirlpool.curlen < 64) { md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0; } whirlpool_compress(md, md->whirlpool.buf); md->whirlpool.curlen = 0; } /* pad upto 56 bytes of zeroes (should be 32 but we only support 64-bit lengths) */ while (md->whirlpool.curlen < 56) { md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0; } /* store length */ STORE64H(md->whirlpool.length, md->whirlpool.buf+56); whirlpool_compress(md, md->whirlpool.buf); /* copy output */ for (i = 0; i < 8; i++) { STORE64H(md->whirlpool.state[i], out+(8*i)); } #ifdef LTC_CLEAN_STACK zeromem(md, sizeof(*md)); #endif return CRYPT_OK; } /** Self-test the hash @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled */ int whirlpool_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { int len; unsigned char msg[128], hash[64]; } tests[] = { /* NULL Message */ { 0, { 0x00 }, { 0x19, 0xFA, 0x61, 0xD7, 0x55, 0x22, 0xA4, 0x66, 0x9B, 0x44, 0xE3, 0x9C, 0x1D, 0x2E, 0x17, 0x26, 0xC5, 0x30, 0x23, 0x21, 0x30, 0xD4, 0x07, 0xF8, 0x9A, 0xFE, 0xE0, 0x96, 0x49, 0x97, 0xF7, 0xA7, 0x3E, 0x83, 0xBE, 0x69, 0x8B, 0x28, 0x8F, 0xEB, 0xCF, 0x88, 0xE3, 0xE0, 0x3C, 0x4F, 0x07, 0x57, 0xEA, 0x89, 0x64, 0xE5, 0x9B, 0x63, 0xD9, 0x37, 0x08, 0xB1, 0x38, 0xCC, 0x42, 0xA6, 0x6E, 0xB3 } }, /* 448-bits of 0 bits */ { 56, { 0x00 }, { 0x0B, 0x3F, 0x53, 0x78, 0xEB, 0xED, 0x2B, 0xF4, 0xD7, 0xBE, 0x3C, 0xFD, 0x81, 0x8C, 0x1B, 0x03, 0xB6, 0xBB, 0x03, 0xD3, 0x46, 0x94, 0x8B, 0x04, 0xF4, 0xF4, 0x0C, 0x72, 0x6F, 0x07, 0x58, 0x70, 0x2A, 0x0F, 0x1E, 0x22, 0x58, 0x80, 0xE3, 0x8D, 0xD5, 0xF6, 0xED, 0x6D, 0xE9, 0xB1, 0xE9, 0x61, 0xE4, 0x9F, 0xC1, 0x31, 0x8D, 0x7C, 0xB7, 0x48, 0x22, 0xF3, 0xD0, 0xE2, 0xE9, 0xA7, 0xE7, 0xB0 } }, /* 520-bits of 0 bits */ { 65, { 0x00 }, { 0x85, 0xE1, 0x24, 0xC4, 0x41, 0x5B, 0xCF, 0x43, 0x19, 0x54, 0x3E, 0x3A, 0x63, 0xFF, 0x57, 0x1D, 0x09, 0x35, 0x4C, 0xEE, 0xBE, 0xE1, 0xE3, 0x25, 0x30, 0x8C, 0x90, 0x69, 0xF4, 0x3E, 0x2A, 0xE4, 0xD0, 0xE5, 0x1D, 0x4E, 0xB1, 0xE8, 0x64, 0x28, 0x70, 0x19, 0x4E, 0x95, 0x30, 0xD8, 0xD8, 0xAF, 0x65, 0x89, 0xD1, 0xBF, 0x69, 0x49, 0xDD, 0xF9, 0x0A, 0x7F, 0x12, 0x08, 0x62, 0x37, 0x95, 0xB9 } }, /* 512-bits, leading set */ { 64, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x10, 0x3E, 0x00, 0x55, 0xA9, 0xB0, 0x90, 0xE1, 0x1C, 0x8F, 0xDD, 0xEB, 0xBA, 0x06, 0xC0, 0x5A, 0xCE, 0x8B, 0x64, 0xB8, 0x96, 0x12, 0x8F, 0x6E, 0xED, 0x30, 0x71, 0xFC, 0xF3, 0xDC, 0x16, 0x94, 0x67, 0x78, 0xE0, 0x72, 0x23, 0x23, 0x3F, 0xD1, 0x80, 0xFC, 0x40, 0xCC, 0xDB, 0x84, 0x30, 0xA6, 0x40, 0xE3, 0x76, 0x34, 0x27, 0x1E, 0x65, 0x5C, 0xA1, 0x67, 0x4E, 0xBF, 0xF5, 0x07, 0xF8, 0xCB } }, /* 512-bits, leading set of second byte */ { 64, { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x35, 0x7B, 0x42, 0xEA, 0x79, 0xBC, 0x97, 0x86, 0x97, 0x5A, 0x3C, 0x44, 0x70, 0xAA, 0xB2, 0x3E, 0x62, 0x29, 0x79, 0x7B, 0xAD, 0xBD, 0x54, 0x36, 0x5B, 0x54, 0x96, 0xE5, 0x5D, 0x9D, 0xD7, 0x9F, 0xE9, 0x62, 0x4F, 0xB4, 0x22, 0x66, 0x93, 0x0A, 0x62, 0x8E, 0xD4, 0xDB, 0x08, 0xF9, 0xDD, 0x35, 0xEF, 0x1B, 0xE1, 0x04, 0x53, 0xFC, 0x18, 0xF4, 0x2C, 0x7F, 0x5E, 0x1F, 0x9B, 0xAE, 0x55, 0xE0 } }, /* 512-bits, leading set of last byte */ { 64, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 }, { 0x8B, 0x39, 0x04, 0xDD, 0x19, 0x81, 0x41, 0x26, 0xFD, 0x02, 0x74, 0xAB, 0x49, 0xC5, 0x97, 0xF6, 0xD7, 0x75, 0x33, 0x52, 0xA2, 0xDD, 0x91, 0xFD, 0x8F, 0x9F, 0x54, 0x05, 0x4C, 0x54, 0xBF, 0x0F, 0x06, 0xDB, 0x4F, 0xF7, 0x08, 0xA3, 0xA2, 0x8B, 0xC3, 0x7A, 0x92, 0x1E, 0xEE, 0x11, 0xED, 0x7B, 0x6A, 0x53, 0x79, 0x32, 0xCC, 0x5E, 0x94, 0xEE, 0x1E, 0xA6, 0x57, 0x60, 0x7E, 0x36, 0xC9, 0xF7 } }, }; int i; unsigned char tmp[64]; hash_state md; for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { whirlpool_init(&md); whirlpool_process(&md, (unsigned char *)tests[i].msg, tests[i].len); whirlpool_done(&md, tmp); if (XMEMCMP(tmp, tests[i].hash, 64) != 0) { #if 0 printf("\nFailed test %d\n", i); for (i = 0; i < 64; ) { printf("%02x ", tmp[i]); if (!(++i & 15)) printf("\n"); } #endif return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/hashes/whirl/whirl.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2007/05/12 14:21:44 $ */ libtomcrypt-1.17/src/hashes/tiger.c0000644000175100001440000014520210621351501016047 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file tiger.c Tiger hash function, Tom St Denis */ #ifdef LTC_TIGER const struct ltc_hash_descriptor tiger_desc = { "tiger", 1, 24, 64, /* OID */ { 1, 3, 6, 1, 4, 1, 11591, 12, 2, }, 9, &tiger_init, &tiger_process, &tiger_done, &tiger_test, NULL }; #define t1 (table) #define t2 (table+256) #define t3 (table+256*2) #define t4 (table+256*3) static const ulong64 table[4*256] = { CONST64(0x02AAB17CF7E90C5E) /* 0 */, CONST64(0xAC424B03E243A8EC) /* 1 */, CONST64(0x72CD5BE30DD5FCD3) /* 2 */, CONST64(0x6D019B93F6F97F3A) /* 3 */, CONST64(0xCD9978FFD21F9193) /* 4 */, CONST64(0x7573A1C9708029E2) /* 5 */, CONST64(0xB164326B922A83C3) /* 6 */, CONST64(0x46883EEE04915870) /* 7 */, CONST64(0xEAACE3057103ECE6) /* 8 */, CONST64(0xC54169B808A3535C) /* 9 */, CONST64(0x4CE754918DDEC47C) /* 10 */, CONST64(0x0AA2F4DFDC0DF40C) /* 11 */, CONST64(0x10B76F18A74DBEFA) /* 12 */, CONST64(0xC6CCB6235AD1AB6A) /* 13 */, CONST64(0x13726121572FE2FF) /* 14 */, CONST64(0x1A488C6F199D921E) /* 15 */, CONST64(0x4BC9F9F4DA0007CA) /* 16 */, CONST64(0x26F5E6F6E85241C7) /* 17 */, CONST64(0x859079DBEA5947B6) /* 18 */, CONST64(0x4F1885C5C99E8C92) /* 19 */, CONST64(0xD78E761EA96F864B) /* 20 */, CONST64(0x8E36428C52B5C17D) /* 21 */, CONST64(0x69CF6827373063C1) /* 22 */, CONST64(0xB607C93D9BB4C56E) /* 23 */, CONST64(0x7D820E760E76B5EA) /* 24 */, CONST64(0x645C9CC6F07FDC42) /* 25 */, CONST64(0xBF38A078243342E0) /* 26 */, CONST64(0x5F6B343C9D2E7D04) /* 27 */, CONST64(0xF2C28AEB600B0EC6) /* 28 */, CONST64(0x6C0ED85F7254BCAC) /* 29 */, CONST64(0x71592281A4DB4FE5) /* 30 */, CONST64(0x1967FA69CE0FED9F) /* 31 */, CONST64(0xFD5293F8B96545DB) /* 32 */, CONST64(0xC879E9D7F2A7600B) /* 33 */, CONST64(0x860248920193194E) /* 34 */, CONST64(0xA4F9533B2D9CC0B3) /* 35 */, CONST64(0x9053836C15957613) /* 36 */, CONST64(0xDB6DCF8AFC357BF1) /* 37 */, CONST64(0x18BEEA7A7A370F57) /* 38 */, CONST64(0x037117CA50B99066) /* 39 */, CONST64(0x6AB30A9774424A35) /* 40 */, CONST64(0xF4E92F02E325249B) /* 41 */, CONST64(0x7739DB07061CCAE1) /* 42 */, CONST64(0xD8F3B49CECA42A05) /* 43 */, CONST64(0xBD56BE3F51382F73) /* 44 */, CONST64(0x45FAED5843B0BB28) /* 45 */, CONST64(0x1C813D5C11BF1F83) /* 46 */, CONST64(0x8AF0E4B6D75FA169) /* 47 */, CONST64(0x33EE18A487AD9999) /* 48 */, CONST64(0x3C26E8EAB1C94410) /* 49 */, CONST64(0xB510102BC0A822F9) /* 50 */, CONST64(0x141EEF310CE6123B) /* 51 */, CONST64(0xFC65B90059DDB154) /* 52 */, CONST64(0xE0158640C5E0E607) /* 53 */, CONST64(0x884E079826C3A3CF) /* 54 */, CONST64(0x930D0D9523C535FD) /* 55 */, CONST64(0x35638D754E9A2B00) /* 56 */, CONST64(0x4085FCCF40469DD5) /* 57 */, CONST64(0xC4B17AD28BE23A4C) /* 58 */, CONST64(0xCAB2F0FC6A3E6A2E) /* 59 */, CONST64(0x2860971A6B943FCD) /* 60 */, CONST64(0x3DDE6EE212E30446) /* 61 */, CONST64(0x6222F32AE01765AE) /* 62 */, CONST64(0x5D550BB5478308FE) /* 63 */, CONST64(0xA9EFA98DA0EDA22A) /* 64 */, CONST64(0xC351A71686C40DA7) /* 65 */, CONST64(0x1105586D9C867C84) /* 66 */, CONST64(0xDCFFEE85FDA22853) /* 67 */, CONST64(0xCCFBD0262C5EEF76) /* 68 */, CONST64(0xBAF294CB8990D201) /* 69 */, CONST64(0xE69464F52AFAD975) /* 70 */, CONST64(0x94B013AFDF133E14) /* 71 */, CONST64(0x06A7D1A32823C958) /* 72 */, CONST64(0x6F95FE5130F61119) /* 73 */, CONST64(0xD92AB34E462C06C0) /* 74 */, CONST64(0xED7BDE33887C71D2) /* 75 */, CONST64(0x79746D6E6518393E) /* 76 */, CONST64(0x5BA419385D713329) /* 77 */, CONST64(0x7C1BA6B948A97564) /* 78 */, CONST64(0x31987C197BFDAC67) /* 79 */, CONST64(0xDE6C23C44B053D02) /* 80 */, CONST64(0x581C49FED002D64D) /* 81 */, CONST64(0xDD474D6338261571) /* 82 */, CONST64(0xAA4546C3E473D062) /* 83 */, CONST64(0x928FCE349455F860) /* 84 */, CONST64(0x48161BBACAAB94D9) /* 85 */, CONST64(0x63912430770E6F68) /* 86 */, CONST64(0x6EC8A5E602C6641C) /* 87 */, CONST64(0x87282515337DDD2B) /* 88 */, CONST64(0x2CDA6B42034B701B) /* 89 */, CONST64(0xB03D37C181CB096D) /* 90 */, CONST64(0xE108438266C71C6F) /* 91 */, CONST64(0x2B3180C7EB51B255) /* 92 */, CONST64(0xDF92B82F96C08BBC) /* 93 */, CONST64(0x5C68C8C0A632F3BA) /* 94 */, CONST64(0x5504CC861C3D0556) /* 95 */, CONST64(0xABBFA4E55FB26B8F) /* 96 */, CONST64(0x41848B0AB3BACEB4) /* 97 */, CONST64(0xB334A273AA445D32) /* 98 */, CONST64(0xBCA696F0A85AD881) /* 99 */, CONST64(0x24F6EC65B528D56C) /* 100 */, CONST64(0x0CE1512E90F4524A) /* 101 */, CONST64(0x4E9DD79D5506D35A) /* 102 */, CONST64(0x258905FAC6CE9779) /* 103 */, CONST64(0x2019295B3E109B33) /* 104 */, CONST64(0xF8A9478B73A054CC) /* 105 */, CONST64(0x2924F2F934417EB0) /* 106 */, CONST64(0x3993357D536D1BC4) /* 107 */, CONST64(0x38A81AC21DB6FF8B) /* 108 */, CONST64(0x47C4FBF17D6016BF) /* 109 */, CONST64(0x1E0FAADD7667E3F5) /* 110 */, CONST64(0x7ABCFF62938BEB96) /* 111 */, CONST64(0xA78DAD948FC179C9) /* 112 */, CONST64(0x8F1F98B72911E50D) /* 113 */, CONST64(0x61E48EAE27121A91) /* 114 */, CONST64(0x4D62F7AD31859808) /* 115 */, CONST64(0xECEBA345EF5CEAEB) /* 116 */, CONST64(0xF5CEB25EBC9684CE) /* 117 */, CONST64(0xF633E20CB7F76221) /* 118 */, CONST64(0xA32CDF06AB8293E4) /* 119 */, CONST64(0x985A202CA5EE2CA4) /* 120 */, CONST64(0xCF0B8447CC8A8FB1) /* 121 */, CONST64(0x9F765244979859A3) /* 122 */, CONST64(0xA8D516B1A1240017) /* 123 */, CONST64(0x0BD7BA3EBB5DC726) /* 124 */, CONST64(0xE54BCA55B86ADB39) /* 125 */, CONST64(0x1D7A3AFD6C478063) /* 126 */, CONST64(0x519EC608E7669EDD) /* 127 */, CONST64(0x0E5715A2D149AA23) /* 128 */, CONST64(0x177D4571848FF194) /* 129 */, CONST64(0xEEB55F3241014C22) /* 130 */, CONST64(0x0F5E5CA13A6E2EC2) /* 131 */, CONST64(0x8029927B75F5C361) /* 132 */, CONST64(0xAD139FABC3D6E436) /* 133 */, CONST64(0x0D5DF1A94CCF402F) /* 134 */, CONST64(0x3E8BD948BEA5DFC8) /* 135 */, CONST64(0xA5A0D357BD3FF77E) /* 136 */, CONST64(0xA2D12E251F74F645) /* 137 */, CONST64(0x66FD9E525E81A082) /* 138 */, CONST64(0x2E0C90CE7F687A49) /* 139 */, CONST64(0xC2E8BCBEBA973BC5) /* 140 */, CONST64(0x000001BCE509745F) /* 141 */, CONST64(0x423777BBE6DAB3D6) /* 142 */, CONST64(0xD1661C7EAEF06EB5) /* 143 */, CONST64(0xA1781F354DAACFD8) /* 144 */, CONST64(0x2D11284A2B16AFFC) /* 145 */, CONST64(0xF1FC4F67FA891D1F) /* 146 */, CONST64(0x73ECC25DCB920ADA) /* 147 */, CONST64(0xAE610C22C2A12651) /* 148 */, CONST64(0x96E0A810D356B78A) /* 149 */, CONST64(0x5A9A381F2FE7870F) /* 150 */, CONST64(0xD5AD62EDE94E5530) /* 151 */, CONST64(0xD225E5E8368D1427) /* 152 */, CONST64(0x65977B70C7AF4631) /* 153 */, CONST64(0x99F889B2DE39D74F) /* 154 */, CONST64(0x233F30BF54E1D143) /* 155 */, CONST64(0x9A9675D3D9A63C97) /* 156 */, CONST64(0x5470554FF334F9A8) /* 157 */, CONST64(0x166ACB744A4F5688) /* 158 */, CONST64(0x70C74CAAB2E4AEAD) /* 159 */, CONST64(0xF0D091646F294D12) /* 160 */, CONST64(0x57B82A89684031D1) /* 161 */, CONST64(0xEFD95A5A61BE0B6B) /* 162 */, CONST64(0x2FBD12E969F2F29A) /* 163 */, CONST64(0x9BD37013FEFF9FE8) /* 164 */, CONST64(0x3F9B0404D6085A06) /* 165 */, CONST64(0x4940C1F3166CFE15) /* 166 */, CONST64(0x09542C4DCDF3DEFB) /* 167 */, CONST64(0xB4C5218385CD5CE3) /* 168 */, CONST64(0xC935B7DC4462A641) /* 169 */, CONST64(0x3417F8A68ED3B63F) /* 170 */, CONST64(0xB80959295B215B40) /* 171 */, CONST64(0xF99CDAEF3B8C8572) /* 172 */, CONST64(0x018C0614F8FCB95D) /* 173 */, CONST64(0x1B14ACCD1A3ACDF3) /* 174 */, CONST64(0x84D471F200BB732D) /* 175 */, CONST64(0xC1A3110E95E8DA16) /* 176 */, CONST64(0x430A7220BF1A82B8) /* 177 */, CONST64(0xB77E090D39DF210E) /* 178 */, CONST64(0x5EF4BD9F3CD05E9D) /* 179 */, CONST64(0x9D4FF6DA7E57A444) /* 180 */, CONST64(0xDA1D60E183D4A5F8) /* 181 */, CONST64(0xB287C38417998E47) /* 182 */, CONST64(0xFE3EDC121BB31886) /* 183 */, CONST64(0xC7FE3CCC980CCBEF) /* 184 */, CONST64(0xE46FB590189BFD03) /* 185 */, CONST64(0x3732FD469A4C57DC) /* 186 */, CONST64(0x7EF700A07CF1AD65) /* 187 */, CONST64(0x59C64468A31D8859) /* 188 */, CONST64(0x762FB0B4D45B61F6) /* 189 */, CONST64(0x155BAED099047718) /* 190 */, CONST64(0x68755E4C3D50BAA6) /* 191 */, CONST64(0xE9214E7F22D8B4DF) /* 192 */, CONST64(0x2ADDBF532EAC95F4) /* 193 */, CONST64(0x32AE3909B4BD0109) /* 194 */, CONST64(0x834DF537B08E3450) /* 195 */, CONST64(0xFA209DA84220728D) /* 196 */, CONST64(0x9E691D9B9EFE23F7) /* 197 */, CONST64(0x0446D288C4AE8D7F) /* 198 */, CONST64(0x7B4CC524E169785B) /* 199 */, CONST64(0x21D87F0135CA1385) /* 200 */, CONST64(0xCEBB400F137B8AA5) /* 201 */, CONST64(0x272E2B66580796BE) /* 202 */, CONST64(0x3612264125C2B0DE) /* 203 */, CONST64(0x057702BDAD1EFBB2) /* 204 */, CONST64(0xD4BABB8EACF84BE9) /* 205 */, CONST64(0x91583139641BC67B) /* 206 */, CONST64(0x8BDC2DE08036E024) /* 207 */, CONST64(0x603C8156F49F68ED) /* 208 */, CONST64(0xF7D236F7DBEF5111) /* 209 */, CONST64(0x9727C4598AD21E80) /* 210 */, CONST64(0xA08A0896670A5FD7) /* 211 */, CONST64(0xCB4A8F4309EBA9CB) /* 212 */, CONST64(0x81AF564B0F7036A1) /* 213 */, CONST64(0xC0B99AA778199ABD) /* 214 */, CONST64(0x959F1EC83FC8E952) /* 215 */, CONST64(0x8C505077794A81B9) /* 216 */, CONST64(0x3ACAAF8F056338F0) /* 217 */, CONST64(0x07B43F50627A6778) /* 218 */, CONST64(0x4A44AB49F5ECCC77) /* 219 */, CONST64(0x3BC3D6E4B679EE98) /* 220 */, CONST64(0x9CC0D4D1CF14108C) /* 221 */, CONST64(0x4406C00B206BC8A0) /* 222 */, CONST64(0x82A18854C8D72D89) /* 223 */, CONST64(0x67E366B35C3C432C) /* 224 */, CONST64(0xB923DD61102B37F2) /* 225 */, CONST64(0x56AB2779D884271D) /* 226 */, CONST64(0xBE83E1B0FF1525AF) /* 227 */, CONST64(0xFB7C65D4217E49A9) /* 228 */, CONST64(0x6BDBE0E76D48E7D4) /* 229 */, CONST64(0x08DF828745D9179E) /* 230 */, CONST64(0x22EA6A9ADD53BD34) /* 231 */, CONST64(0xE36E141C5622200A) /* 232 */, CONST64(0x7F805D1B8CB750EE) /* 233 */, CONST64(0xAFE5C7A59F58E837) /* 234 */, CONST64(0xE27F996A4FB1C23C) /* 235 */, CONST64(0xD3867DFB0775F0D0) /* 236 */, CONST64(0xD0E673DE6E88891A) /* 237 */, CONST64(0x123AEB9EAFB86C25) /* 238 */, CONST64(0x30F1D5D5C145B895) /* 239 */, CONST64(0xBB434A2DEE7269E7) /* 240 */, CONST64(0x78CB67ECF931FA38) /* 241 */, CONST64(0xF33B0372323BBF9C) /* 242 */, CONST64(0x52D66336FB279C74) /* 243 */, CONST64(0x505F33AC0AFB4EAA) /* 244 */, CONST64(0xE8A5CD99A2CCE187) /* 245 */, CONST64(0x534974801E2D30BB) /* 246 */, CONST64(0x8D2D5711D5876D90) /* 247 */, CONST64(0x1F1A412891BC038E) /* 248 */, CONST64(0xD6E2E71D82E56648) /* 249 */, CONST64(0x74036C3A497732B7) /* 250 */, CONST64(0x89B67ED96361F5AB) /* 251 */, CONST64(0xFFED95D8F1EA02A2) /* 252 */, CONST64(0xE72B3BD61464D43D) /* 253 */, CONST64(0xA6300F170BDC4820) /* 254 */, CONST64(0xEBC18760ED78A77A) /* 255 */, CONST64(0xE6A6BE5A05A12138) /* 256 */, CONST64(0xB5A122A5B4F87C98) /* 257 */, CONST64(0x563C6089140B6990) /* 258 */, CONST64(0x4C46CB2E391F5DD5) /* 259 */, CONST64(0xD932ADDBC9B79434) /* 260 */, CONST64(0x08EA70E42015AFF5) /* 261 */, CONST64(0xD765A6673E478CF1) /* 262 */, CONST64(0xC4FB757EAB278D99) /* 263 */, CONST64(0xDF11C6862D6E0692) /* 264 */, CONST64(0xDDEB84F10D7F3B16) /* 265 */, CONST64(0x6F2EF604A665EA04) /* 266 */, CONST64(0x4A8E0F0FF0E0DFB3) /* 267 */, CONST64(0xA5EDEEF83DBCBA51) /* 268 */, CONST64(0xFC4F0A2A0EA4371E) /* 269 */, CONST64(0xE83E1DA85CB38429) /* 270 */, CONST64(0xDC8FF882BA1B1CE2) /* 271 */, CONST64(0xCD45505E8353E80D) /* 272 */, CONST64(0x18D19A00D4DB0717) /* 273 */, CONST64(0x34A0CFEDA5F38101) /* 274 */, CONST64(0x0BE77E518887CAF2) /* 275 */, CONST64(0x1E341438B3C45136) /* 276 */, CONST64(0xE05797F49089CCF9) /* 277 */, CONST64(0xFFD23F9DF2591D14) /* 278 */, CONST64(0x543DDA228595C5CD) /* 279 */, CONST64(0x661F81FD99052A33) /* 280 */, CONST64(0x8736E641DB0F7B76) /* 281 */, CONST64(0x15227725418E5307) /* 282 */, CONST64(0xE25F7F46162EB2FA) /* 283 */, CONST64(0x48A8B2126C13D9FE) /* 284 */, CONST64(0xAFDC541792E76EEA) /* 285 */, CONST64(0x03D912BFC6D1898F) /* 286 */, CONST64(0x31B1AAFA1B83F51B) /* 287 */, CONST64(0xF1AC2796E42AB7D9) /* 288 */, CONST64(0x40A3A7D7FCD2EBAC) /* 289 */, CONST64(0x1056136D0AFBBCC5) /* 290 */, CONST64(0x7889E1DD9A6D0C85) /* 291 */, CONST64(0xD33525782A7974AA) /* 292 */, CONST64(0xA7E25D09078AC09B) /* 293 */, CONST64(0xBD4138B3EAC6EDD0) /* 294 */, CONST64(0x920ABFBE71EB9E70) /* 295 */, CONST64(0xA2A5D0F54FC2625C) /* 296 */, CONST64(0xC054E36B0B1290A3) /* 297 */, CONST64(0xF6DD59FF62FE932B) /* 298 */, CONST64(0x3537354511A8AC7D) /* 299 */, CONST64(0xCA845E9172FADCD4) /* 300 */, CONST64(0x84F82B60329D20DC) /* 301 */, CONST64(0x79C62CE1CD672F18) /* 302 */, CONST64(0x8B09A2ADD124642C) /* 303 */, CONST64(0xD0C1E96A19D9E726) /* 304 */, CONST64(0x5A786A9B4BA9500C) /* 305 */, CONST64(0x0E020336634C43F3) /* 306 */, CONST64(0xC17B474AEB66D822) /* 307 */, CONST64(0x6A731AE3EC9BAAC2) /* 308 */, CONST64(0x8226667AE0840258) /* 309 */, CONST64(0x67D4567691CAECA5) /* 310 */, CONST64(0x1D94155C4875ADB5) /* 311 */, CONST64(0x6D00FD985B813FDF) /* 312 */, CONST64(0x51286EFCB774CD06) /* 313 */, CONST64(0x5E8834471FA744AF) /* 314 */, CONST64(0xF72CA0AEE761AE2E) /* 315 */, CONST64(0xBE40E4CDAEE8E09A) /* 316 */, CONST64(0xE9970BBB5118F665) /* 317 */, CONST64(0x726E4BEB33DF1964) /* 318 */, CONST64(0x703B000729199762) /* 319 */, CONST64(0x4631D816F5EF30A7) /* 320 */, CONST64(0xB880B5B51504A6BE) /* 321 */, CONST64(0x641793C37ED84B6C) /* 322 */, CONST64(0x7B21ED77F6E97D96) /* 323 */, CONST64(0x776306312EF96B73) /* 324 */, CONST64(0xAE528948E86FF3F4) /* 325 */, CONST64(0x53DBD7F286A3F8F8) /* 326 */, CONST64(0x16CADCE74CFC1063) /* 327 */, CONST64(0x005C19BDFA52C6DD) /* 328 */, CONST64(0x68868F5D64D46AD3) /* 329 */, CONST64(0x3A9D512CCF1E186A) /* 330 */, CONST64(0x367E62C2385660AE) /* 331 */, CONST64(0xE359E7EA77DCB1D7) /* 332 */, CONST64(0x526C0773749ABE6E) /* 333 */, CONST64(0x735AE5F9D09F734B) /* 334 */, CONST64(0x493FC7CC8A558BA8) /* 335 */, CONST64(0xB0B9C1533041AB45) /* 336 */, CONST64(0x321958BA470A59BD) /* 337 */, CONST64(0x852DB00B5F46C393) /* 338 */, CONST64(0x91209B2BD336B0E5) /* 339 */, CONST64(0x6E604F7D659EF19F) /* 340 */, CONST64(0xB99A8AE2782CCB24) /* 341 */, CONST64(0xCCF52AB6C814C4C7) /* 342 */, CONST64(0x4727D9AFBE11727B) /* 343 */, CONST64(0x7E950D0C0121B34D) /* 344 */, CONST64(0x756F435670AD471F) /* 345 */, CONST64(0xF5ADD442615A6849) /* 346 */, CONST64(0x4E87E09980B9957A) /* 347 */, CONST64(0x2ACFA1DF50AEE355) /* 348 */, CONST64(0xD898263AFD2FD556) /* 349 */, CONST64(0xC8F4924DD80C8FD6) /* 350 */, CONST64(0xCF99CA3D754A173A) /* 351 */, CONST64(0xFE477BACAF91BF3C) /* 352 */, CONST64(0xED5371F6D690C12D) /* 353 */, CONST64(0x831A5C285E687094) /* 354 */, CONST64(0xC5D3C90A3708A0A4) /* 355 */, CONST64(0x0F7F903717D06580) /* 356 */, CONST64(0x19F9BB13B8FDF27F) /* 357 */, CONST64(0xB1BD6F1B4D502843) /* 358 */, CONST64(0x1C761BA38FFF4012) /* 359 */, CONST64(0x0D1530C4E2E21F3B) /* 360 */, CONST64(0x8943CE69A7372C8A) /* 361 */, CONST64(0xE5184E11FEB5CE66) /* 362 */, CONST64(0x618BDB80BD736621) /* 363 */, CONST64(0x7D29BAD68B574D0B) /* 364 */, CONST64(0x81BB613E25E6FE5B) /* 365 */, CONST64(0x071C9C10BC07913F) /* 366 */, CONST64(0xC7BEEB7909AC2D97) /* 367 */, CONST64(0xC3E58D353BC5D757) /* 368 */, CONST64(0xEB017892F38F61E8) /* 369 */, CONST64(0xD4EFFB9C9B1CC21A) /* 370 */, CONST64(0x99727D26F494F7AB) /* 371 */, CONST64(0xA3E063A2956B3E03) /* 372 */, CONST64(0x9D4A8B9A4AA09C30) /* 373 */, CONST64(0x3F6AB7D500090FB4) /* 374 */, CONST64(0x9CC0F2A057268AC0) /* 375 */, CONST64(0x3DEE9D2DEDBF42D1) /* 376 */, CONST64(0x330F49C87960A972) /* 377 */, CONST64(0xC6B2720287421B41) /* 378 */, CONST64(0x0AC59EC07C00369C) /* 379 */, CONST64(0xEF4EAC49CB353425) /* 380 */, CONST64(0xF450244EEF0129D8) /* 381 */, CONST64(0x8ACC46E5CAF4DEB6) /* 382 */, CONST64(0x2FFEAB63989263F7) /* 383 */, CONST64(0x8F7CB9FE5D7A4578) /* 384 */, CONST64(0x5BD8F7644E634635) /* 385 */, CONST64(0x427A7315BF2DC900) /* 386 */, CONST64(0x17D0C4AA2125261C) /* 387 */, CONST64(0x3992486C93518E50) /* 388 */, CONST64(0xB4CBFEE0A2D7D4C3) /* 389 */, CONST64(0x7C75D6202C5DDD8D) /* 390 */, CONST64(0xDBC295D8E35B6C61) /* 391 */, CONST64(0x60B369D302032B19) /* 392 */, CONST64(0xCE42685FDCE44132) /* 393 */, CONST64(0x06F3DDB9DDF65610) /* 394 */, CONST64(0x8EA4D21DB5E148F0) /* 395 */, CONST64(0x20B0FCE62FCD496F) /* 396 */, CONST64(0x2C1B912358B0EE31) /* 397 */, CONST64(0xB28317B818F5A308) /* 398 */, CONST64(0xA89C1E189CA6D2CF) /* 399 */, CONST64(0x0C6B18576AAADBC8) /* 400 */, CONST64(0xB65DEAA91299FAE3) /* 401 */, CONST64(0xFB2B794B7F1027E7) /* 402 */, CONST64(0x04E4317F443B5BEB) /* 403 */, CONST64(0x4B852D325939D0A6) /* 404 */, CONST64(0xD5AE6BEEFB207FFC) /* 405 */, CONST64(0x309682B281C7D374) /* 406 */, CONST64(0xBAE309A194C3B475) /* 407 */, CONST64(0x8CC3F97B13B49F05) /* 408 */, CONST64(0x98A9422FF8293967) /* 409 */, CONST64(0x244B16B01076FF7C) /* 410 */, CONST64(0xF8BF571C663D67EE) /* 411 */, CONST64(0x1F0D6758EEE30DA1) /* 412 */, CONST64(0xC9B611D97ADEB9B7) /* 413 */, CONST64(0xB7AFD5887B6C57A2) /* 414 */, CONST64(0x6290AE846B984FE1) /* 415 */, CONST64(0x94DF4CDEACC1A5FD) /* 416 */, CONST64(0x058A5BD1C5483AFF) /* 417 */, CONST64(0x63166CC142BA3C37) /* 418 */, CONST64(0x8DB8526EB2F76F40) /* 419 */, CONST64(0xE10880036F0D6D4E) /* 420 */, CONST64(0x9E0523C9971D311D) /* 421 */, CONST64(0x45EC2824CC7CD691) /* 422 */, CONST64(0x575B8359E62382C9) /* 423 */, CONST64(0xFA9E400DC4889995) /* 424 */, CONST64(0xD1823ECB45721568) /* 425 */, CONST64(0xDAFD983B8206082F) /* 426 */, CONST64(0xAA7D29082386A8CB) /* 427 */, CONST64(0x269FCD4403B87588) /* 428 */, CONST64(0x1B91F5F728BDD1E0) /* 429 */, CONST64(0xE4669F39040201F6) /* 430 */, CONST64(0x7A1D7C218CF04ADE) /* 431 */, CONST64(0x65623C29D79CE5CE) /* 432 */, CONST64(0x2368449096C00BB1) /* 433 */, CONST64(0xAB9BF1879DA503BA) /* 434 */, CONST64(0xBC23ECB1A458058E) /* 435 */, CONST64(0x9A58DF01BB401ECC) /* 436 */, CONST64(0xA070E868A85F143D) /* 437 */, CONST64(0x4FF188307DF2239E) /* 438 */, CONST64(0x14D565B41A641183) /* 439 */, CONST64(0xEE13337452701602) /* 440 */, CONST64(0x950E3DCF3F285E09) /* 441 */, CONST64(0x59930254B9C80953) /* 442 */, CONST64(0x3BF299408930DA6D) /* 443 */, CONST64(0xA955943F53691387) /* 444 */, CONST64(0xA15EDECAA9CB8784) /* 445 */, CONST64(0x29142127352BE9A0) /* 446 */, CONST64(0x76F0371FFF4E7AFB) /* 447 */, CONST64(0x0239F450274F2228) /* 448 */, CONST64(0xBB073AF01D5E868B) /* 449 */, CONST64(0xBFC80571C10E96C1) /* 450 */, CONST64(0xD267088568222E23) /* 451 */, CONST64(0x9671A3D48E80B5B0) /* 452 */, CONST64(0x55B5D38AE193BB81) /* 453 */, CONST64(0x693AE2D0A18B04B8) /* 454 */, CONST64(0x5C48B4ECADD5335F) /* 455 */, CONST64(0xFD743B194916A1CA) /* 456 */, CONST64(0x2577018134BE98C4) /* 457 */, CONST64(0xE77987E83C54A4AD) /* 458 */, CONST64(0x28E11014DA33E1B9) /* 459 */, CONST64(0x270CC59E226AA213) /* 460 */, CONST64(0x71495F756D1A5F60) /* 461 */, CONST64(0x9BE853FB60AFEF77) /* 462 */, CONST64(0xADC786A7F7443DBF) /* 463 */, CONST64(0x0904456173B29A82) /* 464 */, CONST64(0x58BC7A66C232BD5E) /* 465 */, CONST64(0xF306558C673AC8B2) /* 466 */, CONST64(0x41F639C6B6C9772A) /* 467 */, CONST64(0x216DEFE99FDA35DA) /* 468 */, CONST64(0x11640CC71C7BE615) /* 469 */, CONST64(0x93C43694565C5527) /* 470 */, CONST64(0xEA038E6246777839) /* 471 */, CONST64(0xF9ABF3CE5A3E2469) /* 472 */, CONST64(0x741E768D0FD312D2) /* 473 */, CONST64(0x0144B883CED652C6) /* 474 */, CONST64(0xC20B5A5BA33F8552) /* 475 */, CONST64(0x1AE69633C3435A9D) /* 476 */, CONST64(0x97A28CA4088CFDEC) /* 477 */, CONST64(0x8824A43C1E96F420) /* 478 */, CONST64(0x37612FA66EEEA746) /* 479 */, CONST64(0x6B4CB165F9CF0E5A) /* 480 */, CONST64(0x43AA1C06A0ABFB4A) /* 481 */, CONST64(0x7F4DC26FF162796B) /* 482 */, CONST64(0x6CBACC8E54ED9B0F) /* 483 */, CONST64(0xA6B7FFEFD2BB253E) /* 484 */, CONST64(0x2E25BC95B0A29D4F) /* 485 */, CONST64(0x86D6A58BDEF1388C) /* 486 */, CONST64(0xDED74AC576B6F054) /* 487 */, CONST64(0x8030BDBC2B45805D) /* 488 */, CONST64(0x3C81AF70E94D9289) /* 489 */, CONST64(0x3EFF6DDA9E3100DB) /* 490 */, CONST64(0xB38DC39FDFCC8847) /* 491 */, CONST64(0x123885528D17B87E) /* 492 */, CONST64(0xF2DA0ED240B1B642) /* 493 */, CONST64(0x44CEFADCD54BF9A9) /* 494 */, CONST64(0x1312200E433C7EE6) /* 495 */, CONST64(0x9FFCC84F3A78C748) /* 496 */, CONST64(0xF0CD1F72248576BB) /* 497 */, CONST64(0xEC6974053638CFE4) /* 498 */, CONST64(0x2BA7B67C0CEC4E4C) /* 499 */, CONST64(0xAC2F4DF3E5CE32ED) /* 500 */, CONST64(0xCB33D14326EA4C11) /* 501 */, CONST64(0xA4E9044CC77E58BC) /* 502 */, CONST64(0x5F513293D934FCEF) /* 503 */, CONST64(0x5DC9645506E55444) /* 504 */, CONST64(0x50DE418F317DE40A) /* 505 */, CONST64(0x388CB31A69DDE259) /* 506 */, CONST64(0x2DB4A83455820A86) /* 507 */, CONST64(0x9010A91E84711AE9) /* 508 */, CONST64(0x4DF7F0B7B1498371) /* 509 */, CONST64(0xD62A2EABC0977179) /* 510 */, CONST64(0x22FAC097AA8D5C0E) /* 511 */, CONST64(0xF49FCC2FF1DAF39B) /* 512 */, CONST64(0x487FD5C66FF29281) /* 513 */, CONST64(0xE8A30667FCDCA83F) /* 514 */, CONST64(0x2C9B4BE3D2FCCE63) /* 515 */, CONST64(0xDA3FF74B93FBBBC2) /* 516 */, CONST64(0x2FA165D2FE70BA66) /* 517 */, CONST64(0xA103E279970E93D4) /* 518 */, CONST64(0xBECDEC77B0E45E71) /* 519 */, CONST64(0xCFB41E723985E497) /* 520 */, CONST64(0xB70AAA025EF75017) /* 521 */, CONST64(0xD42309F03840B8E0) /* 522 */, CONST64(0x8EFC1AD035898579) /* 523 */, CONST64(0x96C6920BE2B2ABC5) /* 524 */, CONST64(0x66AF4163375A9172) /* 525 */, CONST64(0x2174ABDCCA7127FB) /* 526 */, CONST64(0xB33CCEA64A72FF41) /* 527 */, CONST64(0xF04A4933083066A5) /* 528 */, CONST64(0x8D970ACDD7289AF5) /* 529 */, CONST64(0x8F96E8E031C8C25E) /* 530 */, CONST64(0xF3FEC02276875D47) /* 531 */, CONST64(0xEC7BF310056190DD) /* 532 */, CONST64(0xF5ADB0AEBB0F1491) /* 533 */, CONST64(0x9B50F8850FD58892) /* 534 */, CONST64(0x4975488358B74DE8) /* 535 */, CONST64(0xA3354FF691531C61) /* 536 */, CONST64(0x0702BBE481D2C6EE) /* 537 */, CONST64(0x89FB24057DEDED98) /* 538 */, CONST64(0xAC3075138596E902) /* 539 */, CONST64(0x1D2D3580172772ED) /* 540 */, CONST64(0xEB738FC28E6BC30D) /* 541 */, CONST64(0x5854EF8F63044326) /* 542 */, CONST64(0x9E5C52325ADD3BBE) /* 543 */, CONST64(0x90AA53CF325C4623) /* 544 */, CONST64(0xC1D24D51349DD067) /* 545 */, CONST64(0x2051CFEEA69EA624) /* 546 */, CONST64(0x13220F0A862E7E4F) /* 547 */, CONST64(0xCE39399404E04864) /* 548 */, CONST64(0xD9C42CA47086FCB7) /* 549 */, CONST64(0x685AD2238A03E7CC) /* 550 */, CONST64(0x066484B2AB2FF1DB) /* 551 */, CONST64(0xFE9D5D70EFBF79EC) /* 552 */, CONST64(0x5B13B9DD9C481854) /* 553 */, CONST64(0x15F0D475ED1509AD) /* 554 */, CONST64(0x0BEBCD060EC79851) /* 555 */, CONST64(0xD58C6791183AB7F8) /* 556 */, CONST64(0xD1187C5052F3EEE4) /* 557 */, CONST64(0xC95D1192E54E82FF) /* 558 */, CONST64(0x86EEA14CB9AC6CA2) /* 559 */, CONST64(0x3485BEB153677D5D) /* 560 */, CONST64(0xDD191D781F8C492A) /* 561 */, CONST64(0xF60866BAA784EBF9) /* 562 */, CONST64(0x518F643BA2D08C74) /* 563 */, CONST64(0x8852E956E1087C22) /* 564 */, CONST64(0xA768CB8DC410AE8D) /* 565 */, CONST64(0x38047726BFEC8E1A) /* 566 */, CONST64(0xA67738B4CD3B45AA) /* 567 */, CONST64(0xAD16691CEC0DDE19) /* 568 */, CONST64(0xC6D4319380462E07) /* 569 */, CONST64(0xC5A5876D0BA61938) /* 570 */, CONST64(0x16B9FA1FA58FD840) /* 571 */, CONST64(0x188AB1173CA74F18) /* 572 */, CONST64(0xABDA2F98C99C021F) /* 573 */, CONST64(0x3E0580AB134AE816) /* 574 */, CONST64(0x5F3B05B773645ABB) /* 575 */, CONST64(0x2501A2BE5575F2F6) /* 576 */, CONST64(0x1B2F74004E7E8BA9) /* 577 */, CONST64(0x1CD7580371E8D953) /* 578 */, CONST64(0x7F6ED89562764E30) /* 579 */, CONST64(0xB15926FF596F003D) /* 580 */, CONST64(0x9F65293DA8C5D6B9) /* 581 */, CONST64(0x6ECEF04DD690F84C) /* 582 */, CONST64(0x4782275FFF33AF88) /* 583 */, CONST64(0xE41433083F820801) /* 584 */, CONST64(0xFD0DFE409A1AF9B5) /* 585 */, CONST64(0x4325A3342CDB396B) /* 586 */, CONST64(0x8AE77E62B301B252) /* 587 */, CONST64(0xC36F9E9F6655615A) /* 588 */, CONST64(0x85455A2D92D32C09) /* 589 */, CONST64(0xF2C7DEA949477485) /* 590 */, CONST64(0x63CFB4C133A39EBA) /* 591 */, CONST64(0x83B040CC6EBC5462) /* 592 */, CONST64(0x3B9454C8FDB326B0) /* 593 */, CONST64(0x56F56A9E87FFD78C) /* 594 */, CONST64(0x2DC2940D99F42BC6) /* 595 */, CONST64(0x98F7DF096B096E2D) /* 596 */, CONST64(0x19A6E01E3AD852BF) /* 597 */, CONST64(0x42A99CCBDBD4B40B) /* 598 */, CONST64(0xA59998AF45E9C559) /* 599 */, CONST64(0x366295E807D93186) /* 600 */, CONST64(0x6B48181BFAA1F773) /* 601 */, CONST64(0x1FEC57E2157A0A1D) /* 602 */, CONST64(0x4667446AF6201AD5) /* 603 */, CONST64(0xE615EBCACFB0F075) /* 604 */, CONST64(0xB8F31F4F68290778) /* 605 */, CONST64(0x22713ED6CE22D11E) /* 606 */, CONST64(0x3057C1A72EC3C93B) /* 607 */, CONST64(0xCB46ACC37C3F1F2F) /* 608 */, CONST64(0xDBB893FD02AAF50E) /* 609 */, CONST64(0x331FD92E600B9FCF) /* 610 */, CONST64(0xA498F96148EA3AD6) /* 611 */, CONST64(0xA8D8426E8B6A83EA) /* 612 */, CONST64(0xA089B274B7735CDC) /* 613 */, CONST64(0x87F6B3731E524A11) /* 614 */, CONST64(0x118808E5CBC96749) /* 615 */, CONST64(0x9906E4C7B19BD394) /* 616 */, CONST64(0xAFED7F7E9B24A20C) /* 617 */, CONST64(0x6509EADEEB3644A7) /* 618 */, CONST64(0x6C1EF1D3E8EF0EDE) /* 619 */, CONST64(0xB9C97D43E9798FB4) /* 620 */, CONST64(0xA2F2D784740C28A3) /* 621 */, CONST64(0x7B8496476197566F) /* 622 */, CONST64(0x7A5BE3E6B65F069D) /* 623 */, CONST64(0xF96330ED78BE6F10) /* 624 */, CONST64(0xEEE60DE77A076A15) /* 625 */, CONST64(0x2B4BEE4AA08B9BD0) /* 626 */, CONST64(0x6A56A63EC7B8894E) /* 627 */, CONST64(0x02121359BA34FEF4) /* 628 */, CONST64(0x4CBF99F8283703FC) /* 629 */, CONST64(0x398071350CAF30C8) /* 630 */, CONST64(0xD0A77A89F017687A) /* 631 */, CONST64(0xF1C1A9EB9E423569) /* 632 */, CONST64(0x8C7976282DEE8199) /* 633 */, CONST64(0x5D1737A5DD1F7ABD) /* 634 */, CONST64(0x4F53433C09A9FA80) /* 635 */, CONST64(0xFA8B0C53DF7CA1D9) /* 636 */, CONST64(0x3FD9DCBC886CCB77) /* 637 */, CONST64(0xC040917CA91B4720) /* 638 */, CONST64(0x7DD00142F9D1DCDF) /* 639 */, CONST64(0x8476FC1D4F387B58) /* 640 */, CONST64(0x23F8E7C5F3316503) /* 641 */, CONST64(0x032A2244E7E37339) /* 642 */, CONST64(0x5C87A5D750F5A74B) /* 643 */, CONST64(0x082B4CC43698992E) /* 644 */, CONST64(0xDF917BECB858F63C) /* 645 */, CONST64(0x3270B8FC5BF86DDA) /* 646 */, CONST64(0x10AE72BB29B5DD76) /* 647 */, CONST64(0x576AC94E7700362B) /* 648 */, CONST64(0x1AD112DAC61EFB8F) /* 649 */, CONST64(0x691BC30EC5FAA427) /* 650 */, CONST64(0xFF246311CC327143) /* 651 */, CONST64(0x3142368E30E53206) /* 652 */, CONST64(0x71380E31E02CA396) /* 653 */, CONST64(0x958D5C960AAD76F1) /* 654 */, CONST64(0xF8D6F430C16DA536) /* 655 */, CONST64(0xC8FFD13F1BE7E1D2) /* 656 */, CONST64(0x7578AE66004DDBE1) /* 657 */, CONST64(0x05833F01067BE646) /* 658 */, CONST64(0xBB34B5AD3BFE586D) /* 659 */, CONST64(0x095F34C9A12B97F0) /* 660 */, CONST64(0x247AB64525D60CA8) /* 661 */, CONST64(0xDCDBC6F3017477D1) /* 662 */, CONST64(0x4A2E14D4DECAD24D) /* 663 */, CONST64(0xBDB5E6D9BE0A1EEB) /* 664 */, CONST64(0x2A7E70F7794301AB) /* 665 */, CONST64(0xDEF42D8A270540FD) /* 666 */, CONST64(0x01078EC0A34C22C1) /* 667 */, CONST64(0xE5DE511AF4C16387) /* 668 */, CONST64(0x7EBB3A52BD9A330A) /* 669 */, CONST64(0x77697857AA7D6435) /* 670 */, CONST64(0x004E831603AE4C32) /* 671 */, CONST64(0xE7A21020AD78E312) /* 672 */, CONST64(0x9D41A70C6AB420F2) /* 673 */, CONST64(0x28E06C18EA1141E6) /* 674 */, CONST64(0xD2B28CBD984F6B28) /* 675 */, CONST64(0x26B75F6C446E9D83) /* 676 */, CONST64(0xBA47568C4D418D7F) /* 677 */, CONST64(0xD80BADBFE6183D8E) /* 678 */, CONST64(0x0E206D7F5F166044) /* 679 */, CONST64(0xE258A43911CBCA3E) /* 680 */, CONST64(0x723A1746B21DC0BC) /* 681 */, CONST64(0xC7CAA854F5D7CDD3) /* 682 */, CONST64(0x7CAC32883D261D9C) /* 683 */, CONST64(0x7690C26423BA942C) /* 684 */, CONST64(0x17E55524478042B8) /* 685 */, CONST64(0xE0BE477656A2389F) /* 686 */, CONST64(0x4D289B5E67AB2DA0) /* 687 */, CONST64(0x44862B9C8FBBFD31) /* 688 */, CONST64(0xB47CC8049D141365) /* 689 */, CONST64(0x822C1B362B91C793) /* 690 */, CONST64(0x4EB14655FB13DFD8) /* 691 */, CONST64(0x1ECBBA0714E2A97B) /* 692 */, CONST64(0x6143459D5CDE5F14) /* 693 */, CONST64(0x53A8FBF1D5F0AC89) /* 694 */, CONST64(0x97EA04D81C5E5B00) /* 695 */, CONST64(0x622181A8D4FDB3F3) /* 696 */, CONST64(0xE9BCD341572A1208) /* 697 */, CONST64(0x1411258643CCE58A) /* 698 */, CONST64(0x9144C5FEA4C6E0A4) /* 699 */, CONST64(0x0D33D06565CF620F) /* 700 */, CONST64(0x54A48D489F219CA1) /* 701 */, CONST64(0xC43E5EAC6D63C821) /* 702 */, CONST64(0xA9728B3A72770DAF) /* 703 */, CONST64(0xD7934E7B20DF87EF) /* 704 */, CONST64(0xE35503B61A3E86E5) /* 705 */, CONST64(0xCAE321FBC819D504) /* 706 */, CONST64(0x129A50B3AC60BFA6) /* 707 */, CONST64(0xCD5E68EA7E9FB6C3) /* 708 */, CONST64(0xB01C90199483B1C7) /* 709 */, CONST64(0x3DE93CD5C295376C) /* 710 */, CONST64(0xAED52EDF2AB9AD13) /* 711 */, CONST64(0x2E60F512C0A07884) /* 712 */, CONST64(0xBC3D86A3E36210C9) /* 713 */, CONST64(0x35269D9B163951CE) /* 714 */, CONST64(0x0C7D6E2AD0CDB5FA) /* 715 */, CONST64(0x59E86297D87F5733) /* 716 */, CONST64(0x298EF221898DB0E7) /* 717 */, CONST64(0x55000029D1A5AA7E) /* 718 */, CONST64(0x8BC08AE1B5061B45) /* 719 */, CONST64(0xC2C31C2B6C92703A) /* 720 */, CONST64(0x94CC596BAF25EF42) /* 721 */, CONST64(0x0A1D73DB22540456) /* 722 */, CONST64(0x04B6A0F9D9C4179A) /* 723 */, CONST64(0xEFFDAFA2AE3D3C60) /* 724 */, CONST64(0xF7C8075BB49496C4) /* 725 */, CONST64(0x9CC5C7141D1CD4E3) /* 726 */, CONST64(0x78BD1638218E5534) /* 727 */, CONST64(0xB2F11568F850246A) /* 728 */, CONST64(0xEDFABCFA9502BC29) /* 729 */, CONST64(0x796CE5F2DA23051B) /* 730 */, CONST64(0xAAE128B0DC93537C) /* 731 */, CONST64(0x3A493DA0EE4B29AE) /* 732 */, CONST64(0xB5DF6B2C416895D7) /* 733 */, CONST64(0xFCABBD25122D7F37) /* 734 */, CONST64(0x70810B58105DC4B1) /* 735 */, CONST64(0xE10FDD37F7882A90) /* 736 */, CONST64(0x524DCAB5518A3F5C) /* 737 */, CONST64(0x3C9E85878451255B) /* 738 */, CONST64(0x4029828119BD34E2) /* 739 */, CONST64(0x74A05B6F5D3CECCB) /* 740 */, CONST64(0xB610021542E13ECA) /* 741 */, CONST64(0x0FF979D12F59E2AC) /* 742 */, CONST64(0x6037DA27E4F9CC50) /* 743 */, CONST64(0x5E92975A0DF1847D) /* 744 */, CONST64(0xD66DE190D3E623FE) /* 745 */, CONST64(0x5032D6B87B568048) /* 746 */, CONST64(0x9A36B7CE8235216E) /* 747 */, CONST64(0x80272A7A24F64B4A) /* 748 */, CONST64(0x93EFED8B8C6916F7) /* 749 */, CONST64(0x37DDBFF44CCE1555) /* 750 */, CONST64(0x4B95DB5D4B99BD25) /* 751 */, CONST64(0x92D3FDA169812FC0) /* 752 */, CONST64(0xFB1A4A9A90660BB6) /* 753 */, CONST64(0x730C196946A4B9B2) /* 754 */, CONST64(0x81E289AA7F49DA68) /* 755 */, CONST64(0x64669A0F83B1A05F) /* 756 */, CONST64(0x27B3FF7D9644F48B) /* 757 */, CONST64(0xCC6B615C8DB675B3) /* 758 */, CONST64(0x674F20B9BCEBBE95) /* 759 */, CONST64(0x6F31238275655982) /* 760 */, CONST64(0x5AE488713E45CF05) /* 761 */, CONST64(0xBF619F9954C21157) /* 762 */, CONST64(0xEABAC46040A8EAE9) /* 763 */, CONST64(0x454C6FE9F2C0C1CD) /* 764 */, CONST64(0x419CF6496412691C) /* 765 */, CONST64(0xD3DC3BEF265B0F70) /* 766 */, CONST64(0x6D0E60F5C3578A9E) /* 767 */, CONST64(0x5B0E608526323C55) /* 768 */, CONST64(0x1A46C1A9FA1B59F5) /* 769 */, CONST64(0xA9E245A17C4C8FFA) /* 770 */, CONST64(0x65CA5159DB2955D7) /* 771 */, CONST64(0x05DB0A76CE35AFC2) /* 772 */, CONST64(0x81EAC77EA9113D45) /* 773 */, CONST64(0x528EF88AB6AC0A0D) /* 774 */, CONST64(0xA09EA253597BE3FF) /* 775 */, CONST64(0x430DDFB3AC48CD56) /* 776 */, CONST64(0xC4B3A67AF45CE46F) /* 777 */, CONST64(0x4ECECFD8FBE2D05E) /* 778 */, CONST64(0x3EF56F10B39935F0) /* 779 */, CONST64(0x0B22D6829CD619C6) /* 780 */, CONST64(0x17FD460A74DF2069) /* 781 */, CONST64(0x6CF8CC8E8510ED40) /* 782 */, CONST64(0xD6C824BF3A6ECAA7) /* 783 */, CONST64(0x61243D581A817049) /* 784 */, CONST64(0x048BACB6BBC163A2) /* 785 */, CONST64(0xD9A38AC27D44CC32) /* 786 */, CONST64(0x7FDDFF5BAAF410AB) /* 787 */, CONST64(0xAD6D495AA804824B) /* 788 */, CONST64(0xE1A6A74F2D8C9F94) /* 789 */, CONST64(0xD4F7851235DEE8E3) /* 790 */, CONST64(0xFD4B7F886540D893) /* 791 */, CONST64(0x247C20042AA4BFDA) /* 792 */, CONST64(0x096EA1C517D1327C) /* 793 */, CONST64(0xD56966B4361A6685) /* 794 */, CONST64(0x277DA5C31221057D) /* 795 */, CONST64(0x94D59893A43ACFF7) /* 796 */, CONST64(0x64F0C51CCDC02281) /* 797 */, CONST64(0x3D33BCC4FF6189DB) /* 798 */, CONST64(0xE005CB184CE66AF1) /* 799 */, CONST64(0xFF5CCD1D1DB99BEA) /* 800 */, CONST64(0xB0B854A7FE42980F) /* 801 */, CONST64(0x7BD46A6A718D4B9F) /* 802 */, CONST64(0xD10FA8CC22A5FD8C) /* 803 */, CONST64(0xD31484952BE4BD31) /* 804 */, CONST64(0xC7FA975FCB243847) /* 805 */, CONST64(0x4886ED1E5846C407) /* 806 */, CONST64(0x28CDDB791EB70B04) /* 807 */, CONST64(0xC2B00BE2F573417F) /* 808 */, CONST64(0x5C9590452180F877) /* 809 */, CONST64(0x7A6BDDFFF370EB00) /* 810 */, CONST64(0xCE509E38D6D9D6A4) /* 811 */, CONST64(0xEBEB0F00647FA702) /* 812 */, CONST64(0x1DCC06CF76606F06) /* 813 */, CONST64(0xE4D9F28BA286FF0A) /* 814 */, CONST64(0xD85A305DC918C262) /* 815 */, CONST64(0x475B1D8732225F54) /* 816 */, CONST64(0x2D4FB51668CCB5FE) /* 817 */, CONST64(0xA679B9D9D72BBA20) /* 818 */, CONST64(0x53841C0D912D43A5) /* 819 */, CONST64(0x3B7EAA48BF12A4E8) /* 820 */, CONST64(0x781E0E47F22F1DDF) /* 821 */, CONST64(0xEFF20CE60AB50973) /* 822 */, CONST64(0x20D261D19DFFB742) /* 823 */, CONST64(0x16A12B03062A2E39) /* 824 */, CONST64(0x1960EB2239650495) /* 825 */, CONST64(0x251C16FED50EB8B8) /* 826 */, CONST64(0x9AC0C330F826016E) /* 827 */, CONST64(0xED152665953E7671) /* 828 */, CONST64(0x02D63194A6369570) /* 829 */, CONST64(0x5074F08394B1C987) /* 830 */, CONST64(0x70BA598C90B25CE1) /* 831 */, CONST64(0x794A15810B9742F6) /* 832 */, CONST64(0x0D5925E9FCAF8C6C) /* 833 */, CONST64(0x3067716CD868744E) /* 834 */, CONST64(0x910AB077E8D7731B) /* 835 */, CONST64(0x6A61BBDB5AC42F61) /* 836 */, CONST64(0x93513EFBF0851567) /* 837 */, CONST64(0xF494724B9E83E9D5) /* 838 */, CONST64(0xE887E1985C09648D) /* 839 */, CONST64(0x34B1D3C675370CFD) /* 840 */, CONST64(0xDC35E433BC0D255D) /* 841 */, CONST64(0xD0AAB84234131BE0) /* 842 */, CONST64(0x08042A50B48B7EAF) /* 843 */, CONST64(0x9997C4EE44A3AB35) /* 844 */, CONST64(0x829A7B49201799D0) /* 845 */, CONST64(0x263B8307B7C54441) /* 846 */, CONST64(0x752F95F4FD6A6CA6) /* 847 */, CONST64(0x927217402C08C6E5) /* 848 */, CONST64(0x2A8AB754A795D9EE) /* 849 */, CONST64(0xA442F7552F72943D) /* 850 */, CONST64(0x2C31334E19781208) /* 851 */, CONST64(0x4FA98D7CEAEE6291) /* 852 */, CONST64(0x55C3862F665DB309) /* 853 */, CONST64(0xBD0610175D53B1F3) /* 854 */, CONST64(0x46FE6CB840413F27) /* 855 */, CONST64(0x3FE03792DF0CFA59) /* 856 */, CONST64(0xCFE700372EB85E8F) /* 857 */, CONST64(0xA7BE29E7ADBCE118) /* 858 */, CONST64(0xE544EE5CDE8431DD) /* 859 */, CONST64(0x8A781B1B41F1873E) /* 860 */, CONST64(0xA5C94C78A0D2F0E7) /* 861 */, CONST64(0x39412E2877B60728) /* 862 */, CONST64(0xA1265EF3AFC9A62C) /* 863 */, CONST64(0xBCC2770C6A2506C5) /* 864 */, CONST64(0x3AB66DD5DCE1CE12) /* 865 */, CONST64(0xE65499D04A675B37) /* 866 */, CONST64(0x7D8F523481BFD216) /* 867 */, CONST64(0x0F6F64FCEC15F389) /* 868 */, CONST64(0x74EFBE618B5B13C8) /* 869 */, CONST64(0xACDC82B714273E1D) /* 870 */, CONST64(0xDD40BFE003199D17) /* 871 */, CONST64(0x37E99257E7E061F8) /* 872 */, CONST64(0xFA52626904775AAA) /* 873 */, CONST64(0x8BBBF63A463D56F9) /* 874 */, CONST64(0xF0013F1543A26E64) /* 875 */, CONST64(0xA8307E9F879EC898) /* 876 */, CONST64(0xCC4C27A4150177CC) /* 877 */, CONST64(0x1B432F2CCA1D3348) /* 878 */, CONST64(0xDE1D1F8F9F6FA013) /* 879 */, CONST64(0x606602A047A7DDD6) /* 880 */, CONST64(0xD237AB64CC1CB2C7) /* 881 */, CONST64(0x9B938E7225FCD1D3) /* 882 */, CONST64(0xEC4E03708E0FF476) /* 883 */, CONST64(0xFEB2FBDA3D03C12D) /* 884 */, CONST64(0xAE0BCED2EE43889A) /* 885 */, CONST64(0x22CB8923EBFB4F43) /* 886 */, CONST64(0x69360D013CF7396D) /* 887 */, CONST64(0x855E3602D2D4E022) /* 888 */, CONST64(0x073805BAD01F784C) /* 889 */, CONST64(0x33E17A133852F546) /* 890 */, CONST64(0xDF4874058AC7B638) /* 891 */, CONST64(0xBA92B29C678AA14A) /* 892 */, CONST64(0x0CE89FC76CFAADCD) /* 893 */, CONST64(0x5F9D4E0908339E34) /* 894 */, CONST64(0xF1AFE9291F5923B9) /* 895 */, CONST64(0x6E3480F60F4A265F) /* 896 */, CONST64(0xEEBF3A2AB29B841C) /* 897 */, CONST64(0xE21938A88F91B4AD) /* 898 */, CONST64(0x57DFEFF845C6D3C3) /* 899 */, CONST64(0x2F006B0BF62CAAF2) /* 900 */, CONST64(0x62F479EF6F75EE78) /* 901 */, CONST64(0x11A55AD41C8916A9) /* 902 */, CONST64(0xF229D29084FED453) /* 903 */, CONST64(0x42F1C27B16B000E6) /* 904 */, CONST64(0x2B1F76749823C074) /* 905 */, CONST64(0x4B76ECA3C2745360) /* 906 */, CONST64(0x8C98F463B91691BD) /* 907 */, CONST64(0x14BCC93CF1ADE66A) /* 908 */, CONST64(0x8885213E6D458397) /* 909 */, CONST64(0x8E177DF0274D4711) /* 910 */, CONST64(0xB49B73B5503F2951) /* 911 */, CONST64(0x10168168C3F96B6B) /* 912 */, CONST64(0x0E3D963B63CAB0AE) /* 913 */, CONST64(0x8DFC4B5655A1DB14) /* 914 */, CONST64(0xF789F1356E14DE5C) /* 915 */, CONST64(0x683E68AF4E51DAC1) /* 916 */, CONST64(0xC9A84F9D8D4B0FD9) /* 917 */, CONST64(0x3691E03F52A0F9D1) /* 918 */, CONST64(0x5ED86E46E1878E80) /* 919 */, CONST64(0x3C711A0E99D07150) /* 920 */, CONST64(0x5A0865B20C4E9310) /* 921 */, CONST64(0x56FBFC1FE4F0682E) /* 922 */, CONST64(0xEA8D5DE3105EDF9B) /* 923 */, CONST64(0x71ABFDB12379187A) /* 924 */, CONST64(0x2EB99DE1BEE77B9C) /* 925 */, CONST64(0x21ECC0EA33CF4523) /* 926 */, CONST64(0x59A4D7521805C7A1) /* 927 */, CONST64(0x3896F5EB56AE7C72) /* 928 */, CONST64(0xAA638F3DB18F75DC) /* 929 */, CONST64(0x9F39358DABE9808E) /* 930 */, CONST64(0xB7DEFA91C00B72AC) /* 931 */, CONST64(0x6B5541FD62492D92) /* 932 */, CONST64(0x6DC6DEE8F92E4D5B) /* 933 */, CONST64(0x353F57ABC4BEEA7E) /* 934 */, CONST64(0x735769D6DA5690CE) /* 935 */, CONST64(0x0A234AA642391484) /* 936 */, CONST64(0xF6F9508028F80D9D) /* 937 */, CONST64(0xB8E319A27AB3F215) /* 938 */, CONST64(0x31AD9C1151341A4D) /* 939 */, CONST64(0x773C22A57BEF5805) /* 940 */, CONST64(0x45C7561A07968633) /* 941 */, CONST64(0xF913DA9E249DBE36) /* 942 */, CONST64(0xDA652D9B78A64C68) /* 943 */, CONST64(0x4C27A97F3BC334EF) /* 944 */, CONST64(0x76621220E66B17F4) /* 945 */, CONST64(0x967743899ACD7D0B) /* 946 */, CONST64(0xF3EE5BCAE0ED6782) /* 947 */, CONST64(0x409F753600C879FC) /* 948 */, CONST64(0x06D09A39B5926DB6) /* 949 */, CONST64(0x6F83AEB0317AC588) /* 950 */, CONST64(0x01E6CA4A86381F21) /* 951 */, CONST64(0x66FF3462D19F3025) /* 952 */, CONST64(0x72207C24DDFD3BFB) /* 953 */, CONST64(0x4AF6B6D3E2ECE2EB) /* 954 */, CONST64(0x9C994DBEC7EA08DE) /* 955 */, CONST64(0x49ACE597B09A8BC4) /* 956 */, CONST64(0xB38C4766CF0797BA) /* 957 */, CONST64(0x131B9373C57C2A75) /* 958 */, CONST64(0xB1822CCE61931E58) /* 959 */, CONST64(0x9D7555B909BA1C0C) /* 960 */, CONST64(0x127FAFDD937D11D2) /* 961 */, CONST64(0x29DA3BADC66D92E4) /* 962 */, CONST64(0xA2C1D57154C2ECBC) /* 963 */, CONST64(0x58C5134D82F6FE24) /* 964 */, CONST64(0x1C3AE3515B62274F) /* 965 */, CONST64(0xE907C82E01CB8126) /* 966 */, CONST64(0xF8ED091913E37FCB) /* 967 */, CONST64(0x3249D8F9C80046C9) /* 968 */, CONST64(0x80CF9BEDE388FB63) /* 969 */, CONST64(0x1881539A116CF19E) /* 970 */, CONST64(0x5103F3F76BD52457) /* 971 */, CONST64(0x15B7E6F5AE47F7A8) /* 972 */, CONST64(0xDBD7C6DED47E9CCF) /* 973 */, CONST64(0x44E55C410228BB1A) /* 974 */, CONST64(0xB647D4255EDB4E99) /* 975 */, CONST64(0x5D11882BB8AAFC30) /* 976 */, CONST64(0xF5098BBB29D3212A) /* 977 */, CONST64(0x8FB5EA14E90296B3) /* 978 */, CONST64(0x677B942157DD025A) /* 979 */, CONST64(0xFB58E7C0A390ACB5) /* 980 */, CONST64(0x89D3674C83BD4A01) /* 981 */, CONST64(0x9E2DA4DF4BF3B93B) /* 982 */, CONST64(0xFCC41E328CAB4829) /* 983 */, CONST64(0x03F38C96BA582C52) /* 984 */, CONST64(0xCAD1BDBD7FD85DB2) /* 985 */, CONST64(0xBBB442C16082AE83) /* 986 */, CONST64(0xB95FE86BA5DA9AB0) /* 987 */, CONST64(0xB22E04673771A93F) /* 988 */, CONST64(0x845358C9493152D8) /* 989 */, CONST64(0xBE2A488697B4541E) /* 990 */, CONST64(0x95A2DC2DD38E6966) /* 991 */, CONST64(0xC02C11AC923C852B) /* 992 */, CONST64(0x2388B1990DF2A87B) /* 993 */, CONST64(0x7C8008FA1B4F37BE) /* 994 */, CONST64(0x1F70D0C84D54E503) /* 995 */, CONST64(0x5490ADEC7ECE57D4) /* 996 */, CONST64(0x002B3C27D9063A3A) /* 997 */, CONST64(0x7EAEA3848030A2BF) /* 998 */, CONST64(0xC602326DED2003C0) /* 999 */, CONST64(0x83A7287D69A94086) /* 1000 */, CONST64(0xC57A5FCB30F57A8A) /* 1001 */, CONST64(0xB56844E479EBE779) /* 1002 */, CONST64(0xA373B40F05DCBCE9) /* 1003 */, CONST64(0xD71A786E88570EE2) /* 1004 */, CONST64(0x879CBACDBDE8F6A0) /* 1005 */, CONST64(0x976AD1BCC164A32F) /* 1006 */, CONST64(0xAB21E25E9666D78B) /* 1007 */, CONST64(0x901063AAE5E5C33C) /* 1008 */, CONST64(0x9818B34448698D90) /* 1009 */, CONST64(0xE36487AE3E1E8ABB) /* 1010 */, CONST64(0xAFBDF931893BDCB4) /* 1011 */, CONST64(0x6345A0DC5FBBD519) /* 1012 */, CONST64(0x8628FE269B9465CA) /* 1013 */, CONST64(0x1E5D01603F9C51EC) /* 1014 */, CONST64(0x4DE44006A15049B7) /* 1015 */, CONST64(0xBF6C70E5F776CBB1) /* 1016 */, CONST64(0x411218F2EF552BED) /* 1017 */, CONST64(0xCB0C0708705A36A3) /* 1018 */, CONST64(0xE74D14754F986044) /* 1019 */, CONST64(0xCD56D9430EA8280E) /* 1020 */, CONST64(0xC12591D7535F5065) /* 1021 */, CONST64(0xC83223F1720AEF96) /* 1022 */, CONST64(0xC3A0396F7363A51F) /* 1023 */}; #ifdef _MSC_VER #define INLINE __inline #else #define INLINE #endif /* one round of the hash function */ INLINE static void tiger_round(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 x, int mul) { ulong64 tmp; tmp = (*c ^= x); *a -= t1[byte(tmp, 0)] ^ t2[byte(tmp, 2)] ^ t3[byte(tmp, 4)] ^ t4[byte(tmp, 6)]; tmp = (*b += t4[byte(tmp, 1)] ^ t3[byte(tmp, 3)] ^ t2[byte(tmp,5)] ^ t1[byte(tmp,7)]); switch (mul) { case 5: *b = (tmp << 2) + tmp; break; case 7: *b = (tmp << 3) - tmp; break; case 9: *b = (tmp << 3) + tmp; break; } } /* one complete pass */ static void pass(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 *x, int mul) { tiger_round(a,b,c,x[0],mul); tiger_round(b,c,a,x[1],mul); tiger_round(c,a,b,x[2],mul); tiger_round(a,b,c,x[3],mul); tiger_round(b,c,a,x[4],mul); tiger_round(c,a,b,x[5],mul); tiger_round(a,b,c,x[6],mul); tiger_round(b,c,a,x[7],mul); } /* The key mixing schedule */ static void key_schedule(ulong64 *x) { x[0] -= x[7] ^ CONST64(0xA5A5A5A5A5A5A5A5); x[1] ^= x[0]; x[2] += x[1]; x[3] -= x[2] ^ ((~x[1])<<19); x[4] ^= x[3]; x[5] += x[4]; x[6] -= x[5] ^ ((~x[4])>>23); x[7] ^= x[6]; x[0] += x[7]; x[1] -= x[0] ^ ((~x[7])<<19); x[2] ^= x[1]; x[3] += x[2]; x[4] -= x[3] ^ ((~x[2])>>23); x[5] ^= x[4]; x[6] += x[5]; x[7] -= x[6] ^ CONST64(0x0123456789ABCDEF); } #ifdef LTC_CLEAN_STACK static int _tiger_compress(hash_state *md, unsigned char *buf) #else static int tiger_compress(hash_state *md, unsigned char *buf) #endif { ulong64 a, b, c, x[8]; unsigned long i; /* load words */ for (i = 0; i < 8; i++) { LOAD64L(x[i],&buf[8*i]); } a = md->tiger.state[0]; b = md->tiger.state[1]; c = md->tiger.state[2]; pass(&a,&b,&c,x,5); key_schedule(x); pass(&c,&a,&b,x,7); key_schedule(x); pass(&b,&c,&a,x,9); /* store state */ md->tiger.state[0] = a ^ md->tiger.state[0]; md->tiger.state[1] = b - md->tiger.state[1]; md->tiger.state[2] = c + md->tiger.state[2]; return CRYPT_OK; } #ifdef LTC_CLEAN_STACK static int tiger_compress(hash_state *md, unsigned char *buf) { int err; err = _tiger_compress(md, buf); burn_stack(sizeof(ulong64) * 11 + sizeof(unsigned long)); return err; } #endif /** Initialize the hash state @param md The hash state you wish to initialize @return CRYPT_OK if successful */ int tiger_init(hash_state *md) { LTC_ARGCHK(md != NULL); md->tiger.state[0] = CONST64(0x0123456789ABCDEF); md->tiger.state[1] = CONST64(0xFEDCBA9876543210); md->tiger.state[2] = CONST64(0xF096A5B4C3B2E187); md->tiger.curlen = 0; md->tiger.length = 0; return CRYPT_OK; } /** Process a block of memory though the hash @param md The hash state @param in The data to hash @param inlen The length of the data (octets) @return CRYPT_OK if successful */ HASH_PROCESS(tiger_process, tiger_compress, tiger, 64) /** Terminate the hash to get the digest @param md The hash state @param out [out] The destination of the hash (24 bytes) @return CRYPT_OK if successful */ int tiger_done(hash_state * md, unsigned char *out) { LTC_ARGCHK(md != NULL); LTC_ARGCHK(out != NULL); if (md->tiger.curlen >= sizeof(md->tiger.buf)) { return CRYPT_INVALID_ARG; } /* increase the length of the message */ md->tiger.length += md->tiger.curlen * 8; /* append the '1' bit */ md->tiger.buf[md->tiger.curlen++] = (unsigned char)0x01; /* if the length is currently above 56 bytes we append zeros * then compress. Then we can fall back to padding zeros and length * encoding like normal. */ if (md->tiger.curlen > 56) { while (md->tiger.curlen < 64) { md->tiger.buf[md->tiger.curlen++] = (unsigned char)0; } tiger_compress(md, md->tiger.buf); md->tiger.curlen = 0; } /* pad upto 56 bytes of zeroes */ while (md->tiger.curlen < 56) { md->tiger.buf[md->tiger.curlen++] = (unsigned char)0; } /* store length */ STORE64L(md->tiger.length, md->tiger.buf+56); tiger_compress(md, md->tiger.buf); /* copy output */ STORE64L(md->tiger.state[0], &out[0]); STORE64L(md->tiger.state[1], &out[8]); STORE64L(md->tiger.state[2], &out[16]); #ifdef LTC_CLEAN_STACK zeromem(md, sizeof(hash_state)); #endif return CRYPT_OK; } /** Self-test the hash @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled */ int tiger_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { char *msg; unsigned char hash[24]; } tests[] = { { "", { 0x32, 0x93, 0xac, 0x63, 0x0c, 0x13, 0xf0, 0x24, 0x5f, 0x92, 0xbb, 0xb1, 0x76, 0x6e, 0x16, 0x16, 0x7a, 0x4e, 0x58, 0x49, 0x2d, 0xde, 0x73, 0xf3 } }, { "abc", { 0x2a, 0xab, 0x14, 0x84, 0xe8, 0xc1, 0x58, 0xf2, 0xbf, 0xb8, 0xc5, 0xff, 0x41, 0xb5, 0x7a, 0x52, 0x51, 0x29, 0x13, 0x1c, 0x95, 0x7b, 0x5f, 0x93 } }, { "Tiger", { 0xdd, 0x00, 0x23, 0x07, 0x99, 0xf5, 0x00, 0x9f, 0xec, 0x6d, 0xeb, 0xc8, 0x38, 0xbb, 0x6a, 0x27, 0xdf, 0x2b, 0x9d, 0x6f, 0x11, 0x0c, 0x79, 0x37 } }, { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", { 0xf7, 0x1c, 0x85, 0x83, 0x90, 0x2a, 0xfb, 0x87, 0x9e, 0xdf, 0xe6, 0x10, 0xf8, 0x2c, 0x0d, 0x47, 0x86, 0xa3, 0xa5, 0x34, 0x50, 0x44, 0x86, 0xb5 } }, { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", { 0xc5, 0x40, 0x34, 0xe5, 0xb4, 0x3e, 0xb8, 0x00, 0x58, 0x48, 0xa7, 0xe0, 0xae, 0x6a, 0xac, 0x76, 0xe4, 0xff, 0x59, 0x0a, 0xe7, 0x15, 0xfd, 0x25 } }, }; int i; unsigned char tmp[24]; hash_state md; for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { tiger_init(&md); tiger_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg)); tiger_done(&md, tmp); if (XMEMCMP(tmp, tests[i].hash, 24) != 0) { return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } #endif /* Hash of "": 24F0130C63AC9332 16166E76B1BB925F F373DE2D49584E7A Hash of "abc": F258C1E88414AB2A 527AB541FFC5B8BF 935F7B951C132951 Hash of "Tiger": 9F00F599072300DD 276ABB38C8EB6DEC 37790C116F9D2BDF Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-": 87FB2A9083851CF7 470D2CF810E6DF9E B586445034A5A386 Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789": 467DB80863EBCE48 8DF1CD1261655DE9 57896565975F9197 Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham": 0C410A042968868A 1671DA5A3FD29A72 5EC1E457D3CDB303 Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge.": EBF591D5AFA655CE 7F22894FF87F54AC 89C811B6B0DA3193 Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge, 1996.": 3D9AEB03D1BD1A63 57B2774DFD6D5B24 DD68151D503974FC Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-": 00B83EB4E53440C5 76AC6AAEE0A74858 25FD15E70A59FFE4 */ /* $Source: /cvs/libtom/libtomcrypt/src/hashes/tiger.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2007/05/12 14:25:28 $ */ libtomcrypt-1.17/src/hashes/helper/0000755000175100001440000000000010621351501016044 5ustar tomuserslibtomcrypt-1.17/src/hashes/helper/hash_memory_multi.c0000644000175100001440000000470710621351501021745 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" #include /** @file hash_memory_multi.c Hash (multiple buffers) memory helper, Tom St Denis */ /** Hash multiple (non-adjacent) blocks of memory at once. @param hash The index of the hash you wish to use @param out [out] Where to store the digest @param outlen [in/out] Max size and resulting size of the digest @param in The data you wish to hash @param inlen The length of the data to hash (octets) @param ... tuples of (data,len) pairs to hash, terminated with a (NULL,x) (x=don't care) @return CRYPT_OK if successful */ int hash_memory_multi(int hash, unsigned char *out, unsigned long *outlen, const unsigned char *in, unsigned long inlen, ...) { hash_state *md; int err; va_list args; const unsigned char *curptr; unsigned long curlen; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); if ((err = hash_is_valid(hash)) != CRYPT_OK) { return err; } if (*outlen < hash_descriptor[hash].hashsize) { *outlen = hash_descriptor[hash].hashsize; return CRYPT_BUFFER_OVERFLOW; } md = XMALLOC(sizeof(hash_state)); if (md == NULL) { return CRYPT_MEM; } if ((err = hash_descriptor[hash].init(md)) != CRYPT_OK) { goto LBL_ERR; } va_start(args, inlen); curptr = in; curlen = inlen; for (;;) { /* process buf */ if ((err = hash_descriptor[hash].process(md, curptr, curlen)) != CRYPT_OK) { goto LBL_ERR; } /* step to next */ curptr = va_arg(args, const unsigned char*); if (curptr == NULL) { break; } curlen = va_arg(args, unsigned long); } err = hash_descriptor[hash].done(md, out); *outlen = hash_descriptor[hash].hashsize; LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(md, sizeof(hash_state)); #endif XFREE(md); va_end(args); return err; } /* $Source: /cvs/libtom/libtomcrypt/src/hashes/helper/hash_memory_multi.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/hashes/helper/hash_file.c0000644000175100001440000000255110621351501020135 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file hash_file.c Hash a file, Tom St Denis */ /** @param hash The index of the hash desired @param fname The name of the file you wish to hash @param out [out] The destination of the digest @param outlen [in/out] The max size and resulting size of the message digest @result CRYPT_OK if successful */ int hash_file(int hash, const char *fname, unsigned char *out, unsigned long *outlen) { #ifdef LTC_NO_FILE return CRYPT_NOP; #else FILE *in; int err; LTC_ARGCHK(fname != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); if ((err = hash_is_valid(hash)) != CRYPT_OK) { return err; } in = fopen(fname, "rb"); if (in == NULL) { return CRYPT_FILE_NOTFOUND; } err = hash_filehandle(hash, in, out, outlen); if (fclose(in) != 0) { return CRYPT_ERROR; } return err; #endif } /* $Source: /cvs/libtom/libtomcrypt/src/hashes/helper/hash_file.c,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/hashes/helper/hash_memory.c0000644000175100001440000000351410621351501020526 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file hash_memory.c Hash memory helper, Tom St Denis */ /** Hash a block of memory and store the digest. @param hash The index of the hash you wish to use @param in The data you wish to hash @param inlen The length of the data to hash (octets) @param out [out] Where to store the digest @param outlen [in/out] Max size and resulting size of the digest @return CRYPT_OK if successful */ int hash_memory(int hash, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen) { hash_state *md; int err; LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); if ((err = hash_is_valid(hash)) != CRYPT_OK) { return err; } if (*outlen < hash_descriptor[hash].hashsize) { *outlen = hash_descriptor[hash].hashsize; return CRYPT_BUFFER_OVERFLOW; } md = XMALLOC(sizeof(hash_state)); if (md == NULL) { return CRYPT_MEM; } if ((err = hash_descriptor[hash].init(md)) != CRYPT_OK) { goto LBL_ERR; } if ((err = hash_descriptor[hash].process(md, in, inlen)) != CRYPT_OK) { goto LBL_ERR; } err = hash_descriptor[hash].done(md, out); *outlen = hash_descriptor[hash].hashsize; LBL_ERR: #ifdef LTC_CLEAN_STACK zeromem(md, sizeof(hash_state)); #endif XFREE(md); return err; } /* $Source: /cvs/libtom/libtomcrypt/src/hashes/helper/hash_memory.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/hashes/helper/hash_filehandle.c0000644000175100001440000000352710621351501021315 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file hash_filehandle.c Hash open files, Tom St Denis */ /** Hash data from an open file handle. @param hash The index of the hash you want to use @param in The FILE* handle of the file you want to hash @param out [out] The destination of the digest @param outlen [in/out] The max size and resulting size of the digest @result CRYPT_OK if successful */ int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outlen) { #ifdef LTC_NO_FILE return CRYPT_NOP; #else hash_state md; unsigned char buf[512]; size_t x; int err; LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); LTC_ARGCHK(in != NULL); if ((err = hash_is_valid(hash)) != CRYPT_OK) { return err; } if (*outlen < hash_descriptor[hash].hashsize) { *outlen = hash_descriptor[hash].hashsize; return CRYPT_BUFFER_OVERFLOW; } if ((err = hash_descriptor[hash].init(&md)) != CRYPT_OK) { return err; } *outlen = hash_descriptor[hash].hashsize; do { x = fread(buf, 1, sizeof(buf), in); if ((err = hash_descriptor[hash].process(&md, buf, x)) != CRYPT_OK) { return err; } } while (x == sizeof(buf)); err = hash_descriptor[hash].done(&md, out); #ifdef LTC_CLEAN_STACK zeromem(buf, sizeof(buf)); #endif return err; #endif } /* $Source: /cvs/libtom/libtomcrypt/src/hashes/helper/hash_filehandle.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/hashes/sha1.c0000644000175100001440000001531710621351501015574 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file sha1.c LTC_SHA1 code by Tom St Denis */ #ifdef LTC_SHA1 const struct ltc_hash_descriptor sha1_desc = { "sha1", 2, 20, 64, /* OID */ { 1, 3, 14, 3, 2, 26, }, 6, &sha1_init, &sha1_process, &sha1_done, &sha1_test, NULL }; #define F0(x,y,z) (z ^ (x & (y ^ z))) #define F1(x,y,z) (x ^ y ^ z) #define F2(x,y,z) ((x & y) | (z & (x | y))) #define F3(x,y,z) (x ^ y ^ z) #ifdef LTC_CLEAN_STACK static int _sha1_compress(hash_state *md, unsigned char *buf) #else static int sha1_compress(hash_state *md, unsigned char *buf) #endif { ulong32 a,b,c,d,e,W[80],i; #ifdef LTC_SMALL_CODE ulong32 t; #endif /* copy the state into 512-bits into W[0..15] */ for (i = 0; i < 16; i++) { LOAD32H(W[i], buf + (4*i)); } /* copy state */ a = md->sha1.state[0]; b = md->sha1.state[1]; c = md->sha1.state[2]; d = md->sha1.state[3]; e = md->sha1.state[4]; /* expand it */ for (i = 16; i < 80; i++) { W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1); } /* compress */ /* round one */ #define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30); #define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30); #define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30); #define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30); #ifdef LTC_SMALL_CODE for (i = 0; i < 20; ) { FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; } for (; i < 40; ) { FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; } for (; i < 60; ) { FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; } for (; i < 80; ) { FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t; } #else for (i = 0; i < 20; ) { FF0(a,b,c,d,e,i++); FF0(e,a,b,c,d,i++); FF0(d,e,a,b,c,i++); FF0(c,d,e,a,b,i++); FF0(b,c,d,e,a,i++); } /* round two */ for (; i < 40; ) { FF1(a,b,c,d,e,i++); FF1(e,a,b,c,d,i++); FF1(d,e,a,b,c,i++); FF1(c,d,e,a,b,i++); FF1(b,c,d,e,a,i++); } /* round three */ for (; i < 60; ) { FF2(a,b,c,d,e,i++); FF2(e,a,b,c,d,i++); FF2(d,e,a,b,c,i++); FF2(c,d,e,a,b,i++); FF2(b,c,d,e,a,i++); } /* round four */ for (; i < 80; ) { FF3(a,b,c,d,e,i++); FF3(e,a,b,c,d,i++); FF3(d,e,a,b,c,i++); FF3(c,d,e,a,b,i++); FF3(b,c,d,e,a,i++); } #endif #undef FF0 #undef FF1 #undef FF2 #undef FF3 /* store */ md->sha1.state[0] = md->sha1.state[0] + a; md->sha1.state[1] = md->sha1.state[1] + b; md->sha1.state[2] = md->sha1.state[2] + c; md->sha1.state[3] = md->sha1.state[3] + d; md->sha1.state[4] = md->sha1.state[4] + e; return CRYPT_OK; } #ifdef LTC_CLEAN_STACK static int sha1_compress(hash_state *md, unsigned char *buf) { int err; err = _sha1_compress(md, buf); burn_stack(sizeof(ulong32) * 87); return err; } #endif /** Initialize the hash state @param md The hash state you wish to initialize @return CRYPT_OK if successful */ int sha1_init(hash_state * md) { LTC_ARGCHK(md != NULL); md->sha1.state[0] = 0x67452301UL; md->sha1.state[1] = 0xefcdab89UL; md->sha1.state[2] = 0x98badcfeUL; md->sha1.state[3] = 0x10325476UL; md->sha1.state[4] = 0xc3d2e1f0UL; md->sha1.curlen = 0; md->sha1.length = 0; return CRYPT_OK; } /** Process a block of memory though the hash @param md The hash state @param in The data to hash @param inlen The length of the data (octets) @return CRYPT_OK if successful */ HASH_PROCESS(sha1_process, sha1_compress, sha1, 64) /** Terminate the hash to get the digest @param md The hash state @param out [out] The destination of the hash (20 bytes) @return CRYPT_OK if successful */ int sha1_done(hash_state * md, unsigned char *out) { int i; LTC_ARGCHK(md != NULL); LTC_ARGCHK(out != NULL); if (md->sha1.curlen >= sizeof(md->sha1.buf)) { return CRYPT_INVALID_ARG; } /* increase the length of the message */ md->sha1.length += md->sha1.curlen * 8; /* append the '1' bit */ md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80; /* if the length is currently above 56 bytes we append zeros * then compress. Then we can fall back to padding zeros and length * encoding like normal. */ if (md->sha1.curlen > 56) { while (md->sha1.curlen < 64) { md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; } sha1_compress(md, md->sha1.buf); md->sha1.curlen = 0; } /* pad upto 56 bytes of zeroes */ while (md->sha1.curlen < 56) { md->sha1.buf[md->sha1.curlen++] = (unsigned char)0; } /* store length */ STORE64H(md->sha1.length, md->sha1.buf+56); sha1_compress(md, md->sha1.buf); /* copy output */ for (i = 0; i < 5; i++) { STORE32H(md->sha1.state[i], out+(4*i)); } #ifdef LTC_CLEAN_STACK zeromem(md, sizeof(hash_state)); #endif return CRYPT_OK; } /** Self-test the hash @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled */ int sha1_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { char *msg; unsigned char hash[20]; } tests[] = { { "abc", { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, 0x9c, 0xd0, 0xd8, 0x9d } }, { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 } } }; int i; unsigned char tmp[20]; hash_state md; for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { sha1_init(&md); sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg)); sha1_done(&md, tmp); if (XMEMCMP(tmp, tests[i].hash, 20) != 0) { return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha1.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2007/05/12 14:25:28 $ */ libtomcrypt-1.17/src/headers/0000755000175100001440000000000010621351501014725 5ustar tomuserslibtomcrypt-1.17/src/headers/tomcrypt_cfg.h0000644000175100001440000000743510621351501017607 0ustar tomusers/* This is the build config file. * * With this you can setup what to inlcude/exclude automatically during any build. Just comment * out the line that #define's the word for the thing you want to remove. phew! */ #ifndef TOMCRYPT_CFG_H #define TOMCRYPT_CFG_H #if defined(_WIN32) || defined(_MSC_VER) #define LTC_CALL __cdecl #else #ifndef LTC_CALL #define LTC_CALL #endif #endif #ifndef LTC_EXPORT #define LTC_EXPORT #endif /* certain platforms use macros for these, making the prototypes broken */ #ifndef LTC_NO_PROTOTYPES /* you can change how memory allocation works ... */ LTC_EXPORT void * LTC_CALL XMALLOC(size_t n); LTC_EXPORT void * LTC_CALL XREALLOC(void *p, size_t n); LTC_EXPORT void * LTC_CALL XCALLOC(size_t n, size_t s); LTC_EXPORT void LTC_CALL XFREE(void *p); LTC_EXPORT void LTC_CALL XQSORT(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *)); /* change the clock function too */ LTC_EXPORT clock_t LTC_CALL XCLOCK(void); /* various other functions */ LTC_EXPORT void * LTC_CALL XMEMCPY(void *dest, const void *src, size_t n); LTC_EXPORT int LTC_CALL XMEMCMP(const void *s1, const void *s2, size_t n); LTC_EXPORT void * LTC_CALL XMEMSET(void *s, int c, size_t n); LTC_EXPORT int LTC_CALL XSTRCMP(const char *s1, const char *s2); #endif /* type of argument checking, 0=default, 1=fatal and 2=error+continue, 3=nothing */ #ifndef ARGTYPE #define ARGTYPE 0 #endif /* Controls endianess and size of registers. Leave uncommented to get platform neutral [slower] code * * Note: in order to use the optimized macros your platform must support unaligned 32 and 64 bit read/writes. * The x86 platforms allow this but some others [ARM for instance] do not. On those platforms you **MUST** * use the portable [slower] macros. */ /* detect x86-32 machines somewhat */ #if !defined(__STRICT_ANSI__) && (defined(INTEL_CC) || (defined(_MSC_VER) && defined(WIN32)) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__)))) #define ENDIAN_LITTLE #define ENDIAN_32BITWORD #define LTC_FAST #define LTC_FAST_TYPE unsigned long #endif /* detects MIPS R5900 processors (PS2) */ #if (defined(__R5900) || defined(R5900) || defined(__R5900__)) && (defined(_mips) || defined(__mips__) || defined(mips)) #define ENDIAN_LITTLE #define ENDIAN_64BITWORD #endif /* detect amd64 */ #if !defined(__STRICT_ANSI__) && defined(__x86_64__) #define ENDIAN_LITTLE #define ENDIAN_64BITWORD #define LTC_FAST #define LTC_FAST_TYPE unsigned long #endif /* detect PPC32 */ #if !defined(__STRICT_ANSI__) && defined(LTC_PPC32) #define ENDIAN_BIG #define ENDIAN_32BITWORD #define LTC_FAST #define LTC_FAST_TYPE unsigned long #endif /* detect sparc and sparc64 */ #if defined(__sparc__) #define ENDIAN_BIG #if defined(__arch64__) #define ENDIAN_64BITWORD #else #define ENDIAN_32BITWORD #endif #endif #ifdef LTC_NO_FAST #ifdef LTC_FAST #undef LTC_FAST #endif #endif /* No asm is a quick way to disable anything "not portable" */ #ifdef LTC_NO_ASM #undef ENDIAN_LITTLE #undef ENDIAN_BIG #undef ENDIAN_32BITWORD #undef ENDIAN_64BITWORD #undef LTC_FAST #undef LTC_FAST_TYPE #define LTC_NO_ROLC #define LTC_NO_BSWAP #endif /* #define ENDIAN_LITTLE */ /* #define ENDIAN_BIG */ /* #define ENDIAN_32BITWORD */ /* #define ENDIAN_64BITWORD */ #if (defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) && !(defined(ENDIAN_32BITWORD) || defined(ENDIAN_64BITWORD)) #error You must specify a word size as well as endianess in tomcrypt_cfg.h #endif #if !(defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) #define ENDIAN_NEUTRAL #endif #endif /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_cfg.h,v $ */ /* $Revision: 1.19 $ */ /* $Date: 2006/12/04 02:19:48 $ */ libtomcrypt-1.17/src/headers/tomcrypt_mac.h0000644000175100001440000003422210621351501017602 0ustar tomusers#ifdef LTC_HMAC typedef struct Hmac_state { hash_state md; int hash; hash_state hashstate; unsigned char *key; } hmac_state; int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen); int hmac_process(hmac_state *hmac, const unsigned char *in, unsigned long inlen); int hmac_done(hmac_state *hmac, unsigned char *out, unsigned long *outlen); int hmac_test(void); int hmac_memory(int hash, const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); int hmac_memory_multi(int hash, const unsigned char *key, unsigned long keylen, unsigned char *out, unsigned long *outlen, const unsigned char *in, unsigned long inlen, ...); int hmac_file(int hash, const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *dst, unsigned long *dstlen); #endif #ifdef LTC_OMAC typedef struct { int cipher_idx, buflen, blklen; unsigned char block[MAXBLOCKSIZE], prev[MAXBLOCKSIZE], Lu[2][MAXBLOCKSIZE]; symmetric_key key; } omac_state; int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned long keylen); int omac_process(omac_state *omac, const unsigned char *in, unsigned long inlen); int omac_done(omac_state *omac, unsigned char *out, unsigned long *outlen); int omac_memory(int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); int omac_memory_multi(int cipher, const unsigned char *key, unsigned long keylen, unsigned char *out, unsigned long *outlen, const unsigned char *in, unsigned long inlen, ...); int omac_file(int cipher, const unsigned char *key, unsigned long keylen, const char *filename, unsigned char *out, unsigned long *outlen); int omac_test(void); #endif /* LTC_OMAC */ #ifdef LTC_PMAC typedef struct { unsigned char Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */ Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */ Lr[MAXBLOCKSIZE], /* L * x^-1 */ block[MAXBLOCKSIZE], /* currently accumulated block */ checksum[MAXBLOCKSIZE]; /* current checksum */ symmetric_key key; /* scheduled key for cipher */ unsigned long block_index; /* index # for current block */ int cipher_idx, /* cipher idx */ block_len, /* length of block */ buflen; /* number of bytes in the buffer */ } pmac_state; int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned long keylen); int pmac_process(pmac_state *pmac, const unsigned char *in, unsigned long inlen); int pmac_done(pmac_state *pmac, unsigned char *out, unsigned long *outlen); int pmac_memory(int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *msg, unsigned long msglen, unsigned char *out, unsigned long *outlen); int pmac_memory_multi(int cipher, const unsigned char *key, unsigned long keylen, unsigned char *out, unsigned long *outlen, const unsigned char *in, unsigned long inlen, ...); int pmac_file(int cipher, const unsigned char *key, unsigned long keylen, const char *filename, unsigned char *out, unsigned long *outlen); int pmac_test(void); /* internal functions */ int pmac_ntz(unsigned long x); void pmac_shift_xor(pmac_state *pmac); #endif /* PMAC */ #ifdef LTC_EAX_MODE #if !(defined(LTC_OMAC) && defined(LTC_CTR_MODE)) #error LTC_EAX_MODE requires LTC_OMAC and CTR #endif typedef struct { unsigned char N[MAXBLOCKSIZE]; symmetric_CTR ctr; omac_state headeromac, ctomac; } eax_state; int eax_init(eax_state *eax, int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *nonce, unsigned long noncelen, const unsigned char *header, unsigned long headerlen); int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, unsigned long length); int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, unsigned long length); int eax_addheader(eax_state *eax, const unsigned char *header, unsigned long length); int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen); int eax_encrypt_authenticate_memory(int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *nonce, unsigned long noncelen, const unsigned char *header, unsigned long headerlen, const unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tag, unsigned long *taglen); int eax_decrypt_verify_memory(int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *nonce, unsigned long noncelen, const unsigned char *header, unsigned long headerlen, const unsigned char *ct, unsigned long ctlen, unsigned char *pt, unsigned char *tag, unsigned long taglen, int *stat); int eax_test(void); #endif /* EAX MODE */ #ifdef LTC_OCB_MODE typedef struct { unsigned char L[MAXBLOCKSIZE], /* L value */ Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */ Li[MAXBLOCKSIZE], /* value of Li [current value, we calc from previous recall] */ Lr[MAXBLOCKSIZE], /* L * x^-1 */ R[MAXBLOCKSIZE], /* R value */ checksum[MAXBLOCKSIZE]; /* current checksum */ symmetric_key key; /* scheduled key for cipher */ unsigned long block_index; /* index # for current block */ int cipher, /* cipher idx */ block_len; /* length of block */ } ocb_state; int ocb_init(ocb_state *ocb, int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *nonce); int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct); int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt); int ocb_done_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tag, unsigned long *taglen); int ocb_done_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt, const unsigned char *tag, unsigned long taglen, int *stat); int ocb_encrypt_authenticate_memory(int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *nonce, const unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tag, unsigned long *taglen); int ocb_decrypt_verify_memory(int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *nonce, const unsigned char *ct, unsigned long ctlen, unsigned char *pt, const unsigned char *tag, unsigned long taglen, int *stat); int ocb_test(void); /* internal functions */ void ocb_shift_xor(ocb_state *ocb, unsigned char *Z); int ocb_ntz(unsigned long x); int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tag, unsigned long *taglen, int mode); #endif /* LTC_OCB_MODE */ #ifdef LTC_CCM_MODE #define CCM_ENCRYPT 0 #define CCM_DECRYPT 1 int ccm_memory(int cipher, const unsigned char *key, unsigned long keylen, symmetric_key *uskey, const unsigned char *nonce, unsigned long noncelen, const unsigned char *header, unsigned long headerlen, unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tag, unsigned long *taglen, int direction); int ccm_test(void); #endif /* LTC_CCM_MODE */ #if defined(LRW_MODE) || defined(LTC_GCM_MODE) void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c); #endif /* table shared between GCM and LRW */ #if defined(LTC_GCM_TABLES) || defined(LRW_TABLES) || ((defined(LTC_GCM_MODE) || defined(LTC_GCM_MODE)) && defined(LTC_FAST)) extern const unsigned char gcm_shift_table[]; #endif #ifdef LTC_GCM_MODE #define GCM_ENCRYPT 0 #define GCM_DECRYPT 1 #define LTC_GCM_MODE_IV 0 #define LTC_GCM_MODE_AAD 1 #define LTC_GCM_MODE_TEXT 2 typedef struct { symmetric_key K; unsigned char H[16], /* multiplier */ X[16], /* accumulator */ Y[16], /* counter */ Y_0[16], /* initial counter */ buf[16]; /* buffer for stuff */ int cipher, /* which cipher */ ivmode, /* Which mode is the IV in? */ mode, /* mode the GCM code is in */ buflen; /* length of data in buf */ ulong64 totlen, /* 64-bit counter used for IV and AAD */ pttotlen; /* 64-bit counter for the PT */ #ifdef LTC_GCM_TABLES unsigned char PC[16][256][16] /* 16 tables of 8x128 */ #ifdef LTC_GCM_TABLES_SSE2 __attribute__ ((aligned (16))) #endif ; #endif } gcm_state; void gcm_mult_h(gcm_state *gcm, unsigned char *I); int gcm_init(gcm_state *gcm, int cipher, const unsigned char *key, int keylen); int gcm_reset(gcm_state *gcm); int gcm_add_iv(gcm_state *gcm, const unsigned char *IV, unsigned long IVlen); int gcm_add_aad(gcm_state *gcm, const unsigned char *adata, unsigned long adatalen); int gcm_process(gcm_state *gcm, unsigned char *pt, unsigned long ptlen, unsigned char *ct, int direction); int gcm_done(gcm_state *gcm, unsigned char *tag, unsigned long *taglen); int gcm_memory( int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *IV, unsigned long IVlen, const unsigned char *adata, unsigned long adatalen, unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tag, unsigned long *taglen, int direction); int gcm_test(void); #endif /* LTC_GCM_MODE */ #ifdef LTC_PELICAN typedef struct pelican_state { symmetric_key K; unsigned char state[16]; int buflen; } pelican_state; int pelican_init(pelican_state *pelmac, const unsigned char *key, unsigned long keylen); int pelican_process(pelican_state *pelmac, const unsigned char *in, unsigned long inlen); int pelican_done(pelican_state *pelmac, unsigned char *out); int pelican_test(void); int pelican_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out); #endif #ifdef LTC_XCBC /* add this to "keylen" to xcbc_init to use a pure three-key XCBC MAC */ #define LTC_XCBC_PURE 0x8000UL typedef struct { unsigned char K[3][MAXBLOCKSIZE], IV[MAXBLOCKSIZE]; symmetric_key key; int cipher, buflen, blocksize; } xcbc_state; int xcbc_init(xcbc_state *xcbc, int cipher, const unsigned char *key, unsigned long keylen); int xcbc_process(xcbc_state *xcbc, const unsigned char *in, unsigned long inlen); int xcbc_done(xcbc_state *xcbc, unsigned char *out, unsigned long *outlen); int xcbc_memory(int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); int xcbc_memory_multi(int cipher, const unsigned char *key, unsigned long keylen, unsigned char *out, unsigned long *outlen, const unsigned char *in, unsigned long inlen, ...); int xcbc_file(int cipher, const unsigned char *key, unsigned long keylen, const char *filename, unsigned char *out, unsigned long *outlen); int xcbc_test(void); #endif #ifdef LTC_F9_MODE typedef struct { unsigned char akey[MAXBLOCKSIZE], ACC[MAXBLOCKSIZE], IV[MAXBLOCKSIZE]; symmetric_key key; int cipher, buflen, keylen, blocksize; } f9_state; int f9_init(f9_state *f9, int cipher, const unsigned char *key, unsigned long keylen); int f9_process(f9_state *f9, const unsigned char *in, unsigned long inlen); int f9_done(f9_state *f9, unsigned char *out, unsigned long *outlen); int f9_memory(int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); int f9_memory_multi(int cipher, const unsigned char *key, unsigned long keylen, unsigned char *out, unsigned long *outlen, const unsigned char *in, unsigned long inlen, ...); int f9_file(int cipher, const unsigned char *key, unsigned long keylen, const char *filename, unsigned char *out, unsigned long *outlen); int f9_test(void); #endif /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_mac.h,v $ */ /* $Revision: 1.23 $ */ /* $Date: 2007/05/12 14:37:41 $ */ libtomcrypt-1.17/src/headers/tomcrypt_macros.h0000644000175100001440000003403510621351501020330 0ustar tomusers/* fix for MSVC ...evil! */ #ifdef _MSC_VER #define CONST64(n) n ## ui64 typedef unsigned __int64 ulong64; #else #define CONST64(n) n ## ULL typedef unsigned long long ulong64; #endif /* this is the "32-bit at least" data type * Re-define it to suit your platform but it must be at least 32-bits */ #if defined(__x86_64__) || (defined(__sparc__) && defined(__arch64__)) typedef unsigned ulong32; #else typedef unsigned long ulong32; #endif /* ---- HELPER MACROS ---- */ #ifdef ENDIAN_NEUTRAL #define STORE32L(x, y) \ { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } #define LOAD32L(x, y) \ { x = ((unsigned long)((y)[3] & 255)<<24) | \ ((unsigned long)((y)[2] & 255)<<16) | \ ((unsigned long)((y)[1] & 255)<<8) | \ ((unsigned long)((y)[0] & 255)); } #define STORE64L(x, y) \ { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } #define LOAD64L(x, y) \ { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \ (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \ (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \ (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } #define STORE32H(x, y) \ { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } #define LOAD32H(x, y) \ { x = ((unsigned long)((y)[0] & 255)<<24) | \ ((unsigned long)((y)[1] & 255)<<16) | \ ((unsigned long)((y)[2] & 255)<<8) | \ ((unsigned long)((y)[3] & 255)); } #define STORE64H(x, y) \ { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } #define LOAD64H(x, y) \ { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \ (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \ (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } #endif /* ENDIAN_NEUTRAL */ #ifdef ENDIAN_LITTLE #if !defined(LTC_NO_BSWAP) && (defined(INTEL_CC) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__) || defined(__x86_64__)))) #define STORE32H(x, y) \ asm __volatile__ ( \ "bswapl %0 \n\t" \ "movl %0,(%1)\n\t" \ "bswapl %0 \n\t" \ ::"r"(x), "r"(y)); #define LOAD32H(x, y) \ asm __volatile__ ( \ "movl (%1),%0\n\t" \ "bswapl %0\n\t" \ :"=r"(x): "r"(y)); #else #define STORE32H(x, y) \ { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \ (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); } #define LOAD32H(x, y) \ { x = ((unsigned long)((y)[0] & 255)<<24) | \ ((unsigned long)((y)[1] & 255)<<16) | \ ((unsigned long)((y)[2] & 255)<<8) | \ ((unsigned long)((y)[3] & 255)); } #endif /* x86_64 processor */ #if !defined(LTC_NO_BSWAP) && (defined(__GNUC__) && defined(__x86_64__)) #define STORE64H(x, y) \ asm __volatile__ ( \ "bswapq %0 \n\t" \ "movq %0,(%1)\n\t" \ "bswapq %0 \n\t" \ ::"r"(x), "r"(y)); #define LOAD64H(x, y) \ asm __volatile__ ( \ "movq (%1),%0\n\t" \ "bswapq %0\n\t" \ :"=r"(x): "r"(y)); #else #define STORE64H(x, y) \ { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } #define LOAD64H(x, y) \ { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \ (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \ (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \ (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); } #endif #ifdef ENDIAN_32BITWORD #define STORE32L(x, y) \ { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } #define LOAD32L(x, y) \ XMEMCPY(&(x), y, 4); #define STORE64L(x, y) \ { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } #define LOAD64L(x, y) \ { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \ (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \ (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \ (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } #else /* 64-bit words then */ #define STORE32L(x, y) \ { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } #define LOAD32L(x, y) \ { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } #define STORE64L(x, y) \ { ulong64 __t = (x); XMEMCPY(y, &__t, 8); } #define LOAD64L(x, y) \ { XMEMCPY(&(x), y, 8); } #endif /* ENDIAN_64BITWORD */ #endif /* ENDIAN_LITTLE */ #ifdef ENDIAN_BIG #define STORE32L(x, y) \ { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } #define LOAD32L(x, y) \ { x = ((unsigned long)((y)[3] & 255)<<24) | \ ((unsigned long)((y)[2] & 255)<<16) | \ ((unsigned long)((y)[1] & 255)<<8) | \ ((unsigned long)((y)[0] & 255)); } #define STORE64L(x, y) \ { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \ (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \ (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \ (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); } #define LOAD64L(x, y) \ { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48) | \ (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32) | \ (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16) | \ (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); } #ifdef ENDIAN_32BITWORD #define STORE32H(x, y) \ { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } #define LOAD32H(x, y) \ XMEMCPY(&(x), y, 4); #define STORE64H(x, y) \ { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \ (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \ (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \ (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); } #define LOAD64H(x, y) \ { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48)| \ (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32)| \ (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16)| \ (((ulong64)((y)[6] & 255))<<8)| (((ulong64)((y)[7] & 255))); } #else /* 64-bit words then */ #define STORE32H(x, y) \ { ulong32 __t = (x); XMEMCPY(y, &__t, 4); } #define LOAD32H(x, y) \ { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; } #define STORE64H(x, y) \ { ulong64 __t = (x); XMEMCPY(y, &__t, 8); } #define LOAD64H(x, y) \ { XMEMCPY(&(x), y, 8); } #endif /* ENDIAN_64BITWORD */ #endif /* ENDIAN_BIG */ #define BSWAP(x) ( ((x>>24)&0x000000FFUL) | ((x<<24)&0xFF000000UL) | \ ((x>>8)&0x0000FF00UL) | ((x<<8)&0x00FF0000UL) ) /* 32-bit Rotates */ #if defined(_MSC_VER) /* instrinsic rotate */ #include #pragma intrinsic(_lrotr,_lrotl) #define ROR(x,n) _lrotr(x,n) #define ROL(x,n) _lrotl(x,n) #define RORc(x,n) _lrotr(x,n) #define ROLc(x,n) _lrotl(x,n) #elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && !defined(INTEL_CC) && !defined(LTC_NO_ASM) static inline unsigned ROL(unsigned word, int i) { asm ("roll %%cl,%0" :"=r" (word) :"0" (word),"c" (i)); return word; } static inline unsigned ROR(unsigned word, int i) { asm ("rorl %%cl,%0" :"=r" (word) :"0" (word),"c" (i)); return word; } #ifndef LTC_NO_ROLC static inline unsigned ROLc(unsigned word, const int i) { asm ("roll %2,%0" :"=r" (word) :"0" (word),"I" (i)); return word; } static inline unsigned RORc(unsigned word, const int i) { asm ("rorl %2,%0" :"=r" (word) :"0" (word),"I" (i)); return word; } #else #define ROLc ROL #define RORc ROR #endif #elif !defined(__STRICT_ANSI__) && defined(LTC_PPC32) static inline unsigned ROL(unsigned word, int i) { asm ("rotlw %0,%0,%2" :"=r" (word) :"0" (word),"r" (i)); return word; } static inline unsigned ROR(unsigned word, int i) { asm ("rotlw %0,%0,%2" :"=r" (word) :"0" (word),"r" (32-i)); return word; } #ifndef LTC_NO_ROLC static inline unsigned ROLc(unsigned word, const int i) { asm ("rotlwi %0,%0,%2" :"=r" (word) :"0" (word),"I" (i)); return word; } static inline unsigned RORc(unsigned word, const int i) { asm ("rotrwi %0,%0,%2" :"=r" (word) :"0" (word),"I" (i)); return word; } #else #define ROLc ROL #define RORc ROR #endif #else /* rotates the hard way */ #define ROL(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) #define ROR(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) #define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) #define RORc(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL) #endif /* 64-bit Rotates */ #if !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__x86_64__) && !defined(LTC_NO_ASM) static inline unsigned long ROL64(unsigned long word, int i) { asm("rolq %%cl,%0" :"=r" (word) :"0" (word),"c" (i)); return word; } static inline unsigned long ROR64(unsigned long word, int i) { asm("rorq %%cl,%0" :"=r" (word) :"0" (word),"c" (i)); return word; } #ifndef LTC_NO_ROLC static inline unsigned long ROL64c(unsigned long word, const int i) { asm("rolq %2,%0" :"=r" (word) :"0" (word),"J" (i)); return word; } static inline unsigned long ROR64c(unsigned long word, const int i) { asm("rorq %2,%0" :"=r" (word) :"0" (word),"J" (i)); return word; } #else /* LTC_NO_ROLC */ #define ROL64c ROL64 #define ROR64c ROR64 #endif #else /* Not x86_64 */ #define ROL64(x, y) \ ( (((x)<<((ulong64)(y)&63)) | \ (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF)) #define ROR64(x, y) \ ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \ ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF)) #define ROL64c(x, y) \ ( (((x)<<((ulong64)(y)&63)) | \ (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF)) #define ROR64c(x, y) \ ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \ ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF)) #endif #ifndef MAX #define MAX(x, y) ( ((x)>(y))?(x):(y) ) #endif #ifndef MIN #define MIN(x, y) ( ((x)<(y))?(x):(y) ) #endif /* extract a byte portably */ #ifdef _MSC_VER #define byte(x, n) ((unsigned char)((x) >> (8 * (n)))) #else #define byte(x, n) (((x) >> (8 * (n))) & 255) #endif /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_macros.h,v $ */ /* $Revision: 1.15 $ */ /* $Date: 2006/11/29 23:43:57 $ */ libtomcrypt-1.17/src/headers/tomcrypt_custom.h0000644000175100001440000002031010621351501020345 0ustar tomusers#ifndef TOMCRYPT_CUSTOM_H_ #define TOMCRYPT_CUSTOM_H_ /* macros for various libc functions you can change for embedded targets */ #ifndef XMALLOC #ifdef malloc #define LTC_NO_PROTOTYPES #endif #define XMALLOC malloc #endif #ifndef XREALLOC #ifdef realloc #define LTC_NO_PROTOTYPES #endif #define XREALLOC realloc #endif #ifndef XCALLOC #ifdef calloc #define LTC_NO_PROTOTYPES #endif #define XCALLOC calloc #endif #ifndef XFREE #ifdef free #define LTC_NO_PROTOTYPES #endif #define XFREE free #endif #ifndef XMEMSET #ifdef memset #define LTC_NO_PROTOTYPES #endif #define XMEMSET memset #endif #ifndef XMEMCPY #ifdef memcpy #define LTC_NO_PROTOTYPES #endif #define XMEMCPY memcpy #endif #ifndef XMEMCMP #ifdef memcmp #define LTC_NO_PROTOTYPES #endif #define XMEMCMP memcmp #endif #ifndef XSTRCMP #ifdef strcmp #define LTC_NO_PROTOTYPES #endif #define XSTRCMP strcmp #endif #ifndef XCLOCK #define XCLOCK clock #endif #ifndef XCLOCKS_PER_SEC #define XCLOCKS_PER_SEC CLOCKS_PER_SEC #endif #ifndef XQSORT #ifdef qsort #define LTC_NO_PROTOTYPES #endif #define XQSORT qsort #endif /* Easy button? */ #ifdef LTC_EASY #define LTC_NO_CIPHERS #define LTC_RIJNDAEL #define LTC_BLOWFISH #define LTC_DES #define LTC_CAST5 #define LTC_NO_MODES #define LTC_ECB_MODE #define LTC_CBC_MODE #define LTC_CTR_MODE #define LTC_NO_HASHES #define LTC_SHA1 #define LTC_SHA512 #define LTC_SHA384 #define LTC_SHA256 #define LTC_SHA224 #define LTC_NO_MACS #define LTC_HMAC #define LTC_OMAC #define LTC_CCM_MODE #define LTC_NO_PRNGS #define LTC_SPRNG #define LTC_YARROW #define LTC_DEVRANDOM #define TRY_URANDOM_FIRST #define LTC_NO_PK #define LTC_MRSA #define LTC_MECC #endif /* Use small code where possible */ /* #define LTC_SMALL_CODE */ /* Enable self-test test vector checking */ #ifndef LTC_NO_TEST #define LTC_TEST #endif /* clean the stack of functions which put private information on stack */ /* #define LTC_CLEAN_STACK */ /* disable all file related functions */ /* #define LTC_NO_FILE */ /* disable all forms of ASM */ /* #define LTC_NO_ASM */ /* disable FAST mode */ /* #define LTC_NO_FAST */ /* disable BSWAP on x86 */ /* #define LTC_NO_BSWAP */ /* ---> Symmetric Block Ciphers <--- */ #ifndef LTC_NO_CIPHERS #define LTC_BLOWFISH #define LTC_RC2 #define LTC_RC5 #define LTC_RC6 #define LTC_SAFERP #define LTC_RIJNDAEL #define LTC_XTEA /* _TABLES tells it to use tables during setup, _SMALL means to use the smaller scheduled key format * (saves 4KB of ram), _ALL_TABLES enables all tables during setup */ #define LTC_TWOFISH #ifndef LTC_NO_TABLES #define LTC_TWOFISH_TABLES /* #define LTC_TWOFISH_ALL_TABLES */ #else #define LTC_TWOFISH_SMALL #endif /* #define LTC_TWOFISH_SMALL */ /* LTC_DES includes EDE triple-LTC_DES */ #define LTC_DES #define LTC_CAST5 #define LTC_NOEKEON #define LTC_SKIPJACK #define LTC_SAFER #define LTC_KHAZAD #define LTC_ANUBIS #define LTC_ANUBIS_TWEAK #define LTC_KSEED #define LTC_KASUMI #endif /* LTC_NO_CIPHERS */ /* ---> Block Cipher Modes of Operation <--- */ #ifndef LTC_NO_MODES #define LTC_CFB_MODE #define LTC_OFB_MODE #define LTC_ECB_MODE #define LTC_CBC_MODE #define LTC_CTR_MODE /* F8 chaining mode */ #define LTC_F8_MODE /* LRW mode */ #define LTC_LRW_MODE #ifndef LTC_NO_TABLES /* like GCM mode this will enable 16 8x128 tables [64KB] that make * seeking very fast. */ #define LRW_TABLES #endif /* XTS mode */ #define LTC_XTS_MODE #endif /* LTC_NO_MODES */ /* ---> One-Way Hash Functions <--- */ #ifndef LTC_NO_HASHES #define LTC_CHC_HASH #define LTC_WHIRLPOOL #define LTC_SHA512 #define LTC_SHA384 #define LTC_SHA256 #define LTC_SHA224 #define LTC_TIGER #define LTC_SHA1 #define LTC_MD5 #define LTC_MD4 #define LTC_MD2 #define LTC_RIPEMD128 #define LTC_RIPEMD160 #define LTC_RIPEMD256 #define LTC_RIPEMD320 #endif /* LTC_NO_HASHES */ /* ---> MAC functions <--- */ #ifndef LTC_NO_MACS #define LTC_HMAC #define LTC_OMAC #define LTC_PMAC #define LTC_XCBC #define LTC_F9_MODE #define LTC_PELICAN #if defined(LTC_PELICAN) && !defined(LTC_RIJNDAEL) #error Pelican-MAC requires LTC_RIJNDAEL #endif /* ---> Encrypt + Authenticate Modes <--- */ #define LTC_EAX_MODE #if defined(LTC_EAX_MODE) && !(defined(LTC_CTR_MODE) && defined(LTC_OMAC)) #error LTC_EAX_MODE requires CTR and LTC_OMAC mode #endif #define LTC_OCB_MODE #define LTC_CCM_MODE #define LTC_GCM_MODE /* Use 64KiB tables */ #ifndef LTC_NO_TABLES #define LTC_GCM_TABLES #endif /* USE SSE2? requires GCC works on x86_32 and x86_64*/ #ifdef LTC_GCM_TABLES /* #define LTC_GCM_TABLES_SSE2 */ #endif #endif /* LTC_NO_MACS */ /* Various tidbits of modern neatoness */ #define LTC_BASE64 /* --> Pseudo Random Number Generators <--- */ #ifndef LTC_NO_PRNGS /* Yarrow */ #define LTC_YARROW /* which descriptor of AES to use? */ /* 0 = rijndael_enc 1 = aes_enc, 2 = rijndael [full], 3 = aes [full] */ #define LTC_YARROW_AES 0 #if defined(LTC_YARROW) && !defined(LTC_CTR_MODE) #error LTC_YARROW requires LTC_CTR_MODE chaining mode to be defined! #endif /* a PRNG that simply reads from an available system source */ #define LTC_SPRNG /* The LTC_RC4 stream cipher */ #define LTC_RC4 /* Fortuna PRNG */ #define LTC_FORTUNA /* reseed every N calls to the read function */ #define LTC_FORTUNA_WD 10 /* number of pools (4..32) can save a bit of ram by lowering the count */ #define LTC_FORTUNA_POOLS 32 /* Greg's LTC_SOBER128 PRNG ;-0 */ #define LTC_SOBER128 /* the *nix style /dev/random device */ #define LTC_DEVRANDOM /* try /dev/urandom before trying /dev/random */ #define TRY_URANDOM_FIRST #endif /* LTC_NO_PRNGS */ /* ---> math provider? <--- */ #ifndef LTC_NO_MATH /* LibTomMath */ /* #define LTM_LTC_DESC */ /* TomsFastMath */ /* #define TFM_LTC_DESC */ #endif /* LTC_NO_MATH */ /* ---> Public Key Crypto <--- */ #ifndef LTC_NO_PK /* Include RSA support */ #define LTC_MRSA /* Include Katja (a Rabin variant like RSA) */ /* #define MKAT */ /* Digital Signature Algorithm */ #define LTC_MDSA /* ECC */ #define LTC_MECC /* use Shamir's trick for point mul (speeds up signature verification) */ #define LTC_ECC_SHAMIR #if defined(TFM_LTC_DESC) && defined(LTC_MECC) #define LTC_MECC_ACCEL #endif /* do we want fixed point ECC */ /* #define LTC_MECC_FP */ /* Timing Resistant? */ /* #define LTC_ECC_TIMING_RESISTANT */ #endif /* LTC_NO_PK */ /* LTC_PKCS #1 (RSA) and #5 (Password Handling) stuff */ #ifndef LTC_NO_PKCS #define LTC_PKCS_1 #define LTC_PKCS_5 /* Include ASN.1 DER (required by DSA/RSA) */ #define LTC_DER #endif /* LTC_NO_PKCS */ /* cleanup */ #ifdef LTC_MECC /* Supported ECC Key Sizes */ #ifndef LTC_NO_CURVES #define ECC112 #define ECC128 #define ECC160 #define ECC192 #define ECC224 #define ECC256 #define ECC384 #define ECC521 #endif #endif #if defined(LTC_MECC) || defined(LTC_MRSA) || defined(LTC_MDSA) || defined(MKATJA) /* Include the MPI functionality? (required by the PK algorithms) */ #define MPI #endif #ifdef LTC_MRSA #define LTC_PKCS_1 #endif #if defined(LTC_DER) && !defined(MPI) #error ASN.1 DER requires MPI functionality #endif #if (defined(LTC_MDSA) || defined(LTC_MRSA) || defined(LTC_MECC) || defined(MKATJA)) && !defined(LTC_DER) #error PK requires ASN.1 DER functionality, make sure LTC_DER is enabled #endif /* THREAD management */ #ifdef LTC_PTHREAD #include #define LTC_MUTEX_GLOBAL(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER; #define LTC_MUTEX_PROTO(x) extern pthread_mutex_t x; #define LTC_MUTEX_TYPE(x) pthread_mutex_t x; #define LTC_MUTEX_INIT(x) pthread_mutex_init(x, NULL); #define LTC_MUTEX_LOCK(x) pthread_mutex_lock(x); #define LTC_MUTEX_UNLOCK(x) pthread_mutex_unlock(x); #else /* default no functions */ #define LTC_MUTEX_GLOBAL(x) #define LTC_MUTEX_PROTO(x) #define LTC_MUTEX_TYPE(x) #define LTC_MUTEX_INIT(x) #define LTC_MUTEX_LOCK(x) #define LTC_MUTEX_UNLOCK(x) #endif /* Debuggers */ /* define this if you use Valgrind, note: it CHANGES the way SOBER-128 and LTC_RC4 work (see the code) */ /* #define LTC_VALGRIND */ #endif /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_custom.h,v $ */ /* $Revision: 1.73 $ */ /* $Date: 2007/05/12 14:37:41 $ */ libtomcrypt-1.17/src/headers/tomcrypt_argchk.h0000644000175100001440000000172110621351501020277 0ustar tomusers/* Defines the LTC_ARGCHK macro used within the library */ /* ARGTYPE is defined in mycrypt_cfg.h */ #if ARGTYPE == 0 #include /* this is the default LibTomCrypt macro */ void crypt_argchk(char *v, char *s, int d); #define LTC_ARGCHK(x) if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); } #define LTC_ARGCHKVD(x) LTC_ARGCHK(x) #elif ARGTYPE == 1 /* fatal type of error */ #define LTC_ARGCHK(x) assert((x)) #define LTC_ARGCHKVD(x) LTC_ARGCHK(x) #elif ARGTYPE == 2 #define LTC_ARGCHK(x) if (!(x)) { fprintf(stderr, "\nwarning: ARGCHK failed at %s:%d\n", __FILE__, __LINE__); } #define LTC_ARGCHKVD(x) LTC_ARGCHK(x) #elif ARGTYPE == 3 #define LTC_ARGCHK(x) #define LTC_ARGCHKVD(x) LTC_ARGCHK(x) #elif ARGTYPE == 4 #define LTC_ARGCHK(x) if (!(x)) return CRYPT_INVALID_ARG; #define LTC_ARGCHKVD(x) if (!(x)) return; #endif /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_argchk.h,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2006/08/27 20:50:21 $ */ libtomcrypt-1.17/src/headers/tomcrypt_cipher.h0000644000175100001440000007572610621351501020332 0ustar tomusers/* ---- SYMMETRIC KEY STUFF ----- * * We put each of the ciphers scheduled keys in their own structs then we put all of * the key formats in one union. This makes the function prototypes easier to use. */ #ifdef LTC_BLOWFISH struct blowfish_key { ulong32 S[4][256]; ulong32 K[18]; }; #endif #ifdef LTC_RC5 struct rc5_key { int rounds; ulong32 K[50]; }; #endif #ifdef LTC_RC6 struct rc6_key { ulong32 K[44]; }; #endif #ifdef LTC_SAFERP struct saferp_key { unsigned char K[33][16]; long rounds; }; #endif #ifdef LTC_RIJNDAEL struct rijndael_key { ulong32 eK[60], dK[60]; int Nr; }; #endif #ifdef LTC_KSEED struct kseed_key { ulong32 K[32], dK[32]; }; #endif #ifdef LTC_KASUMI struct kasumi_key { ulong32 KLi1[8], KLi2[8], KOi1[8], KOi2[8], KOi3[8], KIi1[8], KIi2[8], KIi3[8]; }; #endif #ifdef LTC_XTEA struct xtea_key { unsigned long A[32], B[32]; }; #endif #ifdef LTC_TWOFISH #ifndef LTC_TWOFISH_SMALL struct twofish_key { ulong32 S[4][256], K[40]; }; #else struct twofish_key { ulong32 K[40]; unsigned char S[32], start; }; #endif #endif #ifdef LTC_SAFER #define LTC_SAFER_K64_DEFAULT_NOF_ROUNDS 6 #define LTC_SAFER_K128_DEFAULT_NOF_ROUNDS 10 #define LTC_SAFER_SK64_DEFAULT_NOF_ROUNDS 8 #define LTC_SAFER_SK128_DEFAULT_NOF_ROUNDS 10 #define LTC_SAFER_MAX_NOF_ROUNDS 13 #define LTC_SAFER_BLOCK_LEN 8 #define LTC_SAFER_KEY_LEN (1 + LTC_SAFER_BLOCK_LEN * (1 + 2 * LTC_SAFER_MAX_NOF_ROUNDS)) typedef unsigned char safer_block_t[LTC_SAFER_BLOCK_LEN]; typedef unsigned char safer_key_t[LTC_SAFER_KEY_LEN]; struct safer_key { safer_key_t key; }; #endif #ifdef LTC_RC2 struct rc2_key { unsigned xkey[64]; }; #endif #ifdef LTC_DES struct des_key { ulong32 ek[32], dk[32]; }; struct des3_key { ulong32 ek[3][32], dk[3][32]; }; #endif #ifdef LTC_CAST5 struct cast5_key { ulong32 K[32], keylen; }; #endif #ifdef LTC_NOEKEON struct noekeon_key { ulong32 K[4], dK[4]; }; #endif #ifdef LTC_SKIPJACK struct skipjack_key { unsigned char key[10]; }; #endif #ifdef LTC_KHAZAD struct khazad_key { ulong64 roundKeyEnc[8 + 1]; ulong64 roundKeyDec[8 + 1]; }; #endif #ifdef LTC_ANUBIS struct anubis_key { int keyBits; int R; ulong32 roundKeyEnc[18 + 1][4]; ulong32 roundKeyDec[18 + 1][4]; }; #endif #ifdef LTC_MULTI2 struct multi2_key { int N; ulong32 uk[8]; }; #endif typedef union Symmetric_key { #ifdef LTC_DES struct des_key des; struct des3_key des3; #endif #ifdef LTC_RC2 struct rc2_key rc2; #endif #ifdef LTC_SAFER struct safer_key safer; #endif #ifdef LTC_TWOFISH struct twofish_key twofish; #endif #ifdef LTC_BLOWFISH struct blowfish_key blowfish; #endif #ifdef LTC_RC5 struct rc5_key rc5; #endif #ifdef LTC_RC6 struct rc6_key rc6; #endif #ifdef LTC_SAFERP struct saferp_key saferp; #endif #ifdef LTC_RIJNDAEL struct rijndael_key rijndael; #endif #ifdef LTC_XTEA struct xtea_key xtea; #endif #ifdef LTC_CAST5 struct cast5_key cast5; #endif #ifdef LTC_NOEKEON struct noekeon_key noekeon; #endif #ifdef LTC_SKIPJACK struct skipjack_key skipjack; #endif #ifdef LTC_KHAZAD struct khazad_key khazad; #endif #ifdef LTC_ANUBIS struct anubis_key anubis; #endif #ifdef LTC_KSEED struct kseed_key kseed; #endif #ifdef LTC_KASUMI struct kasumi_key kasumi; #endif #ifdef LTC_MULTI2 struct multi2_key multi2; #endif void *data; } symmetric_key; #ifdef LTC_ECB_MODE /** A block cipher ECB structure */ typedef struct { /** The index of the cipher chosen */ int cipher, /** The block size of the given cipher */ blocklen; /** The scheduled key */ symmetric_key key; } symmetric_ECB; #endif #ifdef LTC_CFB_MODE /** A block cipher CFB structure */ typedef struct { /** The index of the cipher chosen */ int cipher, /** The block size of the given cipher */ blocklen, /** The padding offset */ padlen; /** The current IV */ unsigned char IV[MAXBLOCKSIZE], /** The pad used to encrypt/decrypt */ pad[MAXBLOCKSIZE]; /** The scheduled key */ symmetric_key key; } symmetric_CFB; #endif #ifdef LTC_OFB_MODE /** A block cipher OFB structure */ typedef struct { /** The index of the cipher chosen */ int cipher, /** The block size of the given cipher */ blocklen, /** The padding offset */ padlen; /** The current IV */ unsigned char IV[MAXBLOCKSIZE]; /** The scheduled key */ symmetric_key key; } symmetric_OFB; #endif #ifdef LTC_CBC_MODE /** A block cipher CBC structure */ typedef struct { /** The index of the cipher chosen */ int cipher, /** The block size of the given cipher */ blocklen; /** The current IV */ unsigned char IV[MAXBLOCKSIZE]; /** The scheduled key */ symmetric_key key; } symmetric_CBC; #endif #ifdef LTC_CTR_MODE /** A block cipher CTR structure */ typedef struct { /** The index of the cipher chosen */ int cipher, /** The block size of the given cipher */ blocklen, /** The padding offset */ padlen, /** The mode (endianess) of the CTR, 0==little, 1==big */ mode, /** counter width */ ctrlen; /** The counter */ unsigned char ctr[MAXBLOCKSIZE], /** The pad used to encrypt/decrypt */ pad[MAXBLOCKSIZE]; /** The scheduled key */ symmetric_key key; } symmetric_CTR; #endif #ifdef LTC_LRW_MODE /** A LRW structure */ typedef struct { /** The index of the cipher chosen (must be a 128-bit block cipher) */ int cipher; /** The current IV */ unsigned char IV[16], /** the tweak key */ tweak[16], /** The current pad, it's the product of the first 15 bytes against the tweak key */ pad[16]; /** The scheduled symmetric key */ symmetric_key key; #ifdef LRW_TABLES /** The pre-computed multiplication table */ unsigned char PC[16][256][16]; #endif } symmetric_LRW; #endif #ifdef LTC_F8_MODE /** A block cipher F8 structure */ typedef struct { /** The index of the cipher chosen */ int cipher, /** The block size of the given cipher */ blocklen, /** The padding offset */ padlen; /** The current IV */ unsigned char IV[MAXBLOCKSIZE], MIV[MAXBLOCKSIZE]; /** Current block count */ ulong32 blockcnt; /** The scheduled key */ symmetric_key key; } symmetric_F8; #endif /** cipher descriptor table, last entry has "name == NULL" to mark the end of table */ extern struct ltc_cipher_descriptor { /** name of cipher */ char *name; /** internal ID */ unsigned char ID; /** min keysize (octets) */ int min_key_length, /** max keysize (octets) */ max_key_length, /** block size (octets) */ block_length, /** default number of rounds */ default_rounds; /** Setup the cipher @param key The input symmetric key @param keylen The length of the input key (octets) @param num_rounds The requested number of rounds (0==default) @param skey [out] The destination of the scheduled key @return CRYPT_OK if successful */ int (*setup)(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); /** Encrypt a block @param pt The plaintext @param ct [out] The ciphertext @param skey The scheduled key @return CRYPT_OK if successful */ int (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); /** Decrypt a block @param ct The ciphertext @param pt [out] The plaintext @param skey The scheduled key @return CRYPT_OK if successful */ int (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); /** Test the block cipher @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled */ int (*test)(void); /** Terminate the context @param skey The scheduled key */ void (*done)(symmetric_key *skey); /** Determine a key size @param keysize [in/out] The size of the key desired and the suggested size @return CRYPT_OK if successful */ int (*keysize)(int *keysize); /** Accelerators **/ /** Accelerated ECB encryption @param pt Plaintext @param ct Ciphertext @param blocks The number of complete blocks to process @param skey The scheduled key context @return CRYPT_OK if successful */ int (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, symmetric_key *skey); /** Accelerated ECB decryption @param pt Plaintext @param ct Ciphertext @param blocks The number of complete blocks to process @param skey The scheduled key context @return CRYPT_OK if successful */ int (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, symmetric_key *skey); /** Accelerated CBC encryption @param pt Plaintext @param ct Ciphertext @param blocks The number of complete blocks to process @param IV The initial value (input/output) @param skey The scheduled key context @return CRYPT_OK if successful */ int (*accel_cbc_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, symmetric_key *skey); /** Accelerated CBC decryption @param pt Plaintext @param ct Ciphertext @param blocks The number of complete blocks to process @param IV The initial value (input/output) @param skey The scheduled key context @return CRYPT_OK if successful */ int (*accel_cbc_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, symmetric_key *skey); /** Accelerated CTR encryption @param pt Plaintext @param ct Ciphertext @param blocks The number of complete blocks to process @param IV The initial value (input/output) @param mode little or big endian counter (mode=0 or mode=1) @param skey The scheduled key context @return CRYPT_OK if successful */ int (*accel_ctr_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, int mode, symmetric_key *skey); /** Accelerated LRW @param pt Plaintext @param ct Ciphertext @param blocks The number of complete blocks to process @param IV The initial value (input/output) @param tweak The LRW tweak @param skey The scheduled key context @return CRYPT_OK if successful */ int (*accel_lrw_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, symmetric_key *skey); /** Accelerated LRW @param ct Ciphertext @param pt Plaintext @param blocks The number of complete blocks to process @param IV The initial value (input/output) @param tweak The LRW tweak @param skey The scheduled key context @return CRYPT_OK if successful */ int (*accel_lrw_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, symmetric_key *skey); /** Accelerated CCM packet (one-shot) @param key The secret key to use @param keylen The length of the secret key (octets) @param uskey A previously scheduled key [optional can be NULL] @param nonce The session nonce [use once] @param noncelen The length of the nonce @param header The header for the session @param headerlen The length of the header (octets) @param pt [out] The plaintext @param ptlen The length of the plaintext (octets) @param ct [out] The ciphertext @param tag [out] The destination tag @param taglen [in/out] The max size and resulting size of the authentication tag @param direction Encrypt or Decrypt direction (0 or 1) @return CRYPT_OK if successful */ int (*accel_ccm_memory)( const unsigned char *key, unsigned long keylen, symmetric_key *uskey, const unsigned char *nonce, unsigned long noncelen, const unsigned char *header, unsigned long headerlen, unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tag, unsigned long *taglen, int direction); /** Accelerated GCM packet (one shot) @param key The secret key @param keylen The length of the secret key @param IV The initial vector @param IVlen The length of the initial vector @param adata The additional authentication data (header) @param adatalen The length of the adata @param pt The plaintext @param ptlen The length of the plaintext (ciphertext length is the same) @param ct The ciphertext @param tag [out] The MAC tag @param taglen [in/out] The MAC tag length @param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT) @return CRYPT_OK on success */ int (*accel_gcm_memory)( const unsigned char *key, unsigned long keylen, const unsigned char *IV, unsigned long IVlen, const unsigned char *adata, unsigned long adatalen, unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tag, unsigned long *taglen, int direction); /** Accelerated one shot LTC_OMAC @param key The secret key @param keylen The key length (octets) @param in The message @param inlen Length of message (octets) @param out [out] Destination for tag @param outlen [in/out] Initial and final size of out @return CRYPT_OK on success */ int (*omac_memory)( const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); /** Accelerated one shot XCBC @param key The secret key @param keylen The key length (octets) @param in The message @param inlen Length of message (octets) @param out [out] Destination for tag @param outlen [in/out] Initial and final size of out @return CRYPT_OK on success */ int (*xcbc_memory)( const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); /** Accelerated one shot F9 @param key The secret key @param keylen The key length (octets) @param in The message @param inlen Length of message (octets) @param out [out] Destination for tag @param outlen [in/out] Initial and final size of out @return CRYPT_OK on success @remark Requires manual padding */ int (*f9_memory)( const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); } cipher_descriptor[]; #ifdef LTC_BLOWFISH int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int blowfish_test(void); void blowfish_done(symmetric_key *skey); int blowfish_keysize(int *keysize); extern const struct ltc_cipher_descriptor blowfish_desc; #endif #ifdef LTC_RC5 int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int rc5_test(void); void rc5_done(symmetric_key *skey); int rc5_keysize(int *keysize); extern const struct ltc_cipher_descriptor rc5_desc; #endif #ifdef LTC_RC6 int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int rc6_test(void); void rc6_done(symmetric_key *skey); int rc6_keysize(int *keysize); extern const struct ltc_cipher_descriptor rc6_desc; #endif #ifdef LTC_RC2 int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int rc2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int rc2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int rc2_test(void); void rc2_done(symmetric_key *skey); int rc2_keysize(int *keysize); extern const struct ltc_cipher_descriptor rc2_desc; #endif #ifdef LTC_SAFERP int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int saferp_test(void); void saferp_done(symmetric_key *skey); int saferp_keysize(int *keysize); extern const struct ltc_cipher_descriptor saferp_desc; #endif #ifdef LTC_SAFER int safer_k64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int safer_sk64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int safer_k128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int safer_sk128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int safer_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); int safer_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key); int safer_k64_test(void); int safer_sk64_test(void); int safer_sk128_test(void); void safer_done(symmetric_key *skey); int safer_64_keysize(int *keysize); int safer_128_keysize(int *keysize); extern const struct ltc_cipher_descriptor safer_k64_desc, safer_k128_desc, safer_sk64_desc, safer_sk128_desc; #endif #ifdef LTC_RIJNDAEL /* make aes an alias */ #define aes_setup rijndael_setup #define aes_ecb_encrypt rijndael_ecb_encrypt #define aes_ecb_decrypt rijndael_ecb_decrypt #define aes_test rijndael_test #define aes_done rijndael_done #define aes_keysize rijndael_keysize #define aes_enc_setup rijndael_enc_setup #define aes_enc_ecb_encrypt rijndael_enc_ecb_encrypt #define aes_enc_keysize rijndael_enc_keysize int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int rijndael_test(void); void rijndael_done(symmetric_key *skey); int rijndael_keysize(int *keysize); int rijndael_enc_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int rijndael_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); void rijndael_enc_done(symmetric_key *skey); int rijndael_enc_keysize(int *keysize); extern const struct ltc_cipher_descriptor rijndael_desc, aes_desc; extern const struct ltc_cipher_descriptor rijndael_enc_desc, aes_enc_desc; #endif #ifdef LTC_XTEA int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int xtea_test(void); void xtea_done(symmetric_key *skey); int xtea_keysize(int *keysize); extern const struct ltc_cipher_descriptor xtea_desc; #endif #ifdef LTC_TWOFISH int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int twofish_test(void); void twofish_done(symmetric_key *skey); int twofish_keysize(int *keysize); extern const struct ltc_cipher_descriptor twofish_desc; #endif #ifdef LTC_DES int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int des_test(void); void des_done(symmetric_key *skey); int des_keysize(int *keysize); int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int des3_test(void); void des3_done(symmetric_key *skey); int des3_keysize(int *keysize); extern const struct ltc_cipher_descriptor des_desc, des3_desc; #endif #ifdef LTC_CAST5 int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int cast5_test(void); void cast5_done(symmetric_key *skey); int cast5_keysize(int *keysize); extern const struct ltc_cipher_descriptor cast5_desc; #endif #ifdef LTC_NOEKEON int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int noekeon_test(void); void noekeon_done(symmetric_key *skey); int noekeon_keysize(int *keysize); extern const struct ltc_cipher_descriptor noekeon_desc; #endif #ifdef LTC_SKIPJACK int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int skipjack_test(void); void skipjack_done(symmetric_key *skey); int skipjack_keysize(int *keysize); extern const struct ltc_cipher_descriptor skipjack_desc; #endif #ifdef LTC_KHAZAD int khazad_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int khazad_test(void); void khazad_done(symmetric_key *skey); int khazad_keysize(int *keysize); extern const struct ltc_cipher_descriptor khazad_desc; #endif #ifdef LTC_ANUBIS int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int anubis_test(void); void anubis_done(symmetric_key *skey); int anubis_keysize(int *keysize); extern const struct ltc_cipher_descriptor anubis_desc; #endif #ifdef LTC_KSEED int kseed_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int kseed_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int kseed_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int kseed_test(void); void kseed_done(symmetric_key *skey); int kseed_keysize(int *keysize); extern const struct ltc_cipher_descriptor kseed_desc; #endif #ifdef LTC_KASUMI int kasumi_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int kasumi_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int kasumi_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int kasumi_test(void); void kasumi_done(symmetric_key *skey); int kasumi_keysize(int *keysize); extern const struct ltc_cipher_descriptor kasumi_desc; #endif #ifdef LTC_MULTI2 int multi2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int multi2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int multi2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); int multi2_test(void); void multi2_done(symmetric_key *skey); int multi2_keysize(int *keysize); extern const struct ltc_cipher_descriptor multi2_desc; #endif #ifdef LTC_ECB_MODE int ecb_start(int cipher, const unsigned char *key, int keylen, int num_rounds, symmetric_ECB *ecb); int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_ECB *ecb); int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_ECB *ecb); int ecb_done(symmetric_ECB *ecb); #endif #ifdef LTC_CFB_MODE int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key, int keylen, int num_rounds, symmetric_CFB *cfb); int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb); int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb); int cfb_getiv(unsigned char *IV, unsigned long *len, symmetric_CFB *cfb); int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb); int cfb_done(symmetric_CFB *cfb); #endif #ifdef LTC_OFB_MODE int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key, int keylen, int num_rounds, symmetric_OFB *ofb); int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_OFB *ofb); int ofb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_OFB *ofb); int ofb_getiv(unsigned char *IV, unsigned long *len, symmetric_OFB *ofb); int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb); int ofb_done(symmetric_OFB *ofb); #endif #ifdef LTC_CBC_MODE int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key, int keylen, int num_rounds, symmetric_CBC *cbc); int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CBC *cbc); int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CBC *cbc); int cbc_getiv(unsigned char *IV, unsigned long *len, symmetric_CBC *cbc); int cbc_setiv(const unsigned char *IV, unsigned long len, symmetric_CBC *cbc); int cbc_done(symmetric_CBC *cbc); #endif #ifdef LTC_CTR_MODE #define CTR_COUNTER_LITTLE_ENDIAN 0x0000 #define CTR_COUNTER_BIG_ENDIAN 0x1000 #define LTC_CTR_RFC3686 0x2000 int ctr_start( int cipher, const unsigned char *IV, const unsigned char *key, int keylen, int num_rounds, int ctr_mode, symmetric_CTR *ctr); int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr); int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr); int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr); int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr); int ctr_done(symmetric_CTR *ctr); int ctr_test(void); #endif #ifdef LTC_LRW_MODE #define LRW_ENCRYPT 0 #define LRW_DECRYPT 1 int lrw_start( int cipher, const unsigned char *IV, const unsigned char *key, int keylen, const unsigned char *tweak, int num_rounds, symmetric_LRW *lrw); int lrw_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_LRW *lrw); int lrw_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_LRW *lrw); int lrw_getiv(unsigned char *IV, unsigned long *len, symmetric_LRW *lrw); int lrw_setiv(const unsigned char *IV, unsigned long len, symmetric_LRW *lrw); int lrw_done(symmetric_LRW *lrw); int lrw_test(void); /* don't call */ int lrw_process(const unsigned char *pt, unsigned char *ct, unsigned long len, int mode, symmetric_LRW *lrw); #endif #ifdef LTC_F8_MODE int f8_start( int cipher, const unsigned char *IV, const unsigned char *key, int keylen, const unsigned char *salt_key, int skeylen, int num_rounds, symmetric_F8 *f8); int f8_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_F8 *f8); int f8_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_F8 *f8); int f8_getiv(unsigned char *IV, unsigned long *len, symmetric_F8 *f8); int f8_setiv(const unsigned char *IV, unsigned long len, symmetric_F8 *f8); int f8_done(symmetric_F8 *f8); int f8_test_mode(void); #endif #ifdef LTC_XTS_MODE typedef struct { symmetric_key key1, key2; int cipher; } symmetric_xts; int xts_start( int cipher, const unsigned char *key1, const unsigned char *key2, unsigned long keylen, int num_rounds, symmetric_xts *xts); int xts_encrypt( const unsigned char *pt, unsigned long ptlen, unsigned char *ct, const unsigned char *tweak, symmetric_xts *xts); int xts_decrypt( const unsigned char *ct, unsigned long ptlen, unsigned char *pt, const unsigned char *tweak, symmetric_xts *xts); void xts_done(symmetric_xts *xts); int xts_test(void); void xts_mult_x(unsigned char *I); #endif int find_cipher(const char *name); int find_cipher_any(const char *name, int blocklen, int keylen); int find_cipher_id(unsigned char ID); int register_cipher(const struct ltc_cipher_descriptor *cipher); int unregister_cipher(const struct ltc_cipher_descriptor *cipher); int cipher_is_valid(int idx); LTC_MUTEX_PROTO(ltc_cipher_mutex) /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_cipher.h,v $ */ /* $Revision: 1.54 $ */ /* $Date: 2007/05/12 14:37:41 $ */ libtomcrypt-1.17/src/headers/tomcrypt_pk.h0000644000175100001440000005103010621351501017450 0ustar tomusers/* ---- NUMBER THEORY ---- */ enum { PK_PUBLIC=0, PK_PRIVATE=1 }; int rand_prime(void *N, long len, prng_state *prng, int wprng); /* ---- RSA ---- */ #ifdef LTC_MRSA /* Min and Max RSA key sizes (in bits) */ #define MIN_RSA_SIZE 1024 #define MAX_RSA_SIZE 4096 /** RSA LTC_PKCS style key */ typedef struct Rsa_key { /** Type of key, PK_PRIVATE or PK_PUBLIC */ int type; /** The public exponent */ void *e; /** The private exponent */ void *d; /** The modulus */ void *N; /** The p factor of N */ void *p; /** The q factor of N */ void *q; /** The 1/q mod p CRT param */ void *qP; /** The d mod (p - 1) CRT param */ void *dP; /** The d mod (q - 1) CRT param */ void *dQ; } rsa_key; int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key); int rsa_exptmod(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, int which, rsa_key *key); void rsa_free(rsa_key *key); /* These use LTC_PKCS #1 v2.0 padding */ #define rsa_encrypt_key(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, _key) \ rsa_encrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, LTC_LTC_PKCS_1_OAEP, _key) #define rsa_decrypt_key(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _hash_idx, _stat, _key) \ rsa_decrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _hash_idx, LTC_LTC_PKCS_1_OAEP, _stat, _key) #define rsa_sign_hash(_in, _inlen, _out, _outlen, _prng, _prng_idx, _hash_idx, _saltlen, _key) \ rsa_sign_hash_ex(_in, _inlen, _out, _outlen, LTC_LTC_PKCS_1_PSS, _prng, _prng_idx, _hash_idx, _saltlen, _key) #define rsa_verify_hash(_sig, _siglen, _hash, _hashlen, _hash_idx, _saltlen, _stat, _key) \ rsa_verify_hash_ex(_sig, _siglen, _hash, _hashlen, LTC_LTC_PKCS_1_PSS, _hash_idx, _saltlen, _stat, _key) /* These can be switched between LTC_PKCS #1 v2.x and LTC_PKCS #1 v1.5 paddings */ int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, const unsigned char *lparam, unsigned long lparamlen, prng_state *prng, int prng_idx, int hash_idx, int padding, rsa_key *key); int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, const unsigned char *lparam, unsigned long lparamlen, int hash_idx, int padding, int *stat, rsa_key *key); int rsa_sign_hash_ex(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, int padding, prng_state *prng, int prng_idx, int hash_idx, unsigned long saltlen, rsa_key *key); int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen, const unsigned char *hash, unsigned long hashlen, int padding, int hash_idx, unsigned long saltlen, int *stat, rsa_key *key); /* LTC_PKCS #1 import/export */ int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key); int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key); #endif /* ---- Katja ---- */ #ifdef MKAT /* Min and Max KAT key sizes (in bits) */ #define MIN_KAT_SIZE 1024 #define MAX_KAT_SIZE 4096 /** Katja LTC_PKCS style key */ typedef struct KAT_key { /** Type of key, PK_PRIVATE or PK_PUBLIC */ int type; /** The private exponent */ void *d; /** The modulus */ void *N; /** The p factor of N */ void *p; /** The q factor of N */ void *q; /** The 1/q mod p CRT param */ void *qP; /** The d mod (p - 1) CRT param */ void *dP; /** The d mod (q - 1) CRT param */ void *dQ; /** The pq param */ void *pq; } katja_key; int katja_make_key(prng_state *prng, int wprng, int size, katja_key *key); int katja_exptmod(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, int which, katja_key *key); void katja_free(katja_key *key); /* These use LTC_PKCS #1 v2.0 padding */ int katja_encrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, const unsigned char *lparam, unsigned long lparamlen, prng_state *prng, int prng_idx, int hash_idx, katja_key *key); int katja_decrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, const unsigned char *lparam, unsigned long lparamlen, int hash_idx, int *stat, katja_key *key); /* LTC_PKCS #1 import/export */ int katja_export(unsigned char *out, unsigned long *outlen, int type, katja_key *key); int katja_import(const unsigned char *in, unsigned long inlen, katja_key *key); #endif /* ---- ECC Routines ---- */ #ifdef LTC_MECC /* size of our temp buffers for exported keys */ #define ECC_BUF_SIZE 256 /* max private key size */ #define ECC_MAXSIZE 66 /** Structure defines a NIST GF(p) curve */ typedef struct { /** The size of the curve in octets */ int size; /** name of curve */ char *name; /** The prime that defines the field the curve is in (encoded in hex) */ char *prime; /** The fields B param (hex) */ char *B; /** The order of the curve (hex) */ char *order; /** The x co-ordinate of the base point on the curve (hex) */ char *Gx; /** The y co-ordinate of the base point on the curve (hex) */ char *Gy; } ltc_ecc_set_type; /** A point on a ECC curve, stored in Jacbobian format such that (x,y,z) => (x/z^2, y/z^3, 1) when interpretted as affine */ typedef struct { /** The x co-ordinate */ void *x; /** The y co-ordinate */ void *y; /** The z co-ordinate */ void *z; } ecc_point; /** An ECC key */ typedef struct { /** Type of key, PK_PRIVATE or PK_PUBLIC */ int type; /** Index into the ltc_ecc_sets[] for the parameters of this curve; if -1, then this key is using user supplied curve in dp */ int idx; /** pointer to domain parameters; either points to NIST curves (identified by idx >= 0) or user supplied curve */ const ltc_ecc_set_type *dp; /** The public key */ ecc_point pubkey; /** The private key */ void *k; } ecc_key; /** the ECC params provided */ extern const ltc_ecc_set_type ltc_ecc_sets[]; int ecc_test(void); void ecc_sizes(int *low, int *high); int ecc_get_size(ecc_key *key); int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key); int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp); void ecc_free(ecc_key *key); int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key); int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp); int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen); int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key); int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp); int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, unsigned char *out, unsigned long *outlen); int ecc_encrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, prng_state *prng, int wprng, int hash, ecc_key *key); int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, ecc_key *key); int ecc_sign_hash(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, prng_state *prng, int wprng, ecc_key *key); int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, const unsigned char *hash, unsigned long hashlen, int *stat, ecc_key *key); /* low level functions */ ecc_point *ltc_ecc_new_point(void); void ltc_ecc_del_point(ecc_point *p); int ltc_ecc_is_valid_idx(int n); /* point ops (mp == montgomery digit) */ #if !defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC) || defined(GMP_LTC_DESC) /* R = 2P */ int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp); /* R = P + Q */ int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp); #endif #if defined(LTC_MECC_FP) /* optimized point multiplication using fixed point cache (HAC algorithm 14.117) */ int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map); /* functions for saving/loading/freeing/adding to fixed point cache */ int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen); int ltc_ecc_fp_restore_state(unsigned char *in, unsigned long inlen); void ltc_ecc_fp_free(void); int ltc_ecc_fp_add_point(ecc_point *g, void *modulus, int lock); /* lock/unlock all points currently in fixed point cache */ void ltc_ecc_fp_tablelock(int lock); #endif /* R = kG */ int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map); #ifdef LTC_ECC_SHAMIR /* kA*A + kB*B = C */ int ltc_ecc_mul2add(ecc_point *A, void *kA, ecc_point *B, void *kB, ecc_point *C, void *modulus); #ifdef LTC_MECC_FP /* Shamir's trick with optimized point multiplication using fixed point cache */ int ltc_ecc_fp_mul2add(ecc_point *A, void *kA, ecc_point *B, void *kB, ecc_point *C, void *modulus); #endif #endif /* map P to affine from projective */ int ltc_ecc_map(ecc_point *P, void *modulus, void *mp); #endif #ifdef LTC_MDSA /* Max diff between group and modulus size in bytes */ #define LTC_MDSA_DELTA 512 /* Max DSA group size in bytes (default allows 4k-bit groups) */ #define LTC_MDSA_MAX_GROUP 512 /** DSA key structure */ typedef struct { /** The key type, PK_PRIVATE or PK_PUBLIC */ int type; /** The order of the sub-group used in octets */ int qord; /** The generator */ void *g; /** The prime used to generate the sub-group */ void *q; /** The large prime that generats the field the contains the sub-group */ void *p; /** The private key */ void *x; /** The public key */ void *y; } dsa_key; int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key); void dsa_free(dsa_key *key); int dsa_sign_hash_raw(const unsigned char *in, unsigned long inlen, void *r, void *s, prng_state *prng, int wprng, dsa_key *key); int dsa_sign_hash(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, prng_state *prng, int wprng, dsa_key *key); int dsa_verify_hash_raw( void *r, void *s, const unsigned char *hash, unsigned long hashlen, int *stat, dsa_key *key); int dsa_verify_hash(const unsigned char *sig, unsigned long siglen, const unsigned char *hash, unsigned long hashlen, int *stat, dsa_key *key); int dsa_encrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, prng_state *prng, int wprng, int hash, dsa_key *key); int dsa_decrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, dsa_key *key); int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key); int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key); int dsa_verify_key(dsa_key *key, int *stat); int dsa_shared_secret(void *private_key, void *base, dsa_key *public_key, unsigned char *out, unsigned long *outlen); #endif #ifdef LTC_DER /* DER handling */ enum { LTC_ASN1_EOL, LTC_ASN1_BOOLEAN, LTC_ASN1_INTEGER, LTC_ASN1_SHORT_INTEGER, LTC_ASN1_BIT_STRING, LTC_ASN1_OCTET_STRING, LTC_ASN1_NULL, LTC_ASN1_OBJECT_IDENTIFIER, LTC_ASN1_IA5_STRING, LTC_ASN1_PRINTABLE_STRING, LTC_ASN1_UTF8_STRING, LTC_ASN1_UTCTIME, LTC_ASN1_CHOICE, LTC_ASN1_SEQUENCE, LTC_ASN1_SET, LTC_ASN1_SETOF }; /** A LTC ASN.1 list type */ typedef struct ltc_asn1_list_ { /** The LTC ASN.1 enumerated type identifier */ int type; /** The data to encode or place for decoding */ void *data; /** The size of the input or resulting output */ unsigned long size; /** The used flag, this is used by the CHOICE ASN.1 type to indicate which choice was made */ int used; /** prev/next entry in the list */ struct ltc_asn1_list_ *prev, *next, *child, *parent; } ltc_asn1_list; #define LTC_SET_ASN1(list, index, Type, Data, Size) \ do { \ int LTC_MACRO_temp = (index); \ ltc_asn1_list *LTC_MACRO_list = (list); \ LTC_MACRO_list[LTC_MACRO_temp].type = (Type); \ LTC_MACRO_list[LTC_MACRO_temp].data = (void*)(Data); \ LTC_MACRO_list[LTC_MACRO_temp].size = (Size); \ LTC_MACRO_list[LTC_MACRO_temp].used = 0; \ } while (0); /* SEQUENCE */ int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen, unsigned char *out, unsigned long *outlen, int type_of); #define der_encode_sequence(list, inlen, out, outlen) der_encode_sequence_ex(list, inlen, out, outlen, LTC_ASN1_SEQUENCE) int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen, ltc_asn1_list *list, unsigned long outlen, int ordered); #define der_decode_sequence(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 1) int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, unsigned long *outlen); /* SET */ #define der_decode_set(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 0) #define der_length_set der_length_sequence int der_encode_set(ltc_asn1_list *list, unsigned long inlen, unsigned char *out, unsigned long *outlen); int der_encode_setof(ltc_asn1_list *list, unsigned long inlen, unsigned char *out, unsigned long *outlen); /* VA list handy helpers with triplets of */ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...); int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...); /* FLEXI DECODER handle unknown list decoder */ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out); void der_free_sequence_flexi(ltc_asn1_list *list); void der_sequence_free(ltc_asn1_list *in); /* BOOLEAN */ int der_length_boolean(unsigned long *outlen); int der_encode_boolean(int in, unsigned char *out, unsigned long *outlen); int der_decode_boolean(const unsigned char *in, unsigned long inlen, int *out); /* INTEGER */ int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen); int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num); int der_length_integer(void *num, unsigned long *len); /* INTEGER -- handy for 0..2^32-1 values */ int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num); int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen); int der_length_short_integer(unsigned long num, unsigned long *outlen); /* BIT STRING */ int der_encode_bit_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); int der_decode_bit_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); int der_length_bit_string(unsigned long nbits, unsigned long *outlen); /* OCTET STRING */ int der_encode_octet_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); int der_decode_octet_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); int der_length_octet_string(unsigned long noctets, unsigned long *outlen); /* OBJECT IDENTIFIER */ int der_encode_object_identifier(unsigned long *words, unsigned long nwords, unsigned char *out, unsigned long *outlen); int der_decode_object_identifier(const unsigned char *in, unsigned long inlen, unsigned long *words, unsigned long *outlen); int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen); unsigned long der_object_identifier_bits(unsigned long x); /* IA5 STRING */ int der_encode_ia5_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); int der_decode_ia5_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen); int der_ia5_char_encode(int c); int der_ia5_value_decode(int v); /* Printable STRING */ int der_encode_printable_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); int der_decode_printable_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen); int der_printable_char_encode(int c); int der_printable_value_decode(int v); /* UTF-8 */ #if (defined(SIZE_MAX) || __STDC_VERSION__ >= 199901L || defined(WCHAR_MAX) || defined(_WCHAR_T) || defined(_WCHAR_T_DEFINED) || defined (__WCHAR_TYPE__)) && !defined(LTC_NO_WCHAR) #include #else typedef ulong32 wchar_t; #endif int der_encode_utf8_string(const wchar_t *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); int der_decode_utf8_string(const unsigned char *in, unsigned long inlen, wchar_t *out, unsigned long *outlen); unsigned long der_utf8_charsize(const wchar_t c); int der_length_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen); /* CHOICE */ int der_decode_choice(const unsigned char *in, unsigned long *inlen, ltc_asn1_list *list, unsigned long outlen); /* UTCTime */ typedef struct { unsigned YY, /* year */ MM, /* month */ DD, /* day */ hh, /* hour */ mm, /* minute */ ss, /* second */ off_dir, /* timezone offset direction 0 == +, 1 == - */ off_hh, /* timezone offset hours */ off_mm; /* timezone offset minutes */ } ltc_utctime; int der_encode_utctime(ltc_utctime *utctime, unsigned char *out, unsigned long *outlen); int der_decode_utctime(const unsigned char *in, unsigned long *inlen, ltc_utctime *out); int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen); #endif /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_pk.h,v $ */ /* $Revision: 1.81 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/headers/tomcrypt_hash.h0000644000175100001440000003025110621351501017763 0ustar tomusers/* ---- HASH FUNCTIONS ---- */ #ifdef LTC_SHA512 struct sha512_state { ulong64 length, state[8]; unsigned long curlen; unsigned char buf[128]; }; #endif #ifdef LTC_SHA256 struct sha256_state { ulong64 length; ulong32 state[8], curlen; unsigned char buf[64]; }; #endif #ifdef LTC_SHA1 struct sha1_state { ulong64 length; ulong32 state[5], curlen; unsigned char buf[64]; }; #endif #ifdef LTC_MD5 struct md5_state { ulong64 length; ulong32 state[4], curlen; unsigned char buf[64]; }; #endif #ifdef LTC_MD4 struct md4_state { ulong64 length; ulong32 state[4], curlen; unsigned char buf[64]; }; #endif #ifdef LTC_TIGER struct tiger_state { ulong64 state[3], length; unsigned long curlen; unsigned char buf[64]; }; #endif #ifdef LTC_MD2 struct md2_state { unsigned char chksum[16], X[48], buf[16]; unsigned long curlen; }; #endif #ifdef LTC_RIPEMD128 struct rmd128_state { ulong64 length; unsigned char buf[64]; ulong32 curlen, state[4]; }; #endif #ifdef LTC_RIPEMD160 struct rmd160_state { ulong64 length; unsigned char buf[64]; ulong32 curlen, state[5]; }; #endif #ifdef LTC_RIPEMD256 struct rmd256_state { ulong64 length; unsigned char buf[64]; ulong32 curlen, state[8]; }; #endif #ifdef LTC_RIPEMD320 struct rmd320_state { ulong64 length; unsigned char buf[64]; ulong32 curlen, state[10]; }; #endif #ifdef LTC_WHIRLPOOL struct whirlpool_state { ulong64 length, state[8]; unsigned char buf[64]; ulong32 curlen; }; #endif #ifdef LTC_CHC_HASH struct chc_state { ulong64 length; unsigned char state[MAXBLOCKSIZE], buf[MAXBLOCKSIZE]; ulong32 curlen; }; #endif typedef union Hash_state { char dummy[1]; #ifdef LTC_CHC_HASH struct chc_state chc; #endif #ifdef LTC_WHIRLPOOL struct whirlpool_state whirlpool; #endif #ifdef LTC_SHA512 struct sha512_state sha512; #endif #ifdef LTC_SHA256 struct sha256_state sha256; #endif #ifdef LTC_SHA1 struct sha1_state sha1; #endif #ifdef LTC_MD5 struct md5_state md5; #endif #ifdef LTC_MD4 struct md4_state md4; #endif #ifdef LTC_MD2 struct md2_state md2; #endif #ifdef LTC_TIGER struct tiger_state tiger; #endif #ifdef LTC_RIPEMD128 struct rmd128_state rmd128; #endif #ifdef LTC_RIPEMD160 struct rmd160_state rmd160; #endif #ifdef LTC_RIPEMD256 struct rmd256_state rmd256; #endif #ifdef LTC_RIPEMD320 struct rmd320_state rmd320; #endif void *data; } hash_state; /** hash descriptor */ extern struct ltc_hash_descriptor { /** name of hash */ char *name; /** internal ID */ unsigned char ID; /** Size of digest in octets */ unsigned long hashsize; /** Input block size in octets */ unsigned long blocksize; /** ASN.1 OID */ unsigned long OID[16]; /** Length of DER encoding */ unsigned long OIDlen; /** Init a hash state @param hash The hash to initialize @return CRYPT_OK if successful */ int (*init)(hash_state *hash); /** Process a block of data @param hash The hash state @param in The data to hash @param inlen The length of the data (octets) @return CRYPT_OK if successful */ int (*process)(hash_state *hash, const unsigned char *in, unsigned long inlen); /** Produce the digest and store it @param hash The hash state @param out [out] The destination of the digest @return CRYPT_OK if successful */ int (*done)(hash_state *hash, unsigned char *out); /** Self-test @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled */ int (*test)(void); /* accelerated hmac callback: if you need to-do multiple packets just use the generic hmac_memory and provide a hash callback */ int (*hmac_block)(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); } hash_descriptor[]; #ifdef LTC_CHC_HASH int chc_register(int cipher); int chc_init(hash_state * md); int chc_process(hash_state * md, const unsigned char *in, unsigned long inlen); int chc_done(hash_state * md, unsigned char *hash); int chc_test(void); extern const struct ltc_hash_descriptor chc_desc; #endif #ifdef LTC_WHIRLPOOL int whirlpool_init(hash_state * md); int whirlpool_process(hash_state * md, const unsigned char *in, unsigned long inlen); int whirlpool_done(hash_state * md, unsigned char *hash); int whirlpool_test(void); extern const struct ltc_hash_descriptor whirlpool_desc; #endif #ifdef LTC_SHA512 int sha512_init(hash_state * md); int sha512_process(hash_state * md, const unsigned char *in, unsigned long inlen); int sha512_done(hash_state * md, unsigned char *hash); int sha512_test(void); extern const struct ltc_hash_descriptor sha512_desc; #endif #ifdef LTC_SHA384 #ifndef LTC_SHA512 #error LTC_SHA512 is required for LTC_SHA384 #endif int sha384_init(hash_state * md); #define sha384_process sha512_process int sha384_done(hash_state * md, unsigned char *hash); int sha384_test(void); extern const struct ltc_hash_descriptor sha384_desc; #endif #ifdef LTC_SHA256 int sha256_init(hash_state * md); int sha256_process(hash_state * md, const unsigned char *in, unsigned long inlen); int sha256_done(hash_state * md, unsigned char *hash); int sha256_test(void); extern const struct ltc_hash_descriptor sha256_desc; #ifdef LTC_SHA224 #ifndef LTC_SHA256 #error LTC_SHA256 is required for LTC_SHA224 #endif int sha224_init(hash_state * md); #define sha224_process sha256_process int sha224_done(hash_state * md, unsigned char *hash); int sha224_test(void); extern const struct ltc_hash_descriptor sha224_desc; #endif #endif #ifdef LTC_SHA1 int sha1_init(hash_state * md); int sha1_process(hash_state * md, const unsigned char *in, unsigned long inlen); int sha1_done(hash_state * md, unsigned char *hash); int sha1_test(void); extern const struct ltc_hash_descriptor sha1_desc; #endif #ifdef LTC_MD5 int md5_init(hash_state * md); int md5_process(hash_state * md, const unsigned char *in, unsigned long inlen); int md5_done(hash_state * md, unsigned char *hash); int md5_test(void); extern const struct ltc_hash_descriptor md5_desc; #endif #ifdef LTC_MD4 int md4_init(hash_state * md); int md4_process(hash_state * md, const unsigned char *in, unsigned long inlen); int md4_done(hash_state * md, unsigned char *hash); int md4_test(void); extern const struct ltc_hash_descriptor md4_desc; #endif #ifdef LTC_MD2 int md2_init(hash_state * md); int md2_process(hash_state * md, const unsigned char *in, unsigned long inlen); int md2_done(hash_state * md, unsigned char *hash); int md2_test(void); extern const struct ltc_hash_descriptor md2_desc; #endif #ifdef LTC_TIGER int tiger_init(hash_state * md); int tiger_process(hash_state * md, const unsigned char *in, unsigned long inlen); int tiger_done(hash_state * md, unsigned char *hash); int tiger_test(void); extern const struct ltc_hash_descriptor tiger_desc; #endif #ifdef LTC_RIPEMD128 int rmd128_init(hash_state * md); int rmd128_process(hash_state * md, const unsigned char *in, unsigned long inlen); int rmd128_done(hash_state * md, unsigned char *hash); int rmd128_test(void); extern const struct ltc_hash_descriptor rmd128_desc; #endif #ifdef LTC_RIPEMD160 int rmd160_init(hash_state * md); int rmd160_process(hash_state * md, const unsigned char *in, unsigned long inlen); int rmd160_done(hash_state * md, unsigned char *hash); int rmd160_test(void); extern const struct ltc_hash_descriptor rmd160_desc; #endif #ifdef LTC_RIPEMD256 int rmd256_init(hash_state * md); int rmd256_process(hash_state * md, const unsigned char *in, unsigned long inlen); int rmd256_done(hash_state * md, unsigned char *hash); int rmd256_test(void); extern const struct ltc_hash_descriptor rmd256_desc; #endif #ifdef LTC_RIPEMD320 int rmd320_init(hash_state * md); int rmd320_process(hash_state * md, const unsigned char *in, unsigned long inlen); int rmd320_done(hash_state * md, unsigned char *hash); int rmd320_test(void); extern const struct ltc_hash_descriptor rmd320_desc; #endif int find_hash(const char *name); int find_hash_id(unsigned char ID); int find_hash_oid(const unsigned long *ID, unsigned long IDlen); int find_hash_any(const char *name, int digestlen); int register_hash(const struct ltc_hash_descriptor *hash); int unregister_hash(const struct ltc_hash_descriptor *hash); int hash_is_valid(int idx); LTC_MUTEX_PROTO(ltc_hash_mutex) int hash_memory(int hash, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); int hash_memory_multi(int hash, unsigned char *out, unsigned long *outlen, const unsigned char *in, unsigned long inlen, ...); int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outlen); int hash_file(int hash, const char *fname, unsigned char *out, unsigned long *outlen); /* a simple macro for making hash "process" functions */ #define HASH_PROCESS(func_name, compress_name, state_var, block_size) \ int func_name (hash_state * md, const unsigned char *in, unsigned long inlen) \ { \ unsigned long n; \ int err; \ LTC_ARGCHK(md != NULL); \ LTC_ARGCHK(in != NULL); \ if (md-> state_var .curlen > sizeof(md-> state_var .buf)) { \ return CRYPT_INVALID_ARG; \ } \ while (inlen > 0) { \ if (md-> state_var .curlen == 0 && inlen >= block_size) { \ if ((err = compress_name (md, (unsigned char *)in)) != CRYPT_OK) { \ return err; \ } \ md-> state_var .length += block_size * 8; \ in += block_size; \ inlen -= block_size; \ } else { \ n = MIN(inlen, (block_size - md-> state_var .curlen)); \ memcpy(md-> state_var .buf + md-> state_var.curlen, in, (size_t)n); \ md-> state_var .curlen += n; \ in += n; \ inlen -= n; \ if (md-> state_var .curlen == block_size) { \ if ((err = compress_name (md, md-> state_var .buf)) != CRYPT_OK) { \ return err; \ } \ md-> state_var .length += 8*block_size; \ md-> state_var .curlen = 0; \ } \ } \ } \ return CRYPT_OK; \ } /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_hash.h,v $ */ /* $Revision: 1.22 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/headers/tomcrypt_math.h0000644000175100001440000004130510621351501017773 0ustar tomusers/** math functions **/ #define LTC_MP_LT -1 #define LTC_MP_EQ 0 #define LTC_MP_GT 1 #define LTC_MP_NO 0 #define LTC_MP_YES 1 #ifndef LTC_MECC typedef void ecc_point; #endif #ifndef LTC_MRSA typedef void rsa_key; #endif /** math descriptor */ typedef struct { /** Name of the math provider */ char *name; /** Bits per digit, amount of bits must fit in an unsigned long */ int bits_per_digit; /* ---- init/deinit functions ---- */ /** initialize a bignum @param a The number to initialize @return CRYPT_OK on success */ int (*init)(void **a); /** init copy @param dst The number to initialize and write to @param src The number to copy from @return CRYPT_OK on success */ int (*init_copy)(void **dst, void *src); /** deinit @param a The number to free @return CRYPT_OK on success */ void (*deinit)(void *a); /* ---- data movement ---- */ /** negate @param src The number to negate @param dst The destination @return CRYPT_OK on success */ int (*neg)(void *src, void *dst); /** copy @param src The number to copy from @param dst The number to write to @return CRYPT_OK on success */ int (*copy)(void *src, void *dst); /* ---- trivial low level functions ---- */ /** set small constant @param a Number to write to @param n Source upto bits_per_digit (actually meant for very small constants) @return CRYPT_OK on succcess */ int (*set_int)(void *a, unsigned long n); /** get small constant @param a Number to read, only fetches upto bits_per_digit from the number @return The lower bits_per_digit of the integer (unsigned) */ unsigned long (*get_int)(void *a); /** get digit n @param a The number to read from @param n The number of the digit to fetch @return The bits_per_digit sized n'th digit of a */ unsigned long (*get_digit)(void *a, int n); /** Get the number of digits that represent the number @param a The number to count @return The number of digits used to represent the number */ int (*get_digit_count)(void *a); /** compare two integers @param a The left side integer @param b The right side integer @return LTC_MP_LT if a < b, LTC_MP_GT if a > b and LTC_MP_EQ otherwise. (signed comparison) */ int (*compare)(void *a, void *b); /** compare against int @param a The left side integer @param b The right side integer (upto bits_per_digit) @return LTC_MP_LT if a < b, LTC_MP_GT if a > b and LTC_MP_EQ otherwise. (signed comparison) */ int (*compare_d)(void *a, unsigned long n); /** Count the number of bits used to represent the integer @param a The integer to count @return The number of bits required to represent the integer */ int (*count_bits)(void * a); /** Count the number of LSB bits which are zero @param a The integer to count @return The number of contiguous zero LSB bits */ int (*count_lsb_bits)(void *a); /** Compute a power of two @param a The integer to store the power in @param n The power of two you want to store (a = 2^n) @return CRYPT_OK on success */ int (*twoexpt)(void *a , int n); /* ---- radix conversions ---- */ /** read ascii string @param a The integer to store into @param str The string to read @param radix The radix the integer has been represented in (2-64) @return CRYPT_OK on success */ int (*read_radix)(void *a, const char *str, int radix); /** write number to string @param a The integer to store @param str The destination for the string @param radix The radix the integer is to be represented in (2-64) @return CRYPT_OK on success */ int (*write_radix)(void *a, char *str, int radix); /** get size as unsigned char string @param a The integer to get the size (when stored in array of octets) @return The length of the integer */ unsigned long (*unsigned_size)(void *a); /** store an integer as an array of octets @param src The integer to store @param dst The buffer to store the integer in @return CRYPT_OK on success */ int (*unsigned_write)(void *src, unsigned char *dst); /** read an array of octets and store as integer @param dst The integer to load @param src The array of octets @param len The number of octets @return CRYPT_OK on success */ int (*unsigned_read)(void *dst, unsigned char *src, unsigned long len); /* ---- basic math ---- */ /** add two integers @param a The first source integer @param b The second source integer @param c The destination of "a + b" @return CRYPT_OK on success */ int (*add)(void *a, void *b, void *c); /** add two integers @param a The first source integer @param b The second source integer (single digit of upto bits_per_digit in length) @param c The destination of "a + b" @return CRYPT_OK on success */ int (*addi)(void *a, unsigned long b, void *c); /** subtract two integers @param a The first source integer @param b The second source integer @param c The destination of "a - b" @return CRYPT_OK on success */ int (*sub)(void *a, void *b, void *c); /** subtract two integers @param a The first source integer @param b The second source integer (single digit of upto bits_per_digit in length) @param c The destination of "a - b" @return CRYPT_OK on success */ int (*subi)(void *a, unsigned long b, void *c); /** multiply two integers @param a The first source integer @param b The second source integer (single digit of upto bits_per_digit in length) @param c The destination of "a * b" @return CRYPT_OK on success */ int (*mul)(void *a, void *b, void *c); /** multiply two integers @param a The first source integer @param b The second source integer (single digit of upto bits_per_digit in length) @param c The destination of "a * b" @return CRYPT_OK on success */ int (*muli)(void *a, unsigned long b, void *c); /** Square an integer @param a The integer to square @param b The destination @return CRYPT_OK on success */ int (*sqr)(void *a, void *b); /** Divide an integer @param a The dividend @param b The divisor @param c The quotient (can be NULL to signify don't care) @param d The remainder (can be NULL to signify don't care) @return CRYPT_OK on success */ int (*mpdiv)(void *a, void *b, void *c, void *d); /** divide by two @param a The integer to divide (shift right) @param b The destination @return CRYPT_OK on success */ int (*div_2)(void *a, void *b); /** Get remainder (small value) @param a The integer to reduce @param b The modulus (upto bits_per_digit in length) @param c The destination for the residue @return CRYPT_OK on success */ int (*modi)(void *a, unsigned long b, unsigned long *c); /** gcd @param a The first integer @param b The second integer @param c The destination for (a, b) @return CRYPT_OK on success */ int (*gcd)(void *a, void *b, void *c); /** lcm @param a The first integer @param b The second integer @param c The destination for [a, b] @return CRYPT_OK on success */ int (*lcm)(void *a, void *b, void *c); /** Modular multiplication @param a The first source @param b The second source @param c The modulus @param d The destination (a*b mod c) @return CRYPT_OK on success */ int (*mulmod)(void *a, void *b, void *c, void *d); /** Modular squaring @param a The first source @param b The modulus @param c The destination (a*a mod b) @return CRYPT_OK on success */ int (*sqrmod)(void *a, void *b, void *c); /** Modular inversion @param a The value to invert @param b The modulus @param c The destination (1/a mod b) @return CRYPT_OK on success */ int (*invmod)(void *, void *, void *); /* ---- reduction ---- */ /** setup montgomery @param a The modulus @param b The destination for the reduction digit @return CRYPT_OK on success */ int (*montgomery_setup)(void *a, void **b); /** get normalization value @param a The destination for the normalization value @param b The modulus @return CRYPT_OK on success */ int (*montgomery_normalization)(void *a, void *b); /** reduce a number @param a The number [and dest] to reduce @param b The modulus @param c The value "b" from montgomery_setup() @return CRYPT_OK on success */ int (*montgomery_reduce)(void *a, void *b, void *c); /** clean up (frees memory) @param a The value "b" from montgomery_setup() @return CRYPT_OK on success */ void (*montgomery_deinit)(void *a); /* ---- exponentiation ---- */ /** Modular exponentiation @param a The base integer @param b The power (can be negative) integer @param c The modulus integer @param d The destination @return CRYPT_OK on success */ int (*exptmod)(void *a, void *b, void *c, void *d); /** Primality testing @param a The integer to test @param b The destination of the result (FP_YES if prime) @return CRYPT_OK on success */ int (*isprime)(void *a, int *b); /* ---- (optional) ecc point math ---- */ /** ECC GF(p) point multiplication (from the NIST curves) @param k The integer to multiply the point by @param G The point to multiply @param R The destination for kG @param modulus The modulus for the field @param map Boolean indicated whether to map back to affine or not (can be ignored if you work in affine only) @return CRYPT_OK on success */ int (*ecc_ptmul)(void *k, ecc_point *G, ecc_point *R, void *modulus, int map); /** ECC GF(p) point addition @param P The first point @param Q The second point @param R The destination of P + Q @param modulus The modulus @param mp The "b" value from montgomery_setup() @return CRYPT_OK on success */ int (*ecc_ptadd)(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp); /** ECC GF(p) point double @param P The first point @param R The destination of 2P @param modulus The modulus @param mp The "b" value from montgomery_setup() @return CRYPT_OK on success */ int (*ecc_ptdbl)(ecc_point *P, ecc_point *R, void *modulus, void *mp); /** ECC mapping from projective to affine, currently uses (x,y,z) => (x/z^2, y/z^3, 1) @param P The point to map @param modulus The modulus @param mp The "b" value from montgomery_setup() @return CRYPT_OK on success @remark The mapping can be different but keep in mind a ecc_point only has three integers (x,y,z) so if you use a different mapping you have to make it fit. */ int (*ecc_map)(ecc_point *P, void *modulus, void *mp); /** Computes kA*A + kB*B = C using Shamir's Trick @param A First point to multiply @param kA What to multiple A by @param B Second point to multiply @param kB What to multiple B by @param C [out] Destination point (can overlap with A or B @param modulus Modulus for curve @return CRYPT_OK on success */ int (*ecc_mul2add)(ecc_point *A, void *kA, ecc_point *B, void *kB, ecc_point *C, void *modulus); /* ---- (optional) rsa optimized math (for internal CRT) ---- */ /** RSA Key Generation @param prng An active PRNG state @param wprng The index of the PRNG desired @param size The size of the modulus (key size) desired (octets) @param e The "e" value (public key). e==65537 is a good choice @param key [out] Destination of a newly created private key pair @return CRYPT_OK if successful, upon error all allocated ram is freed */ int (*rsa_keygen)(prng_state *prng, int wprng, int size, long e, rsa_key *key); /** RSA exponentiation @param in The octet array representing the base @param inlen The length of the input @param out The destination (to be stored in an octet array format) @param outlen The length of the output buffer and the resulting size (zero padded to the size of the modulus) @param which PK_PUBLIC for public RSA and PK_PRIVATE for private RSA @param key The RSA key to use @return CRYPT_OK on success */ int (*rsa_me)(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, int which, rsa_key *key); } ltc_math_descriptor; extern ltc_math_descriptor ltc_mp; int ltc_init_multi(void **a, ...); void ltc_deinit_multi(void *a, ...); #ifdef LTM_DESC extern const ltc_math_descriptor ltm_desc; #endif #ifdef TFM_DESC extern const ltc_math_descriptor tfm_desc; #endif #ifdef GMP_DESC extern const ltc_math_descriptor gmp_desc; #endif #if !defined(DESC_DEF_ONLY) && defined(LTC_SOURCE) #define MP_DIGIT_BIT ltc_mp.bits_per_digit /* some handy macros */ #define mp_init(a) ltc_mp.init(a) #define mp_init_multi ltc_init_multi #define mp_clear(a) ltc_mp.deinit(a) #define mp_clear_multi ltc_deinit_multi #define mp_init_copy(a, b) ltc_mp.init_copy(a, b) #define mp_neg(a, b) ltc_mp.neg(a, b) #define mp_copy(a, b) ltc_mp.copy(a, b) #define mp_set(a, b) ltc_mp.set_int(a, b) #define mp_set_int(a, b) ltc_mp.set_int(a, b) #define mp_get_int(a) ltc_mp.get_int(a) #define mp_get_digit(a, n) ltc_mp.get_digit(a, n) #define mp_get_digit_count(a) ltc_mp.get_digit_count(a) #define mp_cmp(a, b) ltc_mp.compare(a, b) #define mp_cmp_d(a, b) ltc_mp.compare_d(a, b) #define mp_count_bits(a) ltc_mp.count_bits(a) #define mp_cnt_lsb(a) ltc_mp.count_lsb_bits(a) #define mp_2expt(a, b) ltc_mp.twoexpt(a, b) #define mp_read_radix(a, b, c) ltc_mp.read_radix(a, b, c) #define mp_toradix(a, b, c) ltc_mp.write_radix(a, b, c) #define mp_unsigned_bin_size(a) ltc_mp.unsigned_size(a) #define mp_to_unsigned_bin(a, b) ltc_mp.unsigned_write(a, b) #define mp_read_unsigned_bin(a, b, c) ltc_mp.unsigned_read(a, b, c) #define mp_add(a, b, c) ltc_mp.add(a, b, c) #define mp_add_d(a, b, c) ltc_mp.addi(a, b, c) #define mp_sub(a, b, c) ltc_mp.sub(a, b, c) #define mp_sub_d(a, b, c) ltc_mp.subi(a, b, c) #define mp_mul(a, b, c) ltc_mp.mul(a, b, c) #define mp_mul_d(a, b, c) ltc_mp.muli(a, b, c) #define mp_sqr(a, b) ltc_mp.sqr(a, b) #define mp_div(a, b, c, d) ltc_mp.mpdiv(a, b, c, d) #define mp_div_2(a, b) ltc_mp.div_2(a, b) #define mp_mod(a, b, c) ltc_mp.mpdiv(a, b, NULL, c) #define mp_mod_d(a, b, c) ltc_mp.modi(a, b, c) #define mp_gcd(a, b, c) ltc_mp.gcd(a, b, c) #define mp_lcm(a, b, c) ltc_mp.lcm(a, b, c) #define mp_mulmod(a, b, c, d) ltc_mp.mulmod(a, b, c, d) #define mp_sqrmod(a, b, c) ltc_mp.sqrmod(a, b, c) #define mp_invmod(a, b, c) ltc_mp.invmod(a, b, c) #define mp_montgomery_setup(a, b) ltc_mp.montgomery_setup(a, b) #define mp_montgomery_normalization(a, b) ltc_mp.montgomery_normalization(a, b) #define mp_montgomery_reduce(a, b, c) ltc_mp.montgomery_reduce(a, b, c) #define mp_montgomery_free(a) ltc_mp.montgomery_deinit(a) #define mp_exptmod(a,b,c,d) ltc_mp.exptmod(a,b,c,d) #define mp_prime_is_prime(a, b, c) ltc_mp.isprime(a, c) #define mp_iszero(a) (mp_cmp_d(a, 0) == LTC_MP_EQ ? LTC_MP_YES : LTC_MP_NO) #define mp_isodd(a) (mp_get_digit_count(a) > 0 ? (mp_get_digit(a, 0) & 1 ? LTC_MP_YES : LTC_MP_NO) : LTC_MP_NO) #define mp_exch(a, b) do { void *ABC__tmp = a; a = b; b = ABC__tmp; } while(0); #define mp_tohex(a, b) mp_toradix(a, b, 16) #endif /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_math.h,v $ */ /* $Revision: 1.44 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/headers/tomcrypt_misc.h0000644000175100001440000000126310621351501017774 0ustar tomusers/* ---- LTC_BASE64 Routines ---- */ #ifdef LTC_BASE64 int base64_encode(const unsigned char *in, unsigned long len, unsigned char *out, unsigned long *outlen); int base64_decode(const unsigned char *in, unsigned long len, unsigned char *out, unsigned long *outlen); #endif /* ---- MEM routines ---- */ void zeromem(void *dst, size_t len); void burn_stack(unsigned long len); const char *error_to_string(int err); extern const char *crypt_build_settings; /* ---- HMM ---- */ int crypt_fsa(void *mp, ...); /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_misc.h,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/headers/tomcrypt.h0000644000175100001440000000475710621351501016774 0ustar tomusers#ifndef TOMCRYPT_H_ #define TOMCRYPT_H_ #include #include #include #include #include #include #include /* use configuration data */ #include #ifdef __cplusplus extern "C" { #endif /* version */ #define CRYPT 0x0117 #define SCRYPT "1.17" /* max size of either a cipher/hash block or symmetric key [largest of the two] */ #define MAXBLOCKSIZE 128 /* descriptor table size */ #define TAB_SIZE 32 /* error codes [will be expanded in future releases] */ enum { CRYPT_OK=0, /* Result OK */ CRYPT_ERROR, /* Generic Error */ CRYPT_NOP, /* Not a failure but no operation was performed */ CRYPT_INVALID_KEYSIZE, /* Invalid key size given */ CRYPT_INVALID_ROUNDS, /* Invalid number of rounds */ CRYPT_FAIL_TESTVECTOR, /* Algorithm failed test vectors */ CRYPT_BUFFER_OVERFLOW, /* Not enough space for output */ CRYPT_INVALID_PACKET, /* Invalid input packet given */ CRYPT_INVALID_PRNGSIZE, /* Invalid number of bits for a PRNG */ CRYPT_ERROR_READPRNG, /* Could not read enough from PRNG */ CRYPT_INVALID_CIPHER, /* Invalid cipher specified */ CRYPT_INVALID_HASH, /* Invalid hash specified */ CRYPT_INVALID_PRNG, /* Invalid PRNG specified */ CRYPT_MEM, /* Out of memory */ CRYPT_PK_TYPE_MISMATCH, /* Not equivalent types of PK keys */ CRYPT_PK_NOT_PRIVATE, /* Requires a private PK key */ CRYPT_INVALID_ARG, /* Generic invalid argument */ CRYPT_FILE_NOTFOUND, /* File Not Found */ CRYPT_PK_INVALID_TYPE, /* Invalid type of PK key */ CRYPT_PK_INVALID_SYSTEM,/* Invalid PK system specified */ CRYPT_PK_DUP, /* Duplicate key already in key ring */ CRYPT_PK_NOT_FOUND, /* Key not found in keyring */ CRYPT_PK_INVALID_SIZE, /* Invalid size input for PK parameters */ CRYPT_INVALID_PRIME_SIZE,/* Invalid size of prime requested */ CRYPT_PK_INVALID_PADDING /* Invalid padding on input */ }; #include #include #include #include #include #include #include #include #include #include #include #ifdef __cplusplus } #endif #endif /* TOMCRYPT_H_ */ /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt.h,v $ */ /* $Revision: 1.21 $ */ /* $Date: 2006/12/16 19:34:05 $ */ libtomcrypt-1.17/src/headers/tomcrypt_pkcs.h0000644000175100001440000000762510621351501020011 0ustar tomusers/* LTC_PKCS Header Info */ /* ===> LTC_PKCS #1 -- RSA Cryptography <=== */ #ifdef LTC_PKCS_1 enum ltc_pkcs_1_v1_5_blocks { LTC_LTC_PKCS_1_EMSA = 1, /* Block type 1 (LTC_PKCS #1 v1.5 signature padding) */ LTC_LTC_PKCS_1_EME = 2 /* Block type 2 (LTC_PKCS #1 v1.5 encryption padding) */ }; enum ltc_pkcs_1_paddings { LTC_LTC_PKCS_1_V1_5 = 1, /* LTC_PKCS #1 v1.5 padding (\sa ltc_pkcs_1_v1_5_blocks) */ LTC_LTC_PKCS_1_OAEP = 2, /* LTC_PKCS #1 v2.0 encryption padding */ LTC_LTC_PKCS_1_PSS = 3 /* LTC_PKCS #1 v2.1 signature padding */ }; int pkcs_1_mgf1( int hash_idx, const unsigned char *seed, unsigned long seedlen, unsigned char *mask, unsigned long masklen); int pkcs_1_i2osp(void *n, unsigned long modulus_len, unsigned char *out); int pkcs_1_os2ip(void *n, unsigned char *in, unsigned long inlen); /* *** v1.5 padding */ int pkcs_1_v1_5_encode(const unsigned char *msg, unsigned long msglen, int block_type, unsigned long modulus_bitlen, prng_state *prng, int prng_idx, unsigned char *out, unsigned long *outlen); int pkcs_1_v1_5_decode(const unsigned char *msg, unsigned long msglen, int block_type, unsigned long modulus_bitlen, unsigned char *out, unsigned long *outlen, int *is_valid); /* *** v2.1 padding */ int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, const unsigned char *lparam, unsigned long lparamlen, unsigned long modulus_bitlen, prng_state *prng, int prng_idx, int hash_idx, unsigned char *out, unsigned long *outlen); int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, const unsigned char *lparam, unsigned long lparamlen, unsigned long modulus_bitlen, int hash_idx, unsigned char *out, unsigned long *outlen, int *res); int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, unsigned long saltlen, prng_state *prng, int prng_idx, int hash_idx, unsigned long modulus_bitlen, unsigned char *out, unsigned long *outlen); int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, const unsigned char *sig, unsigned long siglen, unsigned long saltlen, int hash_idx, unsigned long modulus_bitlen, int *res); #endif /* LTC_PKCS_1 */ /* ===> LTC_PKCS #5 -- Password Based Cryptography <=== */ #ifdef LTC_PKCS_5 /* Algorithm #1 (old) */ int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, const unsigned char *salt, int iteration_count, int hash_idx, unsigned char *out, unsigned long *outlen); /* Algorithm #2 (new) */ int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, const unsigned char *salt, unsigned long salt_len, int iteration_count, int hash_idx, unsigned char *out, unsigned long *outlen); #endif /* LTC_PKCS_5 */ /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_pkcs.h,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/headers/tomcrypt_prng.h0000644000175100001440000001607010621351501020011 0ustar tomusers/* ---- PRNG Stuff ---- */ #ifdef LTC_YARROW struct yarrow_prng { int cipher, hash; unsigned char pool[MAXBLOCKSIZE]; symmetric_CTR ctr; LTC_MUTEX_TYPE(prng_lock) }; #endif #ifdef LTC_RC4 struct rc4_prng { int x, y; unsigned char buf[256]; }; #endif #ifdef LTC_FORTUNA struct fortuna_prng { hash_state pool[LTC_FORTUNA_POOLS]; /* the pools */ symmetric_key skey; unsigned char K[32], /* the current key */ IV[16]; /* IV for CTR mode */ unsigned long pool_idx, /* current pool we will add to */ pool0_len, /* length of 0'th pool */ wd; ulong64 reset_cnt; /* number of times we have reset */ LTC_MUTEX_TYPE(prng_lock) }; #endif #ifdef LTC_SOBER128 struct sober128_prng { ulong32 R[17], /* Working storage for the shift register */ initR[17], /* saved register contents */ konst, /* key dependent constant */ sbuf; /* partial word encryption buffer */ int nbuf, /* number of part-word stream bits buffered */ flag, /* first add_entropy call or not? */ set; /* did we call add_entropy to set key? */ }; #endif typedef union Prng_state { char dummy[1]; #ifdef LTC_YARROW struct yarrow_prng yarrow; #endif #ifdef LTC_RC4 struct rc4_prng rc4; #endif #ifdef LTC_FORTUNA struct fortuna_prng fortuna; #endif #ifdef LTC_SOBER128 struct sober128_prng sober128; #endif } prng_state; /** PRNG descriptor */ extern struct ltc_prng_descriptor { /** Name of the PRNG */ char *name; /** size in bytes of exported state */ int export_size; /** Start a PRNG state @param prng [out] The state to initialize @return CRYPT_OK if successful */ int (*start)(prng_state *prng); /** Add entropy to the PRNG @param in The entropy @param inlen Length of the entropy (octets)\ @param prng The PRNG state @return CRYPT_OK if successful */ int (*add_entropy)(const unsigned char *in, unsigned long inlen, prng_state *prng); /** Ready a PRNG state to read from @param prng The PRNG state to ready @return CRYPT_OK if successful */ int (*ready)(prng_state *prng); /** Read from the PRNG @param out [out] Where to store the data @param outlen Length of data desired (octets) @param prng The PRNG state to read from @return Number of octets read */ unsigned long (*read)(unsigned char *out, unsigned long outlen, prng_state *prng); /** Terminate a PRNG state @param prng The PRNG state to terminate @return CRYPT_OK if successful */ int (*done)(prng_state *prng); /** Export a PRNG state @param out [out] The destination for the state @param outlen [in/out] The max size and resulting size of the PRNG state @param prng The PRNG to export @return CRYPT_OK if successful */ int (*pexport)(unsigned char *out, unsigned long *outlen, prng_state *prng); /** Import a PRNG state @param in The data to import @param inlen The length of the data to import (octets) @param prng The PRNG to initialize/import @return CRYPT_OK if successful */ int (*pimport)(const unsigned char *in, unsigned long inlen, prng_state *prng); /** Self-test the PRNG @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled */ int (*test)(void); } prng_descriptor[]; #ifdef LTC_YARROW int yarrow_start(prng_state *prng); int yarrow_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); int yarrow_ready(prng_state *prng); unsigned long yarrow_read(unsigned char *out, unsigned long outlen, prng_state *prng); int yarrow_done(prng_state *prng); int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng); int yarrow_import(const unsigned char *in, unsigned long inlen, prng_state *prng); int yarrow_test(void); extern const struct ltc_prng_descriptor yarrow_desc; #endif #ifdef LTC_FORTUNA int fortuna_start(prng_state *prng); int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); int fortuna_ready(prng_state *prng); unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state *prng); int fortuna_done(prng_state *prng); int fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng); int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng); int fortuna_test(void); extern const struct ltc_prng_descriptor fortuna_desc; #endif #ifdef LTC_RC4 int rc4_start(prng_state *prng); int rc4_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); int rc4_ready(prng_state *prng); unsigned long rc4_read(unsigned char *out, unsigned long outlen, prng_state *prng); int rc4_done(prng_state *prng); int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng); int rc4_import(const unsigned char *in, unsigned long inlen, prng_state *prng); int rc4_test(void); extern const struct ltc_prng_descriptor rc4_desc; #endif #ifdef LTC_SPRNG int sprng_start(prng_state *prng); int sprng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); int sprng_ready(prng_state *prng); unsigned long sprng_read(unsigned char *out, unsigned long outlen, prng_state *prng); int sprng_done(prng_state *prng); int sprng_export(unsigned char *out, unsigned long *outlen, prng_state *prng); int sprng_import(const unsigned char *in, unsigned long inlen, prng_state *prng); int sprng_test(void); extern const struct ltc_prng_descriptor sprng_desc; #endif #ifdef LTC_SOBER128 int sober128_start(prng_state *prng); int sober128_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); int sober128_ready(prng_state *prng); unsigned long sober128_read(unsigned char *out, unsigned long outlen, prng_state *prng); int sober128_done(prng_state *prng); int sober128_export(unsigned char *out, unsigned long *outlen, prng_state *prng); int sober128_import(const unsigned char *in, unsigned long inlen, prng_state *prng); int sober128_test(void); extern const struct ltc_prng_descriptor sober128_desc; #endif int find_prng(const char *name); int register_prng(const struct ltc_prng_descriptor *prng); int unregister_prng(const struct ltc_prng_descriptor *prng); int prng_is_valid(int idx); LTC_MUTEX_PROTO(ltc_prng_mutex) /* Slow RNG you **might** be able to use to seed a PRNG with. Be careful as this * might not work on all platforms as planned */ unsigned long rng_get_bytes(unsigned char *out, unsigned long outlen, void (*callback)(void)); int rng_make_prng(int bits, int wprng, prng_state *prng, void (*callback)(void)); /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_prng.h,v $ */ /* $Revision: 1.9 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/ciphers/0000755000175100001440000000000010621351501014747 5ustar tomuserslibtomcrypt-1.17/src/ciphers/aes/0000755000175100001440000000000010621351501015517 5ustar tomuserslibtomcrypt-1.17/src/ciphers/aes/aes.c0000644000175100001440000004572410621351501016447 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /* AES implementation by Tom St Denis * * Derived from the Public Domain source code by --- * rijndael-alg-fst.c * * @version 3.0 (December 2000) * * Optimised ANSI C code for the Rijndael cipher (now AES) * * @author Vincent Rijmen * @author Antoon Bosselaers * @author Paulo Barreto --- */ /** @file aes.c Implementation of AES */ #include "tomcrypt.h" #ifdef LTC_RIJNDAEL #ifndef ENCRYPT_ONLY #define SETUP rijndael_setup #define ECB_ENC rijndael_ecb_encrypt #define ECB_DEC rijndael_ecb_decrypt #define ECB_DONE rijndael_done #define ECB_TEST rijndael_test #define ECB_KS rijndael_keysize const struct ltc_cipher_descriptor rijndael_desc = { "rijndael", 6, 16, 32, 16, 10, SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; const struct ltc_cipher_descriptor aes_desc = { "aes", 6, 16, 32, 16, 10, SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; #else #define SETUP rijndael_enc_setup #define ECB_ENC rijndael_enc_ecb_encrypt #define ECB_KS rijndael_enc_keysize #define ECB_DONE rijndael_enc_done const struct ltc_cipher_descriptor rijndael_enc_desc = { "rijndael", 6, 16, 32, 16, 10, SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; const struct ltc_cipher_descriptor aes_enc_desc = { "aes", 6, 16, 32, 16, 10, SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; #endif #include "aes_tab.c" static ulong32 setup_mix(ulong32 temp) { return (Te4_3[byte(temp, 2)]) ^ (Te4_2[byte(temp, 1)]) ^ (Te4_1[byte(temp, 0)]) ^ (Te4_0[byte(temp, 3)]); } #ifndef ENCRYPT_ONLY #ifdef LTC_SMALL_CODE static ulong32 setup_mix2(ulong32 temp) { return Td0(255 & Te4[byte(temp, 3)]) ^ Td1(255 & Te4[byte(temp, 2)]) ^ Td2(255 & Te4[byte(temp, 1)]) ^ Td3(255 & Te4[byte(temp, 0)]); } #endif #endif /** Initialize the AES (Rijndael) block cipher @param key The symmetric key you wish to pass @param keylen The key length in bytes @param num_rounds The number of rounds desired (0 for default) @param skey The key in as scheduled by this function. @return CRYPT_OK if successful */ int SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) { int i, j; ulong32 temp, *rk; #ifndef ENCRYPT_ONLY ulong32 *rrk; #endif LTC_ARGCHK(key != NULL); LTC_ARGCHK(skey != NULL); if (keylen != 16 && keylen != 24 && keylen != 32) { return CRYPT_INVALID_KEYSIZE; } if (num_rounds != 0 && num_rounds != (10 + ((keylen/8)-2)*2)) { return CRYPT_INVALID_ROUNDS; } skey->rijndael.Nr = 10 + ((keylen/8)-2)*2; /* setup the forward key */ i = 0; rk = skey->rijndael.eK; LOAD32H(rk[0], key ); LOAD32H(rk[1], key + 4); LOAD32H(rk[2], key + 8); LOAD32H(rk[3], key + 12); if (keylen == 16) { j = 44; for (;;) { temp = rk[3]; rk[4] = rk[0] ^ setup_mix(temp) ^ rcon[i]; rk[5] = rk[1] ^ rk[4]; rk[6] = rk[2] ^ rk[5]; rk[7] = rk[3] ^ rk[6]; if (++i == 10) { break; } rk += 4; } } else if (keylen == 24) { j = 52; LOAD32H(rk[4], key + 16); LOAD32H(rk[5], key + 20); for (;;) { #ifdef _MSC_VER temp = skey->rijndael.eK[rk - skey->rijndael.eK + 5]; #else temp = rk[5]; #endif rk[ 6] = rk[ 0] ^ setup_mix(temp) ^ rcon[i]; rk[ 7] = rk[ 1] ^ rk[ 6]; rk[ 8] = rk[ 2] ^ rk[ 7]; rk[ 9] = rk[ 3] ^ rk[ 8]; if (++i == 8) { break; } rk[10] = rk[ 4] ^ rk[ 9]; rk[11] = rk[ 5] ^ rk[10]; rk += 6; } } else if (keylen == 32) { j = 60; LOAD32H(rk[4], key + 16); LOAD32H(rk[5], key + 20); LOAD32H(rk[6], key + 24); LOAD32H(rk[7], key + 28); for (;;) { #ifdef _MSC_VER temp = skey->rijndael.eK[rk - skey->rijndael.eK + 7]; #else temp = rk[7]; #endif rk[ 8] = rk[ 0] ^ setup_mix(temp) ^ rcon[i]; rk[ 9] = rk[ 1] ^ rk[ 8]; rk[10] = rk[ 2] ^ rk[ 9]; rk[11] = rk[ 3] ^ rk[10]; if (++i == 7) { break; } temp = rk[11]; rk[12] = rk[ 4] ^ setup_mix(RORc(temp, 8)); rk[13] = rk[ 5] ^ rk[12]; rk[14] = rk[ 6] ^ rk[13]; rk[15] = rk[ 7] ^ rk[14]; rk += 8; } } else { /* this can't happen */ return CRYPT_ERROR; } #ifndef ENCRYPT_ONLY /* setup the inverse key now */ rk = skey->rijndael.dK; rrk = skey->rijndael.eK + j - 4; /* apply the inverse MixColumn transform to all round keys but the first and the last: */ /* copy first */ *rk++ = *rrk++; *rk++ = *rrk++; *rk++ = *rrk++; *rk = *rrk; rk -= 3; rrk -= 3; for (i = 1; i < skey->rijndael.Nr; i++) { rrk -= 4; rk += 4; #ifdef LTC_SMALL_CODE temp = rrk[0]; rk[0] = setup_mix2(temp); temp = rrk[1]; rk[1] = setup_mix2(temp); temp = rrk[2]; rk[2] = setup_mix2(temp); temp = rrk[3]; rk[3] = setup_mix2(temp); #else temp = rrk[0]; rk[0] = Tks0[byte(temp, 3)] ^ Tks1[byte(temp, 2)] ^ Tks2[byte(temp, 1)] ^ Tks3[byte(temp, 0)]; temp = rrk[1]; rk[1] = Tks0[byte(temp, 3)] ^ Tks1[byte(temp, 2)] ^ Tks2[byte(temp, 1)] ^ Tks3[byte(temp, 0)]; temp = rrk[2]; rk[2] = Tks0[byte(temp, 3)] ^ Tks1[byte(temp, 2)] ^ Tks2[byte(temp, 1)] ^ Tks3[byte(temp, 0)]; temp = rrk[3]; rk[3] = Tks0[byte(temp, 3)] ^ Tks1[byte(temp, 2)] ^ Tks2[byte(temp, 1)] ^ Tks3[byte(temp, 0)]; #endif } /* copy last */ rrk -= 4; rk += 4; *rk++ = *rrk++; *rk++ = *rrk++; *rk++ = *rrk++; *rk = *rrk; #endif /* ENCRYPT_ONLY */ return CRYPT_OK; } /** Encrypts a block of text with AES @param pt The input plaintext (16 bytes) @param ct The output ciphertext (16 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ #ifdef LTC_CLEAN_STACK static int _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) #else int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) #endif { ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk; int Nr, r; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); Nr = skey->rijndael.Nr; rk = skey->rijndael.eK; /* * map byte array block to cipher state * and add initial round key: */ LOAD32H(s0, pt ); s0 ^= rk[0]; LOAD32H(s1, pt + 4); s1 ^= rk[1]; LOAD32H(s2, pt + 8); s2 ^= rk[2]; LOAD32H(s3, pt + 12); s3 ^= rk[3]; #ifdef LTC_SMALL_CODE for (r = 0; ; r++) { rk += 4; t0 = Te0(byte(s0, 3)) ^ Te1(byte(s1, 2)) ^ Te2(byte(s2, 1)) ^ Te3(byte(s3, 0)) ^ rk[0]; t1 = Te0(byte(s1, 3)) ^ Te1(byte(s2, 2)) ^ Te2(byte(s3, 1)) ^ Te3(byte(s0, 0)) ^ rk[1]; t2 = Te0(byte(s2, 3)) ^ Te1(byte(s3, 2)) ^ Te2(byte(s0, 1)) ^ Te3(byte(s1, 0)) ^ rk[2]; t3 = Te0(byte(s3, 3)) ^ Te1(byte(s0, 2)) ^ Te2(byte(s1, 1)) ^ Te3(byte(s2, 0)) ^ rk[3]; if (r == Nr-2) { break; } s0 = t0; s1 = t1; s2 = t2; s3 = t3; } rk += 4; #else /* * Nr - 1 full rounds: */ r = Nr >> 1; for (;;) { t0 = Te0(byte(s0, 3)) ^ Te1(byte(s1, 2)) ^ Te2(byte(s2, 1)) ^ Te3(byte(s3, 0)) ^ rk[4]; t1 = Te0(byte(s1, 3)) ^ Te1(byte(s2, 2)) ^ Te2(byte(s3, 1)) ^ Te3(byte(s0, 0)) ^ rk[5]; t2 = Te0(byte(s2, 3)) ^ Te1(byte(s3, 2)) ^ Te2(byte(s0, 1)) ^ Te3(byte(s1, 0)) ^ rk[6]; t3 = Te0(byte(s3, 3)) ^ Te1(byte(s0, 2)) ^ Te2(byte(s1, 1)) ^ Te3(byte(s2, 0)) ^ rk[7]; rk += 8; if (--r == 0) { break; } s0 = Te0(byte(t0, 3)) ^ Te1(byte(t1, 2)) ^ Te2(byte(t2, 1)) ^ Te3(byte(t3, 0)) ^ rk[0]; s1 = Te0(byte(t1, 3)) ^ Te1(byte(t2, 2)) ^ Te2(byte(t3, 1)) ^ Te3(byte(t0, 0)) ^ rk[1]; s2 = Te0(byte(t2, 3)) ^ Te1(byte(t3, 2)) ^ Te2(byte(t0, 1)) ^ Te3(byte(t1, 0)) ^ rk[2]; s3 = Te0(byte(t3, 3)) ^ Te1(byte(t0, 2)) ^ Te2(byte(t1, 1)) ^ Te3(byte(t2, 0)) ^ rk[3]; } #endif /* * apply last round and * map cipher state to byte array block: */ s0 = (Te4_3[byte(t0, 3)]) ^ (Te4_2[byte(t1, 2)]) ^ (Te4_1[byte(t2, 1)]) ^ (Te4_0[byte(t3, 0)]) ^ rk[0]; STORE32H(s0, ct); s1 = (Te4_3[byte(t1, 3)]) ^ (Te4_2[byte(t2, 2)]) ^ (Te4_1[byte(t3, 1)]) ^ (Te4_0[byte(t0, 0)]) ^ rk[1]; STORE32H(s1, ct+4); s2 = (Te4_3[byte(t2, 3)]) ^ (Te4_2[byte(t3, 2)]) ^ (Te4_1[byte(t0, 1)]) ^ (Te4_0[byte(t1, 0)]) ^ rk[2]; STORE32H(s2, ct+8); s3 = (Te4_3[byte(t3, 3)]) ^ (Te4_2[byte(t0, 2)]) ^ (Te4_1[byte(t1, 1)]) ^ (Te4_0[byte(t2, 0)]) ^ rk[3]; STORE32H(s3, ct+12); return CRYPT_OK; } #ifdef LTC_CLEAN_STACK int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) { int err = _rijndael_ecb_encrypt(pt, ct, skey); burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2); return err; } #endif #ifndef ENCRYPT_ONLY /** Decrypts a block of text with AES @param ct The input ciphertext (16 bytes) @param pt The output plaintext (16 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ #ifdef LTC_CLEAN_STACK static int _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) #else int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) #endif { ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk; int Nr, r; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); Nr = skey->rijndael.Nr; rk = skey->rijndael.dK; /* * map byte array block to cipher state * and add initial round key: */ LOAD32H(s0, ct ); s0 ^= rk[0]; LOAD32H(s1, ct + 4); s1 ^= rk[1]; LOAD32H(s2, ct + 8); s2 ^= rk[2]; LOAD32H(s3, ct + 12); s3 ^= rk[3]; #ifdef LTC_SMALL_CODE for (r = 0; ; r++) { rk += 4; t0 = Td0(byte(s0, 3)) ^ Td1(byte(s3, 2)) ^ Td2(byte(s2, 1)) ^ Td3(byte(s1, 0)) ^ rk[0]; t1 = Td0(byte(s1, 3)) ^ Td1(byte(s0, 2)) ^ Td2(byte(s3, 1)) ^ Td3(byte(s2, 0)) ^ rk[1]; t2 = Td0(byte(s2, 3)) ^ Td1(byte(s1, 2)) ^ Td2(byte(s0, 1)) ^ Td3(byte(s3, 0)) ^ rk[2]; t3 = Td0(byte(s3, 3)) ^ Td1(byte(s2, 2)) ^ Td2(byte(s1, 1)) ^ Td3(byte(s0, 0)) ^ rk[3]; if (r == Nr-2) { break; } s0 = t0; s1 = t1; s2 = t2; s3 = t3; } rk += 4; #else /* * Nr - 1 full rounds: */ r = Nr >> 1; for (;;) { t0 = Td0(byte(s0, 3)) ^ Td1(byte(s3, 2)) ^ Td2(byte(s2, 1)) ^ Td3(byte(s1, 0)) ^ rk[4]; t1 = Td0(byte(s1, 3)) ^ Td1(byte(s0, 2)) ^ Td2(byte(s3, 1)) ^ Td3(byte(s2, 0)) ^ rk[5]; t2 = Td0(byte(s2, 3)) ^ Td1(byte(s1, 2)) ^ Td2(byte(s0, 1)) ^ Td3(byte(s3, 0)) ^ rk[6]; t3 = Td0(byte(s3, 3)) ^ Td1(byte(s2, 2)) ^ Td2(byte(s1, 1)) ^ Td3(byte(s0, 0)) ^ rk[7]; rk += 8; if (--r == 0) { break; } s0 = Td0(byte(t0, 3)) ^ Td1(byte(t3, 2)) ^ Td2(byte(t2, 1)) ^ Td3(byte(t1, 0)) ^ rk[0]; s1 = Td0(byte(t1, 3)) ^ Td1(byte(t0, 2)) ^ Td2(byte(t3, 1)) ^ Td3(byte(t2, 0)) ^ rk[1]; s2 = Td0(byte(t2, 3)) ^ Td1(byte(t1, 2)) ^ Td2(byte(t0, 1)) ^ Td3(byte(t3, 0)) ^ rk[2]; s3 = Td0(byte(t3, 3)) ^ Td1(byte(t2, 2)) ^ Td2(byte(t1, 1)) ^ Td3(byte(t0, 0)) ^ rk[3]; } #endif /* * apply last round and * map cipher state to byte array block: */ s0 = (Td4[byte(t0, 3)] & 0xff000000) ^ (Td4[byte(t3, 2)] & 0x00ff0000) ^ (Td4[byte(t2, 1)] & 0x0000ff00) ^ (Td4[byte(t1, 0)] & 0x000000ff) ^ rk[0]; STORE32H(s0, pt); s1 = (Td4[byte(t1, 3)] & 0xff000000) ^ (Td4[byte(t0, 2)] & 0x00ff0000) ^ (Td4[byte(t3, 1)] & 0x0000ff00) ^ (Td4[byte(t2, 0)] & 0x000000ff) ^ rk[1]; STORE32H(s1, pt+4); s2 = (Td4[byte(t2, 3)] & 0xff000000) ^ (Td4[byte(t1, 2)] & 0x00ff0000) ^ (Td4[byte(t0, 1)] & 0x0000ff00) ^ (Td4[byte(t3, 0)] & 0x000000ff) ^ rk[2]; STORE32H(s2, pt+8); s3 = (Td4[byte(t3, 3)] & 0xff000000) ^ (Td4[byte(t2, 2)] & 0x00ff0000) ^ (Td4[byte(t1, 1)] & 0x0000ff00) ^ (Td4[byte(t0, 0)] & 0x000000ff) ^ rk[3]; STORE32H(s3, pt+12); return CRYPT_OK; } #ifdef LTC_CLEAN_STACK int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) { int err = _rijndael_ecb_decrypt(ct, pt, skey); burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2); return err; } #endif /** Performs a self-test of the AES block cipher @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled */ int ECB_TEST(void) { #ifndef LTC_TEST return CRYPT_NOP; #else int err; static const struct { int keylen; unsigned char key[32], pt[16], ct[16]; } tests[] = { { 16, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a } }, { 24, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 }, { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0, 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 } }, { 32, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }, { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf, 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 } } }; symmetric_key key; unsigned char tmp[2][16]; int i, y; for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { zeromem(&key, sizeof(key)); if ((err = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { return err; } rijndael_ecb_encrypt(tests[i].pt, tmp[0], &key); rijndael_ecb_decrypt(tmp[0], tmp[1], &key); if (XMEMCMP(tmp[0], tests[i].ct, 16) || XMEMCMP(tmp[1], tests[i].pt, 16)) { #if 0 printf("\n\nTest %d failed\n", i); if (XMEMCMP(tmp[0], tests[i].ct, 16)) { printf("CT: "); for (i = 0; i < 16; i++) { printf("%02x ", tmp[0][i]); } printf("\n"); } else { printf("PT: "); for (i = 0; i < 16; i++) { printf("%02x ", tmp[1][i]); } printf("\n"); } #endif return CRYPT_FAIL_TESTVECTOR; } /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ for (y = 0; y < 16; y++) tmp[0][y] = 0; for (y = 0; y < 1000; y++) rijndael_ecb_encrypt(tmp[0], tmp[0], &key); for (y = 0; y < 1000; y++) rijndael_ecb_decrypt(tmp[0], tmp[0], &key); for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; } return CRYPT_OK; #endif } #endif /* ENCRYPT_ONLY */ /** Terminate the context @param skey The scheduled key */ void ECB_DONE(symmetric_key *skey) { } /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. @return CRYPT_OK if the input key size is acceptable. */ int ECB_KS(int *keysize) { LTC_ARGCHK(keysize != NULL); if (*keysize < 16) return CRYPT_INVALID_KEYSIZE; if (*keysize < 24) { *keysize = 16; return CRYPT_OK; } else if (*keysize < 32) { *keysize = 24; return CRYPT_OK; } else { *keysize = 32; return CRYPT_OK; } } #endif /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/aes/aes.c,v $ */ /* $Revision: 1.16 $ */ /* $Date: 2007/05/12 14:13:00 $ */ libtomcrypt-1.17/src/ciphers/aes/aes_tab.c0000644000175100001440000021035610621351501017270 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /* The precomputed tables for AES */ /* Te0[x] = S [x].[02, 01, 01, 03]; Te1[x] = S [x].[03, 02, 01, 01]; Te2[x] = S [x].[01, 03, 02, 01]; Te3[x] = S [x].[01, 01, 03, 02]; Te4[x] = S [x].[01, 01, 01, 01]; Td0[x] = Si[x].[0e, 09, 0d, 0b]; Td1[x] = Si[x].[0b, 0e, 09, 0d]; Td2[x] = Si[x].[0d, 0b, 0e, 09]; Td3[x] = Si[x].[09, 0d, 0b, 0e]; Td4[x] = Si[x].[01, 01, 01, 01]; */ /** @file aes_tab.c AES tables */ static const ulong32 TE0[256] = { 0xc66363a5UL, 0xf87c7c84UL, 0xee777799UL, 0xf67b7b8dUL, 0xfff2f20dUL, 0xd66b6bbdUL, 0xde6f6fb1UL, 0x91c5c554UL, 0x60303050UL, 0x02010103UL, 0xce6767a9UL, 0x562b2b7dUL, 0xe7fefe19UL, 0xb5d7d762UL, 0x4dababe6UL, 0xec76769aUL, 0x8fcaca45UL, 0x1f82829dUL, 0x89c9c940UL, 0xfa7d7d87UL, 0xeffafa15UL, 0xb25959ebUL, 0x8e4747c9UL, 0xfbf0f00bUL, 0x41adadecUL, 0xb3d4d467UL, 0x5fa2a2fdUL, 0x45afafeaUL, 0x239c9cbfUL, 0x53a4a4f7UL, 0xe4727296UL, 0x9bc0c05bUL, 0x75b7b7c2UL, 0xe1fdfd1cUL, 0x3d9393aeUL, 0x4c26266aUL, 0x6c36365aUL, 0x7e3f3f41UL, 0xf5f7f702UL, 0x83cccc4fUL, 0x6834345cUL, 0x51a5a5f4UL, 0xd1e5e534UL, 0xf9f1f108UL, 0xe2717193UL, 0xabd8d873UL, 0x62313153UL, 0x2a15153fUL, 0x0804040cUL, 0x95c7c752UL, 0x46232365UL, 0x9dc3c35eUL, 0x30181828UL, 0x379696a1UL, 0x0a05050fUL, 0x2f9a9ab5UL, 0x0e070709UL, 0x24121236UL, 0x1b80809bUL, 0xdfe2e23dUL, 0xcdebeb26UL, 0x4e272769UL, 0x7fb2b2cdUL, 0xea75759fUL, 0x1209091bUL, 0x1d83839eUL, 0x582c2c74UL, 0x341a1a2eUL, 0x361b1b2dUL, 0xdc6e6eb2UL, 0xb45a5aeeUL, 0x5ba0a0fbUL, 0xa45252f6UL, 0x763b3b4dUL, 0xb7d6d661UL, 0x7db3b3ceUL, 0x5229297bUL, 0xdde3e33eUL, 0x5e2f2f71UL, 0x13848497UL, 0xa65353f5UL, 0xb9d1d168UL, 0x00000000UL, 0xc1eded2cUL, 0x40202060UL, 0xe3fcfc1fUL, 0x79b1b1c8UL, 0xb65b5bedUL, 0xd46a6abeUL, 0x8dcbcb46UL, 0x67bebed9UL, 0x7239394bUL, 0x944a4adeUL, 0x984c4cd4UL, 0xb05858e8UL, 0x85cfcf4aUL, 0xbbd0d06bUL, 0xc5efef2aUL, 0x4faaaae5UL, 0xedfbfb16UL, 0x864343c5UL, 0x9a4d4dd7UL, 0x66333355UL, 0x11858594UL, 0x8a4545cfUL, 0xe9f9f910UL, 0x04020206UL, 0xfe7f7f81UL, 0xa05050f0UL, 0x783c3c44UL, 0x259f9fbaUL, 0x4ba8a8e3UL, 0xa25151f3UL, 0x5da3a3feUL, 0x804040c0UL, 0x058f8f8aUL, 0x3f9292adUL, 0x219d9dbcUL, 0x70383848UL, 0xf1f5f504UL, 0x63bcbcdfUL, 0x77b6b6c1UL, 0xafdada75UL, 0x42212163UL, 0x20101030UL, 0xe5ffff1aUL, 0xfdf3f30eUL, 0xbfd2d26dUL, 0x81cdcd4cUL, 0x180c0c14UL, 0x26131335UL, 0xc3ecec2fUL, 0xbe5f5fe1UL, 0x359797a2UL, 0x884444ccUL, 0x2e171739UL, 0x93c4c457UL, 0x55a7a7f2UL, 0xfc7e7e82UL, 0x7a3d3d47UL, 0xc86464acUL, 0xba5d5de7UL, 0x3219192bUL, 0xe6737395UL, 0xc06060a0UL, 0x19818198UL, 0x9e4f4fd1UL, 0xa3dcdc7fUL, 0x44222266UL, 0x542a2a7eUL, 0x3b9090abUL, 0x0b888883UL, 0x8c4646caUL, 0xc7eeee29UL, 0x6bb8b8d3UL, 0x2814143cUL, 0xa7dede79UL, 0xbc5e5ee2UL, 0x160b0b1dUL, 0xaddbdb76UL, 0xdbe0e03bUL, 0x64323256UL, 0x743a3a4eUL, 0x140a0a1eUL, 0x924949dbUL, 0x0c06060aUL, 0x4824246cUL, 0xb85c5ce4UL, 0x9fc2c25dUL, 0xbdd3d36eUL, 0x43acacefUL, 0xc46262a6UL, 0x399191a8UL, 0x319595a4UL, 0xd3e4e437UL, 0xf279798bUL, 0xd5e7e732UL, 0x8bc8c843UL, 0x6e373759UL, 0xda6d6db7UL, 0x018d8d8cUL, 0xb1d5d564UL, 0x9c4e4ed2UL, 0x49a9a9e0UL, 0xd86c6cb4UL, 0xac5656faUL, 0xf3f4f407UL, 0xcfeaea25UL, 0xca6565afUL, 0xf47a7a8eUL, 0x47aeaee9UL, 0x10080818UL, 0x6fbabad5UL, 0xf0787888UL, 0x4a25256fUL, 0x5c2e2e72UL, 0x381c1c24UL, 0x57a6a6f1UL, 0x73b4b4c7UL, 0x97c6c651UL, 0xcbe8e823UL, 0xa1dddd7cUL, 0xe874749cUL, 0x3e1f1f21UL, 0x964b4bddUL, 0x61bdbddcUL, 0x0d8b8b86UL, 0x0f8a8a85UL, 0xe0707090UL, 0x7c3e3e42UL, 0x71b5b5c4UL, 0xcc6666aaUL, 0x904848d8UL, 0x06030305UL, 0xf7f6f601UL, 0x1c0e0e12UL, 0xc26161a3UL, 0x6a35355fUL, 0xae5757f9UL, 0x69b9b9d0UL, 0x17868691UL, 0x99c1c158UL, 0x3a1d1d27UL, 0x279e9eb9UL, 0xd9e1e138UL, 0xebf8f813UL, 0x2b9898b3UL, 0x22111133UL, 0xd26969bbUL, 0xa9d9d970UL, 0x078e8e89UL, 0x339494a7UL, 0x2d9b9bb6UL, 0x3c1e1e22UL, 0x15878792UL, 0xc9e9e920UL, 0x87cece49UL, 0xaa5555ffUL, 0x50282878UL, 0xa5dfdf7aUL, 0x038c8c8fUL, 0x59a1a1f8UL, 0x09898980UL, 0x1a0d0d17UL, 0x65bfbfdaUL, 0xd7e6e631UL, 0x844242c6UL, 0xd06868b8UL, 0x824141c3UL, 0x299999b0UL, 0x5a2d2d77UL, 0x1e0f0f11UL, 0x7bb0b0cbUL, 0xa85454fcUL, 0x6dbbbbd6UL, 0x2c16163aUL, }; #ifndef PELI_TAB static const ulong32 Te4[256] = { 0x63636363UL, 0x7c7c7c7cUL, 0x77777777UL, 0x7b7b7b7bUL, 0xf2f2f2f2UL, 0x6b6b6b6bUL, 0x6f6f6f6fUL, 0xc5c5c5c5UL, 0x30303030UL, 0x01010101UL, 0x67676767UL, 0x2b2b2b2bUL, 0xfefefefeUL, 0xd7d7d7d7UL, 0xababababUL, 0x76767676UL, 0xcacacacaUL, 0x82828282UL, 0xc9c9c9c9UL, 0x7d7d7d7dUL, 0xfafafafaUL, 0x59595959UL, 0x47474747UL, 0xf0f0f0f0UL, 0xadadadadUL, 0xd4d4d4d4UL, 0xa2a2a2a2UL, 0xafafafafUL, 0x9c9c9c9cUL, 0xa4a4a4a4UL, 0x72727272UL, 0xc0c0c0c0UL, 0xb7b7b7b7UL, 0xfdfdfdfdUL, 0x93939393UL, 0x26262626UL, 0x36363636UL, 0x3f3f3f3fUL, 0xf7f7f7f7UL, 0xccccccccUL, 0x34343434UL, 0xa5a5a5a5UL, 0xe5e5e5e5UL, 0xf1f1f1f1UL, 0x71717171UL, 0xd8d8d8d8UL, 0x31313131UL, 0x15151515UL, 0x04040404UL, 0xc7c7c7c7UL, 0x23232323UL, 0xc3c3c3c3UL, 0x18181818UL, 0x96969696UL, 0x05050505UL, 0x9a9a9a9aUL, 0x07070707UL, 0x12121212UL, 0x80808080UL, 0xe2e2e2e2UL, 0xebebebebUL, 0x27272727UL, 0xb2b2b2b2UL, 0x75757575UL, 0x09090909UL, 0x83838383UL, 0x2c2c2c2cUL, 0x1a1a1a1aUL, 0x1b1b1b1bUL, 0x6e6e6e6eUL, 0x5a5a5a5aUL, 0xa0a0a0a0UL, 0x52525252UL, 0x3b3b3b3bUL, 0xd6d6d6d6UL, 0xb3b3b3b3UL, 0x29292929UL, 0xe3e3e3e3UL, 0x2f2f2f2fUL, 0x84848484UL, 0x53535353UL, 0xd1d1d1d1UL, 0x00000000UL, 0xededededUL, 0x20202020UL, 0xfcfcfcfcUL, 0xb1b1b1b1UL, 0x5b5b5b5bUL, 0x6a6a6a6aUL, 0xcbcbcbcbUL, 0xbebebebeUL, 0x39393939UL, 0x4a4a4a4aUL, 0x4c4c4c4cUL, 0x58585858UL, 0xcfcfcfcfUL, 0xd0d0d0d0UL, 0xefefefefUL, 0xaaaaaaaaUL, 0xfbfbfbfbUL, 0x43434343UL, 0x4d4d4d4dUL, 0x33333333UL, 0x85858585UL, 0x45454545UL, 0xf9f9f9f9UL, 0x02020202UL, 0x7f7f7f7fUL, 0x50505050UL, 0x3c3c3c3cUL, 0x9f9f9f9fUL, 0xa8a8a8a8UL, 0x51515151UL, 0xa3a3a3a3UL, 0x40404040UL, 0x8f8f8f8fUL, 0x92929292UL, 0x9d9d9d9dUL, 0x38383838UL, 0xf5f5f5f5UL, 0xbcbcbcbcUL, 0xb6b6b6b6UL, 0xdadadadaUL, 0x21212121UL, 0x10101010UL, 0xffffffffUL, 0xf3f3f3f3UL, 0xd2d2d2d2UL, 0xcdcdcdcdUL, 0x0c0c0c0cUL, 0x13131313UL, 0xececececUL, 0x5f5f5f5fUL, 0x97979797UL, 0x44444444UL, 0x17171717UL, 0xc4c4c4c4UL, 0xa7a7a7a7UL, 0x7e7e7e7eUL, 0x3d3d3d3dUL, 0x64646464UL, 0x5d5d5d5dUL, 0x19191919UL, 0x73737373UL, 0x60606060UL, 0x81818181UL, 0x4f4f4f4fUL, 0xdcdcdcdcUL, 0x22222222UL, 0x2a2a2a2aUL, 0x90909090UL, 0x88888888UL, 0x46464646UL, 0xeeeeeeeeUL, 0xb8b8b8b8UL, 0x14141414UL, 0xdedededeUL, 0x5e5e5e5eUL, 0x0b0b0b0bUL, 0xdbdbdbdbUL, 0xe0e0e0e0UL, 0x32323232UL, 0x3a3a3a3aUL, 0x0a0a0a0aUL, 0x49494949UL, 0x06060606UL, 0x24242424UL, 0x5c5c5c5cUL, 0xc2c2c2c2UL, 0xd3d3d3d3UL, 0xacacacacUL, 0x62626262UL, 0x91919191UL, 0x95959595UL, 0xe4e4e4e4UL, 0x79797979UL, 0xe7e7e7e7UL, 0xc8c8c8c8UL, 0x37373737UL, 0x6d6d6d6dUL, 0x8d8d8d8dUL, 0xd5d5d5d5UL, 0x4e4e4e4eUL, 0xa9a9a9a9UL, 0x6c6c6c6cUL, 0x56565656UL, 0xf4f4f4f4UL, 0xeaeaeaeaUL, 0x65656565UL, 0x7a7a7a7aUL, 0xaeaeaeaeUL, 0x08080808UL, 0xbabababaUL, 0x78787878UL, 0x25252525UL, 0x2e2e2e2eUL, 0x1c1c1c1cUL, 0xa6a6a6a6UL, 0xb4b4b4b4UL, 0xc6c6c6c6UL, 0xe8e8e8e8UL, 0xddddddddUL, 0x74747474UL, 0x1f1f1f1fUL, 0x4b4b4b4bUL, 0xbdbdbdbdUL, 0x8b8b8b8bUL, 0x8a8a8a8aUL, 0x70707070UL, 0x3e3e3e3eUL, 0xb5b5b5b5UL, 0x66666666UL, 0x48484848UL, 0x03030303UL, 0xf6f6f6f6UL, 0x0e0e0e0eUL, 0x61616161UL, 0x35353535UL, 0x57575757UL, 0xb9b9b9b9UL, 0x86868686UL, 0xc1c1c1c1UL, 0x1d1d1d1dUL, 0x9e9e9e9eUL, 0xe1e1e1e1UL, 0xf8f8f8f8UL, 0x98989898UL, 0x11111111UL, 0x69696969UL, 0xd9d9d9d9UL, 0x8e8e8e8eUL, 0x94949494UL, 0x9b9b9b9bUL, 0x1e1e1e1eUL, 0x87878787UL, 0xe9e9e9e9UL, 0xcecececeUL, 0x55555555UL, 0x28282828UL, 0xdfdfdfdfUL, 0x8c8c8c8cUL, 0xa1a1a1a1UL, 0x89898989UL, 0x0d0d0d0dUL, 0xbfbfbfbfUL, 0xe6e6e6e6UL, 0x42424242UL, 0x68686868UL, 0x41414141UL, 0x99999999UL, 0x2d2d2d2dUL, 0x0f0f0f0fUL, 0xb0b0b0b0UL, 0x54545454UL, 0xbbbbbbbbUL, 0x16161616UL, }; #endif #ifndef ENCRYPT_ONLY static const ulong32 TD0[256] = { 0x51f4a750UL, 0x7e416553UL, 0x1a17a4c3UL, 0x3a275e96UL, 0x3bab6bcbUL, 0x1f9d45f1UL, 0xacfa58abUL, 0x4be30393UL, 0x2030fa55UL, 0xad766df6UL, 0x88cc7691UL, 0xf5024c25UL, 0x4fe5d7fcUL, 0xc52acbd7UL, 0x26354480UL, 0xb562a38fUL, 0xdeb15a49UL, 0x25ba1b67UL, 0x45ea0e98UL, 0x5dfec0e1UL, 0xc32f7502UL, 0x814cf012UL, 0x8d4697a3UL, 0x6bd3f9c6UL, 0x038f5fe7UL, 0x15929c95UL, 0xbf6d7aebUL, 0x955259daUL, 0xd4be832dUL, 0x587421d3UL, 0x49e06929UL, 0x8ec9c844UL, 0x75c2896aUL, 0xf48e7978UL, 0x99583e6bUL, 0x27b971ddUL, 0xbee14fb6UL, 0xf088ad17UL, 0xc920ac66UL, 0x7dce3ab4UL, 0x63df4a18UL, 0xe51a3182UL, 0x97513360UL, 0x62537f45UL, 0xb16477e0UL, 0xbb6bae84UL, 0xfe81a01cUL, 0xf9082b94UL, 0x70486858UL, 0x8f45fd19UL, 0x94de6c87UL, 0x527bf8b7UL, 0xab73d323UL, 0x724b02e2UL, 0xe31f8f57UL, 0x6655ab2aUL, 0xb2eb2807UL, 0x2fb5c203UL, 0x86c57b9aUL, 0xd33708a5UL, 0x302887f2UL, 0x23bfa5b2UL, 0x02036abaUL, 0xed16825cUL, 0x8acf1c2bUL, 0xa779b492UL, 0xf307f2f0UL, 0x4e69e2a1UL, 0x65daf4cdUL, 0x0605bed5UL, 0xd134621fUL, 0xc4a6fe8aUL, 0x342e539dUL, 0xa2f355a0UL, 0x058ae132UL, 0xa4f6eb75UL, 0x0b83ec39UL, 0x4060efaaUL, 0x5e719f06UL, 0xbd6e1051UL, 0x3e218af9UL, 0x96dd063dUL, 0xdd3e05aeUL, 0x4de6bd46UL, 0x91548db5UL, 0x71c45d05UL, 0x0406d46fUL, 0x605015ffUL, 0x1998fb24UL, 0xd6bde997UL, 0x894043ccUL, 0x67d99e77UL, 0xb0e842bdUL, 0x07898b88UL, 0xe7195b38UL, 0x79c8eedbUL, 0xa17c0a47UL, 0x7c420fe9UL, 0xf8841ec9UL, 0x00000000UL, 0x09808683UL, 0x322bed48UL, 0x1e1170acUL, 0x6c5a724eUL, 0xfd0efffbUL, 0x0f853856UL, 0x3daed51eUL, 0x362d3927UL, 0x0a0fd964UL, 0x685ca621UL, 0x9b5b54d1UL, 0x24362e3aUL, 0x0c0a67b1UL, 0x9357e70fUL, 0xb4ee96d2UL, 0x1b9b919eUL, 0x80c0c54fUL, 0x61dc20a2UL, 0x5a774b69UL, 0x1c121a16UL, 0xe293ba0aUL, 0xc0a02ae5UL, 0x3c22e043UL, 0x121b171dUL, 0x0e090d0bUL, 0xf28bc7adUL, 0x2db6a8b9UL, 0x141ea9c8UL, 0x57f11985UL, 0xaf75074cUL, 0xee99ddbbUL, 0xa37f60fdUL, 0xf701269fUL, 0x5c72f5bcUL, 0x44663bc5UL, 0x5bfb7e34UL, 0x8b432976UL, 0xcb23c6dcUL, 0xb6edfc68UL, 0xb8e4f163UL, 0xd731dccaUL, 0x42638510UL, 0x13972240UL, 0x84c61120UL, 0x854a247dUL, 0xd2bb3df8UL, 0xaef93211UL, 0xc729a16dUL, 0x1d9e2f4bUL, 0xdcb230f3UL, 0x0d8652ecUL, 0x77c1e3d0UL, 0x2bb3166cUL, 0xa970b999UL, 0x119448faUL, 0x47e96422UL, 0xa8fc8cc4UL, 0xa0f03f1aUL, 0x567d2cd8UL, 0x223390efUL, 0x87494ec7UL, 0xd938d1c1UL, 0x8ccaa2feUL, 0x98d40b36UL, 0xa6f581cfUL, 0xa57ade28UL, 0xdab78e26UL, 0x3fadbfa4UL, 0x2c3a9de4UL, 0x5078920dUL, 0x6a5fcc9bUL, 0x547e4662UL, 0xf68d13c2UL, 0x90d8b8e8UL, 0x2e39f75eUL, 0x82c3aff5UL, 0x9f5d80beUL, 0x69d0937cUL, 0x6fd52da9UL, 0xcf2512b3UL, 0xc8ac993bUL, 0x10187da7UL, 0xe89c636eUL, 0xdb3bbb7bUL, 0xcd267809UL, 0x6e5918f4UL, 0xec9ab701UL, 0x834f9aa8UL, 0xe6956e65UL, 0xaaffe67eUL, 0x21bccf08UL, 0xef15e8e6UL, 0xbae79bd9UL, 0x4a6f36ceUL, 0xea9f09d4UL, 0x29b07cd6UL, 0x31a4b2afUL, 0x2a3f2331UL, 0xc6a59430UL, 0x35a266c0UL, 0x744ebc37UL, 0xfc82caa6UL, 0xe090d0b0UL, 0x33a7d815UL, 0xf104984aUL, 0x41ecdaf7UL, 0x7fcd500eUL, 0x1791f62fUL, 0x764dd68dUL, 0x43efb04dUL, 0xccaa4d54UL, 0xe49604dfUL, 0x9ed1b5e3UL, 0x4c6a881bUL, 0xc12c1fb8UL, 0x4665517fUL, 0x9d5eea04UL, 0x018c355dUL, 0xfa877473UL, 0xfb0b412eUL, 0xb3671d5aUL, 0x92dbd252UL, 0xe9105633UL, 0x6dd64713UL, 0x9ad7618cUL, 0x37a10c7aUL, 0x59f8148eUL, 0xeb133c89UL, 0xcea927eeUL, 0xb761c935UL, 0xe11ce5edUL, 0x7a47b13cUL, 0x9cd2df59UL, 0x55f2733fUL, 0x1814ce79UL, 0x73c737bfUL, 0x53f7cdeaUL, 0x5ffdaa5bUL, 0xdf3d6f14UL, 0x7844db86UL, 0xcaaff381UL, 0xb968c43eUL, 0x3824342cUL, 0xc2a3405fUL, 0x161dc372UL, 0xbce2250cUL, 0x283c498bUL, 0xff0d9541UL, 0x39a80171UL, 0x080cb3deUL, 0xd8b4e49cUL, 0x6456c190UL, 0x7bcb8461UL, 0xd532b670UL, 0x486c5c74UL, 0xd0b85742UL, }; static const ulong32 Td4[256] = { 0x52525252UL, 0x09090909UL, 0x6a6a6a6aUL, 0xd5d5d5d5UL, 0x30303030UL, 0x36363636UL, 0xa5a5a5a5UL, 0x38383838UL, 0xbfbfbfbfUL, 0x40404040UL, 0xa3a3a3a3UL, 0x9e9e9e9eUL, 0x81818181UL, 0xf3f3f3f3UL, 0xd7d7d7d7UL, 0xfbfbfbfbUL, 0x7c7c7c7cUL, 0xe3e3e3e3UL, 0x39393939UL, 0x82828282UL, 0x9b9b9b9bUL, 0x2f2f2f2fUL, 0xffffffffUL, 0x87878787UL, 0x34343434UL, 0x8e8e8e8eUL, 0x43434343UL, 0x44444444UL, 0xc4c4c4c4UL, 0xdedededeUL, 0xe9e9e9e9UL, 0xcbcbcbcbUL, 0x54545454UL, 0x7b7b7b7bUL, 0x94949494UL, 0x32323232UL, 0xa6a6a6a6UL, 0xc2c2c2c2UL, 0x23232323UL, 0x3d3d3d3dUL, 0xeeeeeeeeUL, 0x4c4c4c4cUL, 0x95959595UL, 0x0b0b0b0bUL, 0x42424242UL, 0xfafafafaUL, 0xc3c3c3c3UL, 0x4e4e4e4eUL, 0x08080808UL, 0x2e2e2e2eUL, 0xa1a1a1a1UL, 0x66666666UL, 0x28282828UL, 0xd9d9d9d9UL, 0x24242424UL, 0xb2b2b2b2UL, 0x76767676UL, 0x5b5b5b5bUL, 0xa2a2a2a2UL, 0x49494949UL, 0x6d6d6d6dUL, 0x8b8b8b8bUL, 0xd1d1d1d1UL, 0x25252525UL, 0x72727272UL, 0xf8f8f8f8UL, 0xf6f6f6f6UL, 0x64646464UL, 0x86868686UL, 0x68686868UL, 0x98989898UL, 0x16161616UL, 0xd4d4d4d4UL, 0xa4a4a4a4UL, 0x5c5c5c5cUL, 0xccccccccUL, 0x5d5d5d5dUL, 0x65656565UL, 0xb6b6b6b6UL, 0x92929292UL, 0x6c6c6c6cUL, 0x70707070UL, 0x48484848UL, 0x50505050UL, 0xfdfdfdfdUL, 0xededededUL, 0xb9b9b9b9UL, 0xdadadadaUL, 0x5e5e5e5eUL, 0x15151515UL, 0x46464646UL, 0x57575757UL, 0xa7a7a7a7UL, 0x8d8d8d8dUL, 0x9d9d9d9dUL, 0x84848484UL, 0x90909090UL, 0xd8d8d8d8UL, 0xababababUL, 0x00000000UL, 0x8c8c8c8cUL, 0xbcbcbcbcUL, 0xd3d3d3d3UL, 0x0a0a0a0aUL, 0xf7f7f7f7UL, 0xe4e4e4e4UL, 0x58585858UL, 0x05050505UL, 0xb8b8b8b8UL, 0xb3b3b3b3UL, 0x45454545UL, 0x06060606UL, 0xd0d0d0d0UL, 0x2c2c2c2cUL, 0x1e1e1e1eUL, 0x8f8f8f8fUL, 0xcacacacaUL, 0x3f3f3f3fUL, 0x0f0f0f0fUL, 0x02020202UL, 0xc1c1c1c1UL, 0xafafafafUL, 0xbdbdbdbdUL, 0x03030303UL, 0x01010101UL, 0x13131313UL, 0x8a8a8a8aUL, 0x6b6b6b6bUL, 0x3a3a3a3aUL, 0x91919191UL, 0x11111111UL, 0x41414141UL, 0x4f4f4f4fUL, 0x67676767UL, 0xdcdcdcdcUL, 0xeaeaeaeaUL, 0x97979797UL, 0xf2f2f2f2UL, 0xcfcfcfcfUL, 0xcecececeUL, 0xf0f0f0f0UL, 0xb4b4b4b4UL, 0xe6e6e6e6UL, 0x73737373UL, 0x96969696UL, 0xacacacacUL, 0x74747474UL, 0x22222222UL, 0xe7e7e7e7UL, 0xadadadadUL, 0x35353535UL, 0x85858585UL, 0xe2e2e2e2UL, 0xf9f9f9f9UL, 0x37373737UL, 0xe8e8e8e8UL, 0x1c1c1c1cUL, 0x75757575UL, 0xdfdfdfdfUL, 0x6e6e6e6eUL, 0x47474747UL, 0xf1f1f1f1UL, 0x1a1a1a1aUL, 0x71717171UL, 0x1d1d1d1dUL, 0x29292929UL, 0xc5c5c5c5UL, 0x89898989UL, 0x6f6f6f6fUL, 0xb7b7b7b7UL, 0x62626262UL, 0x0e0e0e0eUL, 0xaaaaaaaaUL, 0x18181818UL, 0xbebebebeUL, 0x1b1b1b1bUL, 0xfcfcfcfcUL, 0x56565656UL, 0x3e3e3e3eUL, 0x4b4b4b4bUL, 0xc6c6c6c6UL, 0xd2d2d2d2UL, 0x79797979UL, 0x20202020UL, 0x9a9a9a9aUL, 0xdbdbdbdbUL, 0xc0c0c0c0UL, 0xfefefefeUL, 0x78787878UL, 0xcdcdcdcdUL, 0x5a5a5a5aUL, 0xf4f4f4f4UL, 0x1f1f1f1fUL, 0xddddddddUL, 0xa8a8a8a8UL, 0x33333333UL, 0x88888888UL, 0x07070707UL, 0xc7c7c7c7UL, 0x31313131UL, 0xb1b1b1b1UL, 0x12121212UL, 0x10101010UL, 0x59595959UL, 0x27272727UL, 0x80808080UL, 0xececececUL, 0x5f5f5f5fUL, 0x60606060UL, 0x51515151UL, 0x7f7f7f7fUL, 0xa9a9a9a9UL, 0x19191919UL, 0xb5b5b5b5UL, 0x4a4a4a4aUL, 0x0d0d0d0dUL, 0x2d2d2d2dUL, 0xe5e5e5e5UL, 0x7a7a7a7aUL, 0x9f9f9f9fUL, 0x93939393UL, 0xc9c9c9c9UL, 0x9c9c9c9cUL, 0xefefefefUL, 0xa0a0a0a0UL, 0xe0e0e0e0UL, 0x3b3b3b3bUL, 0x4d4d4d4dUL, 0xaeaeaeaeUL, 0x2a2a2a2aUL, 0xf5f5f5f5UL, 0xb0b0b0b0UL, 0xc8c8c8c8UL, 0xebebebebUL, 0xbbbbbbbbUL, 0x3c3c3c3cUL, 0x83838383UL, 0x53535353UL, 0x99999999UL, 0x61616161UL, 0x17171717UL, 0x2b2b2b2bUL, 0x04040404UL, 0x7e7e7e7eUL, 0xbabababaUL, 0x77777777UL, 0xd6d6d6d6UL, 0x26262626UL, 0xe1e1e1e1UL, 0x69696969UL, 0x14141414UL, 0x63636363UL, 0x55555555UL, 0x21212121UL, 0x0c0c0c0cUL, 0x7d7d7d7dUL, }; #endif /* ENCRYPT_ONLY */ #ifdef LTC_SMALL_CODE #define Te0(x) TE0[x] #define Te1(x) RORc(TE0[x], 8) #define Te2(x) RORc(TE0[x], 16) #define Te3(x) RORc(TE0[x], 24) #define Td0(x) TD0[x] #define Td1(x) RORc(TD0[x], 8) #define Td2(x) RORc(TD0[x], 16) #define Td3(x) RORc(TD0[x], 24) #define Te4_0 0x000000FF & Te4 #define Te4_1 0x0000FF00 & Te4 #define Te4_2 0x00FF0000 & Te4 #define Te4_3 0xFF000000 & Te4 #else #define Te0(x) TE0[x] #define Te1(x) TE1[x] #define Te2(x) TE2[x] #define Te3(x) TE3[x] #define Td0(x) TD0[x] #define Td1(x) TD1[x] #define Td2(x) TD2[x] #define Td3(x) TD3[x] static const ulong32 TE1[256] = { 0xa5c66363UL, 0x84f87c7cUL, 0x99ee7777UL, 0x8df67b7bUL, 0x0dfff2f2UL, 0xbdd66b6bUL, 0xb1de6f6fUL, 0x5491c5c5UL, 0x50603030UL, 0x03020101UL, 0xa9ce6767UL, 0x7d562b2bUL, 0x19e7fefeUL, 0x62b5d7d7UL, 0xe64dababUL, 0x9aec7676UL, 0x458fcacaUL, 0x9d1f8282UL, 0x4089c9c9UL, 0x87fa7d7dUL, 0x15effafaUL, 0xebb25959UL, 0xc98e4747UL, 0x0bfbf0f0UL, 0xec41adadUL, 0x67b3d4d4UL, 0xfd5fa2a2UL, 0xea45afafUL, 0xbf239c9cUL, 0xf753a4a4UL, 0x96e47272UL, 0x5b9bc0c0UL, 0xc275b7b7UL, 0x1ce1fdfdUL, 0xae3d9393UL, 0x6a4c2626UL, 0x5a6c3636UL, 0x417e3f3fUL, 0x02f5f7f7UL, 0x4f83ccccUL, 0x5c683434UL, 0xf451a5a5UL, 0x34d1e5e5UL, 0x08f9f1f1UL, 0x93e27171UL, 0x73abd8d8UL, 0x53623131UL, 0x3f2a1515UL, 0x0c080404UL, 0x5295c7c7UL, 0x65462323UL, 0x5e9dc3c3UL, 0x28301818UL, 0xa1379696UL, 0x0f0a0505UL, 0xb52f9a9aUL, 0x090e0707UL, 0x36241212UL, 0x9b1b8080UL, 0x3ddfe2e2UL, 0x26cdebebUL, 0x694e2727UL, 0xcd7fb2b2UL, 0x9fea7575UL, 0x1b120909UL, 0x9e1d8383UL, 0x74582c2cUL, 0x2e341a1aUL, 0x2d361b1bUL, 0xb2dc6e6eUL, 0xeeb45a5aUL, 0xfb5ba0a0UL, 0xf6a45252UL, 0x4d763b3bUL, 0x61b7d6d6UL, 0xce7db3b3UL, 0x7b522929UL, 0x3edde3e3UL, 0x715e2f2fUL, 0x97138484UL, 0xf5a65353UL, 0x68b9d1d1UL, 0x00000000UL, 0x2cc1ededUL, 0x60402020UL, 0x1fe3fcfcUL, 0xc879b1b1UL, 0xedb65b5bUL, 0xbed46a6aUL, 0x468dcbcbUL, 0xd967bebeUL, 0x4b723939UL, 0xde944a4aUL, 0xd4984c4cUL, 0xe8b05858UL, 0x4a85cfcfUL, 0x6bbbd0d0UL, 0x2ac5efefUL, 0xe54faaaaUL, 0x16edfbfbUL, 0xc5864343UL, 0xd79a4d4dUL, 0x55663333UL, 0x94118585UL, 0xcf8a4545UL, 0x10e9f9f9UL, 0x06040202UL, 0x81fe7f7fUL, 0xf0a05050UL, 0x44783c3cUL, 0xba259f9fUL, 0xe34ba8a8UL, 0xf3a25151UL, 0xfe5da3a3UL, 0xc0804040UL, 0x8a058f8fUL, 0xad3f9292UL, 0xbc219d9dUL, 0x48703838UL, 0x04f1f5f5UL, 0xdf63bcbcUL, 0xc177b6b6UL, 0x75afdadaUL, 0x63422121UL, 0x30201010UL, 0x1ae5ffffUL, 0x0efdf3f3UL, 0x6dbfd2d2UL, 0x4c81cdcdUL, 0x14180c0cUL, 0x35261313UL, 0x2fc3ececUL, 0xe1be5f5fUL, 0xa2359797UL, 0xcc884444UL, 0x392e1717UL, 0x5793c4c4UL, 0xf255a7a7UL, 0x82fc7e7eUL, 0x477a3d3dUL, 0xacc86464UL, 0xe7ba5d5dUL, 0x2b321919UL, 0x95e67373UL, 0xa0c06060UL, 0x98198181UL, 0xd19e4f4fUL, 0x7fa3dcdcUL, 0x66442222UL, 0x7e542a2aUL, 0xab3b9090UL, 0x830b8888UL, 0xca8c4646UL, 0x29c7eeeeUL, 0xd36bb8b8UL, 0x3c281414UL, 0x79a7dedeUL, 0xe2bc5e5eUL, 0x1d160b0bUL, 0x76addbdbUL, 0x3bdbe0e0UL, 0x56643232UL, 0x4e743a3aUL, 0x1e140a0aUL, 0xdb924949UL, 0x0a0c0606UL, 0x6c482424UL, 0xe4b85c5cUL, 0x5d9fc2c2UL, 0x6ebdd3d3UL, 0xef43acacUL, 0xa6c46262UL, 0xa8399191UL, 0xa4319595UL, 0x37d3e4e4UL, 0x8bf27979UL, 0x32d5e7e7UL, 0x438bc8c8UL, 0x596e3737UL, 0xb7da6d6dUL, 0x8c018d8dUL, 0x64b1d5d5UL, 0xd29c4e4eUL, 0xe049a9a9UL, 0xb4d86c6cUL, 0xfaac5656UL, 0x07f3f4f4UL, 0x25cfeaeaUL, 0xafca6565UL, 0x8ef47a7aUL, 0xe947aeaeUL, 0x18100808UL, 0xd56fbabaUL, 0x88f07878UL, 0x6f4a2525UL, 0x725c2e2eUL, 0x24381c1cUL, 0xf157a6a6UL, 0xc773b4b4UL, 0x5197c6c6UL, 0x23cbe8e8UL, 0x7ca1ddddUL, 0x9ce87474UL, 0x213e1f1fUL, 0xdd964b4bUL, 0xdc61bdbdUL, 0x860d8b8bUL, 0x850f8a8aUL, 0x90e07070UL, 0x427c3e3eUL, 0xc471b5b5UL, 0xaacc6666UL, 0xd8904848UL, 0x05060303UL, 0x01f7f6f6UL, 0x121c0e0eUL, 0xa3c26161UL, 0x5f6a3535UL, 0xf9ae5757UL, 0xd069b9b9UL, 0x91178686UL, 0x5899c1c1UL, 0x273a1d1dUL, 0xb9279e9eUL, 0x38d9e1e1UL, 0x13ebf8f8UL, 0xb32b9898UL, 0x33221111UL, 0xbbd26969UL, 0x70a9d9d9UL, 0x89078e8eUL, 0xa7339494UL, 0xb62d9b9bUL, 0x223c1e1eUL, 0x92158787UL, 0x20c9e9e9UL, 0x4987ceceUL, 0xffaa5555UL, 0x78502828UL, 0x7aa5dfdfUL, 0x8f038c8cUL, 0xf859a1a1UL, 0x80098989UL, 0x171a0d0dUL, 0xda65bfbfUL, 0x31d7e6e6UL, 0xc6844242UL, 0xb8d06868UL, 0xc3824141UL, 0xb0299999UL, 0x775a2d2dUL, 0x111e0f0fUL, 0xcb7bb0b0UL, 0xfca85454UL, 0xd66dbbbbUL, 0x3a2c1616UL, }; static const ulong32 TE2[256] = { 0x63a5c663UL, 0x7c84f87cUL, 0x7799ee77UL, 0x7b8df67bUL, 0xf20dfff2UL, 0x6bbdd66bUL, 0x6fb1de6fUL, 0xc55491c5UL, 0x30506030UL, 0x01030201UL, 0x67a9ce67UL, 0x2b7d562bUL, 0xfe19e7feUL, 0xd762b5d7UL, 0xabe64dabUL, 0x769aec76UL, 0xca458fcaUL, 0x829d1f82UL, 0xc94089c9UL, 0x7d87fa7dUL, 0xfa15effaUL, 0x59ebb259UL, 0x47c98e47UL, 0xf00bfbf0UL, 0xadec41adUL, 0xd467b3d4UL, 0xa2fd5fa2UL, 0xafea45afUL, 0x9cbf239cUL, 0xa4f753a4UL, 0x7296e472UL, 0xc05b9bc0UL, 0xb7c275b7UL, 0xfd1ce1fdUL, 0x93ae3d93UL, 0x266a4c26UL, 0x365a6c36UL, 0x3f417e3fUL, 0xf702f5f7UL, 0xcc4f83ccUL, 0x345c6834UL, 0xa5f451a5UL, 0xe534d1e5UL, 0xf108f9f1UL, 0x7193e271UL, 0xd873abd8UL, 0x31536231UL, 0x153f2a15UL, 0x040c0804UL, 0xc75295c7UL, 0x23654623UL, 0xc35e9dc3UL, 0x18283018UL, 0x96a13796UL, 0x050f0a05UL, 0x9ab52f9aUL, 0x07090e07UL, 0x12362412UL, 0x809b1b80UL, 0xe23ddfe2UL, 0xeb26cdebUL, 0x27694e27UL, 0xb2cd7fb2UL, 0x759fea75UL, 0x091b1209UL, 0x839e1d83UL, 0x2c74582cUL, 0x1a2e341aUL, 0x1b2d361bUL, 0x6eb2dc6eUL, 0x5aeeb45aUL, 0xa0fb5ba0UL, 0x52f6a452UL, 0x3b4d763bUL, 0xd661b7d6UL, 0xb3ce7db3UL, 0x297b5229UL, 0xe33edde3UL, 0x2f715e2fUL, 0x84971384UL, 0x53f5a653UL, 0xd168b9d1UL, 0x00000000UL, 0xed2cc1edUL, 0x20604020UL, 0xfc1fe3fcUL, 0xb1c879b1UL, 0x5bedb65bUL, 0x6abed46aUL, 0xcb468dcbUL, 0xbed967beUL, 0x394b7239UL, 0x4ade944aUL, 0x4cd4984cUL, 0x58e8b058UL, 0xcf4a85cfUL, 0xd06bbbd0UL, 0xef2ac5efUL, 0xaae54faaUL, 0xfb16edfbUL, 0x43c58643UL, 0x4dd79a4dUL, 0x33556633UL, 0x85941185UL, 0x45cf8a45UL, 0xf910e9f9UL, 0x02060402UL, 0x7f81fe7fUL, 0x50f0a050UL, 0x3c44783cUL, 0x9fba259fUL, 0xa8e34ba8UL, 0x51f3a251UL, 0xa3fe5da3UL, 0x40c08040UL, 0x8f8a058fUL, 0x92ad3f92UL, 0x9dbc219dUL, 0x38487038UL, 0xf504f1f5UL, 0xbcdf63bcUL, 0xb6c177b6UL, 0xda75afdaUL, 0x21634221UL, 0x10302010UL, 0xff1ae5ffUL, 0xf30efdf3UL, 0xd26dbfd2UL, 0xcd4c81cdUL, 0x0c14180cUL, 0x13352613UL, 0xec2fc3ecUL, 0x5fe1be5fUL, 0x97a23597UL, 0x44cc8844UL, 0x17392e17UL, 0xc45793c4UL, 0xa7f255a7UL, 0x7e82fc7eUL, 0x3d477a3dUL, 0x64acc864UL, 0x5de7ba5dUL, 0x192b3219UL, 0x7395e673UL, 0x60a0c060UL, 0x81981981UL, 0x4fd19e4fUL, 0xdc7fa3dcUL, 0x22664422UL, 0x2a7e542aUL, 0x90ab3b90UL, 0x88830b88UL, 0x46ca8c46UL, 0xee29c7eeUL, 0xb8d36bb8UL, 0x143c2814UL, 0xde79a7deUL, 0x5ee2bc5eUL, 0x0b1d160bUL, 0xdb76addbUL, 0xe03bdbe0UL, 0x32566432UL, 0x3a4e743aUL, 0x0a1e140aUL, 0x49db9249UL, 0x060a0c06UL, 0x246c4824UL, 0x5ce4b85cUL, 0xc25d9fc2UL, 0xd36ebdd3UL, 0xacef43acUL, 0x62a6c462UL, 0x91a83991UL, 0x95a43195UL, 0xe437d3e4UL, 0x798bf279UL, 0xe732d5e7UL, 0xc8438bc8UL, 0x37596e37UL, 0x6db7da6dUL, 0x8d8c018dUL, 0xd564b1d5UL, 0x4ed29c4eUL, 0xa9e049a9UL, 0x6cb4d86cUL, 0x56faac56UL, 0xf407f3f4UL, 0xea25cfeaUL, 0x65afca65UL, 0x7a8ef47aUL, 0xaee947aeUL, 0x08181008UL, 0xbad56fbaUL, 0x7888f078UL, 0x256f4a25UL, 0x2e725c2eUL, 0x1c24381cUL, 0xa6f157a6UL, 0xb4c773b4UL, 0xc65197c6UL, 0xe823cbe8UL, 0xdd7ca1ddUL, 0x749ce874UL, 0x1f213e1fUL, 0x4bdd964bUL, 0xbddc61bdUL, 0x8b860d8bUL, 0x8a850f8aUL, 0x7090e070UL, 0x3e427c3eUL, 0xb5c471b5UL, 0x66aacc66UL, 0x48d89048UL, 0x03050603UL, 0xf601f7f6UL, 0x0e121c0eUL, 0x61a3c261UL, 0x355f6a35UL, 0x57f9ae57UL, 0xb9d069b9UL, 0x86911786UL, 0xc15899c1UL, 0x1d273a1dUL, 0x9eb9279eUL, 0xe138d9e1UL, 0xf813ebf8UL, 0x98b32b98UL, 0x11332211UL, 0x69bbd269UL, 0xd970a9d9UL, 0x8e89078eUL, 0x94a73394UL, 0x9bb62d9bUL, 0x1e223c1eUL, 0x87921587UL, 0xe920c9e9UL, 0xce4987ceUL, 0x55ffaa55UL, 0x28785028UL, 0xdf7aa5dfUL, 0x8c8f038cUL, 0xa1f859a1UL, 0x89800989UL, 0x0d171a0dUL, 0xbfda65bfUL, 0xe631d7e6UL, 0x42c68442UL, 0x68b8d068UL, 0x41c38241UL, 0x99b02999UL, 0x2d775a2dUL, 0x0f111e0fUL, 0xb0cb7bb0UL, 0x54fca854UL, 0xbbd66dbbUL, 0x163a2c16UL, }; static const ulong32 TE3[256] = { 0x6363a5c6UL, 0x7c7c84f8UL, 0x777799eeUL, 0x7b7b8df6UL, 0xf2f20dffUL, 0x6b6bbdd6UL, 0x6f6fb1deUL, 0xc5c55491UL, 0x30305060UL, 0x01010302UL, 0x6767a9ceUL, 0x2b2b7d56UL, 0xfefe19e7UL, 0xd7d762b5UL, 0xababe64dUL, 0x76769aecUL, 0xcaca458fUL, 0x82829d1fUL, 0xc9c94089UL, 0x7d7d87faUL, 0xfafa15efUL, 0x5959ebb2UL, 0x4747c98eUL, 0xf0f00bfbUL, 0xadadec41UL, 0xd4d467b3UL, 0xa2a2fd5fUL, 0xafafea45UL, 0x9c9cbf23UL, 0xa4a4f753UL, 0x727296e4UL, 0xc0c05b9bUL, 0xb7b7c275UL, 0xfdfd1ce1UL, 0x9393ae3dUL, 0x26266a4cUL, 0x36365a6cUL, 0x3f3f417eUL, 0xf7f702f5UL, 0xcccc4f83UL, 0x34345c68UL, 0xa5a5f451UL, 0xe5e534d1UL, 0xf1f108f9UL, 0x717193e2UL, 0xd8d873abUL, 0x31315362UL, 0x15153f2aUL, 0x04040c08UL, 0xc7c75295UL, 0x23236546UL, 0xc3c35e9dUL, 0x18182830UL, 0x9696a137UL, 0x05050f0aUL, 0x9a9ab52fUL, 0x0707090eUL, 0x12123624UL, 0x80809b1bUL, 0xe2e23ddfUL, 0xebeb26cdUL, 0x2727694eUL, 0xb2b2cd7fUL, 0x75759feaUL, 0x09091b12UL, 0x83839e1dUL, 0x2c2c7458UL, 0x1a1a2e34UL, 0x1b1b2d36UL, 0x6e6eb2dcUL, 0x5a5aeeb4UL, 0xa0a0fb5bUL, 0x5252f6a4UL, 0x3b3b4d76UL, 0xd6d661b7UL, 0xb3b3ce7dUL, 0x29297b52UL, 0xe3e33eddUL, 0x2f2f715eUL, 0x84849713UL, 0x5353f5a6UL, 0xd1d168b9UL, 0x00000000UL, 0xeded2cc1UL, 0x20206040UL, 0xfcfc1fe3UL, 0xb1b1c879UL, 0x5b5bedb6UL, 0x6a6abed4UL, 0xcbcb468dUL, 0xbebed967UL, 0x39394b72UL, 0x4a4ade94UL, 0x4c4cd498UL, 0x5858e8b0UL, 0xcfcf4a85UL, 0xd0d06bbbUL, 0xefef2ac5UL, 0xaaaae54fUL, 0xfbfb16edUL, 0x4343c586UL, 0x4d4dd79aUL, 0x33335566UL, 0x85859411UL, 0x4545cf8aUL, 0xf9f910e9UL, 0x02020604UL, 0x7f7f81feUL, 0x5050f0a0UL, 0x3c3c4478UL, 0x9f9fba25UL, 0xa8a8e34bUL, 0x5151f3a2UL, 0xa3a3fe5dUL, 0x4040c080UL, 0x8f8f8a05UL, 0x9292ad3fUL, 0x9d9dbc21UL, 0x38384870UL, 0xf5f504f1UL, 0xbcbcdf63UL, 0xb6b6c177UL, 0xdada75afUL, 0x21216342UL, 0x10103020UL, 0xffff1ae5UL, 0xf3f30efdUL, 0xd2d26dbfUL, 0xcdcd4c81UL, 0x0c0c1418UL, 0x13133526UL, 0xecec2fc3UL, 0x5f5fe1beUL, 0x9797a235UL, 0x4444cc88UL, 0x1717392eUL, 0xc4c45793UL, 0xa7a7f255UL, 0x7e7e82fcUL, 0x3d3d477aUL, 0x6464acc8UL, 0x5d5de7baUL, 0x19192b32UL, 0x737395e6UL, 0x6060a0c0UL, 0x81819819UL, 0x4f4fd19eUL, 0xdcdc7fa3UL, 0x22226644UL, 0x2a2a7e54UL, 0x9090ab3bUL, 0x8888830bUL, 0x4646ca8cUL, 0xeeee29c7UL, 0xb8b8d36bUL, 0x14143c28UL, 0xdede79a7UL, 0x5e5ee2bcUL, 0x0b0b1d16UL, 0xdbdb76adUL, 0xe0e03bdbUL, 0x32325664UL, 0x3a3a4e74UL, 0x0a0a1e14UL, 0x4949db92UL, 0x06060a0cUL, 0x24246c48UL, 0x5c5ce4b8UL, 0xc2c25d9fUL, 0xd3d36ebdUL, 0xacacef43UL, 0x6262a6c4UL, 0x9191a839UL, 0x9595a431UL, 0xe4e437d3UL, 0x79798bf2UL, 0xe7e732d5UL, 0xc8c8438bUL, 0x3737596eUL, 0x6d6db7daUL, 0x8d8d8c01UL, 0xd5d564b1UL, 0x4e4ed29cUL, 0xa9a9e049UL, 0x6c6cb4d8UL, 0x5656faacUL, 0xf4f407f3UL, 0xeaea25cfUL, 0x6565afcaUL, 0x7a7a8ef4UL, 0xaeaee947UL, 0x08081810UL, 0xbabad56fUL, 0x787888f0UL, 0x25256f4aUL, 0x2e2e725cUL, 0x1c1c2438UL, 0xa6a6f157UL, 0xb4b4c773UL, 0xc6c65197UL, 0xe8e823cbUL, 0xdddd7ca1UL, 0x74749ce8UL, 0x1f1f213eUL, 0x4b4bdd96UL, 0xbdbddc61UL, 0x8b8b860dUL, 0x8a8a850fUL, 0x707090e0UL, 0x3e3e427cUL, 0xb5b5c471UL, 0x6666aaccUL, 0x4848d890UL, 0x03030506UL, 0xf6f601f7UL, 0x0e0e121cUL, 0x6161a3c2UL, 0x35355f6aUL, 0x5757f9aeUL, 0xb9b9d069UL, 0x86869117UL, 0xc1c15899UL, 0x1d1d273aUL, 0x9e9eb927UL, 0xe1e138d9UL, 0xf8f813ebUL, 0x9898b32bUL, 0x11113322UL, 0x6969bbd2UL, 0xd9d970a9UL, 0x8e8e8907UL, 0x9494a733UL, 0x9b9bb62dUL, 0x1e1e223cUL, 0x87879215UL, 0xe9e920c9UL, 0xcece4987UL, 0x5555ffaaUL, 0x28287850UL, 0xdfdf7aa5UL, 0x8c8c8f03UL, 0xa1a1f859UL, 0x89898009UL, 0x0d0d171aUL, 0xbfbfda65UL, 0xe6e631d7UL, 0x4242c684UL, 0x6868b8d0UL, 0x4141c382UL, 0x9999b029UL, 0x2d2d775aUL, 0x0f0f111eUL, 0xb0b0cb7bUL, 0x5454fca8UL, 0xbbbbd66dUL, 0x16163a2cUL, }; #ifndef PELI_TAB static const ulong32 Te4_0[] = { 0x00000063UL, 0x0000007cUL, 0x00000077UL, 0x0000007bUL, 0x000000f2UL, 0x0000006bUL, 0x0000006fUL, 0x000000c5UL, 0x00000030UL, 0x00000001UL, 0x00000067UL, 0x0000002bUL, 0x000000feUL, 0x000000d7UL, 0x000000abUL, 0x00000076UL, 0x000000caUL, 0x00000082UL, 0x000000c9UL, 0x0000007dUL, 0x000000faUL, 0x00000059UL, 0x00000047UL, 0x000000f0UL, 0x000000adUL, 0x000000d4UL, 0x000000a2UL, 0x000000afUL, 0x0000009cUL, 0x000000a4UL, 0x00000072UL, 0x000000c0UL, 0x000000b7UL, 0x000000fdUL, 0x00000093UL, 0x00000026UL, 0x00000036UL, 0x0000003fUL, 0x000000f7UL, 0x000000ccUL, 0x00000034UL, 0x000000a5UL, 0x000000e5UL, 0x000000f1UL, 0x00000071UL, 0x000000d8UL, 0x00000031UL, 0x00000015UL, 0x00000004UL, 0x000000c7UL, 0x00000023UL, 0x000000c3UL, 0x00000018UL, 0x00000096UL, 0x00000005UL, 0x0000009aUL, 0x00000007UL, 0x00000012UL, 0x00000080UL, 0x000000e2UL, 0x000000ebUL, 0x00000027UL, 0x000000b2UL, 0x00000075UL, 0x00000009UL, 0x00000083UL, 0x0000002cUL, 0x0000001aUL, 0x0000001bUL, 0x0000006eUL, 0x0000005aUL, 0x000000a0UL, 0x00000052UL, 0x0000003bUL, 0x000000d6UL, 0x000000b3UL, 0x00000029UL, 0x000000e3UL, 0x0000002fUL, 0x00000084UL, 0x00000053UL, 0x000000d1UL, 0x00000000UL, 0x000000edUL, 0x00000020UL, 0x000000fcUL, 0x000000b1UL, 0x0000005bUL, 0x0000006aUL, 0x000000cbUL, 0x000000beUL, 0x00000039UL, 0x0000004aUL, 0x0000004cUL, 0x00000058UL, 0x000000cfUL, 0x000000d0UL, 0x000000efUL, 0x000000aaUL, 0x000000fbUL, 0x00000043UL, 0x0000004dUL, 0x00000033UL, 0x00000085UL, 0x00000045UL, 0x000000f9UL, 0x00000002UL, 0x0000007fUL, 0x00000050UL, 0x0000003cUL, 0x0000009fUL, 0x000000a8UL, 0x00000051UL, 0x000000a3UL, 0x00000040UL, 0x0000008fUL, 0x00000092UL, 0x0000009dUL, 0x00000038UL, 0x000000f5UL, 0x000000bcUL, 0x000000b6UL, 0x000000daUL, 0x00000021UL, 0x00000010UL, 0x000000ffUL, 0x000000f3UL, 0x000000d2UL, 0x000000cdUL, 0x0000000cUL, 0x00000013UL, 0x000000ecUL, 0x0000005fUL, 0x00000097UL, 0x00000044UL, 0x00000017UL, 0x000000c4UL, 0x000000a7UL, 0x0000007eUL, 0x0000003dUL, 0x00000064UL, 0x0000005dUL, 0x00000019UL, 0x00000073UL, 0x00000060UL, 0x00000081UL, 0x0000004fUL, 0x000000dcUL, 0x00000022UL, 0x0000002aUL, 0x00000090UL, 0x00000088UL, 0x00000046UL, 0x000000eeUL, 0x000000b8UL, 0x00000014UL, 0x000000deUL, 0x0000005eUL, 0x0000000bUL, 0x000000dbUL, 0x000000e0UL, 0x00000032UL, 0x0000003aUL, 0x0000000aUL, 0x00000049UL, 0x00000006UL, 0x00000024UL, 0x0000005cUL, 0x000000c2UL, 0x000000d3UL, 0x000000acUL, 0x00000062UL, 0x00000091UL, 0x00000095UL, 0x000000e4UL, 0x00000079UL, 0x000000e7UL, 0x000000c8UL, 0x00000037UL, 0x0000006dUL, 0x0000008dUL, 0x000000d5UL, 0x0000004eUL, 0x000000a9UL, 0x0000006cUL, 0x00000056UL, 0x000000f4UL, 0x000000eaUL, 0x00000065UL, 0x0000007aUL, 0x000000aeUL, 0x00000008UL, 0x000000baUL, 0x00000078UL, 0x00000025UL, 0x0000002eUL, 0x0000001cUL, 0x000000a6UL, 0x000000b4UL, 0x000000c6UL, 0x000000e8UL, 0x000000ddUL, 0x00000074UL, 0x0000001fUL, 0x0000004bUL, 0x000000bdUL, 0x0000008bUL, 0x0000008aUL, 0x00000070UL, 0x0000003eUL, 0x000000b5UL, 0x00000066UL, 0x00000048UL, 0x00000003UL, 0x000000f6UL, 0x0000000eUL, 0x00000061UL, 0x00000035UL, 0x00000057UL, 0x000000b9UL, 0x00000086UL, 0x000000c1UL, 0x0000001dUL, 0x0000009eUL, 0x000000e1UL, 0x000000f8UL, 0x00000098UL, 0x00000011UL, 0x00000069UL, 0x000000d9UL, 0x0000008eUL, 0x00000094UL, 0x0000009bUL, 0x0000001eUL, 0x00000087UL, 0x000000e9UL, 0x000000ceUL, 0x00000055UL, 0x00000028UL, 0x000000dfUL, 0x0000008cUL, 0x000000a1UL, 0x00000089UL, 0x0000000dUL, 0x000000bfUL, 0x000000e6UL, 0x00000042UL, 0x00000068UL, 0x00000041UL, 0x00000099UL, 0x0000002dUL, 0x0000000fUL, 0x000000b0UL, 0x00000054UL, 0x000000bbUL, 0x00000016UL }; static const ulong32 Te4_1[] = { 0x00006300UL, 0x00007c00UL, 0x00007700UL, 0x00007b00UL, 0x0000f200UL, 0x00006b00UL, 0x00006f00UL, 0x0000c500UL, 0x00003000UL, 0x00000100UL, 0x00006700UL, 0x00002b00UL, 0x0000fe00UL, 0x0000d700UL, 0x0000ab00UL, 0x00007600UL, 0x0000ca00UL, 0x00008200UL, 0x0000c900UL, 0x00007d00UL, 0x0000fa00UL, 0x00005900UL, 0x00004700UL, 0x0000f000UL, 0x0000ad00UL, 0x0000d400UL, 0x0000a200UL, 0x0000af00UL, 0x00009c00UL, 0x0000a400UL, 0x00007200UL, 0x0000c000UL, 0x0000b700UL, 0x0000fd00UL, 0x00009300UL, 0x00002600UL, 0x00003600UL, 0x00003f00UL, 0x0000f700UL, 0x0000cc00UL, 0x00003400UL, 0x0000a500UL, 0x0000e500UL, 0x0000f100UL, 0x00007100UL, 0x0000d800UL, 0x00003100UL, 0x00001500UL, 0x00000400UL, 0x0000c700UL, 0x00002300UL, 0x0000c300UL, 0x00001800UL, 0x00009600UL, 0x00000500UL, 0x00009a00UL, 0x00000700UL, 0x00001200UL, 0x00008000UL, 0x0000e200UL, 0x0000eb00UL, 0x00002700UL, 0x0000b200UL, 0x00007500UL, 0x00000900UL, 0x00008300UL, 0x00002c00UL, 0x00001a00UL, 0x00001b00UL, 0x00006e00UL, 0x00005a00UL, 0x0000a000UL, 0x00005200UL, 0x00003b00UL, 0x0000d600UL, 0x0000b300UL, 0x00002900UL, 0x0000e300UL, 0x00002f00UL, 0x00008400UL, 0x00005300UL, 0x0000d100UL, 0x00000000UL, 0x0000ed00UL, 0x00002000UL, 0x0000fc00UL, 0x0000b100UL, 0x00005b00UL, 0x00006a00UL, 0x0000cb00UL, 0x0000be00UL, 0x00003900UL, 0x00004a00UL, 0x00004c00UL, 0x00005800UL, 0x0000cf00UL, 0x0000d000UL, 0x0000ef00UL, 0x0000aa00UL, 0x0000fb00UL, 0x00004300UL, 0x00004d00UL, 0x00003300UL, 0x00008500UL, 0x00004500UL, 0x0000f900UL, 0x00000200UL, 0x00007f00UL, 0x00005000UL, 0x00003c00UL, 0x00009f00UL, 0x0000a800UL, 0x00005100UL, 0x0000a300UL, 0x00004000UL, 0x00008f00UL, 0x00009200UL, 0x00009d00UL, 0x00003800UL, 0x0000f500UL, 0x0000bc00UL, 0x0000b600UL, 0x0000da00UL, 0x00002100UL, 0x00001000UL, 0x0000ff00UL, 0x0000f300UL, 0x0000d200UL, 0x0000cd00UL, 0x00000c00UL, 0x00001300UL, 0x0000ec00UL, 0x00005f00UL, 0x00009700UL, 0x00004400UL, 0x00001700UL, 0x0000c400UL, 0x0000a700UL, 0x00007e00UL, 0x00003d00UL, 0x00006400UL, 0x00005d00UL, 0x00001900UL, 0x00007300UL, 0x00006000UL, 0x00008100UL, 0x00004f00UL, 0x0000dc00UL, 0x00002200UL, 0x00002a00UL, 0x00009000UL, 0x00008800UL, 0x00004600UL, 0x0000ee00UL, 0x0000b800UL, 0x00001400UL, 0x0000de00UL, 0x00005e00UL, 0x00000b00UL, 0x0000db00UL, 0x0000e000UL, 0x00003200UL, 0x00003a00UL, 0x00000a00UL, 0x00004900UL, 0x00000600UL, 0x00002400UL, 0x00005c00UL, 0x0000c200UL, 0x0000d300UL, 0x0000ac00UL, 0x00006200UL, 0x00009100UL, 0x00009500UL, 0x0000e400UL, 0x00007900UL, 0x0000e700UL, 0x0000c800UL, 0x00003700UL, 0x00006d00UL, 0x00008d00UL, 0x0000d500UL, 0x00004e00UL, 0x0000a900UL, 0x00006c00UL, 0x00005600UL, 0x0000f400UL, 0x0000ea00UL, 0x00006500UL, 0x00007a00UL, 0x0000ae00UL, 0x00000800UL, 0x0000ba00UL, 0x00007800UL, 0x00002500UL, 0x00002e00UL, 0x00001c00UL, 0x0000a600UL, 0x0000b400UL, 0x0000c600UL, 0x0000e800UL, 0x0000dd00UL, 0x00007400UL, 0x00001f00UL, 0x00004b00UL, 0x0000bd00UL, 0x00008b00UL, 0x00008a00UL, 0x00007000UL, 0x00003e00UL, 0x0000b500UL, 0x00006600UL, 0x00004800UL, 0x00000300UL, 0x0000f600UL, 0x00000e00UL, 0x00006100UL, 0x00003500UL, 0x00005700UL, 0x0000b900UL, 0x00008600UL, 0x0000c100UL, 0x00001d00UL, 0x00009e00UL, 0x0000e100UL, 0x0000f800UL, 0x00009800UL, 0x00001100UL, 0x00006900UL, 0x0000d900UL, 0x00008e00UL, 0x00009400UL, 0x00009b00UL, 0x00001e00UL, 0x00008700UL, 0x0000e900UL, 0x0000ce00UL, 0x00005500UL, 0x00002800UL, 0x0000df00UL, 0x00008c00UL, 0x0000a100UL, 0x00008900UL, 0x00000d00UL, 0x0000bf00UL, 0x0000e600UL, 0x00004200UL, 0x00006800UL, 0x00004100UL, 0x00009900UL, 0x00002d00UL, 0x00000f00UL, 0x0000b000UL, 0x00005400UL, 0x0000bb00UL, 0x00001600UL }; static const ulong32 Te4_2[] = { 0x00630000UL, 0x007c0000UL, 0x00770000UL, 0x007b0000UL, 0x00f20000UL, 0x006b0000UL, 0x006f0000UL, 0x00c50000UL, 0x00300000UL, 0x00010000UL, 0x00670000UL, 0x002b0000UL, 0x00fe0000UL, 0x00d70000UL, 0x00ab0000UL, 0x00760000UL, 0x00ca0000UL, 0x00820000UL, 0x00c90000UL, 0x007d0000UL, 0x00fa0000UL, 0x00590000UL, 0x00470000UL, 0x00f00000UL, 0x00ad0000UL, 0x00d40000UL, 0x00a20000UL, 0x00af0000UL, 0x009c0000UL, 0x00a40000UL, 0x00720000UL, 0x00c00000UL, 0x00b70000UL, 0x00fd0000UL, 0x00930000UL, 0x00260000UL, 0x00360000UL, 0x003f0000UL, 0x00f70000UL, 0x00cc0000UL, 0x00340000UL, 0x00a50000UL, 0x00e50000UL, 0x00f10000UL, 0x00710000UL, 0x00d80000UL, 0x00310000UL, 0x00150000UL, 0x00040000UL, 0x00c70000UL, 0x00230000UL, 0x00c30000UL, 0x00180000UL, 0x00960000UL, 0x00050000UL, 0x009a0000UL, 0x00070000UL, 0x00120000UL, 0x00800000UL, 0x00e20000UL, 0x00eb0000UL, 0x00270000UL, 0x00b20000UL, 0x00750000UL, 0x00090000UL, 0x00830000UL, 0x002c0000UL, 0x001a0000UL, 0x001b0000UL, 0x006e0000UL, 0x005a0000UL, 0x00a00000UL, 0x00520000UL, 0x003b0000UL, 0x00d60000UL, 0x00b30000UL, 0x00290000UL, 0x00e30000UL, 0x002f0000UL, 0x00840000UL, 0x00530000UL, 0x00d10000UL, 0x00000000UL, 0x00ed0000UL, 0x00200000UL, 0x00fc0000UL, 0x00b10000UL, 0x005b0000UL, 0x006a0000UL, 0x00cb0000UL, 0x00be0000UL, 0x00390000UL, 0x004a0000UL, 0x004c0000UL, 0x00580000UL, 0x00cf0000UL, 0x00d00000UL, 0x00ef0000UL, 0x00aa0000UL, 0x00fb0000UL, 0x00430000UL, 0x004d0000UL, 0x00330000UL, 0x00850000UL, 0x00450000UL, 0x00f90000UL, 0x00020000UL, 0x007f0000UL, 0x00500000UL, 0x003c0000UL, 0x009f0000UL, 0x00a80000UL, 0x00510000UL, 0x00a30000UL, 0x00400000UL, 0x008f0000UL, 0x00920000UL, 0x009d0000UL, 0x00380000UL, 0x00f50000UL, 0x00bc0000UL, 0x00b60000UL, 0x00da0000UL, 0x00210000UL, 0x00100000UL, 0x00ff0000UL, 0x00f30000UL, 0x00d20000UL, 0x00cd0000UL, 0x000c0000UL, 0x00130000UL, 0x00ec0000UL, 0x005f0000UL, 0x00970000UL, 0x00440000UL, 0x00170000UL, 0x00c40000UL, 0x00a70000UL, 0x007e0000UL, 0x003d0000UL, 0x00640000UL, 0x005d0000UL, 0x00190000UL, 0x00730000UL, 0x00600000UL, 0x00810000UL, 0x004f0000UL, 0x00dc0000UL, 0x00220000UL, 0x002a0000UL, 0x00900000UL, 0x00880000UL, 0x00460000UL, 0x00ee0000UL, 0x00b80000UL, 0x00140000UL, 0x00de0000UL, 0x005e0000UL, 0x000b0000UL, 0x00db0000UL, 0x00e00000UL, 0x00320000UL, 0x003a0000UL, 0x000a0000UL, 0x00490000UL, 0x00060000UL, 0x00240000UL, 0x005c0000UL, 0x00c20000UL, 0x00d30000UL, 0x00ac0000UL, 0x00620000UL, 0x00910000UL, 0x00950000UL, 0x00e40000UL, 0x00790000UL, 0x00e70000UL, 0x00c80000UL, 0x00370000UL, 0x006d0000UL, 0x008d0000UL, 0x00d50000UL, 0x004e0000UL, 0x00a90000UL, 0x006c0000UL, 0x00560000UL, 0x00f40000UL, 0x00ea0000UL, 0x00650000UL, 0x007a0000UL, 0x00ae0000UL, 0x00080000UL, 0x00ba0000UL, 0x00780000UL, 0x00250000UL, 0x002e0000UL, 0x001c0000UL, 0x00a60000UL, 0x00b40000UL, 0x00c60000UL, 0x00e80000UL, 0x00dd0000UL, 0x00740000UL, 0x001f0000UL, 0x004b0000UL, 0x00bd0000UL, 0x008b0000UL, 0x008a0000UL, 0x00700000UL, 0x003e0000UL, 0x00b50000UL, 0x00660000UL, 0x00480000UL, 0x00030000UL, 0x00f60000UL, 0x000e0000UL, 0x00610000UL, 0x00350000UL, 0x00570000UL, 0x00b90000UL, 0x00860000UL, 0x00c10000UL, 0x001d0000UL, 0x009e0000UL, 0x00e10000UL, 0x00f80000UL, 0x00980000UL, 0x00110000UL, 0x00690000UL, 0x00d90000UL, 0x008e0000UL, 0x00940000UL, 0x009b0000UL, 0x001e0000UL, 0x00870000UL, 0x00e90000UL, 0x00ce0000UL, 0x00550000UL, 0x00280000UL, 0x00df0000UL, 0x008c0000UL, 0x00a10000UL, 0x00890000UL, 0x000d0000UL, 0x00bf0000UL, 0x00e60000UL, 0x00420000UL, 0x00680000UL, 0x00410000UL, 0x00990000UL, 0x002d0000UL, 0x000f0000UL, 0x00b00000UL, 0x00540000UL, 0x00bb0000UL, 0x00160000UL }; static const ulong32 Te4_3[] = { 0x63000000UL, 0x7c000000UL, 0x77000000UL, 0x7b000000UL, 0xf2000000UL, 0x6b000000UL, 0x6f000000UL, 0xc5000000UL, 0x30000000UL, 0x01000000UL, 0x67000000UL, 0x2b000000UL, 0xfe000000UL, 0xd7000000UL, 0xab000000UL, 0x76000000UL, 0xca000000UL, 0x82000000UL, 0xc9000000UL, 0x7d000000UL, 0xfa000000UL, 0x59000000UL, 0x47000000UL, 0xf0000000UL, 0xad000000UL, 0xd4000000UL, 0xa2000000UL, 0xaf000000UL, 0x9c000000UL, 0xa4000000UL, 0x72000000UL, 0xc0000000UL, 0xb7000000UL, 0xfd000000UL, 0x93000000UL, 0x26000000UL, 0x36000000UL, 0x3f000000UL, 0xf7000000UL, 0xcc000000UL, 0x34000000UL, 0xa5000000UL, 0xe5000000UL, 0xf1000000UL, 0x71000000UL, 0xd8000000UL, 0x31000000UL, 0x15000000UL, 0x04000000UL, 0xc7000000UL, 0x23000000UL, 0xc3000000UL, 0x18000000UL, 0x96000000UL, 0x05000000UL, 0x9a000000UL, 0x07000000UL, 0x12000000UL, 0x80000000UL, 0xe2000000UL, 0xeb000000UL, 0x27000000UL, 0xb2000000UL, 0x75000000UL, 0x09000000UL, 0x83000000UL, 0x2c000000UL, 0x1a000000UL, 0x1b000000UL, 0x6e000000UL, 0x5a000000UL, 0xa0000000UL, 0x52000000UL, 0x3b000000UL, 0xd6000000UL, 0xb3000000UL, 0x29000000UL, 0xe3000000UL, 0x2f000000UL, 0x84000000UL, 0x53000000UL, 0xd1000000UL, 0x00000000UL, 0xed000000UL, 0x20000000UL, 0xfc000000UL, 0xb1000000UL, 0x5b000000UL, 0x6a000000UL, 0xcb000000UL, 0xbe000000UL, 0x39000000UL, 0x4a000000UL, 0x4c000000UL, 0x58000000UL, 0xcf000000UL, 0xd0000000UL, 0xef000000UL, 0xaa000000UL, 0xfb000000UL, 0x43000000UL, 0x4d000000UL, 0x33000000UL, 0x85000000UL, 0x45000000UL, 0xf9000000UL, 0x02000000UL, 0x7f000000UL, 0x50000000UL, 0x3c000000UL, 0x9f000000UL, 0xa8000000UL, 0x51000000UL, 0xa3000000UL, 0x40000000UL, 0x8f000000UL, 0x92000000UL, 0x9d000000UL, 0x38000000UL, 0xf5000000UL, 0xbc000000UL, 0xb6000000UL, 0xda000000UL, 0x21000000UL, 0x10000000UL, 0xff000000UL, 0xf3000000UL, 0xd2000000UL, 0xcd000000UL, 0x0c000000UL, 0x13000000UL, 0xec000000UL, 0x5f000000UL, 0x97000000UL, 0x44000000UL, 0x17000000UL, 0xc4000000UL, 0xa7000000UL, 0x7e000000UL, 0x3d000000UL, 0x64000000UL, 0x5d000000UL, 0x19000000UL, 0x73000000UL, 0x60000000UL, 0x81000000UL, 0x4f000000UL, 0xdc000000UL, 0x22000000UL, 0x2a000000UL, 0x90000000UL, 0x88000000UL, 0x46000000UL, 0xee000000UL, 0xb8000000UL, 0x14000000UL, 0xde000000UL, 0x5e000000UL, 0x0b000000UL, 0xdb000000UL, 0xe0000000UL, 0x32000000UL, 0x3a000000UL, 0x0a000000UL, 0x49000000UL, 0x06000000UL, 0x24000000UL, 0x5c000000UL, 0xc2000000UL, 0xd3000000UL, 0xac000000UL, 0x62000000UL, 0x91000000UL, 0x95000000UL, 0xe4000000UL, 0x79000000UL, 0xe7000000UL, 0xc8000000UL, 0x37000000UL, 0x6d000000UL, 0x8d000000UL, 0xd5000000UL, 0x4e000000UL, 0xa9000000UL, 0x6c000000UL, 0x56000000UL, 0xf4000000UL, 0xea000000UL, 0x65000000UL, 0x7a000000UL, 0xae000000UL, 0x08000000UL, 0xba000000UL, 0x78000000UL, 0x25000000UL, 0x2e000000UL, 0x1c000000UL, 0xa6000000UL, 0xb4000000UL, 0xc6000000UL, 0xe8000000UL, 0xdd000000UL, 0x74000000UL, 0x1f000000UL, 0x4b000000UL, 0xbd000000UL, 0x8b000000UL, 0x8a000000UL, 0x70000000UL, 0x3e000000UL, 0xb5000000UL, 0x66000000UL, 0x48000000UL, 0x03000000UL, 0xf6000000UL, 0x0e000000UL, 0x61000000UL, 0x35000000UL, 0x57000000UL, 0xb9000000UL, 0x86000000UL, 0xc1000000UL, 0x1d000000UL, 0x9e000000UL, 0xe1000000UL, 0xf8000000UL, 0x98000000UL, 0x11000000UL, 0x69000000UL, 0xd9000000UL, 0x8e000000UL, 0x94000000UL, 0x9b000000UL, 0x1e000000UL, 0x87000000UL, 0xe9000000UL, 0xce000000UL, 0x55000000UL, 0x28000000UL, 0xdf000000UL, 0x8c000000UL, 0xa1000000UL, 0x89000000UL, 0x0d000000UL, 0xbf000000UL, 0xe6000000UL, 0x42000000UL, 0x68000000UL, 0x41000000UL, 0x99000000UL, 0x2d000000UL, 0x0f000000UL, 0xb0000000UL, 0x54000000UL, 0xbb000000UL, 0x16000000UL }; #endif /* pelimac */ #ifndef ENCRYPT_ONLY static const ulong32 TD1[256] = { 0x5051f4a7UL, 0x537e4165UL, 0xc31a17a4UL, 0x963a275eUL, 0xcb3bab6bUL, 0xf11f9d45UL, 0xabacfa58UL, 0x934be303UL, 0x552030faUL, 0xf6ad766dUL, 0x9188cc76UL, 0x25f5024cUL, 0xfc4fe5d7UL, 0xd7c52acbUL, 0x80263544UL, 0x8fb562a3UL, 0x49deb15aUL, 0x6725ba1bUL, 0x9845ea0eUL, 0xe15dfec0UL, 0x02c32f75UL, 0x12814cf0UL, 0xa38d4697UL, 0xc66bd3f9UL, 0xe7038f5fUL, 0x9515929cUL, 0xebbf6d7aUL, 0xda955259UL, 0x2dd4be83UL, 0xd3587421UL, 0x2949e069UL, 0x448ec9c8UL, 0x6a75c289UL, 0x78f48e79UL, 0x6b99583eUL, 0xdd27b971UL, 0xb6bee14fUL, 0x17f088adUL, 0x66c920acUL, 0xb47dce3aUL, 0x1863df4aUL, 0x82e51a31UL, 0x60975133UL, 0x4562537fUL, 0xe0b16477UL, 0x84bb6baeUL, 0x1cfe81a0UL, 0x94f9082bUL, 0x58704868UL, 0x198f45fdUL, 0x8794de6cUL, 0xb7527bf8UL, 0x23ab73d3UL, 0xe2724b02UL, 0x57e31f8fUL, 0x2a6655abUL, 0x07b2eb28UL, 0x032fb5c2UL, 0x9a86c57bUL, 0xa5d33708UL, 0xf2302887UL, 0xb223bfa5UL, 0xba02036aUL, 0x5ced1682UL, 0x2b8acf1cUL, 0x92a779b4UL, 0xf0f307f2UL, 0xa14e69e2UL, 0xcd65daf4UL, 0xd50605beUL, 0x1fd13462UL, 0x8ac4a6feUL, 0x9d342e53UL, 0xa0a2f355UL, 0x32058ae1UL, 0x75a4f6ebUL, 0x390b83ecUL, 0xaa4060efUL, 0x065e719fUL, 0x51bd6e10UL, 0xf93e218aUL, 0x3d96dd06UL, 0xaedd3e05UL, 0x464de6bdUL, 0xb591548dUL, 0x0571c45dUL, 0x6f0406d4UL, 0xff605015UL, 0x241998fbUL, 0x97d6bde9UL, 0xcc894043UL, 0x7767d99eUL, 0xbdb0e842UL, 0x8807898bUL, 0x38e7195bUL, 0xdb79c8eeUL, 0x47a17c0aUL, 0xe97c420fUL, 0xc9f8841eUL, 0x00000000UL, 0x83098086UL, 0x48322bedUL, 0xac1e1170UL, 0x4e6c5a72UL, 0xfbfd0effUL, 0x560f8538UL, 0x1e3daed5UL, 0x27362d39UL, 0x640a0fd9UL, 0x21685ca6UL, 0xd19b5b54UL, 0x3a24362eUL, 0xb10c0a67UL, 0x0f9357e7UL, 0xd2b4ee96UL, 0x9e1b9b91UL, 0x4f80c0c5UL, 0xa261dc20UL, 0x695a774bUL, 0x161c121aUL, 0x0ae293baUL, 0xe5c0a02aUL, 0x433c22e0UL, 0x1d121b17UL, 0x0b0e090dUL, 0xadf28bc7UL, 0xb92db6a8UL, 0xc8141ea9UL, 0x8557f119UL, 0x4caf7507UL, 0xbbee99ddUL, 0xfda37f60UL, 0x9ff70126UL, 0xbc5c72f5UL, 0xc544663bUL, 0x345bfb7eUL, 0x768b4329UL, 0xdccb23c6UL, 0x68b6edfcUL, 0x63b8e4f1UL, 0xcad731dcUL, 0x10426385UL, 0x40139722UL, 0x2084c611UL, 0x7d854a24UL, 0xf8d2bb3dUL, 0x11aef932UL, 0x6dc729a1UL, 0x4b1d9e2fUL, 0xf3dcb230UL, 0xec0d8652UL, 0xd077c1e3UL, 0x6c2bb316UL, 0x99a970b9UL, 0xfa119448UL, 0x2247e964UL, 0xc4a8fc8cUL, 0x1aa0f03fUL, 0xd8567d2cUL, 0xef223390UL, 0xc787494eUL, 0xc1d938d1UL, 0xfe8ccaa2UL, 0x3698d40bUL, 0xcfa6f581UL, 0x28a57adeUL, 0x26dab78eUL, 0xa43fadbfUL, 0xe42c3a9dUL, 0x0d507892UL, 0x9b6a5fccUL, 0x62547e46UL, 0xc2f68d13UL, 0xe890d8b8UL, 0x5e2e39f7UL, 0xf582c3afUL, 0xbe9f5d80UL, 0x7c69d093UL, 0xa96fd52dUL, 0xb3cf2512UL, 0x3bc8ac99UL, 0xa710187dUL, 0x6ee89c63UL, 0x7bdb3bbbUL, 0x09cd2678UL, 0xf46e5918UL, 0x01ec9ab7UL, 0xa8834f9aUL, 0x65e6956eUL, 0x7eaaffe6UL, 0x0821bccfUL, 0xe6ef15e8UL, 0xd9bae79bUL, 0xce4a6f36UL, 0xd4ea9f09UL, 0xd629b07cUL, 0xaf31a4b2UL, 0x312a3f23UL, 0x30c6a594UL, 0xc035a266UL, 0x37744ebcUL, 0xa6fc82caUL, 0xb0e090d0UL, 0x1533a7d8UL, 0x4af10498UL, 0xf741ecdaUL, 0x0e7fcd50UL, 0x2f1791f6UL, 0x8d764dd6UL, 0x4d43efb0UL, 0x54ccaa4dUL, 0xdfe49604UL, 0xe39ed1b5UL, 0x1b4c6a88UL, 0xb8c12c1fUL, 0x7f466551UL, 0x049d5eeaUL, 0x5d018c35UL, 0x73fa8774UL, 0x2efb0b41UL, 0x5ab3671dUL, 0x5292dbd2UL, 0x33e91056UL, 0x136dd647UL, 0x8c9ad761UL, 0x7a37a10cUL, 0x8e59f814UL, 0x89eb133cUL, 0xeecea927UL, 0x35b761c9UL, 0xede11ce5UL, 0x3c7a47b1UL, 0x599cd2dfUL, 0x3f55f273UL, 0x791814ceUL, 0xbf73c737UL, 0xea53f7cdUL, 0x5b5ffdaaUL, 0x14df3d6fUL, 0x867844dbUL, 0x81caaff3UL, 0x3eb968c4UL, 0x2c382434UL, 0x5fc2a340UL, 0x72161dc3UL, 0x0cbce225UL, 0x8b283c49UL, 0x41ff0d95UL, 0x7139a801UL, 0xde080cb3UL, 0x9cd8b4e4UL, 0x906456c1UL, 0x617bcb84UL, 0x70d532b6UL, 0x74486c5cUL, 0x42d0b857UL, }; static const ulong32 TD2[256] = { 0xa75051f4UL, 0x65537e41UL, 0xa4c31a17UL, 0x5e963a27UL, 0x6bcb3babUL, 0x45f11f9dUL, 0x58abacfaUL, 0x03934be3UL, 0xfa552030UL, 0x6df6ad76UL, 0x769188ccUL, 0x4c25f502UL, 0xd7fc4fe5UL, 0xcbd7c52aUL, 0x44802635UL, 0xa38fb562UL, 0x5a49deb1UL, 0x1b6725baUL, 0x0e9845eaUL, 0xc0e15dfeUL, 0x7502c32fUL, 0xf012814cUL, 0x97a38d46UL, 0xf9c66bd3UL, 0x5fe7038fUL, 0x9c951592UL, 0x7aebbf6dUL, 0x59da9552UL, 0x832dd4beUL, 0x21d35874UL, 0x692949e0UL, 0xc8448ec9UL, 0x896a75c2UL, 0x7978f48eUL, 0x3e6b9958UL, 0x71dd27b9UL, 0x4fb6bee1UL, 0xad17f088UL, 0xac66c920UL, 0x3ab47dceUL, 0x4a1863dfUL, 0x3182e51aUL, 0x33609751UL, 0x7f456253UL, 0x77e0b164UL, 0xae84bb6bUL, 0xa01cfe81UL, 0x2b94f908UL, 0x68587048UL, 0xfd198f45UL, 0x6c8794deUL, 0xf8b7527bUL, 0xd323ab73UL, 0x02e2724bUL, 0x8f57e31fUL, 0xab2a6655UL, 0x2807b2ebUL, 0xc2032fb5UL, 0x7b9a86c5UL, 0x08a5d337UL, 0x87f23028UL, 0xa5b223bfUL, 0x6aba0203UL, 0x825ced16UL, 0x1c2b8acfUL, 0xb492a779UL, 0xf2f0f307UL, 0xe2a14e69UL, 0xf4cd65daUL, 0xbed50605UL, 0x621fd134UL, 0xfe8ac4a6UL, 0x539d342eUL, 0x55a0a2f3UL, 0xe132058aUL, 0xeb75a4f6UL, 0xec390b83UL, 0xefaa4060UL, 0x9f065e71UL, 0x1051bd6eUL, 0x8af93e21UL, 0x063d96ddUL, 0x05aedd3eUL, 0xbd464de6UL, 0x8db59154UL, 0x5d0571c4UL, 0xd46f0406UL, 0x15ff6050UL, 0xfb241998UL, 0xe997d6bdUL, 0x43cc8940UL, 0x9e7767d9UL, 0x42bdb0e8UL, 0x8b880789UL, 0x5b38e719UL, 0xeedb79c8UL, 0x0a47a17cUL, 0x0fe97c42UL, 0x1ec9f884UL, 0x00000000UL, 0x86830980UL, 0xed48322bUL, 0x70ac1e11UL, 0x724e6c5aUL, 0xfffbfd0eUL, 0x38560f85UL, 0xd51e3daeUL, 0x3927362dUL, 0xd9640a0fUL, 0xa621685cUL, 0x54d19b5bUL, 0x2e3a2436UL, 0x67b10c0aUL, 0xe70f9357UL, 0x96d2b4eeUL, 0x919e1b9bUL, 0xc54f80c0UL, 0x20a261dcUL, 0x4b695a77UL, 0x1a161c12UL, 0xba0ae293UL, 0x2ae5c0a0UL, 0xe0433c22UL, 0x171d121bUL, 0x0d0b0e09UL, 0xc7adf28bUL, 0xa8b92db6UL, 0xa9c8141eUL, 0x198557f1UL, 0x074caf75UL, 0xddbbee99UL, 0x60fda37fUL, 0x269ff701UL, 0xf5bc5c72UL, 0x3bc54466UL, 0x7e345bfbUL, 0x29768b43UL, 0xc6dccb23UL, 0xfc68b6edUL, 0xf163b8e4UL, 0xdccad731UL, 0x85104263UL, 0x22401397UL, 0x112084c6UL, 0x247d854aUL, 0x3df8d2bbUL, 0x3211aef9UL, 0xa16dc729UL, 0x2f4b1d9eUL, 0x30f3dcb2UL, 0x52ec0d86UL, 0xe3d077c1UL, 0x166c2bb3UL, 0xb999a970UL, 0x48fa1194UL, 0x642247e9UL, 0x8cc4a8fcUL, 0x3f1aa0f0UL, 0x2cd8567dUL, 0x90ef2233UL, 0x4ec78749UL, 0xd1c1d938UL, 0xa2fe8ccaUL, 0x0b3698d4UL, 0x81cfa6f5UL, 0xde28a57aUL, 0x8e26dab7UL, 0xbfa43fadUL, 0x9de42c3aUL, 0x920d5078UL, 0xcc9b6a5fUL, 0x4662547eUL, 0x13c2f68dUL, 0xb8e890d8UL, 0xf75e2e39UL, 0xaff582c3UL, 0x80be9f5dUL, 0x937c69d0UL, 0x2da96fd5UL, 0x12b3cf25UL, 0x993bc8acUL, 0x7da71018UL, 0x636ee89cUL, 0xbb7bdb3bUL, 0x7809cd26UL, 0x18f46e59UL, 0xb701ec9aUL, 0x9aa8834fUL, 0x6e65e695UL, 0xe67eaaffUL, 0xcf0821bcUL, 0xe8e6ef15UL, 0x9bd9bae7UL, 0x36ce4a6fUL, 0x09d4ea9fUL, 0x7cd629b0UL, 0xb2af31a4UL, 0x23312a3fUL, 0x9430c6a5UL, 0x66c035a2UL, 0xbc37744eUL, 0xcaa6fc82UL, 0xd0b0e090UL, 0xd81533a7UL, 0x984af104UL, 0xdaf741ecUL, 0x500e7fcdUL, 0xf62f1791UL, 0xd68d764dUL, 0xb04d43efUL, 0x4d54ccaaUL, 0x04dfe496UL, 0xb5e39ed1UL, 0x881b4c6aUL, 0x1fb8c12cUL, 0x517f4665UL, 0xea049d5eUL, 0x355d018cUL, 0x7473fa87UL, 0x412efb0bUL, 0x1d5ab367UL, 0xd25292dbUL, 0x5633e910UL, 0x47136dd6UL, 0x618c9ad7UL, 0x0c7a37a1UL, 0x148e59f8UL, 0x3c89eb13UL, 0x27eecea9UL, 0xc935b761UL, 0xe5ede11cUL, 0xb13c7a47UL, 0xdf599cd2UL, 0x733f55f2UL, 0xce791814UL, 0x37bf73c7UL, 0xcdea53f7UL, 0xaa5b5ffdUL, 0x6f14df3dUL, 0xdb867844UL, 0xf381caafUL, 0xc43eb968UL, 0x342c3824UL, 0x405fc2a3UL, 0xc372161dUL, 0x250cbce2UL, 0x498b283cUL, 0x9541ff0dUL, 0x017139a8UL, 0xb3de080cUL, 0xe49cd8b4UL, 0xc1906456UL, 0x84617bcbUL, 0xb670d532UL, 0x5c74486cUL, 0x5742d0b8UL, }; static const ulong32 TD3[256] = { 0xf4a75051UL, 0x4165537eUL, 0x17a4c31aUL, 0x275e963aUL, 0xab6bcb3bUL, 0x9d45f11fUL, 0xfa58abacUL, 0xe303934bUL, 0x30fa5520UL, 0x766df6adUL, 0xcc769188UL, 0x024c25f5UL, 0xe5d7fc4fUL, 0x2acbd7c5UL, 0x35448026UL, 0x62a38fb5UL, 0xb15a49deUL, 0xba1b6725UL, 0xea0e9845UL, 0xfec0e15dUL, 0x2f7502c3UL, 0x4cf01281UL, 0x4697a38dUL, 0xd3f9c66bUL, 0x8f5fe703UL, 0x929c9515UL, 0x6d7aebbfUL, 0x5259da95UL, 0xbe832dd4UL, 0x7421d358UL, 0xe0692949UL, 0xc9c8448eUL, 0xc2896a75UL, 0x8e7978f4UL, 0x583e6b99UL, 0xb971dd27UL, 0xe14fb6beUL, 0x88ad17f0UL, 0x20ac66c9UL, 0xce3ab47dUL, 0xdf4a1863UL, 0x1a3182e5UL, 0x51336097UL, 0x537f4562UL, 0x6477e0b1UL, 0x6bae84bbUL, 0x81a01cfeUL, 0x082b94f9UL, 0x48685870UL, 0x45fd198fUL, 0xde6c8794UL, 0x7bf8b752UL, 0x73d323abUL, 0x4b02e272UL, 0x1f8f57e3UL, 0x55ab2a66UL, 0xeb2807b2UL, 0xb5c2032fUL, 0xc57b9a86UL, 0x3708a5d3UL, 0x2887f230UL, 0xbfa5b223UL, 0x036aba02UL, 0x16825cedUL, 0xcf1c2b8aUL, 0x79b492a7UL, 0x07f2f0f3UL, 0x69e2a14eUL, 0xdaf4cd65UL, 0x05bed506UL, 0x34621fd1UL, 0xa6fe8ac4UL, 0x2e539d34UL, 0xf355a0a2UL, 0x8ae13205UL, 0xf6eb75a4UL, 0x83ec390bUL, 0x60efaa40UL, 0x719f065eUL, 0x6e1051bdUL, 0x218af93eUL, 0xdd063d96UL, 0x3e05aeddUL, 0xe6bd464dUL, 0x548db591UL, 0xc45d0571UL, 0x06d46f04UL, 0x5015ff60UL, 0x98fb2419UL, 0xbde997d6UL, 0x4043cc89UL, 0xd99e7767UL, 0xe842bdb0UL, 0x898b8807UL, 0x195b38e7UL, 0xc8eedb79UL, 0x7c0a47a1UL, 0x420fe97cUL, 0x841ec9f8UL, 0x00000000UL, 0x80868309UL, 0x2bed4832UL, 0x1170ac1eUL, 0x5a724e6cUL, 0x0efffbfdUL, 0x8538560fUL, 0xaed51e3dUL, 0x2d392736UL, 0x0fd9640aUL, 0x5ca62168UL, 0x5b54d19bUL, 0x362e3a24UL, 0x0a67b10cUL, 0x57e70f93UL, 0xee96d2b4UL, 0x9b919e1bUL, 0xc0c54f80UL, 0xdc20a261UL, 0x774b695aUL, 0x121a161cUL, 0x93ba0ae2UL, 0xa02ae5c0UL, 0x22e0433cUL, 0x1b171d12UL, 0x090d0b0eUL, 0x8bc7adf2UL, 0xb6a8b92dUL, 0x1ea9c814UL, 0xf1198557UL, 0x75074cafUL, 0x99ddbbeeUL, 0x7f60fda3UL, 0x01269ff7UL, 0x72f5bc5cUL, 0x663bc544UL, 0xfb7e345bUL, 0x4329768bUL, 0x23c6dccbUL, 0xedfc68b6UL, 0xe4f163b8UL, 0x31dccad7UL, 0x63851042UL, 0x97224013UL, 0xc6112084UL, 0x4a247d85UL, 0xbb3df8d2UL, 0xf93211aeUL, 0x29a16dc7UL, 0x9e2f4b1dUL, 0xb230f3dcUL, 0x8652ec0dUL, 0xc1e3d077UL, 0xb3166c2bUL, 0x70b999a9UL, 0x9448fa11UL, 0xe9642247UL, 0xfc8cc4a8UL, 0xf03f1aa0UL, 0x7d2cd856UL, 0x3390ef22UL, 0x494ec787UL, 0x38d1c1d9UL, 0xcaa2fe8cUL, 0xd40b3698UL, 0xf581cfa6UL, 0x7ade28a5UL, 0xb78e26daUL, 0xadbfa43fUL, 0x3a9de42cUL, 0x78920d50UL, 0x5fcc9b6aUL, 0x7e466254UL, 0x8d13c2f6UL, 0xd8b8e890UL, 0x39f75e2eUL, 0xc3aff582UL, 0x5d80be9fUL, 0xd0937c69UL, 0xd52da96fUL, 0x2512b3cfUL, 0xac993bc8UL, 0x187da710UL, 0x9c636ee8UL, 0x3bbb7bdbUL, 0x267809cdUL, 0x5918f46eUL, 0x9ab701ecUL, 0x4f9aa883UL, 0x956e65e6UL, 0xffe67eaaUL, 0xbccf0821UL, 0x15e8e6efUL, 0xe79bd9baUL, 0x6f36ce4aUL, 0x9f09d4eaUL, 0xb07cd629UL, 0xa4b2af31UL, 0x3f23312aUL, 0xa59430c6UL, 0xa266c035UL, 0x4ebc3774UL, 0x82caa6fcUL, 0x90d0b0e0UL, 0xa7d81533UL, 0x04984af1UL, 0xecdaf741UL, 0xcd500e7fUL, 0x91f62f17UL, 0x4dd68d76UL, 0xefb04d43UL, 0xaa4d54ccUL, 0x9604dfe4UL, 0xd1b5e39eUL, 0x6a881b4cUL, 0x2c1fb8c1UL, 0x65517f46UL, 0x5eea049dUL, 0x8c355d01UL, 0x877473faUL, 0x0b412efbUL, 0x671d5ab3UL, 0xdbd25292UL, 0x105633e9UL, 0xd647136dUL, 0xd7618c9aUL, 0xa10c7a37UL, 0xf8148e59UL, 0x133c89ebUL, 0xa927eeceUL, 0x61c935b7UL, 0x1ce5ede1UL, 0x47b13c7aUL, 0xd2df599cUL, 0xf2733f55UL, 0x14ce7918UL, 0xc737bf73UL, 0xf7cdea53UL, 0xfdaa5b5fUL, 0x3d6f14dfUL, 0x44db8678UL, 0xaff381caUL, 0x68c43eb9UL, 0x24342c38UL, 0xa3405fc2UL, 0x1dc37216UL, 0xe2250cbcUL, 0x3c498b28UL, 0x0d9541ffUL, 0xa8017139UL, 0x0cb3de08UL, 0xb4e49cd8UL, 0x56c19064UL, 0xcb84617bUL, 0x32b670d5UL, 0x6c5c7448UL, 0xb85742d0UL, }; static const ulong32 Tks0[] = { 0x00000000UL, 0x0e090d0bUL, 0x1c121a16UL, 0x121b171dUL, 0x3824342cUL, 0x362d3927UL, 0x24362e3aUL, 0x2a3f2331UL, 0x70486858UL, 0x7e416553UL, 0x6c5a724eUL, 0x62537f45UL, 0x486c5c74UL, 0x4665517fUL, 0x547e4662UL, 0x5a774b69UL, 0xe090d0b0UL, 0xee99ddbbUL, 0xfc82caa6UL, 0xf28bc7adUL, 0xd8b4e49cUL, 0xd6bde997UL, 0xc4a6fe8aUL, 0xcaaff381UL, 0x90d8b8e8UL, 0x9ed1b5e3UL, 0x8ccaa2feUL, 0x82c3aff5UL, 0xa8fc8cc4UL, 0xa6f581cfUL, 0xb4ee96d2UL, 0xbae79bd9UL, 0xdb3bbb7bUL, 0xd532b670UL, 0xc729a16dUL, 0xc920ac66UL, 0xe31f8f57UL, 0xed16825cUL, 0xff0d9541UL, 0xf104984aUL, 0xab73d323UL, 0xa57ade28UL, 0xb761c935UL, 0xb968c43eUL, 0x9357e70fUL, 0x9d5eea04UL, 0x8f45fd19UL, 0x814cf012UL, 0x3bab6bcbUL, 0x35a266c0UL, 0x27b971ddUL, 0x29b07cd6UL, 0x038f5fe7UL, 0x0d8652ecUL, 0x1f9d45f1UL, 0x119448faUL, 0x4be30393UL, 0x45ea0e98UL, 0x57f11985UL, 0x59f8148eUL, 0x73c737bfUL, 0x7dce3ab4UL, 0x6fd52da9UL, 0x61dc20a2UL, 0xad766df6UL, 0xa37f60fdUL, 0xb16477e0UL, 0xbf6d7aebUL, 0x955259daUL, 0x9b5b54d1UL, 0x894043ccUL, 0x87494ec7UL, 0xdd3e05aeUL, 0xd33708a5UL, 0xc12c1fb8UL, 0xcf2512b3UL, 0xe51a3182UL, 0xeb133c89UL, 0xf9082b94UL, 0xf701269fUL, 0x4de6bd46UL, 0x43efb04dUL, 0x51f4a750UL, 0x5ffdaa5bUL, 0x75c2896aUL, 0x7bcb8461UL, 0x69d0937cUL, 0x67d99e77UL, 0x3daed51eUL, 0x33a7d815UL, 0x21bccf08UL, 0x2fb5c203UL, 0x058ae132UL, 0x0b83ec39UL, 0x1998fb24UL, 0x1791f62fUL, 0x764dd68dUL, 0x7844db86UL, 0x6a5fcc9bUL, 0x6456c190UL, 0x4e69e2a1UL, 0x4060efaaUL, 0x527bf8b7UL, 0x5c72f5bcUL, 0x0605bed5UL, 0x080cb3deUL, 0x1a17a4c3UL, 0x141ea9c8UL, 0x3e218af9UL, 0x302887f2UL, 0x223390efUL, 0x2c3a9de4UL, 0x96dd063dUL, 0x98d40b36UL, 0x8acf1c2bUL, 0x84c61120UL, 0xaef93211UL, 0xa0f03f1aUL, 0xb2eb2807UL, 0xbce2250cUL, 0xe6956e65UL, 0xe89c636eUL, 0xfa877473UL, 0xf48e7978UL, 0xdeb15a49UL, 0xd0b85742UL, 0xc2a3405fUL, 0xccaa4d54UL, 0x41ecdaf7UL, 0x4fe5d7fcUL, 0x5dfec0e1UL, 0x53f7cdeaUL, 0x79c8eedbUL, 0x77c1e3d0UL, 0x65daf4cdUL, 0x6bd3f9c6UL, 0x31a4b2afUL, 0x3fadbfa4UL, 0x2db6a8b9UL, 0x23bfa5b2UL, 0x09808683UL, 0x07898b88UL, 0x15929c95UL, 0x1b9b919eUL, 0xa17c0a47UL, 0xaf75074cUL, 0xbd6e1051UL, 0xb3671d5aUL, 0x99583e6bUL, 0x97513360UL, 0x854a247dUL, 0x8b432976UL, 0xd134621fUL, 0xdf3d6f14UL, 0xcd267809UL, 0xc32f7502UL, 0xe9105633UL, 0xe7195b38UL, 0xf5024c25UL, 0xfb0b412eUL, 0x9ad7618cUL, 0x94de6c87UL, 0x86c57b9aUL, 0x88cc7691UL, 0xa2f355a0UL, 0xacfa58abUL, 0xbee14fb6UL, 0xb0e842bdUL, 0xea9f09d4UL, 0xe49604dfUL, 0xf68d13c2UL, 0xf8841ec9UL, 0xd2bb3df8UL, 0xdcb230f3UL, 0xcea927eeUL, 0xc0a02ae5UL, 0x7a47b13cUL, 0x744ebc37UL, 0x6655ab2aUL, 0x685ca621UL, 0x42638510UL, 0x4c6a881bUL, 0x5e719f06UL, 0x5078920dUL, 0x0a0fd964UL, 0x0406d46fUL, 0x161dc372UL, 0x1814ce79UL, 0x322bed48UL, 0x3c22e043UL, 0x2e39f75eUL, 0x2030fa55UL, 0xec9ab701UL, 0xe293ba0aUL, 0xf088ad17UL, 0xfe81a01cUL, 0xd4be832dUL, 0xdab78e26UL, 0xc8ac993bUL, 0xc6a59430UL, 0x9cd2df59UL, 0x92dbd252UL, 0x80c0c54fUL, 0x8ec9c844UL, 0xa4f6eb75UL, 0xaaffe67eUL, 0xb8e4f163UL, 0xb6edfc68UL, 0x0c0a67b1UL, 0x02036abaUL, 0x10187da7UL, 0x1e1170acUL, 0x342e539dUL, 0x3a275e96UL, 0x283c498bUL, 0x26354480UL, 0x7c420fe9UL, 0x724b02e2UL, 0x605015ffUL, 0x6e5918f4UL, 0x44663bc5UL, 0x4a6f36ceUL, 0x587421d3UL, 0x567d2cd8UL, 0x37a10c7aUL, 0x39a80171UL, 0x2bb3166cUL, 0x25ba1b67UL, 0x0f853856UL, 0x018c355dUL, 0x13972240UL, 0x1d9e2f4bUL, 0x47e96422UL, 0x49e06929UL, 0x5bfb7e34UL, 0x55f2733fUL, 0x7fcd500eUL, 0x71c45d05UL, 0x63df4a18UL, 0x6dd64713UL, 0xd731dccaUL, 0xd938d1c1UL, 0xcb23c6dcUL, 0xc52acbd7UL, 0xef15e8e6UL, 0xe11ce5edUL, 0xf307f2f0UL, 0xfd0efffbUL, 0xa779b492UL, 0xa970b999UL, 0xbb6bae84UL, 0xb562a38fUL, 0x9f5d80beUL, 0x91548db5UL, 0x834f9aa8UL, 0x8d4697a3UL }; static const ulong32 Tks1[] = { 0x00000000UL, 0x0b0e090dUL, 0x161c121aUL, 0x1d121b17UL, 0x2c382434UL, 0x27362d39UL, 0x3a24362eUL, 0x312a3f23UL, 0x58704868UL, 0x537e4165UL, 0x4e6c5a72UL, 0x4562537fUL, 0x74486c5cUL, 0x7f466551UL, 0x62547e46UL, 0x695a774bUL, 0xb0e090d0UL, 0xbbee99ddUL, 0xa6fc82caUL, 0xadf28bc7UL, 0x9cd8b4e4UL, 0x97d6bde9UL, 0x8ac4a6feUL, 0x81caaff3UL, 0xe890d8b8UL, 0xe39ed1b5UL, 0xfe8ccaa2UL, 0xf582c3afUL, 0xc4a8fc8cUL, 0xcfa6f581UL, 0xd2b4ee96UL, 0xd9bae79bUL, 0x7bdb3bbbUL, 0x70d532b6UL, 0x6dc729a1UL, 0x66c920acUL, 0x57e31f8fUL, 0x5ced1682UL, 0x41ff0d95UL, 0x4af10498UL, 0x23ab73d3UL, 0x28a57adeUL, 0x35b761c9UL, 0x3eb968c4UL, 0x0f9357e7UL, 0x049d5eeaUL, 0x198f45fdUL, 0x12814cf0UL, 0xcb3bab6bUL, 0xc035a266UL, 0xdd27b971UL, 0xd629b07cUL, 0xe7038f5fUL, 0xec0d8652UL, 0xf11f9d45UL, 0xfa119448UL, 0x934be303UL, 0x9845ea0eUL, 0x8557f119UL, 0x8e59f814UL, 0xbf73c737UL, 0xb47dce3aUL, 0xa96fd52dUL, 0xa261dc20UL, 0xf6ad766dUL, 0xfda37f60UL, 0xe0b16477UL, 0xebbf6d7aUL, 0xda955259UL, 0xd19b5b54UL, 0xcc894043UL, 0xc787494eUL, 0xaedd3e05UL, 0xa5d33708UL, 0xb8c12c1fUL, 0xb3cf2512UL, 0x82e51a31UL, 0x89eb133cUL, 0x94f9082bUL, 0x9ff70126UL, 0x464de6bdUL, 0x4d43efb0UL, 0x5051f4a7UL, 0x5b5ffdaaUL, 0x6a75c289UL, 0x617bcb84UL, 0x7c69d093UL, 0x7767d99eUL, 0x1e3daed5UL, 0x1533a7d8UL, 0x0821bccfUL, 0x032fb5c2UL, 0x32058ae1UL, 0x390b83ecUL, 0x241998fbUL, 0x2f1791f6UL, 0x8d764dd6UL, 0x867844dbUL, 0x9b6a5fccUL, 0x906456c1UL, 0xa14e69e2UL, 0xaa4060efUL, 0xb7527bf8UL, 0xbc5c72f5UL, 0xd50605beUL, 0xde080cb3UL, 0xc31a17a4UL, 0xc8141ea9UL, 0xf93e218aUL, 0xf2302887UL, 0xef223390UL, 0xe42c3a9dUL, 0x3d96dd06UL, 0x3698d40bUL, 0x2b8acf1cUL, 0x2084c611UL, 0x11aef932UL, 0x1aa0f03fUL, 0x07b2eb28UL, 0x0cbce225UL, 0x65e6956eUL, 0x6ee89c63UL, 0x73fa8774UL, 0x78f48e79UL, 0x49deb15aUL, 0x42d0b857UL, 0x5fc2a340UL, 0x54ccaa4dUL, 0xf741ecdaUL, 0xfc4fe5d7UL, 0xe15dfec0UL, 0xea53f7cdUL, 0xdb79c8eeUL, 0xd077c1e3UL, 0xcd65daf4UL, 0xc66bd3f9UL, 0xaf31a4b2UL, 0xa43fadbfUL, 0xb92db6a8UL, 0xb223bfa5UL, 0x83098086UL, 0x8807898bUL, 0x9515929cUL, 0x9e1b9b91UL, 0x47a17c0aUL, 0x4caf7507UL, 0x51bd6e10UL, 0x5ab3671dUL, 0x6b99583eUL, 0x60975133UL, 0x7d854a24UL, 0x768b4329UL, 0x1fd13462UL, 0x14df3d6fUL, 0x09cd2678UL, 0x02c32f75UL, 0x33e91056UL, 0x38e7195bUL, 0x25f5024cUL, 0x2efb0b41UL, 0x8c9ad761UL, 0x8794de6cUL, 0x9a86c57bUL, 0x9188cc76UL, 0xa0a2f355UL, 0xabacfa58UL, 0xb6bee14fUL, 0xbdb0e842UL, 0xd4ea9f09UL, 0xdfe49604UL, 0xc2f68d13UL, 0xc9f8841eUL, 0xf8d2bb3dUL, 0xf3dcb230UL, 0xeecea927UL, 0xe5c0a02aUL, 0x3c7a47b1UL, 0x37744ebcUL, 0x2a6655abUL, 0x21685ca6UL, 0x10426385UL, 0x1b4c6a88UL, 0x065e719fUL, 0x0d507892UL, 0x640a0fd9UL, 0x6f0406d4UL, 0x72161dc3UL, 0x791814ceUL, 0x48322bedUL, 0x433c22e0UL, 0x5e2e39f7UL, 0x552030faUL, 0x01ec9ab7UL, 0x0ae293baUL, 0x17f088adUL, 0x1cfe81a0UL, 0x2dd4be83UL, 0x26dab78eUL, 0x3bc8ac99UL, 0x30c6a594UL, 0x599cd2dfUL, 0x5292dbd2UL, 0x4f80c0c5UL, 0x448ec9c8UL, 0x75a4f6ebUL, 0x7eaaffe6UL, 0x63b8e4f1UL, 0x68b6edfcUL, 0xb10c0a67UL, 0xba02036aUL, 0xa710187dUL, 0xac1e1170UL, 0x9d342e53UL, 0x963a275eUL, 0x8b283c49UL, 0x80263544UL, 0xe97c420fUL, 0xe2724b02UL, 0xff605015UL, 0xf46e5918UL, 0xc544663bUL, 0xce4a6f36UL, 0xd3587421UL, 0xd8567d2cUL, 0x7a37a10cUL, 0x7139a801UL, 0x6c2bb316UL, 0x6725ba1bUL, 0x560f8538UL, 0x5d018c35UL, 0x40139722UL, 0x4b1d9e2fUL, 0x2247e964UL, 0x2949e069UL, 0x345bfb7eUL, 0x3f55f273UL, 0x0e7fcd50UL, 0x0571c45dUL, 0x1863df4aUL, 0x136dd647UL, 0xcad731dcUL, 0xc1d938d1UL, 0xdccb23c6UL, 0xd7c52acbUL, 0xe6ef15e8UL, 0xede11ce5UL, 0xf0f307f2UL, 0xfbfd0effUL, 0x92a779b4UL, 0x99a970b9UL, 0x84bb6baeUL, 0x8fb562a3UL, 0xbe9f5d80UL, 0xb591548dUL, 0xa8834f9aUL, 0xa38d4697UL }; static const ulong32 Tks2[] = { 0x00000000UL, 0x0d0b0e09UL, 0x1a161c12UL, 0x171d121bUL, 0x342c3824UL, 0x3927362dUL, 0x2e3a2436UL, 0x23312a3fUL, 0x68587048UL, 0x65537e41UL, 0x724e6c5aUL, 0x7f456253UL, 0x5c74486cUL, 0x517f4665UL, 0x4662547eUL, 0x4b695a77UL, 0xd0b0e090UL, 0xddbbee99UL, 0xcaa6fc82UL, 0xc7adf28bUL, 0xe49cd8b4UL, 0xe997d6bdUL, 0xfe8ac4a6UL, 0xf381caafUL, 0xb8e890d8UL, 0xb5e39ed1UL, 0xa2fe8ccaUL, 0xaff582c3UL, 0x8cc4a8fcUL, 0x81cfa6f5UL, 0x96d2b4eeUL, 0x9bd9bae7UL, 0xbb7bdb3bUL, 0xb670d532UL, 0xa16dc729UL, 0xac66c920UL, 0x8f57e31fUL, 0x825ced16UL, 0x9541ff0dUL, 0x984af104UL, 0xd323ab73UL, 0xde28a57aUL, 0xc935b761UL, 0xc43eb968UL, 0xe70f9357UL, 0xea049d5eUL, 0xfd198f45UL, 0xf012814cUL, 0x6bcb3babUL, 0x66c035a2UL, 0x71dd27b9UL, 0x7cd629b0UL, 0x5fe7038fUL, 0x52ec0d86UL, 0x45f11f9dUL, 0x48fa1194UL, 0x03934be3UL, 0x0e9845eaUL, 0x198557f1UL, 0x148e59f8UL, 0x37bf73c7UL, 0x3ab47dceUL, 0x2da96fd5UL, 0x20a261dcUL, 0x6df6ad76UL, 0x60fda37fUL, 0x77e0b164UL, 0x7aebbf6dUL, 0x59da9552UL, 0x54d19b5bUL, 0x43cc8940UL, 0x4ec78749UL, 0x05aedd3eUL, 0x08a5d337UL, 0x1fb8c12cUL, 0x12b3cf25UL, 0x3182e51aUL, 0x3c89eb13UL, 0x2b94f908UL, 0x269ff701UL, 0xbd464de6UL, 0xb04d43efUL, 0xa75051f4UL, 0xaa5b5ffdUL, 0x896a75c2UL, 0x84617bcbUL, 0x937c69d0UL, 0x9e7767d9UL, 0xd51e3daeUL, 0xd81533a7UL, 0xcf0821bcUL, 0xc2032fb5UL, 0xe132058aUL, 0xec390b83UL, 0xfb241998UL, 0xf62f1791UL, 0xd68d764dUL, 0xdb867844UL, 0xcc9b6a5fUL, 0xc1906456UL, 0xe2a14e69UL, 0xefaa4060UL, 0xf8b7527bUL, 0xf5bc5c72UL, 0xbed50605UL, 0xb3de080cUL, 0xa4c31a17UL, 0xa9c8141eUL, 0x8af93e21UL, 0x87f23028UL, 0x90ef2233UL, 0x9de42c3aUL, 0x063d96ddUL, 0x0b3698d4UL, 0x1c2b8acfUL, 0x112084c6UL, 0x3211aef9UL, 0x3f1aa0f0UL, 0x2807b2ebUL, 0x250cbce2UL, 0x6e65e695UL, 0x636ee89cUL, 0x7473fa87UL, 0x7978f48eUL, 0x5a49deb1UL, 0x5742d0b8UL, 0x405fc2a3UL, 0x4d54ccaaUL, 0xdaf741ecUL, 0xd7fc4fe5UL, 0xc0e15dfeUL, 0xcdea53f7UL, 0xeedb79c8UL, 0xe3d077c1UL, 0xf4cd65daUL, 0xf9c66bd3UL, 0xb2af31a4UL, 0xbfa43fadUL, 0xa8b92db6UL, 0xa5b223bfUL, 0x86830980UL, 0x8b880789UL, 0x9c951592UL, 0x919e1b9bUL, 0x0a47a17cUL, 0x074caf75UL, 0x1051bd6eUL, 0x1d5ab367UL, 0x3e6b9958UL, 0x33609751UL, 0x247d854aUL, 0x29768b43UL, 0x621fd134UL, 0x6f14df3dUL, 0x7809cd26UL, 0x7502c32fUL, 0x5633e910UL, 0x5b38e719UL, 0x4c25f502UL, 0x412efb0bUL, 0x618c9ad7UL, 0x6c8794deUL, 0x7b9a86c5UL, 0x769188ccUL, 0x55a0a2f3UL, 0x58abacfaUL, 0x4fb6bee1UL, 0x42bdb0e8UL, 0x09d4ea9fUL, 0x04dfe496UL, 0x13c2f68dUL, 0x1ec9f884UL, 0x3df8d2bbUL, 0x30f3dcb2UL, 0x27eecea9UL, 0x2ae5c0a0UL, 0xb13c7a47UL, 0xbc37744eUL, 0xab2a6655UL, 0xa621685cUL, 0x85104263UL, 0x881b4c6aUL, 0x9f065e71UL, 0x920d5078UL, 0xd9640a0fUL, 0xd46f0406UL, 0xc372161dUL, 0xce791814UL, 0xed48322bUL, 0xe0433c22UL, 0xf75e2e39UL, 0xfa552030UL, 0xb701ec9aUL, 0xba0ae293UL, 0xad17f088UL, 0xa01cfe81UL, 0x832dd4beUL, 0x8e26dab7UL, 0x993bc8acUL, 0x9430c6a5UL, 0xdf599cd2UL, 0xd25292dbUL, 0xc54f80c0UL, 0xc8448ec9UL, 0xeb75a4f6UL, 0xe67eaaffUL, 0xf163b8e4UL, 0xfc68b6edUL, 0x67b10c0aUL, 0x6aba0203UL, 0x7da71018UL, 0x70ac1e11UL, 0x539d342eUL, 0x5e963a27UL, 0x498b283cUL, 0x44802635UL, 0x0fe97c42UL, 0x02e2724bUL, 0x15ff6050UL, 0x18f46e59UL, 0x3bc54466UL, 0x36ce4a6fUL, 0x21d35874UL, 0x2cd8567dUL, 0x0c7a37a1UL, 0x017139a8UL, 0x166c2bb3UL, 0x1b6725baUL, 0x38560f85UL, 0x355d018cUL, 0x22401397UL, 0x2f4b1d9eUL, 0x642247e9UL, 0x692949e0UL, 0x7e345bfbUL, 0x733f55f2UL, 0x500e7fcdUL, 0x5d0571c4UL, 0x4a1863dfUL, 0x47136dd6UL, 0xdccad731UL, 0xd1c1d938UL, 0xc6dccb23UL, 0xcbd7c52aUL, 0xe8e6ef15UL, 0xe5ede11cUL, 0xf2f0f307UL, 0xfffbfd0eUL, 0xb492a779UL, 0xb999a970UL, 0xae84bb6bUL, 0xa38fb562UL, 0x80be9f5dUL, 0x8db59154UL, 0x9aa8834fUL, 0x97a38d46UL }; static const ulong32 Tks3[] = { 0x00000000UL, 0x090d0b0eUL, 0x121a161cUL, 0x1b171d12UL, 0x24342c38UL, 0x2d392736UL, 0x362e3a24UL, 0x3f23312aUL, 0x48685870UL, 0x4165537eUL, 0x5a724e6cUL, 0x537f4562UL, 0x6c5c7448UL, 0x65517f46UL, 0x7e466254UL, 0x774b695aUL, 0x90d0b0e0UL, 0x99ddbbeeUL, 0x82caa6fcUL, 0x8bc7adf2UL, 0xb4e49cd8UL, 0xbde997d6UL, 0xa6fe8ac4UL, 0xaff381caUL, 0xd8b8e890UL, 0xd1b5e39eUL, 0xcaa2fe8cUL, 0xc3aff582UL, 0xfc8cc4a8UL, 0xf581cfa6UL, 0xee96d2b4UL, 0xe79bd9baUL, 0x3bbb7bdbUL, 0x32b670d5UL, 0x29a16dc7UL, 0x20ac66c9UL, 0x1f8f57e3UL, 0x16825cedUL, 0x0d9541ffUL, 0x04984af1UL, 0x73d323abUL, 0x7ade28a5UL, 0x61c935b7UL, 0x68c43eb9UL, 0x57e70f93UL, 0x5eea049dUL, 0x45fd198fUL, 0x4cf01281UL, 0xab6bcb3bUL, 0xa266c035UL, 0xb971dd27UL, 0xb07cd629UL, 0x8f5fe703UL, 0x8652ec0dUL, 0x9d45f11fUL, 0x9448fa11UL, 0xe303934bUL, 0xea0e9845UL, 0xf1198557UL, 0xf8148e59UL, 0xc737bf73UL, 0xce3ab47dUL, 0xd52da96fUL, 0xdc20a261UL, 0x766df6adUL, 0x7f60fda3UL, 0x6477e0b1UL, 0x6d7aebbfUL, 0x5259da95UL, 0x5b54d19bUL, 0x4043cc89UL, 0x494ec787UL, 0x3e05aeddUL, 0x3708a5d3UL, 0x2c1fb8c1UL, 0x2512b3cfUL, 0x1a3182e5UL, 0x133c89ebUL, 0x082b94f9UL, 0x01269ff7UL, 0xe6bd464dUL, 0xefb04d43UL, 0xf4a75051UL, 0xfdaa5b5fUL, 0xc2896a75UL, 0xcb84617bUL, 0xd0937c69UL, 0xd99e7767UL, 0xaed51e3dUL, 0xa7d81533UL, 0xbccf0821UL, 0xb5c2032fUL, 0x8ae13205UL, 0x83ec390bUL, 0x98fb2419UL, 0x91f62f17UL, 0x4dd68d76UL, 0x44db8678UL, 0x5fcc9b6aUL, 0x56c19064UL, 0x69e2a14eUL, 0x60efaa40UL, 0x7bf8b752UL, 0x72f5bc5cUL, 0x05bed506UL, 0x0cb3de08UL, 0x17a4c31aUL, 0x1ea9c814UL, 0x218af93eUL, 0x2887f230UL, 0x3390ef22UL, 0x3a9de42cUL, 0xdd063d96UL, 0xd40b3698UL, 0xcf1c2b8aUL, 0xc6112084UL, 0xf93211aeUL, 0xf03f1aa0UL, 0xeb2807b2UL, 0xe2250cbcUL, 0x956e65e6UL, 0x9c636ee8UL, 0x877473faUL, 0x8e7978f4UL, 0xb15a49deUL, 0xb85742d0UL, 0xa3405fc2UL, 0xaa4d54ccUL, 0xecdaf741UL, 0xe5d7fc4fUL, 0xfec0e15dUL, 0xf7cdea53UL, 0xc8eedb79UL, 0xc1e3d077UL, 0xdaf4cd65UL, 0xd3f9c66bUL, 0xa4b2af31UL, 0xadbfa43fUL, 0xb6a8b92dUL, 0xbfa5b223UL, 0x80868309UL, 0x898b8807UL, 0x929c9515UL, 0x9b919e1bUL, 0x7c0a47a1UL, 0x75074cafUL, 0x6e1051bdUL, 0x671d5ab3UL, 0x583e6b99UL, 0x51336097UL, 0x4a247d85UL, 0x4329768bUL, 0x34621fd1UL, 0x3d6f14dfUL, 0x267809cdUL, 0x2f7502c3UL, 0x105633e9UL, 0x195b38e7UL, 0x024c25f5UL, 0x0b412efbUL, 0xd7618c9aUL, 0xde6c8794UL, 0xc57b9a86UL, 0xcc769188UL, 0xf355a0a2UL, 0xfa58abacUL, 0xe14fb6beUL, 0xe842bdb0UL, 0x9f09d4eaUL, 0x9604dfe4UL, 0x8d13c2f6UL, 0x841ec9f8UL, 0xbb3df8d2UL, 0xb230f3dcUL, 0xa927eeceUL, 0xa02ae5c0UL, 0x47b13c7aUL, 0x4ebc3774UL, 0x55ab2a66UL, 0x5ca62168UL, 0x63851042UL, 0x6a881b4cUL, 0x719f065eUL, 0x78920d50UL, 0x0fd9640aUL, 0x06d46f04UL, 0x1dc37216UL, 0x14ce7918UL, 0x2bed4832UL, 0x22e0433cUL, 0x39f75e2eUL, 0x30fa5520UL, 0x9ab701ecUL, 0x93ba0ae2UL, 0x88ad17f0UL, 0x81a01cfeUL, 0xbe832dd4UL, 0xb78e26daUL, 0xac993bc8UL, 0xa59430c6UL, 0xd2df599cUL, 0xdbd25292UL, 0xc0c54f80UL, 0xc9c8448eUL, 0xf6eb75a4UL, 0xffe67eaaUL, 0xe4f163b8UL, 0xedfc68b6UL, 0x0a67b10cUL, 0x036aba02UL, 0x187da710UL, 0x1170ac1eUL, 0x2e539d34UL, 0x275e963aUL, 0x3c498b28UL, 0x35448026UL, 0x420fe97cUL, 0x4b02e272UL, 0x5015ff60UL, 0x5918f46eUL, 0x663bc544UL, 0x6f36ce4aUL, 0x7421d358UL, 0x7d2cd856UL, 0xa10c7a37UL, 0xa8017139UL, 0xb3166c2bUL, 0xba1b6725UL, 0x8538560fUL, 0x8c355d01UL, 0x97224013UL, 0x9e2f4b1dUL, 0xe9642247UL, 0xe0692949UL, 0xfb7e345bUL, 0xf2733f55UL, 0xcd500e7fUL, 0xc45d0571UL, 0xdf4a1863UL, 0xd647136dUL, 0x31dccad7UL, 0x38d1c1d9UL, 0x23c6dccbUL, 0x2acbd7c5UL, 0x15e8e6efUL, 0x1ce5ede1UL, 0x07f2f0f3UL, 0x0efffbfdUL, 0x79b492a7UL, 0x70b999a9UL, 0x6bae84bbUL, 0x62a38fb5UL, 0x5d80be9fUL, 0x548db591UL, 0x4f9aa883UL, 0x4697a38dUL }; #endif /* ENCRYPT_ONLY */ #endif /* SMALL CODE */ static const ulong32 rcon[] = { 0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL, 0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL, 0x1B000000UL, 0x36000000UL, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ }; /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/aes/aes_tab.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/ciphers/khazad.c0000644000175100001440000021313410621351501016361 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file khazad.c Khazad implementation derived from public domain source Authors: Paulo S.L.M. Barreto and Vincent Rijmen. */ #ifdef LTC_KHAZAD const struct ltc_cipher_descriptor khazad_desc = { "khazad", 18, 16, 16, 8, 8, &khazad_setup, &khazad_ecb_encrypt, &khazad_ecb_decrypt, &khazad_test, &khazad_done, &khazad_keysize, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; #define R 8 #define KEYSIZE 128 #define KEYSIZEB (KEYSIZE/8) #define BLOCKSIZE 64 #define BLOCKSIZEB (BLOCKSIZE/8) static const ulong64 T0[256] = { CONST64(0xbad3d268bbb96a01), CONST64(0x54fc4d19e59a66b1), CONST64(0x2f71bc93e26514cd), CONST64(0x749ccdb925871b51), CONST64(0x53f55102f7a257a4), CONST64(0xd3686bb8d0d6be03), CONST64(0xd26b6fbdd6deb504), CONST64(0x4dd72964b35285fe), CONST64(0x50f05d0dfdba4aad), CONST64(0xace98a26cf09e063), CONST64(0x8d8a0e83091c9684), CONST64(0xbfdcc679a5914d1a), CONST64(0x7090ddad3da7374d), CONST64(0x52f65507f1aa5ca3), CONST64(0x9ab352c87ba417e1), CONST64(0x4cd42d61b55a8ef9), CONST64(0xea238f65460320ac), CONST64(0xd56273a6c4e68411), CONST64(0x97a466f155cc68c2), CONST64(0xd16e63b2dcc6a80d), CONST64(0x3355ccffaa85d099), CONST64(0x51f35908fbb241aa), CONST64(0x5bed712ac7e20f9c), CONST64(0xa6f7a204f359ae55), CONST64(0xde7f5f81febec120), CONST64(0x48d83d75ad7aa2e5), CONST64(0xa8e59a32d729cc7f), CONST64(0x99b65ec771bc0ae8), CONST64(0xdb704b90e096e63b), CONST64(0x3256c8faac8ddb9e), CONST64(0xb7c4e65195d11522), CONST64(0xfc19d72b32b3aace), CONST64(0xe338ab48704b7393), CONST64(0x9ebf42dc63843bfd), CONST64(0x91ae7eef41fc52d0), CONST64(0x9bb056cd7dac1ce6), CONST64(0xe23baf4d76437894), CONST64(0xbbd0d66dbdb16106), CONST64(0x41c319589b32f1da), CONST64(0x6eb2a5cb7957e517), CONST64(0xa5f2ae0bf941b35c), CONST64(0xcb400bc08016564b), CONST64(0x6bbdb1da677fc20c), CONST64(0x95a26efb59dc7ecc), CONST64(0xa1febe1fe1619f40), CONST64(0xf308eb1810cbc3e3), CONST64(0xb1cefe4f81e12f30), CONST64(0x0206080a0c10160e), CONST64(0xcc4917db922e675e), CONST64(0xc45137f3a26e3f66), CONST64(0x1d2774694ee8cf53), CONST64(0x143c504478a09c6c), CONST64(0xc3582be8b0560e73), CONST64(0x63a591f2573f9a34), CONST64(0xda734f95e69eed3c), CONST64(0x5de76934d3d2358e), CONST64(0x5fe1613edfc22380), CONST64(0xdc79578bf2aed72e), CONST64(0x7d87e99413cf486e), CONST64(0xcd4a13de94266c59), CONST64(0x7f81e19e1fdf5e60), CONST64(0x5aee752fc1ea049b), CONST64(0x6cb4adc17547f319), CONST64(0x5ce46d31d5da3e89), CONST64(0xf704fb0c08ebefff), CONST64(0x266a98bed42d47f2), CONST64(0xff1cdb2438abb7c7), CONST64(0xed2a937e543b11b9), CONST64(0xe825876f4a1336a2), CONST64(0x9dba4ed3699c26f4), CONST64(0x6fb1a1ce7f5fee10), CONST64(0x8e8f028c03048b8d), CONST64(0x192b647d56c8e34f), CONST64(0xa0fdba1ae7699447), CONST64(0xf00de7171ad3deea), CONST64(0x89861e97113cba98), CONST64(0x0f113c332278692d), CONST64(0x07091c1b12383115), CONST64(0xafec8629c511fd6a), CONST64(0xfb10cb30208b9bdb), CONST64(0x0818202830405838), CONST64(0x153f54417ea8976b), CONST64(0x0d1734392e687f23), CONST64(0x040c101418202c1c), CONST64(0x0103040506080b07), CONST64(0x64ac8de94507ab21), CONST64(0xdf7c5b84f8b6ca27), CONST64(0x769ac5b329970d5f), CONST64(0x798bf9800bef6472), CONST64(0xdd7a538ef4a6dc29), CONST64(0x3d47f4c98ef5b2b3), CONST64(0x163a584e74b08a62), CONST64(0x3f41fcc382e5a4bd), CONST64(0x3759dcebb2a5fc85), CONST64(0x6db7a9c4734ff81e), CONST64(0x3848e0d890dd95a8), CONST64(0xb9d6de67b1a17708), CONST64(0x7395d1a237bf2a44), CONST64(0xe926836a4c1b3da5), CONST64(0x355fd4e1beb5ea8b), CONST64(0x55ff491ce3926db6), CONST64(0x7193d9a83baf3c4a), CONST64(0x7b8df18a07ff727c), CONST64(0x8c890a860f149d83), CONST64(0x7296d5a731b72143), CONST64(0x88851a921734b19f), CONST64(0xf607ff090ee3e4f8), CONST64(0x2a7ea882fc4d33d6), CONST64(0x3e42f8c684edafba), CONST64(0x5ee2653bd9ca2887), CONST64(0x27699cbbd2254cf5), CONST64(0x46ca0543890ac0cf), CONST64(0x0c14303c28607424), CONST64(0x65af89ec430fa026), CONST64(0x68b8bdd56d67df05), CONST64(0x61a399f85b2f8c3a), CONST64(0x03050c0f0a181d09), CONST64(0xc15e23e2bc46187d), CONST64(0x57f94116ef827bb8), CONST64(0xd6677fa9cefe9918), CONST64(0xd976439aec86f035), CONST64(0x58e87d25cdfa1295), CONST64(0xd875479fea8efb32), CONST64(0x66aa85e34917bd2f), CONST64(0xd7647bacc8f6921f), CONST64(0x3a4ee8d29ccd83a6), CONST64(0xc84507cf8a0e4b42), CONST64(0x3c44f0cc88fdb9b4), CONST64(0xfa13cf35268390dc), CONST64(0x96a762f453c463c5), CONST64(0xa7f4a601f551a552), CONST64(0x98b55ac277b401ef), CONST64(0xec29977b52331abe), CONST64(0xb8d5da62b7a97c0f), CONST64(0xc7543bfca876226f), CONST64(0xaeef822cc319f66d), CONST64(0x69bbb9d06b6fd402), CONST64(0x4bdd317aa762bfec), CONST64(0xabe0963ddd31d176), CONST64(0xa9e69e37d121c778), CONST64(0x67a981e64f1fb628), CONST64(0x0a1e28223c504e36), CONST64(0x47c901468f02cbc8), CONST64(0xf20bef1d16c3c8e4), CONST64(0xb5c2ee5b99c1032c), CONST64(0x226688aacc0d6bee), CONST64(0xe532b356647b4981), CONST64(0xee2f9f715e230cb0), CONST64(0xbedfc27ca399461d), CONST64(0x2b7dac87fa4538d1), CONST64(0x819e3ebf217ce2a0), CONST64(0x1236485a6c90a67e), CONST64(0x839836b52d6cf4ae), CONST64(0x1b2d6c775ad8f541), CONST64(0x0e1238362470622a), CONST64(0x23658cafca0560e9), CONST64(0xf502f30604fbf9f1), CONST64(0x45cf094c8312ddc6), CONST64(0x216384a5c61576e7), CONST64(0xce4f1fd19e3e7150), CONST64(0x49db3970ab72a9e2), CONST64(0x2c74b09ce87d09c4), CONST64(0xf916c33a2c9b8dd5), CONST64(0xe637bf596e635488), CONST64(0xb6c7e25493d91e25), CONST64(0x2878a088f05d25d8), CONST64(0x17395c4b72b88165), CONST64(0x829b32b02b64ffa9), CONST64(0x1a2e68725cd0fe46), CONST64(0x8b80169d1d2cac96), CONST64(0xfe1fdf213ea3bcc0), CONST64(0x8a8312981b24a791), CONST64(0x091b242d3648533f), CONST64(0xc94603ca8c064045), CONST64(0x879426a1354cd8b2), CONST64(0x4ed2256bb94a98f7), CONST64(0xe13ea3427c5b659d), CONST64(0x2e72b896e46d1fca), CONST64(0xe431b75362734286), CONST64(0xe03da7477a536e9a), CONST64(0xeb208b60400b2bab), CONST64(0x90ad7aea47f459d7), CONST64(0xa4f1aa0eff49b85b), CONST64(0x1e22786644f0d25a), CONST64(0x85922eab395ccebc), CONST64(0x60a09dfd5d27873d), CONST64(0x0000000000000000), CONST64(0x256f94b1de355afb), CONST64(0xf401f70302f3f2f6), CONST64(0xf10ee3121cdbd5ed), CONST64(0x94a16afe5fd475cb), CONST64(0x0b1d2c273a584531), CONST64(0xe734bb5c686b5f8f), CONST64(0x759fc9bc238f1056), CONST64(0xef2c9b74582b07b7), CONST64(0x345cd0e4b8bde18c), CONST64(0x3153c4f5a695c697), CONST64(0xd46177a3c2ee8f16), CONST64(0xd06d67b7dacea30a), CONST64(0x869722a43344d3b5), CONST64(0x7e82e59b19d75567), CONST64(0xadea8e23c901eb64), CONST64(0xfd1ad32e34bba1c9), CONST64(0x297ba48df6552edf), CONST64(0x3050c0f0a09dcd90), CONST64(0x3b4decd79ac588a1), CONST64(0x9fbc46d9658c30fa), CONST64(0xf815c73f2a9386d2), CONST64(0xc6573ff9ae7e2968), CONST64(0x13354c5f6a98ad79), CONST64(0x060a181e14303a12), CONST64(0x050f14111e28271b), CONST64(0xc55233f6a4663461), CONST64(0x113344556688bb77), CONST64(0x7799c1b62f9f0658), CONST64(0x7c84ed9115c74369), CONST64(0x7a8ef58f01f7797b), CONST64(0x7888fd850de76f75), CONST64(0x365ad8eeb4adf782), CONST64(0x1c24706c48e0c454), CONST64(0x394be4dd96d59eaf), CONST64(0x59eb7920cbf21992), CONST64(0x1828607850c0e848), CONST64(0x56fa4513e98a70bf), CONST64(0xb3c8f6458df1393e), CONST64(0xb0cdfa4a87e92437), CONST64(0x246c90b4d83d51fc), CONST64(0x206080a0c01d7de0), CONST64(0xb2cbf2408bf93239), CONST64(0x92ab72e04be44fd9), CONST64(0xa3f8b615ed71894e), CONST64(0xc05d27e7ba4e137a), CONST64(0x44cc0d49851ad6c1), CONST64(0x62a695f751379133), CONST64(0x103040506080b070), CONST64(0xb4c1ea5e9fc9082b), CONST64(0x84912aae3f54c5bb), CONST64(0x43c511529722e7d4), CONST64(0x93a876e54dec44de), CONST64(0xc25b2fedb65e0574), CONST64(0x4ade357fa16ab4eb), CONST64(0xbddace73a9815b14), CONST64(0x8f8c0689050c808a), CONST64(0x2d77b499ee7502c3), CONST64(0xbcd9ca76af895013), CONST64(0x9cb94ad66f942df3), CONST64(0x6abeb5df6177c90b), CONST64(0x40c01d5d9d3afadd), CONST64(0xcf4c1bd498367a57), CONST64(0xa2fbb210eb798249), CONST64(0x809d3aba2774e9a7), CONST64(0x4fd1216ebf4293f0), CONST64(0x1f217c6342f8d95d), CONST64(0xca430fc5861e5d4c), CONST64(0xaae39238db39da71), CONST64(0x42c61557912aecd3), }; static const ulong64 T1[256] = { CONST64(0xd3ba68d2b9bb016a), CONST64(0xfc54194d9ae5b166), CONST64(0x712f93bc65e2cd14), CONST64(0x9c74b9cd8725511b), CONST64(0xf5530251a2f7a457), CONST64(0x68d3b86bd6d003be), CONST64(0x6bd2bd6fded604b5), CONST64(0xd74d642952b3fe85), CONST64(0xf0500d5dbafdad4a), CONST64(0xe9ac268a09cf63e0), CONST64(0x8a8d830e1c098496), CONST64(0xdcbf79c691a51a4d), CONST64(0x9070addda73d4d37), CONST64(0xf6520755aaf1a35c), CONST64(0xb39ac852a47be117), CONST64(0xd44c612d5ab5f98e), CONST64(0x23ea658f0346ac20), CONST64(0x62d5a673e6c41184), CONST64(0xa497f166cc55c268), CONST64(0x6ed1b263c6dc0da8), CONST64(0x5533ffcc85aa99d0), CONST64(0xf3510859b2fbaa41), CONST64(0xed5b2a71e2c79c0f), CONST64(0xf7a604a259f355ae), CONST64(0x7fde815fbefe20c1), CONST64(0xd848753d7aade5a2), CONST64(0xe5a8329a29d77fcc), CONST64(0xb699c75ebc71e80a), CONST64(0x70db904b96e03be6), CONST64(0x5632fac88dac9edb), CONST64(0xc4b751e6d1952215), CONST64(0x19fc2bd7b332ceaa), CONST64(0x38e348ab4b709373), CONST64(0xbf9edc428463fd3b), CONST64(0xae91ef7efc41d052), CONST64(0xb09bcd56ac7de61c), CONST64(0x3be24daf43769478), CONST64(0xd0bb6dd6b1bd0661), CONST64(0xc3415819329bdaf1), CONST64(0xb26ecba5577917e5), CONST64(0xf2a50bae41f95cb3), CONST64(0x40cbc00b16804b56), CONST64(0xbd6bdab17f670cc2), CONST64(0xa295fb6edc59cc7e), CONST64(0xfea11fbe61e1409f), CONST64(0x08f318ebcb10e3c3), CONST64(0xceb14ffee181302f), CONST64(0x06020a08100c0e16), CONST64(0x49ccdb172e925e67), CONST64(0x51c4f3376ea2663f), CONST64(0x271d6974e84e53cf), CONST64(0x3c144450a0786c9c), CONST64(0x58c3e82b56b0730e), CONST64(0xa563f2913f57349a), CONST64(0x73da954f9ee63ced), CONST64(0xe75d3469d2d38e35), CONST64(0xe15f3e61c2df8023), CONST64(0x79dc8b57aef22ed7), CONST64(0x877d94e9cf136e48), CONST64(0x4acdde132694596c), CONST64(0x817f9ee1df1f605e), CONST64(0xee5a2f75eac19b04), CONST64(0xb46cc1ad477519f3), CONST64(0xe45c316ddad5893e), CONST64(0x04f70cfbeb08ffef), CONST64(0x6a26be982dd4f247), CONST64(0x1cff24dbab38c7b7), CONST64(0x2aed7e933b54b911), CONST64(0x25e86f87134aa236), CONST64(0xba9dd34e9c69f426), CONST64(0xb16fcea15f7f10ee), CONST64(0x8f8e8c0204038d8b), CONST64(0x2b197d64c8564fe3), CONST64(0xfda01aba69e74794), CONST64(0x0df017e7d31aeade), CONST64(0x8689971e3c1198ba), CONST64(0x110f333c78222d69), CONST64(0x09071b1c38121531), CONST64(0xecaf298611c56afd), CONST64(0x10fb30cb8b20db9b), CONST64(0x1808282040303858), CONST64(0x3f154154a87e6b97), CONST64(0x170d3934682e237f), CONST64(0x0c04141020181c2c), CONST64(0x030105040806070b), CONST64(0xac64e98d074521ab), CONST64(0x7cdf845bb6f827ca), CONST64(0x9a76b3c597295f0d), CONST64(0x8b7980f9ef0b7264), CONST64(0x7add8e53a6f429dc), CONST64(0x473dc9f4f58eb3b2), CONST64(0x3a164e58b074628a), CONST64(0x413fc3fce582bda4), CONST64(0x5937ebdca5b285fc), CONST64(0xb76dc4a94f731ef8), CONST64(0x4838d8e0dd90a895), CONST64(0xd6b967dea1b10877), CONST64(0x9573a2d1bf37442a), CONST64(0x26e96a831b4ca53d), CONST64(0x5f35e1d4b5be8bea), CONST64(0xff551c4992e3b66d), CONST64(0x9371a8d9af3b4a3c), CONST64(0x8d7b8af1ff077c72), CONST64(0x898c860a140f839d), CONST64(0x9672a7d5b7314321), CONST64(0x8588921a34179fb1), CONST64(0x07f609ffe30ef8e4), CONST64(0x7e2a82a84dfcd633), CONST64(0x423ec6f8ed84baaf), CONST64(0xe25e3b65cad98728), CONST64(0x6927bb9c25d2f54c), CONST64(0xca4643050a89cfc0), CONST64(0x140c3c3060282474), CONST64(0xaf65ec890f4326a0), CONST64(0xb868d5bd676d05df), CONST64(0xa361f8992f5b3a8c), CONST64(0x05030f0c180a091d), CONST64(0x5ec1e22346bc7d18), CONST64(0xf957164182efb87b), CONST64(0x67d6a97ffece1899), CONST64(0x76d99a4386ec35f0), CONST64(0xe858257dfacd9512), CONST64(0x75d89f478eea32fb), CONST64(0xaa66e38517492fbd), CONST64(0x64d7ac7bf6c81f92), CONST64(0x4e3ad2e8cd9ca683), CONST64(0x45c8cf070e8a424b), CONST64(0x443cccf0fd88b4b9), CONST64(0x13fa35cf8326dc90), CONST64(0xa796f462c453c563), CONST64(0xf4a701a651f552a5), CONST64(0xb598c25ab477ef01), CONST64(0x29ec7b973352be1a), CONST64(0xd5b862daa9b70f7c), CONST64(0x54c7fc3b76a86f22), CONST64(0xefae2c8219c36df6), CONST64(0xbb69d0b96f6b02d4), CONST64(0xdd4b7a3162a7ecbf), CONST64(0xe0ab3d9631dd76d1), CONST64(0xe6a9379e21d178c7), CONST64(0xa967e6811f4f28b6), CONST64(0x1e0a2228503c364e), CONST64(0xc9474601028fc8cb), CONST64(0x0bf21defc316e4c8), CONST64(0xc2b55beec1992c03), CONST64(0x6622aa880dccee6b), CONST64(0x32e556b37b648149), CONST64(0x2fee719f235eb00c), CONST64(0xdfbe7cc299a31d46), CONST64(0x7d2b87ac45fad138), CONST64(0x9e81bf3e7c21a0e2), CONST64(0x36125a48906c7ea6), CONST64(0x9883b5366c2daef4), CONST64(0x2d1b776cd85a41f5), CONST64(0x120e363870242a62), CONST64(0x6523af8c05cae960), CONST64(0x02f506f3fb04f1f9), CONST64(0xcf454c091283c6dd), CONST64(0x6321a58415c6e776), CONST64(0x4fced11f3e9e5071), CONST64(0xdb49703972abe2a9), CONST64(0x742c9cb07de8c409), CONST64(0x16f93ac39b2cd58d), CONST64(0x37e659bf636e8854), CONST64(0xc7b654e2d993251e), CONST64(0x782888a05df0d825), CONST64(0x39174b5cb8726581), CONST64(0x9b82b032642ba9ff), CONST64(0x2e1a7268d05c46fe), CONST64(0x808b9d162c1d96ac), CONST64(0x1ffe21dfa33ec0bc), CONST64(0x838a9812241b91a7), CONST64(0x1b092d2448363f53), CONST64(0x46c9ca03068c4540), CONST64(0x9487a1264c35b2d8), CONST64(0xd24e6b254ab9f798), CONST64(0x3ee142a35b7c9d65), CONST64(0x722e96b86de4ca1f), CONST64(0x31e453b773628642), CONST64(0x3de047a7537a9a6e), CONST64(0x20eb608b0b40ab2b), CONST64(0xad90ea7af447d759), CONST64(0xf1a40eaa49ff5bb8), CONST64(0x221e6678f0445ad2), CONST64(0x9285ab2e5c39bcce), CONST64(0xa060fd9d275d3d87), CONST64(0x0000000000000000), CONST64(0x6f25b19435defb5a), CONST64(0x01f403f7f302f6f2), CONST64(0x0ef112e3db1cedd5), CONST64(0xa194fe6ad45fcb75), CONST64(0x1d0b272c583a3145), CONST64(0x34e75cbb6b688f5f), CONST64(0x9f75bcc98f235610), CONST64(0x2cef749b2b58b707), CONST64(0x5c34e4d0bdb88ce1), CONST64(0x5331f5c495a697c6), CONST64(0x61d4a377eec2168f), CONST64(0x6dd0b767ceda0aa3), CONST64(0x9786a4224433b5d3), CONST64(0x827e9be5d7196755), CONST64(0xeaad238e01c964eb), CONST64(0x1afd2ed3bb34c9a1), CONST64(0x7b298da455f6df2e), CONST64(0x5030f0c09da090cd), CONST64(0x4d3bd7ecc59aa188), CONST64(0xbc9fd9468c65fa30), CONST64(0x15f83fc7932ad286), CONST64(0x57c6f93f7eae6829), CONST64(0x35135f4c986a79ad), CONST64(0x0a061e183014123a), CONST64(0x0f051114281e1b27), CONST64(0x52c5f63366a46134), CONST64(0x33115544886677bb), CONST64(0x9977b6c19f2f5806), CONST64(0x847c91edc7156943), CONST64(0x8e7a8ff5f7017b79), CONST64(0x887885fde70d756f), CONST64(0x5a36eed8adb482f7), CONST64(0x241c6c70e04854c4), CONST64(0x4b39dde4d596af9e), CONST64(0xeb592079f2cb9219), CONST64(0x28187860c05048e8), CONST64(0xfa5613458ae9bf70), CONST64(0xc8b345f6f18d3e39), CONST64(0xcdb04afae9873724), CONST64(0x6c24b4903dd8fc51), CONST64(0x6020a0801dc0e07d), CONST64(0xcbb240f2f98b3932), CONST64(0xab92e072e44bd94f), CONST64(0xf8a315b671ed4e89), CONST64(0x5dc0e7274eba7a13), CONST64(0xcc44490d1a85c1d6), CONST64(0xa662f79537513391), CONST64(0x30105040806070b0), CONST64(0xc1b45eeac99f2b08), CONST64(0x9184ae2a543fbbc5), CONST64(0xc54352112297d4e7), CONST64(0xa893e576ec4dde44), CONST64(0x5bc2ed2f5eb67405), CONST64(0xde4a7f356aa1ebb4), CONST64(0xdabd73ce81a9145b), CONST64(0x8c8f89060c058a80), CONST64(0x772d99b475eec302), CONST64(0xd9bc76ca89af1350), CONST64(0xb99cd64a946ff32d), CONST64(0xbe6adfb577610bc9), CONST64(0xc0405d1d3a9dddfa), CONST64(0x4ccfd41b3698577a), CONST64(0xfba210b279eb4982), CONST64(0x9d80ba3a7427a7e9), CONST64(0xd14f6e2142bff093), CONST64(0x211f637cf8425dd9), CONST64(0x43cac50f1e864c5d), CONST64(0xe3aa389239db71da), CONST64(0xc64257152a91d3ec), }; static const ulong64 T2[256] = { CONST64(0xd268bad36a01bbb9), CONST64(0x4d1954fc66b1e59a), CONST64(0xbc932f7114cde265), CONST64(0xcdb9749c1b512587), CONST64(0x510253f557a4f7a2), CONST64(0x6bb8d368be03d0d6), CONST64(0x6fbdd26bb504d6de), CONST64(0x29644dd785feb352), CONST64(0x5d0d50f04aadfdba), CONST64(0x8a26ace9e063cf09), CONST64(0x0e838d8a9684091c), CONST64(0xc679bfdc4d1aa591), CONST64(0xddad7090374d3da7), CONST64(0x550752f65ca3f1aa), CONST64(0x52c89ab317e17ba4), CONST64(0x2d614cd48ef9b55a), CONST64(0x8f65ea2320ac4603), CONST64(0x73a6d5628411c4e6), CONST64(0x66f197a468c255cc), CONST64(0x63b2d16ea80ddcc6), CONST64(0xccff3355d099aa85), CONST64(0x590851f341aafbb2), CONST64(0x712a5bed0f9cc7e2), CONST64(0xa204a6f7ae55f359), CONST64(0x5f81de7fc120febe), CONST64(0x3d7548d8a2e5ad7a), CONST64(0x9a32a8e5cc7fd729), CONST64(0x5ec799b60ae871bc), CONST64(0x4b90db70e63be096), CONST64(0xc8fa3256db9eac8d), CONST64(0xe651b7c4152295d1), CONST64(0xd72bfc19aace32b3), CONST64(0xab48e3387393704b), CONST64(0x42dc9ebf3bfd6384), CONST64(0x7eef91ae52d041fc), CONST64(0x56cd9bb01ce67dac), CONST64(0xaf4de23b78947643), CONST64(0xd66dbbd06106bdb1), CONST64(0x195841c3f1da9b32), CONST64(0xa5cb6eb2e5177957), CONST64(0xae0ba5f2b35cf941), CONST64(0x0bc0cb40564b8016), CONST64(0xb1da6bbdc20c677f), CONST64(0x6efb95a27ecc59dc), CONST64(0xbe1fa1fe9f40e161), CONST64(0xeb18f308c3e310cb), CONST64(0xfe4fb1ce2f3081e1), CONST64(0x080a0206160e0c10), CONST64(0x17dbcc49675e922e), CONST64(0x37f3c4513f66a26e), CONST64(0x74691d27cf534ee8), CONST64(0x5044143c9c6c78a0), CONST64(0x2be8c3580e73b056), CONST64(0x91f263a59a34573f), CONST64(0x4f95da73ed3ce69e), CONST64(0x69345de7358ed3d2), CONST64(0x613e5fe12380dfc2), CONST64(0x578bdc79d72ef2ae), CONST64(0xe9947d87486e13cf), CONST64(0x13decd4a6c599426), CONST64(0xe19e7f815e601fdf), CONST64(0x752f5aee049bc1ea), CONST64(0xadc16cb4f3197547), CONST64(0x6d315ce43e89d5da), CONST64(0xfb0cf704efff08eb), CONST64(0x98be266a47f2d42d), CONST64(0xdb24ff1cb7c738ab), CONST64(0x937eed2a11b9543b), CONST64(0x876fe82536a24a13), CONST64(0x4ed39dba26f4699c), CONST64(0xa1ce6fb1ee107f5f), CONST64(0x028c8e8f8b8d0304), CONST64(0x647d192be34f56c8), CONST64(0xba1aa0fd9447e769), CONST64(0xe717f00ddeea1ad3), CONST64(0x1e978986ba98113c), CONST64(0x3c330f11692d2278), CONST64(0x1c1b070931151238), CONST64(0x8629afecfd6ac511), CONST64(0xcb30fb109bdb208b), CONST64(0x2028081858383040), CONST64(0x5441153f976b7ea8), CONST64(0x34390d177f232e68), CONST64(0x1014040c2c1c1820), CONST64(0x040501030b070608), CONST64(0x8de964acab214507), CONST64(0x5b84df7cca27f8b6), CONST64(0xc5b3769a0d5f2997), CONST64(0xf980798b64720bef), CONST64(0x538edd7adc29f4a6), CONST64(0xf4c93d47b2b38ef5), CONST64(0x584e163a8a6274b0), CONST64(0xfcc33f41a4bd82e5), CONST64(0xdceb3759fc85b2a5), CONST64(0xa9c46db7f81e734f), CONST64(0xe0d8384895a890dd), CONST64(0xde67b9d67708b1a1), CONST64(0xd1a273952a4437bf), CONST64(0x836ae9263da54c1b), CONST64(0xd4e1355fea8bbeb5), CONST64(0x491c55ff6db6e392), CONST64(0xd9a871933c4a3baf), CONST64(0xf18a7b8d727c07ff), CONST64(0x0a868c899d830f14), CONST64(0xd5a77296214331b7), CONST64(0x1a928885b19f1734), CONST64(0xff09f607e4f80ee3), CONST64(0xa8822a7e33d6fc4d), CONST64(0xf8c63e42afba84ed), CONST64(0x653b5ee22887d9ca), CONST64(0x9cbb27694cf5d225), CONST64(0x054346cac0cf890a), CONST64(0x303c0c1474242860), CONST64(0x89ec65afa026430f), CONST64(0xbdd568b8df056d67), CONST64(0x99f861a38c3a5b2f), CONST64(0x0c0f03051d090a18), CONST64(0x23e2c15e187dbc46), CONST64(0x411657f97bb8ef82), CONST64(0x7fa9d6679918cefe), CONST64(0x439ad976f035ec86), CONST64(0x7d2558e81295cdfa), CONST64(0x479fd875fb32ea8e), CONST64(0x85e366aabd2f4917), CONST64(0x7bacd764921fc8f6), CONST64(0xe8d23a4e83a69ccd), CONST64(0x07cfc8454b428a0e), CONST64(0xf0cc3c44b9b488fd), CONST64(0xcf35fa1390dc2683), CONST64(0x62f496a763c553c4), CONST64(0xa601a7f4a552f551), CONST64(0x5ac298b501ef77b4), CONST64(0x977bec291abe5233), CONST64(0xda62b8d57c0fb7a9), CONST64(0x3bfcc754226fa876), CONST64(0x822caeeff66dc319), CONST64(0xb9d069bbd4026b6f), CONST64(0x317a4bddbfeca762), CONST64(0x963dabe0d176dd31), CONST64(0x9e37a9e6c778d121), CONST64(0x81e667a9b6284f1f), CONST64(0x28220a1e4e363c50), CONST64(0x014647c9cbc88f02), CONST64(0xef1df20bc8e416c3), CONST64(0xee5bb5c2032c99c1), CONST64(0x88aa22666beecc0d), CONST64(0xb356e5324981647b), CONST64(0x9f71ee2f0cb05e23), CONST64(0xc27cbedf461da399), CONST64(0xac872b7d38d1fa45), CONST64(0x3ebf819ee2a0217c), CONST64(0x485a1236a67e6c90), CONST64(0x36b58398f4ae2d6c), CONST64(0x6c771b2df5415ad8), CONST64(0x38360e12622a2470), CONST64(0x8caf236560e9ca05), CONST64(0xf306f502f9f104fb), CONST64(0x094c45cfddc68312), CONST64(0x84a5216376e7c615), CONST64(0x1fd1ce4f71509e3e), CONST64(0x397049dba9e2ab72), CONST64(0xb09c2c7409c4e87d), CONST64(0xc33af9168dd52c9b), CONST64(0xbf59e63754886e63), CONST64(0xe254b6c71e2593d9), CONST64(0xa088287825d8f05d), CONST64(0x5c4b1739816572b8), CONST64(0x32b0829bffa92b64), CONST64(0x68721a2efe465cd0), CONST64(0x169d8b80ac961d2c), CONST64(0xdf21fe1fbcc03ea3), CONST64(0x12988a83a7911b24), CONST64(0x242d091b533f3648), CONST64(0x03cac94640458c06), CONST64(0x26a18794d8b2354c), CONST64(0x256b4ed298f7b94a), CONST64(0xa342e13e659d7c5b), CONST64(0xb8962e721fcae46d), CONST64(0xb753e43142866273), CONST64(0xa747e03d6e9a7a53), CONST64(0x8b60eb202bab400b), CONST64(0x7aea90ad59d747f4), CONST64(0xaa0ea4f1b85bff49), CONST64(0x78661e22d25a44f0), CONST64(0x2eab8592cebc395c), CONST64(0x9dfd60a0873d5d27), CONST64(0x0000000000000000), CONST64(0x94b1256f5afbde35), CONST64(0xf703f401f2f602f3), CONST64(0xe312f10ed5ed1cdb), CONST64(0x6afe94a175cb5fd4), CONST64(0x2c270b1d45313a58), CONST64(0xbb5ce7345f8f686b), CONST64(0xc9bc759f1056238f), CONST64(0x9b74ef2c07b7582b), CONST64(0xd0e4345ce18cb8bd), CONST64(0xc4f53153c697a695), CONST64(0x77a3d4618f16c2ee), CONST64(0x67b7d06da30adace), CONST64(0x22a48697d3b53344), CONST64(0xe59b7e82556719d7), CONST64(0x8e23adeaeb64c901), CONST64(0xd32efd1aa1c934bb), CONST64(0xa48d297b2edff655), CONST64(0xc0f03050cd90a09d), CONST64(0xecd73b4d88a19ac5), CONST64(0x46d99fbc30fa658c), CONST64(0xc73ff81586d22a93), CONST64(0x3ff9c6572968ae7e), CONST64(0x4c5f1335ad796a98), CONST64(0x181e060a3a121430), CONST64(0x1411050f271b1e28), CONST64(0x33f6c5523461a466), CONST64(0x44551133bb776688), CONST64(0xc1b6779906582f9f), CONST64(0xed917c84436915c7), CONST64(0xf58f7a8e797b01f7), CONST64(0xfd8578886f750de7), CONST64(0xd8ee365af782b4ad), CONST64(0x706c1c24c45448e0), CONST64(0xe4dd394b9eaf96d5), CONST64(0x792059eb1992cbf2), CONST64(0x60781828e84850c0), CONST64(0x451356fa70bfe98a), CONST64(0xf645b3c8393e8df1), CONST64(0xfa4ab0cd243787e9), CONST64(0x90b4246c51fcd83d), CONST64(0x80a020607de0c01d), CONST64(0xf240b2cb32398bf9), CONST64(0x72e092ab4fd94be4), CONST64(0xb615a3f8894eed71), CONST64(0x27e7c05d137aba4e), CONST64(0x0d4944ccd6c1851a), CONST64(0x95f762a691335137), CONST64(0x40501030b0706080), CONST64(0xea5eb4c1082b9fc9), CONST64(0x2aae8491c5bb3f54), CONST64(0x115243c5e7d49722), CONST64(0x76e593a844de4dec), CONST64(0x2fedc25b0574b65e), CONST64(0x357f4adeb4eba16a), CONST64(0xce73bdda5b14a981), CONST64(0x06898f8c808a050c), CONST64(0xb4992d7702c3ee75), CONST64(0xca76bcd95013af89), CONST64(0x4ad69cb92df36f94), CONST64(0xb5df6abec90b6177), CONST64(0x1d5d40c0fadd9d3a), CONST64(0x1bd4cf4c7a579836), CONST64(0xb210a2fb8249eb79), CONST64(0x3aba809de9a72774), CONST64(0x216e4fd193f0bf42), CONST64(0x7c631f21d95d42f8), CONST64(0x0fc5ca435d4c861e), CONST64(0x9238aae3da71db39), CONST64(0x155742c6ecd3912a), }; static const ulong64 T3[256] = { CONST64(0x68d2d3ba016ab9bb), CONST64(0x194dfc54b1669ae5), CONST64(0x93bc712fcd1465e2), CONST64(0xb9cd9c74511b8725), CONST64(0x0251f553a457a2f7), CONST64(0xb86b68d303bed6d0), CONST64(0xbd6f6bd204b5ded6), CONST64(0x6429d74dfe8552b3), CONST64(0x0d5df050ad4abafd), CONST64(0x268ae9ac63e009cf), CONST64(0x830e8a8d84961c09), CONST64(0x79c6dcbf1a4d91a5), CONST64(0xaddd90704d37a73d), CONST64(0x0755f652a35caaf1), CONST64(0xc852b39ae117a47b), CONST64(0x612dd44cf98e5ab5), CONST64(0x658f23eaac200346), CONST64(0xa67362d51184e6c4), CONST64(0xf166a497c268cc55), CONST64(0xb2636ed10da8c6dc), CONST64(0xffcc553399d085aa), CONST64(0x0859f351aa41b2fb), CONST64(0x2a71ed5b9c0fe2c7), CONST64(0x04a2f7a655ae59f3), CONST64(0x815f7fde20c1befe), CONST64(0x753dd848e5a27aad), CONST64(0x329ae5a87fcc29d7), CONST64(0xc75eb699e80abc71), CONST64(0x904b70db3be696e0), CONST64(0xfac856329edb8dac), CONST64(0x51e6c4b72215d195), CONST64(0x2bd719fcceaab332), CONST64(0x48ab38e393734b70), CONST64(0xdc42bf9efd3b8463), CONST64(0xef7eae91d052fc41), CONST64(0xcd56b09be61cac7d), CONST64(0x4daf3be294784376), CONST64(0x6dd6d0bb0661b1bd), CONST64(0x5819c341daf1329b), CONST64(0xcba5b26e17e55779), CONST64(0x0baef2a55cb341f9), CONST64(0xc00b40cb4b561680), CONST64(0xdab1bd6b0cc27f67), CONST64(0xfb6ea295cc7edc59), CONST64(0x1fbefea1409f61e1), CONST64(0x18eb08f3e3c3cb10), CONST64(0x4ffeceb1302fe181), CONST64(0x0a0806020e16100c), CONST64(0xdb1749cc5e672e92), CONST64(0xf33751c4663f6ea2), CONST64(0x6974271d53cfe84e), CONST64(0x44503c146c9ca078), CONST64(0xe82b58c3730e56b0), CONST64(0xf291a563349a3f57), CONST64(0x954f73da3ced9ee6), CONST64(0x3469e75d8e35d2d3), CONST64(0x3e61e15f8023c2df), CONST64(0x8b5779dc2ed7aef2), CONST64(0x94e9877d6e48cf13), CONST64(0xde134acd596c2694), CONST64(0x9ee1817f605edf1f), CONST64(0x2f75ee5a9b04eac1), CONST64(0xc1adb46c19f34775), CONST64(0x316de45c893edad5), CONST64(0x0cfb04f7ffefeb08), CONST64(0xbe986a26f2472dd4), CONST64(0x24db1cffc7b7ab38), CONST64(0x7e932aedb9113b54), CONST64(0x6f8725e8a236134a), CONST64(0xd34eba9df4269c69), CONST64(0xcea1b16f10ee5f7f), CONST64(0x8c028f8e8d8b0403), CONST64(0x7d642b194fe3c856), CONST64(0x1abafda0479469e7), CONST64(0x17e70df0eaded31a), CONST64(0x971e868998ba3c11), CONST64(0x333c110f2d697822), CONST64(0x1b1c090715313812), CONST64(0x2986ecaf6afd11c5), CONST64(0x30cb10fbdb9b8b20), CONST64(0x2820180838584030), CONST64(0x41543f156b97a87e), CONST64(0x3934170d237f682e), CONST64(0x14100c041c2c2018), CONST64(0x05040301070b0806), CONST64(0xe98dac6421ab0745), CONST64(0x845b7cdf27cab6f8), CONST64(0xb3c59a765f0d9729), CONST64(0x80f98b797264ef0b), CONST64(0x8e537add29dca6f4), CONST64(0xc9f4473db3b2f58e), CONST64(0x4e583a16628ab074), CONST64(0xc3fc413fbda4e582), CONST64(0xebdc593785fca5b2), CONST64(0xc4a9b76d1ef84f73), CONST64(0xd8e04838a895dd90), CONST64(0x67ded6b90877a1b1), CONST64(0xa2d19573442abf37), CONST64(0x6a8326e9a53d1b4c), CONST64(0xe1d45f358beab5be), CONST64(0x1c49ff55b66d92e3), CONST64(0xa8d993714a3caf3b), CONST64(0x8af18d7b7c72ff07), CONST64(0x860a898c839d140f), CONST64(0xa7d596724321b731), CONST64(0x921a85889fb13417), CONST64(0x09ff07f6f8e4e30e), CONST64(0x82a87e2ad6334dfc), CONST64(0xc6f8423ebaafed84), CONST64(0x3b65e25e8728cad9), CONST64(0xbb9c6927f54c25d2), CONST64(0x4305ca46cfc00a89), CONST64(0x3c30140c24746028), CONST64(0xec89af6526a00f43), CONST64(0xd5bdb86805df676d), CONST64(0xf899a3613a8c2f5b), CONST64(0x0f0c0503091d180a), CONST64(0xe2235ec17d1846bc), CONST64(0x1641f957b87b82ef), CONST64(0xa97f67d61899fece), CONST64(0x9a4376d935f086ec), CONST64(0x257de8589512facd), CONST64(0x9f4775d832fb8eea), CONST64(0xe385aa662fbd1749), CONST64(0xac7b64d71f92f6c8), CONST64(0xd2e84e3aa683cd9c), CONST64(0xcf0745c8424b0e8a), CONST64(0xccf0443cb4b9fd88), CONST64(0x35cf13fadc908326), CONST64(0xf462a796c563c453), CONST64(0x01a6f4a752a551f5), CONST64(0xc25ab598ef01b477), CONST64(0x7b9729ecbe1a3352), CONST64(0x62dad5b80f7ca9b7), CONST64(0xfc3b54c76f2276a8), CONST64(0x2c82efae6df619c3), CONST64(0xd0b9bb6902d46f6b), CONST64(0x7a31dd4becbf62a7), CONST64(0x3d96e0ab76d131dd), CONST64(0x379ee6a978c721d1), CONST64(0xe681a96728b61f4f), CONST64(0x22281e0a364e503c), CONST64(0x4601c947c8cb028f), CONST64(0x1def0bf2e4c8c316), CONST64(0x5beec2b52c03c199), CONST64(0xaa886622ee6b0dcc), CONST64(0x56b332e581497b64), CONST64(0x719f2feeb00c235e), CONST64(0x7cc2dfbe1d4699a3), CONST64(0x87ac7d2bd13845fa), CONST64(0xbf3e9e81a0e27c21), CONST64(0x5a4836127ea6906c), CONST64(0xb5369883aef46c2d), CONST64(0x776c2d1b41f5d85a), CONST64(0x3638120e2a627024), CONST64(0xaf8c6523e96005ca), CONST64(0x06f302f5f1f9fb04), CONST64(0x4c09cf45c6dd1283), CONST64(0xa5846321e77615c6), CONST64(0xd11f4fce50713e9e), CONST64(0x7039db49e2a972ab), CONST64(0x9cb0742cc4097de8), CONST64(0x3ac316f9d58d9b2c), CONST64(0x59bf37e68854636e), CONST64(0x54e2c7b6251ed993), CONST64(0x88a07828d8255df0), CONST64(0x4b5c39176581b872), CONST64(0xb0329b82a9ff642b), CONST64(0x72682e1a46fed05c), CONST64(0x9d16808b96ac2c1d), CONST64(0x21df1ffec0bca33e), CONST64(0x9812838a91a7241b), CONST64(0x2d241b093f534836), CONST64(0xca0346c94540068c), CONST64(0xa1269487b2d84c35), CONST64(0x6b25d24ef7984ab9), CONST64(0x42a33ee19d655b7c), CONST64(0x96b8722eca1f6de4), CONST64(0x53b731e486427362), CONST64(0x47a73de09a6e537a), CONST64(0x608b20ebab2b0b40), CONST64(0xea7aad90d759f447), CONST64(0x0eaaf1a45bb849ff), CONST64(0x6678221e5ad2f044), CONST64(0xab2e9285bcce5c39), CONST64(0xfd9da0603d87275d), CONST64(0x0000000000000000), CONST64(0xb1946f25fb5a35de), CONST64(0x03f701f4f6f2f302), CONST64(0x12e30ef1edd5db1c), CONST64(0xfe6aa194cb75d45f), CONST64(0x272c1d0b3145583a), CONST64(0x5cbb34e78f5f6b68), CONST64(0xbcc99f7556108f23), CONST64(0x749b2cefb7072b58), CONST64(0xe4d05c348ce1bdb8), CONST64(0xf5c4533197c695a6), CONST64(0xa37761d4168feec2), CONST64(0xb7676dd00aa3ceda), CONST64(0xa4229786b5d34433), CONST64(0x9be5827e6755d719), CONST64(0x238eeaad64eb01c9), CONST64(0x2ed31afdc9a1bb34), CONST64(0x8da47b29df2e55f6), CONST64(0xf0c0503090cd9da0), CONST64(0xd7ec4d3ba188c59a), CONST64(0xd946bc9ffa308c65), CONST64(0x3fc715f8d286932a), CONST64(0xf93f57c668297eae), CONST64(0x5f4c351379ad986a), CONST64(0x1e180a06123a3014), CONST64(0x11140f051b27281e), CONST64(0xf63352c5613466a4), CONST64(0x5544331177bb8866), CONST64(0xb6c1997758069f2f), CONST64(0x91ed847c6943c715), CONST64(0x8ff58e7a7b79f701), CONST64(0x85fd8878756fe70d), CONST64(0xeed85a3682f7adb4), CONST64(0x6c70241c54c4e048), CONST64(0xdde44b39af9ed596), CONST64(0x2079eb599219f2cb), CONST64(0x7860281848e8c050), CONST64(0x1345fa56bf708ae9), CONST64(0x45f6c8b33e39f18d), CONST64(0x4afacdb03724e987), CONST64(0xb4906c24fc513dd8), CONST64(0xa0806020e07d1dc0), CONST64(0x40f2cbb23932f98b), CONST64(0xe072ab92d94fe44b), CONST64(0x15b6f8a34e8971ed), CONST64(0xe7275dc07a134eba), CONST64(0x490dcc44c1d61a85), CONST64(0xf795a66233913751), CONST64(0x5040301070b08060), CONST64(0x5eeac1b42b08c99f), CONST64(0xae2a9184bbc5543f), CONST64(0x5211c543d4e72297), CONST64(0xe576a893de44ec4d), CONST64(0xed2f5bc274055eb6), CONST64(0x7f35de4aebb46aa1), CONST64(0x73cedabd145b81a9), CONST64(0x89068c8f8a800c05), CONST64(0x99b4772dc30275ee), CONST64(0x76cad9bc135089af), CONST64(0xd64ab99cf32d946f), CONST64(0xdfb5be6a0bc97761), CONST64(0x5d1dc040ddfa3a9d), CONST64(0xd41b4ccf577a3698), CONST64(0x10b2fba2498279eb), CONST64(0xba3a9d80a7e97427), CONST64(0x6e21d14ff09342bf), CONST64(0x637c211f5dd9f842), CONST64(0xc50f43ca4c5d1e86), CONST64(0x3892e3aa71da39db), CONST64(0x5715c642d3ec2a91), }; static const ulong64 T4[256] = { CONST64(0xbbb96a01bad3d268), CONST64(0xe59a66b154fc4d19), CONST64(0xe26514cd2f71bc93), CONST64(0x25871b51749ccdb9), CONST64(0xf7a257a453f55102), CONST64(0xd0d6be03d3686bb8), CONST64(0xd6deb504d26b6fbd), CONST64(0xb35285fe4dd72964), CONST64(0xfdba4aad50f05d0d), CONST64(0xcf09e063ace98a26), CONST64(0x091c96848d8a0e83), CONST64(0xa5914d1abfdcc679), CONST64(0x3da7374d7090ddad), CONST64(0xf1aa5ca352f65507), CONST64(0x7ba417e19ab352c8), CONST64(0xb55a8ef94cd42d61), CONST64(0x460320acea238f65), CONST64(0xc4e68411d56273a6), CONST64(0x55cc68c297a466f1), CONST64(0xdcc6a80dd16e63b2), CONST64(0xaa85d0993355ccff), CONST64(0xfbb241aa51f35908), CONST64(0xc7e20f9c5bed712a), CONST64(0xf359ae55a6f7a204), CONST64(0xfebec120de7f5f81), CONST64(0xad7aa2e548d83d75), CONST64(0xd729cc7fa8e59a32), CONST64(0x71bc0ae899b65ec7), CONST64(0xe096e63bdb704b90), CONST64(0xac8ddb9e3256c8fa), CONST64(0x95d11522b7c4e651), CONST64(0x32b3aacefc19d72b), CONST64(0x704b7393e338ab48), CONST64(0x63843bfd9ebf42dc), CONST64(0x41fc52d091ae7eef), CONST64(0x7dac1ce69bb056cd), CONST64(0x76437894e23baf4d), CONST64(0xbdb16106bbd0d66d), CONST64(0x9b32f1da41c31958), CONST64(0x7957e5176eb2a5cb), CONST64(0xf941b35ca5f2ae0b), CONST64(0x8016564bcb400bc0), CONST64(0x677fc20c6bbdb1da), CONST64(0x59dc7ecc95a26efb), CONST64(0xe1619f40a1febe1f), CONST64(0x10cbc3e3f308eb18), CONST64(0x81e12f30b1cefe4f), CONST64(0x0c10160e0206080a), CONST64(0x922e675ecc4917db), CONST64(0xa26e3f66c45137f3), CONST64(0x4ee8cf531d277469), CONST64(0x78a09c6c143c5044), CONST64(0xb0560e73c3582be8), CONST64(0x573f9a3463a591f2), CONST64(0xe69eed3cda734f95), CONST64(0xd3d2358e5de76934), CONST64(0xdfc223805fe1613e), CONST64(0xf2aed72edc79578b), CONST64(0x13cf486e7d87e994), CONST64(0x94266c59cd4a13de), CONST64(0x1fdf5e607f81e19e), CONST64(0xc1ea049b5aee752f), CONST64(0x7547f3196cb4adc1), CONST64(0xd5da3e895ce46d31), CONST64(0x08ebeffff704fb0c), CONST64(0xd42d47f2266a98be), CONST64(0x38abb7c7ff1cdb24), CONST64(0x543b11b9ed2a937e), CONST64(0x4a1336a2e825876f), CONST64(0x699c26f49dba4ed3), CONST64(0x7f5fee106fb1a1ce), CONST64(0x03048b8d8e8f028c), CONST64(0x56c8e34f192b647d), CONST64(0xe7699447a0fdba1a), CONST64(0x1ad3deeaf00de717), CONST64(0x113cba9889861e97), CONST64(0x2278692d0f113c33), CONST64(0x1238311507091c1b), CONST64(0xc511fd6aafec8629), CONST64(0x208b9bdbfb10cb30), CONST64(0x3040583808182028), CONST64(0x7ea8976b153f5441), CONST64(0x2e687f230d173439), CONST64(0x18202c1c040c1014), CONST64(0x06080b0701030405), CONST64(0x4507ab2164ac8de9), CONST64(0xf8b6ca27df7c5b84), CONST64(0x29970d5f769ac5b3), CONST64(0x0bef6472798bf980), CONST64(0xf4a6dc29dd7a538e), CONST64(0x8ef5b2b33d47f4c9), CONST64(0x74b08a62163a584e), CONST64(0x82e5a4bd3f41fcc3), CONST64(0xb2a5fc853759dceb), CONST64(0x734ff81e6db7a9c4), CONST64(0x90dd95a83848e0d8), CONST64(0xb1a17708b9d6de67), CONST64(0x37bf2a447395d1a2), CONST64(0x4c1b3da5e926836a), CONST64(0xbeb5ea8b355fd4e1), CONST64(0xe3926db655ff491c), CONST64(0x3baf3c4a7193d9a8), CONST64(0x07ff727c7b8df18a), CONST64(0x0f149d838c890a86), CONST64(0x31b721437296d5a7), CONST64(0x1734b19f88851a92), CONST64(0x0ee3e4f8f607ff09), CONST64(0xfc4d33d62a7ea882), CONST64(0x84edafba3e42f8c6), CONST64(0xd9ca28875ee2653b), CONST64(0xd2254cf527699cbb), CONST64(0x890ac0cf46ca0543), CONST64(0x286074240c14303c), CONST64(0x430fa02665af89ec), CONST64(0x6d67df0568b8bdd5), CONST64(0x5b2f8c3a61a399f8), CONST64(0x0a181d0903050c0f), CONST64(0xbc46187dc15e23e2), CONST64(0xef827bb857f94116), CONST64(0xcefe9918d6677fa9), CONST64(0xec86f035d976439a), CONST64(0xcdfa129558e87d25), CONST64(0xea8efb32d875479f), CONST64(0x4917bd2f66aa85e3), CONST64(0xc8f6921fd7647bac), CONST64(0x9ccd83a63a4ee8d2), CONST64(0x8a0e4b42c84507cf), CONST64(0x88fdb9b43c44f0cc), CONST64(0x268390dcfa13cf35), CONST64(0x53c463c596a762f4), CONST64(0xf551a552a7f4a601), CONST64(0x77b401ef98b55ac2), CONST64(0x52331abeec29977b), CONST64(0xb7a97c0fb8d5da62), CONST64(0xa876226fc7543bfc), CONST64(0xc319f66daeef822c), CONST64(0x6b6fd40269bbb9d0), CONST64(0xa762bfec4bdd317a), CONST64(0xdd31d176abe0963d), CONST64(0xd121c778a9e69e37), CONST64(0x4f1fb62867a981e6), CONST64(0x3c504e360a1e2822), CONST64(0x8f02cbc847c90146), CONST64(0x16c3c8e4f20bef1d), CONST64(0x99c1032cb5c2ee5b), CONST64(0xcc0d6bee226688aa), CONST64(0x647b4981e532b356), CONST64(0x5e230cb0ee2f9f71), CONST64(0xa399461dbedfc27c), CONST64(0xfa4538d12b7dac87), CONST64(0x217ce2a0819e3ebf), CONST64(0x6c90a67e1236485a), CONST64(0x2d6cf4ae839836b5), CONST64(0x5ad8f5411b2d6c77), CONST64(0x2470622a0e123836), CONST64(0xca0560e923658caf), CONST64(0x04fbf9f1f502f306), CONST64(0x8312ddc645cf094c), CONST64(0xc61576e7216384a5), CONST64(0x9e3e7150ce4f1fd1), CONST64(0xab72a9e249db3970), CONST64(0xe87d09c42c74b09c), CONST64(0x2c9b8dd5f916c33a), CONST64(0x6e635488e637bf59), CONST64(0x93d91e25b6c7e254), CONST64(0xf05d25d82878a088), CONST64(0x72b8816517395c4b), CONST64(0x2b64ffa9829b32b0), CONST64(0x5cd0fe461a2e6872), CONST64(0x1d2cac968b80169d), CONST64(0x3ea3bcc0fe1fdf21), CONST64(0x1b24a7918a831298), CONST64(0x3648533f091b242d), CONST64(0x8c064045c94603ca), CONST64(0x354cd8b2879426a1), CONST64(0xb94a98f74ed2256b), CONST64(0x7c5b659de13ea342), CONST64(0xe46d1fca2e72b896), CONST64(0x62734286e431b753), CONST64(0x7a536e9ae03da747), CONST64(0x400b2babeb208b60), CONST64(0x47f459d790ad7aea), CONST64(0xff49b85ba4f1aa0e), CONST64(0x44f0d25a1e227866), CONST64(0x395ccebc85922eab), CONST64(0x5d27873d60a09dfd), CONST64(0x0000000000000000), CONST64(0xde355afb256f94b1), CONST64(0x02f3f2f6f401f703), CONST64(0x1cdbd5edf10ee312), CONST64(0x5fd475cb94a16afe), CONST64(0x3a5845310b1d2c27), CONST64(0x686b5f8fe734bb5c), CONST64(0x238f1056759fc9bc), CONST64(0x582b07b7ef2c9b74), CONST64(0xb8bde18c345cd0e4), CONST64(0xa695c6973153c4f5), CONST64(0xc2ee8f16d46177a3), CONST64(0xdacea30ad06d67b7), CONST64(0x3344d3b5869722a4), CONST64(0x19d755677e82e59b), CONST64(0xc901eb64adea8e23), CONST64(0x34bba1c9fd1ad32e), CONST64(0xf6552edf297ba48d), CONST64(0xa09dcd903050c0f0), CONST64(0x9ac588a13b4decd7), CONST64(0x658c30fa9fbc46d9), CONST64(0x2a9386d2f815c73f), CONST64(0xae7e2968c6573ff9), CONST64(0x6a98ad7913354c5f), CONST64(0x14303a12060a181e), CONST64(0x1e28271b050f1411), CONST64(0xa4663461c55233f6), CONST64(0x6688bb7711334455), CONST64(0x2f9f06587799c1b6), CONST64(0x15c743697c84ed91), CONST64(0x01f7797b7a8ef58f), CONST64(0x0de76f757888fd85), CONST64(0xb4adf782365ad8ee), CONST64(0x48e0c4541c24706c), CONST64(0x96d59eaf394be4dd), CONST64(0xcbf2199259eb7920), CONST64(0x50c0e84818286078), CONST64(0xe98a70bf56fa4513), CONST64(0x8df1393eb3c8f645), CONST64(0x87e92437b0cdfa4a), CONST64(0xd83d51fc246c90b4), CONST64(0xc01d7de0206080a0), CONST64(0x8bf93239b2cbf240), CONST64(0x4be44fd992ab72e0), CONST64(0xed71894ea3f8b615), CONST64(0xba4e137ac05d27e7), CONST64(0x851ad6c144cc0d49), CONST64(0x5137913362a695f7), CONST64(0x6080b07010304050), CONST64(0x9fc9082bb4c1ea5e), CONST64(0x3f54c5bb84912aae), CONST64(0x9722e7d443c51152), CONST64(0x4dec44de93a876e5), CONST64(0xb65e0574c25b2fed), CONST64(0xa16ab4eb4ade357f), CONST64(0xa9815b14bddace73), CONST64(0x050c808a8f8c0689), CONST64(0xee7502c32d77b499), CONST64(0xaf895013bcd9ca76), CONST64(0x6f942df39cb94ad6), CONST64(0x6177c90b6abeb5df), CONST64(0x9d3afadd40c01d5d), CONST64(0x98367a57cf4c1bd4), CONST64(0xeb798249a2fbb210), CONST64(0x2774e9a7809d3aba), CONST64(0xbf4293f04fd1216e), CONST64(0x42f8d95d1f217c63), CONST64(0x861e5d4cca430fc5), CONST64(0xdb39da71aae39238), CONST64(0x912aecd342c61557), }; static const ulong64 T5[256] = { CONST64(0xb9bb016ad3ba68d2), CONST64(0x9ae5b166fc54194d), CONST64(0x65e2cd14712f93bc), CONST64(0x8725511b9c74b9cd), CONST64(0xa2f7a457f5530251), CONST64(0xd6d003be68d3b86b), CONST64(0xded604b56bd2bd6f), CONST64(0x52b3fe85d74d6429), CONST64(0xbafdad4af0500d5d), CONST64(0x09cf63e0e9ac268a), CONST64(0x1c0984968a8d830e), CONST64(0x91a51a4ddcbf79c6), CONST64(0xa73d4d379070addd), CONST64(0xaaf1a35cf6520755), CONST64(0xa47be117b39ac852), CONST64(0x5ab5f98ed44c612d), CONST64(0x0346ac2023ea658f), CONST64(0xe6c4118462d5a673), CONST64(0xcc55c268a497f166), CONST64(0xc6dc0da86ed1b263), CONST64(0x85aa99d05533ffcc), CONST64(0xb2fbaa41f3510859), CONST64(0xe2c79c0fed5b2a71), CONST64(0x59f355aef7a604a2), CONST64(0xbefe20c17fde815f), CONST64(0x7aade5a2d848753d), CONST64(0x29d77fcce5a8329a), CONST64(0xbc71e80ab699c75e), CONST64(0x96e03be670db904b), CONST64(0x8dac9edb5632fac8), CONST64(0xd1952215c4b751e6), CONST64(0xb332ceaa19fc2bd7), CONST64(0x4b70937338e348ab), CONST64(0x8463fd3bbf9edc42), CONST64(0xfc41d052ae91ef7e), CONST64(0xac7de61cb09bcd56), CONST64(0x437694783be24daf), CONST64(0xb1bd0661d0bb6dd6), CONST64(0x329bdaf1c3415819), CONST64(0x577917e5b26ecba5), CONST64(0x41f95cb3f2a50bae), CONST64(0x16804b5640cbc00b), CONST64(0x7f670cc2bd6bdab1), CONST64(0xdc59cc7ea295fb6e), CONST64(0x61e1409ffea11fbe), CONST64(0xcb10e3c308f318eb), CONST64(0xe181302fceb14ffe), CONST64(0x100c0e1606020a08), CONST64(0x2e925e6749ccdb17), CONST64(0x6ea2663f51c4f337), CONST64(0xe84e53cf271d6974), CONST64(0xa0786c9c3c144450), CONST64(0x56b0730e58c3e82b), CONST64(0x3f57349aa563f291), CONST64(0x9ee63ced73da954f), CONST64(0xd2d38e35e75d3469), CONST64(0xc2df8023e15f3e61), CONST64(0xaef22ed779dc8b57), CONST64(0xcf136e48877d94e9), CONST64(0x2694596c4acdde13), CONST64(0xdf1f605e817f9ee1), CONST64(0xeac19b04ee5a2f75), CONST64(0x477519f3b46cc1ad), CONST64(0xdad5893ee45c316d), CONST64(0xeb08ffef04f70cfb), CONST64(0x2dd4f2476a26be98), CONST64(0xab38c7b71cff24db), CONST64(0x3b54b9112aed7e93), CONST64(0x134aa23625e86f87), CONST64(0x9c69f426ba9dd34e), CONST64(0x5f7f10eeb16fcea1), CONST64(0x04038d8b8f8e8c02), CONST64(0xc8564fe32b197d64), CONST64(0x69e74794fda01aba), CONST64(0xd31aeade0df017e7), CONST64(0x3c1198ba8689971e), CONST64(0x78222d69110f333c), CONST64(0x3812153109071b1c), CONST64(0x11c56afdecaf2986), CONST64(0x8b20db9b10fb30cb), CONST64(0x4030385818082820), CONST64(0xa87e6b973f154154), CONST64(0x682e237f170d3934), CONST64(0x20181c2c0c041410), CONST64(0x0806070b03010504), CONST64(0x074521abac64e98d), CONST64(0xb6f827ca7cdf845b), CONST64(0x97295f0d9a76b3c5), CONST64(0xef0b72648b7980f9), CONST64(0xa6f429dc7add8e53), CONST64(0xf58eb3b2473dc9f4), CONST64(0xb074628a3a164e58), CONST64(0xe582bda4413fc3fc), CONST64(0xa5b285fc5937ebdc), CONST64(0x4f731ef8b76dc4a9), CONST64(0xdd90a8954838d8e0), CONST64(0xa1b10877d6b967de), CONST64(0xbf37442a9573a2d1), CONST64(0x1b4ca53d26e96a83), CONST64(0xb5be8bea5f35e1d4), CONST64(0x92e3b66dff551c49), CONST64(0xaf3b4a3c9371a8d9), CONST64(0xff077c728d7b8af1), CONST64(0x140f839d898c860a), CONST64(0xb73143219672a7d5), CONST64(0x34179fb18588921a), CONST64(0xe30ef8e407f609ff), CONST64(0x4dfcd6337e2a82a8), CONST64(0xed84baaf423ec6f8), CONST64(0xcad98728e25e3b65), CONST64(0x25d2f54c6927bb9c), CONST64(0x0a89cfc0ca464305), CONST64(0x60282474140c3c30), CONST64(0x0f4326a0af65ec89), CONST64(0x676d05dfb868d5bd), CONST64(0x2f5b3a8ca361f899), CONST64(0x180a091d05030f0c), CONST64(0x46bc7d185ec1e223), CONST64(0x82efb87bf9571641), CONST64(0xfece189967d6a97f), CONST64(0x86ec35f076d99a43), CONST64(0xfacd9512e858257d), CONST64(0x8eea32fb75d89f47), CONST64(0x17492fbdaa66e385), CONST64(0xf6c81f9264d7ac7b), CONST64(0xcd9ca6834e3ad2e8), CONST64(0x0e8a424b45c8cf07), CONST64(0xfd88b4b9443cccf0), CONST64(0x8326dc9013fa35cf), CONST64(0xc453c563a796f462), CONST64(0x51f552a5f4a701a6), CONST64(0xb477ef01b598c25a), CONST64(0x3352be1a29ec7b97), CONST64(0xa9b70f7cd5b862da), CONST64(0x76a86f2254c7fc3b), CONST64(0x19c36df6efae2c82), CONST64(0x6f6b02d4bb69d0b9), CONST64(0x62a7ecbfdd4b7a31), CONST64(0x31dd76d1e0ab3d96), CONST64(0x21d178c7e6a9379e), CONST64(0x1f4f28b6a967e681), CONST64(0x503c364e1e0a2228), CONST64(0x028fc8cbc9474601), CONST64(0xc316e4c80bf21def), CONST64(0xc1992c03c2b55bee), CONST64(0x0dccee6b6622aa88), CONST64(0x7b64814932e556b3), CONST64(0x235eb00c2fee719f), CONST64(0x99a31d46dfbe7cc2), CONST64(0x45fad1387d2b87ac), CONST64(0x7c21a0e29e81bf3e), CONST64(0x906c7ea636125a48), CONST64(0x6c2daef49883b536), CONST64(0xd85a41f52d1b776c), CONST64(0x70242a62120e3638), CONST64(0x05cae9606523af8c), CONST64(0xfb04f1f902f506f3), CONST64(0x1283c6ddcf454c09), CONST64(0x15c6e7766321a584), CONST64(0x3e9e50714fced11f), CONST64(0x72abe2a9db497039), CONST64(0x7de8c409742c9cb0), CONST64(0x9b2cd58d16f93ac3), CONST64(0x636e885437e659bf), CONST64(0xd993251ec7b654e2), CONST64(0x5df0d825782888a0), CONST64(0xb872658139174b5c), CONST64(0x642ba9ff9b82b032), CONST64(0xd05c46fe2e1a7268), CONST64(0x2c1d96ac808b9d16), CONST64(0xa33ec0bc1ffe21df), CONST64(0x241b91a7838a9812), CONST64(0x48363f531b092d24), CONST64(0x068c454046c9ca03), CONST64(0x4c35b2d89487a126), CONST64(0x4ab9f798d24e6b25), CONST64(0x5b7c9d653ee142a3), CONST64(0x6de4ca1f722e96b8), CONST64(0x7362864231e453b7), CONST64(0x537a9a6e3de047a7), CONST64(0x0b40ab2b20eb608b), CONST64(0xf447d759ad90ea7a), CONST64(0x49ff5bb8f1a40eaa), CONST64(0xf0445ad2221e6678), CONST64(0x5c39bcce9285ab2e), CONST64(0x275d3d87a060fd9d), CONST64(0x0000000000000000), CONST64(0x35defb5a6f25b194), CONST64(0xf302f6f201f403f7), CONST64(0xdb1cedd50ef112e3), CONST64(0xd45fcb75a194fe6a), CONST64(0x583a31451d0b272c), CONST64(0x6b688f5f34e75cbb), CONST64(0x8f2356109f75bcc9), CONST64(0x2b58b7072cef749b), CONST64(0xbdb88ce15c34e4d0), CONST64(0x95a697c65331f5c4), CONST64(0xeec2168f61d4a377), CONST64(0xceda0aa36dd0b767), CONST64(0x4433b5d39786a422), CONST64(0xd7196755827e9be5), CONST64(0x01c964ebeaad238e), CONST64(0xbb34c9a11afd2ed3), CONST64(0x55f6df2e7b298da4), CONST64(0x9da090cd5030f0c0), CONST64(0xc59aa1884d3bd7ec), CONST64(0x8c65fa30bc9fd946), CONST64(0x932ad28615f83fc7), CONST64(0x7eae682957c6f93f), CONST64(0x986a79ad35135f4c), CONST64(0x3014123a0a061e18), CONST64(0x281e1b270f051114), CONST64(0x66a4613452c5f633), CONST64(0x886677bb33115544), CONST64(0x9f2f58069977b6c1), CONST64(0xc7156943847c91ed), CONST64(0xf7017b798e7a8ff5), CONST64(0xe70d756f887885fd), CONST64(0xadb482f75a36eed8), CONST64(0xe04854c4241c6c70), CONST64(0xd596af9e4b39dde4), CONST64(0xf2cb9219eb592079), CONST64(0xc05048e828187860), CONST64(0x8ae9bf70fa561345), CONST64(0xf18d3e39c8b345f6), CONST64(0xe9873724cdb04afa), CONST64(0x3dd8fc516c24b490), CONST64(0x1dc0e07d6020a080), CONST64(0xf98b3932cbb240f2), CONST64(0xe44bd94fab92e072), CONST64(0x71ed4e89f8a315b6), CONST64(0x4eba7a135dc0e727), CONST64(0x1a85c1d6cc44490d), CONST64(0x37513391a662f795), CONST64(0x806070b030105040), CONST64(0xc99f2b08c1b45eea), CONST64(0x543fbbc59184ae2a), CONST64(0x2297d4e7c5435211), CONST64(0xec4dde44a893e576), CONST64(0x5eb674055bc2ed2f), CONST64(0x6aa1ebb4de4a7f35), CONST64(0x81a9145bdabd73ce), CONST64(0x0c058a808c8f8906), CONST64(0x75eec302772d99b4), CONST64(0x89af1350d9bc76ca), CONST64(0x946ff32db99cd64a), CONST64(0x77610bc9be6adfb5), CONST64(0x3a9dddfac0405d1d), CONST64(0x3698577a4ccfd41b), CONST64(0x79eb4982fba210b2), CONST64(0x7427a7e99d80ba3a), CONST64(0x42bff093d14f6e21), CONST64(0xf8425dd9211f637c), CONST64(0x1e864c5d43cac50f), CONST64(0x39db71dae3aa3892), CONST64(0x2a91d3ecc6425715), }; static const ulong64 T6[256] = { CONST64(0x6a01bbb9d268bad3), CONST64(0x66b1e59a4d1954fc), CONST64(0x14cde265bc932f71), CONST64(0x1b512587cdb9749c), CONST64(0x57a4f7a2510253f5), CONST64(0xbe03d0d66bb8d368), CONST64(0xb504d6de6fbdd26b), CONST64(0x85feb35229644dd7), CONST64(0x4aadfdba5d0d50f0), CONST64(0xe063cf098a26ace9), CONST64(0x9684091c0e838d8a), CONST64(0x4d1aa591c679bfdc), CONST64(0x374d3da7ddad7090), CONST64(0x5ca3f1aa550752f6), CONST64(0x17e17ba452c89ab3), CONST64(0x8ef9b55a2d614cd4), CONST64(0x20ac46038f65ea23), CONST64(0x8411c4e673a6d562), CONST64(0x68c255cc66f197a4), CONST64(0xa80ddcc663b2d16e), CONST64(0xd099aa85ccff3355), CONST64(0x41aafbb2590851f3), CONST64(0x0f9cc7e2712a5bed), CONST64(0xae55f359a204a6f7), CONST64(0xc120febe5f81de7f), CONST64(0xa2e5ad7a3d7548d8), CONST64(0xcc7fd7299a32a8e5), CONST64(0x0ae871bc5ec799b6), CONST64(0xe63be0964b90db70), CONST64(0xdb9eac8dc8fa3256), CONST64(0x152295d1e651b7c4), CONST64(0xaace32b3d72bfc19), CONST64(0x7393704bab48e338), CONST64(0x3bfd638442dc9ebf), CONST64(0x52d041fc7eef91ae), CONST64(0x1ce67dac56cd9bb0), CONST64(0x78947643af4de23b), CONST64(0x6106bdb1d66dbbd0), CONST64(0xf1da9b32195841c3), CONST64(0xe5177957a5cb6eb2), CONST64(0xb35cf941ae0ba5f2), CONST64(0x564b80160bc0cb40), CONST64(0xc20c677fb1da6bbd), CONST64(0x7ecc59dc6efb95a2), CONST64(0x9f40e161be1fa1fe), CONST64(0xc3e310cbeb18f308), CONST64(0x2f3081e1fe4fb1ce), CONST64(0x160e0c10080a0206), CONST64(0x675e922e17dbcc49), CONST64(0x3f66a26e37f3c451), CONST64(0xcf534ee874691d27), CONST64(0x9c6c78a05044143c), CONST64(0x0e73b0562be8c358), CONST64(0x9a34573f91f263a5), CONST64(0xed3ce69e4f95da73), CONST64(0x358ed3d269345de7), CONST64(0x2380dfc2613e5fe1), CONST64(0xd72ef2ae578bdc79), CONST64(0x486e13cfe9947d87), CONST64(0x6c59942613decd4a), CONST64(0x5e601fdfe19e7f81), CONST64(0x049bc1ea752f5aee), CONST64(0xf3197547adc16cb4), CONST64(0x3e89d5da6d315ce4), CONST64(0xefff08ebfb0cf704), CONST64(0x47f2d42d98be266a), CONST64(0xb7c738abdb24ff1c), CONST64(0x11b9543b937eed2a), CONST64(0x36a24a13876fe825), CONST64(0x26f4699c4ed39dba), CONST64(0xee107f5fa1ce6fb1), CONST64(0x8b8d0304028c8e8f), CONST64(0xe34f56c8647d192b), CONST64(0x9447e769ba1aa0fd), CONST64(0xdeea1ad3e717f00d), CONST64(0xba98113c1e978986), CONST64(0x692d22783c330f11), CONST64(0x311512381c1b0709), CONST64(0xfd6ac5118629afec), CONST64(0x9bdb208bcb30fb10), CONST64(0x5838304020280818), CONST64(0x976b7ea85441153f), CONST64(0x7f232e6834390d17), CONST64(0x2c1c18201014040c), CONST64(0x0b07060804050103), CONST64(0xab2145078de964ac), CONST64(0xca27f8b65b84df7c), CONST64(0x0d5f2997c5b3769a), CONST64(0x64720beff980798b), CONST64(0xdc29f4a6538edd7a), CONST64(0xb2b38ef5f4c93d47), CONST64(0x8a6274b0584e163a), CONST64(0xa4bd82e5fcc33f41), CONST64(0xfc85b2a5dceb3759), CONST64(0xf81e734fa9c46db7), CONST64(0x95a890dde0d83848), CONST64(0x7708b1a1de67b9d6), CONST64(0x2a4437bfd1a27395), CONST64(0x3da54c1b836ae926), CONST64(0xea8bbeb5d4e1355f), CONST64(0x6db6e392491c55ff), CONST64(0x3c4a3bafd9a87193), CONST64(0x727c07fff18a7b8d), CONST64(0x9d830f140a868c89), CONST64(0x214331b7d5a77296), CONST64(0xb19f17341a928885), CONST64(0xe4f80ee3ff09f607), CONST64(0x33d6fc4da8822a7e), CONST64(0xafba84edf8c63e42), CONST64(0x2887d9ca653b5ee2), CONST64(0x4cf5d2259cbb2769), CONST64(0xc0cf890a054346ca), CONST64(0x74242860303c0c14), CONST64(0xa026430f89ec65af), CONST64(0xdf056d67bdd568b8), CONST64(0x8c3a5b2f99f861a3), CONST64(0x1d090a180c0f0305), CONST64(0x187dbc4623e2c15e), CONST64(0x7bb8ef82411657f9), CONST64(0x9918cefe7fa9d667), CONST64(0xf035ec86439ad976), CONST64(0x1295cdfa7d2558e8), CONST64(0xfb32ea8e479fd875), CONST64(0xbd2f491785e366aa), CONST64(0x921fc8f67bacd764), CONST64(0x83a69ccde8d23a4e), CONST64(0x4b428a0e07cfc845), CONST64(0xb9b488fdf0cc3c44), CONST64(0x90dc2683cf35fa13), CONST64(0x63c553c462f496a7), CONST64(0xa552f551a601a7f4), CONST64(0x01ef77b45ac298b5), CONST64(0x1abe5233977bec29), CONST64(0x7c0fb7a9da62b8d5), CONST64(0x226fa8763bfcc754), CONST64(0xf66dc319822caeef), CONST64(0xd4026b6fb9d069bb), CONST64(0xbfeca762317a4bdd), CONST64(0xd176dd31963dabe0), CONST64(0xc778d1219e37a9e6), CONST64(0xb6284f1f81e667a9), CONST64(0x4e363c5028220a1e), CONST64(0xcbc88f02014647c9), CONST64(0xc8e416c3ef1df20b), CONST64(0x032c99c1ee5bb5c2), CONST64(0x6beecc0d88aa2266), CONST64(0x4981647bb356e532), CONST64(0x0cb05e239f71ee2f), CONST64(0x461da399c27cbedf), CONST64(0x38d1fa45ac872b7d), CONST64(0xe2a0217c3ebf819e), CONST64(0xa67e6c90485a1236), CONST64(0xf4ae2d6c36b58398), CONST64(0xf5415ad86c771b2d), CONST64(0x622a247038360e12), CONST64(0x60e9ca058caf2365), CONST64(0xf9f104fbf306f502), CONST64(0xddc68312094c45cf), CONST64(0x76e7c61584a52163), CONST64(0x71509e3e1fd1ce4f), CONST64(0xa9e2ab72397049db), CONST64(0x09c4e87db09c2c74), CONST64(0x8dd52c9bc33af916), CONST64(0x54886e63bf59e637), CONST64(0x1e2593d9e254b6c7), CONST64(0x25d8f05da0882878), CONST64(0x816572b85c4b1739), CONST64(0xffa92b6432b0829b), CONST64(0xfe465cd068721a2e), CONST64(0xac961d2c169d8b80), CONST64(0xbcc03ea3df21fe1f), CONST64(0xa7911b2412988a83), CONST64(0x533f3648242d091b), CONST64(0x40458c0603cac946), CONST64(0xd8b2354c26a18794), CONST64(0x98f7b94a256b4ed2), CONST64(0x659d7c5ba342e13e), CONST64(0x1fcae46db8962e72), CONST64(0x42866273b753e431), CONST64(0x6e9a7a53a747e03d), CONST64(0x2bab400b8b60eb20), CONST64(0x59d747f47aea90ad), CONST64(0xb85bff49aa0ea4f1), CONST64(0xd25a44f078661e22), CONST64(0xcebc395c2eab8592), CONST64(0x873d5d279dfd60a0), CONST64(0x0000000000000000), CONST64(0x5afbde3594b1256f), CONST64(0xf2f602f3f703f401), CONST64(0xd5ed1cdbe312f10e), CONST64(0x75cb5fd46afe94a1), CONST64(0x45313a582c270b1d), CONST64(0x5f8f686bbb5ce734), CONST64(0x1056238fc9bc759f), CONST64(0x07b7582b9b74ef2c), CONST64(0xe18cb8bdd0e4345c), CONST64(0xc697a695c4f53153), CONST64(0x8f16c2ee77a3d461), CONST64(0xa30adace67b7d06d), CONST64(0xd3b5334422a48697), CONST64(0x556719d7e59b7e82), CONST64(0xeb64c9018e23adea), CONST64(0xa1c934bbd32efd1a), CONST64(0x2edff655a48d297b), CONST64(0xcd90a09dc0f03050), CONST64(0x88a19ac5ecd73b4d), CONST64(0x30fa658c46d99fbc), CONST64(0x86d22a93c73ff815), CONST64(0x2968ae7e3ff9c657), CONST64(0xad796a984c5f1335), CONST64(0x3a121430181e060a), CONST64(0x271b1e281411050f), CONST64(0x3461a46633f6c552), CONST64(0xbb77668844551133), CONST64(0x06582f9fc1b67799), CONST64(0x436915c7ed917c84), CONST64(0x797b01f7f58f7a8e), CONST64(0x6f750de7fd857888), CONST64(0xf782b4add8ee365a), CONST64(0xc45448e0706c1c24), CONST64(0x9eaf96d5e4dd394b), CONST64(0x1992cbf2792059eb), CONST64(0xe84850c060781828), CONST64(0x70bfe98a451356fa), CONST64(0x393e8df1f645b3c8), CONST64(0x243787e9fa4ab0cd), CONST64(0x51fcd83d90b4246c), CONST64(0x7de0c01d80a02060), CONST64(0x32398bf9f240b2cb), CONST64(0x4fd94be472e092ab), CONST64(0x894eed71b615a3f8), CONST64(0x137aba4e27e7c05d), CONST64(0xd6c1851a0d4944cc), CONST64(0x9133513795f762a6), CONST64(0xb070608040501030), CONST64(0x082b9fc9ea5eb4c1), CONST64(0xc5bb3f542aae8491), CONST64(0xe7d49722115243c5), CONST64(0x44de4dec76e593a8), CONST64(0x0574b65e2fedc25b), CONST64(0xb4eba16a357f4ade), CONST64(0x5b14a981ce73bdda), CONST64(0x808a050c06898f8c), CONST64(0x02c3ee75b4992d77), CONST64(0x5013af89ca76bcd9), CONST64(0x2df36f944ad69cb9), CONST64(0xc90b6177b5df6abe), CONST64(0xfadd9d3a1d5d40c0), CONST64(0x7a5798361bd4cf4c), CONST64(0x8249eb79b210a2fb), CONST64(0xe9a727743aba809d), CONST64(0x93f0bf42216e4fd1), CONST64(0xd95d42f87c631f21), CONST64(0x5d4c861e0fc5ca43), CONST64(0xda71db399238aae3), CONST64(0xecd3912a155742c6), }; static const ulong64 T7[256] = { CONST64(0x016ab9bb68d2d3ba), CONST64(0xb1669ae5194dfc54), CONST64(0xcd1465e293bc712f), CONST64(0x511b8725b9cd9c74), CONST64(0xa457a2f70251f553), CONST64(0x03bed6d0b86b68d3), CONST64(0x04b5ded6bd6f6bd2), CONST64(0xfe8552b36429d74d), CONST64(0xad4abafd0d5df050), CONST64(0x63e009cf268ae9ac), CONST64(0x84961c09830e8a8d), CONST64(0x1a4d91a579c6dcbf), CONST64(0x4d37a73daddd9070), CONST64(0xa35caaf10755f652), CONST64(0xe117a47bc852b39a), CONST64(0xf98e5ab5612dd44c), CONST64(0xac200346658f23ea), CONST64(0x1184e6c4a67362d5), CONST64(0xc268cc55f166a497), CONST64(0x0da8c6dcb2636ed1), CONST64(0x99d085aaffcc5533), CONST64(0xaa41b2fb0859f351), CONST64(0x9c0fe2c72a71ed5b), CONST64(0x55ae59f304a2f7a6), CONST64(0x20c1befe815f7fde), CONST64(0xe5a27aad753dd848), CONST64(0x7fcc29d7329ae5a8), CONST64(0xe80abc71c75eb699), CONST64(0x3be696e0904b70db), CONST64(0x9edb8dacfac85632), CONST64(0x2215d19551e6c4b7), CONST64(0xceaab3322bd719fc), CONST64(0x93734b7048ab38e3), CONST64(0xfd3b8463dc42bf9e), CONST64(0xd052fc41ef7eae91), CONST64(0xe61cac7dcd56b09b), CONST64(0x947843764daf3be2), CONST64(0x0661b1bd6dd6d0bb), CONST64(0xdaf1329b5819c341), CONST64(0x17e55779cba5b26e), CONST64(0x5cb341f90baef2a5), CONST64(0x4b561680c00b40cb), CONST64(0x0cc27f67dab1bd6b), CONST64(0xcc7edc59fb6ea295), CONST64(0x409f61e11fbefea1), CONST64(0xe3c3cb1018eb08f3), CONST64(0x302fe1814ffeceb1), CONST64(0x0e16100c0a080602), CONST64(0x5e672e92db1749cc), CONST64(0x663f6ea2f33751c4), CONST64(0x53cfe84e6974271d), CONST64(0x6c9ca07844503c14), CONST64(0x730e56b0e82b58c3), CONST64(0x349a3f57f291a563), CONST64(0x3ced9ee6954f73da), CONST64(0x8e35d2d33469e75d), CONST64(0x8023c2df3e61e15f), CONST64(0x2ed7aef28b5779dc), CONST64(0x6e48cf1394e9877d), CONST64(0x596c2694de134acd), CONST64(0x605edf1f9ee1817f), CONST64(0x9b04eac12f75ee5a), CONST64(0x19f34775c1adb46c), CONST64(0x893edad5316de45c), CONST64(0xffefeb080cfb04f7), CONST64(0xf2472dd4be986a26), CONST64(0xc7b7ab3824db1cff), CONST64(0xb9113b547e932aed), CONST64(0xa236134a6f8725e8), CONST64(0xf4269c69d34eba9d), CONST64(0x10ee5f7fcea1b16f), CONST64(0x8d8b04038c028f8e), CONST64(0x4fe3c8567d642b19), CONST64(0x479469e71abafda0), CONST64(0xeaded31a17e70df0), CONST64(0x98ba3c11971e8689), CONST64(0x2d697822333c110f), CONST64(0x153138121b1c0907), CONST64(0x6afd11c52986ecaf), CONST64(0xdb9b8b2030cb10fb), CONST64(0x3858403028201808), CONST64(0x6b97a87e41543f15), CONST64(0x237f682e3934170d), CONST64(0x1c2c201814100c04), CONST64(0x070b080605040301), CONST64(0x21ab0745e98dac64), CONST64(0x27cab6f8845b7cdf), CONST64(0x5f0d9729b3c59a76), CONST64(0x7264ef0b80f98b79), CONST64(0x29dca6f48e537add), CONST64(0xb3b2f58ec9f4473d), CONST64(0x628ab0744e583a16), CONST64(0xbda4e582c3fc413f), CONST64(0x85fca5b2ebdc5937), CONST64(0x1ef84f73c4a9b76d), CONST64(0xa895dd90d8e04838), CONST64(0x0877a1b167ded6b9), CONST64(0x442abf37a2d19573), CONST64(0xa53d1b4c6a8326e9), CONST64(0x8beab5bee1d45f35), CONST64(0xb66d92e31c49ff55), CONST64(0x4a3caf3ba8d99371), CONST64(0x7c72ff078af18d7b), CONST64(0x839d140f860a898c), CONST64(0x4321b731a7d59672), CONST64(0x9fb13417921a8588), CONST64(0xf8e4e30e09ff07f6), CONST64(0xd6334dfc82a87e2a), CONST64(0xbaafed84c6f8423e), CONST64(0x8728cad93b65e25e), CONST64(0xf54c25d2bb9c6927), CONST64(0xcfc00a894305ca46), CONST64(0x247460283c30140c), CONST64(0x26a00f43ec89af65), CONST64(0x05df676dd5bdb868), CONST64(0x3a8c2f5bf899a361), CONST64(0x091d180a0f0c0503), CONST64(0x7d1846bce2235ec1), CONST64(0xb87b82ef1641f957), CONST64(0x1899fecea97f67d6), CONST64(0x35f086ec9a4376d9), CONST64(0x9512facd257de858), CONST64(0x32fb8eea9f4775d8), CONST64(0x2fbd1749e385aa66), CONST64(0x1f92f6c8ac7b64d7), CONST64(0xa683cd9cd2e84e3a), CONST64(0x424b0e8acf0745c8), CONST64(0xb4b9fd88ccf0443c), CONST64(0xdc90832635cf13fa), CONST64(0xc563c453f462a796), CONST64(0x52a551f501a6f4a7), CONST64(0xef01b477c25ab598), CONST64(0xbe1a33527b9729ec), CONST64(0x0f7ca9b762dad5b8), CONST64(0x6f2276a8fc3b54c7), CONST64(0x6df619c32c82efae), CONST64(0x02d46f6bd0b9bb69), CONST64(0xecbf62a77a31dd4b), CONST64(0x76d131dd3d96e0ab), CONST64(0x78c721d1379ee6a9), CONST64(0x28b61f4fe681a967), CONST64(0x364e503c22281e0a), CONST64(0xc8cb028f4601c947), CONST64(0xe4c8c3161def0bf2), CONST64(0x2c03c1995beec2b5), CONST64(0xee6b0dccaa886622), CONST64(0x81497b6456b332e5), CONST64(0xb00c235e719f2fee), CONST64(0x1d4699a37cc2dfbe), CONST64(0xd13845fa87ac7d2b), CONST64(0xa0e27c21bf3e9e81), CONST64(0x7ea6906c5a483612), CONST64(0xaef46c2db5369883), CONST64(0x41f5d85a776c2d1b), CONST64(0x2a6270243638120e), CONST64(0xe96005caaf8c6523), CONST64(0xf1f9fb0406f302f5), CONST64(0xc6dd12834c09cf45), CONST64(0xe77615c6a5846321), CONST64(0x50713e9ed11f4fce), CONST64(0xe2a972ab7039db49), CONST64(0xc4097de89cb0742c), CONST64(0xd58d9b2c3ac316f9), CONST64(0x8854636e59bf37e6), CONST64(0x251ed99354e2c7b6), CONST64(0xd8255df088a07828), CONST64(0x6581b8724b5c3917), CONST64(0xa9ff642bb0329b82), CONST64(0x46fed05c72682e1a), CONST64(0x96ac2c1d9d16808b), CONST64(0xc0bca33e21df1ffe), CONST64(0x91a7241b9812838a), CONST64(0x3f5348362d241b09), CONST64(0x4540068cca0346c9), CONST64(0xb2d84c35a1269487), CONST64(0xf7984ab96b25d24e), CONST64(0x9d655b7c42a33ee1), CONST64(0xca1f6de496b8722e), CONST64(0x8642736253b731e4), CONST64(0x9a6e537a47a73de0), CONST64(0xab2b0b40608b20eb), CONST64(0xd759f447ea7aad90), CONST64(0x5bb849ff0eaaf1a4), CONST64(0x5ad2f0446678221e), CONST64(0xbcce5c39ab2e9285), CONST64(0x3d87275dfd9da060), CONST64(0x0000000000000000), CONST64(0xfb5a35deb1946f25), CONST64(0xf6f2f30203f701f4), CONST64(0xedd5db1c12e30ef1), CONST64(0xcb75d45ffe6aa194), CONST64(0x3145583a272c1d0b), CONST64(0x8f5f6b685cbb34e7), CONST64(0x56108f23bcc99f75), CONST64(0xb7072b58749b2cef), CONST64(0x8ce1bdb8e4d05c34), CONST64(0x97c695a6f5c45331), CONST64(0x168feec2a37761d4), CONST64(0x0aa3cedab7676dd0), CONST64(0xb5d34433a4229786), CONST64(0x6755d7199be5827e), CONST64(0x64eb01c9238eeaad), CONST64(0xc9a1bb342ed31afd), CONST64(0xdf2e55f68da47b29), CONST64(0x90cd9da0f0c05030), CONST64(0xa188c59ad7ec4d3b), CONST64(0xfa308c65d946bc9f), CONST64(0xd286932a3fc715f8), CONST64(0x68297eaef93f57c6), CONST64(0x79ad986a5f4c3513), CONST64(0x123a30141e180a06), CONST64(0x1b27281e11140f05), CONST64(0x613466a4f63352c5), CONST64(0x77bb886655443311), CONST64(0x58069f2fb6c19977), CONST64(0x6943c71591ed847c), CONST64(0x7b79f7018ff58e7a), CONST64(0x756fe70d85fd8878), CONST64(0x82f7adb4eed85a36), CONST64(0x54c4e0486c70241c), CONST64(0xaf9ed596dde44b39), CONST64(0x9219f2cb2079eb59), CONST64(0x48e8c05078602818), CONST64(0xbf708ae91345fa56), CONST64(0x3e39f18d45f6c8b3), CONST64(0x3724e9874afacdb0), CONST64(0xfc513dd8b4906c24), CONST64(0xe07d1dc0a0806020), CONST64(0x3932f98b40f2cbb2), CONST64(0xd94fe44be072ab92), CONST64(0x4e8971ed15b6f8a3), CONST64(0x7a134ebae7275dc0), CONST64(0xc1d61a85490dcc44), CONST64(0x33913751f795a662), CONST64(0x70b0806050403010), CONST64(0x2b08c99f5eeac1b4), CONST64(0xbbc5543fae2a9184), CONST64(0xd4e722975211c543), CONST64(0xde44ec4de576a893), CONST64(0x74055eb6ed2f5bc2), CONST64(0xebb46aa17f35de4a), CONST64(0x145b81a973cedabd), CONST64(0x8a800c0589068c8f), CONST64(0xc30275ee99b4772d), CONST64(0x135089af76cad9bc), CONST64(0xf32d946fd64ab99c), CONST64(0x0bc97761dfb5be6a), CONST64(0xddfa3a9d5d1dc040), CONST64(0x577a3698d41b4ccf), CONST64(0x498279eb10b2fba2), CONST64(0xa7e97427ba3a9d80), CONST64(0xf09342bf6e21d14f), CONST64(0x5dd9f842637c211f), CONST64(0x4c5d1e86c50f43ca), CONST64(0x71da39db3892e3aa), CONST64(0xd3ec2a915715c642), }; static const ulong64 c[R + 1] = { CONST64(0xba542f7453d3d24d), CONST64(0x50ac8dbf70529a4c), CONST64(0xead597d133515ba6), CONST64(0xde48a899db32b7fc), CONST64(0xe39e919be2bb416e), CONST64(0xa5cb6b95a1f3b102), CONST64(0xccc41d14c363da5d), CONST64(0x5fdc7dcd7f5a6c5c), CONST64(0xf726ffede89d6f8e), }; /** Initialize the Khazad block cipher @param key The symmetric key you wish to pass @param keylen The key length in bytes @param num_rounds The number of rounds desired (0 for default) @param skey The key in as scheduled by this function. @return CRYPT_OK if successful */ int khazad_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) { int r; const ulong64 *S; ulong64 K2, K1; LTC_ARGCHK(key != NULL); LTC_ARGCHK(skey != NULL); if (keylen != 16) { return CRYPT_INVALID_KEYSIZE; } if (num_rounds != 8 && num_rounds != 0) { return CRYPT_INVALID_ROUNDS; } /* use 7th table */ S = T7; /* * map unsigned char array cipher key to initial key state (mu): */ K2 = ((ulong64)key[ 0] << 56) ^ ((ulong64)key[ 1] << 48) ^ ((ulong64)key[ 2] << 40) ^ ((ulong64)key[ 3] << 32) ^ ((ulong64)key[ 4] << 24) ^ ((ulong64)key[ 5] << 16) ^ ((ulong64)key[ 6] << 8) ^ ((ulong64)key[ 7] ); K1 = ((ulong64)key[ 8] << 56) ^ ((ulong64)key[ 9] << 48) ^ ((ulong64)key[10] << 40) ^ ((ulong64)key[11] << 32) ^ ((ulong64)key[12] << 24) ^ ((ulong64)key[13] << 16) ^ ((ulong64)key[14] << 8) ^ ((ulong64)key[15] ); /* * compute the round keys: */ for (r = 0; r <= R; r++) { /* * K[r] = rho(c[r], K1) ^ K2; */ skey->khazad.roundKeyEnc[r] = T0[(int)(K1 >> 56) ] ^ T1[(int)(K1 >> 48) & 0xff] ^ T2[(int)(K1 >> 40) & 0xff] ^ T3[(int)(K1 >> 32) & 0xff] ^ T4[(int)(K1 >> 24) & 0xff] ^ T5[(int)(K1 >> 16) & 0xff] ^ T6[(int)(K1 >> 8) & 0xff] ^ T7[(int)(K1 ) & 0xff] ^ c[r] ^ K2; K2 = K1; K1 = skey->khazad.roundKeyEnc[r]; } /* * compute the inverse key schedule: * K'^0 = K^R, K'^R = K^0, K'^r = theta(K^{R-r}) */ skey->khazad.roundKeyDec[0] = skey->khazad.roundKeyEnc[R]; for (r = 1; r < R; r++) { K1 = skey->khazad.roundKeyEnc[R - r]; skey->khazad.roundKeyDec[r] = T0[(int)S[(int)(K1 >> 56) ] & 0xff] ^ T1[(int)S[(int)(K1 >> 48) & 0xff] & 0xff] ^ T2[(int)S[(int)(K1 >> 40) & 0xff] & 0xff] ^ T3[(int)S[(int)(K1 >> 32) & 0xff] & 0xff] ^ T4[(int)S[(int)(K1 >> 24) & 0xff] & 0xff] ^ T5[(int)S[(int)(K1 >> 16) & 0xff] & 0xff] ^ T6[(int)S[(int)(K1 >> 8) & 0xff] & 0xff] ^ T7[(int)S[(int)(K1 ) & 0xff] & 0xff]; } skey->khazad.roundKeyDec[R] = skey->khazad.roundKeyEnc[0]; return CRYPT_OK; } static void khazad_crypt(const unsigned char *plaintext, unsigned char *ciphertext, const ulong64 *roundKey) { int r; ulong64 state; /* * map plaintext block to cipher state (mu) * and add initial round key (sigma[K^0]): */ state = ((ulong64)plaintext[0] << 56) ^ ((ulong64)plaintext[1] << 48) ^ ((ulong64)plaintext[2] << 40) ^ ((ulong64)plaintext[3] << 32) ^ ((ulong64)plaintext[4] << 24) ^ ((ulong64)plaintext[5] << 16) ^ ((ulong64)plaintext[6] << 8) ^ ((ulong64)plaintext[7] ) ^ roundKey[0]; /* * R - 1 full rounds: */ for (r = 1; r < R; r++) { state = T0[(int)(state >> 56) ] ^ T1[(int)(state >> 48) & 0xff] ^ T2[(int)(state >> 40) & 0xff] ^ T3[(int)(state >> 32) & 0xff] ^ T4[(int)(state >> 24) & 0xff] ^ T5[(int)(state >> 16) & 0xff] ^ T6[(int)(state >> 8) & 0xff] ^ T7[(int)(state ) & 0xff] ^ roundKey[r]; } /* * last round: */ state = (T0[(int)(state >> 56) ] & CONST64(0xff00000000000000)) ^ (T1[(int)(state >> 48) & 0xff] & CONST64(0x00ff000000000000)) ^ (T2[(int)(state >> 40) & 0xff] & CONST64(0x0000ff0000000000)) ^ (T3[(int)(state >> 32) & 0xff] & CONST64(0x000000ff00000000)) ^ (T4[(int)(state >> 24) & 0xff] & CONST64(0x00000000ff000000)) ^ (T5[(int)(state >> 16) & 0xff] & CONST64(0x0000000000ff0000)) ^ (T6[(int)(state >> 8) & 0xff] & CONST64(0x000000000000ff00)) ^ (T7[(int)(state ) & 0xff] & CONST64(0x00000000000000ff)) ^ roundKey[R]; /* * map cipher state to ciphertext block (mu^{-1}): */ ciphertext[0] = (unsigned char)(state >> 56); ciphertext[1] = (unsigned char)(state >> 48); ciphertext[2] = (unsigned char)(state >> 40); ciphertext[3] = (unsigned char)(state >> 32); ciphertext[4] = (unsigned char)(state >> 24); ciphertext[5] = (unsigned char)(state >> 16); ciphertext[6] = (unsigned char)(state >> 8); ciphertext[7] = (unsigned char)(state ); } /** Encrypts a block of text with Khazad @param pt The input plaintext (8 bytes) @param ct The output ciphertext (8 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ int khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) { LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); khazad_crypt(pt, ct, skey->khazad.roundKeyEnc); return CRYPT_OK; } /** Decrypts a block of text with Khazad @param ct The input ciphertext (8 bytes) @param pt The output plaintext (8 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ int khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) { LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); khazad_crypt(ct, pt, skey->khazad.roundKeyDec); return CRYPT_OK; } /** Performs a self-test of the Khazad block cipher @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled */ int khazad_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct test { unsigned char pt[8], ct[8], key[16]; } tests[] = { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x49, 0xA4, 0xCE, 0x32, 0xAC, 0x19, 0x0E, 0x3F }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x64, 0x5D, 0x77, 0x3E, 0x40, 0xAB, 0xDD, 0x53 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }, { { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x9E, 0x39, 0x98, 0x64, 0xF7, 0x8E, 0xCA, 0x02 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, { 0xA9, 0xDF, 0x3D, 0x2C, 0x64, 0xD3, 0xEA, 0x28 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }; int x, y; unsigned char buf[2][8]; symmetric_key skey; for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { khazad_setup(tests[x].key, 16, 0, &skey); khazad_ecb_encrypt(tests[x].pt, buf[0], &skey); khazad_ecb_decrypt(buf[0], buf[1], &skey); if (XMEMCMP(buf[0], tests[x].ct, 8) || XMEMCMP(buf[1], tests[x].pt, 8)) { return CRYPT_FAIL_TESTVECTOR; } for (y = 0; y < 1000; y++) khazad_ecb_encrypt(buf[0], buf[0], &skey); for (y = 0; y < 1000; y++) khazad_ecb_decrypt(buf[0], buf[0], &skey); if (XMEMCMP(buf[0], tests[x].ct, 8)) { return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } /** Terminate the context @param skey The scheduled key */ void khazad_done(symmetric_key *skey) { } /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. @return CRYPT_OK if the input key size is acceptable. */ int khazad_keysize(int *keysize) { LTC_ARGCHK(keysize != NULL); if (*keysize >= 16) { *keysize = 16; return CRYPT_OK; } else { return CRYPT_INVALID_KEYSIZE; } } #endif /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/khazad.c,v $ */ /* $Revision: 1.14 $ */ /* $Date: 2007/05/12 14:20:27 $ */ libtomcrypt-1.17/src/ciphers/des.c0000644000175100001440000045104710621351501015701 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ #include "tomcrypt.h" /** @file des.c LTC_DES code submitted by Dobes Vandermeer */ #ifdef LTC_DES #define EN0 0 #define DE1 1 const struct ltc_cipher_descriptor des_desc = { "des", 13, 8, 8, 8, 16, &des_setup, &des_ecb_encrypt, &des_ecb_decrypt, &des_test, &des_done, &des_keysize, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; const struct ltc_cipher_descriptor des3_desc = { "3des", 14, 24, 24, 8, 16, &des3_setup, &des3_ecb_encrypt, &des3_ecb_decrypt, &des3_test, &des3_done, &des3_keysize, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static const ulong32 bytebit[8] = { 0200, 0100, 040, 020, 010, 04, 02, 01 }; static const ulong32 bigbyte[24] = { 0x800000UL, 0x400000UL, 0x200000UL, 0x100000UL, 0x80000UL, 0x40000UL, 0x20000UL, 0x10000UL, 0x8000UL, 0x4000UL, 0x2000UL, 0x1000UL, 0x800UL, 0x400UL, 0x200UL, 0x100UL, 0x80UL, 0x40UL, 0x20UL, 0x10UL, 0x8UL, 0x4UL, 0x2UL, 0x1L }; /* Use the key schedule specific in the standard (ANSI X3.92-1981) */ static const unsigned char pc1[56] = { 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 }; static const unsigned char totrot[16] = { 1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28 }; static const unsigned char pc2[48] = { 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 }; static const ulong32 SP1[64] = { 0x01010400UL, 0x00000000UL, 0x00010000UL, 0x01010404UL, 0x01010004UL, 0x00010404UL, 0x00000004UL, 0x00010000UL, 0x00000400UL, 0x01010400UL, 0x01010404UL, 0x00000400UL, 0x01000404UL, 0x01010004UL, 0x01000000UL, 0x00000004UL, 0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00010400UL, 0x00010400UL, 0x01010000UL, 0x01010000UL, 0x01000404UL, 0x00010004UL, 0x01000004UL, 0x01000004UL, 0x00010004UL, 0x00000000UL, 0x00000404UL, 0x00010404UL, 0x01000000UL, 0x00010000UL, 0x01010404UL, 0x00000004UL, 0x01010000UL, 0x01010400UL, 0x01000000UL, 0x01000000UL, 0x00000400UL, 0x01010004UL, 0x00010000UL, 0x00010400UL, 0x01000004UL, 0x00000400UL, 0x00000004UL, 0x01000404UL, 0x00010404UL, 0x01010404UL, 0x00010004UL, 0x01010000UL, 0x01000404UL, 0x01000004UL, 0x00000404UL, 0x00010404UL, 0x01010400UL, 0x00000404UL, 0x01000400UL, 0x01000400UL, 0x00000000UL, 0x00010004UL, 0x00010400UL, 0x00000000UL, 0x01010004UL }; static const ulong32 SP2[64] = { 0x80108020UL, 0x80008000UL, 0x00008000UL, 0x00108020UL, 0x00100000UL, 0x00000020UL, 0x80100020UL, 0x80008020UL, 0x80000020UL, 0x80108020UL, 0x80108000UL, 0x80000000UL, 0x80008000UL, 0x00100000UL, 0x00000020UL, 0x80100020UL, 0x00108000UL, 0x00100020UL, 0x80008020UL, 0x00000000UL, 0x80000000UL, 0x00008000UL, 0x00108020UL, 0x80100000UL, 0x00100020UL, 0x80000020UL, 0x00000000UL, 0x00108000UL, 0x00008020UL, 0x80108000UL, 0x80100000UL, 0x00008020UL, 0x00000000UL, 0x00108020UL, 0x80100020UL, 0x00100000UL, 0x80008020UL, 0x80100000UL, 0x80108000UL, 0x00008000UL, 0x80100000UL, 0x80008000UL, 0x00000020UL, 0x80108020UL, 0x00108020UL, 0x00000020UL, 0x00008000UL, 0x80000000UL, 0x00008020UL, 0x80108000UL, 0x00100000UL, 0x80000020UL, 0x00100020UL, 0x80008020UL, 0x80000020UL, 0x00100020UL, 0x00108000UL, 0x00000000UL, 0x80008000UL, 0x00008020UL, 0x80000000UL, 0x80100020UL, 0x80108020UL, 0x00108000UL }; static const ulong32 SP3[64] = { 0x00000208UL, 0x08020200UL, 0x00000000UL, 0x08020008UL, 0x08000200UL, 0x00000000UL, 0x00020208UL, 0x08000200UL, 0x00020008UL, 0x08000008UL, 0x08000008UL, 0x00020000UL, 0x08020208UL, 0x00020008UL, 0x08020000UL, 0x00000208UL, 0x08000000UL, 0x00000008UL, 0x08020200UL, 0x00000200UL, 0x00020200UL, 0x08020000UL, 0x08020008UL, 0x00020208UL, 0x08000208UL, 0x00020200UL, 0x00020000UL, 0x08000208UL, 0x00000008UL, 0x08020208UL, 0x00000200UL, 0x08000000UL, 0x08020200UL, 0x08000000UL, 0x00020008UL, 0x00000208UL, 0x00020000UL, 0x08020200UL, 0x08000200UL, 0x00000000UL, 0x00000200UL, 0x00020008UL, 0x08020208UL, 0x08000200UL, 0x08000008UL, 0x00000200UL, 0x00000000UL, 0x08020008UL, 0x08000208UL, 0x00020000UL, 0x08000000UL, 0x08020208UL, 0x00000008UL, 0x00020208UL, 0x00020200UL, 0x08000008UL, 0x08020000UL, 0x08000208UL, 0x00000208UL, 0x08020000UL, 0x00020208UL, 0x00000008UL, 0x08020008UL, 0x00020200UL }; static const ulong32 SP4[64] = { 0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL, 0x00802080UL, 0x00800081UL, 0x00800001UL, 0x00002001UL, 0x00000000UL, 0x00802000UL, 0x00802000UL, 0x00802081UL, 0x00000081UL, 0x00000000UL, 0x00800080UL, 0x00800001UL, 0x00000001UL, 0x00002000UL, 0x00800000UL, 0x00802001UL, 0x00000080UL, 0x00800000UL, 0x00002001UL, 0x00002080UL, 0x00800081UL, 0x00000001UL, 0x00002080UL, 0x00800080UL, 0x00002000UL, 0x00802080UL, 0x00802081UL, 0x00000081UL, 0x00800080UL, 0x00800001UL, 0x00802000UL, 0x00802081UL, 0x00000081UL, 0x00000000UL, 0x00000000UL, 0x00802000UL, 0x00002080UL, 0x00800080UL, 0x00800081UL, 0x00000001UL, 0x00802001UL, 0x00002081UL, 0x00002081UL, 0x00000080UL, 0x00802081UL, 0x00000081UL, 0x00000001UL, 0x00002000UL, 0x00800001UL, 0x00002001UL, 0x00802080UL, 0x00800081UL, 0x00002001UL, 0x00002080UL, 0x00800000UL, 0x00802001UL, 0x00000080UL, 0x00800000UL, 0x00002000UL, 0x00802080UL }; static const ulong32 SP5[64] = { 0x00000100UL, 0x02080100UL, 0x02080000UL, 0x42000100UL, 0x00080000UL, 0x00000100UL, 0x40000000UL, 0x02080000UL, 0x40080100UL, 0x00080000UL, 0x02000100UL, 0x40080100UL, 0x42000100UL, 0x42080000UL, 0x00080100UL, 0x40000000UL, 0x02000000UL, 0x40080000UL, 0x40080000UL, 0x00000000UL, 0x40000100UL, 0x42080100UL, 0x42080100UL, 0x02000100UL, 0x42080000UL, 0x40000100UL, 0x00000000UL, 0x42000000UL, 0x02080100UL, 0x02000000UL, 0x42000000UL, 0x00080100UL, 0x00080000UL, 0x42000100UL, 0x00000100UL, 0x02000000UL, 0x40000000UL, 0x02080000UL, 0x42000100UL, 0x40080100UL, 0x02000100UL, 0x40000000UL, 0x42080000UL, 0x02080100UL, 0x40080100UL, 0x00000100UL, 0x02000000UL, 0x42080000UL, 0x42080100UL, 0x00080100UL, 0x42000000UL, 0x42080100UL, 0x02080000UL, 0x00000000UL, 0x40080000UL, 0x42000000UL, 0x00080100UL, 0x02000100UL, 0x40000100UL, 0x00080000UL, 0x00000000UL, 0x40080000UL, 0x02080100UL, 0x40000100UL }; static const ulong32 SP6[64] = { 0x20000010UL, 0x20400000UL, 0x00004000UL, 0x20404010UL, 0x20400000UL, 0x00000010UL, 0x20404010UL, 0x00400000UL, 0x20004000UL, 0x00404010UL, 0x00400000UL, 0x20000010UL, 0x00400010UL, 0x20004000UL, 0x20000000UL, 0x00004010UL, 0x00000000UL, 0x00400010UL, 0x20004010UL, 0x00004000UL, 0x00404000UL, 0x20004010UL, 0x00000010UL, 0x20400010UL, 0x20400010UL, 0x00000000UL, 0x00404010UL, 0x20404000UL, 0x00004010UL, 0x00404000UL, 0x20404000UL, 0x20000000UL, 0x20004000UL, 0x00000010UL, 0x20400010UL, 0x00404000UL, 0x20404010UL, 0x00400000UL, 0x00004010UL, 0x20000010UL, 0x00400000UL, 0x20004000UL, 0x20000000UL, 0x00004010UL, 0x20000010UL, 0x20404010UL, 0x00404000UL, 0x20400000UL, 0x00404010UL, 0x20404000UL, 0x00000000UL, 0x20400010UL, 0x00000010UL, 0x00004000UL, 0x20400000UL, 0x00404010UL, 0x00004000UL, 0x00400010UL, 0x20004010UL, 0x00000000UL, 0x20404000UL, 0x20000000UL, 0x00400010UL, 0x20004010UL }; static const ulong32 SP7[64] = { 0x00200000UL, 0x04200002UL, 0x04000802UL, 0x00000000UL, 0x00000800UL, 0x04000802UL, 0x00200802UL, 0x04200800UL, 0x04200802UL, 0x00200000UL, 0x00000000UL, 0x04000002UL, 0x00000002UL, 0x04000000UL, 0x04200002UL, 0x00000802UL, 0x04000800UL, 0x00200802UL, 0x00200002UL, 0x04000800UL, 0x04000002UL, 0x04200000UL, 0x04200800UL, 0x00200002UL, 0x04200000UL, 0x00000800UL, 0x00000802UL, 0x04200802UL, 0x00200800UL, 0x00000002UL, 0x04000000UL, 0x00200800UL, 0x04000000UL, 0x00200800UL, 0x00200000UL, 0x04000802UL, 0x04000802UL, 0x04200002UL, 0x04200002UL, 0x00000002UL, 0x00200002UL, 0x04000000UL, 0x04000800UL, 0x00200000UL, 0x04200800UL, 0x00000802UL, 0x00200802UL, 0x04200800UL, 0x00000802UL, 0x04000002UL, 0x04200802UL, 0x04200000UL, 0x00200800UL, 0x00000000UL, 0x00000002UL, 0x04200802UL, 0x00000000UL, 0x00200802UL, 0x04200000UL, 0x00000800UL, 0x04000002UL, 0x04000800UL, 0x00000800UL, 0x00200002UL }; static const ulong32 SP8[64] = { 0x10001040UL, 0x00001000UL, 0x00040000UL, 0x10041040UL, 0x10000000UL, 0x10001040UL, 0x00000040UL, 0x10000000UL, 0x00040040UL, 0x10040000UL, 0x10041040UL, 0x00041000UL, 0x10041000UL, 0x00041040UL, 0x00001000UL, 0x00000040UL, 0x10040000UL, 0x10000040UL, 0x10001000UL, 0x00001040UL, 0x00041000UL, 0x00040040UL, 0x10040040UL, 0x10041000UL, 0x00001040UL, 0x00000000UL, 0x00000000UL, 0x10040040UL, 0x10000040UL, 0x10001000UL, 0x00041040UL, 0x00040000UL, 0x00041040UL, 0x00040000UL, 0x10041000UL, 0x00001000UL, 0x00000040UL, 0x10040040UL, 0x00001000UL, 0x00041040UL, 0x10001000UL, 0x00000040UL, 0x10000040UL, 0x10040000UL, 0x10040040UL, 0x10000000UL, 0x00040000UL, 0x10001040UL, 0x00000000UL, 0x10041040UL, 0x00040040UL, 0x10000040UL, 0x10040000UL, 0x10001000UL, 0x10001040UL, 0x00000000UL, 0x10041040UL, 0x00041000UL, 0x00041000UL, 0x00001040UL, 0x00001040UL, 0x00040040UL, 0x10000000UL, 0x10041000UL }; #ifndef LTC_SMALL_CODE static const ulong64 des_ip[8][256] = { { CONST64(0x0000000000000000), CONST64(0x0000001000000000), CONST64(0x0000000000000010), CONST64(0x0000001000000010), CONST64(0x0000100000000000), CONST64(0x0000101000000000), CONST64(0x0000100000000010), CONST64(0x0000101000000010), CONST64(0x0000000000001000), CONST64(0x0000001000001000), CONST64(0x0000000000001010), CONST64(0x0000001000001010), CONST64(0x0000100000001000), CONST64(0x0000101000001000), CONST64(0x0000100000001010), CONST64(0x0000101000001010), CONST64(0x0010000000000000), CONST64(0x0010001000000000), CONST64(0x0010000000000010), CONST64(0x0010001000000010), CONST64(0x0010100000000000), CONST64(0x0010101000000000), CONST64(0x0010100000000010), CONST64(0x0010101000000010), CONST64(0x0010000000001000), CONST64(0x0010001000001000), CONST64(0x0010000000001010), CONST64(0x0010001000001010), CONST64(0x0010100000001000), CONST64(0x0010101000001000), CONST64(0x0010100000001010), CONST64(0x0010101000001010), CONST64(0x0000000000100000), CONST64(0x0000001000100000), CONST64(0x0000000000100010), CONST64(0x0000001000100010), CONST64(0x0000100000100000), CONST64(0x0000101000100000), CONST64(0x0000100000100010), CONST64(0x0000101000100010), CONST64(0x0000000000101000), CONST64(0x0000001000101000), CONST64(0x0000000000101010), CONST64(0x0000001000101010), CONST64(0x0000100000101000), CONST64(0x0000101000101000), CONST64(0x0000100000101010), CONST64(0x0000101000101010), CONST64(0x0010000000100000), CONST64(0x0010001000100000), CONST64(0x0010000000100010), CONST64(0x0010001000100010), CONST64(0x0010100000100000), CONST64(0x0010101000100000), CONST64(0x0010100000100010), CONST64(0x0010101000100010), CONST64(0x0010000000101000), CONST64(0x0010001000101000), CONST64(0x0010000000101010), CONST64(0x0010001000101010), CONST64(0x0010100000101000), CONST64(0x0010101000101000), CONST64(0x0010100000101010), CONST64(0x0010101000101010), CONST64(0x1000000000000000), CONST64(0x1000001000000000), CONST64(0x1000000000000010), CONST64(0x1000001000000010), CONST64(0x1000100000000000), CONST64(0x1000101000000000), CONST64(0x1000100000000010), CONST64(0x1000101000000010), CONST64(0x1000000000001000), CONST64(0x1000001000001000), CONST64(0x1000000000001010), CONST64(0x1000001000001010), CONST64(0x1000100000001000), CONST64(0x1000101000001000), CONST64(0x1000100000001010), CONST64(0x1000101000001010), CONST64(0x1010000000000000), CONST64(0x1010001000000000), CONST64(0x1010000000000010), CONST64(0x1010001000000010), CONST64(0x1010100000000000), CONST64(0x1010101000000000), CONST64(0x1010100000000010), CONST64(0x1010101000000010), CONST64(0x1010000000001000), CONST64(0x1010001000001000), CONST64(0x1010000000001010), CONST64(0x1010001000001010), CONST64(0x1010100000001000), CONST64(0x1010101000001000), CONST64(0x1010100000001010), CONST64(0x1010101000001010), CONST64(0x1000000000100000), CONST64(0x1000001000100000), CONST64(0x1000000000100010), CONST64(0x1000001000100010), CONST64(0x1000100000100000), CONST64(0x1000101000100000), CONST64(0x1000100000100010), CONST64(0x1000101000100010), CONST64(0x1000000000101000), CONST64(0x1000001000101000), CONST64(0x1000000000101010), CONST64(0x1000001000101010), CONST64(0x1000100000101000), CONST64(0x1000101000101000), CONST64(0x1000100000101010), CONST64(0x1000101000101010), CONST64(0x1010000000100000), CONST64(0x1010001000100000), CONST64(0x1010000000100010), CONST64(0x1010001000100010), CONST64(0x1010100000100000), CONST64(0x1010101000100000), CONST64(0x1010100000100010), CONST64(0x1010101000100010), CONST64(0x1010000000101000), CONST64(0x1010001000101000), CONST64(0x1010000000101010), CONST64(0x1010001000101010), CONST64(0x1010100000101000), CONST64(0x1010101000101000), CONST64(0x1010100000101010), CONST64(0x1010101000101010), CONST64(0x0000000010000000), CONST64(0x0000001010000000), CONST64(0x0000000010000010), CONST64(0x0000001010000010), CONST64(0x0000100010000000), CONST64(0x0000101010000000), CONST64(0x0000100010000010), CONST64(0x0000101010000010), CONST64(0x0000000010001000), CONST64(0x0000001010001000), CONST64(0x0000000010001010), CONST64(0x0000001010001010), CONST64(0x0000100010001000), CONST64(0x0000101010001000), CONST64(0x0000100010001010), CONST64(0x0000101010001010), CONST64(0x0010000010000000), CONST64(0x0010001010000000), CONST64(0x0010000010000010), CONST64(0x0010001010000010), CONST64(0x0010100010000000), CONST64(0x0010101010000000), CONST64(0x0010100010000010), CONST64(0x0010101010000010), CONST64(0x0010000010001000), CONST64(0x0010001010001000), CONST64(0x0010000010001010), CONST64(0x0010001010001010), CONST64(0x0010100010001000), CONST64(0x0010101010001000), CONST64(0x0010100010001010), CONST64(0x0010101010001010), CONST64(0x0000000010100000), CONST64(0x0000001010100000), CONST64(0x0000000010100010), CONST64(0x0000001010100010), CONST64(0x0000100010100000), CONST64(0x0000101010100000), CONST64(0x0000100010100010), CONST64(0x0000101010100010), CONST64(0x0000000010101000), CONST64(0x0000001010101000), CONST64(0x0000000010101010), CONST64(0x0000001010101010), CONST64(0x0000100010101000), CONST64(0x0000101010101000), CONST64(0x0000100010101010), CONST64(0x0000101010101010), CONST64(0x0010000010100000), CONST64(0x0010001010100000), CONST64(0x0010000010100010), CONST64(0x0010001010100010), CONST64(0x0010100010100000), CONST64(0x0010101010100000), CONST64(0x0010100010100010), CONST64(0x0010101010100010), CONST64(0x0010000010101000), CONST64(0x0010001010101000), CONST64(0x0010000010101010), CONST64(0x0010001010101010), CONST64(0x0010100010101000), CONST64(0x0010101010101000), CONST64(0x0010100010101010), CONST64(0x0010101010101010), CONST64(0x1000000010000000), CONST64(0x1000001010000000), CONST64(0x1000000010000010), CONST64(0x1000001010000010), CONST64(0x1000100010000000), CONST64(0x1000101010000000), CONST64(0x1000100010000010), CONST64(0x1000101010000010), CONST64(0x1000000010001000), CONST64(0x1000001010001000), CONST64(0x1000000010001010), CONST64(0x1000001010001010), CONST64(0x1000100010001000), CONST64(0x1000101010001000), CONST64(0x1000100010001010), CONST64(0x1000101010001010), CONST64(0x1010000010000000), CONST64(0x1010001010000000), CONST64(0x1010000010000010), CONST64(0x1010001010000010), CONST64(0x1010100010000000), CONST64(0x1010101010000000), CONST64(0x1010100010000010), CONST64(0x1010101010000010), CONST64(0x1010000010001000), CONST64(0x1010001010001000), CONST64(0x1010000010001010), CONST64(0x1010001010001010), CONST64(0x1010100010001000), CONST64(0x1010101010001000), CONST64(0x1010100010001010), CONST64(0x1010101010001010), CONST64(0x1000000010100000), CONST64(0x1000001010100000), CONST64(0x1000000010100010), CONST64(0x1000001010100010), CONST64(0x1000100010100000), CONST64(0x1000101010100000), CONST64(0x1000100010100010), CONST64(0x1000101010100010), CONST64(0x1000000010101000), CONST64(0x1000001010101000), CONST64(0x1000000010101010), CONST64(0x1000001010101010), CONST64(0x1000100010101000), CONST64(0x1000101010101000), CONST64(0x1000100010101010), CONST64(0x1000101010101010), CONST64(0x1010000010100000), CONST64(0x1010001010100000), CONST64(0x1010000010100010), CONST64(0x1010001010100010), CONST64(0x1010100010100000), CONST64(0x1010101010100000), CONST64(0x1010100010100010), CONST64(0x1010101010100010), CONST64(0x1010000010101000), CONST64(0x1010001010101000), CONST64(0x1010000010101010), CONST64(0x1010001010101010), CONST64(0x1010100010101000), CONST64(0x1010101010101000), CONST64(0x1010100010101010), CONST64(0x1010101010101010) }, { CONST64(0x0000000000000000), CONST64(0x0000000800000000), CONST64(0x0000000000000008), CONST64(0x0000000800000008), CONST64(0x0000080000000000), CONST64(0x0000080800000000), CONST64(0x0000080000000008), CONST64(0x0000080800000008), CONST64(0x0000000000000800), CONST64(0x0000000800000800), CONST64(0x0000000000000808), CONST64(0x0000000800000808), CONST64(0x0000080000000800), CONST64(0x0000080800000800), CONST64(0x0000080000000808), CONST64(0x0000080800000808), CONST64(0x0008000000000000), CONST64(0x0008000800000000), CONST64(0x0008000000000008), CONST64(0x0008000800000008), CONST64(0x0008080000000000), CONST64(0x0008080800000000), CONST64(0x0008080000000008), CONST64(0x0008080800000008), CONST64(0x0008000000000800), CONST64(0x0008000800000800), CONST64(0x0008000000000808), CONST64(0x0008000800000808), CONST64(0x0008080000000800), CONST64(0x0008080800000800), CONST64(0x0008080000000808), CONST64(0x0008080800000808), CONST64(0x0000000000080000), CONST64(0x0000000800080000), CONST64(0x0000000000080008), CONST64(0x0000000800080008), CONST64(0x0000080000080000), CONST64(0x0000080800080000), CONST64(0x0000080000080008), CONST64(0x0000080800080008), CONST64(0x0000000000080800), CONST64(0x0000000800080800), CONST64(0x0000000000080808), CONST64(0x0000000800080808), CONST64(0x0000080000080800), CONST64(0x0000080800080800), CONST64(0x0000080000080808), CONST64(0x0000080800080808), CONST64(0x0008000000080000), CONST64(0x0008000800080000), CONST64(0x0008000000080008), CONST64(0x0008000800080008), CONST64(0x0008080000080000), CONST64(0x0008080800080000), CONST64(0x0008080000080008), CONST64(0x0008080800080008), CONST64(0x0008000000080800), CONST64(0x0008000800080800), CONST64(0x0008000000080808), CONST64(0x0008000800080808), CONST64(0x0008080000080800), CONST64(0x0008080800080800), CONST64(0x0008080000080808), CONST64(0x0008080800080808), CONST64(0x0800000000000000), CONST64(0x0800000800000000), CONST64(0x0800000000000008), CONST64(0x0800000800000008), CONST64(0x0800080000000000), CONST64(0x0800080800000000), CONST64(0x0800080000000008), CONST64(0x0800080800000008), CONST64(0x0800000000000800), CONST64(0x0800000800000800), CONST64(0x0800000000000808), CONST64(0x0800000800000808), CONST64(0x0800080000000800), CONST64(0x0800080800000800), CONST64(0x0800080000000808), CONST64(0x0800080800000808), CONST64(0x0808000000000000), CONST64(0x0808000800000000), CONST64(0x0808000000000008), CONST64(0x0808000800000008), CONST64(0x0808080000000000), CONST64(0x0808080800000000), CONST64(0x0808080000000008), CONST64(0x0808080800000008), CONST64(0x0808000000000800), CONST64(0x0808000800000800), CONST64(0x0808000000000808), CONST64(0x0808000800000808), CONST64(0x0808080000000800), CONST64(0x0808080800000800), CONST64(0x0808080000000808), CONST64(0x0808080800000808), CONST64(0x0800000000080000), CONST64(0x0800000800080000), CONST64(0x0800000000080008), CONST64(0x0800000800080008), CONST64(0x0800080000080000), CONST64(0x0800080800080000), CONST64(0x0800080000080008), CONST64(0x0800080800080008), CONST64(0x0800000000080800), CONST64(0x0800000800080800), CONST64(0x0800000000080808), CONST64(0x0800000800080808), CONST64(0x0800080000080800), CONST64(0x0800080800080800), CONST64(0x0800080000080808), CONST64(0x0800080800080808), CONST64(0x0808000000080000), CONST64(0x0808000800080000), CONST64(0x0808000000080008), CONST64(0x0808000800080008), CONST64(0x0808080000080000), CONST64(0x0808080800080000), CONST64(0x0808080000080008), CONST64(0x0808080800080008), CONST64(0x0808000000080800), CONST64(0x0808000800080800), CONST64(0x0808000000080808), CONST64(0x0808000800080808), CONST64(0x0808080000080800), CONST64(0x0808080800080800), CONST64(0x0808080000080808), CONST64(0x0808080800080808), CONST64(0x0000000008000000), CONST64(0x0000000808000000), CONST64(0x0000000008000008), CONST64(0x0000000808000008), CONST64(0x0000080008000000), CONST64(0x0000080808000000), CONST64(0x0000080008000008), CONST64(0x0000080808000008), CONST64(0x0000000008000800), CONST64(0x0000000808000800), CONST64(0x0000000008000808), CONST64(0x0000000808000808), CONST64(0x0000080008000800), CONST64(0x0000080808000800), CONST64(0x0000080008000808), CONST64(0x0000080808000808), CONST64(0x0008000008000000), CONST64(0x0008000808000000), CONST64(0x0008000008000008), CONST64(0x0008000808000008), CONST64(0x0008080008000000), CONST64(0x0008080808000000), CONST64(0x0008080008000008), CONST64(0x0008080808000008), CONST64(0x0008000008000800), CONST64(0x0008000808000800), CONST64(0x0008000008000808), CONST64(0x0008000808000808), CONST64(0x0008080008000800), CONST64(0x0008080808000800), CONST64(0x0008080008000808), CONST64(0x0008080808000808), CONST64(0x0000000008080000), CONST64(0x0000000808080000), CONST64(0x0000000008080008), CONST64(0x0000000808080008), CONST64(0x0000080008080000), CONST64(0x0000080808080000), CONST64(0x0000080008080008), CONST64(0x0000080808080008), CONST64(0x0000000008080800), CONST64(0x0000000808080800), CONST64(0x0000000008080808), CONST64(0x0000000808080808), CONST64(0x0000080008080800), CONST64(0x0000080808080800), CONST64(0x0000080008080808), CONST64(0x0000080808080808), CONST64(0x0008000008080000), CONST64(0x0008000808080000), CONST64(0x0008000008080008), CONST64(0x0008000808080008), CONST64(0x0008080008080000), CONST64(0x0008080808080000), CONST64(0x0008080008080008), CONST64(0x0008080808080008), CONST64(0x0008000008080800), CONST64(0x0008000808080800), CONST64(0x0008000008080808), CONST64(0x0008000808080808), CONST64(0x0008080008080800), CONST64(0x0008080808080800), CONST64(0x0008080008080808), CONST64(0x0008080808080808), CONST64(0x0800000008000000), CONST64(0x0800000808000000), CONST64(0x0800000008000008), CONST64(0x0800000808000008), CONST64(0x0800080008000000), CONST64(0x0800080808000000), CONST64(0x0800080008000008), CONST64(0x0800080808000008), CONST64(0x0800000008000800), CONST64(0x0800000808000800), CONST64(0x0800000008000808), CONST64(0x0800000808000808), CONST64(0x0800080008000800), CONST64(0x0800080808000800), CONST64(0x0800080008000808), CONST64(0x0800080808000808), CONST64(0x0808000008000000), CONST64(0x0808000808000000), CONST64(0x0808000008000008), CONST64(0x0808000808000008), CONST64(0x0808080008000000), CONST64(0x0808080808000000), CONST64(0x0808080008000008), CONST64(0x0808080808000008), CONST64(0x0808000008000800), CONST64(0x0808000808000800), CONST64(0x0808000008000808), CONST64(0x0808000808000808), CONST64(0x0808080008000800), CONST64(0x0808080808000800), CONST64(0x0808080008000808), CONST64(0x0808080808000808), CONST64(0x0800000008080000), CONST64(0x0800000808080000), CONST64(0x0800000008080008), CONST64(0x0800000808080008), CONST64(0x0800080008080000), CONST64(0x0800080808080000), CONST64(0x0800080008080008), CONST64(0x0800080808080008), CONST64(0x0800000008080800), CONST64(0x0800000808080800), CONST64(0x0800000008080808), CONST64(0x0800000808080808), CONST64(0x0800080008080800), CONST64(0x0800080808080800), CONST64(0x0800080008080808), CONST64(0x0800080808080808), CONST64(0x0808000008080000), CONST64(0x0808000808080000), CONST64(0x0808000008080008), CONST64(0x0808000808080008), CONST64(0x0808080008080000), CONST64(0x0808080808080000), CONST64(0x0808080008080008), CONST64(0x0808080808080008), CONST64(0x0808000008080800), CONST64(0x0808000808080800), CONST64(0x0808000008080808), CONST64(0x0808000808080808), CONST64(0x0808080008080800), CONST64(0x0808080808080800), CONST64(0x0808080008080808), CONST64(0x0808080808080808) }, { CONST64(0x0000000000000000), CONST64(0x0000000400000000), CONST64(0x0000000000000004), CONST64(0x0000000400000004), CONST64(0x0000040000000000), CONST64(0x0000040400000000), CONST64(0x0000040000000004), CONST64(0x0000040400000004), CONST64(0x0000000000000400), CONST64(0x0000000400000400), CONST64(0x0000000000000404), CONST64(0x0000000400000404), CONST64(0x0000040000000400), CONST64(0x0000040400000400), CONST64(0x0000040000000404), CONST64(0x0000040400000404), CONST64(0x0004000000000000), CONST64(0x0004000400000000), CONST64(0x0004000000000004), CONST64(0x0004000400000004), CONST64(0x0004040000000000), CONST64(0x0004040400000000), CONST64(0x0004040000000004), CONST64(0x0004040400000004), CONST64(0x0004000000000400), CONST64(0x0004000400000400), CONST64(0x0004000000000404), CONST64(0x0004000400000404), CONST64(0x0004040000000400), CONST64(0x0004040400000400), CONST64(0x0004040000000404), CONST64(0x0004040400000404), CONST64(0x0000000000040000), CONST64(0x0000000400040000), CONST64(0x0000000000040004), CONST64(0x0000000400040004), CONST64(0x0000040000040000), CONST64(0x0000040400040000), CONST64(0x0000040000040004), CONST64(0x0000040400040004), CONST64(0x0000000000040400), CONST64(0x0000000400040400), CONST64(0x0000000000040404), CONST64(0x0000000400040404), CONST64(0x0000040000040400), CONST64(0x0000040400040400), CONST64(0x0000040000040404), CONST64(0x0000040400040404), CONST64(0x0004000000040000), CONST64(0x0004000400040000), CONST64(0x0004000000040004), CONST64(0x0004000400040004), CONST64(0x0004040000040000), CONST64(0x0004040400040000), CONST64(0x0004040000040004), CONST64(0x0004040400040004), CONST64(0x0004000000040400), CONST64(0x0004000400040400), CONST64(0x0004000000040404), CONST64(0x0004000400040404), CONST64(0x0004040000040400), CONST64(0x0004040400040400), CONST64(0x0004040000040404), CONST64(0x0004040400040404), CONST64(0x0400000000000000), CONST64(0x0400000400000000), CONST64(0x0400000000000004), CONST64(0x0400000400000004), CONST64(0x0400040000000000), CONST64(0x0400040400000000), CONST64(0x0400040000000004), CONST64(0x0400040400000004), CONST64(0x0400000000000400), CONST64(0x0400000400000400), CONST64(0x0400000000000404), CONST64(0x0400000400000404), CONST64(0x0400040000000400), CONST64(0x0400040400000400), CONST64(0x0400040000000404), CONST64(0x0400040400000404), CONST64(0x0404000000000000), CONST64(0x0404000400000000), CONST64(0x0404000000000004), CONST64(0x0404000400000004), CONST64(0x0404040000000000), CONST64(0x0404040400000000), CONST64(0x0404040000000004), CONST64(0x0404040400000004), CONST64(0x0404000000000400), CONST64(0x0404000400000400), CONST64(0x0404000000000404), CONST64(0x0404000400000404), CONST64(0x0404040000000400), CONST64(0x0404040400000400), CONST64(0x0404040000000404), CONST64(0x0404040400000404), CONST64(0x0400000000040000), CONST64(0x0400000400040000), CONST64(0x0400000000040004), CONST64(0x0400000400040004), CONST64(0x0400040000040000), CONST64(0x0400040400040000), CONST64(0x0400040000040004), CONST64(0x0400040400040004), CONST64(0x0400000000040400), CONST64(0x0400000400040400), CONST64(0x0400000000040404), CONST64(0x0400000400040404), CONST64(0x0400040000040400), CONST64(0x0400040400040400), CONST64(0x0400040000040404), CONST64(0x0400040400040404), CONST64(0x0404000000040000), CONST64(0x0404000400040000), CONST64(0x0404000000040004), CONST64(0x0404000400040004), CONST64(0x0404040000040000), CONST64(0x0404040400040000), CONST64(0x0404040000040004), CONST64(0x0404040400040004), CONST64(0x0404000000040400), CONST64(0x0404000400040400), CONST64(0x0404000000040404), CONST64(0x0404000400040404), CONST64(0x0404040000040400), CONST64(0x0404040400040400), CONST64(0x0404040000040404), CONST64(0x0404040400040404), CONST64(0x0000000004000000), CONST64(0x0000000404000000), CONST64(0x0000000004000004), CONST64(0x0000000404000004), CONST64(0x0000040004000000), CONST64(0x0000040404000000), CONST64(0x0000040004000004), CONST64(0x0000040404000004), CONST64(0x0000000004000400), CONST64(0x0000000404000400), CONST64(0x0000000004000404), CONST64(0x0000000404000404), CONST64(0x0000040004000400), CONST64(0x0000040404000400), CONST64(0x0000040004000404), CONST64(0x0000040404000404), CONST64(0x0004000004000000), CONST64(0x0004000404000000), CONST64(0x0004000004000004), CONST64(0x0004000404000004), CONST64(0x0004040004000000), CONST64(0x0004040404000000), CONST64(0x0004040004000004), CONST64(0x0004040404000004), CONST64(0x0004000004000400), CONST64(0x0004000404000400), CONST64(0x0004000004000404), CONST64(0x0004000404000404), CONST64(0x0004040004000400), CONST64(0x0004040404000400), CONST64(0x0004040004000404), CONST64(0x0004040404000404), CONST64(0x0000000004040000), CONST64(0x0000000404040000), CONST64(0x0000000004040004), CONST64(0x0000000404040004), CONST64(0x0000040004040000), CONST64(0x0000040404040000), CONST64(0x0000040004040004), CONST64(0x0000040404040004), CONST64(0x0000000004040400), CONST64(0x0000000404040400), CONST64(0x0000000004040404), CONST64(0x0000000404040404), CONST64(0x0000040004040400), CONST64(0x0000040404040400), CONST64(0x0000040004040404), CONST64(0x0000040404040404), CONST64(0x0004000004040000), CONST64(0x0004000404040000), CONST64(0x0004000004040004), CONST64(0x0004000404040004), CONST64(0x0004040004040000), CONST64(0x0004040404040000), CONST64(0x0004040004040004), CONST64(0x0004040404040004), CONST64(0x0004000004040400), CONST64(0x0004000404040400), CONST64(0x0004000004040404), CONST64(0x0004000404040404), CONST64(0x0004040004040400), CONST64(0x0004040404040400), CONST64(0x0004040004040404), CONST64(0x0004040404040404), CONST64(0x0400000004000000), CONST64(0x0400000404000000), CONST64(0x0400000004000004), CONST64(0x0400000404000004), CONST64(0x0400040004000000), CONST64(0x0400040404000000), CONST64(0x0400040004000004), CONST64(0x0400040404000004), CONST64(0x0400000004000400), CONST64(0x0400000404000400), CONST64(0x0400000004000404), CONST64(0x0400000404000404), CONST64(0x0400040004000400), CONST64(0x0400040404000400), CONST64(0x0400040004000404), CONST64(0x0400040404000404), CONST64(0x0404000004000000), CONST64(0x0404000404000000), CONST64(0x0404000004000004), CONST64(0x0404000404000004), CONST64(0x0404040004000000), CONST64(0x0404040404000000), CONST64(0x0404040004000004), CONST64(0x0404040404000004), CONST64(0x0404000004000400), CONST64(0x0404000404000400), CONST64(0x0404000004000404), CONST64(0x0404000404000404), CONST64(0x0404040004000400), CONST64(0x0404040404000400), CONST64(0x0404040004000404), CONST64(0x0404040404000404), CONST64(0x0400000004040000), CONST64(0x0400000404040000), CONST64(0x0400000004040004), CONST64(0x0400000404040004), CONST64(0x0400040004040000), CONST64(0x0400040404040000), CONST64(0x0400040004040004), CONST64(0x0400040404040004), CONST64(0x0400000004040400), CONST64(0x0400000404040400), CONST64(0x0400000004040404), CONST64(0x0400000404040404), CONST64(0x0400040004040400), CONST64(0x0400040404040400), CONST64(0x0400040004040404), CONST64(0x0400040404040404), CONST64(0x0404000004040000), CONST64(0x0404000404040000), CONST64(0x0404000004040004), CONST64(0x0404000404040004), CONST64(0x0404040004040000), CONST64(0x0404040404040000), CONST64(0x0404040004040004), CONST64(0x0404040404040004), CONST64(0x0404000004040400), CONST64(0x0404000404040400), CONST64(0x0404000004040404), CONST64(0x0404000404040404), CONST64(0x0404040004040400), CONST64(0x0404040404040400), CONST64(0x0404040004040404), CONST64(0x0404040404040404) }, { CONST64(0x0000000000000000), CONST64(0x0000000200000000), CONST64(0x0000000000000002), CONST64(0x0000000200000002), CONST64(0x0000020000000000), CONST64(0x0000020200000000), CONST64(0x0000020000000002), CONST64(0x0000020200000002), CONST64(0x0000000000000200), CONST64(0x0000000200000200), CONST64(0x0000000000000202), CONST64(0x0000000200000202), CONST64(0x0000020000000200), CONST64(0x0000020200000200), CONST64(0x0000020000000202), CONST64(0x0000020200000202), CONST64(0x0002000000000000), CONST64(0x0002000200000000), CONST64(0x0002000000000002), CONST64(0x0002000200000002), CONST64(0x0002020000000000), CONST64(0x0002020200000000), CONST64(0x0002020000000002), CONST64(0x0002020200000002), CONST64(0x0002000000000200), CONST64(0x0002000200000200), CONST64(0x0002000000000202), CONST64(0x0002000200000202), CONST64(0x0002020000000200), CONST64(0x0002020200000200), CONST64(0x0002020000000202), CONST64(0x0002020200000202), CONST64(0x0000000000020000), CONST64(0x0000000200020000), CONST64(0x0000000000020002), CONST64(0x0000000200020002), CONST64(0x0000020000020000), CONST64(0x0000020200020000), CONST64(0x0000020000020002), CONST64(0x0000020200020002), CONST64(0x0000000000020200), CONST64(0x0000000200020200), CONST64(0x0000000000020202), CONST64(0x0000000200020202), CONST64(0x0000020000020200), CONST64(0x0000020200020200), CONST64(0x0000020000020202), CONST64(0x0000020200020202), CONST64(0x0002000000020000), CONST64(0x0002000200020000), CONST64(0x0002000000020002), CONST64(0x0002000200020002), CONST64(0x0002020000020000), CONST64(0x0002020200020000), CONST64(0x0002020000020002), CONST64(0x0002020200020002), CONST64(0x0002000000020200), CONST64(0x0002000200020200), CONST64(0x0002000000020202), CONST64(0x0002000200020202), CONST64(0x0002020000020200), CONST64(0x0002020200020200), CONST64(0x0002020000020202), CONST64(0x0002020200020202), CONST64(0x0200000000000000), CONST64(0x0200000200000000), CONST64(0x0200000000000002), CONST64(0x0200000200000002), CONST64(0x0200020000000000), CONST64(0x0200020200000000), CONST64(0x0200020000000002), CONST64(0x0200020200000002), CONST64(0x0200000000000200), CONST64(0x0200000200000200), CONST64(0x0200000000000202), CONST64(0x0200000200000202), CONST64(0x0200020000000200), CONST64(0x0200020200000200), CONST64(0x0200020000000202), CONST64(0x0200020200000202), CONST64(0x0202000000000000), CONST64(0x0202000200000000), CONST64(0x0202000000000002), CONST64(0x0202000200000002), CONST64(0x0202020000000000), CONST64(0x0202020200000000), CONST64(0x0202020000000002), CONST64(0x0202020200000002), CONST64(0x0202000000000200), CONST64(0x0202000200000200), CONST64(0x0202000000000202), CONST64(0x0202000200000202), CONST64(0x0202020000000200), CONST64(0x0202020200000200), CONST64(0x0202020000000202), CONST64(0x0202020200000202), CONST64(0x0200000000020000), CONST64(0x0200000200020000), CONST64(0x0200000000020002), CONST64(0x0200000200020002), CONST64(0x0200020000020000), CONST64(0x0200020200020000), CONST64(0x0200020000020002), CONST64(0x0200020200020002), CONST64(0x0200000000020200), CONST64(0x0200000200020200), CONST64(0x0200000000020202), CONST64(0x0200000200020202), CONST64(0x0200020000020200), CONST64(0x0200020200020200), CONST64(0x0200020000020202), CONST64(0x0200020200020202), CONST64(0x0202000000020000), CONST64(0x0202000200020000), CONST64(0x0202000000020002), CONST64(0x0202000200020002), CONST64(0x0202020000020000), CONST64(0x0202020200020000), CONST64(0x0202020000020002), CONST64(0x0202020200020002), CONST64(0x0202000000020200), CONST64(0x0202000200020200), CONST64(0x0202000000020202), CONST64(0x0202000200020202), CONST64(0x0202020000020200), CONST64(0x0202020200020200), CONST64(0x0202020000020202), CONST64(0x0202020200020202), CONST64(0x0000000002000000), CONST64(0x0000000202000000), CONST64(0x0000000002000002), CONST64(0x0000000202000002), CONST64(0x0000020002000000), CONST64(0x0000020202000000), CONST64(0x0000020002000002), CONST64(0x0000020202000002), CONST64(0x0000000002000200), CONST64(0x0000000202000200), CONST64(0x0000000002000202), CONST64(0x0000000202000202), CONST64(0x0000020002000200), CONST64(0x0000020202000200), CONST64(0x0000020002000202), CONST64(0x0000020202000202), CONST64(0x0002000002000000), CONST64(0x0002000202000000), CONST64(0x0002000002000002), CONST64(0x0002000202000002), CONST64(0x0002020002000000), CONST64(0x0002020202000000), CONST64(0x0002020002000002), CONST64(0x0002020202000002), CONST64(0x0002000002000200), CONST64(0x0002000202000200), CONST64(0x0002000002000202), CONST64(0x0002000202000202), CONST64(0x0002020002000200), CONST64(0x0002020202000200), CONST64(0x0002020002000202), CONST64(0x0002020202000202), CONST64(0x0000000002020000), CONST64(0x0000000202020000), CONST64(0x0000000002020002), CONST64(0x0000000202020002), CONST64(0x0000020002020000), CONST64(0x0000020202020000), CONST64(0x0000020002020002), CONST64(0x0000020202020002), CONST64(0x0000000002020200), CONST64(0x0000000202020200), CONST64(0x0000000002020202), CONST64(0x0000000202020202), CONST64(0x0000020002020200), CONST64(0x0000020202020200), CONST64(0x0000020002020202), CONST64(0x0000020202020202), CONST64(0x0002000002020000), CONST64(0x0002000202020000), CONST64(0x0002000002020002), CONST64(0x0002000202020002), CONST64(0x0002020002020000), CONST64(0x0002020202020000), CONST64(0x0002020002020002), CONST64(0x0002020202020002), CONST64(0x0002000002020200), CONST64(0x0002000202020200), CONST64(0x0002000002020202), CONST64(0x0002000202020202), CONST64(0x0002020002020200), CONST64(0x0002020202020200), CONST64(0x0002020002020202), CONST64(0x0002020202020202), CONST64(0x0200000002000000), CONST64(0x0200000202000000), CONST64(0x0200000002000002), CONST64(0x0200000202000002), CONST64(0x0200020002000000), CONST64(0x0200020202000000), CONST64(0x0200020002000002), CONST64(0x0200020202000002), CONST64(0x0200000002000200), CONST64(0x0200000202000200), CONST64(0x0200000002000202), CONST64(0x0200000202000202), CONST64(0x0200020002000200), CONST64(0x0200020202000200), CONST64(0x0200020002000202), CONST64(0x0200020202000202), CONST64(0x0202000002000000), CONST64(0x0202000202000000), CONST64(0x0202000002000002), CONST64(0x0202000202000002), CONST64(0x0202020002000000), CONST64(0x0202020202000000), CONST64(0x0202020002000002), CONST64(0x0202020202000002), CONST64(0x0202000002000200), CONST64(0x0202000202000200), CONST64(0x0202000002000202), CONST64(0x0202000202000202), CONST64(0x0202020002000200), CONST64(0x0202020202000200), CONST64(0x0202020002000202), CONST64(0x0202020202000202), CONST64(0x0200000002020000), CONST64(0x0200000202020000), CONST64(0x0200000002020002), CONST64(0x0200000202020002), CONST64(0x0200020002020000), CONST64(0x0200020202020000), CONST64(0x0200020002020002), CONST64(0x0200020202020002), CONST64(0x0200000002020200), CONST64(0x0200000202020200), CONST64(0x0200000002020202), CONST64(0x0200000202020202), CONST64(0x0200020002020200), CONST64(0x0200020202020200), CONST64(0x0200020002020202), CONST64(0x0200020202020202), CONST64(0x0202000002020000), CONST64(0x0202000202020000), CONST64(0x0202000002020002), CONST64(0x0202000202020002), CONST64(0x0202020002020000), CONST64(0x0202020202020000), CONST64(0x0202020002020002), CONST64(0x0202020202020002), CONST64(0x0202000002020200), CONST64(0x0202000202020200), CONST64(0x0202000002020202), CONST64(0x0202000202020202), CONST64(0x0202020002020200), CONST64(0x0202020202020200), CONST64(0x0202020002020202), CONST64(0x0202020202020202) }, { CONST64(0x0000000000000000), CONST64(0x0000010000000000), CONST64(0x0000000000000100), CONST64(0x0000010000000100), CONST64(0x0001000000000000), CONST64(0x0001010000000000), CONST64(0x0001000000000100), CONST64(0x0001010000000100), CONST64(0x0000000000010000), CONST64(0x0000010000010000), CONST64(0x0000000000010100), CONST64(0x0000010000010100), CONST64(0x0001000000010000), CONST64(0x0001010000010000), CONST64(0x0001000000010100), CONST64(0x0001010000010100), CONST64(0x0100000000000000), CONST64(0x0100010000000000), CONST64(0x0100000000000100), CONST64(0x0100010000000100), CONST64(0x0101000000000000), CONST64(0x0101010000000000), CONST64(0x0101000000000100), CONST64(0x0101010000000100), CONST64(0x0100000000010000), CONST64(0x0100010000010000), CONST64(0x0100000000010100), CONST64(0x0100010000010100), CONST64(0x0101000000010000), CONST64(0x0101010000010000), CONST64(0x0101000000010100), CONST64(0x0101010000010100), CONST64(0x0000000001000000), CONST64(0x0000010001000000), CONST64(0x0000000001000100), CONST64(0x0000010001000100), CONST64(0x0001000001000000), CONST64(0x0001010001000000), CONST64(0x0001000001000100), CONST64(0x0001010001000100), CONST64(0x0000000001010000), CONST64(0x0000010001010000), CONST64(0x0000000001010100), CONST64(0x0000010001010100), CONST64(0x0001000001010000), CONST64(0x0001010001010000), CONST64(0x0001000001010100), CONST64(0x0001010001010100), CONST64(0x0100000001000000), CONST64(0x0100010001000000), CONST64(0x0100000001000100), CONST64(0x0100010001000100), CONST64(0x0101000001000000), CONST64(0x0101010001000000), CONST64(0x0101000001000100), CONST64(0x0101010001000100), CONST64(0x0100000001010000), CONST64(0x0100010001010000), CONST64(0x0100000001010100), CONST64(0x0100010001010100), CONST64(0x0101000001010000), CONST64(0x0101010001010000), CONST64(0x0101000001010100), CONST64(0x0101010001010100), CONST64(0x0000000100000000), CONST64(0x0000010100000000), CONST64(0x0000000100000100), CONST64(0x0000010100000100), CONST64(0x0001000100000000), CONST64(0x0001010100000000), CONST64(0x0001000100000100), CONST64(0x0001010100000100), CONST64(0x0000000100010000), CONST64(0x0000010100010000), CONST64(0x0000000100010100), CONST64(0x0000010100010100), CONST64(0x0001000100010000), CONST64(0x0001010100010000), CONST64(0x0001000100010100), CONST64(0x0001010100010100), CONST64(0x0100000100000000), CONST64(0x0100010100000000), CONST64(0x0100000100000100), CONST64(0x0100010100000100), CONST64(0x0101000100000000), CONST64(0x0101010100000000), CONST64(0x0101000100000100), CONST64(0x0101010100000100), CONST64(0x0100000100010000), CONST64(0x0100010100010000), CONST64(0x0100000100010100), CONST64(0x0100010100010100), CONST64(0x0101000100010000), CONST64(0x0101010100010000), CONST64(0x0101000100010100), CONST64(0x0101010100010100), CONST64(0x0000000101000000), CONST64(0x0000010101000000), CONST64(0x0000000101000100), CONST64(0x0000010101000100), CONST64(0x0001000101000000), CONST64(0x0001010101000000), CONST64(0x0001000101000100), CONST64(0x0001010101000100), CONST64(0x0000000101010000), CONST64(0x0000010101010000), CONST64(0x0000000101010100), CONST64(0x0000010101010100), CONST64(0x0001000101010000), CONST64(0x0001010101010000), CONST64(0x0001000101010100), CONST64(0x0001010101010100), CONST64(0x0100000101000000), CONST64(0x0100010101000000), CONST64(0x0100000101000100), CONST64(0x0100010101000100), CONST64(0x0101000101000000), CONST64(0x0101010101000000), CONST64(0x0101000101000100), CONST64(0x0101010101000100), CONST64(0x0100000101010000), CONST64(0x0100010101010000), CONST64(0x0100000101010100), CONST64(0x0100010101010100), CONST64(0x0101000101010000), CONST64(0x0101010101010000), CONST64(0x0101000101010100), CONST64(0x0101010101010100), CONST64(0x0000000000000001), CONST64(0x0000010000000001), CONST64(0x0000000000000101), CONST64(0x0000010000000101), CONST64(0x0001000000000001), CONST64(0x0001010000000001), CONST64(0x0001000000000101), CONST64(0x0001010000000101), CONST64(0x0000000000010001), CONST64(0x0000010000010001), CONST64(0x0000000000010101), CONST64(0x0000010000010101), CONST64(0x0001000000010001), CONST64(0x0001010000010001), CONST64(0x0001000000010101), CONST64(0x0001010000010101), CONST64(0x0100000000000001), CONST64(0x0100010000000001), CONST64(0x0100000000000101), CONST64(0x0100010000000101), CONST64(0x0101000000000001), CONST64(0x0101010000000001), CONST64(0x0101000000000101), CONST64(0x0101010000000101), CONST64(0x0100000000010001), CONST64(0x0100010000010001), CONST64(0x0100000000010101), CONST64(0x0100010000010101), CONST64(0x0101000000010001), CONST64(0x0101010000010001), CONST64(0x0101000000010101), CONST64(0x0101010000010101), CONST64(0x0000000001000001), CONST64(0x0000010001000001), CONST64(0x0000000001000101), CONST64(0x0000010001000101), CONST64(0x0001000001000001), CONST64(0x0001010001000001), CONST64(0x0001000001000101), CONST64(0x0001010001000101), CONST64(0x0000000001010001), CONST64(0x0000010001010001), CONST64(0x0000000001010101), CONST64(0x0000010001010101), CONST64(0x0001000001010001), CONST64(0x0001010001010001), CONST64(0x0001000001010101), CONST64(0x0001010001010101), CONST64(0x0100000001000001), CONST64(0x0100010001000001), CONST64(0x0100000001000101), CONST64(0x0100010001000101), CONST64(0x0101000001000001), CONST64(0x0101010001000001), CONST64(0x0101000001000101), CONST64(0x0101010001000101), CONST64(0x0100000001010001), CONST64(0x0100010001010001), CONST64(0x0100000001010101), CONST64(0x0100010001010101), CONST64(0x0101000001010001), CONST64(0x0101010001010001), CONST64(0x0101000001010101), CONST64(0x0101010001010101), CONST64(0x0000000100000001), CONST64(0x0000010100000001), CONST64(0x0000000100000101), CONST64(0x0000010100000101), CONST64(0x0001000100000001), CONST64(0x0001010100000001), CONST64(0x0001000100000101), CONST64(0x0001010100000101), CONST64(0x0000000100010001), CONST64(0x0000010100010001), CONST64(0x0000000100010101), CONST64(0x0000010100010101), CONST64(0x0001000100010001), CONST64(0x0001010100010001), CONST64(0x0001000100010101), CONST64(0x0001010100010101), CONST64(0x0100000100000001), CONST64(0x0100010100000001), CONST64(0x0100000100000101), CONST64(0x0100010100000101), CONST64(0x0101000100000001), CONST64(0x0101010100000001), CONST64(0x0101000100000101), CONST64(0x0101010100000101), CONST64(0x0100000100010001), CONST64(0x0100010100010001), CONST64(0x0100000100010101), CONST64(0x0100010100010101), CONST64(0x0101000100010001), CONST64(0x0101010100010001), CONST64(0x0101000100010101), CONST64(0x0101010100010101), CONST64(0x0000000101000001), CONST64(0x0000010101000001), CONST64(0x0000000101000101), CONST64(0x0000010101000101), CONST64(0x0001000101000001), CONST64(0x0001010101000001), CONST64(0x0001000101000101), CONST64(0x0001010101000101), CONST64(0x0000000101010001), CONST64(0x0000010101010001), CONST64(0x0000000101010101), CONST64(0x0000010101010101), CONST64(0x0001000101010001), CONST64(0x0001010101010001), CONST64(0x0001000101010101), CONST64(0x0001010101010101), CONST64(0x0100000101000001), CONST64(0x0100010101000001), CONST64(0x0100000101000101), CONST64(0x0100010101000101), CONST64(0x0101000101000001), CONST64(0x0101010101000001), CONST64(0x0101000101000101), CONST64(0x0101010101000101), CONST64(0x0100000101010001), CONST64(0x0100010101010001), CONST64(0x0100000101010101), CONST64(0x0100010101010101), CONST64(0x0101000101010001), CONST64(0x0101010101010001), CONST64(0x0101000101010101), CONST64(0x0101010101010101) }, { CONST64(0x0000000000000000), CONST64(0x0000008000000000), CONST64(0x0000000000000080), CONST64(0x0000008000000080), CONST64(0x0000800000000000), CONST64(0x0000808000000000), CONST64(0x0000800000000080), CONST64(0x0000808000000080), CONST64(0x0000000000008000), CONST64(0x0000008000008000), CONST64(0x0000000000008080), CONST64(0x0000008000008080), CONST64(0x0000800000008000), CONST64(0x0000808000008000), CONST64(0x0000800000008080), CONST64(0x0000808000008080), CONST64(0x0080000000000000), CONST64(0x0080008000000000), CONST64(0x0080000000000080), CONST64(0x0080008000000080), CONST64(0x0080800000000000), CONST64(0x0080808000000000), CONST64(0x0080800000000080), CONST64(0x0080808000000080), CONST64(0x0080000000008000), CONST64(0x0080008000008000), CONST64(0x0080000000008080), CONST64(0x0080008000008080), CONST64(0x0080800000008000), CONST64(0x0080808000008000), CONST64(0x0080800000008080), CONST64(0x0080808000008080), CONST64(0x0000000000800000), CONST64(0x0000008000800000), CONST64(0x0000000000800080), CONST64(0x0000008000800080), CONST64(0x0000800000800000), CONST64(0x0000808000800000), CONST64(0x0000800000800080), CONST64(0x0000808000800080), CONST64(0x0000000000808000), CONST64(0x0000008000808000), CONST64(0x0000000000808080), CONST64(0x0000008000808080), CONST64(0x0000800000808000), CONST64(0x0000808000808000), CONST64(0x0000800000808080), CONST64(0x0000808000808080), CONST64(0x0080000000800000), CONST64(0x0080008000800000), CONST64(0x0080000000800080), CONST64(0x0080008000800080), CONST64(0x0080800000800000), CONST64(0x0080808000800000), CONST64(0x0080800000800080), CONST64(0x0080808000800080), CONST64(0x0080000000808000), CONST64(0x0080008000808000), CONST64(0x0080000000808080), CONST64(0x0080008000808080), CONST64(0x0080800000808000), CONST64(0x0080808000808000), CONST64(0x0080800000808080), CONST64(0x0080808000808080), CONST64(0x8000000000000000), CONST64(0x8000008000000000), CONST64(0x8000000000000080), CONST64(0x8000008000000080), CONST64(0x8000800000000000), CONST64(0x8000808000000000), CONST64(0x8000800000000080), CONST64(0x8000808000000080), CONST64(0x8000000000008000), CONST64(0x8000008000008000), CONST64(0x8000000000008080), CONST64(0x8000008000008080), CONST64(0x8000800000008000), CONST64(0x8000808000008000), CONST64(0x8000800000008080), CONST64(0x8000808000008080), CONST64(0x8080000000000000), CONST64(0x8080008000000000), CONST64(0x8080000000000080), CONST64(0x8080008000000080), CONST64(0x8080800000000000), CONST64(0x8080808000000000), CONST64(0x8080800000000080), CONST64(0x8080808000000080), CONST64(0x8080000000008000), CONST64(0x8080008000008000), CONST64(0x8080000000008080), CONST64(0x8080008000008080), CONST64(0x8080800000008000), CONST64(0x8080808000008000), CONST64(0x8080800000008080), CONST64(0x8080808000008080), CONST64(0x8000000000800000), CONST64(0x8000008000800000), CONST64(0x8000000000800080), CONST64(0x8000008000800080), CONST64(0x8000800000800000), CONST64(0x8000808000800000), CONST64(0x8000800000800080), CONST64(0x8000808000800080), CONST64(0x8000000000808000), CONST64(0x8000008000808000), CONST64(0x8000000000808080), CONST64(0x8000008000808080), CONST64(0x8000800000808000), CONST64(0x8000808000808000), CONST64(0x8000800000808080), CONST64(0x8000808000808080), CONST64(0x8080000000800000), CONST64(0x8080008000800000), CONST64(0x8080000000800080), CONST64(0x8080008000800080), CONST64(0x8080800000800000), CONST64(0x8080808000800000), CONST64(0x8080800000800080), CONST64(0x8080808000800080), CONST64(0x8080000000808000), CONST64(0x8080008000808000), CONST64(0x8080000000808080), CONST64(0x8080008000808080), CONST64(0x8080800000808000), CONST64(0x8080808000808000), CONST64(0x8080800000808080), CONST64(0x8080808000808080), CONST64(0x0000000080000000), CONST64(0x0000008080000000), CONST64(0x0000000080000080), CONST64(0x0000008080000080), CONST64(0x0000800080000000), CONST64(0x0000808080000000), CONST64(0x0000800080000080), CONST64(0x0000808080000080), CONST64(0x0000000080008000), CONST64(0x0000008080008000), CONST64(0x0000000080008080), CONST64(0x0000008080008080), CONST64(0x0000800080008000), CONST64(0x0000808080008000), CONST64(0x0000800080008080), CONST64(0x0000808080008080), CONST64(0x0080000080000000), CONST64(0x0080008080000000), CONST64(0x0080000080000080), CONST64(0x0080008080000080), CONST64(0x0080800080000000), CONST64(0x0080808080000000), CONST64(0x0080800080000080), CONST64(0x0080808080000080), CONST64(0x0080000080008000), CONST64(0x0080008080008000), CONST64(0x0080000080008080), CONST64(0x0080008080008080), CONST64(0x0080800080008000), CONST64(0x0080808080008000), CONST64(0x0080800080008080), CONST64(0x0080808080008080), CONST64(0x0000000080800000), CONST64(0x0000008080800000), CONST64(0x0000000080800080), CONST64(0x0000008080800080), CONST64(0x0000800080800000), CONST64(0x0000808080800000), CONST64(0x0000800080800080), CONST64(0x0000808080800080), CONST64(0x0000000080808000), CONST64(0x0000008080808000), CONST64(0x0000000080808080), CONST64(0x0000008080808080), CONST64(0x0000800080808000), CONST64(0x0000808080808000), CONST64(0x0000800080808080), CONST64(0x0000808080808080), CONST64(0x0080000080800000), CONST64(0x0080008080800000), CONST64(0x0080000080800080), CONST64(0x0080008080800080), CONST64(0x0080800080800000), CONST64(0x0080808080800000), CONST64(0x0080800080800080), CONST64(0x0080808080800080), CONST64(0x0080000080808000), CONST64(0x0080008080808000), CONST64(0x0080000080808080), CONST64(0x0080008080808080), CONST64(0x0080800080808000), CONST64(0x0080808080808000), CONST64(0x0080800080808080), CONST64(0x0080808080808080), CONST64(0x8000000080000000), CONST64(0x8000008080000000), CONST64(0x8000000080000080), CONST64(0x8000008080000080), CONST64(0x8000800080000000), CONST64(0x8000808080000000), CONST64(0x8000800080000080), CONST64(0x8000808080000080), CONST64(0x8000000080008000), CONST64(0x8000008080008000), CONST64(0x8000000080008080), CONST64(0x8000008080008080), CONST64(0x8000800080008000), CONST64(0x8000808080008000), CONST64(0x8000800080008080), CONST64(0x8000808080008080), CONST64(0x8080000080000000), CONST64(0x8080008080000000), CONST64(0x8080000080000080), CONST64(0x8080008080000080), CONST64(0x8080800080000000), CONST64(0x8080808080000000), CONST64(0x8080800080000080), CONST64(0x8080808080000080), CONST64(0x8080000080008000), CONST64(0x8080008080008000), CONST64(0x8080000080008080), CONST64(0x8080008080008080), CONST64(0x8080800080008000), CONST64(0x8080808080008000), CONST64(0x8080800080008080), CONST64(0x8080808080008080), CONST64(0x8000000080800000), CONST64(0x8000008080800000), CONST64(0x8000000080800080), CONST64(0x8000008080800080), CONST64(0x8000800080800000), CONST64(0x8000808080800000), CONST64(0x8000800080800080), CONST64(0x8000808080800080), CONST64(0x8000000080808000), CONST64(0x8000008080808000), CONST64(0x8000000080808080), CONST64(0x8000008080808080), CONST64(0x8000800080808000), CONST64(0x8000808080808000), CONST64(0x8000800080808080), CONST64(0x8000808080808080), CONST64(0x8080000080800000), CONST64(0x8080008080800000), CONST64(0x8080000080800080), CONST64(0x8080008080800080), CONST64(0x8080800080800000), CONST64(0x8080808080800000), CONST64(0x8080800080800080), CONST64(0x8080808080800080), CONST64(0x8080000080808000), CONST64(0x8080008080808000), CONST64(0x8080000080808080), CONST64(0x8080008080808080), CONST64(0x8080800080808000), CONST64(0x8080808080808000), CONST64(0x8080800080808080), CONST64(0x8080808080808080) }, { CONST64(0x0000000000000000), CONST64(0x0000004000000000), CONST64(0x0000000000000040), CONST64(0x0000004000000040), CONST64(0x0000400000000000), CONST64(0x0000404000000000), CONST64(0x0000400000000040), CONST64(0x0000404000000040), CONST64(0x0000000000004000), CONST64(0x0000004000004000), CONST64(0x0000000000004040), CONST64(0x0000004000004040), CONST64(0x0000400000004000), CONST64(0x0000404000004000), CONST64(0x0000400000004040), CONST64(0x0000404000004040), CONST64(0x0040000000000000), CONST64(0x0040004000000000), CONST64(0x0040000000000040), CONST64(0x0040004000000040), CONST64(0x0040400000000000), CONST64(0x0040404000000000), CONST64(0x0040400000000040), CONST64(0x0040404000000040), CONST64(0x0040000000004000), CONST64(0x0040004000004000), CONST64(0x0040000000004040), CONST64(0x0040004000004040), CONST64(0x0040400000004000), CONST64(0x0040404000004000), CONST64(0x0040400000004040), CONST64(0x0040404000004040), CONST64(0x0000000000400000), CONST64(0x0000004000400000), CONST64(0x0000000000400040), CONST64(0x0000004000400040), CONST64(0x0000400000400000), CONST64(0x0000404000400000), CONST64(0x0000400000400040), CONST64(0x0000404000400040), CONST64(0x0000000000404000), CONST64(0x0000004000404000), CONST64(0x0000000000404040), CONST64(0x0000004000404040), CONST64(0x0000400000404000), CONST64(0x0000404000404000), CONST64(0x0000400000404040), CONST64(0x0000404000404040), CONST64(0x0040000000400000), CONST64(0x0040004000400000), CONST64(0x0040000000400040), CONST64(0x0040004000400040), CONST64(0x0040400000400000), CONST64(0x0040404000400000), CONST64(0x0040400000400040), CONST64(0x0040404000400040), CONST64(0x0040000000404000), CONST64(0x0040004000404000), CONST64(0x0040000000404040), CONST64(0x0040004000404040), CONST64(0x0040400000404000), CONST64(0x0040404000404000), CONST64(0x0040400000404040), CONST64(0x0040404000404040), CONST64(0x4000000000000000), CONST64(0x4000004000000000), CONST64(0x4000000000000040), CONST64(0x4000004000000040), CONST64(0x4000400000000000), CONST64(0x4000404000000000), CONST64(0x4000400000000040), CONST64(0x4000404000000040), CONST64(0x4000000000004000), CONST64(0x4000004000004000), CONST64(0x4000000000004040), CONST64(0x4000004000004040), CONST64(0x4000400000004000), CONST64(0x4000404000004000), CONST64(0x4000400000004040), CONST64(0x4000404000004040), CONST64(0x4040000000000000), CONST64(0x4040004000000000), CONST64(0x4040000000000040), CONST64(0x4040004000000040), CONST64(0x4040400000000000), CONST64(0x4040404000000000), CONST64(0x4040400000000040), CONST64(0x4040404000000040), CONST64(0x4040000000004000), CONST64(0x4040004000004000), CONST64(0x4040000000004040), CONST64(0x4040004000004040), CONST64(0x4040400000004000), CONST64(0x4040404000004000), CONST64(0x4040400000004040), CONST64(0x4040404000004040), CONST64(0x4000000000400000), CONST64(0x4000004000400000), CONST64(0x4000000000400040), CONST64(0x4000004000400040), CONST64(0x4000400000400000), CONST64(0x4000404000400000), CONST64(0x4000400000400040), CONST64(0x4000404000400040), CONST64(0x4000000000404000), CONST64(0x4000004000404000), CONST64(0x4000000000404040), CONST64(0x4000004000404040), CONST64(0x4000400000404000), CONST64(0x4000404000404000), CONST64(0x4000400000404040), CONST64(0x4000404000404040), CONST64(0x4040000000400000), CONST64(0x4040004000400000), CONST64(0x4040000000400040), CONST64(0x4040004000400040), CONST64(0x4040400000400000), CONST64(0x4040404000400000), CONST64(0x4040400000400040), CONST64(0x4040404000400040), CONST64(0x4040000000404000), CONST64(0x4040004000404000), CONST64(0x4040000000404040), CONST64(0x4040004000404040), CONST64(0x4040400000404000), CONST64(0x4040404000404000), CONST64(0x4040400000404040), CONST64(0x4040404000404040), CONST64(0x0000000040000000), CONST64(0x0000004040000000), CONST64(0x0000000040000040), CONST64(0x0000004040000040), CONST64(0x0000400040000000), CONST64(0x0000404040000000), CONST64(0x0000400040000040), CONST64(0x0000404040000040), CONST64(0x0000000040004000), CONST64(0x0000004040004000), CONST64(0x0000000040004040), CONST64(0x0000004040004040), CONST64(0x0000400040004000), CONST64(0x0000404040004000), CONST64(0x0000400040004040), CONST64(0x0000404040004040), CONST64(0x0040000040000000), CONST64(0x0040004040000000), CONST64(0x0040000040000040), CONST64(0x0040004040000040), CONST64(0x0040400040000000), CONST64(0x0040404040000000), CONST64(0x0040400040000040), CONST64(0x0040404040000040), CONST64(0x0040000040004000), CONST64(0x0040004040004000), CONST64(0x0040000040004040), CONST64(0x0040004040004040), CONST64(0x0040400040004000), CONST64(0x0040404040004000), CONST64(0x0040400040004040), CONST64(0x0040404040004040), CONST64(0x0000000040400000), CONST64(0x0000004040400000), CONST64(0x0000000040400040), CONST64(0x0000004040400040), CONST64(0x0000400040400000), CONST64(0x0000404040400000), CONST64(0x0000400040400040), CONST64(0x0000404040400040), CONST64(0x0000000040404000), CONST64(0x0000004040404000), CONST64(0x0000000040404040), CONST64(0x0000004040404040), CONST64(0x0000400040404000), CONST64(0x0000404040404000), CONST64(0x0000400040404040), CONST64(0x0000404040404040), CONST64(0x0040000040400000), CONST64(0x0040004040400000), CONST64(0x0040000040400040), CONST64(0x0040004040400040), CONST64(0x0040400040400000), CONST64(0x0040404040400000), CONST64(0x0040400040400040), CONST64(0x0040404040400040), CONST64(0x0040000040404000), CONST64(0x0040004040404000), CONST64(0x0040000040404040), CONST64(0x0040004040404040), CONST64(0x0040400040404000), CONST64(0x0040404040404000), CONST64(0x0040400040404040), CONST64(0x0040404040404040), CONST64(0x4000000040000000), CONST64(0x4000004040000000), CONST64(0x4000000040000040), CONST64(0x4000004040000040), CONST64(0x4000400040000000), CONST64(0x4000404040000000), CONST64(0x4000400040000040), CONST64(0x4000404040000040), CONST64(0x4000000040004000), CONST64(0x4000004040004000), CONST64(0x4000000040004040), CONST64(0x4000004040004040), CONST64(0x4000400040004000), CONST64(0x4000404040004000), CONST64(0x4000400040004040), CONST64(0x4000404040004040), CONST64(0x4040000040000000), CONST64(0x4040004040000000), CONST64(0x4040000040000040), CONST64(0x4040004040000040), CONST64(0x4040400040000000), CONST64(0x4040404040000000), CONST64(0x4040400040000040), CONST64(0x4040404040000040), CONST64(0x4040000040004000), CONST64(0x4040004040004000), CONST64(0x4040000040004040), CONST64(0x4040004040004040), CONST64(0x4040400040004000), CONST64(0x4040404040004000), CONST64(0x4040400040004040), CONST64(0x4040404040004040), CONST64(0x4000000040400000), CONST64(0x4000004040400000), CONST64(0x4000000040400040), CONST64(0x4000004040400040), CONST64(0x4000400040400000), CONST64(0x4000404040400000), CONST64(0x4000400040400040), CONST64(0x4000404040400040), CONST64(0x4000000040404000), CONST64(0x4000004040404000), CONST64(0x4000000040404040), CONST64(0x4000004040404040), CONST64(0x4000400040404000), CONST64(0x4000404040404000), CONST64(0x4000400040404040), CONST64(0x4000404040404040), CONST64(0x4040000040400000), CONST64(0x4040004040400000), CONST64(0x4040000040400040), CONST64(0x4040004040400040), CONST64(0x4040400040400000), CONST64(0x4040404040400000), CONST64(0x4040400040400040), CONST64(0x4040404040400040), CONST64(0x4040000040404000), CONST64(0x4040004040404000), CONST64(0x4040000040404040), CONST64(0x4040004040404040), CONST64(0x4040400040404000), CONST64(0x4040404040404000), CONST64(0x4040400040404040), CONST64(0x4040404040404040) }, { CONST64(0x0000000000000000), CONST64(0x0000002000000000), CONST64(0x0000000000000020), CONST64(0x0000002000000020), CONST64(0x0000200000000000), CONST64(0x0000202000000000), CONST64(0x0000200000000020), CONST64(0x0000202000000020), CONST64(0x0000000000002000), CONST64(0x0000002000002000), CONST64(0x0000000000002020), CONST64(0x0000002000002020), CONST64(0x0000200000002000), CONST64(0x0000202000002000), CONST64(0x0000200000002020), CONST64(0x0000202000002020), CONST64(0x0020000000000000), CONST64(0x0020002000000000), CONST64(0x0020000000000020), CONST64(0x0020002000000020), CONST64(0x0020200000000000), CONST64(0x0020202000000000), CONST64(0x0020200000000020), CONST64(0x0020202000000020), CONST64(0x0020000000002000), CONST64(0x0020002000002000), CONST64(0x0020000000002020), CONST64(0x0020002000002020), CONST64(0x0020200000002000), CONST64(0x0020202000002000), CONST64(0x0020200000002020), CONST64(0x0020202000002020), CONST64(0x0000000000200000), CONST64(0x0000002000200000), CONST64(0x0000000000200020), CONST64(0x0000002000200020), CONST64(0x0000200000200000), CONST64(0x0000202000200000), CONST64(0x0000200000200020), CONST64(0x0000202000200020), CONST64(0x0000000000202000), CONST64(0x0000002000202000), CONST64(0x0000000000202020), CONST64(0x0000002000202020), CONST64(0x0000200000202000), CONST64(0x0000202000202000), CONST64(0x0000200000202020), CONST64(0x0000202000202020), CONST64(0x0020000000200000), CONST64(0x0020002000200000), CONST64(0x0020000000200020), CONST64(0x0020002000200020), CONST64(0x0020200000200000), CONST64(0x0020202000200000), CONST64(0x0020200000200020), CONST64(0x0020202000200020), CONST64(0x0020000000202000), CONST64(0x0020002000202000), CONST64(0x0020000000202020), CONST64(0x0020002000202020), CONST64(0x0020200000202000), CONST64(0x0020202000202000), CONST64(0x0020200000202020), CONST64(0x0020202000202020), CONST64(0x2000000000000000), CONST64(0x2000002000000000), CONST64(0x2000000000000020), CONST64(0x2000002000000020), CONST64(0x2000200000000000), CONST64(0x2000202000000000), CONST64(0x2000200000000020), CONST64(0x2000202000000020), CONST64(0x2000000000002000), CONST64(0x2000002000002000), CONST64(0x2000000000002020), CONST64(0x2000002000002020), CONST64(0x2000200000002000), CONST64(0x2000202000002000), CONST64(0x2000200000002020), CONST64(0x2000202000002020), CONST64(0x2020000000000000), CONST64(0x2020002000000000), CONST64(0x2020000000000020), CONST64(0x2020002000000020), CONST64(0x2020200000000000), CONST64(0x2020202000000000), CONST64(0x2020200000000020), CONST64(0x2020202000000020), CONST64(0x2020000000002000), CONST64(0x2020002000002000), CONST64(0x2020000000002020), CONST64(0x2020002000002020), CONST64(0x2020200000002000), CONST64(0x2020202000002000), CONST64(0x2020200000002020), CONST64(0x2020202000002020), CONST64(0x2000000000200000), CONST64(0x2000002000200000), CONST64(0x2000000000200020), CONST64(0x2000002000200020), CONST64(0x2000200000200000), CONST64(0x2000202000200000), CONST64(0x2000200000200020), CONST64(0x2000202000200020), CONST64(0x2000000000202000), CONST64(0x2000002000202000), CONST64(0x2000000000202020), CONST64(0x2000002000202020), CONST64(0x2000200000202000), CONST64(0x2000202000202000), CONST64(0x2000200000202020), CONST64(0x2000202000202020), CONST64(0x2020000000200000), CONST64(0x2020002000200000), CONST64(0x2020000000200020), CONST64(0x2020002000200020), CONST64(0x2020200000200000), CONST64(0x2020202000200000), CONST64(0x2020200000200020), CONST64(0x2020202000200020), CONST64(0x2020000000202000), CONST64(0x2020002000202000), CONST64(0x2020000000202020), CONST64(0x2020002000202020), CONST64(0x2020200000202000), CONST64(0x2020202000202000), CONST64(0x2020200000202020), CONST64(0x2020202000202020), CONST64(0x0000000020000000), CONST64(0x0000002020000000), CONST64(0x0000000020000020), CONST64(0x0000002020000020), CONST64(0x0000200020000000), CONST64(0x0000202020000000), CONST64(0x0000200020000020), CONST64(0x0000202020000020), CONST64(0x0000000020002000), CONST64(0x0000002020002000), CONST64(0x0000000020002020), CONST64(0x0000002020002020), CONST64(0x0000200020002000), CONST64(0x0000202020002000), CONST64(0x0000200020002020), CONST64(0x0000202020002020), CONST64(0x0020000020000000), CONST64(0x0020002020000000), CONST64(0x0020000020000020), CONST64(0x0020002020000020), CONST64(0x0020200020000000), CONST64(0x0020202020000000), CONST64(0x0020200020000020), CONST64(0x0020202020000020), CONST64(0x0020000020002000), CONST64(0x0020002020002000), CONST64(0x0020000020002020), CONST64(0x0020002020002020), CONST64(0x0020200020002000), CONST64(0x0020202020002000), CONST64(0x0020200020002020), CONST64(0x0020202020002020), CONST64(0x0000000020200000), CONST64(0x0000002020200000), CONST64(0x0000000020200020), CONST64(0x0000002020200020), CONST64(0x0000200020200000), CONST64(0x0000202020200000), CONST64(0x0000200020200020), CONST64(0x0000202020200020), CONST64(0x0000000020202000), CONST64(0x0000002020202000), CONST64(0x0000000020202020), CONST64(0x0000002020202020), CONST64(0x0000200020202000), CONST64(0x0000202020202000), CONST64(0x0000200020202020), CONST64(0x0000202020202020), CONST64(0x0020000020200000), CONST64(0x0020002020200000), CONST64(0x0020000020200020), CONST64(0x0020002020200020), CONST64(0x0020200020200000), CONST64(0x0020202020200000), CONST64(0x0020200020200020), CONST64(0x0020202020200020), CONST64(0x0020000020202000), CONST64(0x0020002020202000), CONST64(0x0020000020202020), CONST64(0x0020002020202020), CONST64(0x0020200020202000), CONST64(0x0020202020202000), CONST64(0x0020200020202020), CONST64(0x0020202020202020), CONST64(0x2000000020000000), CONST64(0x2000002020000000), CONST64(0x2000000020000020), CONST64(0x2000002020000020), CONST64(0x2000200020000000), CONST64(0x2000202020000000), CONST64(0x2000200020000020), CONST64(0x2000202020000020), CONST64(0x2000000020002000), CONST64(0x2000002020002000), CONST64(0x2000000020002020), CONST64(0x2000002020002020), CONST64(0x2000200020002000), CONST64(0x2000202020002000), CONST64(0x2000200020002020), CONST64(0x2000202020002020), CONST64(0x2020000020000000), CONST64(0x2020002020000000), CONST64(0x2020000020000020), CONST64(0x2020002020000020), CONST64(0x2020200020000000), CONST64(0x2020202020000000), CONST64(0x2020200020000020), CONST64(0x2020202020000020), CONST64(0x2020000020002000), CONST64(0x2020002020002000), CONST64(0x2020000020002020), CONST64(0x2020002020002020), CONST64(0x2020200020002000), CONST64(0x2020202020002000), CONST64(0x2020200020002020), CONST64(0x2020202020002020), CONST64(0x2000000020200000), CONST64(0x2000002020200000), CONST64(0x2000000020200020), CONST64(0x2000002020200020), CONST64(0x2000200020200000), CONST64(0x2000202020200000), CONST64(0x2000200020200020), CONST64(0x2000202020200020), CONST64(0x2000000020202000), CONST64(0x2000002020202000), CONST64(0x2000000020202020), CONST64(0x2000002020202020), CONST64(0x2000200020202000), CONST64(0x2000202020202000), CONST64(0x2000200020202020), CONST64(0x2000202020202020), CONST64(0x2020000020200000), CONST64(0x2020002020200000), CONST64(0x2020000020200020), CONST64(0x2020002020200020), CONST64(0x2020200020200000), CONST64(0x2020202020200000), CONST64(0x2020200020200020), CONST64(0x2020202020200020), CONST64(0x2020000020202000), CONST64(0x2020002020202000), CONST64(0x2020000020202020), CONST64(0x2020002020202020), CONST64(0x2020200020202000), CONST64(0x2020202020202000), CONST64(0x2020200020202020), CONST64(0x2020202020202020) }}; static const ulong64 des_fp[8][256] = { { CONST64(0x0000000000000000), CONST64(0x0000008000000000), CONST64(0x0000000002000000), CONST64(0x0000008002000000), CONST64(0x0000000000020000), CONST64(0x0000008000020000), CONST64(0x0000000002020000), CONST64(0x0000008002020000), CONST64(0x0000000000000200), CONST64(0x0000008000000200), CONST64(0x0000000002000200), CONST64(0x0000008002000200), CONST64(0x0000000000020200), CONST64(0x0000008000020200), CONST64(0x0000000002020200), CONST64(0x0000008002020200), CONST64(0x0000000000000002), CONST64(0x0000008000000002), CONST64(0x0000000002000002), CONST64(0x0000008002000002), CONST64(0x0000000000020002), CONST64(0x0000008000020002), CONST64(0x0000000002020002), CONST64(0x0000008002020002), CONST64(0x0000000000000202), CONST64(0x0000008000000202), CONST64(0x0000000002000202), CONST64(0x0000008002000202), CONST64(0x0000000000020202), CONST64(0x0000008000020202), CONST64(0x0000000002020202), CONST64(0x0000008002020202), CONST64(0x0200000000000000), CONST64(0x0200008000000000), CONST64(0x0200000002000000), CONST64(0x0200008002000000), CONST64(0x0200000000020000), CONST64(0x0200008000020000), CONST64(0x0200000002020000), CONST64(0x0200008002020000), CONST64(0x0200000000000200), CONST64(0x0200008000000200), CONST64(0x0200000002000200), CONST64(0x0200008002000200), CONST64(0x0200000000020200), CONST64(0x0200008000020200), CONST64(0x0200000002020200), CONST64(0x0200008002020200), CONST64(0x0200000000000002), CONST64(0x0200008000000002), CONST64(0x0200000002000002), CONST64(0x0200008002000002), CONST64(0x0200000000020002), CONST64(0x0200008000020002), CONST64(0x0200000002020002), CONST64(0x0200008002020002), CONST64(0x0200000000000202), CONST64(0x0200008000000202), CONST64(0x0200000002000202), CONST64(0x0200008002000202), CONST64(0x0200000000020202), CONST64(0x0200008000020202), CONST64(0x0200000002020202), CONST64(0x0200008002020202), CONST64(0x0002000000000000), CONST64(0x0002008000000000), CONST64(0x0002000002000000), CONST64(0x0002008002000000), CONST64(0x0002000000020000), CONST64(0x0002008000020000), CONST64(0x0002000002020000), CONST64(0x0002008002020000), CONST64(0x0002000000000200), CONST64(0x0002008000000200), CONST64(0x0002000002000200), CONST64(0x0002008002000200), CONST64(0x0002000000020200), CONST64(0x0002008000020200), CONST64(0x0002000002020200), CONST64(0x0002008002020200), CONST64(0x0002000000000002), CONST64(0x0002008000000002), CONST64(0x0002000002000002), CONST64(0x0002008002000002), CONST64(0x0002000000020002), CONST64(0x0002008000020002), CONST64(0x0002000002020002), CONST64(0x0002008002020002), CONST64(0x0002000000000202), CONST64(0x0002008000000202), CONST64(0x0002000002000202), CONST64(0x0002008002000202), CONST64(0x0002000000020202), CONST64(0x0002008000020202), CONST64(0x0002000002020202), CONST64(0x0002008002020202), CONST64(0x0202000000000000), CONST64(0x0202008000000000), CONST64(0x0202000002000000), CONST64(0x0202008002000000), CONST64(0x0202000000020000), CONST64(0x0202008000020000), CONST64(0x0202000002020000), CONST64(0x0202008002020000), CONST64(0x0202000000000200), CONST64(0x0202008000000200), CONST64(0x0202000002000200), CONST64(0x0202008002000200), CONST64(0x0202000000020200), CONST64(0x0202008000020200), CONST64(0x0202000002020200), CONST64(0x0202008002020200), CONST64(0x0202000000000002), CONST64(0x0202008000000002), CONST64(0x0202000002000002), CONST64(0x0202008002000002), CONST64(0x0202000000020002), CONST64(0x0202008000020002), CONST64(0x0202000002020002), CONST64(0x0202008002020002), CONST64(0x0202000000000202), CONST64(0x0202008000000202), CONST64(0x0202000002000202), CONST64(0x0202008002000202), CONST64(0x0202000000020202), CONST64(0x0202008000020202), CONST64(0x0202000002020202), CONST64(0x0202008002020202), CONST64(0x0000020000000000), CONST64(0x0000028000000000), CONST64(0x0000020002000000), CONST64(0x0000028002000000), CONST64(0x0000020000020000), CONST64(0x0000028000020000), CONST64(0x0000020002020000), CONST64(0x0000028002020000), CONST64(0x0000020000000200), CONST64(0x0000028000000200), CONST64(0x0000020002000200), CONST64(0x0000028002000200), CONST64(0x0000020000020200), CONST64(0x0000028000020200), CONST64(0x0000020002020200), CONST64(0x0000028002020200), CONST64(0x0000020000000002), CONST64(0x0000028000000002), CONST64(0x0000020002000002), CONST64(0x0000028002000002), CONST64(0x0000020000020002), CONST64(0x0000028000020002), CONST64(0x0000020002020002), CONST64(0x0000028002020002), CONST64(0x0000020000000202), CONST64(0x0000028000000202), CONST64(0x0000020002000202), CONST64(0x0000028002000202), CONST64(0x0000020000020202), CONST64(0x0000028000020202), CONST64(0x0000020002020202), CONST64(0x0000028002020202), CONST64(0x0200020000000000), CONST64(0x0200028000000000), CONST64(0x0200020002000000), CONST64(0x0200028002000000), CONST64(0x0200020000020000), CONST64(0x0200028000020000), CONST64(0x0200020002020000), CONST64(0x0200028002020000), CONST64(0x0200020000000200), CONST64(0x0200028000000200), CONST64(0x0200020002000200), CONST64(0x0200028002000200), CONST64(0x0200020000020200), CONST64(0x0200028000020200), CONST64(0x0200020002020200), CONST64(0x0200028002020200), CONST64(0x0200020000000002), CONST64(0x0200028000000002), CONST64(0x0200020002000002), CONST64(0x0200028002000002), CONST64(0x0200020000020002), CONST64(0x0200028000020002), CONST64(0x0200020002020002), CONST64(0x0200028002020002), CONST64(0x0200020000000202), CONST64(0x0200028000000202), CONST64(0x0200020002000202), CONST64(0x0200028002000202), CONST64(0x0200020000020202), CONST64(0x0200028000020202), CONST64(0x0200020002020202), CONST64(0x0200028002020202), CONST64(0x0002020000000000), CONST64(0x0002028000000000), CONST64(0x0002020002000000), CONST64(0x0002028002000000), CONST64(0x0002020000020000), CONST64(0x0002028000020000), CONST64(0x0002020002020000), CONST64(0x0002028002020000), CONST64(0x0002020000000200), CONST64(0x0002028000000200), CONST64(0x0002020002000200), CONST64(0x0002028002000200), CONST64(0x0002020000020200), CONST64(0x0002028000020200), CONST64(0x0002020002020200), CONST64(0x0002028002020200), CONST64(0x0002020000000002), CONST64(0x0002028000000002), CONST64(0x0002020002000002), CONST64(0x0002028002000002), CONST64(0x0002020000020002), CONST64(0x0002028000020002), CONST64(0x0002020002020002), CONST64(0x0002028002020002), CONST64(0x0002020000000202), CONST64(0x0002028000000202), CONST64(0x0002020002000202), CONST64(0x0002028002000202), CONST64(0x0002020000020202), CONST64(0x0002028000020202), CONST64(0x0002020002020202), CONST64(0x0002028002020202), CONST64(0x0202020000000000), CONST64(0x0202028000000000), CONST64(0x0202020002000000), CONST64(0x0202028002000000), CONST64(0x0202020000020000), CONST64(0x0202028000020000), CONST64(0x0202020002020000), CONST64(0x0202028002020000), CONST64(0x0202020000000200), CONST64(0x0202028000000200), CONST64(0x0202020002000200), CONST64(0x0202028002000200), CONST64(0x0202020000020200), CONST64(0x0202028000020200), CONST64(0x0202020002020200), CONST64(0x0202028002020200), CONST64(0x0202020000000002), CONST64(0x0202028000000002), CONST64(0x0202020002000002), CONST64(0x0202028002000002), CONST64(0x0202020000020002), CONST64(0x0202028000020002), CONST64(0x0202020002020002), CONST64(0x0202028002020002), CONST64(0x0202020000000202), CONST64(0x0202028000000202), CONST64(0x0202020002000202), CONST64(0x0202028002000202), CONST64(0x0202020000020202), CONST64(0x0202028000020202), CONST64(0x0202020002020202), CONST64(0x0202028002020202) }, { CONST64(0x0000000000000000), CONST64(0x0000000200000000), CONST64(0x0000000008000000), CONST64(0x0000000208000000), CONST64(0x0000000000080000), CONST64(0x0000000200080000), CONST64(0x0000000008080000), CONST64(0x0000000208080000), CONST64(0x0000000000000800), CONST64(0x0000000200000800), CONST64(0x0000000008000800), CONST64(0x0000000208000800), CONST64(0x0000000000080800), CONST64(0x0000000200080800), CONST64(0x0000000008080800), CONST64(0x0000000208080800), CONST64(0x0000000000000008), CONST64(0x0000000200000008), CONST64(0x0000000008000008), CONST64(0x0000000208000008), CONST64(0x0000000000080008), CONST64(0x0000000200080008), CONST64(0x0000000008080008), CONST64(0x0000000208080008), CONST64(0x0000000000000808), CONST64(0x0000000200000808), CONST64(0x0000000008000808), CONST64(0x0000000208000808), CONST64(0x0000000000080808), CONST64(0x0000000200080808), CONST64(0x0000000008080808), CONST64(0x0000000208080808), CONST64(0x0800000000000000), CONST64(0x0800000200000000), CONST64(0x0800000008000000), CONST64(0x0800000208000000), CONST64(0x0800000000080000), CONST64(0x0800000200080000), CONST64(0x0800000008080000), CONST64(0x0800000208080000), CONST64(0x0800000000000800), CONST64(0x0800000200000800), CONST64(0x0800000008000800), CONST64(0x0800000208000800), CONST64(0x0800000000080800), CONST64(0x0800000200080800), CONST64(0x0800000008080800), CONST64(0x0800000208080800), CONST64(0x0800000000000008), CONST64(0x0800000200000008), CONST64(0x0800000008000008), CONST64(0x0800000208000008), CONST64(0x0800000000080008), CONST64(0x0800000200080008), CONST64(0x0800000008080008), CONST64(0x0800000208080008), CONST64(0x0800000000000808), CONST64(0x0800000200000808), CONST64(0x0800000008000808), CONST64(0x0800000208000808), CONST64(0x0800000000080808), CONST64(0x0800000200080808), CONST64(0x0800000008080808), CONST64(0x0800000208080808), CONST64(0x0008000000000000), CONST64(0x0008000200000000), CONST64(0x0008000008000000), CONST64(0x0008000208000000), CONST64(0x0008000000080000), CONST64(0x0008000200080000), CONST64(0x0008000008080000), CONST64(0x0008000208080000), CONST64(0x0008000000000800), CONST64(0x0008000200000800), CONST64(0x0008000008000800), CONST64(0x0008000208000800), CONST64(0x0008000000080800), CONST64(0x0008000200080800), CONST64(0x0008000008080800), CONST64(0x0008000208080800), CONST64(0x0008000000000008), CONST64(0x0008000200000008), CONST64(0x0008000008000008), CONST64(0x0008000208000008), CONST64(0x0008000000080008), CONST64(0x0008000200080008), CONST64(0x0008000008080008), CONST64(0x0008000208080008), CONST64(0x0008000000000808), CONST64(0x0008000200000808), CONST64(0x0008000008000808), CONST64(0x0008000208000808), CONST64(0x0008000000080808), CONST64(0x0008000200080808), CONST64(0x0008000008080808), CONST64(0x0008000208080808), CONST64(0x0808000000000000), CONST64(0x0808000200000000), CONST64(0x0808000008000000), CONST64(0x0808000208000000), CONST64(0x0808000000080000), CONST64(0x0808000200080000), CONST64(0x0808000008080000), CONST64(0x0808000208080000), CONST64(0x0808000000000800), CONST64(0x0808000200000800), CONST64(0x0808000008000800), CONST64(0x0808000208000800), CONST64(0x0808000000080800), CONST64(0x0808000200080800), CONST64(0x0808000008080800), CONST64(0x0808000208080800), CONST64(0x0808000000000008), CONST64(0x0808000200000008), CONST64(0x0808000008000008), CONST64(0x0808000208000008), CONST64(0x0808000000080008), CONST64(0x0808000200080008), CONST64(0x0808000008080008), CONST64(0x0808000208080008), CONST64(0x0808000000000808), CONST64(0x0808000200000808), CONST64(0x0808000008000808), CONST64(0x0808000208000808), CONST64(0x0808000000080808), CONST64(0x0808000200080808), CONST64(0x0808000008080808), CONST64(0x0808000208080808), CONST64(0x0000080000000000), CONST64(0x0000080200000000), CONST64(0x0000080008000000), CONST64(0x0000080208000000), CONST64(0x0000080000080000), CONST64(0x0000080200080000), CONST64(0x0000080008080000), CONST64(0x0000080208080000), CONST64(0x0000080000000800), CONST64(0x0000080200000800), CONST64(0x0000080008000800), CONST64(0x0000080208000800), CONST64(0x0000080000080800), CONST64(0x0000080200080800), CONST64(0x0000080008080800), CONST64(0x0000080208080800), CONST64(0x0000080000000008), CONST64(0x0000080200000008), CONST64(0x0000080008000008), CONST64(0x0000080208000008), CONST64(0x0000080000080008), CONST64(0x0000080200080008), CONST64(0x0000080008080008), CONST64(0x0000080208080008), CONST64(0x0000080000000808), CONST64(0x0000080200000808), CONST64(0x0000080008000808), CONST64(0x0000080208000808), CONST64(0x0000080000080808), CONST64(0x0000080200080808), CONST64(0x0000080008080808), CONST64(0x0000080208080808), CONST64(0x0800080000000000), CONST64(0x0800080200000000), CONST64(0x0800080008000000), CONST64(0x0800080208000000), CONST64(0x0800080000080000), CONST64(0x0800080200080000), CONST64(0x0800080008080000), CONST64(0x0800080208080000), CONST64(0x0800080000000800), CONST64(0x0800080200000800), CONST64(0x0800080008000800), CONST64(0x0800080208000800), CONST64(0x0800080000080800), CONST64(0x0800080200080800), CONST64(0x0800080008080800), CONST64(0x0800080208080800), CONST64(0x0800080000000008), CONST64(0x0800080200000008), CONST64(0x0800080008000008), CONST64(0x0800080208000008), CONST64(0x0800080000080008), CONST64(0x0800080200080008), CONST64(0x0800080008080008), CONST64(0x0800080208080008), CONST64(0x0800080000000808), CONST64(0x0800080200000808), CONST64(0x0800080008000808), CONST64(0x0800080208000808), CONST64(0x0800080000080808), CONST64(0x0800080200080808), CONST64(0x0800080008080808), CONST64(0x0800080208080808), CONST64(0x0008080000000000), CONST64(0x0008080200000000), CONST64(0x0008080008000000), CONST64(0x0008080208000000), CONST64(0x0008080000080000), CONST64(0x0008080200080000), CONST64(0x0008080008080000), CONST64(0x0008080208080000), CONST64(0x0008080000000800), CONST64(0x0008080200000800), CONST64(0x0008080008000800), CONST64(0x0008080208000800), CONST64(0x0008080000080800), CONST64(0x0008080200080800), CONST64(0x0008080008080800), CONST64(0x0008080208080800), CONST64(0x0008080000000008), CONST64(0x0008080200000008), CONST64(0x0008080008000008), CONST64(0x0008080208000008), CONST64(0x0008080000080008), CONST64(0x0008080200080008), CONST64(0x0008080008080008), CONST64(0x0008080208080008), CONST64(0x0008080000000808), CONST64(0x0008080200000808), CONST64(0x0008080008000808), CONST64(0x0008080208000808), CONST64(0x0008080000080808), CONST64(0x0008080200080808), CONST64(0x0008080008080808), CONST64(0x0008080208080808), CONST64(0x0808080000000000), CONST64(0x0808080200000000), CONST64(0x0808080008000000), CONST64(0x0808080208000000), CONST64(0x0808080000080000), CONST64(0x0808080200080000), CONST64(0x0808080008080000), CONST64(0x0808080208080000), CONST64(0x0808080000000800), CONST64(0x0808080200000800), CONST64(0x0808080008000800), CONST64(0x0808080208000800), CONST64(0x0808080000080800), CONST64(0x0808080200080800), CONST64(0x0808080008080800), CONST64(0x0808080208080800), CONST64(0x0808080000000008), CONST64(0x0808080200000008), CONST64(0x0808080008000008), CONST64(0x0808080208000008), CONST64(0x0808080000080008), CONST64(0x0808080200080008), CONST64(0x0808080008080008), CONST64(0x0808080208080008), CONST64(0x0808080000000808), CONST64(0x0808080200000808), CONST64(0x0808080008000808), CONST64(0x0808080208000808), CONST64(0x0808080000080808), CONST64(0x0808080200080808), CONST64(0x0808080008080808), CONST64(0x0808080208080808) }, { CONST64(0x0000000000000000), CONST64(0x0000000800000000), CONST64(0x0000000020000000), CONST64(0x0000000820000000), CONST64(0x0000000000200000), CONST64(0x0000000800200000), CONST64(0x0000000020200000), CONST64(0x0000000820200000), CONST64(0x0000000000002000), CONST64(0x0000000800002000), CONST64(0x0000000020002000), CONST64(0x0000000820002000), CONST64(0x0000000000202000), CONST64(0x0000000800202000), CONST64(0x0000000020202000), CONST64(0x0000000820202000), CONST64(0x0000000000000020), CONST64(0x0000000800000020), CONST64(0x0000000020000020), CONST64(0x0000000820000020), CONST64(0x0000000000200020), CONST64(0x0000000800200020), CONST64(0x0000000020200020), CONST64(0x0000000820200020), CONST64(0x0000000000002020), CONST64(0x0000000800002020), CONST64(0x0000000020002020), CONST64(0x0000000820002020), CONST64(0x0000000000202020), CONST64(0x0000000800202020), CONST64(0x0000000020202020), CONST64(0x0000000820202020), CONST64(0x2000000000000000), CONST64(0x2000000800000000), CONST64(0x2000000020000000), CONST64(0x2000000820000000), CONST64(0x2000000000200000), CONST64(0x2000000800200000), CONST64(0x2000000020200000), CONST64(0x2000000820200000), CONST64(0x2000000000002000), CONST64(0x2000000800002000), CONST64(0x2000000020002000), CONST64(0x2000000820002000), CONST64(0x2000000000202000), CONST64(0x2000000800202000), CONST64(0x2000000020202000), CONST64(0x2000000820202000), CONST64(0x2000000000000020), CONST64(0x2000000800000020), CONST64(0x2000000020000020), CONST64(0x2000000820000020), CONST64(0x2000000000200020), CONST64(0x2000000800200020), CONST64(0x2000000020200020), CONST64(0x2000000820200020), CONST64(0x2000000000002020), CONST64(0x2000000800002020), CONST64(0x2000000020002020), CONST64(0x2000000820002020), CONST64(0x2000000000202020), CONST64(0x2000000800202020), CONST64(0x2000000020202020), CONST64(0x2000000820202020), CONST64(0x0020000000000000), CONST64(0x0020000800000000), CONST64(0x0020000020000000), CONST64(0x0020000820000000), CONST64(0x0020000000200000), CONST64(0x0020000800200000), CONST64(0x0020000020200000), CONST64(0x0020000820200000), CONST64(0x0020000000002000), CONST64(0x0020000800002000), CONST64(0x0020000020002000), CONST64(0x0020000820002000), CONST64(0x0020000000202000), CONST64(0x0020000800202000), CONST64(0x0020000020202000), CONST64(0x0020000820202000), CONST64(0x0020000000000020), CONST64(0x0020000800000020), CONST64(0x0020000020000020), CONST64(0x0020000820000020), CONST64(0x0020000000200020), CONST64(0x0020000800200020), CONST64(0x0020000020200020), CONST64(0x0020000820200020), CONST64(0x0020000000002020), CONST64(0x0020000800002020), CONST64(0x0020000020002020), CONST64(0x0020000820002020), CONST64(0x0020000000202020), CONST64(0x0020000800202020), CONST64(0x0020000020202020), CONST64(0x0020000820202020), CONST64(0x2020000000000000), CONST64(0x2020000800000000), CONST64(0x2020000020000000), CONST64(0x2020000820000000), CONST64(0x2020000000200000), CONST64(0x2020000800200000), CONST64(0x2020000020200000), CONST64(0x2020000820200000), CONST64(0x2020000000002000), CONST64(0x2020000800002000), CONST64(0x2020000020002000), CONST64(0x2020000820002000), CONST64(0x2020000000202000), CONST64(0x2020000800202000), CONST64(0x2020000020202000), CONST64(0x2020000820202000), CONST64(0x2020000000000020), CONST64(0x2020000800000020), CONST64(0x2020000020000020), CONST64(0x2020000820000020), CONST64(0x2020000000200020), CONST64(0x2020000800200020), CONST64(0x2020000020200020), CONST64(0x2020000820200020), CONST64(0x2020000000002020), CONST64(0x2020000800002020), CONST64(0x2020000020002020), CONST64(0x2020000820002020), CONST64(0x2020000000202020), CONST64(0x2020000800202020), CONST64(0x2020000020202020), CONST64(0x2020000820202020), CONST64(0x0000200000000000), CONST64(0x0000200800000000), CONST64(0x0000200020000000), CONST64(0x0000200820000000), CONST64(0x0000200000200000), CONST64(0x0000200800200000), CONST64(0x0000200020200000), CONST64(0x0000200820200000), CONST64(0x0000200000002000), CONST64(0x0000200800002000), CONST64(0x0000200020002000), CONST64(0x0000200820002000), CONST64(0x0000200000202000), CONST64(0x0000200800202000), CONST64(0x0000200020202000), CONST64(0x0000200820202000), CONST64(0x0000200000000020), CONST64(0x0000200800000020), CONST64(0x0000200020000020), CONST64(0x0000200820000020), CONST64(0x0000200000200020), CONST64(0x0000200800200020), CONST64(0x0000200020200020), CONST64(0x0000200820200020), CONST64(0x0000200000002020), CONST64(0x0000200800002020), CONST64(0x0000200020002020), CONST64(0x0000200820002020), CONST64(0x0000200000202020), CONST64(0x0000200800202020), CONST64(0x0000200020202020), CONST64(0x0000200820202020), CONST64(0x2000200000000000), CONST64(0x2000200800000000), CONST64(0x2000200020000000), CONST64(0x2000200820000000), CONST64(0x2000200000200000), CONST64(0x2000200800200000), CONST64(0x2000200020200000), CONST64(0x2000200820200000), CONST64(0x2000200000002000), CONST64(0x2000200800002000), CONST64(0x2000200020002000), CONST64(0x2000200820002000), CONST64(0x2000200000202000), CONST64(0x2000200800202000), CONST64(0x2000200020202000), CONST64(0x2000200820202000), CONST64(0x2000200000000020), CONST64(0x2000200800000020), CONST64(0x2000200020000020), CONST64(0x2000200820000020), CONST64(0x2000200000200020), CONST64(0x2000200800200020), CONST64(0x2000200020200020), CONST64(0x2000200820200020), CONST64(0x2000200000002020), CONST64(0x2000200800002020), CONST64(0x2000200020002020), CONST64(0x2000200820002020), CONST64(0x2000200000202020), CONST64(0x2000200800202020), CONST64(0x2000200020202020), CONST64(0x2000200820202020), CONST64(0x0020200000000000), CONST64(0x0020200800000000), CONST64(0x0020200020000000), CONST64(0x0020200820000000), CONST64(0x0020200000200000), CONST64(0x0020200800200000), CONST64(0x0020200020200000), CONST64(0x0020200820200000), CONST64(0x0020200000002000), CONST64(0x0020200800002000), CONST64(0x0020200020002000), CONST64(0x0020200820002000), CONST64(0x0020200000202000), CONST64(0x0020200800202000), CONST64(0x0020200020202000), CONST64(0x0020200820202000), CONST64(0x0020200000000020), CONST64(0x0020200800000020), CONST64(0x0020200020000020), CONST64(0x0020200820000020), CONST64(0x0020200000200020), CONST64(0x0020200800200020), CONST64(0x0020200020200020), CONST64(0x0020200820200020), CONST64(0x0020200000002020), CONST64(0x0020200800002020), CONST64(0x0020200020002020), CONST64(0x0020200820002020), CONST64(0x0020200000202020), CONST64(0x0020200800202020), CONST64(0x0020200020202020), CONST64(0x0020200820202020), CONST64(0x2020200000000000), CONST64(0x2020200800000000), CONST64(0x2020200020000000), CONST64(0x2020200820000000), CONST64(0x2020200000200000), CONST64(0x2020200800200000), CONST64(0x2020200020200000), CONST64(0x2020200820200000), CONST64(0x2020200000002000), CONST64(0x2020200800002000), CONST64(0x2020200020002000), CONST64(0x2020200820002000), CONST64(0x2020200000202000), CONST64(0x2020200800202000), CONST64(0x2020200020202000), CONST64(0x2020200820202000), CONST64(0x2020200000000020), CONST64(0x2020200800000020), CONST64(0x2020200020000020), CONST64(0x2020200820000020), CONST64(0x2020200000200020), CONST64(0x2020200800200020), CONST64(0x2020200020200020), CONST64(0x2020200820200020), CONST64(0x2020200000002020), CONST64(0x2020200800002020), CONST64(0x2020200020002020), CONST64(0x2020200820002020), CONST64(0x2020200000202020), CONST64(0x2020200800202020), CONST64(0x2020200020202020), CONST64(0x2020200820202020) }, { CONST64(0x0000000000000000), CONST64(0x0000002000000000), CONST64(0x0000000080000000), CONST64(0x0000002080000000), CONST64(0x0000000000800000), CONST64(0x0000002000800000), CONST64(0x0000000080800000), CONST64(0x0000002080800000), CONST64(0x0000000000008000), CONST64(0x0000002000008000), CONST64(0x0000000080008000), CONST64(0x0000002080008000), CONST64(0x0000000000808000), CONST64(0x0000002000808000), CONST64(0x0000000080808000), CONST64(0x0000002080808000), CONST64(0x0000000000000080), CONST64(0x0000002000000080), CONST64(0x0000000080000080), CONST64(0x0000002080000080), CONST64(0x0000000000800080), CONST64(0x0000002000800080), CONST64(0x0000000080800080), CONST64(0x0000002080800080), CONST64(0x0000000000008080), CONST64(0x0000002000008080), CONST64(0x0000000080008080), CONST64(0x0000002080008080), CONST64(0x0000000000808080), CONST64(0x0000002000808080), CONST64(0x0000000080808080), CONST64(0x0000002080808080), CONST64(0x8000000000000000), CONST64(0x8000002000000000), CONST64(0x8000000080000000), CONST64(0x8000002080000000), CONST64(0x8000000000800000), CONST64(0x8000002000800000), CONST64(0x8000000080800000), CONST64(0x8000002080800000), CONST64(0x8000000000008000), CONST64(0x8000002000008000), CONST64(0x8000000080008000), CONST64(0x8000002080008000), CONST64(0x8000000000808000), CONST64(0x8000002000808000), CONST64(0x8000000080808000), CONST64(0x8000002080808000), CONST64(0x8000000000000080), CONST64(0x8000002000000080), CONST64(0x8000000080000080), CONST64(0x8000002080000080), CONST64(0x8000000000800080), CONST64(0x8000002000800080), CONST64(0x8000000080800080), CONST64(0x8000002080800080), CONST64(0x8000000000008080), CONST64(0x8000002000008080), CONST64(0x8000000080008080), CONST64(0x8000002080008080), CONST64(0x8000000000808080), CONST64(0x8000002000808080), CONST64(0x8000000080808080), CONST64(0x8000002080808080), CONST64(0x0080000000000000), CONST64(0x0080002000000000), CONST64(0x0080000080000000), CONST64(0x0080002080000000), CONST64(0x0080000000800000), CONST64(0x0080002000800000), CONST64(0x0080000080800000), CONST64(0x0080002080800000), CONST64(0x0080000000008000), CONST64(0x0080002000008000), CONST64(0x0080000080008000), CONST64(0x0080002080008000), CONST64(0x0080000000808000), CONST64(0x0080002000808000), CONST64(0x0080000080808000), CONST64(0x0080002080808000), CONST64(0x0080000000000080), CONST64(0x0080002000000080), CONST64(0x0080000080000080), CONST64(0x0080002080000080), CONST64(0x0080000000800080), CONST64(0x0080002000800080), CONST64(0x0080000080800080), CONST64(0x0080002080800080), CONST64(0x0080000000008080), CONST64(0x0080002000008080), CONST64(0x0080000080008080), CONST64(0x0080002080008080), CONST64(0x0080000000808080), CONST64(0x0080002000808080), CONST64(0x0080000080808080), CONST64(0x0080002080808080), CONST64(0x8080000000000000), CONST64(0x8080002000000000), CONST64(0x8080000080000000), CONST64(0x8080002080000000), CONST64(0x8080000000800000), CONST64(0x8080002000800000), CONST64(0x8080000080800000), CONST64(0x8080002080800000), CONST64(0x8080000000008000), CONST64(0x8080002000008000), CONST64(0x8080000080008000), CONST64(0x8080002080008000), CONST64(0x8080000000808000), CONST64(0x8080002000808000), CONST64(0x8080000080808000), CONST64(0x8080002080808000), CONST64(0x8080000000000080), CONST64(0x8080002000000080), CONST64(0x8080000080000080), CONST64(0x8080002080000080), CONST64(0x8080000000800080), CONST64(0x8080002000800080), CONST64(0x8080000080800080), CONST64(0x8080002080800080), CONST64(0x8080000000008080), CONST64(0x8080002000008080), CONST64(0x8080000080008080), CONST64(0x8080002080008080), CONST64(0x8080000000808080), CONST64(0x8080002000808080), CONST64(0x8080000080808080), CONST64(0x8080002080808080), CONST64(0x0000800000000000), CONST64(0x0000802000000000), CONST64(0x0000800080000000), CONST64(0x0000802080000000), CONST64(0x0000800000800000), CONST64(0x0000802000800000), CONST64(0x0000800080800000), CONST64(0x0000802080800000), CONST64(0x0000800000008000), CONST64(0x0000802000008000), CONST64(0x0000800080008000), CONST64(0x0000802080008000), CONST64(0x0000800000808000), CONST64(0x0000802000808000), CONST64(0x0000800080808000), CONST64(0x0000802080808000), CONST64(0x0000800000000080), CONST64(0x0000802000000080), CONST64(0x0000800080000080), CONST64(0x0000802080000080), CONST64(0x0000800000800080), CONST64(0x0000802000800080), CONST64(0x0000800080800080), CONST64(0x0000802080800080), CONST64(0x0000800000008080), CONST64(0x0000802000008080), CONST64(0x0000800080008080), CONST64(0x0000802080008080), CONST64(0x0000800000808080), CONST64(0x0000802000808080), CONST64(0x0000800080808080), CONST64(0x0000802080808080), CONST64(0x8000800000000000), CONST64(0x8000802000000000), CONST64(0x8000800080000000), CONST64(0x8000802080000000), CONST64(0x8000800000800000), CONST64(0x8000802000800000), CONST64(0x8000800080800000), CONST64(0x8000802080800000), CONST64(0x8000800000008000), CONST64(0x8000802000008000), CONST64(0x8000800080008000), CONST64(0x8000802080008000), CONST64(0x8000800000808000), CONST64(0x8000802000808000), CONST64(0x8000800080808000), CONST64(0x8000802080808000), CONST64(0x8000800000000080), CONST64(0x8000802000000080), CONST64(0x8000800080000080), CONST64(0x8000802080000080), CONST64(0x8000800000800080), CONST64(0x8000802000800080), CONST64(0x8000800080800080), CONST64(0x8000802080800080), CONST64(0x8000800000008080), CONST64(0x8000802000008080), CONST64(0x8000800080008080), CONST64(0x8000802080008080), CONST64(0x8000800000808080), CONST64(0x8000802000808080), CONST64(0x8000800080808080), CONST64(0x8000802080808080), CONST64(0x0080800000000000), CONST64(0x0080802000000000), CONST64(0x0080800080000000), CONST64(0x0080802080000000), CONST64(0x0080800000800000), CONST64(0x0080802000800000), CONST64(0x0080800080800000), CONST64(0x0080802080800000), CONST64(0x0080800000008000), CONST64(0x0080802000008000), CONST64(0x0080800080008000), CONST64(0x0080802080008000), CONST64(0x0080800000808000), CONST64(0x0080802000808000), CONST64(0x0080800080808000), CONST64(0x0080802080808000), CONST64(0x0080800000000080), CONST64(0x0080802000000080), CONST64(0x0080800080000080), CONST64(0x0080802080000080), CONST64(0x0080800000800080), CONST64(0x0080802000800080), CONST64(0x0080800080800080), CONST64(0x0080802080800080), CONST64(0x0080800000008080), CONST64(0x0080802000008080), CONST64(0x0080800080008080), CONST64(0x0080802080008080), CONST64(0x0080800000808080), CONST64(0x0080802000808080), CONST64(0x0080800080808080), CONST64(0x0080802080808080), CONST64(0x8080800000000000), CONST64(0x8080802000000000), CONST64(0x8080800080000000), CONST64(0x8080802080000000), CONST64(0x8080800000800000), CONST64(0x8080802000800000), CONST64(0x8080800080800000), CONST64(0x8080802080800000), CONST64(0x8080800000008000), CONST64(0x8080802000008000), CONST64(0x8080800080008000), CONST64(0x8080802080008000), CONST64(0x8080800000808000), CONST64(0x8080802000808000), CONST64(0x8080800080808000), CONST64(0x8080802080808000), CONST64(0x8080800000000080), CONST64(0x8080802000000080), CONST64(0x8080800080000080), CONST64(0x8080802080000080), CONST64(0x8080800000800080), CONST64(0x8080802000800080), CONST64(0x8080800080800080), CONST64(0x8080802080800080), CONST64(0x8080800000008080), CONST64(0x8080802000008080), CONST64(0x8080800080008080), CONST64(0x8080802080008080), CONST64(0x8080800000808080), CONST64(0x8080802000808080), CONST64(0x8080800080808080), CONST64(0x8080802080808080) }, { CONST64(0x0000000000000000), CONST64(0x0000004000000000), CONST64(0x0000000001000000), CONST64(0x0000004001000000), CONST64(0x0000000000010000), CONST64(0x0000004000010000), CONST64(0x0000000001010000), CONST64(0x0000004001010000), CONST64(0x0000000000000100), CONST64(0x0000004000000100), CONST64(0x0000000001000100), CONST64(0x0000004001000100), CONST64(0x0000000000010100), CONST64(0x0000004000010100), CONST64(0x0000000001010100), CONST64(0x0000004001010100), CONST64(0x0000000000000001), CONST64(0x0000004000000001), CONST64(0x0000000001000001), CONST64(0x0000004001000001), CONST64(0x0000000000010001), CONST64(0x0000004000010001), CONST64(0x0000000001010001), CONST64(0x0000004001010001), CONST64(0x0000000000000101), CONST64(0x0000004000000101), CONST64(0x0000000001000101), CONST64(0x0000004001000101), CONST64(0x0000000000010101), CONST64(0x0000004000010101), CONST64(0x0000000001010101), CONST64(0x0000004001010101), CONST64(0x0100000000000000), CONST64(0x0100004000000000), CONST64(0x0100000001000000), CONST64(0x0100004001000000), CONST64(0x0100000000010000), CONST64(0x0100004000010000), CONST64(0x0100000001010000), CONST64(0x0100004001010000), CONST64(0x0100000000000100), CONST64(0x0100004000000100), CONST64(0x0100000001000100), CONST64(0x0100004001000100), CONST64(0x0100000000010100), CONST64(0x0100004000010100), CONST64(0x0100000001010100), CONST64(0x0100004001010100), CONST64(0x0100000000000001), CONST64(0x0100004000000001), CONST64(0x0100000001000001), CONST64(0x0100004001000001), CONST64(0x0100000000010001), CONST64(0x0100004000010001), CONST64(0x0100000001010001), CONST64(0x0100004001010001), CONST64(0x0100000000000101), CONST64(0x0100004000000101), CONST64(0x0100000001000101), CONST64(0x0100004001000101), CONST64(0x0100000000010101), CONST64(0x0100004000010101), CONST64(0x0100000001010101), CONST64(0x0100004001010101), CONST64(0x0001000000000000), CONST64(0x0001004000000000), CONST64(0x0001000001000000), CONST64(0x0001004001000000), CONST64(0x0001000000010000), CONST64(0x0001004000010000), CONST64(0x0001000001010000), CONST64(0x0001004001010000), CONST64(0x0001000000000100), CONST64(0x0001004000000100), CONST64(0x0001000001000100), CONST64(0x0001004001000100), CONST64(0x0001000000010100), CONST64(0x0001004000010100), CONST64(0x0001000001010100), CONST64(0x0001004001010100), CONST64(0x0001000000000001), CONST64(0x0001004000000001), CONST64(0x0001000001000001), CONST64(0x0001004001000001), CONST64(0x0001000000010001), CONST64(0x0001004000010001), CONST64(0x0001000001010001), CONST64(0x0001004001010001), CONST64(0x0001000000000101), CONST64(0x0001004000000101), CONST64(0x0001000001000101), CONST64(0x0001004001000101), CONST64(0x0001000000010101), CONST64(0x0001004000010101), CONST64(0x0001000001010101), CONST64(0x0001004001010101), CONST64(0x0101000000000000), CONST64(0x0101004000000000), CONST64(0x0101000001000000), CONST64(0x0101004001000000), CONST64(0x0101000000010000), CONST64(0x0101004000010000), CONST64(0x0101000001010000), CONST64(0x0101004001010000), CONST64(0x0101000000000100), CONST64(0x0101004000000100), CONST64(0x0101000001000100), CONST64(0x0101004001000100), CONST64(0x0101000000010100), CONST64(0x0101004000010100), CONST64(0x0101000001010100), CONST64(0x0101004001010100), CONST64(0x0101000000000001), CONST64(0x0101004000000001), CONST64(0x0101000001000001), CONST64(0x0101004001000001), CONST64(0x0101000000010001), CONST64(0x0101004000010001), CONST64(0x0101000001010001), CONST64(0x0101004001010001), CONST64(0x0101000000000101), CONST64(0x0101004000000101), CONST64(0x0101000001000101), CONST64(0x0101004001000101), CONST64(0x0101000000010101), CONST64(0x0101004000010101), CONST64(0x0101000001010101), CONST64(0x0101004001010101), CONST64(0x0000010000000000), CONST64(0x0000014000000000), CONST64(0x0000010001000000), CONST64(0x0000014001000000), CONST64(0x0000010000010000), CONST64(0x0000014000010000), CONST64(0x0000010001010000), CONST64(0x0000014001010000), CONST64(0x0000010000000100), CONST64(0x0000014000000100), CONST64(0x0000010001000100), CONST64(0x0000014001000100), CONST64(0x0000010000010100), CONST64(0x0000014000010100), CONST64(0x0000010001010100), CONST64(0x0000014001010100), CONST64(0x0000010000000001), CONST64(0x0000014000000001), CONST64(0x0000010001000001), CONST64(0x0000014001000001), CONST64(0x0000010000010001), CONST64(0x0000014000010001), CONST64(0x0000010001010001), CONST64(0x0000014001010001), CONST64(0x0000010000000101), CONST64(0x0000014000000101), CONST64(0x0000010001000101), CONST64(0x0000014001000101), CONST64(0x0000010000010101), CONST64(0x0000014000010101), CONST64(0x0000010001010101), CONST64(0x0000014001010101), CONST64(0x0100010000000000), CONST64(0x0100014000000000), CONST64(0x0100010001000000), CONST64(0x0100014001000000), CONST64(0x0100010000010000), CONST64(0x0100014000010000), CONST64(0x0100010001010000), CONST64(0x0100014001010000), CONST64(0x0100010000000100), CONST64(0x0100014000000100), CONST64(0x0100010001000100), CONST64(0x0100014001000100), CONST64(0x0100010000010100), CONST64(0x0100014000010100), CONST64(0x0100010001010100), CONST64(0x0100014001010100), CONST64(0x0100010000000001), CONST64(0x0100014000000001), CONST64(0x0100010001000001), CONST64(0x0100014001000001), CONST64(0x0100010000010001), CONST64(0x0100014000010001), CONST64(0x0100010001010001), CONST64(0x0100014001010001), CONST64(0x0100010000000101), CONST64(0x0100014000000101), CONST64(0x0100010001000101), CONST64(0x0100014001000101), CONST64(0x0100010000010101), CONST64(0x0100014000010101), CONST64(0x0100010001010101), CONST64(0x0100014001010101), CONST64(0x0001010000000000), CONST64(0x0001014000000000), CONST64(0x0001010001000000), CONST64(0x0001014001000000), CONST64(0x0001010000010000), CONST64(0x0001014000010000), CONST64(0x0001010001010000), CONST64(0x0001014001010000), CONST64(0x0001010000000100), CONST64(0x0001014000000100), CONST64(0x0001010001000100), CONST64(0x0001014001000100), CONST64(0x0001010000010100), CONST64(0x0001014000010100), CONST64(0x0001010001010100), CONST64(0x0001014001010100), CONST64(0x0001010000000001), CONST64(0x0001014000000001), CONST64(0x0001010001000001), CONST64(0x0001014001000001), CONST64(0x0001010000010001), CONST64(0x0001014000010001), CONST64(0x0001010001010001), CONST64(0x0001014001010001), CONST64(0x0001010000000101), CONST64(0x0001014000000101), CONST64(0x0001010001000101), CONST64(0x0001014001000101), CONST64(0x0001010000010101), CONST64(0x0001014000010101), CONST64(0x0001010001010101), CONST64(0x0001014001010101), CONST64(0x0101010000000000), CONST64(0x0101014000000000), CONST64(0x0101010001000000), CONST64(0x0101014001000000), CONST64(0x0101010000010000), CONST64(0x0101014000010000), CONST64(0x0101010001010000), CONST64(0x0101014001010000), CONST64(0x0101010000000100), CONST64(0x0101014000000100), CONST64(0x0101010001000100), CONST64(0x0101014001000100), CONST64(0x0101010000010100), CONST64(0x0101014000010100), CONST64(0x0101010001010100), CONST64(0x0101014001010100), CONST64(0x0101010000000001), CONST64(0x0101014000000001), CONST64(0x0101010001000001), CONST64(0x0101014001000001), CONST64(0x0101010000010001), CONST64(0x0101014000010001), CONST64(0x0101010001010001), CONST64(0x0101014001010001), CONST64(0x0101010000000101), CONST64(0x0101014000000101), CONST64(0x0101010001000101), CONST64(0x0101014001000101), CONST64(0x0101010000010101), CONST64(0x0101014000010101), CONST64(0x0101010001010101), CONST64(0x0101014001010101) }, { CONST64(0x0000000000000000), CONST64(0x0000000100000000), CONST64(0x0000000004000000), CONST64(0x0000000104000000), CONST64(0x0000000000040000), CONST64(0x0000000100040000), CONST64(0x0000000004040000), CONST64(0x0000000104040000), CONST64(0x0000000000000400), CONST64(0x0000000100000400), CONST64(0x0000000004000400), CONST64(0x0000000104000400), CONST64(0x0000000000040400), CONST64(0x0000000100040400), CONST64(0x0000000004040400), CONST64(0x0000000104040400), CONST64(0x0000000000000004), CONST64(0x0000000100000004), CONST64(0x0000000004000004), CONST64(0x0000000104000004), CONST64(0x0000000000040004), CONST64(0x0000000100040004), CONST64(0x0000000004040004), CONST64(0x0000000104040004), CONST64(0x0000000000000404), CONST64(0x0000000100000404), CONST64(0x0000000004000404), CONST64(0x0000000104000404), CONST64(0x0000000000040404), CONST64(0x0000000100040404), CONST64(0x0000000004040404), CONST64(0x0000000104040404), CONST64(0x0400000000000000), CONST64(0x0400000100000000), CONST64(0x0400000004000000), CONST64(0x0400000104000000), CONST64(0x0400000000040000), CONST64(0x0400000100040000), CONST64(0x0400000004040000), CONST64(0x0400000104040000), CONST64(0x0400000000000400), CONST64(0x0400000100000400), CONST64(0x0400000004000400), CONST64(0x0400000104000400), CONST64(0x0400000000040400), CONST64(0x0400000100040400), CONST64(0x0400000004040400), CONST64(0x0400000104040400), CONST64(0x0400000000000004), CONST64(0x0400000100000004), CONST64(0x0400000004000004), CONST64(0x0400000104000004), CONST64(0x0400000000040004), CONST64(0x0400000100040004), CONST64(0x0400000004040004), CONST64(0x0400000104040004), CONST64(0x0400000000000404), CONST64(0x0400000100000404), CONST64(0x0400000004000404), CONST64(0x0400000104000404), CONST64(0x0400000000040404), CONST64(0x0400000100040404), CONST64(0x0400000004040404), CONST64(0x0400000104040404), CONST64(0x0004000000000000), CONST64(0x0004000100000000), CONST64(0x0004000004000000), CONST64(0x0004000104000000), CONST64(0x0004000000040000), CONST64(0x0004000100040000), CONST64(0x0004000004040000), CONST64(0x0004000104040000), CONST64(0x0004000000000400), CONST64(0x0004000100000400), CONST64(0x0004000004000400), CONST64(0x0004000104000400), CONST64(0x0004000000040400), CONST64(0x0004000100040400), CONST64(0x0004000004040400), CONST64(0x0004000104040400), CONST64(0x0004000000000004), CONST64(0x0004000100000004), CONST64(0x0004000004000004), CONST64(0x0004000104000004), CONST64(0x0004000000040004), CONST64(0x0004000100040004), CONST64(0x0004000004040004), CONST64(0x0004000104040004), CONST64(0x0004000000000404), CONST64(0x0004000100000404), CONST64(0x0004000004000404), CONST64(0x0004000104000404), CONST64(0x0004000000040404), CONST64(0x0004000100040404), CONST64(0x0004000004040404), CONST64(0x0004000104040404), CONST64(0x0404000000000000), CONST64(0x0404000100000000), CONST64(0x0404000004000000), CONST64(0x0404000104000000), CONST64(0x0404000000040000), CONST64(0x0404000100040000), CONST64(0x0404000004040000), CONST64(0x0404000104040000), CONST64(0x0404000000000400), CONST64(0x0404000100000400), CONST64(0x0404000004000400), CONST64(0x0404000104000400), CONST64(0x0404000000040400), CONST64(0x0404000100040400), CONST64(0x0404000004040400), CONST64(0x0404000104040400), CONST64(0x0404000000000004), CONST64(0x0404000100000004), CONST64(0x0404000004000004), CONST64(0x0404000104000004), CONST64(0x0404000000040004), CONST64(0x0404000100040004), CONST64(0x0404000004040004), CONST64(0x0404000104040004), CONST64(0x0404000000000404), CONST64(0x0404000100000404), CONST64(0x0404000004000404), CONST64(0x0404000104000404), CONST64(0x0404000000040404), CONST64(0x0404000100040404), CONST64(0x0404000004040404), CONST64(0x0404000104040404), CONST64(0x0000040000000000), CONST64(0x0000040100000000), CONST64(0x0000040004000000), CONST64(0x0000040104000000), CONST64(0x0000040000040000), CONST64(0x0000040100040000), CONST64(0x0000040004040000), CONST64(0x0000040104040000), CONST64(0x0000040000000400), CONST64(0x0000040100000400), CONST64(0x0000040004000400), CONST64(0x0000040104000400), CONST64(0x0000040000040400), CONST64(0x0000040100040400), CONST64(0x0000040004040400), CONST64(0x0000040104040400), CONST64(0x0000040000000004), CONST64(0x0000040100000004), CONST64(0x0000040004000004), CONST64(0x0000040104000004), CONST64(0x0000040000040004), CONST64(0x0000040100040004), CONST64(0x0000040004040004), CONST64(0x0000040104040004), CONST64(0x0000040000000404), CONST64(0x0000040100000404), CONST64(0x0000040004000404), CONST64(0x0000040104000404), CONST64(0x0000040000040404), CONST64(0x0000040100040404), CONST64(0x0000040004040404), CONST64(0x0000040104040404), CONST64(0x0400040000000000), CONST64(0x0400040100000000), CONST64(0x0400040004000000), CONST64(0x0400040104000000), CONST64(0x0400040000040000), CONST64(0x0400040100040000), CONST64(0x0400040004040000), CONST64(0x0400040104040000), CONST64(0x0400040000000400), CONST64(0x0400040100000400), CONST64(0x0400040004000400), CONST64(0x0400040104000400), CONST64(0x0400040000040400), CONST64(0x0400040100040400), CONST64(0x0400040004040400), CONST64(0x0400040104040400), CONST64(0x0400040000000004), CONST64(0x0400040100000004), CONST64(0x0400040004000004), CONST64(0x0400040104000004), CONST64(0x0400040000040004), CONST64(0x0400040100040004), CONST64(0x0400040004040004), CONST64(0x0400040104040004), CONST64(0x0400040000000404), CONST64(0x0400040100000404), CONST64(0x0400040004000404), CONST64(0x0400040104000404), CONST64(0x0400040000040404), CONST64(0x0400040100040404), CONST64(0x0400040004040404), CONST64(0x0400040104040404), CONST64(0x0004040000000000), CONST64(0x0004040100000000), CONST64(0x0004040004000000), CONST64(0x0004040104000000), CONST64(0x0004040000040000), CONST64(0x0004040100040000), CONST64(0x0004040004040000), CONST64(0x0004040104040000), CONST64(0x0004040000000400), CONST64(0x0004040100000400), CONST64(0x0004040004000400), CONST64(0x0004040104000400), CONST64(0x0004040000040400), CONST64(0x0004040100040400), CONST64(0x0004040004040400), CONST64(0x0004040104040400), CONST64(0x0004040000000004), CONST64(0x0004040100000004), CONST64(0x0004040004000004), CONST64(0x0004040104000004), CONST64(0x0004040000040004), CONST64(0x0004040100040004), CONST64(0x0004040004040004), CONST64(0x0004040104040004), CONST64(0x0004040000000404), CONST64(0x0004040100000404), CONST64(0x0004040004000404), CONST64(0x0004040104000404), CONST64(0x0004040000040404), CONST64(0x0004040100040404), CONST64(0x0004040004040404), CONST64(0x0004040104040404), CONST64(0x0404040000000000), CONST64(0x0404040100000000), CONST64(0x0404040004000000), CONST64(0x0404040104000000), CONST64(0x0404040000040000), CONST64(0x0404040100040000), CONST64(0x0404040004040000), CONST64(0x0404040104040000), CONST64(0x0404040000000400), CONST64(0x0404040100000400), CONST64(0x0404040004000400), CONST64(0x0404040104000400), CONST64(0x0404040000040400), CONST64(0x0404040100040400), CONST64(0x0404040004040400), CONST64(0x0404040104040400), CONST64(0x0404040000000004), CONST64(0x0404040100000004), CONST64(0x0404040004000004), CONST64(0x0404040104000004), CONST64(0x0404040000040004), CONST64(0x0404040100040004), CONST64(0x0404040004040004), CONST64(0x0404040104040004), CONST64(0x0404040000000404), CONST64(0x0404040100000404), CONST64(0x0404040004000404), CONST64(0x0404040104000404), CONST64(0x0404040000040404), CONST64(0x0404040100040404), CONST64(0x0404040004040404), CONST64(0x0404040104040404) }, { CONST64(0x0000000000000000), CONST64(0x0000000400000000), CONST64(0x0000000010000000), CONST64(0x0000000410000000), CONST64(0x0000000000100000), CONST64(0x0000000400100000), CONST64(0x0000000010100000), CONST64(0x0000000410100000), CONST64(0x0000000000001000), CONST64(0x0000000400001000), CONST64(0x0000000010001000), CONST64(0x0000000410001000), CONST64(0x0000000000101000), CONST64(0x0000000400101000), CONST64(0x0000000010101000), CONST64(0x0000000410101000), CONST64(0x0000000000000010), CONST64(0x0000000400000010), CONST64(0x0000000010000010), CONST64(0x0000000410000010), CONST64(0x0000000000100010), CONST64(0x0000000400100010), CONST64(0x0000000010100010), CONST64(0x0000000410100010), CONST64(0x0000000000001010), CONST64(0x0000000400001010), CONST64(0x0000000010001010), CONST64(0x0000000410001010), CONST64(0x0000000000101010), CONST64(0x0000000400101010), CONST64(0x0000000010101010), CONST64(0x0000000410101010), CONST64(0x1000000000000000), CONST64(0x1000000400000000), CONST64(0x1000000010000000), CONST64(0x1000000410000000), CONST64(0x1000000000100000), CONST64(0x1000000400100000), CONST64(0x1000000010100000), CONST64(0x1000000410100000), CONST64(0x1000000000001000), CONST64(0x1000000400001000), CONST64(0x1000000010001000), CONST64(0x1000000410001000), CONST64(0x1000000000101000), CONST64(0x1000000400101000), CONST64(0x1000000010101000), CONST64(0x1000000410101000), CONST64(0x1000000000000010), CONST64(0x1000000400000010), CONST64(0x1000000010000010), CONST64(0x1000000410000010), CONST64(0x1000000000100010), CONST64(0x1000000400100010), CONST64(0x1000000010100010), CONST64(0x1000000410100010), CONST64(0x1000000000001010), CONST64(0x1000000400001010), CONST64(0x1000000010001010), CONST64(0x1000000410001010), CONST64(0x1000000000101010), CONST64(0x1000000400101010), CONST64(0x1000000010101010), CONST64(0x1000000410101010), CONST64(0x0010000000000000), CONST64(0x0010000400000000), CONST64(0x0010000010000000), CONST64(0x0010000410000000), CONST64(0x0010000000100000), CONST64(0x0010000400100000), CONST64(0x0010000010100000), CONST64(0x0010000410100000), CONST64(0x0010000000001000), CONST64(0x0010000400001000), CONST64(0x0010000010001000), CONST64(0x0010000410001000), CONST64(0x0010000000101000), CONST64(0x0010000400101000), CONST64(0x0010000010101000), CONST64(0x0010000410101000), CONST64(0x0010000000000010), CONST64(0x0010000400000010), CONST64(0x0010000010000010), CONST64(0x0010000410000010), CONST64(0x0010000000100010), CONST64(0x0010000400100010), CONST64(0x0010000010100010), CONST64(0x0010000410100010), CONST64(0x0010000000001010), CONST64(0x0010000400001010), CONST64(0x0010000010001010), CONST64(0x0010000410001010), CONST64(0x0010000000101010), CONST64(0x0010000400101010), CONST64(0x0010000010101010), CONST64(0x0010000410101010), CONST64(0x1010000000000000), CONST64(0x1010000400000000), CONST64(0x1010000010000000), CONST64(0x1010000410000000), CONST64(0x1010000000100000), CONST64(0x1010000400100000), CONST64(0x1010000010100000), CONST64(0x1010000410100000), CONST64(0x1010000000001000), CONST64(0x1010000400001000), CONST64(0x1010000010001000), CONST64(0x1010000410001000), CONST64(0x1010000000101000), CONST64(0x1010000400101000), CONST64(0x1010000010101000), CONST64(0x1010000410101000), CONST64(0x1010000000000010), CONST64(0x1010000400000010), CONST64(0x1010000010000010), CONST64(0x1010000410000010), CONST64(0x1010000000100010), CONST64(0x1010000400100010), CONST64(0x1010000010100010), CONST64(0x1010000410100010), CONST64(0x1010000000001010), CONST64(0x1010000400001010), CONST64(0x1010000010001010), CONST64(0x1010000410001010), CONST64(0x1010000000101010), CONST64(0x1010000400101010), CONST64(0x1010000010101010), CONST64(0x1010000410101010), CONST64(0x0000100000000000), CONST64(0x0000100400000000), CONST64(0x0000100010000000), CONST64(0x0000100410000000), CONST64(0x0000100000100000), CONST64(0x0000100400100000), CONST64(0x0000100010100000), CONST64(0x0000100410100000), CONST64(0x0000100000001000), CONST64(0x0000100400001000), CONST64(0x0000100010001000), CONST64(0x0000100410001000), CONST64(0x0000100000101000), CONST64(0x0000100400101000), CONST64(0x0000100010101000), CONST64(0x0000100410101000), CONST64(0x0000100000000010), CONST64(0x0000100400000010), CONST64(0x0000100010000010), CONST64(0x0000100410000010), CONST64(0x0000100000100010), CONST64(0x0000100400100010), CONST64(0x0000100010100010), CONST64(0x0000100410100010), CONST64(0x0000100000001010), CONST64(0x0000100400001010), CONST64(0x0000100010001010), CONST64(0x0000100410001010), CONST64(0x0000100000101010), CONST64(0x0000100400101010), CONST64(0x0000100010101010), CONST64(0x0000100410101010), CONST64(0x1000100000000000), CONST64(0x1000100400000000), CONST64(0x1000100010000000), CONST64(0x1000100410000000), CONST64(0x1000100000100000), CONST64(0x1000100400100000), CONST64(0x1000100010100000), CONST64(0x1000100410100000), CONST64(0x1000100000001000), CONST64(0x1000100400001000), CONST64(0x1000100010001000), CONST64(0x1000100410001000), CONST64(0x1000100000101000), CONST64(0x1000100400101000), CONST64(0x1000100010101000), CONST64(0x1000100410101000), CONST64(0x1000100000000010), CONST64(0x1000100400000010), CONST64(0x1000100010000010), CONST64(0x1000100410000010), CONST64(0x1000100000100010), CONST64(0x1000100400100010), CONST64(0x1000100010100010), CONST64(0x1000100410100010), CONST64(0x1000100000001010), CONST64(0x1000100400001010), CONST64(0x1000100010001010), CONST64(0x1000100410001010), CONST64(0x1000100000101010), CONST64(0x1000100400101010), CONST64(0x1000100010101010), CONST64(0x1000100410101010), CONST64(0x0010100000000000), CONST64(0x0010100400000000), CONST64(0x0010100010000000), CONST64(0x0010100410000000), CONST64(0x0010100000100000), CONST64(0x0010100400100000), CONST64(0x0010100010100000), CONST64(0x0010100410100000), CONST64(0x0010100000001000), CONST64(0x0010100400001000), CONST64(0x0010100010001000), CONST64(0x0010100410001000), CONST64(0x0010100000101000), CONST64(0x0010100400101000), CONST64(0x0010100010101000), CONST64(0x0010100410101000), CONST64(0x0010100000000010), CONST64(0x0010100400000010), CONST64(0x0010100010000010), CONST64(0x0010100410000010), CONST64(0x0010100000100010), CONST64(0x0010100400100010), CONST64(0x0010100010100010), CONST64(0x0010100410100010), CONST64(0x0010100000001010), CONST64(0x0010100400001010), CONST64(0x0010100010001010), CONST64(0x0010100410001010), CONST64(0x0010100000101010), CONST64(0x0010100400101010), CONST64(0x0010100010101010), CONST64(0x0010100410101010), CONST64(0x1010100000000000), CONST64(0x1010100400000000), CONST64(0x1010100010000000), CONST64(0x1010100410000000), CONST64(0x1010100000100000), CONST64(0x1010100400100000), CONST64(0x1010100010100000), CONST64(0x1010100410100000), CONST64(0x1010100000001000), CONST64(0x1010100400001000), CONST64(0x1010100010001000), CONST64(0x1010100410001000), CONST64(0x1010100000101000), CONST64(0x1010100400101000), CONST64(0x1010100010101000), CONST64(0x1010100410101000), CONST64(0x1010100000000010), CONST64(0x1010100400000010), CONST64(0x1010100010000010), CONST64(0x1010100410000010), CONST64(0x1010100000100010), CONST64(0x1010100400100010), CONST64(0x1010100010100010), CONST64(0x1010100410100010), CONST64(0x1010100000001010), CONST64(0x1010100400001010), CONST64(0x1010100010001010), CONST64(0x1010100410001010), CONST64(0x1010100000101010), CONST64(0x1010100400101010), CONST64(0x1010100010101010), CONST64(0x1010100410101010) }, { CONST64(0x0000000000000000), CONST64(0x0000001000000000), CONST64(0x0000000040000000), CONST64(0x0000001040000000), CONST64(0x0000000000400000), CONST64(0x0000001000400000), CONST64(0x0000000040400000), CONST64(0x0000001040400000), CONST64(0x0000000000004000), CONST64(0x0000001000004000), CONST64(0x0000000040004000), CONST64(0x0000001040004000), CONST64(0x0000000000404000), CONST64(0x0000001000404000), CONST64(0x0000000040404000), CONST64(0x0000001040404000), CONST64(0x0000000000000040), CONST64(0x0000001000000040), CONST64(0x0000000040000040), CONST64(0x0000001040000040), CONST64(0x0000000000400040), CONST64(0x0000001000400040), CONST64(0x0000000040400040), CONST64(0x0000001040400040), CONST64(0x0000000000004040), CONST64(0x0000001000004040), CONST64(0x0000000040004040), CONST64(0x0000001040004040), CONST64(0x0000000000404040), CONST64(0x0000001000404040), CONST64(0x0000000040404040), CONST64(0x0000001040404040), CONST64(0x4000000000000000), CONST64(0x4000001000000000), CONST64(0x4000000040000000), CONST64(0x4000001040000000), CONST64(0x4000000000400000), CONST64(0x4000001000400000), CONST64(0x4000000040400000), CONST64(0x4000001040400000), CONST64(0x4000000000004000), CONST64(0x4000001000004000), CONST64(0x4000000040004000), CONST64(0x4000001040004000), CONST64(0x4000000000404000), CONST64(0x4000001000404000), CONST64(0x4000000040404000), CONST64(0x4000001040404000), CONST64(0x4000000000000040), CONST64(0x4000001000000040), CONST64(0x4000000040000040), CONST64(0x4000001040000040), CONST64(0x4000000000400040), CONST64(0x4000001000400040), CONST64(0x4000000040400040), CONST64(0x4000001040400040), CONST64(0x4000000000004040), CONST64(0x4000001000004040), CONST64(0x4000000040004040), CONST64(0x4000001040004040), CONST64(0x4000000000404040), CONST64(0x4000001000404040), CONST64(0x4000000040404040), CONST64(0x4000001040404040), CONST64(0x0040000000000000), CONST64(0x0040001000000000), CONST64(0x0040000040000000), CONST64(0x0040001040000000), CONST64(0x0040000000400000), CONST64(0x0040001000400000), CONST64(0x0040000040400000), CONST64(0x0040001040400000), CONST64(0x0040000000004000), CONST64(0x0040001000004000), CONST64(0x0040000040004000), CONST64(0x0040001040004000), CONST64(0x0040000000404000), CONST64(0x0040001000404000), CONST64(0x0040000040404000), CONST64(0x0040001040404000), CONST64(0x0040000000000040), CONST64(0x0040001000000040), CONST64(0x0040000040000040), CONST64(0x0040001040000040), CONST64(0x0040000000400040), CONST64(0x0040001000400040), CONST64(0x0040000040400040), CONST64(0x0040001040400040), CONST64(0x0040000000004040), CONST64(0x0040001000004040), CONST64(0x0040000040004040), CONST64(0x0040001040004040), CONST64(0x0040000000404040), CONST64(0x0040001000404040), CONST64(0x0040000040404040), CONST64(0x0040001040404040), CONST64(0x4040000000000000), CONST64(0x4040001000000000), CONST64(0x4040000040000000), CONST64(0x4040001040000000), CONST64(0x4040000000400000), CONST64(0x4040001000400000), CONST64(0x4040000040400000), CONST64(0x4040001040400000), CONST64(0x4040000000004000), CONST64(0x4040001000004000), CONST64(0x4040000040004000), CONST64(0x4040001040004000), CONST64(0x4040000000404000), CONST64(0x4040001000404000), CONST64(0x4040000040404000), CONST64(0x4040001040404000), CONST64(0x4040000000000040), CONST64(0x4040001000000040), CONST64(0x4040000040000040), CONST64(0x4040001040000040), CONST64(0x4040000000400040), CONST64(0x4040001000400040), CONST64(0x4040000040400040), CONST64(0x4040001040400040), CONST64(0x4040000000004040), CONST64(0x4040001000004040), CONST64(0x4040000040004040), CONST64(0x4040001040004040), CONST64(0x4040000000404040), CONST64(0x4040001000404040), CONST64(0x4040000040404040), CONST64(0x4040001040404040), CONST64(0x0000400000000000), CONST64(0x0000401000000000), CONST64(0x0000400040000000), CONST64(0x0000401040000000), CONST64(0x0000400000400000), CONST64(0x0000401000400000), CONST64(0x0000400040400000), CONST64(0x0000401040400000), CONST64(0x0000400000004000), CONST64(0x0000401000004000), CONST64(0x0000400040004000), CONST64(0x0000401040004000), CONST64(0x0000400000404000), CONST64(0x0000401000404000), CONST64(0x0000400040404000), CONST64(0x0000401040404000), CONST64(0x0000400000000040), CONST64(0x0000401000000040), CONST64(0x0000400040000040), CONST64(0x0000401040000040), CONST64(0x0000400000400040), CONST64(0x0000401000400040), CONST64(0x0000400040400040), CONST64(0x0000401040400040), CONST64(0x0000400000004040), CONST64(0x0000401000004040), CONST64(0x0000400040004040), CONST64(0x0000401040004040), CONST64(0x0000400000404040), CONST64(0x0000401000404040), CONST64(0x0000400040404040), CONST64(0x0000401040404040), CONST64(0x4000400000000000), CONST64(0x4000401000000000), CONST64(0x4000400040000000), CONST64(0x4000401040000000), CONST64(0x4000400000400000), CONST64(0x4000401000400000), CONST64(0x4000400040400000), CONST64(0x4000401040400000), CONST64(0x4000400000004000), CONST64(0x4000401000004000), CONST64(0x4000400040004000), CONST64(0x4000401040004000), CONST64(0x4000400000404000), CONST64(0x4000401000404000), CONST64(0x4000400040404000), CONST64(0x4000401040404000), CONST64(0x4000400000000040), CONST64(0x4000401000000040), CONST64(0x4000400040000040), CONST64(0x4000401040000040), CONST64(0x4000400000400040), CONST64(0x4000401000400040), CONST64(0x4000400040400040), CONST64(0x4000401040400040), CONST64(0x4000400000004040), CONST64(0x4000401000004040), CONST64(0x4000400040004040), CONST64(0x4000401040004040), CONST64(0x4000400000404040), CONST64(0x4000401000404040), CONST64(0x4000400040404040), CONST64(0x4000401040404040), CONST64(0x0040400000000000), CONST64(0x0040401000000000), CONST64(0x0040400040000000), CONST64(0x0040401040000000), CONST64(0x0040400000400000), CONST64(0x0040401000400000), CONST64(0x0040400040400000), CONST64(0x0040401040400000), CONST64(0x0040400000004000), CONST64(0x0040401000004000), CONST64(0x0040400040004000), CONST64(0x0040401040004000), CONST64(0x0040400000404000), CONST64(0x0040401000404000), CONST64(0x0040400040404000), CONST64(0x0040401040404000), CONST64(0x0040400000000040), CONST64(0x0040401000000040), CONST64(0x0040400040000040), CONST64(0x0040401040000040), CONST64(0x0040400000400040), CONST64(0x0040401000400040), CONST64(0x0040400040400040), CONST64(0x0040401040400040), CONST64(0x0040400000004040), CONST64(0x0040401000004040), CONST64(0x0040400040004040), CONST64(0x0040401040004040), CONST64(0x0040400000404040), CONST64(0x0040401000404040), CONST64(0x0040400040404040), CONST64(0x0040401040404040), CONST64(0x4040400000000000), CONST64(0x4040401000000000), CONST64(0x4040400040000000), CONST64(0x4040401040000000), CONST64(0x4040400000400000), CONST64(0x4040401000400000), CONST64(0x4040400040400000), CONST64(0x4040401040400000), CONST64(0x4040400000004000), CONST64(0x4040401000004000), CONST64(0x4040400040004000), CONST64(0x4040401040004000), CONST64(0x4040400000404000), CONST64(0x4040401000404000), CONST64(0x4040400040404000), CONST64(0x4040401040404000), CONST64(0x4040400000000040), CONST64(0x4040401000000040), CONST64(0x4040400040000040), CONST64(0x4040401040000040), CONST64(0x4040400000400040), CONST64(0x4040401000400040), CONST64(0x4040400040400040), CONST64(0x4040401040400040), CONST64(0x4040400000004040), CONST64(0x4040401000004040), CONST64(0x4040400040004040), CONST64(0x4040401040004040), CONST64(0x4040400000404040), CONST64(0x4040401000404040), CONST64(0x4040400040404040), CONST64(0x4040401040404040) }}; #endif static void cookey(const ulong32 *raw1, ulong32 *keyout); #ifdef LTC_CLEAN_STACK static void _deskey(const unsigned char *key, short edf, ulong32 *keyout) #else static void deskey(const unsigned char *key, short edf, ulong32 *keyout) #endif { ulong32 i, j, l, m, n, kn[32]; unsigned char pc1m[56], pcr[56]; for (j=0; j < 56; j++) { l = (ulong32)pc1[j]; m = l & 7; pc1m[j] = (unsigned char)((key[l >> 3U] & bytebit[m]) == bytebit[m] ? 1 : 0); } for (i=0; i < 16; i++) { if (edf == DE1) { m = (15 - i) << 1; } else { m = i << 1; } n = m + 1; kn[m] = kn[n] = 0L; for (j=0; j < 28; j++) { l = j + (ulong32)totrot[i]; if (l < 28) { pcr[j] = pc1m[l]; } else { pcr[j] = pc1m[l - 28]; } } for (/*j = 28*/; j < 56; j++) { l = j + (ulong32)totrot[i]; if (l < 56) { pcr[j] = pc1m[l]; } else { pcr[j] = pc1m[l - 28]; } } for (j=0; j < 24; j++) { if ((int)pcr[(int)pc2[j]] != 0) { kn[m] |= bigbyte[j]; } if ((int)pcr[(int)pc2[j+24]] != 0) { kn[n] |= bigbyte[j]; } } } cookey(kn, keyout); } #ifdef LTC_CLEAN_STACK static void deskey(const unsigned char *key, short edf, ulong32 *keyout) { _deskey(key, edf, keyout); burn_stack(sizeof(int)*5 + sizeof(ulong32)*32 + sizeof(unsigned char)*112); } #endif #ifdef LTC_CLEAN_STACK static void _cookey(const ulong32 *raw1, ulong32 *keyout) #else static void cookey(const ulong32 *raw1, ulong32 *keyout) #endif { ulong32 *cook; const ulong32 *raw0; ulong32 dough[32]; int i; cook = dough; for(i=0; i < 16; i++, raw1++) { raw0 = raw1++; *cook = (*raw0 & 0x00fc0000L) << 6; *cook |= (*raw0 & 0x00000fc0L) << 10; *cook |= (*raw1 & 0x00fc0000L) >> 10; *cook++ |= (*raw1 & 0x00000fc0L) >> 6; *cook = (*raw0 & 0x0003f000L) << 12; *cook |= (*raw0 & 0x0000003fL) << 16; *cook |= (*raw1 & 0x0003f000L) >> 4; *cook++ |= (*raw1 & 0x0000003fL); } XMEMCPY(keyout, dough, sizeof dough); } #ifdef LTC_CLEAN_STACK static void cookey(const ulong32 *raw1, ulong32 *keyout) { _cookey(raw1, keyout); burn_stack(sizeof(ulong32 *) * 2 + sizeof(ulong32)*32 + sizeof(int)); } #endif #ifndef LTC_CLEAN_STACK static void desfunc(ulong32 *block, const ulong32 *keys) #else static void _desfunc(ulong32 *block, const ulong32 *keys) #endif { ulong32 work, right, leftt; int cur_round; leftt = block[0]; right = block[1]; #ifdef LTC_SMALL_CODE work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL; right ^= work; leftt ^= (work << 4); work = ((leftt >> 16) ^ right) & 0x0000ffffL; right ^= work; leftt ^= (work << 16); work = ((right >> 2) ^ leftt) & 0x33333333L; leftt ^= work; right ^= (work << 2); work = ((right >> 8) ^ leftt) & 0x00ff00ffL; leftt ^= work; right ^= (work << 8); right = ROLc(right, 1); work = (leftt ^ right) & 0xaaaaaaaaL; leftt ^= work; right ^= work; leftt = ROLc(leftt, 1); #else { ulong64 tmp; tmp = des_ip[0][byte(leftt, 0)] ^ des_ip[1][byte(leftt, 1)] ^ des_ip[2][byte(leftt, 2)] ^ des_ip[3][byte(leftt, 3)] ^ des_ip[4][byte(right, 0)] ^ des_ip[5][byte(right, 1)] ^ des_ip[6][byte(right, 2)] ^ des_ip[7][byte(right, 3)]; leftt = (ulong32)(tmp >> 32); right = (ulong32)(tmp & 0xFFFFFFFFUL); } #endif for (cur_round = 0; cur_round < 8; cur_round++) { work = RORc(right, 4) ^ *keys++; leftt ^= SP7[work & 0x3fL] ^ SP5[(work >> 8) & 0x3fL] ^ SP3[(work >> 16) & 0x3fL] ^ SP1[(work >> 24) & 0x3fL]; work = right ^ *keys++; leftt ^= SP8[ work & 0x3fL] ^ SP6[(work >> 8) & 0x3fL] ^ SP4[(work >> 16) & 0x3fL] ^ SP2[(work >> 24) & 0x3fL]; work = RORc(leftt, 4) ^ *keys++; right ^= SP7[ work & 0x3fL] ^ SP5[(work >> 8) & 0x3fL] ^ SP3[(work >> 16) & 0x3fL] ^ SP1[(work >> 24) & 0x3fL]; work = leftt ^ *keys++; right ^= SP8[ work & 0x3fL] ^ SP6[(work >> 8) & 0x3fL] ^ SP4[(work >> 16) & 0x3fL] ^ SP2[(work >> 24) & 0x3fL]; } #ifdef LTC_SMALL_CODE right = RORc(right, 1); work = (leftt ^ right) & 0xaaaaaaaaL; leftt ^= work; right ^= work; leftt = RORc(leftt, 1); work = ((leftt >> 8) ^ right) & 0x00ff00ffL; right ^= work; leftt ^= (work << 8); /* -- */ work = ((leftt >> 2) ^ right) & 0x33333333L; right ^= work; leftt ^= (work << 2); work = ((right >> 16) ^ leftt) & 0x0000ffffL; leftt ^= work; right ^= (work << 16); work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL; leftt ^= work; right ^= (work << 4); #else { ulong64 tmp; tmp = des_fp[0][byte(leftt, 0)] ^ des_fp[1][byte(leftt, 1)] ^ des_fp[2][byte(leftt, 2)] ^ des_fp[3][byte(leftt, 3)] ^ des_fp[4][byte(right, 0)] ^ des_fp[5][byte(right, 1)] ^ des_fp[6][byte(right, 2)] ^ des_fp[7][byte(right, 3)]; leftt = (ulong32)(tmp >> 32); right = (ulong32)(tmp & 0xFFFFFFFFUL); } #endif block[0] = right; block[1] = leftt; } #ifdef LTC_CLEAN_STACK static void desfunc(ulong32 *block, const ulong32 *keys) { _desfunc(block, keys); burn_stack(sizeof(ulong32) * 4 + sizeof(int)); } #endif /** Initialize the LTC_DES block cipher @param key The symmetric key you wish to pass @param keylen The key length in bytes @param num_rounds The number of rounds desired (0 for default) @param skey The key in as scheduled by this function. @return CRYPT_OK if successful */ int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) { LTC_ARGCHK(key != NULL); LTC_ARGCHK(skey != NULL); if (num_rounds != 0 && num_rounds != 16) { return CRYPT_INVALID_ROUNDS; } if (keylen != 8) { return CRYPT_INVALID_KEYSIZE; } deskey(key, EN0, skey->des.ek); deskey(key, DE1, skey->des.dk); return CRYPT_OK; } /** Initialize the 3LTC_DES-EDE block cipher @param key The symmetric key you wish to pass @param keylen The key length in bytes @param num_rounds The number of rounds desired (0 for default) @param skey The key in as scheduled by this function. @return CRYPT_OK if successful */ int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) { LTC_ARGCHK(key != NULL); LTC_ARGCHK(skey != NULL); if(num_rounds != 0 && num_rounds != 16) { return CRYPT_INVALID_ROUNDS; } if (keylen != 24) { return CRYPT_INVALID_KEYSIZE; } deskey(key, EN0, skey->des3.ek[0]); deskey(key+8, DE1, skey->des3.ek[1]); deskey(key+16, EN0, skey->des3.ek[2]); deskey(key, DE1, skey->des3.dk[2]); deskey(key+8, EN0, skey->des3.dk[1]); deskey(key+16, DE1, skey->des3.dk[0]); return CRYPT_OK; } /** Encrypts a block of text with LTC_DES @param pt The input plaintext (8 bytes) @param ct The output ciphertext (8 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ int des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) { ulong32 work[2]; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); LOAD32H(work[0], pt+0); LOAD32H(work[1], pt+4); desfunc(work, skey->des.ek); STORE32H(work[0],ct+0); STORE32H(work[1],ct+4); return CRYPT_OK; } /** Decrypts a block of text with LTC_DES @param ct The input ciphertext (8 bytes) @param pt The output plaintext (8 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) { ulong32 work[2]; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); LOAD32H(work[0], ct+0); LOAD32H(work[1], ct+4); desfunc(work, skey->des.dk); STORE32H(work[0],pt+0); STORE32H(work[1],pt+4); return CRYPT_OK; } /** Encrypts a block of text with 3LTC_DES-EDE @param pt The input plaintext (8 bytes) @param ct The output ciphertext (8 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) { ulong32 work[2]; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); LOAD32H(work[0], pt+0); LOAD32H(work[1], pt+4); desfunc(work, skey->des3.ek[0]); desfunc(work, skey->des3.ek[1]); desfunc(work, skey->des3.ek[2]); STORE32H(work[0],ct+0); STORE32H(work[1],ct+4); return CRYPT_OK; } /** Decrypts a block of text with 3LTC_DES-EDE @param ct The input ciphertext (8 bytes) @param pt The output plaintext (8 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) { ulong32 work[2]; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); LOAD32H(work[0], ct+0); LOAD32H(work[1], ct+4); desfunc(work, skey->des3.dk[0]); desfunc(work, skey->des3.dk[1]); desfunc(work, skey->des3.dk[2]); STORE32H(work[0],pt+0); STORE32H(work[1],pt+4); return CRYPT_OK; } /** Performs a self-test of the LTC_DES block cipher @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled */ int des_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else int err; static const struct des_test_case { int num, mode; /* mode 1 = encrypt */ unsigned char key[8], txt[8], out[8]; } cases[] = { { 1, 1, { 0x10, 0x31, 0x6E, 0x02, 0x8C, 0x8F, 0x3B, 0x4A }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x82, 0xDC, 0xBA, 0xFB, 0xDE, 0xAB, 0x66, 0x02 } }, { 2, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00 }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 3, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0xDD, 0x7F, 0x12, 0x1C, 0xA5, 0x01, 0x56, 0x19 }, { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 4, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x2E, 0x86, 0x53, 0x10, 0x4F, 0x38, 0x34, 0xEA }, { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 5, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x4B, 0xD3, 0x88, 0xFF, 0x6C, 0xD8, 0x1D, 0x4F }, { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 6, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x20, 0xB9, 0xE7, 0x67, 0xB2, 0xFB, 0x14, 0x56 }, { 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 7, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x55, 0x57, 0x93, 0x80, 0xD7, 0x71, 0x38, 0xEF }, { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 8, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x6C, 0xC5, 0xDE, 0xFA, 0xAF, 0x04, 0x51, 0x2F }, { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 9, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x0D, 0x9F, 0x27, 0x9B, 0xA5, 0xD8, 0x72, 0x60 }, { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, {10, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0xD9, 0x03, 0x1B, 0x02, 0x71, 0xBD, 0x5A, 0x0A }, { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 1, 0, { 0x10, 0x31, 0x6E, 0x02, 0x8C, 0x8F, 0x3B, 0x4A }, { 0x82, 0xDC, 0xBA, 0xFB, 0xDE, 0xAB, 0x66, 0x02 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 2, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00 } }, { 3, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0xDD, 0x7F, 0x12, 0x1C, 0xA5, 0x01, 0x56, 0x19 } }, { 4, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x2E, 0x86, 0x53, 0x10, 0x4F, 0x38, 0x34, 0xEA } }, { 5, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x4B, 0xD3, 0x88, 0xFF, 0x6C, 0xD8, 0x1D, 0x4F } }, { 6, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x20, 0xB9, 0xE7, 0x67, 0xB2, 0xFB, 0x14, 0x56 } }, { 7, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x55, 0x57, 0x93, 0x80, 0xD7, 0x71, 0x38, 0xEF } }, { 8, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x6C, 0xC5, 0xDE, 0xFA, 0xAF, 0x04, 0x51, 0x2F } }, { 9, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x0D, 0x9F, 0x27, 0x9B, 0xA5, 0xD8, 0x72, 0x60 } }, {10, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0xD9, 0x03, 0x1B, 0x02, 0x71, 0xBD, 0x5A, 0x0A } } /*** more test cases you could add if you are not convinced (the above test cases aren't really too good): key plaintext ciphertext 0000000000000000 0000000000000000 8CA64DE9C1B123A7 FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF 7359B2163E4EDC58 3000000000000000 1000000000000001 958E6E627A05557B 1111111111111111 1111111111111111 F40379AB9E0EC533 0123456789ABCDEF 1111111111111111 17668DFC7292532D 1111111111111111 0123456789ABCDEF 8A5AE1F81AB8F2DD 0000000000000000 0000000000000000 8CA64DE9C1B123A7 FEDCBA9876543210 0123456789ABCDEF ED39D950FA74BCC4 7CA110454A1A6E57 01A1D6D039776742 690F5B0D9A26939B 0131D9619DC1376E 5CD54CA83DEF57DA 7A389D10354BD271 07A1133E4A0B2686 0248D43806F67172 868EBB51CAB4599A 3849674C2602319E 51454B582DDF440A 7178876E01F19B2A 04B915BA43FEB5B6 42FD443059577FA2 AF37FB421F8C4095 0113B970FD34F2CE 059B5E0851CF143A 86A560F10EC6D85B 0170F175468FB5E6 0756D8E0774761D2 0CD3DA020021DC09 43297FAD38E373FE 762514B829BF486A EA676B2CB7DB2B7A 07A7137045DA2A16 3BDD119049372802 DFD64A815CAF1A0F 04689104C2FD3B2F 26955F6835AF609A 5C513C9C4886C088 37D06BB516CB7546 164D5E404F275232 0A2AEEAE3FF4AB77 1F08260D1AC2465E 6B056E18759F5CCA EF1BF03E5DFA575A 584023641ABA6176 004BD6EF09176062 88BF0DB6D70DEE56 025816164629B007 480D39006EE762F2 A1F9915541020B56 49793EBC79B3258F 437540C8698F3CFA 6FBF1CAFCFFD0556 4FB05E1515AB73A7 072D43A077075292 2F22E49BAB7CA1AC 49E95D6D4CA229BF 02FE55778117F12A 5A6B612CC26CCE4A 018310DC409B26D6 1D9D5C5018F728C2 5F4C038ED12B2E41 1C587F1C13924FEF 305532286D6F295A 63FAC0D034D9F793 0101010101010101 0123456789ABCDEF 617B3A0CE8F07100 1F1F1F1F0E0E0E0E 0123456789ABCDEF DB958605F8C8C606 E0FEE0FEF1FEF1FE 0123456789ABCDEF EDBFD1C66C29CCC7 0000000000000000 FFFFFFFFFFFFFFFF 355550B2150E2451 FFFFFFFFFFFFFFFF 0000000000000000 CAAAAF4DEAF1DBAE 0123456789ABCDEF 0000000000000000 D5D44FF720683D0D FEDCBA9876543210 FFFFFFFFFFFFFFFF 2A2BB008DF97C2F2 http://www.ecs.soton.ac.uk/~prw99r/ez438/vectors.txt ***/ }; int i, y; unsigned char tmp[8]; symmetric_key des; for(i=0; i < (int)(sizeof(cases)/sizeof(cases[0])); i++) { if ((err = des_setup(cases[i].key, 8, 0, &des)) != CRYPT_OK) { return err; } if (cases[i].mode != 0) { des_ecb_encrypt(cases[i].txt, tmp, &des); } else { des_ecb_decrypt(cases[i].txt, tmp, &des); } if (XMEMCMP(cases[i].out, tmp, sizeof(tmp)) != 0) { return CRYPT_FAIL_TESTVECTOR; } /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ for (y = 0; y < 8; y++) tmp[y] = 0; for (y = 0; y < 1000; y++) des_ecb_encrypt(tmp, tmp, &des); for (y = 0; y < 1000; y++) des_ecb_decrypt(tmp, tmp, &des); for (y = 0; y < 8; y++) if (tmp[y] != 0) return CRYPT_FAIL_TESTVECTOR; } return CRYPT_OK; #endif } int des3_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else unsigned char key[24], pt[8], ct[8], tmp[8]; symmetric_key skey; int x, err; if ((err = des_test()) != CRYPT_OK) { return err; } for (x = 0; x < 8; x++) { pt[x] = x; } for (x = 0; x < 24; x++) { key[x] = x; } if ((err = des3_setup(key, 24, 0, &skey)) != CRYPT_OK) { return err; } des3_ecb_encrypt(pt, ct, &skey); des3_ecb_decrypt(ct, tmp, &skey); if (XMEMCMP(pt, tmp, 8) != 0) { return CRYPT_FAIL_TESTVECTOR; } return CRYPT_OK; #endif } /** Terminate the context @param skey The scheduled key */ void des_done(symmetric_key *skey) { } /** Terminate the context @param skey The scheduled key */ void des3_done(symmetric_key *skey) { } /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. @return CRYPT_OK if the input key size is acceptable. */ int des_keysize(int *keysize) { LTC_ARGCHK(keysize != NULL); if(*keysize < 8) { return CRYPT_INVALID_KEYSIZE; } *keysize = 8; return CRYPT_OK; } /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. @return CRYPT_OK if the input key size is acceptable. */ int des3_keysize(int *keysize) { LTC_ARGCHK(keysize != NULL); if(*keysize < 24) { return CRYPT_INVALID_KEYSIZE; } *keysize = 24; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/des.c,v $ */ /* $Revision: 1.15 $ */ /* $Date: 2007/05/12 14:20:27 $ */ libtomcrypt-1.17/src/ciphers/rc2.c0000644000175100001440000002667010621351501015614 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /**********************************************************************\ * To commemorate the 1996 RSA Data Security Conference, the following * * code is released into the public domain by its author. Prost! * * * * This cipher uses 16-bit words and little-endian byte ordering. * * I wonder which processor it was optimized for? * * * * Thanks to CodeView, SoftIce, and D86 for helping bring this code to * * the public. * \**********************************************************************/ #include /** @file rc2.c Implementation of LTC_RC2 */ #ifdef LTC_RC2 const struct ltc_cipher_descriptor rc2_desc = { "rc2", 12, 8, 128, 8, 16, &rc2_setup, &rc2_ecb_encrypt, &rc2_ecb_decrypt, &rc2_test, &rc2_done, &rc2_keysize, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; /* 256-entry permutation table, probably derived somehow from pi */ static const unsigned char permute[256] = { 217,120,249,196, 25,221,181,237, 40,233,253,121, 74,160,216,157, 198,126, 55,131, 43,118, 83,142, 98, 76,100,136, 68,139,251,162, 23,154, 89,245,135,179, 79, 19, 97, 69,109,141, 9,129,125, 50, 189,143, 64,235,134,183,123, 11,240,149, 33, 34, 92,107, 78,130, 84,214,101,147,206, 96,178, 28,115, 86,192, 20,167,140,241,220, 18,117,202, 31, 59,190,228,209, 66, 61,212, 48,163, 60,182, 38, 111,191, 14,218, 70,105, 7, 87, 39,242, 29,155,188,148, 67, 3, 248, 17,199,246,144,239, 62,231, 6,195,213, 47,200,102, 30,215, 8,232,234,222,128, 82,238,247,132,170,114,172, 53, 77,106, 42, 150, 26,210,113, 90, 21, 73,116, 75,159,208, 94, 4, 24,164,236, 194,224, 65,110, 15, 81,203,204, 36,145,175, 80,161,244,112, 57, 153,124, 58,133, 35,184,180,122,252, 2, 54, 91, 37, 85,151, 49, 45, 93,250,152,227,138,146,174, 5,223, 41, 16,103,108,186,201, 211, 0,230,207,225,158,168, 44, 99, 22, 1, 63, 88,226,137,169, 13, 56, 52, 27,171, 51,255,176,187, 72, 12, 95,185,177,205, 46, 197,243,219, 71,229,165,156,119, 10,166, 32,104,254,127,193,173 }; /** Initialize the LTC_RC2 block cipher @param key The symmetric key you wish to pass @param keylen The key length in bytes @param num_rounds The number of rounds desired (0 for default) @param skey The key in as scheduled by this function. @return CRYPT_OK if successful */ int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) { unsigned *xkey = skey->rc2.xkey; unsigned char tmp[128]; unsigned T8, TM; int i, bits; LTC_ARGCHK(key != NULL); LTC_ARGCHK(skey != NULL); if (keylen < 8 || keylen > 128) { return CRYPT_INVALID_KEYSIZE; } if (num_rounds != 0 && num_rounds != 16) { return CRYPT_INVALID_ROUNDS; } for (i = 0; i < keylen; i++) { tmp[i] = key[i] & 255; } /* Phase 1: Expand input key to 128 bytes */ if (keylen < 128) { for (i = keylen; i < 128; i++) { tmp[i] = permute[(tmp[i - 1] + tmp[i - keylen]) & 255]; } } /* Phase 2 - reduce effective key size to "bits" */ bits = keylen<<3; T8 = (unsigned)(bits+7)>>3; TM = (255 >> (unsigned)(7 & -bits)); tmp[128 - T8] = permute[tmp[128 - T8] & TM]; for (i = 127 - T8; i >= 0; i--) { tmp[i] = permute[tmp[i + 1] ^ tmp[i + T8]]; } /* Phase 3 - copy to xkey in little-endian order */ for (i = 0; i < 64; i++) { xkey[i] = (unsigned)tmp[2*i] + ((unsigned)tmp[2*i+1] << 8); } #ifdef LTC_CLEAN_STACK zeromem(tmp, sizeof(tmp)); #endif return CRYPT_OK; } /**********************************************************************\ * Encrypt an 8-byte block of plaintext using the given key. * \**********************************************************************/ /** Encrypts a block of text with LTC_RC2 @param pt The input plaintext (8 bytes) @param ct The output ciphertext (8 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ #ifdef LTC_CLEAN_STACK static int _rc2_ecb_encrypt( const unsigned char *pt, unsigned char *ct, symmetric_key *skey) #else int rc2_ecb_encrypt( const unsigned char *pt, unsigned char *ct, symmetric_key *skey) #endif { unsigned *xkey; unsigned x76, x54, x32, x10, i; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); xkey = skey->rc2.xkey; x76 = ((unsigned)pt[7] << 8) + (unsigned)pt[6]; x54 = ((unsigned)pt[5] << 8) + (unsigned)pt[4]; x32 = ((unsigned)pt[3] << 8) + (unsigned)pt[2]; x10 = ((unsigned)pt[1] << 8) + (unsigned)pt[0]; for (i = 0; i < 16; i++) { x10 = (x10 + (x32 & ~x76) + (x54 & x76) + xkey[4*i+0]) & 0xFFFF; x10 = ((x10 << 1) | (x10 >> 15)); x32 = (x32 + (x54 & ~x10) + (x76 & x10) + xkey[4*i+1]) & 0xFFFF; x32 = ((x32 << 2) | (x32 >> 14)); x54 = (x54 + (x76 & ~x32) + (x10 & x32) + xkey[4*i+2]) & 0xFFFF; x54 = ((x54 << 3) | (x54 >> 13)); x76 = (x76 + (x10 & ~x54) + (x32 & x54) + xkey[4*i+3]) & 0xFFFF; x76 = ((x76 << 5) | (x76 >> 11)); if (i == 4 || i == 10) { x10 = (x10 + xkey[x76 & 63]) & 0xFFFF; x32 = (x32 + xkey[x10 & 63]) & 0xFFFF; x54 = (x54 + xkey[x32 & 63]) & 0xFFFF; x76 = (x76 + xkey[x54 & 63]) & 0xFFFF; } } ct[0] = (unsigned char)x10; ct[1] = (unsigned char)(x10 >> 8); ct[2] = (unsigned char)x32; ct[3] = (unsigned char)(x32 >> 8); ct[4] = (unsigned char)x54; ct[5] = (unsigned char)(x54 >> 8); ct[6] = (unsigned char)x76; ct[7] = (unsigned char)(x76 >> 8); return CRYPT_OK; } #ifdef LTC_CLEAN_STACK int rc2_ecb_encrypt( const unsigned char *pt, unsigned char *ct, symmetric_key *skey) { int err = _rc2_ecb_encrypt(pt, ct, skey); burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 5); return err; } #endif /**********************************************************************\ * Decrypt an 8-byte block of ciphertext using the given key. * \**********************************************************************/ /** Decrypts a block of text with LTC_RC2 @param ct The input ciphertext (8 bytes) @param pt The output plaintext (8 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ #ifdef LTC_CLEAN_STACK static int _rc2_ecb_decrypt( const unsigned char *ct, unsigned char *pt, symmetric_key *skey) #else int rc2_ecb_decrypt( const unsigned char *ct, unsigned char *pt, symmetric_key *skey) #endif { unsigned x76, x54, x32, x10; unsigned *xkey; int i; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); xkey = skey->rc2.xkey; x76 = ((unsigned)ct[7] << 8) + (unsigned)ct[6]; x54 = ((unsigned)ct[5] << 8) + (unsigned)ct[4]; x32 = ((unsigned)ct[3] << 8) + (unsigned)ct[2]; x10 = ((unsigned)ct[1] << 8) + (unsigned)ct[0]; for (i = 15; i >= 0; i--) { if (i == 4 || i == 10) { x76 = (x76 - xkey[x54 & 63]) & 0xFFFF; x54 = (x54 - xkey[x32 & 63]) & 0xFFFF; x32 = (x32 - xkey[x10 & 63]) & 0xFFFF; x10 = (x10 - xkey[x76 & 63]) & 0xFFFF; } x76 = ((x76 << 11) | (x76 >> 5)); x76 = (x76 - ((x10 & ~x54) + (x32 & x54) + xkey[4*i+3])) & 0xFFFF; x54 = ((x54 << 13) | (x54 >> 3)); x54 = (x54 - ((x76 & ~x32) + (x10 & x32) + xkey[4*i+2])) & 0xFFFF; x32 = ((x32 << 14) | (x32 >> 2)); x32 = (x32 - ((x54 & ~x10) + (x76 & x10) + xkey[4*i+1])) & 0xFFFF; x10 = ((x10 << 15) | (x10 >> 1)); x10 = (x10 - ((x32 & ~x76) + (x54 & x76) + xkey[4*i+0])) & 0xFFFF; } pt[0] = (unsigned char)x10; pt[1] = (unsigned char)(x10 >> 8); pt[2] = (unsigned char)x32; pt[3] = (unsigned char)(x32 >> 8); pt[4] = (unsigned char)x54; pt[5] = (unsigned char)(x54 >> 8); pt[6] = (unsigned char)x76; pt[7] = (unsigned char)(x76 >> 8); return CRYPT_OK; } #ifdef LTC_CLEAN_STACK int rc2_ecb_decrypt( const unsigned char *ct, unsigned char *pt, symmetric_key *skey) { int err = _rc2_ecb_decrypt(ct, pt, skey); burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 4 + sizeof(int)); return err; } #endif /** Performs a self-test of the LTC_RC2 block cipher @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled */ int rc2_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { int keylen; unsigned char key[16], pt[8], ct[8]; } tests[] = { { 8, { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, { 0x30, 0x64, 0x9e, 0xdf, 0x9b, 0xe7, 0xd2, 0xc2 } }, { 16, { 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f, 0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x22, 0x69, 0x55, 0x2a, 0xb0, 0xf8, 0x5c, 0xa6 } } }; int x, y, err; symmetric_key skey; unsigned char tmp[2][8]; for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { zeromem(tmp, sizeof(tmp)); if ((err = rc2_setup(tests[x].key, tests[x].keylen, 0, &skey)) != CRYPT_OK) { return err; } rc2_ecb_encrypt(tests[x].pt, tmp[0], &skey); rc2_ecb_decrypt(tmp[0], tmp[1], &skey); if (XMEMCMP(tmp[0], tests[x].ct, 8) != 0 || XMEMCMP(tmp[1], tests[x].pt, 8) != 0) { return CRYPT_FAIL_TESTVECTOR; } /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ for (y = 0; y < 8; y++) tmp[0][y] = 0; for (y = 0; y < 1000; y++) rc2_ecb_encrypt(tmp[0], tmp[0], &skey); for (y = 0; y < 1000; y++) rc2_ecb_decrypt(tmp[0], tmp[0], &skey); for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; } return CRYPT_OK; #endif } /** Terminate the context @param skey The scheduled key */ void rc2_done(symmetric_key *skey) { } /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. @return CRYPT_OK if the input key size is acceptable. */ int rc2_keysize(int *keysize) { LTC_ARGCHK(keysize != NULL); if (*keysize < 8) { return CRYPT_INVALID_KEYSIZE; } else if (*keysize > 128) { *keysize = 128; } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/rc2.c,v $ */ /* $Revision: 1.14 $ */ /* $Date: 2007/05/12 14:13:00 $ */ libtomcrypt-1.17/src/ciphers/rc5.c0000644000175100001440000002132410621351501015606 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file rc5.c LTC_RC5 code by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_RC5 const struct ltc_cipher_descriptor rc5_desc = { "rc5", 2, 8, 128, 8, 12, &rc5_setup, &rc5_ecb_encrypt, &rc5_ecb_decrypt, &rc5_test, &rc5_done, &rc5_keysize, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static const ulong32 stab[50] = { 0xb7e15163UL, 0x5618cb1cUL, 0xf45044d5UL, 0x9287be8eUL, 0x30bf3847UL, 0xcef6b200UL, 0x6d2e2bb9UL, 0x0b65a572UL, 0xa99d1f2bUL, 0x47d498e4UL, 0xe60c129dUL, 0x84438c56UL, 0x227b060fUL, 0xc0b27fc8UL, 0x5ee9f981UL, 0xfd21733aUL, 0x9b58ecf3UL, 0x399066acUL, 0xd7c7e065UL, 0x75ff5a1eUL, 0x1436d3d7UL, 0xb26e4d90UL, 0x50a5c749UL, 0xeedd4102UL, 0x8d14babbUL, 0x2b4c3474UL, 0xc983ae2dUL, 0x67bb27e6UL, 0x05f2a19fUL, 0xa42a1b58UL, 0x42619511UL, 0xe0990ecaUL, 0x7ed08883UL, 0x1d08023cUL, 0xbb3f7bf5UL, 0x5976f5aeUL, 0xf7ae6f67UL, 0x95e5e920UL, 0x341d62d9UL, 0xd254dc92UL, 0x708c564bUL, 0x0ec3d004UL, 0xacfb49bdUL, 0x4b32c376UL, 0xe96a3d2fUL, 0x87a1b6e8UL, 0x25d930a1UL, 0xc410aa5aUL, 0x62482413UL, 0x007f9dccUL }; /** Initialize the LTC_RC5 block cipher @param key The symmetric key you wish to pass @param keylen The key length in bytes @param num_rounds The number of rounds desired (0 for default) @param skey The key in as scheduled by this function. @return CRYPT_OK if successful */ #ifdef LTC_CLEAN_STACK static int _rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) #else int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) #endif { ulong32 L[64], *S, A, B, i, j, v, s, t, l; LTC_ARGCHK(skey != NULL); LTC_ARGCHK(key != NULL); /* test parameters */ if (num_rounds == 0) { num_rounds = rc5_desc.default_rounds; } if (num_rounds < 12 || num_rounds > 24) { return CRYPT_INVALID_ROUNDS; } /* key must be between 64 and 1024 bits */ if (keylen < 8 || keylen > 128) { return CRYPT_INVALID_KEYSIZE; } skey->rc5.rounds = num_rounds; S = skey->rc5.K; /* copy the key into the L array */ for (A = i = j = 0; i < (ulong32)keylen; ) { A = (A << 8) | ((ulong32)(key[i++] & 255)); if ((i & 3) == 0) { L[j++] = BSWAP(A); A = 0; } } if ((keylen & 3) != 0) { A <<= (ulong32)((8 * (4 - (keylen&3)))); L[j++] = BSWAP(A); } /* setup the S array */ t = (ulong32)(2 * (num_rounds + 1)); XMEMCPY(S, stab, t * sizeof(*S)); /* mix buffer */ s = 3 * MAX(t, j); l = j; for (A = B = i = j = v = 0; v < s; v++) { A = S[i] = ROLc(S[i] + A + B, 3); B = L[j] = ROL(L[j] + A + B, (A+B)); if (++i == t) { i = 0; } if (++j == l) { j = 0; } } return CRYPT_OK; } #ifdef LTC_CLEAN_STACK int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) { int x; x = _rc5_setup(key, keylen, num_rounds, skey); burn_stack(sizeof(ulong32) * 122 + sizeof(int)); return x; } #endif /** Encrypts a block of text with LTC_RC5 @param pt The input plaintext (8 bytes) @param ct The output ciphertext (8 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ #ifdef LTC_CLEAN_STACK static int _rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) #else int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) #endif { ulong32 A, B, *K; int r; LTC_ARGCHK(skey != NULL); LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LOAD32L(A, &pt[0]); LOAD32L(B, &pt[4]); A += skey->rc5.K[0]; B += skey->rc5.K[1]; K = skey->rc5.K + 2; if ((skey->rc5.rounds & 1) == 0) { for (r = 0; r < skey->rc5.rounds; r += 2) { A = ROL(A ^ B, B) + K[0]; B = ROL(B ^ A, A) + K[1]; A = ROL(A ^ B, B) + K[2]; B = ROL(B ^ A, A) + K[3]; K += 4; } } else { for (r = 0; r < skey->rc5.rounds; r++) { A = ROL(A ^ B, B) + K[0]; B = ROL(B ^ A, A) + K[1]; K += 2; } } STORE32L(A, &ct[0]); STORE32L(B, &ct[4]); return CRYPT_OK; } #ifdef LTC_CLEAN_STACK int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) { int err = _rc5_ecb_encrypt(pt, ct, skey); burn_stack(sizeof(ulong32) * 2 + sizeof(int)); return err; } #endif /** Decrypts a block of text with LTC_RC5 @param ct The input ciphertext (8 bytes) @param pt The output plaintext (8 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ #ifdef LTC_CLEAN_STACK static int _rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) #else int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) #endif { ulong32 A, B, *K; int r; LTC_ARGCHK(skey != NULL); LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LOAD32L(A, &ct[0]); LOAD32L(B, &ct[4]); K = skey->rc5.K + (skey->rc5.rounds << 1); if ((skey->rc5.rounds & 1) == 0) { K -= 2; for (r = skey->rc5.rounds - 1; r >= 0; r -= 2) { B = ROR(B - K[3], A) ^ A; A = ROR(A - K[2], B) ^ B; B = ROR(B - K[1], A) ^ A; A = ROR(A - K[0], B) ^ B; K -= 4; } } else { for (r = skey->rc5.rounds - 1; r >= 0; r--) { B = ROR(B - K[1], A) ^ A; A = ROR(A - K[0], B) ^ B; K -= 2; } } A -= skey->rc5.K[0]; B -= skey->rc5.K[1]; STORE32L(A, &pt[0]); STORE32L(B, &pt[4]); return CRYPT_OK; } #ifdef LTC_CLEAN_STACK int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) { int err = _rc5_ecb_decrypt(ct, pt, skey); burn_stack(sizeof(ulong32) * 2 + sizeof(int)); return err; } #endif /** Performs a self-test of the LTC_RC5 block cipher @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled */ int rc5_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { unsigned char key[16], pt[8], ct[8]; } tests[] = { { { 0x91, 0x5f, 0x46, 0x19, 0xbe, 0x41, 0xb2, 0x51, 0x63, 0x55, 0xa5, 0x01, 0x10, 0xa9, 0xce, 0x91 }, { 0x21, 0xa5, 0xdb, 0xee, 0x15, 0x4b, 0x8f, 0x6d }, { 0xf7, 0xc0, 0x13, 0xac, 0x5b, 0x2b, 0x89, 0x52 } }, { { 0x78, 0x33, 0x48, 0xe7, 0x5a, 0xeb, 0x0f, 0x2f, 0xd7, 0xb1, 0x69, 0xbb, 0x8d, 0xc1, 0x67, 0x87 }, { 0xF7, 0xC0, 0x13, 0xAC, 0x5B, 0x2B, 0x89, 0x52 }, { 0x2F, 0x42, 0xB3, 0xB7, 0x03, 0x69, 0xFC, 0x92 } }, { { 0xDC, 0x49, 0xdb, 0x13, 0x75, 0xa5, 0x58, 0x4f, 0x64, 0x85, 0xb4, 0x13, 0xb5, 0xf1, 0x2b, 0xaf }, { 0x2F, 0x42, 0xB3, 0xB7, 0x03, 0x69, 0xFC, 0x92 }, { 0x65, 0xc1, 0x78, 0xb2, 0x84, 0xd1, 0x97, 0xcc } } }; unsigned char tmp[2][8]; int x, y, err; symmetric_key key; for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { /* setup key */ if ((err = rc5_setup(tests[x].key, 16, 12, &key)) != CRYPT_OK) { return err; } /* encrypt and decrypt */ rc5_ecb_encrypt(tests[x].pt, tmp[0], &key); rc5_ecb_decrypt(tmp[0], tmp[1], &key); /* compare */ if (XMEMCMP(tmp[0], tests[x].ct, 8) != 0 || XMEMCMP(tmp[1], tests[x].pt, 8) != 0) { return CRYPT_FAIL_TESTVECTOR; } /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ for (y = 0; y < 8; y++) tmp[0][y] = 0; for (y = 0; y < 1000; y++) rc5_ecb_encrypt(tmp[0], tmp[0], &key); for (y = 0; y < 1000; y++) rc5_ecb_decrypt(tmp[0], tmp[0], &key); for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; } return CRYPT_OK; #endif } /** Terminate the context @param skey The scheduled key */ void rc5_done(symmetric_key *skey) { } /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. @return CRYPT_OK if the input key size is acceptable. */ int rc5_keysize(int *keysize) { LTC_ARGCHK(keysize != NULL); if (*keysize < 8) { return CRYPT_INVALID_KEYSIZE; } else if (*keysize > 128) { *keysize = 128; } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/rc5.c,v $ */ /* $Revision: 1.14 $ */ /* $Date: 2007/05/12 14:13:00 $ */ libtomcrypt-1.17/src/ciphers/rc6.c0000644000175100001440000002363310621351501015614 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file rc6.c LTC_RC6 code by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_RC6 const struct ltc_cipher_descriptor rc6_desc = { "rc6", 3, 8, 128, 16, 20, &rc6_setup, &rc6_ecb_encrypt, &rc6_ecb_decrypt, &rc6_test, &rc6_done, &rc6_keysize, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static const ulong32 stab[44] = { 0xb7e15163UL, 0x5618cb1cUL, 0xf45044d5UL, 0x9287be8eUL, 0x30bf3847UL, 0xcef6b200UL, 0x6d2e2bb9UL, 0x0b65a572UL, 0xa99d1f2bUL, 0x47d498e4UL, 0xe60c129dUL, 0x84438c56UL, 0x227b060fUL, 0xc0b27fc8UL, 0x5ee9f981UL, 0xfd21733aUL, 0x9b58ecf3UL, 0x399066acUL, 0xd7c7e065UL, 0x75ff5a1eUL, 0x1436d3d7UL, 0xb26e4d90UL, 0x50a5c749UL, 0xeedd4102UL, 0x8d14babbUL, 0x2b4c3474UL, 0xc983ae2dUL, 0x67bb27e6UL, 0x05f2a19fUL, 0xa42a1b58UL, 0x42619511UL, 0xe0990ecaUL, 0x7ed08883UL, 0x1d08023cUL, 0xbb3f7bf5UL, 0x5976f5aeUL, 0xf7ae6f67UL, 0x95e5e920UL, 0x341d62d9UL, 0xd254dc92UL, 0x708c564bUL, 0x0ec3d004UL, 0xacfb49bdUL, 0x4b32c376UL }; /** Initialize the LTC_RC6 block cipher @param key The symmetric key you wish to pass @param keylen The key length in bytes @param num_rounds The number of rounds desired (0 for default) @param skey The key in as scheduled by this function. @return CRYPT_OK if successful */ #ifdef LTC_CLEAN_STACK static int _rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) #else int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) #endif { ulong32 L[64], S[50], A, B, i, j, v, s, l; LTC_ARGCHK(key != NULL); LTC_ARGCHK(skey != NULL); /* test parameters */ if (num_rounds != 0 && num_rounds != 20) { return CRYPT_INVALID_ROUNDS; } /* key must be between 64 and 1024 bits */ if (keylen < 8 || keylen > 128) { return CRYPT_INVALID_KEYSIZE; } /* copy the key into the L array */ for (A = i = j = 0; i < (ulong32)keylen; ) { A = (A << 8) | ((ulong32)(key[i++] & 255)); if (!(i & 3)) { L[j++] = BSWAP(A); A = 0; } } /* handle odd sized keys */ if (keylen & 3) { A <<= (8 * (4 - (keylen&3))); L[j++] = BSWAP(A); } /* setup the S array */ XMEMCPY(S, stab, 44 * sizeof(stab[0])); /* mix buffer */ s = 3 * MAX(44, j); l = j; for (A = B = i = j = v = 0; v < s; v++) { A = S[i] = ROLc(S[i] + A + B, 3); B = L[j] = ROL(L[j] + A + B, (A+B)); if (++i == 44) { i = 0; } if (++j == l) { j = 0; } } /* copy to key */ for (i = 0; i < 44; i++) { skey->rc6.K[i] = S[i]; } return CRYPT_OK; } #ifdef LTC_CLEAN_STACK int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) { int x; x = _rc6_setup(key, keylen, num_rounds, skey); burn_stack(sizeof(ulong32) * 122); return x; } #endif /** Encrypts a block of text with LTC_RC6 @param pt The input plaintext (16 bytes) @param ct The output ciphertext (16 bytes) @param skey The key as scheduled */ #ifdef LTC_CLEAN_STACK static int _rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) #else int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) #endif { ulong32 a,b,c,d,t,u, *K; int r; LTC_ARGCHK(skey != NULL); LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LOAD32L(a,&pt[0]);LOAD32L(b,&pt[4]);LOAD32L(c,&pt[8]);LOAD32L(d,&pt[12]); b += skey->rc6.K[0]; d += skey->rc6.K[1]; #define RND(a,b,c,d) \ t = (b * (b + b + 1)); t = ROLc(t, 5); \ u = (d * (d + d + 1)); u = ROLc(u, 5); \ a = ROL(a^t,u) + K[0]; \ c = ROL(c^u,t) + K[1]; K += 2; K = skey->rc6.K + 2; for (r = 0; r < 20; r += 4) { RND(a,b,c,d); RND(b,c,d,a); RND(c,d,a,b); RND(d,a,b,c); } #undef RND a += skey->rc6.K[42]; c += skey->rc6.K[43]; STORE32L(a,&ct[0]);STORE32L(b,&ct[4]);STORE32L(c,&ct[8]);STORE32L(d,&ct[12]); return CRYPT_OK; } #ifdef LTC_CLEAN_STACK int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) { int err = _rc6_ecb_encrypt(pt, ct, skey); burn_stack(sizeof(ulong32) * 6 + sizeof(int)); return err; } #endif /** Decrypts a block of text with LTC_RC6 @param ct The input ciphertext (16 bytes) @param pt The output plaintext (16 bytes) @param skey The key as scheduled */ #ifdef LTC_CLEAN_STACK static int _rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) #else int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) #endif { ulong32 a,b,c,d,t,u, *K; int r; LTC_ARGCHK(skey != NULL); LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LOAD32L(a,&ct[0]);LOAD32L(b,&ct[4]);LOAD32L(c,&ct[8]);LOAD32L(d,&ct[12]); a -= skey->rc6.K[42]; c -= skey->rc6.K[43]; #define RND(a,b,c,d) \ t = (b * (b + b + 1)); t = ROLc(t, 5); \ u = (d * (d + d + 1)); u = ROLc(u, 5); \ c = ROR(c - K[1], t) ^ u; \ a = ROR(a - K[0], u) ^ t; K -= 2; K = skey->rc6.K + 40; for (r = 0; r < 20; r += 4) { RND(d,a,b,c); RND(c,d,a,b); RND(b,c,d,a); RND(a,b,c,d); } #undef RND b -= skey->rc6.K[0]; d -= skey->rc6.K[1]; STORE32L(a,&pt[0]);STORE32L(b,&pt[4]);STORE32L(c,&pt[8]);STORE32L(d,&pt[12]); return CRYPT_OK; } #ifdef LTC_CLEAN_STACK int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) { int err = _rc6_ecb_decrypt(ct, pt, skey); burn_stack(sizeof(ulong32) * 6 + sizeof(int)); return err; } #endif /** Performs a self-test of the LTC_RC6 block cipher @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled */ int rc6_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { int keylen; unsigned char key[32], pt[16], ct[16]; } tests[] = { { 16, { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79, 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 }, { 0x52, 0x4e, 0x19, 0x2f, 0x47, 0x15, 0xc6, 0x23, 0x1f, 0x51, 0xf6, 0x36, 0x7e, 0xa4, 0x3f, 0x18 } }, { 24, { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79, 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 }, { 0x68, 0x83, 0x29, 0xd0, 0x19, 0xe5, 0x05, 0x04, 0x1e, 0x52, 0xe9, 0x2a, 0xf9, 0x52, 0x91, 0xd4 } }, { 32, { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78, 0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0, 0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe }, { 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79, 0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 }, { 0xc8, 0x24, 0x18, 0x16, 0xf0, 0xd7, 0xe4, 0x89, 0x20, 0xad, 0x16, 0xa1, 0x67, 0x4e, 0x5d, 0x48 } } }; unsigned char tmp[2][16]; int x, y, err; symmetric_key key; for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { /* setup key */ if ((err = rc6_setup(tests[x].key, tests[x].keylen, 0, &key)) != CRYPT_OK) { return err; } /* encrypt and decrypt */ rc6_ecb_encrypt(tests[x].pt, tmp[0], &key); rc6_ecb_decrypt(tmp[0], tmp[1], &key); /* compare */ if (XMEMCMP(tmp[0], tests[x].ct, 16) || XMEMCMP(tmp[1], tests[x].pt, 16)) { #if 0 printf("\n\nFailed test %d\n", x); if (XMEMCMP(tmp[0], tests[x].ct, 16)) { printf("Ciphertext: "); for (y = 0; y < 16; y++) printf("%02x ", tmp[0][y]); printf("\nExpected : "); for (y = 0; y < 16; y++) printf("%02x ", tests[x].ct[y]); printf("\n"); } if (XMEMCMP(tmp[1], tests[x].pt, 16)) { printf("Plaintext: "); for (y = 0; y < 16; y++) printf("%02x ", tmp[0][y]); printf("\nExpected : "); for (y = 0; y < 16; y++) printf("%02x ", tests[x].pt[y]); printf("\n"); } #endif return CRYPT_FAIL_TESTVECTOR; } /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ for (y = 0; y < 16; y++) tmp[0][y] = 0; for (y = 0; y < 1000; y++) rc6_ecb_encrypt(tmp[0], tmp[0], &key); for (y = 0; y < 1000; y++) rc6_ecb_decrypt(tmp[0], tmp[0], &key); for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; } return CRYPT_OK; #endif } /** Terminate the context @param skey The scheduled key */ void rc6_done(symmetric_key *skey) { } /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. @return CRYPT_OK if the input key size is acceptable. */ int rc6_keysize(int *keysize) { LTC_ARGCHK(keysize != NULL); if (*keysize < 8) { return CRYPT_INVALID_KEYSIZE; } else if (*keysize > 128) { *keysize = 128; } return CRYPT_OK; } #endif /*LTC_RC6*/ /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/rc6.c,v $ */ /* $Revision: 1.14 $ */ /* $Date: 2007/05/12 14:13:00 $ */ libtomcrypt-1.17/src/ciphers/safer/0000755000175100001440000000000010621351501016047 5ustar tomuserslibtomcrypt-1.17/src/ciphers/safer/safer.c0000644000175100001440000003732110621351501017321 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /******************************************************************************* * * FILE: safer.c * * LTC_DESCRIPTION: block-cipher algorithm LTC_SAFER (Secure And Fast Encryption * Routine) in its four versions: LTC_SAFER K-64, LTC_SAFER K-128, * LTC_SAFER SK-64 and LTC_SAFER SK-128. * * AUTHOR: Richard De Moliner (demoliner@isi.ee.ethz.ch) * Signal and Information Processing Laboratory * Swiss Federal Institute of Technology * CH-8092 Zuerich, Switzerland * * DATE: September 9, 1995 * * CHANGE HISTORY: * *******************************************************************************/ #include #ifdef LTC_SAFER const struct ltc_cipher_descriptor safer_k64_desc = { "safer-k64", 8, 8, 8, 8, LTC_SAFER_K64_DEFAULT_NOF_ROUNDS, &safer_k64_setup, &safer_ecb_encrypt, &safer_ecb_decrypt, &safer_k64_test, &safer_done, &safer_64_keysize, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, safer_sk64_desc = { "safer-sk64", 9, 8, 8, 8, LTC_SAFER_SK64_DEFAULT_NOF_ROUNDS, &safer_sk64_setup, &safer_ecb_encrypt, &safer_ecb_decrypt, &safer_sk64_test, &safer_done, &safer_64_keysize, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, safer_k128_desc = { "safer-k128", 10, 16, 16, 8, LTC_SAFER_K128_DEFAULT_NOF_ROUNDS, &safer_k128_setup, &safer_ecb_encrypt, &safer_ecb_decrypt, &safer_sk128_test, &safer_done, &safer_128_keysize, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, safer_sk128_desc = { "safer-sk128", 11, 16, 16, 8, LTC_SAFER_SK128_DEFAULT_NOF_ROUNDS, &safer_sk128_setup, &safer_ecb_encrypt, &safer_ecb_decrypt, &safer_sk128_test, &safer_done, &safer_128_keysize, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; /******************* Constants ************************************************/ /* #define TAB_LEN 256 */ /******************* Assertions ***********************************************/ /******************* Macros ***************************************************/ #define ROL8(x, n) ((unsigned char)((unsigned int)(x) << (n)\ |(unsigned int)((x) & 0xFF) >> (8 - (n)))) #define EXP(x) safer_ebox[(x) & 0xFF] #define LOG(x) safer_lbox[(x) & 0xFF] #define PHT(x, y) { y += x; x += y; } #define IPHT(x, y) { x -= y; y -= x; } /******************* Types ****************************************************/ extern const unsigned char safer_ebox[], safer_lbox[]; #ifdef LTC_CLEAN_STACK static void _Safer_Expand_Userkey(const unsigned char *userkey_1, const unsigned char *userkey_2, unsigned int nof_rounds, int strengthened, safer_key_t key) #else static void Safer_Expand_Userkey(const unsigned char *userkey_1, const unsigned char *userkey_2, unsigned int nof_rounds, int strengthened, safer_key_t key) #endif { unsigned int i, j, k; unsigned char ka[LTC_SAFER_BLOCK_LEN + 1]; unsigned char kb[LTC_SAFER_BLOCK_LEN + 1]; if (LTC_SAFER_MAX_NOF_ROUNDS < nof_rounds) nof_rounds = LTC_SAFER_MAX_NOF_ROUNDS; *key++ = (unsigned char)nof_rounds; ka[LTC_SAFER_BLOCK_LEN] = (unsigned char)0; kb[LTC_SAFER_BLOCK_LEN] = (unsigned char)0; k = 0; for (j = 0; j < LTC_SAFER_BLOCK_LEN; j++) { ka[j] = ROL8(userkey_1[j], 5); ka[LTC_SAFER_BLOCK_LEN] ^= ka[j]; kb[j] = *key++ = userkey_2[j]; kb[LTC_SAFER_BLOCK_LEN] ^= kb[j]; } for (i = 1; i <= nof_rounds; i++) { for (j = 0; j < LTC_SAFER_BLOCK_LEN + 1; j++) { ka[j] = ROL8(ka[j], 6); kb[j] = ROL8(kb[j], 6); } if (strengthened) { k = 2 * i - 1; while (k >= (LTC_SAFER_BLOCK_LEN + 1)) { k -= LTC_SAFER_BLOCK_LEN + 1; } } for (j = 0; j < LTC_SAFER_BLOCK_LEN; j++) { if (strengthened) { *key++ = (ka[k] + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 1)&0xFF)]]) & 0xFF; if (++k == (LTC_SAFER_BLOCK_LEN + 1)) { k = 0; } } else { *key++ = (ka[j] + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 1)&0xFF)]]) & 0xFF; } } if (strengthened) { k = 2 * i; while (k >= (LTC_SAFER_BLOCK_LEN + 1)) { k -= LTC_SAFER_BLOCK_LEN + 1; } } for (j = 0; j < LTC_SAFER_BLOCK_LEN; j++) { if (strengthened) { *key++ = (kb[k] + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 10)&0xFF)]]) & 0xFF; if (++k == (LTC_SAFER_BLOCK_LEN + 1)) { k = 0; } } else { *key++ = (kb[j] + safer_ebox[(int)safer_ebox[(int)((18 * i + j + 10)&0xFF)]]) & 0xFF; } } } #ifdef LTC_CLEAN_STACK zeromem(ka, sizeof(ka)); zeromem(kb, sizeof(kb)); #endif } #ifdef LTC_CLEAN_STACK static void Safer_Expand_Userkey(const unsigned char *userkey_1, const unsigned char *userkey_2, unsigned int nof_rounds, int strengthened, safer_key_t key) { _Safer_Expand_Userkey(userkey_1, userkey_2, nof_rounds, strengthened, key); burn_stack(sizeof(unsigned char) * (2 * (LTC_SAFER_BLOCK_LEN + 1)) + sizeof(unsigned int)*2); } #endif int safer_k64_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) { LTC_ARGCHK(key != NULL); LTC_ARGCHK(skey != NULL); if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) { return CRYPT_INVALID_ROUNDS; } if (keylen != 8) { return CRYPT_INVALID_KEYSIZE; } Safer_Expand_Userkey(key, key, (unsigned int)(numrounds != 0 ?numrounds:LTC_SAFER_K64_DEFAULT_NOF_ROUNDS), 0, skey->safer.key); return CRYPT_OK; } int safer_sk64_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) { LTC_ARGCHK(key != NULL); LTC_ARGCHK(skey != NULL); if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) { return CRYPT_INVALID_ROUNDS; } if (keylen != 8) { return CRYPT_INVALID_KEYSIZE; } Safer_Expand_Userkey(key, key, (unsigned int)(numrounds != 0 ?numrounds:LTC_SAFER_SK64_DEFAULT_NOF_ROUNDS), 1, skey->safer.key); return CRYPT_OK; } int safer_k128_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) { LTC_ARGCHK(key != NULL); LTC_ARGCHK(skey != NULL); if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) { return CRYPT_INVALID_ROUNDS; } if (keylen != 16) { return CRYPT_INVALID_KEYSIZE; } Safer_Expand_Userkey(key, key+8, (unsigned int)(numrounds != 0 ?numrounds:LTC_SAFER_K128_DEFAULT_NOF_ROUNDS), 0, skey->safer.key); return CRYPT_OK; } int safer_sk128_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) { LTC_ARGCHK(key != NULL); LTC_ARGCHK(skey != NULL); if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) { return CRYPT_INVALID_ROUNDS; } if (keylen != 16) { return CRYPT_INVALID_KEYSIZE; } Safer_Expand_Userkey(key, key+8, (unsigned int)(numrounds != 0?numrounds:LTC_SAFER_SK128_DEFAULT_NOF_ROUNDS), 1, skey->safer.key); return CRYPT_OK; } #ifdef LTC_CLEAN_STACK static int _safer_ecb_encrypt(const unsigned char *block_in, unsigned char *block_out, symmetric_key *skey) #else int safer_ecb_encrypt(const unsigned char *block_in, unsigned char *block_out, symmetric_key *skey) #endif { unsigned char a, b, c, d, e, f, g, h, t; unsigned int round; unsigned char *key; LTC_ARGCHK(block_in != NULL); LTC_ARGCHK(block_out != NULL); LTC_ARGCHK(skey != NULL); key = skey->safer.key; a = block_in[0]; b = block_in[1]; c = block_in[2]; d = block_in[3]; e = block_in[4]; f = block_in[5]; g = block_in[6]; h = block_in[7]; if (LTC_SAFER_MAX_NOF_ROUNDS < (round = *key)) round = LTC_SAFER_MAX_NOF_ROUNDS; while(round-- > 0) { a ^= *++key; b += *++key; c += *++key; d ^= *++key; e ^= *++key; f += *++key; g += *++key; h ^= *++key; a = EXP(a) + *++key; b = LOG(b) ^ *++key; c = LOG(c) ^ *++key; d = EXP(d) + *++key; e = EXP(e) + *++key; f = LOG(f) ^ *++key; g = LOG(g) ^ *++key; h = EXP(h) + *++key; PHT(a, b); PHT(c, d); PHT(e, f); PHT(g, h); PHT(a, c); PHT(e, g); PHT(b, d); PHT(f, h); PHT(a, e); PHT(b, f); PHT(c, g); PHT(d, h); t = b; b = e; e = c; c = t; t = d; d = f; f = g; g = t; } a ^= *++key; b += *++key; c += *++key; d ^= *++key; e ^= *++key; f += *++key; g += *++key; h ^= *++key; block_out[0] = a & 0xFF; block_out[1] = b & 0xFF; block_out[2] = c & 0xFF; block_out[3] = d & 0xFF; block_out[4] = e & 0xFF; block_out[5] = f & 0xFF; block_out[6] = g & 0xFF; block_out[7] = h & 0xFF; return CRYPT_OK; } #ifdef LTC_CLEAN_STACK int safer_ecb_encrypt(const unsigned char *block_in, unsigned char *block_out, symmetric_key *skey) { int err = _safer_ecb_encrypt(block_in, block_out, skey); burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *)); return err; } #endif #ifdef LTC_CLEAN_STACK static int _safer_ecb_decrypt(const unsigned char *block_in, unsigned char *block_out, symmetric_key *skey) #else int safer_ecb_decrypt(const unsigned char *block_in, unsigned char *block_out, symmetric_key *skey) #endif { unsigned char a, b, c, d, e, f, g, h, t; unsigned int round; unsigned char *key; LTC_ARGCHK(block_in != NULL); LTC_ARGCHK(block_out != NULL); LTC_ARGCHK(skey != NULL); key = skey->safer.key; a = block_in[0]; b = block_in[1]; c = block_in[2]; d = block_in[3]; e = block_in[4]; f = block_in[5]; g = block_in[6]; h = block_in[7]; if (LTC_SAFER_MAX_NOF_ROUNDS < (round = *key)) round = LTC_SAFER_MAX_NOF_ROUNDS; key += LTC_SAFER_BLOCK_LEN * (1 + 2 * round); h ^= *key; g -= *--key; f -= *--key; e ^= *--key; d ^= *--key; c -= *--key; b -= *--key; a ^= *--key; while (round--) { t = e; e = b; b = c; c = t; t = f; f = d; d = g; g = t; IPHT(a, e); IPHT(b, f); IPHT(c, g); IPHT(d, h); IPHT(a, c); IPHT(e, g); IPHT(b, d); IPHT(f, h); IPHT(a, b); IPHT(c, d); IPHT(e, f); IPHT(g, h); h -= *--key; g ^= *--key; f ^= *--key; e -= *--key; d -= *--key; c ^= *--key; b ^= *--key; a -= *--key; h = LOG(h) ^ *--key; g = EXP(g) - *--key; f = EXP(f) - *--key; e = LOG(e) ^ *--key; d = LOG(d) ^ *--key; c = EXP(c) - *--key; b = EXP(b) - *--key; a = LOG(a) ^ *--key; } block_out[0] = a & 0xFF; block_out[1] = b & 0xFF; block_out[2] = c & 0xFF; block_out[3] = d & 0xFF; block_out[4] = e & 0xFF; block_out[5] = f & 0xFF; block_out[6] = g & 0xFF; block_out[7] = h & 0xFF; return CRYPT_OK; } #ifdef LTC_CLEAN_STACK int safer_ecb_decrypt(const unsigned char *block_in, unsigned char *block_out, symmetric_key *skey) { int err = _safer_ecb_decrypt(block_in, block_out, skey); burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *)); return err; } #endif int safer_64_keysize(int *keysize) { LTC_ARGCHK(keysize != NULL); if (*keysize < 8) { return CRYPT_INVALID_KEYSIZE; } else { *keysize = 8; return CRYPT_OK; } } int safer_128_keysize(int *keysize) { LTC_ARGCHK(keysize != NULL); if (*keysize < 16) { return CRYPT_INVALID_KEYSIZE; } else { *keysize = 16; return CRYPT_OK; } } int safer_k64_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const unsigned char k64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, k64_key[] = { 8, 7, 6, 5, 4, 3, 2, 1 }, k64_ct[] = { 200, 242, 156, 221, 135, 120, 62, 217 }; symmetric_key skey; unsigned char buf[2][8]; int err; /* test K64 */ if ((err = safer_k64_setup(k64_key, 8, 6, &skey)) != CRYPT_OK) { return err; } safer_ecb_encrypt(k64_pt, buf[0], &skey); safer_ecb_decrypt(buf[0], buf[1], &skey); if (XMEMCMP(buf[0], k64_ct, 8) != 0 || XMEMCMP(buf[1], k64_pt, 8) != 0) { return CRYPT_FAIL_TESTVECTOR; } return CRYPT_OK; #endif } int safer_sk64_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const unsigned char sk64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, sk64_key[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, sk64_ct[] = { 95, 206, 155, 162, 5, 132, 56, 199 }; symmetric_key skey; unsigned char buf[2][8]; int err, y; /* test SK64 */ if ((err = safer_sk64_setup(sk64_key, 8, 6, &skey)) != CRYPT_OK) { return err; } safer_ecb_encrypt(sk64_pt, buf[0], &skey); safer_ecb_decrypt(buf[0], buf[1], &skey); if (XMEMCMP(buf[0], sk64_ct, 8) != 0 || XMEMCMP(buf[1], sk64_pt, 8) != 0) { return CRYPT_FAIL_TESTVECTOR; } /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ for (y = 0; y < 8; y++) buf[0][y] = 0; for (y = 0; y < 1000; y++) safer_ecb_encrypt(buf[0], buf[0], &skey); for (y = 0; y < 1000; y++) safer_ecb_decrypt(buf[0], buf[0], &skey); for (y = 0; y < 8; y++) if (buf[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; return CRYPT_OK; #endif } /** Terminate the context @param skey The scheduled key */ void safer_done(symmetric_key *skey) { } int safer_sk128_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const unsigned char sk128_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 }, sk128_key[] = { 1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0 }, sk128_ct[] = { 255, 120, 17, 228, 179, 167, 46, 113 }; symmetric_key skey; unsigned char buf[2][8]; int err, y; /* test SK128 */ if ((err = safer_sk128_setup(sk128_key, 16, 0, &skey)) != CRYPT_OK) { return err; } safer_ecb_encrypt(sk128_pt, buf[0], &skey); safer_ecb_decrypt(buf[0], buf[1], &skey); if (XMEMCMP(buf[0], sk128_ct, 8) != 0 || XMEMCMP(buf[1], sk128_pt, 8) != 0) { return CRYPT_FAIL_TESTVECTOR; } /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ for (y = 0; y < 8; y++) buf[0][y] = 0; for (y = 0; y < 1000; y++) safer_ecb_encrypt(buf[0], buf[0], &skey); for (y = 0; y < 1000; y++) safer_ecb_decrypt(buf[0], buf[0], &skey); for (y = 0; y < 8; y++) if (buf[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/safer/safer.c,v $ */ /* $Revision: 1.15 $ */ /* $Date: 2007/05/12 14:20:27 $ */ libtomcrypt-1.17/src/ciphers/safer/safer_tab.c0000644000175100001440000000660410621351501020147 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file safer_tab.c Tables for LTC_SAFER block ciphers */ #include "tomcrypt.h" #if defined(LTC_SAFERP) || defined(LTC_SAFER) /* This is the box defined by ebox[x] = 45^x mod 257. * Its assumed that the value "256" corresponds to zero. */ const unsigned char safer_ebox[256] = { 1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207, 63, 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247, 64, 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177, 255, 167, 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, 241, 51, 239, 218, 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20, 129, 151, 113, 202, 95, 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160, 4, 180, 133, 74, 246, 19, 84, 182, 223, 12, 26, 142, 222, 224, 57, 252, 32, 155, 36, 78, 169, 152, 158, 171, 242, 96, 208, 108, 234, 250, 199, 217, 0, 212, 31, 110, 67, 188, 236, 83, 137, 254, 122, 93, 73, 201, 50, 194, 249, 154, 248, 109, 22, 219, 89, 150, 68, 233, 205, 230, 70, 66, 143, 10, 193, 204, 185, 101, 176, 210, 198, 172, 30, 65, 98, 41, 46, 14, 116, 80, 2, 90, 195, 37, 123, 138, 42, 91, 240, 6, 13, 71, 111, 112, 157, 126, 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104, 54, 117, 125, 228, 237, 128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175, 165, 229, 25, 97, 253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35, 33, 200, 5, 225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7, 58, 40 }; /* This is the inverse of ebox or the base 45 logarithm */ const unsigned char safer_lbox[256] = { 128, 0, 176, 9, 96, 239, 185, 253, 16, 18, 159, 228, 105, 186, 173, 248, 192, 56, 194, 101, 79, 6, 148, 252, 25, 222, 106, 27, 93, 78, 168, 130, 112, 237, 232, 236, 114, 179, 21, 195, 255, 171, 182, 71, 68, 1, 172, 37, 201, 250, 142, 65, 26, 33, 203, 211, 13, 110, 254, 38, 88, 218, 50, 15, 32, 169, 157, 132, 152, 5, 156, 187, 34, 140, 99, 231, 197, 225, 115, 198, 175, 36, 91, 135, 102, 39, 247, 87, 244, 150, 177, 183, 92, 139, 213, 84, 121, 223, 170, 246, 62, 163, 241, 17, 202, 245, 209, 23, 123, 147, 131, 188, 189, 82, 30, 235, 174, 204, 214, 53, 8, 200, 138, 180, 226, 205, 191, 217, 208, 80, 89, 63, 77, 98, 52, 10, 72, 136, 181, 86, 76, 46, 107, 158, 210, 61, 60, 3, 19, 251, 151, 81, 117, 74, 145, 113, 35, 190, 118, 42, 95, 249, 212, 85, 11, 220, 55, 49, 22, 116, 215, 119, 167, 230, 7, 219, 164, 47, 70, 243, 97, 69, 103, 227, 12, 162, 59, 28, 133, 24, 4, 29, 41, 160, 143, 178, 90, 216, 166, 126, 238, 141, 83, 75, 161, 154, 193, 14, 122, 73, 165, 44, 129, 196, 199, 54, 43, 127, 67, 149, 51, 242, 108, 104, 109, 240, 2, 40, 206, 221, 155, 234, 94, 153, 124, 20, 134, 207, 229, 66, 184, 64, 120, 45, 58, 233, 100, 31, 146, 144, 125, 57, 111, 224, 137, 48 }; #endif /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/safer/safer_tab.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2007/05/12 14:20:27 $ */ libtomcrypt-1.17/src/ciphers/safer/saferp.c0000644000175100001440000005175710621351501017512 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file saferp.c LTC_SAFER+ Implementation by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_SAFERP const struct ltc_cipher_descriptor saferp_desc = { "safer+", 4, 16, 32, 16, 8, &saferp_setup, &saferp_ecb_encrypt, &saferp_ecb_decrypt, &saferp_test, &saferp_done, &saferp_keysize, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; /* ROUND(b,i) * * This is one forward key application. Note the basic form is * key addition, substitution, key addition. The safer_ebox and safer_lbox * are the exponentiation box and logarithm boxes respectively. * The value of 'i' is the current round number which allows this * function to be unrolled massively. Most of LTC_SAFER+'s speed * comes from not having to compute indirect accesses into the * array of 16 bytes b[0..15] which is the block of data */ extern const unsigned char safer_ebox[], safer_lbox[]; #define ROUND(b, i) \ b[0] = (safer_ebox[(b[0] ^ skey->saferp.K[i][0]) & 255] + skey->saferp.K[i+1][0]) & 255; \ b[1] = safer_lbox[(b[1] + skey->saferp.K[i][1]) & 255] ^ skey->saferp.K[i+1][1]; \ b[2] = safer_lbox[(b[2] + skey->saferp.K[i][2]) & 255] ^ skey->saferp.K[i+1][2]; \ b[3] = (safer_ebox[(b[3] ^ skey->saferp.K[i][3]) & 255] + skey->saferp.K[i+1][3]) & 255; \ b[4] = (safer_ebox[(b[4] ^ skey->saferp.K[i][4]) & 255] + skey->saferp.K[i+1][4]) & 255; \ b[5] = safer_lbox[(b[5] + skey->saferp.K[i][5]) & 255] ^ skey->saferp.K[i+1][5]; \ b[6] = safer_lbox[(b[6] + skey->saferp.K[i][6]) & 255] ^ skey->saferp.K[i+1][6]; \ b[7] = (safer_ebox[(b[7] ^ skey->saferp.K[i][7]) & 255] + skey->saferp.K[i+1][7]) & 255; \ b[8] = (safer_ebox[(b[8] ^ skey->saferp.K[i][8]) & 255] + skey->saferp.K[i+1][8]) & 255; \ b[9] = safer_lbox[(b[9] + skey->saferp.K[i][9]) & 255] ^ skey->saferp.K[i+1][9]; \ b[10] = safer_lbox[(b[10] + skey->saferp.K[i][10]) & 255] ^ skey->saferp.K[i+1][10]; \ b[11] = (safer_ebox[(b[11] ^ skey->saferp.K[i][11]) & 255] + skey->saferp.K[i+1][11]) & 255; \ b[12] = (safer_ebox[(b[12] ^ skey->saferp.K[i][12]) & 255] + skey->saferp.K[i+1][12]) & 255; \ b[13] = safer_lbox[(b[13] + skey->saferp.K[i][13]) & 255] ^ skey->saferp.K[i+1][13]; \ b[14] = safer_lbox[(b[14] + skey->saferp.K[i][14]) & 255] ^ skey->saferp.K[i+1][14]; \ b[15] = (safer_ebox[(b[15] ^ skey->saferp.K[i][15]) & 255] + skey->saferp.K[i+1][15]) & 255; /* This is one inverse key application */ #define iROUND(b, i) \ b[0] = safer_lbox[(b[0] - skey->saferp.K[i+1][0]) & 255] ^ skey->saferp.K[i][0]; \ b[1] = (safer_ebox[(b[1] ^ skey->saferp.K[i+1][1]) & 255] - skey->saferp.K[i][1]) & 255; \ b[2] = (safer_ebox[(b[2] ^ skey->saferp.K[i+1][2]) & 255] - skey->saferp.K[i][2]) & 255; \ b[3] = safer_lbox[(b[3] - skey->saferp.K[i+1][3]) & 255] ^ skey->saferp.K[i][3]; \ b[4] = safer_lbox[(b[4] - skey->saferp.K[i+1][4]) & 255] ^ skey->saferp.K[i][4]; \ b[5] = (safer_ebox[(b[5] ^ skey->saferp.K[i+1][5]) & 255] - skey->saferp.K[i][5]) & 255; \ b[6] = (safer_ebox[(b[6] ^ skey->saferp.K[i+1][6]) & 255] - skey->saferp.K[i][6]) & 255; \ b[7] = safer_lbox[(b[7] - skey->saferp.K[i+1][7]) & 255] ^ skey->saferp.K[i][7]; \ b[8] = safer_lbox[(b[8] - skey->saferp.K[i+1][8]) & 255] ^ skey->saferp.K[i][8]; \ b[9] = (safer_ebox[(b[9] ^ skey->saferp.K[i+1][9]) & 255] - skey->saferp.K[i][9]) & 255; \ b[10] = (safer_ebox[(b[10] ^ skey->saferp.K[i+1][10]) & 255] - skey->saferp.K[i][10]) & 255; \ b[11] = safer_lbox[(b[11] - skey->saferp.K[i+1][11]) & 255] ^ skey->saferp.K[i][11]; \ b[12] = safer_lbox[(b[12] - skey->saferp.K[i+1][12]) & 255] ^ skey->saferp.K[i][12]; \ b[13] = (safer_ebox[(b[13] ^ skey->saferp.K[i+1][13]) & 255] - skey->saferp.K[i][13]) & 255; \ b[14] = (safer_ebox[(b[14] ^ skey->saferp.K[i+1][14]) & 255] - skey->saferp.K[i][14]) & 255; \ b[15] = safer_lbox[(b[15] - skey->saferp.K[i+1][15]) & 255] ^ skey->saferp.K[i][15]; /* This is a forward single layer PHT transform. */ #define PHT(b) \ b[0] = (b[0] + (b[1] = (b[0] + b[1]) & 255)) & 255; \ b[2] = (b[2] + (b[3] = (b[3] + b[2]) & 255)) & 255; \ b[4] = (b[4] + (b[5] = (b[5] + b[4]) & 255)) & 255; \ b[6] = (b[6] + (b[7] = (b[7] + b[6]) & 255)) & 255; \ b[8] = (b[8] + (b[9] = (b[9] + b[8]) & 255)) & 255; \ b[10] = (b[10] + (b[11] = (b[11] + b[10]) & 255)) & 255; \ b[12] = (b[12] + (b[13] = (b[13] + b[12]) & 255)) & 255; \ b[14] = (b[14] + (b[15] = (b[15] + b[14]) & 255)) & 255; /* This is an inverse single layer PHT transform */ #define iPHT(b) \ b[15] = (b[15] - (b[14] = (b[14] - b[15]) & 255)) & 255; \ b[13] = (b[13] - (b[12] = (b[12] - b[13]) & 255)) & 255; \ b[11] = (b[11] - (b[10] = (b[10] - b[11]) & 255)) & 255; \ b[9] = (b[9] - (b[8] = (b[8] - b[9]) & 255)) & 255; \ b[7] = (b[7] - (b[6] = (b[6] - b[7]) & 255)) & 255; \ b[5] = (b[5] - (b[4] = (b[4] - b[5]) & 255)) & 255; \ b[3] = (b[3] - (b[2] = (b[2] - b[3]) & 255)) & 255; \ b[1] = (b[1] - (b[0] = (b[0] - b[1]) & 255)) & 255; \ /* This is the "Armenian" Shuffle. It takes the input from b and stores it in b2 */ #define SHUF(b, b2) \ b2[0] = b[8]; b2[1] = b[11]; b2[2] = b[12]; b2[3] = b[15]; \ b2[4] = b[2]; b2[5] = b[1]; b2[6] = b[6]; b2[7] = b[5]; \ b2[8] = b[10]; b2[9] = b[9]; b2[10] = b[14]; b2[11] = b[13]; \ b2[12] = b[0]; b2[13] = b[7]; b2[14] = b[4]; b2[15] = b[3]; /* This is the inverse shuffle. It takes from b and gives to b2 */ #define iSHUF(b, b2) \ b2[0] = b[12]; b2[1] = b[5]; b2[2] = b[4]; b2[3] = b[15]; \ b2[4] = b[14]; b2[5] = b[7]; b2[6] = b[6]; b2[7] = b[13]; \ b2[8] = b[0]; b2[9] = b[9]; b2[10] = b[8]; b2[11] = b[1]; \ b2[12] = b[2]; b2[13] = b[11]; b2[14] = b[10]; b2[15] = b[3]; /* The complete forward Linear Transform layer. * Note that alternating usage of b and b2. * Each round of LT starts in 'b' and ends in 'b2'. */ #define LT(b, b2) \ PHT(b); SHUF(b, b2); \ PHT(b2); SHUF(b2, b); \ PHT(b); SHUF(b, b2); \ PHT(b2); /* This is the inverse linear transform layer. */ #define iLT(b, b2) \ iPHT(b); \ iSHUF(b, b2); iPHT(b2); \ iSHUF(b2, b); iPHT(b); \ iSHUF(b, b2); iPHT(b2); #ifdef LTC_SMALL_CODE static void _round(unsigned char *b, int i, symmetric_key *skey) { ROUND(b, i); } static void _iround(unsigned char *b, int i, symmetric_key *skey) { iROUND(b, i); } static void _lt(unsigned char *b, unsigned char *b2) { LT(b, b2); } static void _ilt(unsigned char *b, unsigned char *b2) { iLT(b, b2); } #undef ROUND #define ROUND(b, i) _round(b, i, skey) #undef iROUND #define iROUND(b, i) _iround(b, i, skey) #undef LT #define LT(b, b2) _lt(b, b2) #undef iLT #define iLT(b, b2) _ilt(b, b2) #endif /* These are the 33, 128-bit bias words for the key schedule */ static const unsigned char safer_bias[33][16] = { { 70, 151, 177, 186, 163, 183, 16, 10, 197, 55, 179, 201, 90, 40, 172, 100}, { 236, 171, 170, 198, 103, 149, 88, 13, 248, 154, 246, 110, 102, 220, 5, 61}, { 138, 195, 216, 137, 106, 233, 54, 73, 67, 191, 235, 212, 150, 155, 104, 160}, { 93, 87, 146, 31, 213, 113, 92, 187, 34, 193, 190, 123, 188, 153, 99, 148}, { 42, 97, 184, 52, 50, 25, 253, 251, 23, 64, 230, 81, 29, 65, 68, 143}, { 221, 4, 128, 222, 231, 49, 214, 127, 1, 162, 247, 57, 218, 111, 35, 202}, { 58, 208, 28, 209, 48, 62, 18, 161, 205, 15, 224, 168, 175, 130, 89, 44}, { 125, 173, 178, 239, 194, 135, 206, 117, 6, 19, 2, 144, 79, 46, 114, 51}, { 192, 141, 207, 169, 129, 226, 196, 39, 47, 108, 122, 159, 82, 225, 21, 56}, { 252, 32, 66, 199, 8, 228, 9, 85, 94, 140, 20, 118, 96, 255, 223, 215}, { 250, 11, 33, 0, 26, 249, 166, 185, 232, 158, 98, 76, 217, 145, 80, 210}, { 24, 180, 7, 132, 234, 91, 164, 200, 14, 203, 72, 105, 75, 78, 156, 53}, { 69, 77, 84, 229, 37, 60, 12, 74, 139, 63, 204, 167, 219, 107, 174, 244}, { 45, 243, 124, 109, 157, 181, 38, 116, 242, 147, 83, 176, 240, 17, 237, 131}, { 182, 3, 22, 115, 59, 30, 142, 112, 189, 134, 27, 71, 126, 36, 86, 241}, { 136, 70, 151, 177, 186, 163, 183, 16, 10, 197, 55, 179, 201, 90, 40, 172}, { 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, 241, 51, 239}, { 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20, 129, 151, 113, 202}, { 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160, 4, 180, 133, 74, 246}, { 84, 182, 223, 12, 26, 142, 222, 224, 57, 252, 32, 155, 36, 78, 169, 152}, { 171, 242, 96, 208, 108, 234, 250, 199, 217, 0, 212, 31, 110, 67, 188, 236}, { 137, 254, 122, 93, 73, 201, 50, 194, 249, 154, 248, 109, 22, 219, 89, 150}, { 233, 205, 230, 70, 66, 143, 10, 193, 204, 185, 101, 176, 210, 198, 172, 30}, { 98, 41, 46, 14, 116, 80, 2, 90, 195, 37, 123, 138, 42, 91, 240, 6}, { 71, 111, 112, 157, 126, 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104}, { 117, 125, 228, 237, 128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175}, { 229, 25, 97, 253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35}, { 200, 5, 225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7}, { 40, 1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207}, { 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247}, { 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177, 255}, { 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, 241, 51}}; /** Initialize the LTC_SAFER+ block cipher @param key The symmetric key you wish to pass @param keylen The key length in bytes @param num_rounds The number of rounds desired (0 for default) @param skey The key in as scheduled by this function. @return CRYPT_OK if successful */ int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) { unsigned x, y, z; unsigned char t[33]; static const int rounds[3] = { 8, 12, 16 }; LTC_ARGCHK(key != NULL); LTC_ARGCHK(skey != NULL); /* check arguments */ if (keylen != 16 && keylen != 24 && keylen != 32) { return CRYPT_INVALID_KEYSIZE; } /* Is the number of rounds valid? Either use zero for default or * 8,12,16 rounds for 16,24,32 byte keys */ if (num_rounds != 0 && num_rounds != rounds[(keylen/8)-2]) { return CRYPT_INVALID_ROUNDS; } /* 128 bit key version */ if (keylen == 16) { /* copy key into t */ for (x = y = 0; x < 16; x++) { t[x] = key[x]; y ^= key[x]; } t[16] = y; /* make round keys */ for (x = 0; x < 16; x++) { skey->saferp.K[0][x] = t[x]; } /* make the 16 other keys as a transformation of the first key */ for (x = 1; x < 17; x++) { /* rotate 3 bits each */ for (y = 0; y < 17; y++) { t[y] = ((t[y]<<3)|(t[y]>>5)) & 255; } /* select and add */ z = x; for (y = 0; y < 16; y++) { skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255; if (++z == 17) { z = 0; } } } skey->saferp.rounds = 8; } else if (keylen == 24) { /* copy key into t */ for (x = y = 0; x < 24; x++) { t[x] = key[x]; y ^= key[x]; } t[24] = y; /* make round keys */ for (x = 0; x < 16; x++) { skey->saferp.K[0][x] = t[x]; } for (x = 1; x < 25; x++) { /* rotate 3 bits each */ for (y = 0; y < 25; y++) { t[y] = ((t[y]<<3)|(t[y]>>5)) & 255; } /* select and add */ z = x; for (y = 0; y < 16; y++) { skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255; if (++z == 25) { z = 0; } } } skey->saferp.rounds = 12; } else { /* copy key into t */ for (x = y = 0; x < 32; x++) { t[x] = key[x]; y ^= key[x]; } t[32] = y; /* make round keys */ for (x = 0; x < 16; x++) { skey->saferp.K[0][x] = t[x]; } for (x = 1; x < 33; x++) { /* rotate 3 bits each */ for (y = 0; y < 33; y++) { t[y] = ((t[y]<<3)|(t[y]>>5)) & 255; } /* select and add */ z = x; for (y = 0; y < 16; y++) { skey->saferp.K[x][y] = (t[z] + safer_bias[x-1][y]) & 255; if (++z == 33) { z = 0; } } } skey->saferp.rounds = 16; } #ifdef LTC_CLEAN_STACK zeromem(t, sizeof(t)); #endif return CRYPT_OK; } /** Encrypts a block of text with LTC_SAFER+ @param pt The input plaintext (16 bytes) @param ct The output ciphertext (16 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ int saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) { unsigned char b[16]; int x; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); /* do eight rounds */ for (x = 0; x < 16; x++) { b[x] = pt[x]; } ROUND(b, 0); LT(b, ct); ROUND(ct, 2); LT(ct, b); ROUND(b, 4); LT(b, ct); ROUND(ct, 6); LT(ct, b); ROUND(b, 8); LT(b, ct); ROUND(ct, 10); LT(ct, b); ROUND(b, 12); LT(b, ct); ROUND(ct, 14); LT(ct, b); /* 192-bit key? */ if (skey->saferp.rounds > 8) { ROUND(b, 16); LT(b, ct); ROUND(ct, 18); LT(ct, b); ROUND(b, 20); LT(b, ct); ROUND(ct, 22); LT(ct, b); } /* 256-bit key? */ if (skey->saferp.rounds > 12) { ROUND(b, 24); LT(b, ct); ROUND(ct, 26); LT(ct, b); ROUND(b, 28); LT(b, ct); ROUND(ct, 30); LT(ct, b); } ct[0] = b[0] ^ skey->saferp.K[skey->saferp.rounds*2][0]; ct[1] = (b[1] + skey->saferp.K[skey->saferp.rounds*2][1]) & 255; ct[2] = (b[2] + skey->saferp.K[skey->saferp.rounds*2][2]) & 255; ct[3] = b[3] ^ skey->saferp.K[skey->saferp.rounds*2][3]; ct[4] = b[4] ^ skey->saferp.K[skey->saferp.rounds*2][4]; ct[5] = (b[5] + skey->saferp.K[skey->saferp.rounds*2][5]) & 255; ct[6] = (b[6] + skey->saferp.K[skey->saferp.rounds*2][6]) & 255; ct[7] = b[7] ^ skey->saferp.K[skey->saferp.rounds*2][7]; ct[8] = b[8] ^ skey->saferp.K[skey->saferp.rounds*2][8]; ct[9] = (b[9] + skey->saferp.K[skey->saferp.rounds*2][9]) & 255; ct[10] = (b[10] + skey->saferp.K[skey->saferp.rounds*2][10]) & 255; ct[11] = b[11] ^ skey->saferp.K[skey->saferp.rounds*2][11]; ct[12] = b[12] ^ skey->saferp.K[skey->saferp.rounds*2][12]; ct[13] = (b[13] + skey->saferp.K[skey->saferp.rounds*2][13]) & 255; ct[14] = (b[14] + skey->saferp.K[skey->saferp.rounds*2][14]) & 255; ct[15] = b[15] ^ skey->saferp.K[skey->saferp.rounds*2][15]; #ifdef LTC_CLEAN_STACK zeromem(b, sizeof(b)); #endif return CRYPT_OK; } /** Decrypts a block of text with LTC_SAFER+ @param ct The input ciphertext (16 bytes) @param pt The output plaintext (16 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ int saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) { unsigned char b[16]; int x; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); /* do eight rounds */ b[0] = ct[0] ^ skey->saferp.K[skey->saferp.rounds*2][0]; b[1] = (ct[1] - skey->saferp.K[skey->saferp.rounds*2][1]) & 255; b[2] = (ct[2] - skey->saferp.K[skey->saferp.rounds*2][2]) & 255; b[3] = ct[3] ^ skey->saferp.K[skey->saferp.rounds*2][3]; b[4] = ct[4] ^ skey->saferp.K[skey->saferp.rounds*2][4]; b[5] = (ct[5] - skey->saferp.K[skey->saferp.rounds*2][5]) & 255; b[6] = (ct[6] - skey->saferp.K[skey->saferp.rounds*2][6]) & 255; b[7] = ct[7] ^ skey->saferp.K[skey->saferp.rounds*2][7]; b[8] = ct[8] ^ skey->saferp.K[skey->saferp.rounds*2][8]; b[9] = (ct[9] - skey->saferp.K[skey->saferp.rounds*2][9]) & 255; b[10] = (ct[10] - skey->saferp.K[skey->saferp.rounds*2][10]) & 255; b[11] = ct[11] ^ skey->saferp.K[skey->saferp.rounds*2][11]; b[12] = ct[12] ^ skey->saferp.K[skey->saferp.rounds*2][12]; b[13] = (ct[13] - skey->saferp.K[skey->saferp.rounds*2][13]) & 255; b[14] = (ct[14] - skey->saferp.K[skey->saferp.rounds*2][14]) & 255; b[15] = ct[15] ^ skey->saferp.K[skey->saferp.rounds*2][15]; /* 256-bit key? */ if (skey->saferp.rounds > 12) { iLT(b, pt); iROUND(pt, 30); iLT(pt, b); iROUND(b, 28); iLT(b, pt); iROUND(pt, 26); iLT(pt, b); iROUND(b, 24); } /* 192-bit key? */ if (skey->saferp.rounds > 8) { iLT(b, pt); iROUND(pt, 22); iLT(pt, b); iROUND(b, 20); iLT(b, pt); iROUND(pt, 18); iLT(pt, b); iROUND(b, 16); } iLT(b, pt); iROUND(pt, 14); iLT(pt, b); iROUND(b, 12); iLT(b, pt); iROUND(pt,10); iLT(pt, b); iROUND(b, 8); iLT(b, pt); iROUND(pt,6); iLT(pt, b); iROUND(b, 4); iLT(b, pt); iROUND(pt,2); iLT(pt, b); iROUND(b, 0); for (x = 0; x < 16; x++) { pt[x] = b[x]; } #ifdef LTC_CLEAN_STACK zeromem(b, sizeof(b)); #endif return CRYPT_OK; } /** Performs a self-test of the LTC_SAFER+ block cipher @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled */ int saferp_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { int keylen; unsigned char key[32], pt[16], ct[16]; } tests[] = { { 16, { 41, 35, 190, 132, 225, 108, 214, 174, 82, 144, 73, 241, 241, 187, 233, 235 }, { 179, 166, 219, 60, 135, 12, 62, 153, 36, 94, 13, 28, 6, 183, 71, 222 }, { 224, 31, 182, 10, 12, 255, 84, 70, 127, 13, 89, 249, 9, 57, 165, 220 } }, { 24, { 72, 211, 143, 117, 230, 217, 29, 42, 229, 192, 247, 43, 120, 129, 135, 68, 14, 95, 80, 0, 212, 97, 141, 190 }, { 123, 5, 21, 7, 59, 51, 130, 31, 24, 112, 146, 218, 100, 84, 206, 177 }, { 92, 136, 4, 63, 57, 95, 100, 0, 150, 130, 130, 16, 193, 111, 219, 133 } }, { 32, { 243, 168, 141, 254, 190, 242, 235, 113, 255, 160, 208, 59, 117, 6, 140, 126, 135, 120, 115, 77, 208, 190, 130, 190, 219, 194, 70, 65, 43, 140, 250, 48 }, { 127, 112, 240, 167, 84, 134, 50, 149, 170, 91, 104, 19, 11, 230, 252, 245 }, { 88, 11, 25, 36, 172, 229, 202, 213, 170, 65, 105, 153, 220, 104, 153, 138 } } }; unsigned char tmp[2][16]; symmetric_key skey; int err, i, y; for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { if ((err = saferp_setup(tests[i].key, tests[i].keylen, 0, &skey)) != CRYPT_OK) { return err; } saferp_ecb_encrypt(tests[i].pt, tmp[0], &skey); saferp_ecb_decrypt(tmp[0], tmp[1], &skey); /* compare */ if (XMEMCMP(tmp[0], tests[i].ct, 16) || XMEMCMP(tmp[1], tests[i].pt, 16)) { return CRYPT_FAIL_TESTVECTOR; } /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ for (y = 0; y < 16; y++) tmp[0][y] = 0; for (y = 0; y < 1000; y++) saferp_ecb_encrypt(tmp[0], tmp[0], &skey); for (y = 0; y < 1000; y++) saferp_ecb_decrypt(tmp[0], tmp[0], &skey); for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; } return CRYPT_OK; #endif } /** Terminate the context @param skey The scheduled key */ void saferp_done(symmetric_key *skey) { } /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. @return CRYPT_OK if the input key size is acceptable. */ int saferp_keysize(int *keysize) { LTC_ARGCHK(keysize != NULL); if (*keysize < 16) return CRYPT_INVALID_KEYSIZE; if (*keysize < 24) { *keysize = 16; } else if (*keysize < 32) { *keysize = 24; } else { *keysize = 32; } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/safer/saferp.c,v $ */ /* $Revision: 1.14 $ */ /* $Date: 2007/05/12 14:20:27 $ */ libtomcrypt-1.17/src/ciphers/anubis.c0000644000175100001440000020522110621351501016376 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file anubis.c Anubis implementation derived from public domain source Authors: Paulo S.L.M. Barreto and Vincent Rijmen. */ #include "tomcrypt.h" #ifdef LTC_ANUBIS const struct ltc_cipher_descriptor anubis_desc = { "anubis", 19, 16, 40, 16, 12, &anubis_setup, &anubis_ecb_encrypt, &anubis_ecb_decrypt, &anubis_test, &anubis_done, &anubis_keysize, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; #define MIN_N 4 #define MAX_N 10 #define MIN_ROUNDS (8 + MIN_N) #define MAX_ROUNDS (8 + MAX_N) #define MIN_KEYSIZEB (4*MIN_N) #define MAX_KEYSIZEB (4*MAX_N) #define BLOCKSIZE 128 #define BLOCKSIZEB (BLOCKSIZE/8) /* * Though Anubis is endianness-neutral, the encryption tables are listed * in BIG-ENDIAN format, which is adopted throughout this implementation * (but little-endian notation would be equally suitable if consistently * employed). */ #if defined(LTC_ANUBIS_TWEAK) static const ulong32 T0[256] = { 0xba69d2bbU, 0x54a84de5U, 0x2f5ebce2U, 0x74e8cd25U, 0x53a651f7U, 0xd3bb6bd0U, 0xd2b96fd6U, 0x4d9a29b3U, 0x50a05dfdU, 0xac458acfU, 0x8d070e09U, 0xbf63c6a5U, 0x70e0dd3dU, 0x52a455f1U, 0x9a29527bU, 0x4c982db5U, 0xeac98f46U, 0xd5b773c4U, 0x97336655U, 0xd1bf63dcU, 0x3366ccaaU, 0x51a259fbU, 0x5bb671c7U, 0xa651a2f3U, 0xdea15ffeU, 0x48903dadU, 0xa84d9ad7U, 0x992f5e71U, 0xdbab4be0U, 0x3264c8acU, 0xb773e695U, 0xfce5d732U, 0xe3dbab70U, 0x9e214263U, 0x913f7e41U, 0x9b2b567dU, 0xe2d9af76U, 0xbb6bd6bdU, 0x4182199bU, 0x6edca579U, 0xa557aef9U, 0xcb8b0b80U, 0x6bd6b167U, 0x95376e59U, 0xa15fbee1U, 0xf3fbeb10U, 0xb17ffe81U, 0x0204080cU, 0xcc851792U, 0xc49537a2U, 0x1d3a744eU, 0x14285078U, 0xc39b2bb0U, 0x63c69157U, 0xdaa94fe6U, 0x5dba69d3U, 0x5fbe61dfU, 0xdca557f2U, 0x7dfae913U, 0xcd871394U, 0x7ffee11fU, 0x5ab475c1U, 0x6cd8ad75U, 0x5cb86dd5U, 0xf7f3fb08U, 0x264c98d4U, 0xffe3db38U, 0xedc79354U, 0xe8cd874aU, 0x9d274e69U, 0x6fdea17fU, 0x8e010203U, 0x19326456U, 0xa05dbae7U, 0xf0fde71aU, 0x890f1e11U, 0x0f1e3c22U, 0x070e1c12U, 0xaf4386c5U, 0xfbebcb20U, 0x08102030U, 0x152a547eU, 0x0d1a342eU, 0x04081018U, 0x01020406U, 0x64c88d45U, 0xdfa35bf8U, 0x76ecc529U, 0x79f2f90bU, 0xdda753f4U, 0x3d7af48eU, 0x162c5874U, 0x3f7efc82U, 0x376edcb2U, 0x6ddaa973U, 0x3870e090U, 0xb96fdeb1U, 0x73e6d137U, 0xe9cf834cU, 0x356ad4beU, 0x55aa49e3U, 0x71e2d93bU, 0x7bf6f107U, 0x8c050a0fU, 0x72e4d531U, 0x880d1a17U, 0xf6f1ff0eU, 0x2a54a8fcU, 0x3e7cf884U, 0x5ebc65d9U, 0x274e9cd2U, 0x468c0589U, 0x0c183028U, 0x65ca8943U, 0x68d0bd6dU, 0x61c2995bU, 0x03060c0aU, 0xc19f23bcU, 0x57ae41efU, 0xd6b17fceU, 0xd9af43ecU, 0x58b07dcdU, 0xd8ad47eaU, 0x66cc8549U, 0xd7b37bc8U, 0x3a74e89cU, 0xc88d078aU, 0x3c78f088U, 0xfae9cf26U, 0x96316253U, 0xa753a6f5U, 0x982d5a77U, 0xecc59752U, 0xb86ddab7U, 0xc7933ba8U, 0xae4182c3U, 0x69d2b96bU, 0x4b9631a7U, 0xab4b96ddU, 0xa94f9ed1U, 0x67ce814fU, 0x0a14283cU, 0x478e018fU, 0xf2f9ef16U, 0xb577ee99U, 0x224488ccU, 0xe5d7b364U, 0xeec19f5eU, 0xbe61c2a3U, 0x2b56acfaU, 0x811f3e21U, 0x1224486cU, 0x831b362dU, 0x1b366c5aU, 0x0e1c3824U, 0x23468ccaU, 0xf5f7f304U, 0x458a0983U, 0x214284c6U, 0xce811f9eU, 0x499239abU, 0x2c58b0e8U, 0xf9efc32cU, 0xe6d1bf6eU, 0xb671e293U, 0x2850a0f0U, 0x172e5c72U, 0x8219322bU, 0x1a34685cU, 0x8b0b161dU, 0xfee1df3eU, 0x8a09121bU, 0x09122436U, 0xc98f038cU, 0x87132635U, 0x4e9c25b9U, 0xe1dfa37cU, 0x2e5cb8e4U, 0xe4d5b762U, 0xe0dda77aU, 0xebcb8b40U, 0x903d7a47U, 0xa455aaffU, 0x1e3c7844U, 0x85172e39U, 0x60c09d5dU, 0x00000000U, 0x254a94deU, 0xf4f5f702U, 0xf1ffe31cU, 0x94356a5fU, 0x0b162c3aU, 0xe7d3bb68U, 0x75eac923U, 0xefc39b58U, 0x3468d0b8U, 0x3162c4a6U, 0xd4b577c2U, 0xd0bd67daU, 0x86112233U, 0x7efce519U, 0xad478ec9U, 0xfde7d334U, 0x2952a4f6U, 0x3060c0a0U, 0x3b76ec9aU, 0x9f234665U, 0xf8edc72aU, 0xc6913faeU, 0x13264c6aU, 0x060c1814U, 0x050a141eU, 0xc59733a4U, 0x11224466U, 0x77eec12fU, 0x7cf8ed15U, 0x7af4f501U, 0x78f0fd0dU, 0x366cd8b4U, 0x1c387048U, 0x3972e496U, 0x59b279cbU, 0x18306050U, 0x56ac45e9U, 0xb37bf68dU, 0xb07dfa87U, 0x244890d8U, 0x204080c0U, 0xb279f28bU, 0x9239724bU, 0xa35bb6edU, 0xc09d27baU, 0x44880d85U, 0x62c49551U, 0x10204060U, 0xb475ea9fU, 0x84152a3fU, 0x43861197U, 0x933b764dU, 0xc2992fb6U, 0x4a9435a1U, 0xbd67cea9U, 0x8f030605U, 0x2d5ab4eeU, 0xbc65caafU, 0x9c254a6fU, 0x6ad4b561U, 0x40801d9dU, 0xcf831b98U, 0xa259b2ebU, 0x801d3a27U, 0x4f9e21bfU, 0x1f3e7c42U, 0xca890f86U, 0xaa4992dbU, 0x42841591U, }; static const ulong32 T1[256] = { 0x69babbd2U, 0xa854e54dU, 0x5e2fe2bcU, 0xe87425cdU, 0xa653f751U, 0xbbd3d06bU, 0xb9d2d66fU, 0x9a4db329U, 0xa050fd5dU, 0x45accf8aU, 0x078d090eU, 0x63bfa5c6U, 0xe0703dddU, 0xa452f155U, 0x299a7b52U, 0x984cb52dU, 0xc9ea468fU, 0xb7d5c473U, 0x33975566U, 0xbfd1dc63U, 0x6633aaccU, 0xa251fb59U, 0xb65bc771U, 0x51a6f3a2U, 0xa1defe5fU, 0x9048ad3dU, 0x4da8d79aU, 0x2f99715eU, 0xabdbe04bU, 0x6432acc8U, 0x73b795e6U, 0xe5fc32d7U, 0xdbe370abU, 0x219e6342U, 0x3f91417eU, 0x2b9b7d56U, 0xd9e276afU, 0x6bbbbdd6U, 0x82419b19U, 0xdc6e79a5U, 0x57a5f9aeU, 0x8bcb800bU, 0xd66b67b1U, 0x3795596eU, 0x5fa1e1beU, 0xfbf310ebU, 0x7fb181feU, 0x04020c08U, 0x85cc9217U, 0x95c4a237U, 0x3a1d4e74U, 0x28147850U, 0x9bc3b02bU, 0xc6635791U, 0xa9dae64fU, 0xba5dd369U, 0xbe5fdf61U, 0xa5dcf257U, 0xfa7d13e9U, 0x87cd9413U, 0xfe7f1fe1U, 0xb45ac175U, 0xd86c75adU, 0xb85cd56dU, 0xf3f708fbU, 0x4c26d498U, 0xe3ff38dbU, 0xc7ed5493U, 0xcde84a87U, 0x279d694eU, 0xde6f7fa1U, 0x018e0302U, 0x32195664U, 0x5da0e7baU, 0xfdf01ae7U, 0x0f89111eU, 0x1e0f223cU, 0x0e07121cU, 0x43afc586U, 0xebfb20cbU, 0x10083020U, 0x2a157e54U, 0x1a0d2e34U, 0x08041810U, 0x02010604U, 0xc864458dU, 0xa3dff85bU, 0xec7629c5U, 0xf2790bf9U, 0xa7ddf453U, 0x7a3d8ef4U, 0x2c167458U, 0x7e3f82fcU, 0x6e37b2dcU, 0xda6d73a9U, 0x703890e0U, 0x6fb9b1deU, 0xe67337d1U, 0xcfe94c83U, 0x6a35bed4U, 0xaa55e349U, 0xe2713bd9U, 0xf67b07f1U, 0x058c0f0aU, 0xe47231d5U, 0x0d88171aU, 0xf1f60effU, 0x542afca8U, 0x7c3e84f8U, 0xbc5ed965U, 0x4e27d29cU, 0x8c468905U, 0x180c2830U, 0xca654389U, 0xd0686dbdU, 0xc2615b99U, 0x06030a0cU, 0x9fc1bc23U, 0xae57ef41U, 0xb1d6ce7fU, 0xafd9ec43U, 0xb058cd7dU, 0xadd8ea47U, 0xcc664985U, 0xb3d7c87bU, 0x743a9ce8U, 0x8dc88a07U, 0x783c88f0U, 0xe9fa26cfU, 0x31965362U, 0x53a7f5a6U, 0x2d98775aU, 0xc5ec5297U, 0x6db8b7daU, 0x93c7a83bU, 0x41aec382U, 0xd2696bb9U, 0x964ba731U, 0x4babdd96U, 0x4fa9d19eU, 0xce674f81U, 0x140a3c28U, 0x8e478f01U, 0xf9f216efU, 0x77b599eeU, 0x4422cc88U, 0xd7e564b3U, 0xc1ee5e9fU, 0x61bea3c2U, 0x562bfaacU, 0x1f81213eU, 0x24126c48U, 0x1b832d36U, 0x361b5a6cU, 0x1c0e2438U, 0x4623ca8cU, 0xf7f504f3U, 0x8a458309U, 0x4221c684U, 0x81ce9e1fU, 0x9249ab39U, 0x582ce8b0U, 0xeff92cc3U, 0xd1e66ebfU, 0x71b693e2U, 0x5028f0a0U, 0x2e17725cU, 0x19822b32U, 0x341a5c68U, 0x0b8b1d16U, 0xe1fe3edfU, 0x098a1b12U, 0x12093624U, 0x8fc98c03U, 0x13873526U, 0x9c4eb925U, 0xdfe17ca3U, 0x5c2ee4b8U, 0xd5e462b7U, 0xdde07aa7U, 0xcbeb408bU, 0x3d90477aU, 0x55a4ffaaU, 0x3c1e4478U, 0x1785392eU, 0xc0605d9dU, 0x00000000U, 0x4a25de94U, 0xf5f402f7U, 0xfff11ce3U, 0x35945f6aU, 0x160b3a2cU, 0xd3e768bbU, 0xea7523c9U, 0xc3ef589bU, 0x6834b8d0U, 0x6231a6c4U, 0xb5d4c277U, 0xbdd0da67U, 0x11863322U, 0xfc7e19e5U, 0x47adc98eU, 0xe7fd34d3U, 0x5229f6a4U, 0x6030a0c0U, 0x763b9aecU, 0x239f6546U, 0xedf82ac7U, 0x91c6ae3fU, 0x26136a4cU, 0x0c061418U, 0x0a051e14U, 0x97c5a433U, 0x22116644U, 0xee772fc1U, 0xf87c15edU, 0xf47a01f5U, 0xf0780dfdU, 0x6c36b4d8U, 0x381c4870U, 0x723996e4U, 0xb259cb79U, 0x30185060U, 0xac56e945U, 0x7bb38df6U, 0x7db087faU, 0x4824d890U, 0x4020c080U, 0x79b28bf2U, 0x39924b72U, 0x5ba3edb6U, 0x9dc0ba27U, 0x8844850dU, 0xc4625195U, 0x20106040U, 0x75b49feaU, 0x15843f2aU, 0x86439711U, 0x3b934d76U, 0x99c2b62fU, 0x944aa135U, 0x67bda9ceU, 0x038f0506U, 0x5a2deeb4U, 0x65bcafcaU, 0x259c6f4aU, 0xd46a61b5U, 0x80409d1dU, 0x83cf981bU, 0x59a2ebb2U, 0x1d80273aU, 0x9e4fbf21U, 0x3e1f427cU, 0x89ca860fU, 0x49aadb92U, 0x84429115U, }; static const ulong32 T2[256] = { 0xd2bbba69U, 0x4de554a8U, 0xbce22f5eU, 0xcd2574e8U, 0x51f753a6U, 0x6bd0d3bbU, 0x6fd6d2b9U, 0x29b34d9aU, 0x5dfd50a0U, 0x8acfac45U, 0x0e098d07U, 0xc6a5bf63U, 0xdd3d70e0U, 0x55f152a4U, 0x527b9a29U, 0x2db54c98U, 0x8f46eac9U, 0x73c4d5b7U, 0x66559733U, 0x63dcd1bfU, 0xccaa3366U, 0x59fb51a2U, 0x71c75bb6U, 0xa2f3a651U, 0x5ffedea1U, 0x3dad4890U, 0x9ad7a84dU, 0x5e71992fU, 0x4be0dbabU, 0xc8ac3264U, 0xe695b773U, 0xd732fce5U, 0xab70e3dbU, 0x42639e21U, 0x7e41913fU, 0x567d9b2bU, 0xaf76e2d9U, 0xd6bdbb6bU, 0x199b4182U, 0xa5796edcU, 0xaef9a557U, 0x0b80cb8bU, 0xb1676bd6U, 0x6e599537U, 0xbee1a15fU, 0xeb10f3fbU, 0xfe81b17fU, 0x080c0204U, 0x1792cc85U, 0x37a2c495U, 0x744e1d3aU, 0x50781428U, 0x2bb0c39bU, 0x915763c6U, 0x4fe6daa9U, 0x69d35dbaU, 0x61df5fbeU, 0x57f2dca5U, 0xe9137dfaU, 0x1394cd87U, 0xe11f7ffeU, 0x75c15ab4U, 0xad756cd8U, 0x6dd55cb8U, 0xfb08f7f3U, 0x98d4264cU, 0xdb38ffe3U, 0x9354edc7U, 0x874ae8cdU, 0x4e699d27U, 0xa17f6fdeU, 0x02038e01U, 0x64561932U, 0xbae7a05dU, 0xe71af0fdU, 0x1e11890fU, 0x3c220f1eU, 0x1c12070eU, 0x86c5af43U, 0xcb20fbebU, 0x20300810U, 0x547e152aU, 0x342e0d1aU, 0x10180408U, 0x04060102U, 0x8d4564c8U, 0x5bf8dfa3U, 0xc52976ecU, 0xf90b79f2U, 0x53f4dda7U, 0xf48e3d7aU, 0x5874162cU, 0xfc823f7eU, 0xdcb2376eU, 0xa9736ddaU, 0xe0903870U, 0xdeb1b96fU, 0xd13773e6U, 0x834ce9cfU, 0xd4be356aU, 0x49e355aaU, 0xd93b71e2U, 0xf1077bf6U, 0x0a0f8c05U, 0xd53172e4U, 0x1a17880dU, 0xff0ef6f1U, 0xa8fc2a54U, 0xf8843e7cU, 0x65d95ebcU, 0x9cd2274eU, 0x0589468cU, 0x30280c18U, 0x894365caU, 0xbd6d68d0U, 0x995b61c2U, 0x0c0a0306U, 0x23bcc19fU, 0x41ef57aeU, 0x7fced6b1U, 0x43ecd9afU, 0x7dcd58b0U, 0x47ead8adU, 0x854966ccU, 0x7bc8d7b3U, 0xe89c3a74U, 0x078ac88dU, 0xf0883c78U, 0xcf26fae9U, 0x62539631U, 0xa6f5a753U, 0x5a77982dU, 0x9752ecc5U, 0xdab7b86dU, 0x3ba8c793U, 0x82c3ae41U, 0xb96b69d2U, 0x31a74b96U, 0x96ddab4bU, 0x9ed1a94fU, 0x814f67ceU, 0x283c0a14U, 0x018f478eU, 0xef16f2f9U, 0xee99b577U, 0x88cc2244U, 0xb364e5d7U, 0x9f5eeec1U, 0xc2a3be61U, 0xacfa2b56U, 0x3e21811fU, 0x486c1224U, 0x362d831bU, 0x6c5a1b36U, 0x38240e1cU, 0x8cca2346U, 0xf304f5f7U, 0x0983458aU, 0x84c62142U, 0x1f9ece81U, 0x39ab4992U, 0xb0e82c58U, 0xc32cf9efU, 0xbf6ee6d1U, 0xe293b671U, 0xa0f02850U, 0x5c72172eU, 0x322b8219U, 0x685c1a34U, 0x161d8b0bU, 0xdf3efee1U, 0x121b8a09U, 0x24360912U, 0x038cc98fU, 0x26358713U, 0x25b94e9cU, 0xa37ce1dfU, 0xb8e42e5cU, 0xb762e4d5U, 0xa77ae0ddU, 0x8b40ebcbU, 0x7a47903dU, 0xaaffa455U, 0x78441e3cU, 0x2e398517U, 0x9d5d60c0U, 0x00000000U, 0x94de254aU, 0xf702f4f5U, 0xe31cf1ffU, 0x6a5f9435U, 0x2c3a0b16U, 0xbb68e7d3U, 0xc92375eaU, 0x9b58efc3U, 0xd0b83468U, 0xc4a63162U, 0x77c2d4b5U, 0x67dad0bdU, 0x22338611U, 0xe5197efcU, 0x8ec9ad47U, 0xd334fde7U, 0xa4f62952U, 0xc0a03060U, 0xec9a3b76U, 0x46659f23U, 0xc72af8edU, 0x3faec691U, 0x4c6a1326U, 0x1814060cU, 0x141e050aU, 0x33a4c597U, 0x44661122U, 0xc12f77eeU, 0xed157cf8U, 0xf5017af4U, 0xfd0d78f0U, 0xd8b4366cU, 0x70481c38U, 0xe4963972U, 0x79cb59b2U, 0x60501830U, 0x45e956acU, 0xf68db37bU, 0xfa87b07dU, 0x90d82448U, 0x80c02040U, 0xf28bb279U, 0x724b9239U, 0xb6eda35bU, 0x27bac09dU, 0x0d854488U, 0x955162c4U, 0x40601020U, 0xea9fb475U, 0x2a3f8415U, 0x11974386U, 0x764d933bU, 0x2fb6c299U, 0x35a14a94U, 0xcea9bd67U, 0x06058f03U, 0xb4ee2d5aU, 0xcaafbc65U, 0x4a6f9c25U, 0xb5616ad4U, 0x1d9d4080U, 0x1b98cf83U, 0xb2eba259U, 0x3a27801dU, 0x21bf4f9eU, 0x7c421f3eU, 0x0f86ca89U, 0x92dbaa49U, 0x15914284U, }; static const ulong32 T3[256] = { 0xbbd269baU, 0xe54da854U, 0xe2bc5e2fU, 0x25cde874U, 0xf751a653U, 0xd06bbbd3U, 0xd66fb9d2U, 0xb3299a4dU, 0xfd5da050U, 0xcf8a45acU, 0x090e078dU, 0xa5c663bfU, 0x3ddde070U, 0xf155a452U, 0x7b52299aU, 0xb52d984cU, 0x468fc9eaU, 0xc473b7d5U, 0x55663397U, 0xdc63bfd1U, 0xaacc6633U, 0xfb59a251U, 0xc771b65bU, 0xf3a251a6U, 0xfe5fa1deU, 0xad3d9048U, 0xd79a4da8U, 0x715e2f99U, 0xe04babdbU, 0xacc86432U, 0x95e673b7U, 0x32d7e5fcU, 0x70abdbe3U, 0x6342219eU, 0x417e3f91U, 0x7d562b9bU, 0x76afd9e2U, 0xbdd66bbbU, 0x9b198241U, 0x79a5dc6eU, 0xf9ae57a5U, 0x800b8bcbU, 0x67b1d66bU, 0x596e3795U, 0xe1be5fa1U, 0x10ebfbf3U, 0x81fe7fb1U, 0x0c080402U, 0x921785ccU, 0xa23795c4U, 0x4e743a1dU, 0x78502814U, 0xb02b9bc3U, 0x5791c663U, 0xe64fa9daU, 0xd369ba5dU, 0xdf61be5fU, 0xf257a5dcU, 0x13e9fa7dU, 0x941387cdU, 0x1fe1fe7fU, 0xc175b45aU, 0x75add86cU, 0xd56db85cU, 0x08fbf3f7U, 0xd4984c26U, 0x38dbe3ffU, 0x5493c7edU, 0x4a87cde8U, 0x694e279dU, 0x7fa1de6fU, 0x0302018eU, 0x56643219U, 0xe7ba5da0U, 0x1ae7fdf0U, 0x111e0f89U, 0x223c1e0fU, 0x121c0e07U, 0xc58643afU, 0x20cbebfbU, 0x30201008U, 0x7e542a15U, 0x2e341a0dU, 0x18100804U, 0x06040201U, 0x458dc864U, 0xf85ba3dfU, 0x29c5ec76U, 0x0bf9f279U, 0xf453a7ddU, 0x8ef47a3dU, 0x74582c16U, 0x82fc7e3fU, 0xb2dc6e37U, 0x73a9da6dU, 0x90e07038U, 0xb1de6fb9U, 0x37d1e673U, 0x4c83cfe9U, 0xbed46a35U, 0xe349aa55U, 0x3bd9e271U, 0x07f1f67bU, 0x0f0a058cU, 0x31d5e472U, 0x171a0d88U, 0x0efff1f6U, 0xfca8542aU, 0x84f87c3eU, 0xd965bc5eU, 0xd29c4e27U, 0x89058c46U, 0x2830180cU, 0x4389ca65U, 0x6dbdd068U, 0x5b99c261U, 0x0a0c0603U, 0xbc239fc1U, 0xef41ae57U, 0xce7fb1d6U, 0xec43afd9U, 0xcd7db058U, 0xea47add8U, 0x4985cc66U, 0xc87bb3d7U, 0x9ce8743aU, 0x8a078dc8U, 0x88f0783cU, 0x26cfe9faU, 0x53623196U, 0xf5a653a7U, 0x775a2d98U, 0x5297c5ecU, 0xb7da6db8U, 0xa83b93c7U, 0xc38241aeU, 0x6bb9d269U, 0xa731964bU, 0xdd964babU, 0xd19e4fa9U, 0x4f81ce67U, 0x3c28140aU, 0x8f018e47U, 0x16eff9f2U, 0x99ee77b5U, 0xcc884422U, 0x64b3d7e5U, 0x5e9fc1eeU, 0xa3c261beU, 0xfaac562bU, 0x213e1f81U, 0x6c482412U, 0x2d361b83U, 0x5a6c361bU, 0x24381c0eU, 0xca8c4623U, 0x04f3f7f5U, 0x83098a45U, 0xc6844221U, 0x9e1f81ceU, 0xab399249U, 0xe8b0582cU, 0x2cc3eff9U, 0x6ebfd1e6U, 0x93e271b6U, 0xf0a05028U, 0x725c2e17U, 0x2b321982U, 0x5c68341aU, 0x1d160b8bU, 0x3edfe1feU, 0x1b12098aU, 0x36241209U, 0x8c038fc9U, 0x35261387U, 0xb9259c4eU, 0x7ca3dfe1U, 0xe4b85c2eU, 0x62b7d5e4U, 0x7aa7dde0U, 0x408bcbebU, 0x477a3d90U, 0xffaa55a4U, 0x44783c1eU, 0x392e1785U, 0x5d9dc060U, 0x00000000U, 0xde944a25U, 0x02f7f5f4U, 0x1ce3fff1U, 0x5f6a3594U, 0x3a2c160bU, 0x68bbd3e7U, 0x23c9ea75U, 0x589bc3efU, 0xb8d06834U, 0xa6c46231U, 0xc277b5d4U, 0xda67bdd0U, 0x33221186U, 0x19e5fc7eU, 0xc98e47adU, 0x34d3e7fdU, 0xf6a45229U, 0xa0c06030U, 0x9aec763bU, 0x6546239fU, 0x2ac7edf8U, 0xae3f91c6U, 0x6a4c2613U, 0x14180c06U, 0x1e140a05U, 0xa43397c5U, 0x66442211U, 0x2fc1ee77U, 0x15edf87cU, 0x01f5f47aU, 0x0dfdf078U, 0xb4d86c36U, 0x4870381cU, 0x96e47239U, 0xcb79b259U, 0x50603018U, 0xe945ac56U, 0x8df67bb3U, 0x87fa7db0U, 0xd8904824U, 0xc0804020U, 0x8bf279b2U, 0x4b723992U, 0xedb65ba3U, 0xba279dc0U, 0x850d8844U, 0x5195c462U, 0x60402010U, 0x9fea75b4U, 0x3f2a1584U, 0x97118643U, 0x4d763b93U, 0xb62f99c2U, 0xa135944aU, 0xa9ce67bdU, 0x0506038fU, 0xeeb45a2dU, 0xafca65bcU, 0x6f4a259cU, 0x61b5d46aU, 0x9d1d8040U, 0x981b83cfU, 0xebb259a2U, 0x273a1d80U, 0xbf219e4fU, 0x427c3e1fU, 0x860f89caU, 0xdb9249aaU, 0x91158442U, }; static const ulong32 T4[256] = { 0xbabababaU, 0x54545454U, 0x2f2f2f2fU, 0x74747474U, 0x53535353U, 0xd3d3d3d3U, 0xd2d2d2d2U, 0x4d4d4d4dU, 0x50505050U, 0xacacacacU, 0x8d8d8d8dU, 0xbfbfbfbfU, 0x70707070U, 0x52525252U, 0x9a9a9a9aU, 0x4c4c4c4cU, 0xeaeaeaeaU, 0xd5d5d5d5U, 0x97979797U, 0xd1d1d1d1U, 0x33333333U, 0x51515151U, 0x5b5b5b5bU, 0xa6a6a6a6U, 0xdedededeU, 0x48484848U, 0xa8a8a8a8U, 0x99999999U, 0xdbdbdbdbU, 0x32323232U, 0xb7b7b7b7U, 0xfcfcfcfcU, 0xe3e3e3e3U, 0x9e9e9e9eU, 0x91919191U, 0x9b9b9b9bU, 0xe2e2e2e2U, 0xbbbbbbbbU, 0x41414141U, 0x6e6e6e6eU, 0xa5a5a5a5U, 0xcbcbcbcbU, 0x6b6b6b6bU, 0x95959595U, 0xa1a1a1a1U, 0xf3f3f3f3U, 0xb1b1b1b1U, 0x02020202U, 0xccccccccU, 0xc4c4c4c4U, 0x1d1d1d1dU, 0x14141414U, 0xc3c3c3c3U, 0x63636363U, 0xdadadadaU, 0x5d5d5d5dU, 0x5f5f5f5fU, 0xdcdcdcdcU, 0x7d7d7d7dU, 0xcdcdcdcdU, 0x7f7f7f7fU, 0x5a5a5a5aU, 0x6c6c6c6cU, 0x5c5c5c5cU, 0xf7f7f7f7U, 0x26262626U, 0xffffffffU, 0xededededU, 0xe8e8e8e8U, 0x9d9d9d9dU, 0x6f6f6f6fU, 0x8e8e8e8eU, 0x19191919U, 0xa0a0a0a0U, 0xf0f0f0f0U, 0x89898989U, 0x0f0f0f0fU, 0x07070707U, 0xafafafafU, 0xfbfbfbfbU, 0x08080808U, 0x15151515U, 0x0d0d0d0dU, 0x04040404U, 0x01010101U, 0x64646464U, 0xdfdfdfdfU, 0x76767676U, 0x79797979U, 0xddddddddU, 0x3d3d3d3dU, 0x16161616U, 0x3f3f3f3fU, 0x37373737U, 0x6d6d6d6dU, 0x38383838U, 0xb9b9b9b9U, 0x73737373U, 0xe9e9e9e9U, 0x35353535U, 0x55555555U, 0x71717171U, 0x7b7b7b7bU, 0x8c8c8c8cU, 0x72727272U, 0x88888888U, 0xf6f6f6f6U, 0x2a2a2a2aU, 0x3e3e3e3eU, 0x5e5e5e5eU, 0x27272727U, 0x46464646U, 0x0c0c0c0cU, 0x65656565U, 0x68686868U, 0x61616161U, 0x03030303U, 0xc1c1c1c1U, 0x57575757U, 0xd6d6d6d6U, 0xd9d9d9d9U, 0x58585858U, 0xd8d8d8d8U, 0x66666666U, 0xd7d7d7d7U, 0x3a3a3a3aU, 0xc8c8c8c8U, 0x3c3c3c3cU, 0xfafafafaU, 0x96969696U, 0xa7a7a7a7U, 0x98989898U, 0xececececU, 0xb8b8b8b8U, 0xc7c7c7c7U, 0xaeaeaeaeU, 0x69696969U, 0x4b4b4b4bU, 0xababababU, 0xa9a9a9a9U, 0x67676767U, 0x0a0a0a0aU, 0x47474747U, 0xf2f2f2f2U, 0xb5b5b5b5U, 0x22222222U, 0xe5e5e5e5U, 0xeeeeeeeeU, 0xbebebebeU, 0x2b2b2b2bU, 0x81818181U, 0x12121212U, 0x83838383U, 0x1b1b1b1bU, 0x0e0e0e0eU, 0x23232323U, 0xf5f5f5f5U, 0x45454545U, 0x21212121U, 0xcecececeU, 0x49494949U, 0x2c2c2c2cU, 0xf9f9f9f9U, 0xe6e6e6e6U, 0xb6b6b6b6U, 0x28282828U, 0x17171717U, 0x82828282U, 0x1a1a1a1aU, 0x8b8b8b8bU, 0xfefefefeU, 0x8a8a8a8aU, 0x09090909U, 0xc9c9c9c9U, 0x87878787U, 0x4e4e4e4eU, 0xe1e1e1e1U, 0x2e2e2e2eU, 0xe4e4e4e4U, 0xe0e0e0e0U, 0xebebebebU, 0x90909090U, 0xa4a4a4a4U, 0x1e1e1e1eU, 0x85858585U, 0x60606060U, 0x00000000U, 0x25252525U, 0xf4f4f4f4U, 0xf1f1f1f1U, 0x94949494U, 0x0b0b0b0bU, 0xe7e7e7e7U, 0x75757575U, 0xefefefefU, 0x34343434U, 0x31313131U, 0xd4d4d4d4U, 0xd0d0d0d0U, 0x86868686U, 0x7e7e7e7eU, 0xadadadadU, 0xfdfdfdfdU, 0x29292929U, 0x30303030U, 0x3b3b3b3bU, 0x9f9f9f9fU, 0xf8f8f8f8U, 0xc6c6c6c6U, 0x13131313U, 0x06060606U, 0x05050505U, 0xc5c5c5c5U, 0x11111111U, 0x77777777U, 0x7c7c7c7cU, 0x7a7a7a7aU, 0x78787878U, 0x36363636U, 0x1c1c1c1cU, 0x39393939U, 0x59595959U, 0x18181818U, 0x56565656U, 0xb3b3b3b3U, 0xb0b0b0b0U, 0x24242424U, 0x20202020U, 0xb2b2b2b2U, 0x92929292U, 0xa3a3a3a3U, 0xc0c0c0c0U, 0x44444444U, 0x62626262U, 0x10101010U, 0xb4b4b4b4U, 0x84848484U, 0x43434343U, 0x93939393U, 0xc2c2c2c2U, 0x4a4a4a4aU, 0xbdbdbdbdU, 0x8f8f8f8fU, 0x2d2d2d2dU, 0xbcbcbcbcU, 0x9c9c9c9cU, 0x6a6a6a6aU, 0x40404040U, 0xcfcfcfcfU, 0xa2a2a2a2U, 0x80808080U, 0x4f4f4f4fU, 0x1f1f1f1fU, 0xcacacacaU, 0xaaaaaaaaU, 0x42424242U, }; static const ulong32 T5[256] = { 0x00000000U, 0x01020608U, 0x02040c10U, 0x03060a18U, 0x04081820U, 0x050a1e28U, 0x060c1430U, 0x070e1238U, 0x08103040U, 0x09123648U, 0x0a143c50U, 0x0b163a58U, 0x0c182860U, 0x0d1a2e68U, 0x0e1c2470U, 0x0f1e2278U, 0x10206080U, 0x11226688U, 0x12246c90U, 0x13266a98U, 0x142878a0U, 0x152a7ea8U, 0x162c74b0U, 0x172e72b8U, 0x183050c0U, 0x193256c8U, 0x1a345cd0U, 0x1b365ad8U, 0x1c3848e0U, 0x1d3a4ee8U, 0x1e3c44f0U, 0x1f3e42f8U, 0x2040c01dU, 0x2142c615U, 0x2244cc0dU, 0x2346ca05U, 0x2448d83dU, 0x254ade35U, 0x264cd42dU, 0x274ed225U, 0x2850f05dU, 0x2952f655U, 0x2a54fc4dU, 0x2b56fa45U, 0x2c58e87dU, 0x2d5aee75U, 0x2e5ce46dU, 0x2f5ee265U, 0x3060a09dU, 0x3162a695U, 0x3264ac8dU, 0x3366aa85U, 0x3468b8bdU, 0x356abeb5U, 0x366cb4adU, 0x376eb2a5U, 0x387090ddU, 0x397296d5U, 0x3a749ccdU, 0x3b769ac5U, 0x3c7888fdU, 0x3d7a8ef5U, 0x3e7c84edU, 0x3f7e82e5U, 0x40809d3aU, 0x41829b32U, 0x4284912aU, 0x43869722U, 0x4488851aU, 0x458a8312U, 0x468c890aU, 0x478e8f02U, 0x4890ad7aU, 0x4992ab72U, 0x4a94a16aU, 0x4b96a762U, 0x4c98b55aU, 0x4d9ab352U, 0x4e9cb94aU, 0x4f9ebf42U, 0x50a0fdbaU, 0x51a2fbb2U, 0x52a4f1aaU, 0x53a6f7a2U, 0x54a8e59aU, 0x55aae392U, 0x56ace98aU, 0x57aeef82U, 0x58b0cdfaU, 0x59b2cbf2U, 0x5ab4c1eaU, 0x5bb6c7e2U, 0x5cb8d5daU, 0x5dbad3d2U, 0x5ebcd9caU, 0x5fbedfc2U, 0x60c05d27U, 0x61c25b2fU, 0x62c45137U, 0x63c6573fU, 0x64c84507U, 0x65ca430fU, 0x66cc4917U, 0x67ce4f1fU, 0x68d06d67U, 0x69d26b6fU, 0x6ad46177U, 0x6bd6677fU, 0x6cd87547U, 0x6dda734fU, 0x6edc7957U, 0x6fde7f5fU, 0x70e03da7U, 0x71e23bafU, 0x72e431b7U, 0x73e637bfU, 0x74e82587U, 0x75ea238fU, 0x76ec2997U, 0x77ee2f9fU, 0x78f00de7U, 0x79f20befU, 0x7af401f7U, 0x7bf607ffU, 0x7cf815c7U, 0x7dfa13cfU, 0x7efc19d7U, 0x7ffe1fdfU, 0x801d2774U, 0x811f217cU, 0x82192b64U, 0x831b2d6cU, 0x84153f54U, 0x8517395cU, 0x86113344U, 0x8713354cU, 0x880d1734U, 0x890f113cU, 0x8a091b24U, 0x8b0b1d2cU, 0x8c050f14U, 0x8d07091cU, 0x8e010304U, 0x8f03050cU, 0x903d47f4U, 0x913f41fcU, 0x92394be4U, 0x933b4decU, 0x94355fd4U, 0x953759dcU, 0x963153c4U, 0x973355ccU, 0x982d77b4U, 0x992f71bcU, 0x9a297ba4U, 0x9b2b7dacU, 0x9c256f94U, 0x9d27699cU, 0x9e216384U, 0x9f23658cU, 0xa05de769U, 0xa15fe161U, 0xa259eb79U, 0xa35bed71U, 0xa455ff49U, 0xa557f941U, 0xa651f359U, 0xa753f551U, 0xa84dd729U, 0xa94fd121U, 0xaa49db39U, 0xab4bdd31U, 0xac45cf09U, 0xad47c901U, 0xae41c319U, 0xaf43c511U, 0xb07d87e9U, 0xb17f81e1U, 0xb2798bf9U, 0xb37b8df1U, 0xb4759fc9U, 0xb57799c1U, 0xb67193d9U, 0xb77395d1U, 0xb86db7a9U, 0xb96fb1a1U, 0xba69bbb9U, 0xbb6bbdb1U, 0xbc65af89U, 0xbd67a981U, 0xbe61a399U, 0xbf63a591U, 0xc09dba4eU, 0xc19fbc46U, 0xc299b65eU, 0xc39bb056U, 0xc495a26eU, 0xc597a466U, 0xc691ae7eU, 0xc793a876U, 0xc88d8a0eU, 0xc98f8c06U, 0xca89861eU, 0xcb8b8016U, 0xcc85922eU, 0xcd879426U, 0xce819e3eU, 0xcf839836U, 0xd0bddaceU, 0xd1bfdcc6U, 0xd2b9d6deU, 0xd3bbd0d6U, 0xd4b5c2eeU, 0xd5b7c4e6U, 0xd6b1cefeU, 0xd7b3c8f6U, 0xd8adea8eU, 0xd9afec86U, 0xdaa9e69eU, 0xdbabe096U, 0xdca5f2aeU, 0xdda7f4a6U, 0xdea1febeU, 0xdfa3f8b6U, 0xe0dd7a53U, 0xe1df7c5bU, 0xe2d97643U, 0xe3db704bU, 0xe4d56273U, 0xe5d7647bU, 0xe6d16e63U, 0xe7d3686bU, 0xe8cd4a13U, 0xe9cf4c1bU, 0xeac94603U, 0xebcb400bU, 0xecc55233U, 0xedc7543bU, 0xeec15e23U, 0xefc3582bU, 0xf0fd1ad3U, 0xf1ff1cdbU, 0xf2f916c3U, 0xf3fb10cbU, 0xf4f502f3U, 0xf5f704fbU, 0xf6f10ee3U, 0xf7f308ebU, 0xf8ed2a93U, 0xf9ef2c9bU, 0xfae92683U, 0xfbeb208bU, 0xfce532b3U, 0xfde734bbU, 0xfee13ea3U, 0xffe338abU, }; /** * The round constants. */ static const ulong32 rc[] = { 0xba542f74U, 0x53d3d24dU, 0x50ac8dbfU, 0x70529a4cU, 0xead597d1U, 0x33515ba6U, 0xde48a899U, 0xdb32b7fcU, 0xe39e919bU, 0xe2bb416eU, 0xa5cb6b95U, 0xa1f3b102U, 0xccc41d14U, 0xc363da5dU, 0x5fdc7dcdU, 0x7f5a6c5cU, 0xf726ffedU, 0xe89d6f8eU, 0x19a0f089U, }; #else static const ulong32 T0[256] = { 0xa753a6f5U, 0xd3bb6bd0U, 0xe6d1bf6eU, 0x71e2d93bU, 0xd0bd67daU, 0xac458acfU, 0x4d9a29b3U, 0x79f2f90bU, 0x3a74e89cU, 0xc98f038cU, 0x913f7e41U, 0xfce5d732U, 0x1e3c7844U, 0x478e018fU, 0x54a84de5U, 0xbd67cea9U, 0x8c050a0fU, 0xa557aef9U, 0x7af4f501U, 0xfbebcb20U, 0x63c69157U, 0xb86ddab7U, 0xdda753f4U, 0xd4b577c2U, 0xe5d7b364U, 0xb37bf68dU, 0xc59733a4U, 0xbe61c2a3U, 0xa94f9ed1U, 0x880d1a17U, 0x0c183028U, 0xa259b2ebU, 0x3972e496U, 0xdfa35bf8U, 0x2952a4f6U, 0xdaa94fe6U, 0x2b56acfaU, 0xa84d9ad7U, 0xcb8b0b80U, 0x4c982db5U, 0x4b9631a7U, 0x224488ccU, 0xaa4992dbU, 0x244890d8U, 0x4182199bU, 0x70e0dd3dU, 0xa651a2f3U, 0xf9efc32cU, 0x5ab475c1U, 0xe2d9af76U, 0xb07dfa87U, 0x366cd8b4U, 0x7dfae913U, 0xe4d5b762U, 0x3366ccaaU, 0xffe3db38U, 0x60c09d5dU, 0x204080c0U, 0x08102030U, 0x8b0b161dU, 0x5ebc65d9U, 0xab4b96ddU, 0x7ffee11fU, 0x78f0fd0dU, 0x7cf8ed15U, 0x2c58b0e8U, 0x57ae41efU, 0xd2b96fd6U, 0xdca557f2U, 0x6ddaa973U, 0x7efce519U, 0x0d1a342eU, 0x53a651f7U, 0x94356a5fU, 0xc39b2bb0U, 0x2850a0f0U, 0x274e9cd2U, 0x060c1814U, 0x5fbe61dfU, 0xad478ec9U, 0x67ce814fU, 0x5cb86dd5U, 0x55aa49e3U, 0x48903dadU, 0x0e1c3824U, 0x52a455f1U, 0xeac98f46U, 0x42841591U, 0x5bb671c7U, 0x5dba69d3U, 0x3060c0a0U, 0x58b07dcdU, 0x51a259fbU, 0x59b279cbU, 0x3c78f088U, 0x4e9c25b9U, 0x3870e090U, 0x8a09121bU, 0x72e4d531U, 0x14285078U, 0xe7d3bb68U, 0xc6913faeU, 0xdea15ffeU, 0x50a05dfdU, 0x8e010203U, 0x9239724bU, 0xd1bf63dcU, 0x77eec12fU, 0x933b764dU, 0x458a0983U, 0x9a29527bU, 0xce811f9eU, 0x2d5ab4eeU, 0x03060c0aU, 0x62c49551U, 0xb671e293U, 0xb96fdeb1U, 0xbf63c6a5U, 0x96316253U, 0x6bd6b167U, 0x3f7efc82U, 0x070e1c12U, 0x1224486cU, 0xae4182c3U, 0x40801d9dU, 0x3468d0b8U, 0x468c0589U, 0x3e7cf884U, 0xdbab4be0U, 0xcf831b98U, 0xecc59752U, 0xcc851792U, 0xc19f23bcU, 0xa15fbee1U, 0xc09d27baU, 0xd6b17fceU, 0x1d3a744eU, 0xf4f5f702U, 0x61c2995bU, 0x3b76ec9aU, 0x10204060U, 0xd8ad47eaU, 0x68d0bd6dU, 0xa05dbae7U, 0xb17ffe81U, 0x0a14283cU, 0x69d2b96bU, 0x6cd8ad75U, 0x499239abU, 0xfae9cf26U, 0x76ecc529U, 0xc49537a2U, 0x9e214263U, 0x9b2b567dU, 0x6edca579U, 0x992f5e71U, 0xc2992fb6U, 0xb773e695U, 0x982d5a77U, 0xbc65caafU, 0x8f030605U, 0x85172e39U, 0x1f3e7c42U, 0xb475ea9fU, 0xf8edc72aU, 0x11224466U, 0x2e5cb8e4U, 0x00000000U, 0x254a94deU, 0x1c387048U, 0x2a54a8fcU, 0x3d7af48eU, 0x050a141eU, 0x4f9e21bfU, 0x7bf6f107U, 0xb279f28bU, 0x3264c8acU, 0x903d7a47U, 0xaf4386c5U, 0x19326456U, 0xa35bb6edU, 0xf7f3fb08U, 0x73e6d137U, 0x9d274e69U, 0x152a547eU, 0x74e8cd25U, 0xeec19f5eU, 0xca890f86U, 0x9f234665U, 0x0f1e3c22U, 0x1b366c5aU, 0x75eac923U, 0x86112233U, 0x84152a3fU, 0x9c254a6fU, 0x4a9435a1U, 0x97336655U, 0x1a34685cU, 0x65ca8943U, 0xf6f1ff0eU, 0xedc79354U, 0x09122436U, 0xbb6bd6bdU, 0x264c98d4U, 0x831b362dU, 0xebcb8b40U, 0x6fdea17fU, 0x811f3e21U, 0x04081018U, 0x6ad4b561U, 0x43861197U, 0x01020406U, 0x172e5c72U, 0xe1dfa37cU, 0x87132635U, 0xf5f7f304U, 0x8d070e09U, 0xe3dbab70U, 0x23468ccaU, 0x801d3a27U, 0x44880d85U, 0x162c5874U, 0x66cc8549U, 0x214284c6U, 0xfee1df3eU, 0xd5b773c4U, 0x3162c4a6U, 0xd9af43ecU, 0x356ad4beU, 0x18306050U, 0x0204080cU, 0x64c88d45U, 0xf2f9ef16U, 0xf1ffe31cU, 0x56ac45e9U, 0xcd871394U, 0x8219322bU, 0xc88d078aU, 0xba69d2bbU, 0xf0fde71aU, 0xefc39b58U, 0xe9cf834cU, 0xe8cd874aU, 0xfde7d334U, 0x890f1e11U, 0xd7b37bc8U, 0xc7933ba8U, 0xb577ee99U, 0xa455aaffU, 0x2f5ebce2U, 0x95376e59U, 0x13264c6aU, 0x0b162c3aU, 0xf3fbeb10U, 0xe0dda77aU, 0x376edcb2U, }; static const ulong32 T1[256] = { 0x53a7f5a6U, 0xbbd3d06bU, 0xd1e66ebfU, 0xe2713bd9U, 0xbdd0da67U, 0x45accf8aU, 0x9a4db329U, 0xf2790bf9U, 0x743a9ce8U, 0x8fc98c03U, 0x3f91417eU, 0xe5fc32d7U, 0x3c1e4478U, 0x8e478f01U, 0xa854e54dU, 0x67bda9ceU, 0x058c0f0aU, 0x57a5f9aeU, 0xf47a01f5U, 0xebfb20cbU, 0xc6635791U, 0x6db8b7daU, 0xa7ddf453U, 0xb5d4c277U, 0xd7e564b3U, 0x7bb38df6U, 0x97c5a433U, 0x61bea3c2U, 0x4fa9d19eU, 0x0d88171aU, 0x180c2830U, 0x59a2ebb2U, 0x723996e4U, 0xa3dff85bU, 0x5229f6a4U, 0xa9dae64fU, 0x562bfaacU, 0x4da8d79aU, 0x8bcb800bU, 0x984cb52dU, 0x964ba731U, 0x4422cc88U, 0x49aadb92U, 0x4824d890U, 0x82419b19U, 0xe0703dddU, 0x51a6f3a2U, 0xeff92cc3U, 0xb45ac175U, 0xd9e276afU, 0x7db087faU, 0x6c36b4d8U, 0xfa7d13e9U, 0xd5e462b7U, 0x6633aaccU, 0xe3ff38dbU, 0xc0605d9dU, 0x4020c080U, 0x10083020U, 0x0b8b1d16U, 0xbc5ed965U, 0x4babdd96U, 0xfe7f1fe1U, 0xf0780dfdU, 0xf87c15edU, 0x582ce8b0U, 0xae57ef41U, 0xb9d2d66fU, 0xa5dcf257U, 0xda6d73a9U, 0xfc7e19e5U, 0x1a0d2e34U, 0xa653f751U, 0x35945f6aU, 0x9bc3b02bU, 0x5028f0a0U, 0x4e27d29cU, 0x0c061418U, 0xbe5fdf61U, 0x47adc98eU, 0xce674f81U, 0xb85cd56dU, 0xaa55e349U, 0x9048ad3dU, 0x1c0e2438U, 0xa452f155U, 0xc9ea468fU, 0x84429115U, 0xb65bc771U, 0xba5dd369U, 0x6030a0c0U, 0xb058cd7dU, 0xa251fb59U, 0xb259cb79U, 0x783c88f0U, 0x9c4eb925U, 0x703890e0U, 0x098a1b12U, 0xe47231d5U, 0x28147850U, 0xd3e768bbU, 0x91c6ae3fU, 0xa1defe5fU, 0xa050fd5dU, 0x018e0302U, 0x39924b72U, 0xbfd1dc63U, 0xee772fc1U, 0x3b934d76U, 0x8a458309U, 0x299a7b52U, 0x81ce9e1fU, 0x5a2deeb4U, 0x06030a0cU, 0xc4625195U, 0x71b693e2U, 0x6fb9b1deU, 0x63bfa5c6U, 0x31965362U, 0xd66b67b1U, 0x7e3f82fcU, 0x0e07121cU, 0x24126c48U, 0x41aec382U, 0x80409d1dU, 0x6834b8d0U, 0x8c468905U, 0x7c3e84f8U, 0xabdbe04bU, 0x83cf981bU, 0xc5ec5297U, 0x85cc9217U, 0x9fc1bc23U, 0x5fa1e1beU, 0x9dc0ba27U, 0xb1d6ce7fU, 0x3a1d4e74U, 0xf5f402f7U, 0xc2615b99U, 0x763b9aecU, 0x20106040U, 0xadd8ea47U, 0xd0686dbdU, 0x5da0e7baU, 0x7fb181feU, 0x140a3c28U, 0xd2696bb9U, 0xd86c75adU, 0x9249ab39U, 0xe9fa26cfU, 0xec7629c5U, 0x95c4a237U, 0x219e6342U, 0x2b9b7d56U, 0xdc6e79a5U, 0x2f99715eU, 0x99c2b62fU, 0x73b795e6U, 0x2d98775aU, 0x65bcafcaU, 0x038f0506U, 0x1785392eU, 0x3e1f427cU, 0x75b49feaU, 0xedf82ac7U, 0x22116644U, 0x5c2ee4b8U, 0x00000000U, 0x4a25de94U, 0x381c4870U, 0x542afca8U, 0x7a3d8ef4U, 0x0a051e14U, 0x9e4fbf21U, 0xf67b07f1U, 0x79b28bf2U, 0x6432acc8U, 0x3d90477aU, 0x43afc586U, 0x32195664U, 0x5ba3edb6U, 0xf3f708fbU, 0xe67337d1U, 0x279d694eU, 0x2a157e54U, 0xe87425cdU, 0xc1ee5e9fU, 0x89ca860fU, 0x239f6546U, 0x1e0f223cU, 0x361b5a6cU, 0xea7523c9U, 0x11863322U, 0x15843f2aU, 0x259c6f4aU, 0x944aa135U, 0x33975566U, 0x341a5c68U, 0xca654389U, 0xf1f60effU, 0xc7ed5493U, 0x12093624U, 0x6bbbbdd6U, 0x4c26d498U, 0x1b832d36U, 0xcbeb408bU, 0xde6f7fa1U, 0x1f81213eU, 0x08041810U, 0xd46a61b5U, 0x86439711U, 0x02010604U, 0x2e17725cU, 0xdfe17ca3U, 0x13873526U, 0xf7f504f3U, 0x078d090eU, 0xdbe370abU, 0x4623ca8cU, 0x1d80273aU, 0x8844850dU, 0x2c167458U, 0xcc664985U, 0x4221c684U, 0xe1fe3edfU, 0xb7d5c473U, 0x6231a6c4U, 0xafd9ec43U, 0x6a35bed4U, 0x30185060U, 0x04020c08U, 0xc864458dU, 0xf9f216efU, 0xfff11ce3U, 0xac56e945U, 0x87cd9413U, 0x19822b32U, 0x8dc88a07U, 0x69babbd2U, 0xfdf01ae7U, 0xc3ef589bU, 0xcfe94c83U, 0xcde84a87U, 0xe7fd34d3U, 0x0f89111eU, 0xb3d7c87bU, 0x93c7a83bU, 0x77b599eeU, 0x55a4ffaaU, 0x5e2fe2bcU, 0x3795596eU, 0x26136a4cU, 0x160b3a2cU, 0xfbf310ebU, 0xdde07aa7U, 0x6e37b2dcU, }; static const ulong32 T2[256] = { 0xa6f5a753U, 0x6bd0d3bbU, 0xbf6ee6d1U, 0xd93b71e2U, 0x67dad0bdU, 0x8acfac45U, 0x29b34d9aU, 0xf90b79f2U, 0xe89c3a74U, 0x038cc98fU, 0x7e41913fU, 0xd732fce5U, 0x78441e3cU, 0x018f478eU, 0x4de554a8U, 0xcea9bd67U, 0x0a0f8c05U, 0xaef9a557U, 0xf5017af4U, 0xcb20fbebU, 0x915763c6U, 0xdab7b86dU, 0x53f4dda7U, 0x77c2d4b5U, 0xb364e5d7U, 0xf68db37bU, 0x33a4c597U, 0xc2a3be61U, 0x9ed1a94fU, 0x1a17880dU, 0x30280c18U, 0xb2eba259U, 0xe4963972U, 0x5bf8dfa3U, 0xa4f62952U, 0x4fe6daa9U, 0xacfa2b56U, 0x9ad7a84dU, 0x0b80cb8bU, 0x2db54c98U, 0x31a74b96U, 0x88cc2244U, 0x92dbaa49U, 0x90d82448U, 0x199b4182U, 0xdd3d70e0U, 0xa2f3a651U, 0xc32cf9efU, 0x75c15ab4U, 0xaf76e2d9U, 0xfa87b07dU, 0xd8b4366cU, 0xe9137dfaU, 0xb762e4d5U, 0xccaa3366U, 0xdb38ffe3U, 0x9d5d60c0U, 0x80c02040U, 0x20300810U, 0x161d8b0bU, 0x65d95ebcU, 0x96ddab4bU, 0xe11f7ffeU, 0xfd0d78f0U, 0xed157cf8U, 0xb0e82c58U, 0x41ef57aeU, 0x6fd6d2b9U, 0x57f2dca5U, 0xa9736ddaU, 0xe5197efcU, 0x342e0d1aU, 0x51f753a6U, 0x6a5f9435U, 0x2bb0c39bU, 0xa0f02850U, 0x9cd2274eU, 0x1814060cU, 0x61df5fbeU, 0x8ec9ad47U, 0x814f67ceU, 0x6dd55cb8U, 0x49e355aaU, 0x3dad4890U, 0x38240e1cU, 0x55f152a4U, 0x8f46eac9U, 0x15914284U, 0x71c75bb6U, 0x69d35dbaU, 0xc0a03060U, 0x7dcd58b0U, 0x59fb51a2U, 0x79cb59b2U, 0xf0883c78U, 0x25b94e9cU, 0xe0903870U, 0x121b8a09U, 0xd53172e4U, 0x50781428U, 0xbb68e7d3U, 0x3faec691U, 0x5ffedea1U, 0x5dfd50a0U, 0x02038e01U, 0x724b9239U, 0x63dcd1bfU, 0xc12f77eeU, 0x764d933bU, 0x0983458aU, 0x527b9a29U, 0x1f9ece81U, 0xb4ee2d5aU, 0x0c0a0306U, 0x955162c4U, 0xe293b671U, 0xdeb1b96fU, 0xc6a5bf63U, 0x62539631U, 0xb1676bd6U, 0xfc823f7eU, 0x1c12070eU, 0x486c1224U, 0x82c3ae41U, 0x1d9d4080U, 0xd0b83468U, 0x0589468cU, 0xf8843e7cU, 0x4be0dbabU, 0x1b98cf83U, 0x9752ecc5U, 0x1792cc85U, 0x23bcc19fU, 0xbee1a15fU, 0x27bac09dU, 0x7fced6b1U, 0x744e1d3aU, 0xf702f4f5U, 0x995b61c2U, 0xec9a3b76U, 0x40601020U, 0x47ead8adU, 0xbd6d68d0U, 0xbae7a05dU, 0xfe81b17fU, 0x283c0a14U, 0xb96b69d2U, 0xad756cd8U, 0x39ab4992U, 0xcf26fae9U, 0xc52976ecU, 0x37a2c495U, 0x42639e21U, 0x567d9b2bU, 0xa5796edcU, 0x5e71992fU, 0x2fb6c299U, 0xe695b773U, 0x5a77982dU, 0xcaafbc65U, 0x06058f03U, 0x2e398517U, 0x7c421f3eU, 0xea9fb475U, 0xc72af8edU, 0x44661122U, 0xb8e42e5cU, 0x00000000U, 0x94de254aU, 0x70481c38U, 0xa8fc2a54U, 0xf48e3d7aU, 0x141e050aU, 0x21bf4f9eU, 0xf1077bf6U, 0xf28bb279U, 0xc8ac3264U, 0x7a47903dU, 0x86c5af43U, 0x64561932U, 0xb6eda35bU, 0xfb08f7f3U, 0xd13773e6U, 0x4e699d27U, 0x547e152aU, 0xcd2574e8U, 0x9f5eeec1U, 0x0f86ca89U, 0x46659f23U, 0x3c220f1eU, 0x6c5a1b36U, 0xc92375eaU, 0x22338611U, 0x2a3f8415U, 0x4a6f9c25U, 0x35a14a94U, 0x66559733U, 0x685c1a34U, 0x894365caU, 0xff0ef6f1U, 0x9354edc7U, 0x24360912U, 0xd6bdbb6bU, 0x98d4264cU, 0x362d831bU, 0x8b40ebcbU, 0xa17f6fdeU, 0x3e21811fU, 0x10180408U, 0xb5616ad4U, 0x11974386U, 0x04060102U, 0x5c72172eU, 0xa37ce1dfU, 0x26358713U, 0xf304f5f7U, 0x0e098d07U, 0xab70e3dbU, 0x8cca2346U, 0x3a27801dU, 0x0d854488U, 0x5874162cU, 0x854966ccU, 0x84c62142U, 0xdf3efee1U, 0x73c4d5b7U, 0xc4a63162U, 0x43ecd9afU, 0xd4be356aU, 0x60501830U, 0x080c0204U, 0x8d4564c8U, 0xef16f2f9U, 0xe31cf1ffU, 0x45e956acU, 0x1394cd87U, 0x322b8219U, 0x078ac88dU, 0xd2bbba69U, 0xe71af0fdU, 0x9b58efc3U, 0x834ce9cfU, 0x874ae8cdU, 0xd334fde7U, 0x1e11890fU, 0x7bc8d7b3U, 0x3ba8c793U, 0xee99b577U, 0xaaffa455U, 0xbce22f5eU, 0x6e599537U, 0x4c6a1326U, 0x2c3a0b16U, 0xeb10f3fbU, 0xa77ae0ddU, 0xdcb2376eU, }; static const ulong32 T3[256] = { 0xf5a653a7U, 0xd06bbbd3U, 0x6ebfd1e6U, 0x3bd9e271U, 0xda67bdd0U, 0xcf8a45acU, 0xb3299a4dU, 0x0bf9f279U, 0x9ce8743aU, 0x8c038fc9U, 0x417e3f91U, 0x32d7e5fcU, 0x44783c1eU, 0x8f018e47U, 0xe54da854U, 0xa9ce67bdU, 0x0f0a058cU, 0xf9ae57a5U, 0x01f5f47aU, 0x20cbebfbU, 0x5791c663U, 0xb7da6db8U, 0xf453a7ddU, 0xc277b5d4U, 0x64b3d7e5U, 0x8df67bb3U, 0xa43397c5U, 0xa3c261beU, 0xd19e4fa9U, 0x171a0d88U, 0x2830180cU, 0xebb259a2U, 0x96e47239U, 0xf85ba3dfU, 0xf6a45229U, 0xe64fa9daU, 0xfaac562bU, 0xd79a4da8U, 0x800b8bcbU, 0xb52d984cU, 0xa731964bU, 0xcc884422U, 0xdb9249aaU, 0xd8904824U, 0x9b198241U, 0x3ddde070U, 0xf3a251a6U, 0x2cc3eff9U, 0xc175b45aU, 0x76afd9e2U, 0x87fa7db0U, 0xb4d86c36U, 0x13e9fa7dU, 0x62b7d5e4U, 0xaacc6633U, 0x38dbe3ffU, 0x5d9dc060U, 0xc0804020U, 0x30201008U, 0x1d160b8bU, 0xd965bc5eU, 0xdd964babU, 0x1fe1fe7fU, 0x0dfdf078U, 0x15edf87cU, 0xe8b0582cU, 0xef41ae57U, 0xd66fb9d2U, 0xf257a5dcU, 0x73a9da6dU, 0x19e5fc7eU, 0x2e341a0dU, 0xf751a653U, 0x5f6a3594U, 0xb02b9bc3U, 0xf0a05028U, 0xd29c4e27U, 0x14180c06U, 0xdf61be5fU, 0xc98e47adU, 0x4f81ce67U, 0xd56db85cU, 0xe349aa55U, 0xad3d9048U, 0x24381c0eU, 0xf155a452U, 0x468fc9eaU, 0x91158442U, 0xc771b65bU, 0xd369ba5dU, 0xa0c06030U, 0xcd7db058U, 0xfb59a251U, 0xcb79b259U, 0x88f0783cU, 0xb9259c4eU, 0x90e07038U, 0x1b12098aU, 0x31d5e472U, 0x78502814U, 0x68bbd3e7U, 0xae3f91c6U, 0xfe5fa1deU, 0xfd5da050U, 0x0302018eU, 0x4b723992U, 0xdc63bfd1U, 0x2fc1ee77U, 0x4d763b93U, 0x83098a45U, 0x7b52299aU, 0x9e1f81ceU, 0xeeb45a2dU, 0x0a0c0603U, 0x5195c462U, 0x93e271b6U, 0xb1de6fb9U, 0xa5c663bfU, 0x53623196U, 0x67b1d66bU, 0x82fc7e3fU, 0x121c0e07U, 0x6c482412U, 0xc38241aeU, 0x9d1d8040U, 0xb8d06834U, 0x89058c46U, 0x84f87c3eU, 0xe04babdbU, 0x981b83cfU, 0x5297c5ecU, 0x921785ccU, 0xbc239fc1U, 0xe1be5fa1U, 0xba279dc0U, 0xce7fb1d6U, 0x4e743a1dU, 0x02f7f5f4U, 0x5b99c261U, 0x9aec763bU, 0x60402010U, 0xea47add8U, 0x6dbdd068U, 0xe7ba5da0U, 0x81fe7fb1U, 0x3c28140aU, 0x6bb9d269U, 0x75add86cU, 0xab399249U, 0x26cfe9faU, 0x29c5ec76U, 0xa23795c4U, 0x6342219eU, 0x7d562b9bU, 0x79a5dc6eU, 0x715e2f99U, 0xb62f99c2U, 0x95e673b7U, 0x775a2d98U, 0xafca65bcU, 0x0506038fU, 0x392e1785U, 0x427c3e1fU, 0x9fea75b4U, 0x2ac7edf8U, 0x66442211U, 0xe4b85c2eU, 0x00000000U, 0xde944a25U, 0x4870381cU, 0xfca8542aU, 0x8ef47a3dU, 0x1e140a05U, 0xbf219e4fU, 0x07f1f67bU, 0x8bf279b2U, 0xacc86432U, 0x477a3d90U, 0xc58643afU, 0x56643219U, 0xedb65ba3U, 0x08fbf3f7U, 0x37d1e673U, 0x694e279dU, 0x7e542a15U, 0x25cde874U, 0x5e9fc1eeU, 0x860f89caU, 0x6546239fU, 0x223c1e0fU, 0x5a6c361bU, 0x23c9ea75U, 0x33221186U, 0x3f2a1584U, 0x6f4a259cU, 0xa135944aU, 0x55663397U, 0x5c68341aU, 0x4389ca65U, 0x0efff1f6U, 0x5493c7edU, 0x36241209U, 0xbdd66bbbU, 0xd4984c26U, 0x2d361b83U, 0x408bcbebU, 0x7fa1de6fU, 0x213e1f81U, 0x18100804U, 0x61b5d46aU, 0x97118643U, 0x06040201U, 0x725c2e17U, 0x7ca3dfe1U, 0x35261387U, 0x04f3f7f5U, 0x090e078dU, 0x70abdbe3U, 0xca8c4623U, 0x273a1d80U, 0x850d8844U, 0x74582c16U, 0x4985cc66U, 0xc6844221U, 0x3edfe1feU, 0xc473b7d5U, 0xa6c46231U, 0xec43afd9U, 0xbed46a35U, 0x50603018U, 0x0c080402U, 0x458dc864U, 0x16eff9f2U, 0x1ce3fff1U, 0xe945ac56U, 0x941387cdU, 0x2b321982U, 0x8a078dc8U, 0xbbd269baU, 0x1ae7fdf0U, 0x589bc3efU, 0x4c83cfe9U, 0x4a87cde8U, 0x34d3e7fdU, 0x111e0f89U, 0xc87bb3d7U, 0xa83b93c7U, 0x99ee77b5U, 0xffaa55a4U, 0xe2bc5e2fU, 0x596e3795U, 0x6a4c2613U, 0x3a2c160bU, 0x10ebfbf3U, 0x7aa7dde0U, 0xb2dc6e37U, }; static const ulong32 T4[256] = { 0xa7a7a7a7U, 0xd3d3d3d3U, 0xe6e6e6e6U, 0x71717171U, 0xd0d0d0d0U, 0xacacacacU, 0x4d4d4d4dU, 0x79797979U, 0x3a3a3a3aU, 0xc9c9c9c9U, 0x91919191U, 0xfcfcfcfcU, 0x1e1e1e1eU, 0x47474747U, 0x54545454U, 0xbdbdbdbdU, 0x8c8c8c8cU, 0xa5a5a5a5U, 0x7a7a7a7aU, 0xfbfbfbfbU, 0x63636363U, 0xb8b8b8b8U, 0xddddddddU, 0xd4d4d4d4U, 0xe5e5e5e5U, 0xb3b3b3b3U, 0xc5c5c5c5U, 0xbebebebeU, 0xa9a9a9a9U, 0x88888888U, 0x0c0c0c0cU, 0xa2a2a2a2U, 0x39393939U, 0xdfdfdfdfU, 0x29292929U, 0xdadadadaU, 0x2b2b2b2bU, 0xa8a8a8a8U, 0xcbcbcbcbU, 0x4c4c4c4cU, 0x4b4b4b4bU, 0x22222222U, 0xaaaaaaaaU, 0x24242424U, 0x41414141U, 0x70707070U, 0xa6a6a6a6U, 0xf9f9f9f9U, 0x5a5a5a5aU, 0xe2e2e2e2U, 0xb0b0b0b0U, 0x36363636U, 0x7d7d7d7dU, 0xe4e4e4e4U, 0x33333333U, 0xffffffffU, 0x60606060U, 0x20202020U, 0x08080808U, 0x8b8b8b8bU, 0x5e5e5e5eU, 0xababababU, 0x7f7f7f7fU, 0x78787878U, 0x7c7c7c7cU, 0x2c2c2c2cU, 0x57575757U, 0xd2d2d2d2U, 0xdcdcdcdcU, 0x6d6d6d6dU, 0x7e7e7e7eU, 0x0d0d0d0dU, 0x53535353U, 0x94949494U, 0xc3c3c3c3U, 0x28282828U, 0x27272727U, 0x06060606U, 0x5f5f5f5fU, 0xadadadadU, 0x67676767U, 0x5c5c5c5cU, 0x55555555U, 0x48484848U, 0x0e0e0e0eU, 0x52525252U, 0xeaeaeaeaU, 0x42424242U, 0x5b5b5b5bU, 0x5d5d5d5dU, 0x30303030U, 0x58585858U, 0x51515151U, 0x59595959U, 0x3c3c3c3cU, 0x4e4e4e4eU, 0x38383838U, 0x8a8a8a8aU, 0x72727272U, 0x14141414U, 0xe7e7e7e7U, 0xc6c6c6c6U, 0xdedededeU, 0x50505050U, 0x8e8e8e8eU, 0x92929292U, 0xd1d1d1d1U, 0x77777777U, 0x93939393U, 0x45454545U, 0x9a9a9a9aU, 0xcecececeU, 0x2d2d2d2dU, 0x03030303U, 0x62626262U, 0xb6b6b6b6U, 0xb9b9b9b9U, 0xbfbfbfbfU, 0x96969696U, 0x6b6b6b6bU, 0x3f3f3f3fU, 0x07070707U, 0x12121212U, 0xaeaeaeaeU, 0x40404040U, 0x34343434U, 0x46464646U, 0x3e3e3e3eU, 0xdbdbdbdbU, 0xcfcfcfcfU, 0xececececU, 0xccccccccU, 0xc1c1c1c1U, 0xa1a1a1a1U, 0xc0c0c0c0U, 0xd6d6d6d6U, 0x1d1d1d1dU, 0xf4f4f4f4U, 0x61616161U, 0x3b3b3b3bU, 0x10101010U, 0xd8d8d8d8U, 0x68686868U, 0xa0a0a0a0U, 0xb1b1b1b1U, 0x0a0a0a0aU, 0x69696969U, 0x6c6c6c6cU, 0x49494949U, 0xfafafafaU, 0x76767676U, 0xc4c4c4c4U, 0x9e9e9e9eU, 0x9b9b9b9bU, 0x6e6e6e6eU, 0x99999999U, 0xc2c2c2c2U, 0xb7b7b7b7U, 0x98989898U, 0xbcbcbcbcU, 0x8f8f8f8fU, 0x85858585U, 0x1f1f1f1fU, 0xb4b4b4b4U, 0xf8f8f8f8U, 0x11111111U, 0x2e2e2e2eU, 0x00000000U, 0x25252525U, 0x1c1c1c1cU, 0x2a2a2a2aU, 0x3d3d3d3dU, 0x05050505U, 0x4f4f4f4fU, 0x7b7b7b7bU, 0xb2b2b2b2U, 0x32323232U, 0x90909090U, 0xafafafafU, 0x19191919U, 0xa3a3a3a3U, 0xf7f7f7f7U, 0x73737373U, 0x9d9d9d9dU, 0x15151515U, 0x74747474U, 0xeeeeeeeeU, 0xcacacacaU, 0x9f9f9f9fU, 0x0f0f0f0fU, 0x1b1b1b1bU, 0x75757575U, 0x86868686U, 0x84848484U, 0x9c9c9c9cU, 0x4a4a4a4aU, 0x97979797U, 0x1a1a1a1aU, 0x65656565U, 0xf6f6f6f6U, 0xededededU, 0x09090909U, 0xbbbbbbbbU, 0x26262626U, 0x83838383U, 0xebebebebU, 0x6f6f6f6fU, 0x81818181U, 0x04040404U, 0x6a6a6a6aU, 0x43434343U, 0x01010101U, 0x17171717U, 0xe1e1e1e1U, 0x87878787U, 0xf5f5f5f5U, 0x8d8d8d8dU, 0xe3e3e3e3U, 0x23232323U, 0x80808080U, 0x44444444U, 0x16161616U, 0x66666666U, 0x21212121U, 0xfefefefeU, 0xd5d5d5d5U, 0x31313131U, 0xd9d9d9d9U, 0x35353535U, 0x18181818U, 0x02020202U, 0x64646464U, 0xf2f2f2f2U, 0xf1f1f1f1U, 0x56565656U, 0xcdcdcdcdU, 0x82828282U, 0xc8c8c8c8U, 0xbabababaU, 0xf0f0f0f0U, 0xefefefefU, 0xe9e9e9e9U, 0xe8e8e8e8U, 0xfdfdfdfdU, 0x89898989U, 0xd7d7d7d7U, 0xc7c7c7c7U, 0xb5b5b5b5U, 0xa4a4a4a4U, 0x2f2f2f2fU, 0x95959595U, 0x13131313U, 0x0b0b0b0bU, 0xf3f3f3f3U, 0xe0e0e0e0U, 0x37373737U, }; static const ulong32 T5[256] = { 0x00000000U, 0x01020608U, 0x02040c10U, 0x03060a18U, 0x04081820U, 0x050a1e28U, 0x060c1430U, 0x070e1238U, 0x08103040U, 0x09123648U, 0x0a143c50U, 0x0b163a58U, 0x0c182860U, 0x0d1a2e68U, 0x0e1c2470U, 0x0f1e2278U, 0x10206080U, 0x11226688U, 0x12246c90U, 0x13266a98U, 0x142878a0U, 0x152a7ea8U, 0x162c74b0U, 0x172e72b8U, 0x183050c0U, 0x193256c8U, 0x1a345cd0U, 0x1b365ad8U, 0x1c3848e0U, 0x1d3a4ee8U, 0x1e3c44f0U, 0x1f3e42f8U, 0x2040c01dU, 0x2142c615U, 0x2244cc0dU, 0x2346ca05U, 0x2448d83dU, 0x254ade35U, 0x264cd42dU, 0x274ed225U, 0x2850f05dU, 0x2952f655U, 0x2a54fc4dU, 0x2b56fa45U, 0x2c58e87dU, 0x2d5aee75U, 0x2e5ce46dU, 0x2f5ee265U, 0x3060a09dU, 0x3162a695U, 0x3264ac8dU, 0x3366aa85U, 0x3468b8bdU, 0x356abeb5U, 0x366cb4adU, 0x376eb2a5U, 0x387090ddU, 0x397296d5U, 0x3a749ccdU, 0x3b769ac5U, 0x3c7888fdU, 0x3d7a8ef5U, 0x3e7c84edU, 0x3f7e82e5U, 0x40809d3aU, 0x41829b32U, 0x4284912aU, 0x43869722U, 0x4488851aU, 0x458a8312U, 0x468c890aU, 0x478e8f02U, 0x4890ad7aU, 0x4992ab72U, 0x4a94a16aU, 0x4b96a762U, 0x4c98b55aU, 0x4d9ab352U, 0x4e9cb94aU, 0x4f9ebf42U, 0x50a0fdbaU, 0x51a2fbb2U, 0x52a4f1aaU, 0x53a6f7a2U, 0x54a8e59aU, 0x55aae392U, 0x56ace98aU, 0x57aeef82U, 0x58b0cdfaU, 0x59b2cbf2U, 0x5ab4c1eaU, 0x5bb6c7e2U, 0x5cb8d5daU, 0x5dbad3d2U, 0x5ebcd9caU, 0x5fbedfc2U, 0x60c05d27U, 0x61c25b2fU, 0x62c45137U, 0x63c6573fU, 0x64c84507U, 0x65ca430fU, 0x66cc4917U, 0x67ce4f1fU, 0x68d06d67U, 0x69d26b6fU, 0x6ad46177U, 0x6bd6677fU, 0x6cd87547U, 0x6dda734fU, 0x6edc7957U, 0x6fde7f5fU, 0x70e03da7U, 0x71e23bafU, 0x72e431b7U, 0x73e637bfU, 0x74e82587U, 0x75ea238fU, 0x76ec2997U, 0x77ee2f9fU, 0x78f00de7U, 0x79f20befU, 0x7af401f7U, 0x7bf607ffU, 0x7cf815c7U, 0x7dfa13cfU, 0x7efc19d7U, 0x7ffe1fdfU, 0x801d2774U, 0x811f217cU, 0x82192b64U, 0x831b2d6cU, 0x84153f54U, 0x8517395cU, 0x86113344U, 0x8713354cU, 0x880d1734U, 0x890f113cU, 0x8a091b24U, 0x8b0b1d2cU, 0x8c050f14U, 0x8d07091cU, 0x8e010304U, 0x8f03050cU, 0x903d47f4U, 0x913f41fcU, 0x92394be4U, 0x933b4decU, 0x94355fd4U, 0x953759dcU, 0x963153c4U, 0x973355ccU, 0x982d77b4U, 0x992f71bcU, 0x9a297ba4U, 0x9b2b7dacU, 0x9c256f94U, 0x9d27699cU, 0x9e216384U, 0x9f23658cU, 0xa05de769U, 0xa15fe161U, 0xa259eb79U, 0xa35bed71U, 0xa455ff49U, 0xa557f941U, 0xa651f359U, 0xa753f551U, 0xa84dd729U, 0xa94fd121U, 0xaa49db39U, 0xab4bdd31U, 0xac45cf09U, 0xad47c901U, 0xae41c319U, 0xaf43c511U, 0xb07d87e9U, 0xb17f81e1U, 0xb2798bf9U, 0xb37b8df1U, 0xb4759fc9U, 0xb57799c1U, 0xb67193d9U, 0xb77395d1U, 0xb86db7a9U, 0xb96fb1a1U, 0xba69bbb9U, 0xbb6bbdb1U, 0xbc65af89U, 0xbd67a981U, 0xbe61a399U, 0xbf63a591U, 0xc09dba4eU, 0xc19fbc46U, 0xc299b65eU, 0xc39bb056U, 0xc495a26eU, 0xc597a466U, 0xc691ae7eU, 0xc793a876U, 0xc88d8a0eU, 0xc98f8c06U, 0xca89861eU, 0xcb8b8016U, 0xcc85922eU, 0xcd879426U, 0xce819e3eU, 0xcf839836U, 0xd0bddaceU, 0xd1bfdcc6U, 0xd2b9d6deU, 0xd3bbd0d6U, 0xd4b5c2eeU, 0xd5b7c4e6U, 0xd6b1cefeU, 0xd7b3c8f6U, 0xd8adea8eU, 0xd9afec86U, 0xdaa9e69eU, 0xdbabe096U, 0xdca5f2aeU, 0xdda7f4a6U, 0xdea1febeU, 0xdfa3f8b6U, 0xe0dd7a53U, 0xe1df7c5bU, 0xe2d97643U, 0xe3db704bU, 0xe4d56273U, 0xe5d7647bU, 0xe6d16e63U, 0xe7d3686bU, 0xe8cd4a13U, 0xe9cf4c1bU, 0xeac94603U, 0xebcb400bU, 0xecc55233U, 0xedc7543bU, 0xeec15e23U, 0xefc3582bU, 0xf0fd1ad3U, 0xf1ff1cdbU, 0xf2f916c3U, 0xf3fb10cbU, 0xf4f502f3U, 0xf5f704fbU, 0xf6f10ee3U, 0xf7f308ebU, 0xf8ed2a93U, 0xf9ef2c9bU, 0xfae92683U, 0xfbeb208bU, 0xfce532b3U, 0xfde734bbU, 0xfee13ea3U, 0xffe338abU, }; /** * The round constants. */ static const ulong32 rc[] = { 0xa7d3e671U, 0xd0ac4d79U, 0x3ac991fcU, 0x1e4754bdU, 0x8ca57afbU, 0x63b8ddd4U, 0xe5b3c5beU, 0xa9880ca2U, 0x39df29daU, 0x2ba8cb4cU, 0x4b22aa24U, 0x4170a6f9U, 0x5ae2b036U, 0x7de433ffU, 0x6020088bU, 0x5eab7f78U, 0x7c2c57d2U, 0xdc6d7e0dU, 0x5394c328U, }; #endif /** Initialize the Anubis block cipher @param key The symmetric key you wish to pass @param keylen The key length in bytes @param num_rounds The number of rounds desired (0 for default) @param skey The key in as scheduled by this function. @return CRYPT_OK if successful */ #ifdef LTC_CLEAN_STACK static int _anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) #else int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) #endif { int N, R, i, pos, r; ulong32 kappa[MAX_N]; ulong32 inter[MAX_N]; ulong32 v, K0, K1, K2, K3; LTC_ARGCHK(key != NULL); LTC_ARGCHK(skey != NULL); /* Valid sizes (in bytes) are 16, 20, 24, 28, 32, 36, and 40. */ if ((keylen & 3) || (keylen < 16) || (keylen > 40)) { return CRYPT_INVALID_KEYSIZE; } skey->anubis.keyBits = keylen*8; /* * determine the N length parameter: * (N.B. it is assumed that the key length is valid!) */ N = skey->anubis.keyBits >> 5; /* * determine number of rounds from key size: */ skey->anubis.R = R = 8 + N; if (num_rounds != 0 && num_rounds != skey->anubis.R) { return CRYPT_INVALID_ROUNDS; } /* * map cipher key to initial key state (mu): */ for (i = 0, pos = 0; i < N; i++, pos += 4) { kappa[i] = (key[pos ] << 24) ^ (key[pos + 1] << 16) ^ (key[pos + 2] << 8) ^ (key[pos + 3] ); } /* * generate R + 1 round keys: */ for (r = 0; r <= R; r++) { /* * generate r-th round key K^r: */ K0 = T4[(kappa[N - 1] >> 24) & 0xff]; K1 = T4[(kappa[N - 1] >> 16) & 0xff]; K2 = T4[(kappa[N - 1] >> 8) & 0xff]; K3 = T4[(kappa[N - 1] ) & 0xff]; for (i = N - 2; i >= 0; i--) { K0 = T4[(kappa[i] >> 24) & 0xff] ^ (T5[(K0 >> 24) & 0xff] & 0xff000000U) ^ (T5[(K0 >> 16) & 0xff] & 0x00ff0000U) ^ (T5[(K0 >> 8) & 0xff] & 0x0000ff00U) ^ (T5[(K0 ) & 0xff] & 0x000000ffU); K1 = T4[(kappa[i] >> 16) & 0xff] ^ (T5[(K1 >> 24) & 0xff] & 0xff000000U) ^ (T5[(K1 >> 16) & 0xff] & 0x00ff0000U) ^ (T5[(K1 >> 8) & 0xff] & 0x0000ff00U) ^ (T5[(K1 ) & 0xff] & 0x000000ffU); K2 = T4[(kappa[i] >> 8) & 0xff] ^ (T5[(K2 >> 24) & 0xff] & 0xff000000U) ^ (T5[(K2 >> 16) & 0xff] & 0x00ff0000U) ^ (T5[(K2 >> 8) & 0xff] & 0x0000ff00U) ^ (T5[(K2 ) & 0xff] & 0x000000ffU); K3 = T4[(kappa[i] ) & 0xff] ^ (T5[(K3 >> 24) & 0xff] & 0xff000000U) ^ (T5[(K3 >> 16) & 0xff] & 0x00ff0000U) ^ (T5[(K3 >> 8) & 0xff] & 0x0000ff00U) ^ (T5[(K3 ) & 0xff] & 0x000000ffU); } /* -- this is the code to use with the large U tables: K0 = K1 = K2 = K3 = 0; for (i = 0; i < N; i++) { K0 ^= U[i][(kappa[i] >> 24) & 0xff]; K1 ^= U[i][(kappa[i] >> 16) & 0xff]; K2 ^= U[i][(kappa[i] >> 8) & 0xff]; K3 ^= U[i][(kappa[i] ) & 0xff]; } */ skey->anubis.roundKeyEnc[r][0] = K0; skey->anubis.roundKeyEnc[r][1] = K1; skey->anubis.roundKeyEnc[r][2] = K2; skey->anubis.roundKeyEnc[r][3] = K3; /* * compute kappa^{r+1} from kappa^r: */ if (r == R) { break; } for (i = 0; i < N; i++) { int j = i; inter[i] = T0[(kappa[j--] >> 24) & 0xff]; if (j < 0) j = N - 1; inter[i] ^= T1[(kappa[j--] >> 16) & 0xff]; if (j < 0) j = N - 1; inter[i] ^= T2[(kappa[j--] >> 8) & 0xff]; if (j < 0) j = N - 1; inter[i] ^= T3[(kappa[j ] ) & 0xff]; } kappa[0] = inter[0] ^ rc[r]; for (i = 1; i < N; i++) { kappa[i] = inter[i]; } } /* * generate inverse key schedule: K'^0 = K^R, K'^R = K^0, K'^r = theta(K^{R-r}): */ for (i = 0; i < 4; i++) { skey->anubis.roundKeyDec[0][i] = skey->anubis.roundKeyEnc[R][i]; skey->anubis.roundKeyDec[R][i] = skey->anubis.roundKeyEnc[0][i]; } for (r = 1; r < R; r++) { for (i = 0; i < 4; i++) { v = skey->anubis.roundKeyEnc[R - r][i]; skey->anubis.roundKeyDec[r][i] = T0[T4[(v >> 24) & 0xff] & 0xff] ^ T1[T4[(v >> 16) & 0xff] & 0xff] ^ T2[T4[(v >> 8) & 0xff] & 0xff] ^ T3[T4[(v ) & 0xff] & 0xff]; } } return CRYPT_OK; } #ifdef LTC_CLEAN_STACK int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) { int err; err = _anubis_setup(key, keylen, num_rounds, skey); burn_stack(sizeof(int) * 5 + sizeof(ulong32) * (MAX_N + MAX_N + 5)); return err; } #endif static void anubis_crypt(const unsigned char *plaintext, unsigned char *ciphertext, ulong32 roundKey[18 + 1][4], int R) { int i, pos, r; ulong32 state[4]; ulong32 inter[4]; /* * map plaintext block to cipher state (mu) * and add initial round key (sigma[K^0]): */ for (i = 0, pos = 0; i < 4; i++, pos += 4) { state[i] = (plaintext[pos ] << 24) ^ (plaintext[pos + 1] << 16) ^ (plaintext[pos + 2] << 8) ^ (plaintext[pos + 3] ) ^ roundKey[0][i]; } /* * R - 1 full rounds: */ for (r = 1; r < R; r++) { inter[0] = T0[(state[0] >> 24) & 0xff] ^ T1[(state[1] >> 24) & 0xff] ^ T2[(state[2] >> 24) & 0xff] ^ T3[(state[3] >> 24) & 0xff] ^ roundKey[r][0]; inter[1] = T0[(state[0] >> 16) & 0xff] ^ T1[(state[1] >> 16) & 0xff] ^ T2[(state[2] >> 16) & 0xff] ^ T3[(state[3] >> 16) & 0xff] ^ roundKey[r][1]; inter[2] = T0[(state[0] >> 8) & 0xff] ^ T1[(state[1] >> 8) & 0xff] ^ T2[(state[2] >> 8) & 0xff] ^ T3[(state[3] >> 8) & 0xff] ^ roundKey[r][2]; inter[3] = T0[(state[0] ) & 0xff] ^ T1[(state[1] ) & 0xff] ^ T2[(state[2] ) & 0xff] ^ T3[(state[3] ) & 0xff] ^ roundKey[r][3]; state[0] = inter[0]; state[1] = inter[1]; state[2] = inter[2]; state[3] = inter[3]; } /* * last round: */ inter[0] = (T0[(state[0] >> 24) & 0xff] & 0xff000000U) ^ (T1[(state[1] >> 24) & 0xff] & 0x00ff0000U) ^ (T2[(state[2] >> 24) & 0xff] & 0x0000ff00U) ^ (T3[(state[3] >> 24) & 0xff] & 0x000000ffU) ^ roundKey[R][0]; inter[1] = (T0[(state[0] >> 16) & 0xff] & 0xff000000U) ^ (T1[(state[1] >> 16) & 0xff] & 0x00ff0000U) ^ (T2[(state[2] >> 16) & 0xff] & 0x0000ff00U) ^ (T3[(state[3] >> 16) & 0xff] & 0x000000ffU) ^ roundKey[R][1]; inter[2] = (T0[(state[0] >> 8) & 0xff] & 0xff000000U) ^ (T1[(state[1] >> 8) & 0xff] & 0x00ff0000U) ^ (T2[(state[2] >> 8) & 0xff] & 0x0000ff00U) ^ (T3[(state[3] >> 8) & 0xff] & 0x000000ffU) ^ roundKey[R][2]; inter[3] = (T0[(state[0] ) & 0xff] & 0xff000000U) ^ (T1[(state[1] ) & 0xff] & 0x00ff0000U) ^ (T2[(state[2] ) & 0xff] & 0x0000ff00U) ^ (T3[(state[3] ) & 0xff] & 0x000000ffU) ^ roundKey[R][3]; /* * map cipher state to ciphertext block (mu^{-1}): */ for (i = 0, pos = 0; i < 4; i++, pos += 4) { ulong32 w = inter[i]; ciphertext[pos ] = (unsigned char)(w >> 24); ciphertext[pos + 1] = (unsigned char)(w >> 16); ciphertext[pos + 2] = (unsigned char)(w >> 8); ciphertext[pos + 3] = (unsigned char)(w ); } } /** Encrypts a block of text with Anubis @param pt The input plaintext (16 bytes) @param ct The output ciphertext (16 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ int anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) { LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); anubis_crypt(pt, ct, skey->anubis.roundKeyEnc, skey->anubis.R); return CRYPT_OK; } /** Decrypts a block of text with Anubis @param ct The input ciphertext (16 bytes) @param pt The output plaintext (16 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) { LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); anubis_crypt(ct, pt, skey->anubis.roundKeyDec, skey->anubis.R); return CRYPT_OK; } /** Performs a self-test of the Anubis block cipher @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled */ int anubis_test(void) { #if !defined(LTC_TEST) return CRYPT_NOP; #else static const struct test { int keylen; unsigned char pt[16], ct[16], key[40]; } tests[] = { #ifndef LTC_ANUBIS_TWEAK /**** ORIGINAL LTC_ANUBIS ****/ /* 128 bit keys */ { 16, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0xF0, 0x68, 0x60, 0xFC, 0x67, 0x30, 0xE8, 0x18, 0xF1, 0x32, 0xC7, 0x8A, 0xF4, 0x13, 0x2A, 0xFE }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 16, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0xA8, 0x66, 0x84, 0x80, 0x07, 0x74, 0x5C, 0x89, 0xFC, 0x5E, 0xB5, 0xBA, 0xD4, 0xFE, 0x32, 0x6D }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* 160-bit keys */ { 20, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0xBD, 0x5E, 0x32, 0xBE, 0x51, 0x67, 0xA8, 0xE2, 0x72, 0xD7, 0x95, 0x0F, 0x83, 0xC6, 0x8C, 0x31 }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 20, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x4C, 0x1F, 0x86, 0x2E, 0x11, 0xEB, 0xCE, 0xEB, 0xFE, 0xB9, 0x73, 0xC9, 0xDF, 0xEF, 0x7A, 0xDB }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* 192-bit keys */ { 24, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x17, 0xAC, 0x57, 0x44, 0x9D, 0x59, 0x61, 0x66, 0xD0, 0xC7, 0x9E, 0x04, 0x7C, 0xC7, 0x58, 0xF0 }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 24, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x71, 0x52, 0xB4, 0xEB, 0x1D, 0xAA, 0x36, 0xFD, 0x57, 0x14, 0x5F, 0x57, 0x04, 0x9F, 0x70, 0x74 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* 224-bit keys */ { 28, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0xA2, 0xF0, 0xA6, 0xB9, 0x17, 0x93, 0x2A, 0x3B, 0xEF, 0x08, 0xE8, 0x7A, 0x58, 0xD6, 0xF8, 0x53 }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 28, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0xF0, 0xCA, 0xFC, 0x78, 0x8B, 0x4B, 0x4E, 0x53, 0x8B, 0xC4, 0x32, 0x6A, 0xF5, 0xB9, 0x1B, 0x5F }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* 256-bit keys */ { 32, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0xE0, 0x86, 0xAC, 0x45, 0x6B, 0x3C, 0xE5, 0x13, 0xED, 0xF5, 0xDF, 0xDD, 0xD6, 0x3B, 0x71, 0x93 }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 32, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x50, 0x01, 0xB9, 0xF5, 0x21, 0xC1, 0xC1, 0x29, 0x00, 0xD5, 0xEC, 0x98, 0x2B, 0x9E, 0xE8, 0x21 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* 288-bit keys */ { 36, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0xE8, 0xF4, 0xAF, 0x2B, 0x21, 0xA0, 0x87, 0x9B, 0x41, 0x95, 0xB9, 0x71, 0x75, 0x79, 0x04, 0x7C }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 36, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0xE6, 0xA6, 0xA5, 0xBC, 0x8B, 0x63, 0x6F, 0xE2, 0xBD, 0xA7, 0xA7, 0x53, 0xAB, 0x40, 0x22, 0xE0 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* 320-bit keys */ { 40, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x17, 0x04, 0xD7, 0x2C, 0xC6, 0x85, 0x76, 0x02, 0x4B, 0xCC, 0x39, 0x80, 0xD8, 0x22, 0xEA, 0xA4 }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 40, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x7A, 0x41, 0xE6, 0x7D, 0x4F, 0xD8, 0x64, 0xF0, 0x44, 0xA8, 0x3C, 0x73, 0x81, 0x7E, 0x53, 0xD8 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } #else /**** Tweaked LTC_ANUBIS ****/ /* 128 bit keys */ { 16, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0xB8, 0x35, 0xBD, 0xC3, 0x34, 0x82, 0x9D, 0x83, 0x71, 0xBF, 0xA3, 0x71, 0xE4, 0xB3, 0xC4, 0xFD }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 16, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0xE6, 0x14, 0x1E, 0xAF, 0xEB, 0xE0, 0x59, 0x3C, 0x48, 0xE1, 0xCD, 0xF2, 0x1B, 0xBA, 0xA1, 0x89 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* 160-bit keys */ { 20, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x97, 0x59, 0x79, 0x4B, 0x5C, 0xA0, 0x70, 0x73, 0x24, 0xEF, 0xB3, 0x58, 0x67, 0xCA, 0xD4, 0xB3 }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 20, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0xB8, 0x0D, 0xFB, 0x9B, 0xE4, 0xA1, 0x58, 0x87, 0xB3, 0x76, 0xD5, 0x02, 0x18, 0x95, 0xC1, 0x2E }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* 192-bit keys */ { 24, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x7D, 0x62, 0x3B, 0x52, 0xC7, 0x4C, 0x64, 0xD8, 0xEB, 0xC7, 0x2D, 0x57, 0x97, 0x85, 0x43, 0x8F }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 24, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0xB1, 0x0A, 0x59, 0xDD, 0x5D, 0x5D, 0x8D, 0x67, 0xEC, 0xEE, 0x4A, 0xC4, 0xBE, 0x4F, 0xA8, 0x4F }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* 224-bit keys */ { 28, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x68, 0x9E, 0x05, 0x94, 0x6A, 0x94, 0x43, 0x8F, 0xE7, 0x8E, 0x37, 0x3D, 0x24, 0x97, 0x92, 0xF5 }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 28, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0xDD, 0xB7, 0xB0, 0xB4, 0xE9, 0xB4, 0x9B, 0x9C, 0x38, 0x20, 0x25, 0x0B, 0x47, 0xC2, 0x1F, 0x89 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* 256-bit keys */ { 32, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x96, 0x00, 0xF0, 0x76, 0x91, 0x69, 0x29, 0x87, 0xF5, 0xE5, 0x97, 0xDB, 0xDB, 0xAF, 0x1B, 0x0A }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 32, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x69, 0x9C, 0xAF, 0xDD, 0x94, 0xC7, 0xBC, 0x60, 0x44, 0xFE, 0x02, 0x05, 0x8A, 0x6E, 0xEF, 0xBD }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* 288-bit keys */ { 36, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x0F, 0xC7, 0xA2, 0xC0, 0x11, 0x17, 0xAC, 0x43, 0x52, 0x5E, 0xDF, 0x6C, 0xF3, 0x96, 0x33, 0x6C }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 36, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0xAD, 0x08, 0x4F, 0xED, 0x55, 0xA6, 0x94, 0x3E, 0x7E, 0x5E, 0xED, 0x05, 0xA1, 0x9D, 0x41, 0xB4 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }, /* 320-bit keys */ { 40, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0xFE, 0xE2, 0x0E, 0x2A, 0x9D, 0xC5, 0x83, 0xBA, 0xA3, 0xA6, 0xD6, 0xA6, 0xF2, 0xE8, 0x06, 0xA5 }, { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, { 40, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x86, 0x3D, 0xCC, 0x4A, 0x60, 0x34, 0x9C, 0x28, 0xA7, 0xDA, 0xA4, 0x3B, 0x0A, 0xD7, 0xFD, 0xC7 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } #endif }; int x, y; unsigned char buf[2][16]; symmetric_key skey; for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { anubis_setup(tests[x].key, tests[x].keylen, 0, &skey); anubis_ecb_encrypt(tests[x].pt, buf[0], &skey); anubis_ecb_decrypt(buf[0], buf[1], &skey); if (XMEMCMP(buf[0], tests[x].ct, 16) || XMEMCMP(buf[1], tests[x].pt, 16)) { return CRYPT_FAIL_TESTVECTOR; } for (y = 0; y < 1000; y++) anubis_ecb_encrypt(buf[0], buf[0], &skey); for (y = 0; y < 1000; y++) anubis_ecb_decrypt(buf[0], buf[0], &skey); if (XMEMCMP(buf[0], tests[x].ct, 16)) { return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } /** Terminate the context @param skey The scheduled key */ void anubis_done(symmetric_key *skey) { } /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. @return CRYPT_OK if the input key size is acceptable. */ int anubis_keysize(int *keysize) { LTC_ARGCHK(keysize != NULL); if (*keysize >= 40) { *keysize = 40; } else if (*keysize >= 36) { *keysize = 36; } else if (*keysize >= 32) { *keysize = 32; } else if (*keysize >= 28) { *keysize = 28; } else if (*keysize >= 24) { *keysize = 24; } else if (*keysize >= 20) { *keysize = 20; } else if (*keysize >= 16) { *keysize = 16; } else { return CRYPT_INVALID_KEYSIZE; } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/anubis.c,v $ */ /* $Revision: 1.17 $ */ /* $Date: 2007/05/12 14:21:44 $ */ libtomcrypt-1.17/src/ciphers/noekeon.c0000644000175100001440000002000310621351501016544 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file noekeon.c Implementation of the Noekeon block cipher by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_NOEKEON const struct ltc_cipher_descriptor noekeon_desc = { "noekeon", 16, 16, 16, 16, 16, &noekeon_setup, &noekeon_ecb_encrypt, &noekeon_ecb_decrypt, &noekeon_test, &noekeon_done, &noekeon_keysize, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static const ulong32 RC[] = { 0x00000080UL, 0x0000001bUL, 0x00000036UL, 0x0000006cUL, 0x000000d8UL, 0x000000abUL, 0x0000004dUL, 0x0000009aUL, 0x0000002fUL, 0x0000005eUL, 0x000000bcUL, 0x00000063UL, 0x000000c6UL, 0x00000097UL, 0x00000035UL, 0x0000006aUL, 0x000000d4UL }; #define kTHETA(a, b, c, d) \ temp = a^c; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \ b ^= temp; d ^= temp; \ temp = b^d; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \ a ^= temp; c ^= temp; #define THETA(k, a, b, c, d) \ temp = a^c; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \ b ^= temp ^ k[1]; d ^= temp ^ k[3]; \ temp = b^d; temp = temp ^ ROLc(temp, 8) ^ RORc(temp, 8); \ a ^= temp ^ k[0]; c ^= temp ^ k[2]; #define GAMMA(a, b, c, d) \ b ^= ~(d|c); \ a ^= c&b; \ temp = d; d = a; a = temp;\ c ^= a ^ b ^ d; \ b ^= ~(d|c); \ a ^= c&b; #define PI1(a, b, c, d) \ a = ROLc(a, 1); c = ROLc(c, 5); d = ROLc(d, 2); #define PI2(a, b, c, d) \ a = RORc(a, 1); c = RORc(c, 5); d = RORc(d, 2); /** Initialize the Noekeon block cipher @param key The symmetric key you wish to pass @param keylen The key length in bytes @param num_rounds The number of rounds desired (0 for default) @param skey The key in as scheduled by this function. @return CRYPT_OK if successful */ int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) { ulong32 temp; LTC_ARGCHK(key != NULL); LTC_ARGCHK(skey != NULL); if (keylen != 16) { return CRYPT_INVALID_KEYSIZE; } if (num_rounds != 16 && num_rounds != 0) { return CRYPT_INVALID_ROUNDS; } LOAD32H(skey->noekeon.K[0],&key[0]); LOAD32H(skey->noekeon.K[1],&key[4]); LOAD32H(skey->noekeon.K[2],&key[8]); LOAD32H(skey->noekeon.K[3],&key[12]); LOAD32H(skey->noekeon.dK[0],&key[0]); LOAD32H(skey->noekeon.dK[1],&key[4]); LOAD32H(skey->noekeon.dK[2],&key[8]); LOAD32H(skey->noekeon.dK[3],&key[12]); kTHETA(skey->noekeon.dK[0], skey->noekeon.dK[1], skey->noekeon.dK[2], skey->noekeon.dK[3]); return CRYPT_OK; } /** Encrypts a block of text with Noekeon @param pt The input plaintext (16 bytes) @param ct The output ciphertext (16 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ #ifdef LTC_CLEAN_STACK static int _noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) #else int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) #endif { ulong32 a,b,c,d,temp; int r; LTC_ARGCHK(skey != NULL); LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LOAD32H(a,&pt[0]); LOAD32H(b,&pt[4]); LOAD32H(c,&pt[8]); LOAD32H(d,&pt[12]); #define ROUND(i) \ a ^= RC[i]; \ THETA(skey->noekeon.K, a,b,c,d); \ PI1(a,b,c,d); \ GAMMA(a,b,c,d); \ PI2(a,b,c,d); for (r = 0; r < 16; ++r) { ROUND(r); } #undef ROUND a ^= RC[16]; THETA(skey->noekeon.K, a, b, c, d); STORE32H(a,&ct[0]); STORE32H(b,&ct[4]); STORE32H(c,&ct[8]); STORE32H(d,&ct[12]); return CRYPT_OK; } #ifdef LTC_CLEAN_STACK int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) { int err = _noekeon_ecb_encrypt(pt, ct, skey); burn_stack(sizeof(ulong32) * 5 + sizeof(int)); return CRYPT_OK; } #endif /** Decrypts a block of text with Noekeon @param ct The input ciphertext (16 bytes) @param pt The output plaintext (16 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ #ifdef LTC_CLEAN_STACK static int _noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) #else int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) #endif { ulong32 a,b,c,d, temp; int r; LTC_ARGCHK(skey != NULL); LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LOAD32H(a,&ct[0]); LOAD32H(b,&ct[4]); LOAD32H(c,&ct[8]); LOAD32H(d,&ct[12]); #define ROUND(i) \ THETA(skey->noekeon.dK, a,b,c,d); \ a ^= RC[i]; \ PI1(a,b,c,d); \ GAMMA(a,b,c,d); \ PI2(a,b,c,d); for (r = 16; r > 0; --r) { ROUND(r); } #undef ROUND THETA(skey->noekeon.dK, a,b,c,d); a ^= RC[0]; STORE32H(a,&pt[0]); STORE32H(b, &pt[4]); STORE32H(c,&pt[8]); STORE32H(d, &pt[12]); return CRYPT_OK; } #ifdef LTC_CLEAN_STACK int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) { int err = _noekeon_ecb_decrypt(ct, pt, skey); burn_stack(sizeof(ulong32) * 5 + sizeof(int)); return err; } #endif /** Performs a self-test of the Noekeon block cipher @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled */ int noekeon_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { int keylen; unsigned char key[16], pt[16], ct[16]; } tests[] = { { 16, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, { 0x18, 0xa6, 0xec, 0xe5, 0x28, 0xaa, 0x79, 0x73, 0x28, 0xb2, 0xc0, 0x91, 0xa0, 0x2f, 0x54, 0xc5} } }; symmetric_key key; unsigned char tmp[2][16]; int err, i, y; for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { zeromem(&key, sizeof(key)); if ((err = noekeon_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { return err; } noekeon_ecb_encrypt(tests[i].pt, tmp[0], &key); noekeon_ecb_decrypt(tmp[0], tmp[1], &key); if (XMEMCMP(tmp[0], tests[i].ct, 16) || XMEMCMP(tmp[1], tests[i].pt, 16)) { #if 0 printf("\n\nTest %d failed\n", i); if (XMEMCMP(tmp[0], tests[i].ct, 16)) { printf("CT: "); for (i = 0; i < 16; i++) { printf("%02x ", tmp[0][i]); } printf("\n"); } else { printf("PT: "); for (i = 0; i < 16; i++) { printf("%02x ", tmp[1][i]); } printf("\n"); } #endif return CRYPT_FAIL_TESTVECTOR; } /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ for (y = 0; y < 16; y++) tmp[0][y] = 0; for (y = 0; y < 1000; y++) noekeon_ecb_encrypt(tmp[0], tmp[0], &key); for (y = 0; y < 1000; y++) noekeon_ecb_decrypt(tmp[0], tmp[0], &key); for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; } return CRYPT_OK; #endif } /** Terminate the context @param skey The scheduled key */ void noekeon_done(symmetric_key *skey) { } /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. @return CRYPT_OK if the input key size is acceptable. */ int noekeon_keysize(int *keysize) { LTC_ARGCHK(keysize != NULL); if (*keysize < 16) { return CRYPT_INVALID_KEYSIZE; } else { *keysize = 16; return CRYPT_OK; } } #endif /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/noekeon.c,v $ */ /* $Revision: 1.14 $ */ /* $Date: 2007/05/12 14:20:27 $ */ libtomcrypt-1.17/src/ciphers/kseed.c0000644000175100001440000004646410621351501016224 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file kseed.c seed implementation of SEED derived from RFC4269 Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_KSEED const struct ltc_cipher_descriptor kseed_desc = { "seed", 20, 16, 16, 16, 16, &kseed_setup, &kseed_ecb_encrypt, &kseed_ecb_decrypt, &kseed_test, &kseed_done, &kseed_keysize, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static const ulong32 SS0[256] = { 0x2989A1A8UL,0x05858184UL,0x16C6D2D4UL,0x13C3D3D0UL,0x14445054UL,0x1D0D111CUL,0x2C8CA0ACUL,0x25052124UL, 0x1D4D515CUL,0x03434340UL,0x18081018UL,0x1E0E121CUL,0x11415150UL,0x3CCCF0FCUL,0x0ACAC2C8UL,0x23436360UL, 0x28082028UL,0x04444044UL,0x20002020UL,0x1D8D919CUL,0x20C0E0E0UL,0x22C2E2E0UL,0x08C8C0C8UL,0x17071314UL, 0x2585A1A4UL,0x0F8F838CUL,0x03030300UL,0x3B4B7378UL,0x3B8BB3B8UL,0x13031310UL,0x12C2D2D0UL,0x2ECEE2ECUL, 0x30407070UL,0x0C8C808CUL,0x3F0F333CUL,0x2888A0A8UL,0x32023230UL,0x1DCDD1DCUL,0x36C6F2F4UL,0x34447074UL, 0x2CCCE0ECUL,0x15859194UL,0x0B0B0308UL,0x17475354UL,0x1C4C505CUL,0x1B4B5358UL,0x3D8DB1BCUL,0x01010100UL, 0x24042024UL,0x1C0C101CUL,0x33437370UL,0x18889098UL,0x10001010UL,0x0CCCC0CCUL,0x32C2F2F0UL,0x19C9D1D8UL, 0x2C0C202CUL,0x27C7E3E4UL,0x32427270UL,0x03838380UL,0x1B8B9398UL,0x11C1D1D0UL,0x06868284UL,0x09C9C1C8UL, 0x20406060UL,0x10405050UL,0x2383A3A0UL,0x2BCBE3E8UL,0x0D0D010CUL,0x3686B2B4UL,0x1E8E929CUL,0x0F4F434CUL, 0x3787B3B4UL,0x1A4A5258UL,0x06C6C2C4UL,0x38487078UL,0x2686A2A4UL,0x12021210UL,0x2F8FA3ACUL,0x15C5D1D4UL, 0x21416160UL,0x03C3C3C0UL,0x3484B0B4UL,0x01414140UL,0x12425250UL,0x3D4D717CUL,0x0D8D818CUL,0x08080008UL, 0x1F0F131CUL,0x19899198UL,0x00000000UL,0x19091118UL,0x04040004UL,0x13435350UL,0x37C7F3F4UL,0x21C1E1E0UL, 0x3DCDF1FCUL,0x36467274UL,0x2F0F232CUL,0x27072324UL,0x3080B0B0UL,0x0B8B8388UL,0x0E0E020CUL,0x2B8BA3A8UL, 0x2282A2A0UL,0x2E4E626CUL,0x13839390UL,0x0D4D414CUL,0x29496168UL,0x3C4C707CUL,0x09090108UL,0x0A0A0208UL, 0x3F8FB3BCUL,0x2FCFE3ECUL,0x33C3F3F0UL,0x05C5C1C4UL,0x07878384UL,0x14041014UL,0x3ECEF2FCUL,0x24446064UL, 0x1ECED2DCUL,0x2E0E222CUL,0x0B4B4348UL,0x1A0A1218UL,0x06060204UL,0x21012120UL,0x2B4B6368UL,0x26466264UL, 0x02020200UL,0x35C5F1F4UL,0x12829290UL,0x0A8A8288UL,0x0C0C000CUL,0x3383B3B0UL,0x3E4E727CUL,0x10C0D0D0UL, 0x3A4A7278UL,0x07474344UL,0x16869294UL,0x25C5E1E4UL,0x26062224UL,0x00808080UL,0x2D8DA1ACUL,0x1FCFD3DCUL, 0x2181A1A0UL,0x30003030UL,0x37073334UL,0x2E8EA2ACUL,0x36063234UL,0x15051114UL,0x22022220UL,0x38083038UL, 0x34C4F0F4UL,0x2787A3A4UL,0x05454144UL,0x0C4C404CUL,0x01818180UL,0x29C9E1E8UL,0x04848084UL,0x17879394UL, 0x35053134UL,0x0BCBC3C8UL,0x0ECEC2CCUL,0x3C0C303CUL,0x31417170UL,0x11011110UL,0x07C7C3C4UL,0x09898188UL, 0x35457174UL,0x3BCBF3F8UL,0x1ACAD2D8UL,0x38C8F0F8UL,0x14849094UL,0x19495158UL,0x02828280UL,0x04C4C0C4UL, 0x3FCFF3FCUL,0x09494148UL,0x39093138UL,0x27476364UL,0x00C0C0C0UL,0x0FCFC3CCUL,0x17C7D3D4UL,0x3888B0B8UL, 0x0F0F030CUL,0x0E8E828CUL,0x02424240UL,0x23032320UL,0x11819190UL,0x2C4C606CUL,0x1BCBD3D8UL,0x2484A0A4UL, 0x34043034UL,0x31C1F1F0UL,0x08484048UL,0x02C2C2C0UL,0x2F4F636CUL,0x3D0D313CUL,0x2D0D212CUL,0x00404040UL, 0x3E8EB2BCUL,0x3E0E323CUL,0x3C8CB0BCUL,0x01C1C1C0UL,0x2A8AA2A8UL,0x3A8AB2B8UL,0x0E4E424CUL,0x15455154UL, 0x3B0B3338UL,0x1CCCD0DCUL,0x28486068UL,0x3F4F737CUL,0x1C8C909CUL,0x18C8D0D8UL,0x0A4A4248UL,0x16465254UL, 0x37477374UL,0x2080A0A0UL,0x2DCDE1ECUL,0x06464244UL,0x3585B1B4UL,0x2B0B2328UL,0x25456164UL,0x3ACAF2F8UL, 0x23C3E3E0UL,0x3989B1B8UL,0x3181B1B0UL,0x1F8F939CUL,0x1E4E525CUL,0x39C9F1F8UL,0x26C6E2E4UL,0x3282B2B0UL, 0x31013130UL,0x2ACAE2E8UL,0x2D4D616CUL,0x1F4F535CUL,0x24C4E0E4UL,0x30C0F0F0UL,0x0DCDC1CCUL,0x08888088UL, 0x16061214UL,0x3A0A3238UL,0x18485058UL,0x14C4D0D4UL,0x22426260UL,0x29092128UL,0x07070304UL,0x33033330UL, 0x28C8E0E8UL,0x1B0B1318UL,0x05050104UL,0x39497178UL,0x10809090UL,0x2A4A6268UL,0x2A0A2228UL,0x1A8A9298UL }; static const ulong32 SS1[256] = { 0x38380830UL,0xE828C8E0UL,0x2C2D0D21UL,0xA42686A2UL,0xCC0FCFC3UL,0xDC1ECED2UL,0xB03383B3UL,0xB83888B0UL, 0xAC2F8FA3UL,0x60204060UL,0x54154551UL,0xC407C7C3UL,0x44044440UL,0x6C2F4F63UL,0x682B4B63UL,0x581B4B53UL, 0xC003C3C3UL,0x60224262UL,0x30330333UL,0xB43585B1UL,0x28290921UL,0xA02080A0UL,0xE022C2E2UL,0xA42787A3UL, 0xD013C3D3UL,0x90118191UL,0x10110111UL,0x04060602UL,0x1C1C0C10UL,0xBC3C8CB0UL,0x34360632UL,0x480B4B43UL, 0xEC2FCFE3UL,0x88088880UL,0x6C2C4C60UL,0xA82888A0UL,0x14170713UL,0xC404C4C0UL,0x14160612UL,0xF434C4F0UL, 0xC002C2C2UL,0x44054541UL,0xE021C1E1UL,0xD416C6D2UL,0x3C3F0F33UL,0x3C3D0D31UL,0x8C0E8E82UL,0x98188890UL, 0x28280820UL,0x4C0E4E42UL,0xF436C6F2UL,0x3C3E0E32UL,0xA42585A1UL,0xF839C9F1UL,0x0C0D0D01UL,0xDC1FCFD3UL, 0xD818C8D0UL,0x282B0B23UL,0x64264662UL,0x783A4A72UL,0x24270723UL,0x2C2F0F23UL,0xF031C1F1UL,0x70324272UL, 0x40024242UL,0xD414C4D0UL,0x40014141UL,0xC000C0C0UL,0x70334373UL,0x64274763UL,0xAC2C8CA0UL,0x880B8B83UL, 0xF437C7F3UL,0xAC2D8DA1UL,0x80008080UL,0x1C1F0F13UL,0xC80ACAC2UL,0x2C2C0C20UL,0xA82A8AA2UL,0x34340430UL, 0xD012C2D2UL,0x080B0B03UL,0xEC2ECEE2UL,0xE829C9E1UL,0x5C1D4D51UL,0x94148490UL,0x18180810UL,0xF838C8F0UL, 0x54174753UL,0xAC2E8EA2UL,0x08080800UL,0xC405C5C1UL,0x10130313UL,0xCC0DCDC1UL,0x84068682UL,0xB83989B1UL, 0xFC3FCFF3UL,0x7C3D4D71UL,0xC001C1C1UL,0x30310131UL,0xF435C5F1UL,0x880A8A82UL,0x682A4A62UL,0xB03181B1UL, 0xD011C1D1UL,0x20200020UL,0xD417C7D3UL,0x00020202UL,0x20220222UL,0x04040400UL,0x68284860UL,0x70314171UL, 0x04070703UL,0xD81BCBD3UL,0x9C1D8D91UL,0x98198991UL,0x60214161UL,0xBC3E8EB2UL,0xE426C6E2UL,0x58194951UL, 0xDC1DCDD1UL,0x50114151UL,0x90108090UL,0xDC1CCCD0UL,0x981A8A92UL,0xA02383A3UL,0xA82B8BA3UL,0xD010C0D0UL, 0x80018181UL,0x0C0F0F03UL,0x44074743UL,0x181A0A12UL,0xE023C3E3UL,0xEC2CCCE0UL,0x8C0D8D81UL,0xBC3F8FB3UL, 0x94168692UL,0x783B4B73UL,0x5C1C4C50UL,0xA02282A2UL,0xA02181A1UL,0x60234363UL,0x20230323UL,0x4C0D4D41UL, 0xC808C8C0UL,0x9C1E8E92UL,0x9C1C8C90UL,0x383A0A32UL,0x0C0C0C00UL,0x2C2E0E22UL,0xB83A8AB2UL,0x6C2E4E62UL, 0x9C1F8F93UL,0x581A4A52UL,0xF032C2F2UL,0x90128292UL,0xF033C3F3UL,0x48094941UL,0x78384870UL,0xCC0CCCC0UL, 0x14150511UL,0xF83BCBF3UL,0x70304070UL,0x74354571UL,0x7C3F4F73UL,0x34350531UL,0x10100010UL,0x00030303UL, 0x64244460UL,0x6C2D4D61UL,0xC406C6C2UL,0x74344470UL,0xD415C5D1UL,0xB43484B0UL,0xE82ACAE2UL,0x08090901UL, 0x74364672UL,0x18190911UL,0xFC3ECEF2UL,0x40004040UL,0x10120212UL,0xE020C0E0UL,0xBC3D8DB1UL,0x04050501UL, 0xF83ACAF2UL,0x00010101UL,0xF030C0F0UL,0x282A0A22UL,0x5C1E4E52UL,0xA82989A1UL,0x54164652UL,0x40034343UL, 0x84058581UL,0x14140410UL,0x88098981UL,0x981B8B93UL,0xB03080B0UL,0xE425C5E1UL,0x48084840UL,0x78394971UL, 0x94178793UL,0xFC3CCCF0UL,0x1C1E0E12UL,0x80028282UL,0x20210121UL,0x8C0C8C80UL,0x181B0B13UL,0x5C1F4F53UL, 0x74374773UL,0x54144450UL,0xB03282B2UL,0x1C1D0D11UL,0x24250521UL,0x4C0F4F43UL,0x00000000UL,0x44064642UL, 0xEC2DCDE1UL,0x58184850UL,0x50124252UL,0xE82BCBE3UL,0x7C3E4E72UL,0xD81ACAD2UL,0xC809C9C1UL,0xFC3DCDF1UL, 0x30300030UL,0x94158591UL,0x64254561UL,0x3C3C0C30UL,0xB43686B2UL,0xE424C4E0UL,0xB83B8BB3UL,0x7C3C4C70UL, 0x0C0E0E02UL,0x50104050UL,0x38390931UL,0x24260622UL,0x30320232UL,0x84048480UL,0x68294961UL,0x90138393UL, 0x34370733UL,0xE427C7E3UL,0x24240420UL,0xA42484A0UL,0xC80BCBC3UL,0x50134353UL,0x080A0A02UL,0x84078783UL, 0xD819C9D1UL,0x4C0C4C40UL,0x80038383UL,0x8C0F8F83UL,0xCC0ECEC2UL,0x383B0B33UL,0x480A4A42UL,0xB43787B3UL }; static const ulong32 SS2[256] = { 0xA1A82989UL,0x81840585UL,0xD2D416C6UL,0xD3D013C3UL,0x50541444UL,0x111C1D0DUL,0xA0AC2C8CUL,0x21242505UL, 0x515C1D4DUL,0x43400343UL,0x10181808UL,0x121C1E0EUL,0x51501141UL,0xF0FC3CCCUL,0xC2C80ACAUL,0x63602343UL, 0x20282808UL,0x40440444UL,0x20202000UL,0x919C1D8DUL,0xE0E020C0UL,0xE2E022C2UL,0xC0C808C8UL,0x13141707UL, 0xA1A42585UL,0x838C0F8FUL,0x03000303UL,0x73783B4BUL,0xB3B83B8BUL,0x13101303UL,0xD2D012C2UL,0xE2EC2ECEUL, 0x70703040UL,0x808C0C8CUL,0x333C3F0FUL,0xA0A82888UL,0x32303202UL,0xD1DC1DCDUL,0xF2F436C6UL,0x70743444UL, 0xE0EC2CCCUL,0x91941585UL,0x03080B0BUL,0x53541747UL,0x505C1C4CUL,0x53581B4BUL,0xB1BC3D8DUL,0x01000101UL, 0x20242404UL,0x101C1C0CUL,0x73703343UL,0x90981888UL,0x10101000UL,0xC0CC0CCCUL,0xF2F032C2UL,0xD1D819C9UL, 0x202C2C0CUL,0xE3E427C7UL,0x72703242UL,0x83800383UL,0x93981B8BUL,0xD1D011C1UL,0x82840686UL,0xC1C809C9UL, 0x60602040UL,0x50501040UL,0xA3A02383UL,0xE3E82BCBUL,0x010C0D0DUL,0xB2B43686UL,0x929C1E8EUL,0x434C0F4FUL, 0xB3B43787UL,0x52581A4AUL,0xC2C406C6UL,0x70783848UL,0xA2A42686UL,0x12101202UL,0xA3AC2F8FUL,0xD1D415C5UL, 0x61602141UL,0xC3C003C3UL,0xB0B43484UL,0x41400141UL,0x52501242UL,0x717C3D4DUL,0x818C0D8DUL,0x00080808UL, 0x131C1F0FUL,0x91981989UL,0x00000000UL,0x11181909UL,0x00040404UL,0x53501343UL,0xF3F437C7UL,0xE1E021C1UL, 0xF1FC3DCDUL,0x72743646UL,0x232C2F0FUL,0x23242707UL,0xB0B03080UL,0x83880B8BUL,0x020C0E0EUL,0xA3A82B8BUL, 0xA2A02282UL,0x626C2E4EUL,0x93901383UL,0x414C0D4DUL,0x61682949UL,0x707C3C4CUL,0x01080909UL,0x02080A0AUL, 0xB3BC3F8FUL,0xE3EC2FCFUL,0xF3F033C3UL,0xC1C405C5UL,0x83840787UL,0x10141404UL,0xF2FC3ECEUL,0x60642444UL, 0xD2DC1ECEUL,0x222C2E0EUL,0x43480B4BUL,0x12181A0AUL,0x02040606UL,0x21202101UL,0x63682B4BUL,0x62642646UL, 0x02000202UL,0xF1F435C5UL,0x92901282UL,0x82880A8AUL,0x000C0C0CUL,0xB3B03383UL,0x727C3E4EUL,0xD0D010C0UL, 0x72783A4AUL,0x43440747UL,0x92941686UL,0xE1E425C5UL,0x22242606UL,0x80800080UL,0xA1AC2D8DUL,0xD3DC1FCFUL, 0xA1A02181UL,0x30303000UL,0x33343707UL,0xA2AC2E8EUL,0x32343606UL,0x11141505UL,0x22202202UL,0x30383808UL, 0xF0F434C4UL,0xA3A42787UL,0x41440545UL,0x404C0C4CUL,0x81800181UL,0xE1E829C9UL,0x80840484UL,0x93941787UL, 0x31343505UL,0xC3C80BCBUL,0xC2CC0ECEUL,0x303C3C0CUL,0x71703141UL,0x11101101UL,0xC3C407C7UL,0x81880989UL, 0x71743545UL,0xF3F83BCBUL,0xD2D81ACAUL,0xF0F838C8UL,0x90941484UL,0x51581949UL,0x82800282UL,0xC0C404C4UL, 0xF3FC3FCFUL,0x41480949UL,0x31383909UL,0x63642747UL,0xC0C000C0UL,0xC3CC0FCFUL,0xD3D417C7UL,0xB0B83888UL, 0x030C0F0FUL,0x828C0E8EUL,0x42400242UL,0x23202303UL,0x91901181UL,0x606C2C4CUL,0xD3D81BCBUL,0xA0A42484UL, 0x30343404UL,0xF1F031C1UL,0x40480848UL,0xC2C002C2UL,0x636C2F4FUL,0x313C3D0DUL,0x212C2D0DUL,0x40400040UL, 0xB2BC3E8EUL,0x323C3E0EUL,0xB0BC3C8CUL,0xC1C001C1UL,0xA2A82A8AUL,0xB2B83A8AUL,0x424C0E4EUL,0x51541545UL, 0x33383B0BUL,0xD0DC1CCCUL,0x60682848UL,0x737C3F4FUL,0x909C1C8CUL,0xD0D818C8UL,0x42480A4AUL,0x52541646UL, 0x73743747UL,0xA0A02080UL,0xE1EC2DCDUL,0x42440646UL,0xB1B43585UL,0x23282B0BUL,0x61642545UL,0xF2F83ACAUL, 0xE3E023C3UL,0xB1B83989UL,0xB1B03181UL,0x939C1F8FUL,0x525C1E4EUL,0xF1F839C9UL,0xE2E426C6UL,0xB2B03282UL, 0x31303101UL,0xE2E82ACAUL,0x616C2D4DUL,0x535C1F4FUL,0xE0E424C4UL,0xF0F030C0UL,0xC1CC0DCDUL,0x80880888UL, 0x12141606UL,0x32383A0AUL,0x50581848UL,0xD0D414C4UL,0x62602242UL,0x21282909UL,0x03040707UL,0x33303303UL, 0xE0E828C8UL,0x13181B0BUL,0x01040505UL,0x71783949UL,0x90901080UL,0x62682A4AUL,0x22282A0AUL,0x92981A8AUL }; static const ulong32 SS3[256] = { 0x08303838UL,0xC8E0E828UL,0x0D212C2DUL,0x86A2A426UL,0xCFC3CC0FUL,0xCED2DC1EUL,0x83B3B033UL,0x88B0B838UL, 0x8FA3AC2FUL,0x40606020UL,0x45515415UL,0xC7C3C407UL,0x44404404UL,0x4F636C2FUL,0x4B63682BUL,0x4B53581BUL, 0xC3C3C003UL,0x42626022UL,0x03333033UL,0x85B1B435UL,0x09212829UL,0x80A0A020UL,0xC2E2E022UL,0x87A3A427UL, 0xC3D3D013UL,0x81919011UL,0x01111011UL,0x06020406UL,0x0C101C1CUL,0x8CB0BC3CUL,0x06323436UL,0x4B43480BUL, 0xCFE3EC2FUL,0x88808808UL,0x4C606C2CUL,0x88A0A828UL,0x07131417UL,0xC4C0C404UL,0x06121416UL,0xC4F0F434UL, 0xC2C2C002UL,0x45414405UL,0xC1E1E021UL,0xC6D2D416UL,0x0F333C3FUL,0x0D313C3DUL,0x8E828C0EUL,0x88909818UL, 0x08202828UL,0x4E424C0EUL,0xC6F2F436UL,0x0E323C3EUL,0x85A1A425UL,0xC9F1F839UL,0x0D010C0DUL,0xCFD3DC1FUL, 0xC8D0D818UL,0x0B23282BUL,0x46626426UL,0x4A72783AUL,0x07232427UL,0x0F232C2FUL,0xC1F1F031UL,0x42727032UL, 0x42424002UL,0xC4D0D414UL,0x41414001UL,0xC0C0C000UL,0x43737033UL,0x47636427UL,0x8CA0AC2CUL,0x8B83880BUL, 0xC7F3F437UL,0x8DA1AC2DUL,0x80808000UL,0x0F131C1FUL,0xCAC2C80AUL,0x0C202C2CUL,0x8AA2A82AUL,0x04303434UL, 0xC2D2D012UL,0x0B03080BUL,0xCEE2EC2EUL,0xC9E1E829UL,0x4D515C1DUL,0x84909414UL,0x08101818UL,0xC8F0F838UL, 0x47535417UL,0x8EA2AC2EUL,0x08000808UL,0xC5C1C405UL,0x03131013UL,0xCDC1CC0DUL,0x86828406UL,0x89B1B839UL, 0xCFF3FC3FUL,0x4D717C3DUL,0xC1C1C001UL,0x01313031UL,0xC5F1F435UL,0x8A82880AUL,0x4A62682AUL,0x81B1B031UL, 0xC1D1D011UL,0x00202020UL,0xC7D3D417UL,0x02020002UL,0x02222022UL,0x04000404UL,0x48606828UL,0x41717031UL, 0x07030407UL,0xCBD3D81BUL,0x8D919C1DUL,0x89919819UL,0x41616021UL,0x8EB2BC3EUL,0xC6E2E426UL,0x49515819UL, 0xCDD1DC1DUL,0x41515011UL,0x80909010UL,0xCCD0DC1CUL,0x8A92981AUL,0x83A3A023UL,0x8BA3A82BUL,0xC0D0D010UL, 0x81818001UL,0x0F030C0FUL,0x47434407UL,0x0A12181AUL,0xC3E3E023UL,0xCCE0EC2CUL,0x8D818C0DUL,0x8FB3BC3FUL, 0x86929416UL,0x4B73783BUL,0x4C505C1CUL,0x82A2A022UL,0x81A1A021UL,0x43636023UL,0x03232023UL,0x4D414C0DUL, 0xC8C0C808UL,0x8E929C1EUL,0x8C909C1CUL,0x0A32383AUL,0x0C000C0CUL,0x0E222C2EUL,0x8AB2B83AUL,0x4E626C2EUL, 0x8F939C1FUL,0x4A52581AUL,0xC2F2F032UL,0x82929012UL,0xC3F3F033UL,0x49414809UL,0x48707838UL,0xCCC0CC0CUL, 0x05111415UL,0xCBF3F83BUL,0x40707030UL,0x45717435UL,0x4F737C3FUL,0x05313435UL,0x00101010UL,0x03030003UL, 0x44606424UL,0x4D616C2DUL,0xC6C2C406UL,0x44707434UL,0xC5D1D415UL,0x84B0B434UL,0xCAE2E82AUL,0x09010809UL, 0x46727436UL,0x09111819UL,0xCEF2FC3EUL,0x40404000UL,0x02121012UL,0xC0E0E020UL,0x8DB1BC3DUL,0x05010405UL, 0xCAF2F83AUL,0x01010001UL,0xC0F0F030UL,0x0A22282AUL,0x4E525C1EUL,0x89A1A829UL,0x46525416UL,0x43434003UL, 0x85818405UL,0x04101414UL,0x89818809UL,0x8B93981BUL,0x80B0B030UL,0xC5E1E425UL,0x48404808UL,0x49717839UL, 0x87939417UL,0xCCF0FC3CUL,0x0E121C1EUL,0x82828002UL,0x01212021UL,0x8C808C0CUL,0x0B13181BUL,0x4F535C1FUL, 0x47737437UL,0x44505414UL,0x82B2B032UL,0x0D111C1DUL,0x05212425UL,0x4F434C0FUL,0x00000000UL,0x46424406UL, 0xCDE1EC2DUL,0x48505818UL,0x42525012UL,0xCBE3E82BUL,0x4E727C3EUL,0xCAD2D81AUL,0xC9C1C809UL,0xCDF1FC3DUL, 0x00303030UL,0x85919415UL,0x45616425UL,0x0C303C3CUL,0x86B2B436UL,0xC4E0E424UL,0x8BB3B83BUL,0x4C707C3CUL, 0x0E020C0EUL,0x40505010UL,0x09313839UL,0x06222426UL,0x02323032UL,0x84808404UL,0x49616829UL,0x83939013UL, 0x07333437UL,0xC7E3E427UL,0x04202424UL,0x84A0A424UL,0xCBC3C80BUL,0x43535013UL,0x0A02080AUL,0x87838407UL, 0xC9D1D819UL,0x4C404C0CUL,0x83838003UL,0x8F838C0FUL,0xCEC2CC0EUL,0x0B33383BUL,0x4A42480AUL,0x87B3B437UL }; static const ulong32 KCi[16] = { 0x9E3779B9,0x3C6EF373, 0x78DDE6E6,0xF1BBCDCC, 0xE3779B99,0xC6EF3733, 0x8DDE6E67,0x1BBCDCCF, 0x3779B99E,0x6EF3733C, 0xDDE6E678,0xBBCDCCF1, 0x779B99E3,0xEF3733C6, 0xDE6E678D,0xBCDCCF1B }; #define G(x) (SS3[((x)>>24)&255] ^ SS2[((x)>>16)&255] ^ SS1[((x)>>8)&255] ^ SS0[(x)&255]) #define F(L1, L2, R1, R2, K1, K2) \ T2 = G((R1 ^ K1) ^ (R2 ^ K2)); \ T = G( G(T2 + (R1 ^ K1)) + T2); \ L2 ^= T; \ L1 ^= (T + G(T2 + (R1 ^ K1))); \ /** Initialize the SEED block cipher @param key The symmetric key you wish to pass @param keylen The key length in bytes @param num_rounds The number of rounds desired (0 for default) @param skey The key in as scheduled by this function. @return CRYPT_OK if successful */ int kseed_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) { int i; ulong32 tmp, k1, k2, k3, k4; if (keylen != 16) { return CRYPT_INVALID_KEYSIZE; } if (num_rounds != 16 && num_rounds != 0) { return CRYPT_INVALID_ROUNDS; } /* load key */ LOAD32H(k1, key); LOAD32H(k2, key+4); LOAD32H(k3, key+8); LOAD32H(k4, key+12); for (i = 0; i < 16; i++) { skey->kseed.K[2*i+0] = G(k1 + k3 - KCi[i]); skey->kseed.K[2*i+1] = G(k2 - k4 + KCi[i]); if (i&1) { tmp = k3; k3 = ((k3 << 8) | (k4 >> 24)) & 0xFFFFFFFF; k4 = ((k4 << 8) | (tmp >> 24)) & 0xFFFFFFFF; } else { tmp = k1; k1 = ((k1 >> 8) | (k2 << 24)) & 0xFFFFFFFF; k2 = ((k2 >> 8) | (tmp << 24)) & 0xFFFFFFFF; } /* reverse keys for decrypt */ skey->kseed.dK[2*(15-i)+0] = skey->kseed.K[2*i+0]; skey->kseed.dK[2*(15-i)+1] = skey->kseed.K[2*i+1]; } return CRYPT_OK; } static void rounds(ulong32 *P, ulong32 *K) { ulong32 T, T2; int i; for (i = 0; i < 16; i += 2) { F(P[0], P[1], P[2], P[3], K[0], K[1]); F(P[2], P[3], P[0], P[1], K[2], K[3]); K += 4; } } /** Encrypts a block of text with SEED @param pt The input plaintext (16 bytes) @param ct The output ciphertext (16 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ int kseed_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) { ulong32 P[4]; LOAD32H(P[0], pt); LOAD32H(P[1], pt+4); LOAD32H(P[2], pt+8); LOAD32H(P[3], pt+12); rounds(P, skey->kseed.K); STORE32H(P[2], ct); STORE32H(P[3], ct+4); STORE32H(P[0], ct+8); STORE32H(P[1], ct+12); return CRYPT_OK; } /** Decrypts a block of text with SEED @param ct The input ciphertext (16 bytes) @param pt The output plaintext (16 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ int kseed_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) { ulong32 P[4]; LOAD32H(P[0], ct); LOAD32H(P[1], ct+4); LOAD32H(P[2], ct+8); LOAD32H(P[3], ct+12); rounds(P, skey->kseed.dK); STORE32H(P[2], pt); STORE32H(P[3], pt+4); STORE32H(P[0], pt+8); STORE32H(P[1], pt+12); return CRYPT_OK; } /** Terminate the context @param skey The scheduled key */ void kseed_done(symmetric_key *skey) { } /** Performs a self-test of the SEED block cipher @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled */ int kseed_test(void) { #if !defined(LTC_TEST) return CRYPT_NOP; #else static const struct test { unsigned char pt[16], ct[16], key[16]; } tests[] = { { { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F }, { 0x5E,0xBA,0xC6,0xE0,0x05,0x4E,0x16,0x68,0x19,0xAF,0xF1,0xCC,0x6D,0x34,0x6C,0xDB }, { 0 }, }, { { 0 }, { 0xC1,0x1F,0x22,0xF2,0x01,0x40,0x50,0x50,0x84,0x48,0x35,0x97,0xE4,0x37,0x0F,0x43 }, { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F }, }, { { 0x83,0xA2,0xF8,0xA2,0x88,0x64,0x1F,0xB9,0xA4,0xE9,0xA5,0xCC,0x2F,0x13,0x1C,0x7D }, { 0xEE,0x54,0xD1,0x3E,0xBC,0xAE,0x70,0x6D,0x22,0x6B,0xC3,0x14,0x2C,0xD4,0x0D,0x4A }, { 0x47,0x06,0x48,0x08,0x51,0xE6,0x1B,0xE8,0x5D,0x74,0xBF,0xB3,0xFD,0x95,0x61,0x85 }, }, { { 0xB4,0x1E,0x6B,0xE2,0xEB,0xA8,0x4A,0x14,0x8E,0x2E,0xED,0x84,0x59,0x3C,0x5E,0xC7 }, { 0x9B,0x9B,0x7B,0xFC,0xD1,0x81,0x3C,0xB9,0x5D,0x0B,0x36,0x18,0xF4,0x0F,0x51,0x22 }, { 0x28,0xDB,0xC3,0xBC,0x49,0xFF,0xD8,0x7D,0xCF,0xA5,0x09,0xB1,0x1D,0x42,0x2B,0xE7 }, } }; int x; unsigned char buf[2][16]; symmetric_key skey; for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { kseed_setup(tests[x].key, 16, 0, &skey); kseed_ecb_encrypt(tests[x].pt, buf[0], &skey); kseed_ecb_decrypt(buf[0], buf[1], &skey); if (XMEMCMP(buf[0], tests[x].ct, 16) || XMEMCMP(buf[1], tests[x].pt, 16)) { return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. @return CRYPT_OK if the input key size is acceptable. */ int kseed_keysize(int *keysize) { LTC_ARGCHK(keysize != NULL); if (*keysize >= 16) { *keysize = 16; } else { return CRYPT_INVALID_KEYSIZE; } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/kseed.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2007/05/12 14:21:44 $ */ libtomcrypt-1.17/src/ciphers/kasumi.c0000644000175100001440000002337110621351501016412 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file kasumi.c Implementation of the 3GPP Kasumi block cipher Derived from the 3GPP standard source code */ #include "tomcrypt.h" #ifdef LTC_KASUMI typedef unsigned u16; #define ROL16(x, y) ((((x)<<(y)) | ((x)>>(16-(y)))) & 0xFFFF) const struct ltc_cipher_descriptor kasumi_desc = { "kasumi", 21, 16, 16, 8, 8, &kasumi_setup, &kasumi_ecb_encrypt, &kasumi_ecb_decrypt, &kasumi_test, &kasumi_done, &kasumi_keysize, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static u16 FI( u16 in, u16 subkey ) { u16 nine, seven; static const u16 S7[128] = { 54, 50, 62, 56, 22, 34, 94, 96, 38, 6, 63, 93, 2, 18,123, 33, 55,113, 39,114, 21, 67, 65, 12, 47, 73, 46, 27, 25,111,124, 81, 53, 9,121, 79, 52, 60, 58, 48,101,127, 40,120,104, 70, 71, 43, 20,122, 72, 61, 23,109, 13,100, 77, 1, 16, 7, 82, 10,105, 98, 117,116, 76, 11, 89,106, 0,125,118, 99, 86, 69, 30, 57,126, 87, 112, 51, 17, 5, 95, 14, 90, 84, 91, 8, 35,103, 32, 97, 28, 66, 102, 31, 26, 45, 75, 4, 85, 92, 37, 74, 80, 49, 68, 29,115, 44, 64,107,108, 24,110, 83, 36, 78, 42, 19, 15, 41, 88,119, 59, 3 }; static const u16 S9[512] = { 167,239,161,379,391,334, 9,338, 38,226, 48,358,452,385, 90,397, 183,253,147,331,415,340, 51,362,306,500,262, 82,216,159,356,177, 175,241,489, 37,206, 17, 0,333, 44,254,378, 58,143,220, 81,400, 95, 3,315,245, 54,235,218,405,472,264,172,494,371,290,399, 76, 165,197,395,121,257,480,423,212,240, 28,462,176,406,507,288,223, 501,407,249,265, 89,186,221,428,164, 74,440,196,458,421,350,163, 232,158,134,354, 13,250,491,142,191, 69,193,425,152,227,366,135, 344,300,276,242,437,320,113,278, 11,243, 87,317, 36, 93,496, 27, 487,446,482, 41, 68,156,457,131,326,403,339, 20, 39,115,442,124, 475,384,508, 53,112,170,479,151,126,169, 73,268,279,321,168,364, 363,292, 46,499,393,327,324, 24,456,267,157,460,488,426,309,229, 439,506,208,271,349,401,434,236, 16,209,359, 52, 56,120,199,277, 465,416,252,287,246, 6, 83,305,420,345,153,502, 65, 61,244,282, 173,222,418, 67,386,368,261,101,476,291,195,430, 49, 79,166,330, 280,383,373,128,382,408,155,495,367,388,274,107,459,417, 62,454, 132,225,203,316,234, 14,301, 91,503,286,424,211,347,307,140,374, 35,103,125,427, 19,214,453,146,498,314,444,230,256,329,198,285, 50,116, 78,410, 10,205,510,171,231, 45,139,467, 29, 86,505, 32, 72, 26,342,150,313,490,431,238,411,325,149,473, 40,119,174,355, 185,233,389, 71,448,273,372, 55,110,178,322, 12,469,392,369,190, 1,109,375,137,181, 88, 75,308,260,484, 98,272,370,275,412,111, 336,318, 4,504,492,259,304, 77,337,435, 21,357,303,332,483, 18, 47, 85, 25,497,474,289,100,269,296,478,270,106, 31,104,433, 84, 414,486,394, 96, 99,154,511,148,413,361,409,255,162,215,302,201, 266,351,343,144,441,365,108,298,251, 34,182,509,138,210,335,133, 311,352,328,141,396,346,123,319,450,281,429,228,443,481, 92,404, 485,422,248,297, 23,213,130,466, 22,217,283, 70,294,360,419,127, 312,377, 7,468,194, 2,117,295,463,258,224,447,247,187, 80,398, 284,353,105,390,299,471,470,184, 57,200,348, 63,204,188, 33,451, 97, 30,310,219, 94,160,129,493, 64,179,263,102,189,207,114,402, 438,477,387,122,192, 42,381, 5,145,118,180,449,293,323,136,380, 43, 66, 60,455,341,445,202,432, 8,237, 15,376,436,464, 59,461}; /* The sixteen bit input is split into two unequal halves, * * nine bits and seven bits - as is the subkey */ nine = (u16)(in>>7)&0x1FF; seven = (u16)(in&0x7F); /* Now run the various operations */ nine = (u16)(S9[nine] ^ seven); seven = (u16)(S7[seven] ^ (nine & 0x7F)); seven ^= (subkey>>9); nine ^= (subkey&0x1FF); nine = (u16)(S9[nine] ^ seven); seven = (u16)(S7[seven] ^ (nine & 0x7F)); return (u16)(seven<<9) + nine; } static ulong32 FO( ulong32 in, int round_no, symmetric_key *key) { u16 left, right; /* Split the input into two 16-bit words */ left = (u16)(in>>16); right = (u16) in&0xFFFF; /* Now apply the same basic transformation three times */ left ^= key->kasumi.KOi1[round_no]; left = FI( left, key->kasumi.KIi1[round_no] ); left ^= right; right ^= key->kasumi.KOi2[round_no]; right = FI( right, key->kasumi.KIi2[round_no] ); right ^= left; left ^= key->kasumi.KOi3[round_no]; left = FI( left, key->kasumi.KIi3[round_no] ); left ^= right; return (((ulong32)right)<<16)+left; } static ulong32 FL( ulong32 in, int round_no, symmetric_key *key ) { u16 l, r, a, b; /* split out the left and right halves */ l = (u16)(in>>16); r = (u16)(in)&0xFFFF; /* do the FL() operations */ a = (u16) (l & key->kasumi.KLi1[round_no]); r ^= ROL16(a,1); b = (u16)(r | key->kasumi.KLi2[round_no]); l ^= ROL16(b,1); /* put the two halves back together */ return (((ulong32)l)<<16) + r; } int kasumi_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) { ulong32 left, right, temp; int n; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); LOAD32H(left, pt); LOAD32H(right, pt+4); for (n = 0; n <= 7; ) { temp = FL(left, n, skey); temp = FO(temp, n++, skey); right ^= temp; temp = FO(right, n, skey); temp = FL(temp, n++, skey); left ^= temp; } STORE32H(left, ct); STORE32H(right, ct+4); return CRYPT_OK; } int kasumi_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) { ulong32 left, right, temp; int n; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); LOAD32H(left, ct); LOAD32H(right, ct+4); for (n = 7; n >= 0; ) { temp = FO(right, n, skey); temp = FL(temp, n--, skey); left ^= temp; temp = FL(left, n, skey); temp = FO(temp, n--, skey); right ^= temp; } STORE32H(left, pt); STORE32H(right, pt+4); return CRYPT_OK; } int kasumi_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) { static const u16 C[8] = { 0x0123,0x4567,0x89AB,0xCDEF, 0xFEDC,0xBA98,0x7654,0x3210 }; u16 ukey[8], Kprime[8]; int n; LTC_ARGCHK(key != NULL); LTC_ARGCHK(skey != NULL); if (keylen != 16) { return CRYPT_INVALID_KEYSIZE; } if (num_rounds != 0 && num_rounds != 8) { return CRYPT_INVALID_ROUNDS; } /* Start by ensuring the subkeys are endian correct on a 16-bit basis */ for (n = 0; n < 8; n++ ) { ukey[n] = (((u16)key[2*n]) << 8) | key[2*n+1]; } /* Now build the K'[] keys */ for (n = 0; n < 8; n++) { Kprime[n] = ukey[n] ^ C[n]; } /* Finally construct the various sub keys */ for(n = 0; n < 8; n++) { skey->kasumi.KLi1[n] = ROL16(ukey[n],1); skey->kasumi.KLi2[n] = Kprime[(n+2)&0x7]; skey->kasumi.KOi1[n] = ROL16(ukey[(n+1)&0x7],5); skey->kasumi.KOi2[n] = ROL16(ukey[(n+5)&0x7],8); skey->kasumi.KOi3[n] = ROL16(ukey[(n+6)&0x7],13); skey->kasumi.KIi1[n] = Kprime[(n+4)&0x7]; skey->kasumi.KIi2[n] = Kprime[(n+3)&0x7]; skey->kasumi.KIi3[n] = Kprime[(n+7)&0x7]; } return CRYPT_OK; } void kasumi_done(symmetric_key *skey) { } int kasumi_keysize(int *keysize) { LTC_ARGCHK(keysize != NULL); if (*keysize >= 16) { *keysize = 16; return CRYPT_OK; } else { return CRYPT_INVALID_KEYSIZE; } } int kasumi_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { unsigned char key[16], pt[8], ct[8]; } tests[] = { { { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x4B, 0x58, 0xA7, 0x71, 0xAF, 0xC7, 0xE5, 0xE8 } }, { { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x7E, 0xEF, 0x11, 0x3C, 0x95, 0xBB, 0x5A, 0x77 } }, { { 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x5F, 0x14, 0x06, 0x86, 0xD7, 0xAD, 0x5A, 0x39 }, }, { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x2E, 0x14, 0x91, 0xCF, 0x70, 0xAA, 0x46, 0x5D } }, { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0xB5, 0x45, 0x86, 0xF4, 0xAB, 0x9A, 0xE5, 0x46 } }, }; unsigned char buf[2][8]; symmetric_key key; int err, x; for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { if ((err = kasumi_setup(tests[x].key, 16, 0, &key)) != CRYPT_OK) { return err; } if ((err = kasumi_ecb_encrypt(tests[x].pt, buf[0], &key)) != CRYPT_OK) { return err; } if ((err = kasumi_ecb_decrypt(tests[x].ct, buf[1], &key)) != CRYPT_OK) { return err; } if (XMEMCMP(tests[x].pt, buf[1], 8) || XMEMCMP(tests[x].ct, buf[0], 8)) { return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; #endif } #endif /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/kasumi.c,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2006/12/28 01:27:23 $ */ libtomcrypt-1.17/src/ciphers/multi2.c0000644000175100001440000001516110621351501016333 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file multi2.c Multi-2 implementation (not public domain, hence the default disable) */ #include "tomcrypt.h" #ifdef LTC_MULTI2 static void pi1(ulong32 *p) { p[1] ^= p[0]; } static void pi2(ulong32 *p, ulong32 *k) { ulong32 t; t = (p[1] + k[0]) & 0xFFFFFFFFUL; t = (ROL(t, 1) + t - 1) & 0xFFFFFFFFUL; t = (ROL(t, 4) ^ t) & 0xFFFFFFFFUL; p[0] ^= t; } static void pi3(ulong32 *p, ulong32 *k) { ulong32 t; t = p[0] + k[1]; t = (ROL(t, 2) + t + 1) & 0xFFFFFFFFUL; t = (ROL(t, 8) ^ t) & 0xFFFFFFFFUL; t = (t + k[2]) & 0xFFFFFFFFUL; t = (ROL(t, 1) - t) & 0xFFFFFFFFUL; t = ROL(t, 16) ^ (p[0] | t); p[1] ^= t; } static void pi4(ulong32 *p, ulong32 *k) { ulong32 t; t = (p[1] + k[3]) & 0xFFFFFFFFUL; t = (ROL(t, 2) + t + 1) & 0xFFFFFFFFUL; p[0] ^= t; } static void setup(ulong32 *dk, ulong32 *k, ulong32 *uk) { int n, t; ulong32 p[2]; p[0] = dk[0]; p[1] = dk[1]; t = 4; n = 0; pi1(p); pi2(p, k); uk[n++] = p[0]; pi3(p, k); uk[n++] = p[1]; pi4(p, k); uk[n++] = p[0]; pi1(p); uk[n++] = p[1]; pi2(p, k+t); uk[n++] = p[0]; pi3(p, k+t); uk[n++] = p[1]; pi4(p, k+t); uk[n++] = p[0]; pi1(p); uk[n++] = p[1]; } static void encrypt(ulong32 *p, int N, ulong32 *uk) { int n, t; for (t = n = 0; ; ) { pi1(p); if (++n == N) break; pi2(p, uk+t); if (++n == N) break; pi3(p, uk+t); if (++n == N) break; pi4(p, uk+t); if (++n == N) break; t ^= 4; } } static void decrypt(ulong32 *p, int N, ulong32 *uk) { int n, t; for (t = 4*((N&1)^1), n = N; ; ) { switch (n >= 4 ? 4 : 0) { case 4: pi4(p, uk+t); --n; case 3: pi3(p, uk+t); --n; case 2: pi2(p, uk+t); --n; case 1: pi1(p); --n; break; case 0: return; } t ^= 4; } } const struct ltc_cipher_descriptor multi2_desc = { "multi2", 22, 40, 40, 8, 128, &multi2_setup, &multi2_ecb_encrypt, &multi2_ecb_decrypt, &multi2_test, &multi2_done, &multi2_keysize, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; int multi2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) { ulong32 sk[8], dk[2]; int x; LTC_ARGCHK(key != NULL); LTC_ARGCHK(skey != NULL); if (keylen != 40) return CRYPT_INVALID_KEYSIZE; if (num_rounds == 0) num_rounds = 128; skey->multi2.N = num_rounds; for (x = 0; x < 8; x++) { LOAD32H(sk[x], key + x*4); } LOAD32H(dk[0], key + 32); LOAD32H(dk[1], key + 36); setup(dk, sk, skey->multi2.uk); zeromem(sk, sizeof(sk)); zeromem(dk, sizeof(dk)); return CRYPT_OK; } /** Encrypts a block of text with multi2 @param pt The input plaintext (8 bytes) @param ct The output ciphertext (8 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ int multi2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) { ulong32 p[2]; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); LOAD32H(p[0], pt); LOAD32H(p[1], pt+4); encrypt(p, skey->multi2.N, skey->multi2.uk); STORE32H(p[0], ct); STORE32H(p[1], ct+4); return CRYPT_OK; } /** Decrypts a block of text with multi2 @param ct The input ciphertext (8 bytes) @param pt The output plaintext (8 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ int multi2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) { ulong32 p[2]; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); LOAD32H(p[0], ct); LOAD32H(p[1], ct+4); decrypt(p, skey->multi2.N, skey->multi2.uk); STORE32H(p[0], pt); STORE32H(p[1], pt+4); return CRYPT_OK; } /** Performs a self-test of the multi2 block cipher @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled */ int multi2_test(void) { static const struct { unsigned char key[40]; unsigned char pt[8], ct[8]; int rounds; } tests[] = { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, }, { 0xf8, 0x94, 0x40, 0x84, 0x5e, 0x11, 0xcf, 0x89 }, 128, }, { { 0x35, 0x91, 0x9d, 0x96, 0x07, 0x02, 0xe2, 0xce, 0x8d, 0x0b, 0x58, 0x3c, 0xc9, 0xc8, 0x9d, 0x59, 0xa2, 0xae, 0x96, 0x4e, 0x87, 0x82, 0x45, 0xed, 0x3f, 0x2e, 0x62, 0xd6, 0x36, 0x35, 0xd0, 0x67, 0xb1, 0x27, 0xb9, 0x06, 0xe7, 0x56, 0x22, 0x38, }, { 0x1f, 0xb4, 0x60, 0x60, 0xd0, 0xb3, 0x4f, 0xa5 }, { 0xca, 0x84, 0xa9, 0x34, 0x75, 0xc8, 0x60, 0xe5 }, 216, } }; unsigned char buf[8]; symmetric_key skey; int err, x; for (x = 1; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) { if ((err = multi2_setup(tests[x].key, 40, tests[x].rounds, &skey)) != CRYPT_OK) { return err; } if ((err = multi2_ecb_encrypt(tests[x].pt, buf, &skey)) != CRYPT_OK) { return err; } if (XMEMCMP(buf, tests[x].ct, 8)) { return CRYPT_FAIL_TESTVECTOR; } if ((err = multi2_ecb_decrypt(buf, buf, &skey)) != CRYPT_OK) { return err; } if (XMEMCMP(buf, tests[x].pt, 8)) { return CRYPT_FAIL_TESTVECTOR; } } return CRYPT_OK; } /** Terminate the context @param skey The scheduled key */ void multi2_done(symmetric_key *skey) { } /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. @return CRYPT_OK if the input key size is acceptable. */ int multi2_keysize(int *keysize) { LTC_ARGCHK(keysize != NULL); if (*keysize >= 40) { *keysize = 40; } else { return CRYPT_INVALID_KEYSIZE; } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/multi2.c,v $ */ /* $Revision: 1.1 $ */ /* $Date: 2007/01/05 16:01:25 $ */ libtomcrypt-1.17/src/ciphers/blowfish.c0000644000175100001440000006117610621351501016743 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file blowfish.c Implementation of the Blowfish block cipher, Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_BLOWFISH const struct ltc_cipher_descriptor blowfish_desc = { "blowfish", 0, 8, 56, 8, 16, &blowfish_setup, &blowfish_ecb_encrypt, &blowfish_ecb_decrypt, &blowfish_test, &blowfish_done, &blowfish_keysize, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static const ulong32 ORIG_P[16 + 2] = { 0x243F6A88UL, 0x85A308D3UL, 0x13198A2EUL, 0x03707344UL, 0xA4093822UL, 0x299F31D0UL, 0x082EFA98UL, 0xEC4E6C89UL, 0x452821E6UL, 0x38D01377UL, 0xBE5466CFUL, 0x34E90C6CUL, 0xC0AC29B7UL, 0xC97C50DDUL, 0x3F84D5B5UL, 0xB5470917UL, 0x9216D5D9UL, 0x8979FB1BUL }; static const ulong32 ORIG_S[4][256] = { { 0xD1310BA6UL, 0x98DFB5ACUL, 0x2FFD72DBUL, 0xD01ADFB7UL, 0xB8E1AFEDUL, 0x6A267E96UL, 0xBA7C9045UL, 0xF12C7F99UL, 0x24A19947UL, 0xB3916CF7UL, 0x0801F2E2UL, 0x858EFC16UL, 0x636920D8UL, 0x71574E69UL, 0xA458FEA3UL, 0xF4933D7EUL, 0x0D95748FUL, 0x728EB658UL, 0x718BCD58UL, 0x82154AEEUL, 0x7B54A41DUL, 0xC25A59B5UL, 0x9C30D539UL, 0x2AF26013UL, 0xC5D1B023UL, 0x286085F0UL, 0xCA417918UL, 0xB8DB38EFUL, 0x8E79DCB0UL, 0x603A180EUL, 0x6C9E0E8BUL, 0xB01E8A3EUL, 0xD71577C1UL, 0xBD314B27UL, 0x78AF2FDAUL, 0x55605C60UL, 0xE65525F3UL, 0xAA55AB94UL, 0x57489862UL, 0x63E81440UL, 0x55CA396AUL, 0x2AAB10B6UL, 0xB4CC5C34UL, 0x1141E8CEUL, 0xA15486AFUL, 0x7C72E993UL, 0xB3EE1411UL, 0x636FBC2AUL, 0x2BA9C55DUL, 0x741831F6UL, 0xCE5C3E16UL, 0x9B87931EUL, 0xAFD6BA33UL, 0x6C24CF5CUL, 0x7A325381UL, 0x28958677UL, 0x3B8F4898UL, 0x6B4BB9AFUL, 0xC4BFE81BUL, 0x66282193UL, 0x61D809CCUL, 0xFB21A991UL, 0x487CAC60UL, 0x5DEC8032UL, 0xEF845D5DUL, 0xE98575B1UL, 0xDC262302UL, 0xEB651B88UL, 0x23893E81UL, 0xD396ACC5UL, 0x0F6D6FF3UL, 0x83F44239UL, 0x2E0B4482UL, 0xA4842004UL, 0x69C8F04AUL, 0x9E1F9B5EUL, 0x21C66842UL, 0xF6E96C9AUL, 0x670C9C61UL, 0xABD388F0UL, 0x6A51A0D2UL, 0xD8542F68UL, 0x960FA728UL, 0xAB5133A3UL, 0x6EEF0B6CUL, 0x137A3BE4UL, 0xBA3BF050UL, 0x7EFB2A98UL, 0xA1F1651DUL, 0x39AF0176UL, 0x66CA593EUL, 0x82430E88UL, 0x8CEE8619UL, 0x456F9FB4UL, 0x7D84A5C3UL, 0x3B8B5EBEUL, 0xE06F75D8UL, 0x85C12073UL, 0x401A449FUL, 0x56C16AA6UL, 0x4ED3AA62UL, 0x363F7706UL, 0x1BFEDF72UL, 0x429B023DUL, 0x37D0D724UL, 0xD00A1248UL, 0xDB0FEAD3UL, 0x49F1C09BUL, 0x075372C9UL, 0x80991B7BUL, 0x25D479D8UL, 0xF6E8DEF7UL, 0xE3FE501AUL, 0xB6794C3BUL, 0x976CE0BDUL, 0x04C006BAUL, 0xC1A94FB6UL, 0x409F60C4UL, 0x5E5C9EC2UL, 0x196A2463UL, 0x68FB6FAFUL, 0x3E6C53B5UL, 0x1339B2EBUL, 0x3B52EC6FUL, 0x6DFC511FUL, 0x9B30952CUL, 0xCC814544UL, 0xAF5EBD09UL, 0xBEE3D004UL, 0xDE334AFDUL, 0x660F2807UL, 0x192E4BB3UL, 0xC0CBA857UL, 0x45C8740FUL, 0xD20B5F39UL, 0xB9D3FBDBUL, 0x5579C0BDUL, 0x1A60320AUL, 0xD6A100C6UL, 0x402C7279UL, 0x679F25FEUL, 0xFB1FA3CCUL, 0x8EA5E9F8UL, 0xDB3222F8UL, 0x3C7516DFUL, 0xFD616B15UL, 0x2F501EC8UL, 0xAD0552ABUL, 0x323DB5FAUL, 0xFD238760UL, 0x53317B48UL, 0x3E00DF82UL, 0x9E5C57BBUL, 0xCA6F8CA0UL, 0x1A87562EUL, 0xDF1769DBUL, 0xD542A8F6UL, 0x287EFFC3UL, 0xAC6732C6UL, 0x8C4F5573UL, 0x695B27B0UL, 0xBBCA58C8UL, 0xE1FFA35DUL, 0xB8F011A0UL, 0x10FA3D98UL, 0xFD2183B8UL, 0x4AFCB56CUL, 0x2DD1D35BUL, 0x9A53E479UL, 0xB6F84565UL, 0xD28E49BCUL, 0x4BFB9790UL, 0xE1DDF2DAUL, 0xA4CB7E33UL, 0x62FB1341UL, 0xCEE4C6E8UL, 0xEF20CADAUL, 0x36774C01UL, 0xD07E9EFEUL, 0x2BF11FB4UL, 0x95DBDA4DUL, 0xAE909198UL, 0xEAAD8E71UL, 0x6B93D5A0UL, 0xD08ED1D0UL, 0xAFC725E0UL, 0x8E3C5B2FUL, 0x8E7594B7UL, 0x8FF6E2FBUL, 0xF2122B64UL, 0x8888B812UL, 0x900DF01CUL, 0x4FAD5EA0UL, 0x688FC31CUL, 0xD1CFF191UL, 0xB3A8C1ADUL, 0x2F2F2218UL, 0xBE0E1777UL, 0xEA752DFEUL, 0x8B021FA1UL, 0xE5A0CC0FUL, 0xB56F74E8UL, 0x18ACF3D6UL, 0xCE89E299UL, 0xB4A84FE0UL, 0xFD13E0B7UL, 0x7CC43B81UL, 0xD2ADA8D9UL, 0x165FA266UL, 0x80957705UL, 0x93CC7314UL, 0x211A1477UL, 0xE6AD2065UL, 0x77B5FA86UL, 0xC75442F5UL, 0xFB9D35CFUL, 0xEBCDAF0CUL, 0x7B3E89A0UL, 0xD6411BD3UL, 0xAE1E7E49UL, 0x00250E2DUL, 0x2071B35EUL, 0x226800BBUL, 0x57B8E0AFUL, 0x2464369BUL, 0xF009B91EUL, 0x5563911DUL, 0x59DFA6AAUL, 0x78C14389UL, 0xD95A537FUL, 0x207D5BA2UL, 0x02E5B9C5UL, 0x83260376UL, 0x6295CFA9UL, 0x11C81968UL, 0x4E734A41UL, 0xB3472DCAUL, 0x7B14A94AUL, 0x1B510052UL, 0x9A532915UL, 0xD60F573FUL, 0xBC9BC6E4UL, 0x2B60A476UL, 0x81E67400UL, 0x08BA6FB5UL, 0x571BE91FUL, 0xF296EC6BUL, 0x2A0DD915UL, 0xB6636521UL, 0xE7B9F9B6UL, 0xFF34052EUL, 0xC5855664UL, 0x53B02D5DUL, 0xA99F8FA1UL, 0x08BA4799UL, 0x6E85076AUL }, { 0x4B7A70E9UL, 0xB5B32944UL, 0xDB75092EUL, 0xC4192623UL, 0xAD6EA6B0UL, 0x49A7DF7DUL, 0x9CEE60B8UL, 0x8FEDB266UL, 0xECAA8C71UL, 0x699A17FFUL, 0x5664526CUL, 0xC2B19EE1UL, 0x193602A5UL, 0x75094C29UL, 0xA0591340UL, 0xE4183A3EUL, 0x3F54989AUL, 0x5B429D65UL, 0x6B8FE4D6UL, 0x99F73FD6UL, 0xA1D29C07UL, 0xEFE830F5UL, 0x4D2D38E6UL, 0xF0255DC1UL, 0x4CDD2086UL, 0x8470EB26UL, 0x6382E9C6UL, 0x021ECC5EUL, 0x09686B3FUL, 0x3EBAEFC9UL, 0x3C971814UL, 0x6B6A70A1UL, 0x687F3584UL, 0x52A0E286UL, 0xB79C5305UL, 0xAA500737UL, 0x3E07841CUL, 0x7FDEAE5CUL, 0x8E7D44ECUL, 0x5716F2B8UL, 0xB03ADA37UL, 0xF0500C0DUL, 0xF01C1F04UL, 0x0200B3FFUL, 0xAE0CF51AUL, 0x3CB574B2UL, 0x25837A58UL, 0xDC0921BDUL, 0xD19113F9UL, 0x7CA92FF6UL, 0x94324773UL, 0x22F54701UL, 0x3AE5E581UL, 0x37C2DADCUL, 0xC8B57634UL, 0x9AF3DDA7UL, 0xA9446146UL, 0x0FD0030EUL, 0xECC8C73EUL, 0xA4751E41UL, 0xE238CD99UL, 0x3BEA0E2FUL, 0x3280BBA1UL, 0x183EB331UL, 0x4E548B38UL, 0x4F6DB908UL, 0x6F420D03UL, 0xF60A04BFUL, 0x2CB81290UL, 0x24977C79UL, 0x5679B072UL, 0xBCAF89AFUL, 0xDE9A771FUL, 0xD9930810UL, 0xB38BAE12UL, 0xDCCF3F2EUL, 0x5512721FUL, 0x2E6B7124UL, 0x501ADDE6UL, 0x9F84CD87UL, 0x7A584718UL, 0x7408DA17UL, 0xBC9F9ABCUL, 0xE94B7D8CUL, 0xEC7AEC3AUL, 0xDB851DFAUL, 0x63094366UL, 0xC464C3D2UL, 0xEF1C1847UL, 0x3215D908UL, 0xDD433B37UL, 0x24C2BA16UL, 0x12A14D43UL, 0x2A65C451UL, 0x50940002UL, 0x133AE4DDUL, 0x71DFF89EUL, 0x10314E55UL, 0x81AC77D6UL, 0x5F11199BUL, 0x043556F1UL, 0xD7A3C76BUL, 0x3C11183BUL, 0x5924A509UL, 0xF28FE6EDUL, 0x97F1FBFAUL, 0x9EBABF2CUL, 0x1E153C6EUL, 0x86E34570UL, 0xEAE96FB1UL, 0x860E5E0AUL, 0x5A3E2AB3UL, 0x771FE71CUL, 0x4E3D06FAUL, 0x2965DCB9UL, 0x99E71D0FUL, 0x803E89D6UL, 0x5266C825UL, 0x2E4CC978UL, 0x9C10B36AUL, 0xC6150EBAUL, 0x94E2EA78UL, 0xA5FC3C53UL, 0x1E0A2DF4UL, 0xF2F74EA7UL, 0x361D2B3DUL, 0x1939260FUL, 0x19C27960UL, 0x5223A708UL, 0xF71312B6UL, 0xEBADFE6EUL, 0xEAC31F66UL, 0xE3BC4595UL, 0xA67BC883UL, 0xB17F37D1UL, 0x018CFF28UL, 0xC332DDEFUL, 0xBE6C5AA5UL, 0x65582185UL, 0x68AB9802UL, 0xEECEA50FUL, 0xDB2F953BUL, 0x2AEF7DADUL, 0x5B6E2F84UL, 0x1521B628UL, 0x29076170UL, 0xECDD4775UL, 0x619F1510UL, 0x13CCA830UL, 0xEB61BD96UL, 0x0334FE1EUL, 0xAA0363CFUL, 0xB5735C90UL, 0x4C70A239UL, 0xD59E9E0BUL, 0xCBAADE14UL, 0xEECC86BCUL, 0x60622CA7UL, 0x9CAB5CABUL, 0xB2F3846EUL, 0x648B1EAFUL, 0x19BDF0CAUL, 0xA02369B9UL, 0x655ABB50UL, 0x40685A32UL, 0x3C2AB4B3UL, 0x319EE9D5UL, 0xC021B8F7UL, 0x9B540B19UL, 0x875FA099UL, 0x95F7997EUL, 0x623D7DA8UL, 0xF837889AUL, 0x97E32D77UL, 0x11ED935FUL, 0x16681281UL, 0x0E358829UL, 0xC7E61FD6UL, 0x96DEDFA1UL, 0x7858BA99UL, 0x57F584A5UL, 0x1B227263UL, 0x9B83C3FFUL, 0x1AC24696UL, 0xCDB30AEBUL, 0x532E3054UL, 0x8FD948E4UL, 0x6DBC3128UL, 0x58EBF2EFUL, 0x34C6FFEAUL, 0xFE28ED61UL, 0xEE7C3C73UL, 0x5D4A14D9UL, 0xE864B7E3UL, 0x42105D14UL, 0x203E13E0UL, 0x45EEE2B6UL, 0xA3AAABEAUL, 0xDB6C4F15UL, 0xFACB4FD0UL, 0xC742F442UL, 0xEF6ABBB5UL, 0x654F3B1DUL, 0x41CD2105UL, 0xD81E799EUL, 0x86854DC7UL, 0xE44B476AUL, 0x3D816250UL, 0xCF62A1F2UL, 0x5B8D2646UL, 0xFC8883A0UL, 0xC1C7B6A3UL, 0x7F1524C3UL, 0x69CB7492UL, 0x47848A0BUL, 0x5692B285UL, 0x095BBF00UL, 0xAD19489DUL, 0x1462B174UL, 0x23820E00UL, 0x58428D2AUL, 0x0C55F5EAUL, 0x1DADF43EUL, 0x233F7061UL, 0x3372F092UL, 0x8D937E41UL, 0xD65FECF1UL, 0x6C223BDBUL, 0x7CDE3759UL, 0xCBEE7460UL, 0x4085F2A7UL, 0xCE77326EUL, 0xA6078084UL, 0x19F8509EUL, 0xE8EFD855UL, 0x61D99735UL, 0xA969A7AAUL, 0xC50C06C2UL, 0x5A04ABFCUL, 0x800BCADCUL, 0x9E447A2EUL, 0xC3453484UL, 0xFDD56705UL, 0x0E1E9EC9UL, 0xDB73DBD3UL, 0x105588CDUL, 0x675FDA79UL, 0xE3674340UL, 0xC5C43465UL, 0x713E38D8UL, 0x3D28F89EUL, 0xF16DFF20UL, 0x153E21E7UL, 0x8FB03D4AUL, 0xE6E39F2BUL, 0xDB83ADF7UL }, { 0xE93D5A68UL, 0x948140F7UL, 0xF64C261CUL, 0x94692934UL, 0x411520F7UL, 0x7602D4F7UL, 0xBCF46B2EUL, 0xD4A20068UL, 0xD4082471UL, 0x3320F46AUL, 0x43B7D4B7UL, 0x500061AFUL, 0x1E39F62EUL, 0x97244546UL, 0x14214F74UL, 0xBF8B8840UL, 0x4D95FC1DUL, 0x96B591AFUL, 0x70F4DDD3UL, 0x66A02F45UL, 0xBFBC09ECUL, 0x03BD9785UL, 0x7FAC6DD0UL, 0x31CB8504UL, 0x96EB27B3UL, 0x55FD3941UL, 0xDA2547E6UL, 0xABCA0A9AUL, 0x28507825UL, 0x530429F4UL, 0x0A2C86DAUL, 0xE9B66DFBUL, 0x68DC1462UL, 0xD7486900UL, 0x680EC0A4UL, 0x27A18DEEUL, 0x4F3FFEA2UL, 0xE887AD8CUL, 0xB58CE006UL, 0x7AF4D6B6UL, 0xAACE1E7CUL, 0xD3375FECUL, 0xCE78A399UL, 0x406B2A42UL, 0x20FE9E35UL, 0xD9F385B9UL, 0xEE39D7ABUL, 0x3B124E8BUL, 0x1DC9FAF7UL, 0x4B6D1856UL, 0x26A36631UL, 0xEAE397B2UL, 0x3A6EFA74UL, 0xDD5B4332UL, 0x6841E7F7UL, 0xCA7820FBUL, 0xFB0AF54EUL, 0xD8FEB397UL, 0x454056ACUL, 0xBA489527UL, 0x55533A3AUL, 0x20838D87UL, 0xFE6BA9B7UL, 0xD096954BUL, 0x55A867BCUL, 0xA1159A58UL, 0xCCA92963UL, 0x99E1DB33UL, 0xA62A4A56UL, 0x3F3125F9UL, 0x5EF47E1CUL, 0x9029317CUL, 0xFDF8E802UL, 0x04272F70UL, 0x80BB155CUL, 0x05282CE3UL, 0x95C11548UL, 0xE4C66D22UL, 0x48C1133FUL, 0xC70F86DCUL, 0x07F9C9EEUL, 0x41041F0FUL, 0x404779A4UL, 0x5D886E17UL, 0x325F51EBUL, 0xD59BC0D1UL, 0xF2BCC18FUL, 0x41113564UL, 0x257B7834UL, 0x602A9C60UL, 0xDFF8E8A3UL, 0x1F636C1BUL, 0x0E12B4C2UL, 0x02E1329EUL, 0xAF664FD1UL, 0xCAD18115UL, 0x6B2395E0UL, 0x333E92E1UL, 0x3B240B62UL, 0xEEBEB922UL, 0x85B2A20EUL, 0xE6BA0D99UL, 0xDE720C8CUL, 0x2DA2F728UL, 0xD0127845UL, 0x95B794FDUL, 0x647D0862UL, 0xE7CCF5F0UL, 0x5449A36FUL, 0x877D48FAUL, 0xC39DFD27UL, 0xF33E8D1EUL, 0x0A476341UL, 0x992EFF74UL, 0x3A6F6EABUL, 0xF4F8FD37UL, 0xA812DC60UL, 0xA1EBDDF8UL, 0x991BE14CUL, 0xDB6E6B0DUL, 0xC67B5510UL, 0x6D672C37UL, 0x2765D43BUL, 0xDCD0E804UL, 0xF1290DC7UL, 0xCC00FFA3UL, 0xB5390F92UL, 0x690FED0BUL, 0x667B9FFBUL, 0xCEDB7D9CUL, 0xA091CF0BUL, 0xD9155EA3UL, 0xBB132F88UL, 0x515BAD24UL, 0x7B9479BFUL, 0x763BD6EBUL, 0x37392EB3UL, 0xCC115979UL, 0x8026E297UL, 0xF42E312DUL, 0x6842ADA7UL, 0xC66A2B3BUL, 0x12754CCCUL, 0x782EF11CUL, 0x6A124237UL, 0xB79251E7UL, 0x06A1BBE6UL, 0x4BFB6350UL, 0x1A6B1018UL, 0x11CAEDFAUL, 0x3D25BDD8UL, 0xE2E1C3C9UL, 0x44421659UL, 0x0A121386UL, 0xD90CEC6EUL, 0xD5ABEA2AUL, 0x64AF674EUL, 0xDA86A85FUL, 0xBEBFE988UL, 0x64E4C3FEUL, 0x9DBC8057UL, 0xF0F7C086UL, 0x60787BF8UL, 0x6003604DUL, 0xD1FD8346UL, 0xF6381FB0UL, 0x7745AE04UL, 0xD736FCCCUL, 0x83426B33UL, 0xF01EAB71UL, 0xB0804187UL, 0x3C005E5FUL, 0x77A057BEUL, 0xBDE8AE24UL, 0x55464299UL, 0xBF582E61UL, 0x4E58F48FUL, 0xF2DDFDA2UL, 0xF474EF38UL, 0x8789BDC2UL, 0x5366F9C3UL, 0xC8B38E74UL, 0xB475F255UL, 0x46FCD9B9UL, 0x7AEB2661UL, 0x8B1DDF84UL, 0x846A0E79UL, 0x915F95E2UL, 0x466E598EUL, 0x20B45770UL, 0x8CD55591UL, 0xC902DE4CUL, 0xB90BACE1UL, 0xBB8205D0UL, 0x11A86248UL, 0x7574A99EUL, 0xB77F19B6UL, 0xE0A9DC09UL, 0x662D09A1UL, 0xC4324633UL, 0xE85A1F02UL, 0x09F0BE8CUL, 0x4A99A025UL, 0x1D6EFE10UL, 0x1AB93D1DUL, 0x0BA5A4DFUL, 0xA186F20FUL, 0x2868F169UL, 0xDCB7DA83UL, 0x573906FEUL, 0xA1E2CE9BUL, 0x4FCD7F52UL, 0x50115E01UL, 0xA70683FAUL, 0xA002B5C4UL, 0x0DE6D027UL, 0x9AF88C27UL, 0x773F8641UL, 0xC3604C06UL, 0x61A806B5UL, 0xF0177A28UL, 0xC0F586E0UL, 0x006058AAUL, 0x30DC7D62UL, 0x11E69ED7UL, 0x2338EA63UL, 0x53C2DD94UL, 0xC2C21634UL, 0xBBCBEE56UL, 0x90BCB6DEUL, 0xEBFC7DA1UL, 0xCE591D76UL, 0x6F05E409UL, 0x4B7C0188UL, 0x39720A3DUL, 0x7C927C24UL, 0x86E3725FUL, 0x724D9DB9UL, 0x1AC15BB4UL, 0xD39EB8FCUL, 0xED545578UL, 0x08FCA5B5UL, 0xD83D7CD3UL, 0x4DAD0FC4UL, 0x1E50EF5EUL, 0xB161E6F8UL, 0xA28514D9UL, 0x6C51133CUL, 0x6FD5C7E7UL, 0x56E14EC4UL, 0x362ABFCEUL, 0xDDC6C837UL, 0xD79A3234UL, 0x92638212UL, 0x670EFA8EUL, 0x406000E0UL }, { 0x3A39CE37UL, 0xD3FAF5CFUL, 0xABC27737UL, 0x5AC52D1BUL, 0x5CB0679EUL, 0x4FA33742UL, 0xD3822740UL, 0x99BC9BBEUL, 0xD5118E9DUL, 0xBF0F7315UL, 0xD62D1C7EUL, 0xC700C47BUL, 0xB78C1B6BUL, 0x21A19045UL, 0xB26EB1BEUL, 0x6A366EB4UL, 0x5748AB2FUL, 0xBC946E79UL, 0xC6A376D2UL, 0x6549C2C8UL, 0x530FF8EEUL, 0x468DDE7DUL, 0xD5730A1DUL, 0x4CD04DC6UL, 0x2939BBDBUL, 0xA9BA4650UL, 0xAC9526E8UL, 0xBE5EE304UL, 0xA1FAD5F0UL, 0x6A2D519AUL, 0x63EF8CE2UL, 0x9A86EE22UL, 0xC089C2B8UL, 0x43242EF6UL, 0xA51E03AAUL, 0x9CF2D0A4UL, 0x83C061BAUL, 0x9BE96A4DUL, 0x8FE51550UL, 0xBA645BD6UL, 0x2826A2F9UL, 0xA73A3AE1UL, 0x4BA99586UL, 0xEF5562E9UL, 0xC72FEFD3UL, 0xF752F7DAUL, 0x3F046F69UL, 0x77FA0A59UL, 0x80E4A915UL, 0x87B08601UL, 0x9B09E6ADUL, 0x3B3EE593UL, 0xE990FD5AUL, 0x9E34D797UL, 0x2CF0B7D9UL, 0x022B8B51UL, 0x96D5AC3AUL, 0x017DA67DUL, 0xD1CF3ED6UL, 0x7C7D2D28UL, 0x1F9F25CFUL, 0xADF2B89BUL, 0x5AD6B472UL, 0x5A88F54CUL, 0xE029AC71UL, 0xE019A5E6UL, 0x47B0ACFDUL, 0xED93FA9BUL, 0xE8D3C48DUL, 0x283B57CCUL, 0xF8D56629UL, 0x79132E28UL, 0x785F0191UL, 0xED756055UL, 0xF7960E44UL, 0xE3D35E8CUL, 0x15056DD4UL, 0x88F46DBAUL, 0x03A16125UL, 0x0564F0BDUL, 0xC3EB9E15UL, 0x3C9057A2UL, 0x97271AECUL, 0xA93A072AUL, 0x1B3F6D9BUL, 0x1E6321F5UL, 0xF59C66FBUL, 0x26DCF319UL, 0x7533D928UL, 0xB155FDF5UL, 0x03563482UL, 0x8ABA3CBBUL, 0x28517711UL, 0xC20AD9F8UL, 0xABCC5167UL, 0xCCAD925FUL, 0x4DE81751UL, 0x3830DC8EUL, 0x379D5862UL, 0x9320F991UL, 0xEA7A90C2UL, 0xFB3E7BCEUL, 0x5121CE64UL, 0x774FBE32UL, 0xA8B6E37EUL, 0xC3293D46UL, 0x48DE5369UL, 0x6413E680UL, 0xA2AE0810UL, 0xDD6DB224UL, 0x69852DFDUL, 0x09072166UL, 0xB39A460AUL, 0x6445C0DDUL, 0x586CDECFUL, 0x1C20C8AEUL, 0x5BBEF7DDUL, 0x1B588D40UL, 0xCCD2017FUL, 0x6BB4E3BBUL, 0xDDA26A7EUL, 0x3A59FF45UL, 0x3E350A44UL, 0xBCB4CDD5UL, 0x72EACEA8UL, 0xFA6484BBUL, 0x8D6612AEUL, 0xBF3C6F47UL, 0xD29BE463UL, 0x542F5D9EUL, 0xAEC2771BUL, 0xF64E6370UL, 0x740E0D8DUL, 0xE75B1357UL, 0xF8721671UL, 0xAF537D5DUL, 0x4040CB08UL, 0x4EB4E2CCUL, 0x34D2466AUL, 0x0115AF84UL, 0xE1B00428UL, 0x95983A1DUL, 0x06B89FB4UL, 0xCE6EA048UL, 0x6F3F3B82UL, 0x3520AB82UL, 0x011A1D4BUL, 0x277227F8UL, 0x611560B1UL, 0xE7933FDCUL, 0xBB3A792BUL, 0x344525BDUL, 0xA08839E1UL, 0x51CE794BUL, 0x2F32C9B7UL, 0xA01FBAC9UL, 0xE01CC87EUL, 0xBCC7D1F6UL, 0xCF0111C3UL, 0xA1E8AAC7UL, 0x1A908749UL, 0xD44FBD9AUL, 0xD0DADECBUL, 0xD50ADA38UL, 0x0339C32AUL, 0xC6913667UL, 0x8DF9317CUL, 0xE0B12B4FUL, 0xF79E59B7UL, 0x43F5BB3AUL, 0xF2D519FFUL, 0x27D9459CUL, 0xBF97222CUL, 0x15E6FC2AUL, 0x0F91FC71UL, 0x9B941525UL, 0xFAE59361UL, 0xCEB69CEBUL, 0xC2A86459UL, 0x12BAA8D1UL, 0xB6C1075EUL, 0xE3056A0CUL, 0x10D25065UL, 0xCB03A442UL, 0xE0EC6E0EUL, 0x1698DB3BUL, 0x4C98A0BEUL, 0x3278E964UL, 0x9F1F9532UL, 0xE0D392DFUL, 0xD3A0342BUL, 0x8971F21EUL, 0x1B0A7441UL, 0x4BA3348CUL, 0xC5BE7120UL, 0xC37632D8UL, 0xDF359F8DUL, 0x9B992F2EUL, 0xE60B6F47UL, 0x0FE3F11DUL, 0xE54CDA54UL, 0x1EDAD891UL, 0xCE6279CFUL, 0xCD3E7E6FUL, 0x1618B166UL, 0xFD2C1D05UL, 0x848FD2C5UL, 0xF6FB2299UL, 0xF523F357UL, 0xA6327623UL, 0x93A83531UL, 0x56CCCD02UL, 0xACF08162UL, 0x5A75EBB5UL, 0x6E163697UL, 0x88D273CCUL, 0xDE966292UL, 0x81B949D0UL, 0x4C50901BUL, 0x71C65614UL, 0xE6C6C7BDUL, 0x327A140AUL, 0x45E1D006UL, 0xC3F27B9AUL, 0xC9AA53FDUL, 0x62A80F00UL, 0xBB25BFE2UL, 0x35BDD2F6UL, 0x71126905UL, 0xB2040222UL, 0xB6CBCF7CUL, 0xCD769C2BUL, 0x53113EC0UL, 0x1640E3D3UL, 0x38ABBD60UL, 0x2547ADF0UL, 0xBA38209CUL, 0xF746CE76UL, 0x77AFA1C5UL, 0x20756060UL, 0x85CBFE4EUL, 0x8AE88DD8UL, 0x7AAAF9B0UL, 0x4CF9AA7EUL, 0x1948C25CUL, 0x02FB8A8CUL, 0x01C36AE4UL, 0xD6EBE1F9UL, 0x90D4F869UL, 0xA65CDEA0UL, 0x3F09252DUL, 0xC208E69FUL, 0xB74E6132UL, 0xCE77E25BUL, 0x578FDFE3UL, 0x3AC372E6UL } }; /** Initialize the Blowfish block cipher @param key The symmetric key you wish to pass @param keylen The key length in bytes @param num_rounds The number of rounds desired (0 for default) @param skey The key in as scheduled by this function. @return CRYPT_OK if successful */ int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) { ulong32 x, y, z, A; unsigned char B[8]; LTC_ARGCHK(key != NULL); LTC_ARGCHK(skey != NULL); /* check key length */ if (keylen < 8 || keylen > 56) { return CRYPT_INVALID_KEYSIZE; } /* check rounds */ if (num_rounds != 0 && num_rounds != 16) { return CRYPT_INVALID_ROUNDS; } /* load in key bytes (Supplied by David Hopwood) */ for (x = y = 0; x < 18; x++) { A = 0; for (z = 0; z < 4; z++) { A = (A << 8) | ((ulong32)key[y++] & 255); if (y == (ulong32)keylen) { y = 0; } } skey->blowfish.K[x] = ORIG_P[x] ^ A; } /* copy sboxes */ for (x = 0; x < 4; x++) { for (y = 0; y < 256; y++) { skey->blowfish.S[x][y] = ORIG_S[x][y]; } } /* encrypt K array */ for (x = 0; x < 8; x++) { B[x] = 0; } for (x = 0; x < 18; x += 2) { /* encrypt it */ blowfish_ecb_encrypt(B, B, skey); /* copy it */ LOAD32H(skey->blowfish.K[x], &B[0]); LOAD32H(skey->blowfish.K[x+1], &B[4]); } /* encrypt S array */ for (x = 0; x < 4; x++) { for (y = 0; y < 256; y += 2) { /* encrypt it */ blowfish_ecb_encrypt(B, B, skey); /* copy it */ LOAD32H(skey->blowfish.S[x][y], &B[0]); LOAD32H(skey->blowfish.S[x][y+1], &B[4]); } } #ifdef LTC_CLEAN_STACK zeromem(B, sizeof(B)); #endif return CRYPT_OK; } #ifndef __GNUC__ #define F(x) ((S1[byte(x,3)] + S2[byte(x,2)]) ^ S3[byte(x,1)]) + S4[byte(x,0)] #else #define F(x) ((skey->blowfish.S[0][byte(x,3)] + skey->blowfish.S[1][byte(x,2)]) ^ skey->blowfish.S[2][byte(x,1)]) + skey->blowfish.S[3][byte(x,0)] #endif /** Encrypts a block of text with Blowfish @param pt The input plaintext (8 bytes) @param ct The output ciphertext (8 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ #ifdef LTC_CLEAN_STACK static int _blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) #else int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) #endif { ulong32 L, R; int r; #ifndef __GNUC__ ulong32 *S1, *S2, *S3, *S4; #endif LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); #ifndef __GNUC__ S1 = skey->blowfish.S[0]; S2 = skey->blowfish.S[1]; S3 = skey->blowfish.S[2]; S4 = skey->blowfish.S[3]; #endif /* load it */ LOAD32H(L, &pt[0]); LOAD32H(R, &pt[4]); /* do 16 rounds */ for (r = 0; r < 16; ) { L ^= skey->blowfish.K[r++]; R ^= F(L); R ^= skey->blowfish.K[r++]; L ^= F(R); L ^= skey->blowfish.K[r++]; R ^= F(L); R ^= skey->blowfish.K[r++]; L ^= F(R); } /* last keying */ R ^= skey->blowfish.K[17]; L ^= skey->blowfish.K[16]; /* store */ STORE32H(R, &ct[0]); STORE32H(L, &ct[4]); return CRYPT_OK; } #ifdef LTC_CLEAN_STACK int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) { int err = _blowfish_ecb_encrypt(pt, ct, skey); burn_stack(sizeof(ulong32) * 2 + sizeof(int)); return err; } #endif /** Decrypts a block of text with Blowfish @param ct The input ciphertext (8 bytes) @param pt The output plaintext (8 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ #ifdef LTC_CLEAN_STACK static int _blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) #else int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) #endif { ulong32 L, R; int r; #ifndef __GNUC__ ulong32 *S1, *S2, *S3, *S4; #endif LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); #ifndef __GNUC__ S1 = skey->blowfish.S[0]; S2 = skey->blowfish.S[1]; S3 = skey->blowfish.S[2]; S4 = skey->blowfish.S[3]; #endif /* load it */ LOAD32H(R, &ct[0]); LOAD32H(L, &ct[4]); /* undo last keying */ R ^= skey->blowfish.K[17]; L ^= skey->blowfish.K[16]; /* do 16 rounds */ for (r = 15; r > 0; ) { L ^= F(R); R ^= skey->blowfish.K[r--]; R ^= F(L); L ^= skey->blowfish.K[r--]; L ^= F(R); R ^= skey->blowfish.K[r--]; R ^= F(L); L ^= skey->blowfish.K[r--]; } /* store */ STORE32H(L, &pt[0]); STORE32H(R, &pt[4]); return CRYPT_OK; } #ifdef LTC_CLEAN_STACK int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) { int err = _blowfish_ecb_decrypt(ct, pt, skey); burn_stack(sizeof(ulong32) * 2 + sizeof(int)); return err; } #endif /** Performs a self-test of the Blowfish block cipher @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled */ int blowfish_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else int err; symmetric_key key; static const struct { unsigned char key[8], pt[8], ct[8]; } tests[] = { { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, { 0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78} }, { { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, { 0x51, 0x86, 0x6F, 0xD5, 0xB8, 0x5E, 0xCB, 0x8A} }, { { 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, { 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, { 0x7D, 0x85, 0x6F, 0x9A, 0x61, 0x30, 0x63, 0xF2} } }; unsigned char tmp[2][8]; int x, y; for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { /* setup key */ if ((err = blowfish_setup(tests[x].key, 8, 16, &key)) != CRYPT_OK) { return err; } /* encrypt and decrypt */ blowfish_ecb_encrypt(tests[x].pt, tmp[0], &key); blowfish_ecb_decrypt(tmp[0], tmp[1], &key); /* compare */ if ((XMEMCMP(tmp[0], tests[x].ct, 8) != 0) || (XMEMCMP(tmp[1], tests[x].pt, 8) != 0)) { return CRYPT_FAIL_TESTVECTOR; } /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ for (y = 0; y < 8; y++) tmp[0][y] = 0; for (y = 0; y < 1000; y++) blowfish_ecb_encrypt(tmp[0], tmp[0], &key); for (y = 0; y < 1000; y++) blowfish_ecb_decrypt(tmp[0], tmp[0], &key); for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; } return CRYPT_OK; #endif } /** Terminate the context @param skey The scheduled key */ void blowfish_done(symmetric_key *skey) { } /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. @return CRYPT_OK if the input key size is acceptable. */ int blowfish_keysize(int *keysize) { LTC_ARGCHK(keysize != NULL); if (*keysize < 8) { return CRYPT_INVALID_KEYSIZE; } else if (*keysize > 56) { *keysize = 56; } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/blowfish.c,v $ */ /* $Revision: 1.14 $ */ /* $Date: 2007/05/12 14:20:27 $ */ libtomcrypt-1.17/src/ciphers/twofish/0000755000175100001440000000000010621351501016432 5ustar tomuserslibtomcrypt-1.17/src/ciphers/twofish/twofish_tab.c0000644000175100001440000013515410621351501021120 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file twofish_tab.c Twofish tables, Tom St Denis */ #ifdef LTC_TWOFISH_TABLES /* pre generated 8x8 tables from the four 4x4s */ static const unsigned char SBOX[2][256] = { { 0xa9, 0x67, 0xb3, 0xe8, 0x04, 0xfd, 0xa3, 0x76, 0x9a, 0x92, 0x80, 0x78, 0xe4, 0xdd, 0xd1, 0x38, 0x0d, 0xc6, 0x35, 0x98, 0x18, 0xf7, 0xec, 0x6c, 0x43, 0x75, 0x37, 0x26, 0xfa, 0x13, 0x94, 0x48, 0xf2, 0xd0, 0x8b, 0x30, 0x84, 0x54, 0xdf, 0x23, 0x19, 0x5b, 0x3d, 0x59, 0xf3, 0xae, 0xa2, 0x82, 0x63, 0x01, 0x83, 0x2e, 0xd9, 0x51, 0x9b, 0x7c, 0xa6, 0xeb, 0xa5, 0xbe, 0x16, 0x0c, 0xe3, 0x61, 0xc0, 0x8c, 0x3a, 0xf5, 0x73, 0x2c, 0x25, 0x0b, 0xbb, 0x4e, 0x89, 0x6b, 0x53, 0x6a, 0xb4, 0xf1, 0xe1, 0xe6, 0xbd, 0x45, 0xe2, 0xf4, 0xb6, 0x66, 0xcc, 0x95, 0x03, 0x56, 0xd4, 0x1c, 0x1e, 0xd7, 0xfb, 0xc3, 0x8e, 0xb5, 0xe9, 0xcf, 0xbf, 0xba, 0xea, 0x77, 0x39, 0xaf, 0x33, 0xc9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xad, 0x24, 0xcd, 0xf9, 0xd8, 0xe5, 0xc5, 0xb9, 0x4d, 0x44, 0x08, 0x86, 0xe7, 0xa1, 0x1d, 0xaa, 0xed, 0x06, 0x70, 0xb2, 0xd2, 0x41, 0x7b, 0xa0, 0x11, 0x31, 0xc2, 0x27, 0x90, 0x20, 0xf6, 0x60, 0xff, 0x96, 0x5c, 0xb1, 0xab, 0x9e, 0x9c, 0x52, 0x1b, 0x5f, 0x93, 0x0a, 0xef, 0x91, 0x85, 0x49, 0xee, 0x2d, 0x4f, 0x8f, 0x3b, 0x47, 0x87, 0x6d, 0x46, 0xd6, 0x3e, 0x69, 0x64, 0x2a, 0xce, 0xcb, 0x2f, 0xfc, 0x97, 0x05, 0x7a, 0xac, 0x7f, 0xd5, 0x1a, 0x4b, 0x0e, 0xa7, 0x5a, 0x28, 0x14, 0x3f, 0x29, 0x88, 0x3c, 0x4c, 0x02, 0xb8, 0xda, 0xb0, 0x17, 0x55, 0x1f, 0x8a, 0x7d, 0x57, 0xc7, 0x8d, 0x74, 0xb7, 0xc4, 0x9f, 0x72, 0x7e, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6e, 0x50, 0xde, 0x68, 0x65, 0xbc, 0xdb, 0xf8, 0xc8, 0xa8, 0x2b, 0x40, 0xdc, 0xfe, 0x32, 0xa4, 0xca, 0x10, 0x21, 0xf0, 0xd3, 0x5d, 0x0f, 0x00, 0x6f, 0x9d, 0x36, 0x42, 0x4a, 0x5e, 0xc1, 0xe0}, { 0x75, 0xf3, 0xc6, 0xf4, 0xdb, 0x7b, 0xfb, 0xc8, 0x4a, 0xd3, 0xe6, 0x6b, 0x45, 0x7d, 0xe8, 0x4b, 0xd6, 0x32, 0xd8, 0xfd, 0x37, 0x71, 0xf1, 0xe1, 0x30, 0x0f, 0xf8, 0x1b, 0x87, 0xfa, 0x06, 0x3f, 0x5e, 0xba, 0xae, 0x5b, 0x8a, 0x00, 0xbc, 0x9d, 0x6d, 0xc1, 0xb1, 0x0e, 0x80, 0x5d, 0xd2, 0xd5, 0xa0, 0x84, 0x07, 0x14, 0xb5, 0x90, 0x2c, 0xa3, 0xb2, 0x73, 0x4c, 0x54, 0x92, 0x74, 0x36, 0x51, 0x38, 0xb0, 0xbd, 0x5a, 0xfc, 0x60, 0x62, 0x96, 0x6c, 0x42, 0xf7, 0x10, 0x7c, 0x28, 0x27, 0x8c, 0x13, 0x95, 0x9c, 0xc7, 0x24, 0x46, 0x3b, 0x70, 0xca, 0xe3, 0x85, 0xcb, 0x11, 0xd0, 0x93, 0xb8, 0xa6, 0x83, 0x20, 0xff, 0x9f, 0x77, 0xc3, 0xcc, 0x03, 0x6f, 0x08, 0xbf, 0x40, 0xe7, 0x2b, 0xe2, 0x79, 0x0c, 0xaa, 0x82, 0x41, 0x3a, 0xea, 0xb9, 0xe4, 0x9a, 0xa4, 0x97, 0x7e, 0xda, 0x7a, 0x17, 0x66, 0x94, 0xa1, 0x1d, 0x3d, 0xf0, 0xde, 0xb3, 0x0b, 0x72, 0xa7, 0x1c, 0xef, 0xd1, 0x53, 0x3e, 0x8f, 0x33, 0x26, 0x5f, 0xec, 0x76, 0x2a, 0x49, 0x81, 0x88, 0xee, 0x21, 0xc4, 0x1a, 0xeb, 0xd9, 0xc5, 0x39, 0x99, 0xcd, 0xad, 0x31, 0x8b, 0x01, 0x18, 0x23, 0xdd, 0x1f, 0x4e, 0x2d, 0xf9, 0x48, 0x4f, 0xf2, 0x65, 0x8e, 0x78, 0x5c, 0x58, 0x19, 0x8d, 0xe5, 0x98, 0x57, 0x67, 0x7f, 0x05, 0x64, 0xaf, 0x63, 0xb6, 0xfe, 0xf5, 0xb7, 0x3c, 0xa5, 0xce, 0xe9, 0x68, 0x44, 0xe0, 0x4d, 0x43, 0x69, 0x29, 0x2e, 0xac, 0x15, 0x59, 0xa8, 0x0a, 0x9e, 0x6e, 0x47, 0xdf, 0x34, 0x35, 0x6a, 0xcf, 0xdc, 0x22, 0xc9, 0xc0, 0x9b, 0x89, 0xd4, 0xed, 0xab, 0x12, 0xa2, 0x0d, 0x52, 0xbb, 0x02, 0x2f, 0xa9, 0xd7, 0x61, 0x1e, 0xb4, 0x50, 0x04, 0xf6, 0xc2, 0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xbe, 0x91} }; /* the 4x4 MDS in a nicer format */ static const ulong32 mds_tab[4][256] = { { 0x00000000UL, 0xefef5b01UL, 0xb7b7b602UL, 0x5858ed03UL, 0x07070504UL, 0xe8e85e05UL, 0xb0b0b306UL, 0x5f5fe807UL, 0x0e0e0a08UL, 0xe1e15109UL, 0xb9b9bc0aUL, 0x5656e70bUL, 0x09090f0cUL, 0xe6e6540dUL, 0xbebeb90eUL, 0x5151e20fUL, 0x1c1c1410UL, 0xf3f34f11UL, 0xababa212UL, 0x4444f913UL, 0x1b1b1114UL, 0xf4f44a15UL, 0xacaca716UL, 0x4343fc17UL, 0x12121e18UL, 0xfdfd4519UL, 0xa5a5a81aUL, 0x4a4af31bUL, 0x15151b1cUL, 0xfafa401dUL, 0xa2a2ad1eUL, 0x4d4df61fUL, 0x38382820UL, 0xd7d77321UL, 0x8f8f9e22UL, 0x6060c523UL, 0x3f3f2d24UL, 0xd0d07625UL, 0x88889b26UL, 0x6767c027UL, 0x36362228UL, 0xd9d97929UL, 0x8181942aUL, 0x6e6ecf2bUL, 0x3131272cUL, 0xdede7c2dUL, 0x8686912eUL, 0x6969ca2fUL, 0x24243c30UL, 0xcbcb6731UL, 0x93938a32UL, 0x7c7cd133UL, 0x23233934UL, 0xcccc6235UL, 0x94948f36UL, 0x7b7bd437UL, 0x2a2a3638UL, 0xc5c56d39UL, 0x9d9d803aUL, 0x7272db3bUL, 0x2d2d333cUL, 0xc2c2683dUL, 0x9a9a853eUL, 0x7575de3fUL, 0x70705040UL, 0x9f9f0b41UL, 0xc7c7e642UL, 0x2828bd43UL, 0x77775544UL, 0x98980e45UL, 0xc0c0e346UL, 0x2f2fb847UL, 0x7e7e5a48UL, 0x91910149UL, 0xc9c9ec4aUL, 0x2626b74bUL, 0x79795f4cUL, 0x9696044dUL, 0xcecee94eUL, 0x2121b24fUL, 0x6c6c4450UL, 0x83831f51UL, 0xdbdbf252UL, 0x3434a953UL, 0x6b6b4154UL, 0x84841a55UL, 0xdcdcf756UL, 0x3333ac57UL, 0x62624e58UL, 0x8d8d1559UL, 0xd5d5f85aUL, 0x3a3aa35bUL, 0x65654b5cUL, 0x8a8a105dUL, 0xd2d2fd5eUL, 0x3d3da65fUL, 0x48487860UL, 0xa7a72361UL, 0xffffce62UL, 0x10109563UL, 0x4f4f7d64UL, 0xa0a02665UL, 0xf8f8cb66UL, 0x17179067UL, 0x46467268UL, 0xa9a92969UL, 0xf1f1c46aUL, 0x1e1e9f6bUL, 0x4141776cUL, 0xaeae2c6dUL, 0xf6f6c16eUL, 0x19199a6fUL, 0x54546c70UL, 0xbbbb3771UL, 0xe3e3da72UL, 0x0c0c8173UL, 0x53536974UL, 0xbcbc3275UL, 0xe4e4df76UL, 0x0b0b8477UL, 0x5a5a6678UL, 0xb5b53d79UL, 0xededd07aUL, 0x02028b7bUL, 0x5d5d637cUL, 0xb2b2387dUL, 0xeaead57eUL, 0x05058e7fUL, 0xe0e0a080UL, 0x0f0ffb81UL, 0x57571682UL, 0xb8b84d83UL, 0xe7e7a584UL, 0x0808fe85UL, 0x50501386UL, 0xbfbf4887UL, 0xeeeeaa88UL, 0x0101f189UL, 0x59591c8aUL, 0xb6b6478bUL, 0xe9e9af8cUL, 0x0606f48dUL, 0x5e5e198eUL, 0xb1b1428fUL, 0xfcfcb490UL, 0x1313ef91UL, 0x4b4b0292UL, 0xa4a45993UL, 0xfbfbb194UL, 0x1414ea95UL, 0x4c4c0796UL, 0xa3a35c97UL, 0xf2f2be98UL, 0x1d1de599UL, 0x4545089aUL, 0xaaaa539bUL, 0xf5f5bb9cUL, 0x1a1ae09dUL, 0x42420d9eUL, 0xadad569fUL, 0xd8d888a0UL, 0x3737d3a1UL, 0x6f6f3ea2UL, 0x808065a3UL, 0xdfdf8da4UL, 0x3030d6a5UL, 0x68683ba6UL, 0x878760a7UL, 0xd6d682a8UL, 0x3939d9a9UL, 0x616134aaUL, 0x8e8e6fabUL, 0xd1d187acUL, 0x3e3edcadUL, 0x666631aeUL, 0x89896aafUL, 0xc4c49cb0UL, 0x2b2bc7b1UL, 0x73732ab2UL, 0x9c9c71b3UL, 0xc3c399b4UL, 0x2c2cc2b5UL, 0x74742fb6UL, 0x9b9b74b7UL, 0xcaca96b8UL, 0x2525cdb9UL, 0x7d7d20baUL, 0x92927bbbUL, 0xcdcd93bcUL, 0x2222c8bdUL, 0x7a7a25beUL, 0x95957ebfUL, 0x9090f0c0UL, 0x7f7fabc1UL, 0x272746c2UL, 0xc8c81dc3UL, 0x9797f5c4UL, 0x7878aec5UL, 0x202043c6UL, 0xcfcf18c7UL, 0x9e9efac8UL, 0x7171a1c9UL, 0x29294ccaUL, 0xc6c617cbUL, 0x9999ffccUL, 0x7676a4cdUL, 0x2e2e49ceUL, 0xc1c112cfUL, 0x8c8ce4d0UL, 0x6363bfd1UL, 0x3b3b52d2UL, 0xd4d409d3UL, 0x8b8be1d4UL, 0x6464bad5UL, 0x3c3c57d6UL, 0xd3d30cd7UL, 0x8282eed8UL, 0x6d6db5d9UL, 0x353558daUL, 0xdada03dbUL, 0x8585ebdcUL, 0x6a6ab0ddUL, 0x32325ddeUL, 0xdddd06dfUL, 0xa8a8d8e0UL, 0x474783e1UL, 0x1f1f6ee2UL, 0xf0f035e3UL, 0xafafdde4UL, 0x404086e5UL, 0x18186be6UL, 0xf7f730e7UL, 0xa6a6d2e8UL, 0x494989e9UL, 0x111164eaUL, 0xfefe3febUL, 0xa1a1d7ecUL, 0x4e4e8cedUL, 0x161661eeUL, 0xf9f93aefUL, 0xb4b4ccf0UL, 0x5b5b97f1UL, 0x03037af2UL, 0xecec21f3UL, 0xb3b3c9f4UL, 0x5c5c92f5UL, 0x04047ff6UL, 0xebeb24f7UL, 0xbabac6f8UL, 0x55559df9UL, 0x0d0d70faUL, 0xe2e22bfbUL, 0xbdbdc3fcUL, 0x525298fdUL, 0x0a0a75feUL, 0xe5e52effUL }, { 0x00000000UL, 0x015befefUL, 0x02b6b7b7UL, 0x03ed5858UL, 0x04050707UL, 0x055ee8e8UL, 0x06b3b0b0UL, 0x07e85f5fUL, 0x080a0e0eUL, 0x0951e1e1UL, 0x0abcb9b9UL, 0x0be75656UL, 0x0c0f0909UL, 0x0d54e6e6UL, 0x0eb9bebeUL, 0x0fe25151UL, 0x10141c1cUL, 0x114ff3f3UL, 0x12a2ababUL, 0x13f94444UL, 0x14111b1bUL, 0x154af4f4UL, 0x16a7acacUL, 0x17fc4343UL, 0x181e1212UL, 0x1945fdfdUL, 0x1aa8a5a5UL, 0x1bf34a4aUL, 0x1c1b1515UL, 0x1d40fafaUL, 0x1eada2a2UL, 0x1ff64d4dUL, 0x20283838UL, 0x2173d7d7UL, 0x229e8f8fUL, 0x23c56060UL, 0x242d3f3fUL, 0x2576d0d0UL, 0x269b8888UL, 0x27c06767UL, 0x28223636UL, 0x2979d9d9UL, 0x2a948181UL, 0x2bcf6e6eUL, 0x2c273131UL, 0x2d7cdedeUL, 0x2e918686UL, 0x2fca6969UL, 0x303c2424UL, 0x3167cbcbUL, 0x328a9393UL, 0x33d17c7cUL, 0x34392323UL, 0x3562ccccUL, 0x368f9494UL, 0x37d47b7bUL, 0x38362a2aUL, 0x396dc5c5UL, 0x3a809d9dUL, 0x3bdb7272UL, 0x3c332d2dUL, 0x3d68c2c2UL, 0x3e859a9aUL, 0x3fde7575UL, 0x40507070UL, 0x410b9f9fUL, 0x42e6c7c7UL, 0x43bd2828UL, 0x44557777UL, 0x450e9898UL, 0x46e3c0c0UL, 0x47b82f2fUL, 0x485a7e7eUL, 0x49019191UL, 0x4aecc9c9UL, 0x4bb72626UL, 0x4c5f7979UL, 0x4d049696UL, 0x4ee9ceceUL, 0x4fb22121UL, 0x50446c6cUL, 0x511f8383UL, 0x52f2dbdbUL, 0x53a93434UL, 0x54416b6bUL, 0x551a8484UL, 0x56f7dcdcUL, 0x57ac3333UL, 0x584e6262UL, 0x59158d8dUL, 0x5af8d5d5UL, 0x5ba33a3aUL, 0x5c4b6565UL, 0x5d108a8aUL, 0x5efdd2d2UL, 0x5fa63d3dUL, 0x60784848UL, 0x6123a7a7UL, 0x62ceffffUL, 0x63951010UL, 0x647d4f4fUL, 0x6526a0a0UL, 0x66cbf8f8UL, 0x67901717UL, 0x68724646UL, 0x6929a9a9UL, 0x6ac4f1f1UL, 0x6b9f1e1eUL, 0x6c774141UL, 0x6d2caeaeUL, 0x6ec1f6f6UL, 0x6f9a1919UL, 0x706c5454UL, 0x7137bbbbUL, 0x72dae3e3UL, 0x73810c0cUL, 0x74695353UL, 0x7532bcbcUL, 0x76dfe4e4UL, 0x77840b0bUL, 0x78665a5aUL, 0x793db5b5UL, 0x7ad0ededUL, 0x7b8b0202UL, 0x7c635d5dUL, 0x7d38b2b2UL, 0x7ed5eaeaUL, 0x7f8e0505UL, 0x80a0e0e0UL, 0x81fb0f0fUL, 0x82165757UL, 0x834db8b8UL, 0x84a5e7e7UL, 0x85fe0808UL, 0x86135050UL, 0x8748bfbfUL, 0x88aaeeeeUL, 0x89f10101UL, 0x8a1c5959UL, 0x8b47b6b6UL, 0x8cafe9e9UL, 0x8df40606UL, 0x8e195e5eUL, 0x8f42b1b1UL, 0x90b4fcfcUL, 0x91ef1313UL, 0x92024b4bUL, 0x9359a4a4UL, 0x94b1fbfbUL, 0x95ea1414UL, 0x96074c4cUL, 0x975ca3a3UL, 0x98bef2f2UL, 0x99e51d1dUL, 0x9a084545UL, 0x9b53aaaaUL, 0x9cbbf5f5UL, 0x9de01a1aUL, 0x9e0d4242UL, 0x9f56adadUL, 0xa088d8d8UL, 0xa1d33737UL, 0xa23e6f6fUL, 0xa3658080UL, 0xa48ddfdfUL, 0xa5d63030UL, 0xa63b6868UL, 0xa7608787UL, 0xa882d6d6UL, 0xa9d93939UL, 0xaa346161UL, 0xab6f8e8eUL, 0xac87d1d1UL, 0xaddc3e3eUL, 0xae316666UL, 0xaf6a8989UL, 0xb09cc4c4UL, 0xb1c72b2bUL, 0xb22a7373UL, 0xb3719c9cUL, 0xb499c3c3UL, 0xb5c22c2cUL, 0xb62f7474UL, 0xb7749b9bUL, 0xb896cacaUL, 0xb9cd2525UL, 0xba207d7dUL, 0xbb7b9292UL, 0xbc93cdcdUL, 0xbdc82222UL, 0xbe257a7aUL, 0xbf7e9595UL, 0xc0f09090UL, 0xc1ab7f7fUL, 0xc2462727UL, 0xc31dc8c8UL, 0xc4f59797UL, 0xc5ae7878UL, 0xc6432020UL, 0xc718cfcfUL, 0xc8fa9e9eUL, 0xc9a17171UL, 0xca4c2929UL, 0xcb17c6c6UL, 0xccff9999UL, 0xcda47676UL, 0xce492e2eUL, 0xcf12c1c1UL, 0xd0e48c8cUL, 0xd1bf6363UL, 0xd2523b3bUL, 0xd309d4d4UL, 0xd4e18b8bUL, 0xd5ba6464UL, 0xd6573c3cUL, 0xd70cd3d3UL, 0xd8ee8282UL, 0xd9b56d6dUL, 0xda583535UL, 0xdb03dadaUL, 0xdceb8585UL, 0xddb06a6aUL, 0xde5d3232UL, 0xdf06ddddUL, 0xe0d8a8a8UL, 0xe1834747UL, 0xe26e1f1fUL, 0xe335f0f0UL, 0xe4ddafafUL, 0xe5864040UL, 0xe66b1818UL, 0xe730f7f7UL, 0xe8d2a6a6UL, 0xe9894949UL, 0xea641111UL, 0xeb3ffefeUL, 0xecd7a1a1UL, 0xed8c4e4eUL, 0xee611616UL, 0xef3af9f9UL, 0xf0ccb4b4UL, 0xf1975b5bUL, 0xf27a0303UL, 0xf321ececUL, 0xf4c9b3b3UL, 0xf5925c5cUL, 0xf67f0404UL, 0xf724ebebUL, 0xf8c6babaUL, 0xf99d5555UL, 0xfa700d0dUL, 0xfb2be2e2UL, 0xfcc3bdbdUL, 0xfd985252UL, 0xfe750a0aUL, 0xff2ee5e5UL }, { 0x00000000UL, 0xef01ef5bUL, 0xb702b7b6UL, 0x580358edUL, 0x07040705UL, 0xe805e85eUL, 0xb006b0b3UL, 0x5f075fe8UL, 0x0e080e0aUL, 0xe109e151UL, 0xb90ab9bcUL, 0x560b56e7UL, 0x090c090fUL, 0xe60de654UL, 0xbe0ebeb9UL, 0x510f51e2UL, 0x1c101c14UL, 0xf311f34fUL, 0xab12aba2UL, 0x441344f9UL, 0x1b141b11UL, 0xf415f44aUL, 0xac16aca7UL, 0x431743fcUL, 0x1218121eUL, 0xfd19fd45UL, 0xa51aa5a8UL, 0x4a1b4af3UL, 0x151c151bUL, 0xfa1dfa40UL, 0xa21ea2adUL, 0x4d1f4df6UL, 0x38203828UL, 0xd721d773UL, 0x8f228f9eUL, 0x602360c5UL, 0x3f243f2dUL, 0xd025d076UL, 0x8826889bUL, 0x672767c0UL, 0x36283622UL, 0xd929d979UL, 0x812a8194UL, 0x6e2b6ecfUL, 0x312c3127UL, 0xde2dde7cUL, 0x862e8691UL, 0x692f69caUL, 0x2430243cUL, 0xcb31cb67UL, 0x9332938aUL, 0x7c337cd1UL, 0x23342339UL, 0xcc35cc62UL, 0x9436948fUL, 0x7b377bd4UL, 0x2a382a36UL, 0xc539c56dUL, 0x9d3a9d80UL, 0x723b72dbUL, 0x2d3c2d33UL, 0xc23dc268UL, 0x9a3e9a85UL, 0x753f75deUL, 0x70407050UL, 0x9f419f0bUL, 0xc742c7e6UL, 0x284328bdUL, 0x77447755UL, 0x9845980eUL, 0xc046c0e3UL, 0x2f472fb8UL, 0x7e487e5aUL, 0x91499101UL, 0xc94ac9ecUL, 0x264b26b7UL, 0x794c795fUL, 0x964d9604UL, 0xce4ecee9UL, 0x214f21b2UL, 0x6c506c44UL, 0x8351831fUL, 0xdb52dbf2UL, 0x345334a9UL, 0x6b546b41UL, 0x8455841aUL, 0xdc56dcf7UL, 0x335733acUL, 0x6258624eUL, 0x8d598d15UL, 0xd55ad5f8UL, 0x3a5b3aa3UL, 0x655c654bUL, 0x8a5d8a10UL, 0xd25ed2fdUL, 0x3d5f3da6UL, 0x48604878UL, 0xa761a723UL, 0xff62ffceUL, 0x10631095UL, 0x4f644f7dUL, 0xa065a026UL, 0xf866f8cbUL, 0x17671790UL, 0x46684672UL, 0xa969a929UL, 0xf16af1c4UL, 0x1e6b1e9fUL, 0x416c4177UL, 0xae6dae2cUL, 0xf66ef6c1UL, 0x196f199aUL, 0x5470546cUL, 0xbb71bb37UL, 0xe372e3daUL, 0x0c730c81UL, 0x53745369UL, 0xbc75bc32UL, 0xe476e4dfUL, 0x0b770b84UL, 0x5a785a66UL, 0xb579b53dUL, 0xed7aedd0UL, 0x027b028bUL, 0x5d7c5d63UL, 0xb27db238UL, 0xea7eead5UL, 0x057f058eUL, 0xe080e0a0UL, 0x0f810ffbUL, 0x57825716UL, 0xb883b84dUL, 0xe784e7a5UL, 0x088508feUL, 0x50865013UL, 0xbf87bf48UL, 0xee88eeaaUL, 0x018901f1UL, 0x598a591cUL, 0xb68bb647UL, 0xe98ce9afUL, 0x068d06f4UL, 0x5e8e5e19UL, 0xb18fb142UL, 0xfc90fcb4UL, 0x139113efUL, 0x4b924b02UL, 0xa493a459UL, 0xfb94fbb1UL, 0x149514eaUL, 0x4c964c07UL, 0xa397a35cUL, 0xf298f2beUL, 0x1d991de5UL, 0x459a4508UL, 0xaa9baa53UL, 0xf59cf5bbUL, 0x1a9d1ae0UL, 0x429e420dUL, 0xad9fad56UL, 0xd8a0d888UL, 0x37a137d3UL, 0x6fa26f3eUL, 0x80a38065UL, 0xdfa4df8dUL, 0x30a530d6UL, 0x68a6683bUL, 0x87a78760UL, 0xd6a8d682UL, 0x39a939d9UL, 0x61aa6134UL, 0x8eab8e6fUL, 0xd1acd187UL, 0x3ead3edcUL, 0x66ae6631UL, 0x89af896aUL, 0xc4b0c49cUL, 0x2bb12bc7UL, 0x73b2732aUL, 0x9cb39c71UL, 0xc3b4c399UL, 0x2cb52cc2UL, 0x74b6742fUL, 0x9bb79b74UL, 0xcab8ca96UL, 0x25b925cdUL, 0x7dba7d20UL, 0x92bb927bUL, 0xcdbccd93UL, 0x22bd22c8UL, 0x7abe7a25UL, 0x95bf957eUL, 0x90c090f0UL, 0x7fc17fabUL, 0x27c22746UL, 0xc8c3c81dUL, 0x97c497f5UL, 0x78c578aeUL, 0x20c62043UL, 0xcfc7cf18UL, 0x9ec89efaUL, 0x71c971a1UL, 0x29ca294cUL, 0xc6cbc617UL, 0x99cc99ffUL, 0x76cd76a4UL, 0x2ece2e49UL, 0xc1cfc112UL, 0x8cd08ce4UL, 0x63d163bfUL, 0x3bd23b52UL, 0xd4d3d409UL, 0x8bd48be1UL, 0x64d564baUL, 0x3cd63c57UL, 0xd3d7d30cUL, 0x82d882eeUL, 0x6dd96db5UL, 0x35da3558UL, 0xdadbda03UL, 0x85dc85ebUL, 0x6add6ab0UL, 0x32de325dUL, 0xdddfdd06UL, 0xa8e0a8d8UL, 0x47e14783UL, 0x1fe21f6eUL, 0xf0e3f035UL, 0xafe4afddUL, 0x40e54086UL, 0x18e6186bUL, 0xf7e7f730UL, 0xa6e8a6d2UL, 0x49e94989UL, 0x11ea1164UL, 0xfeebfe3fUL, 0xa1eca1d7UL, 0x4eed4e8cUL, 0x16ee1661UL, 0xf9eff93aUL, 0xb4f0b4ccUL, 0x5bf15b97UL, 0x03f2037aUL, 0xecf3ec21UL, 0xb3f4b3c9UL, 0x5cf55c92UL, 0x04f6047fUL, 0xebf7eb24UL, 0xbaf8bac6UL, 0x55f9559dUL, 0x0dfa0d70UL, 0xe2fbe22bUL, 0xbdfcbdc3UL, 0x52fd5298UL, 0x0afe0a75UL, 0xe5ffe52eUL }, { 0x00000000UL, 0x5bef015bUL, 0xb6b702b6UL, 0xed5803edUL, 0x05070405UL, 0x5ee8055eUL, 0xb3b006b3UL, 0xe85f07e8UL, 0x0a0e080aUL, 0x51e10951UL, 0xbcb90abcUL, 0xe7560be7UL, 0x0f090c0fUL, 0x54e60d54UL, 0xb9be0eb9UL, 0xe2510fe2UL, 0x141c1014UL, 0x4ff3114fUL, 0xa2ab12a2UL, 0xf94413f9UL, 0x111b1411UL, 0x4af4154aUL, 0xa7ac16a7UL, 0xfc4317fcUL, 0x1e12181eUL, 0x45fd1945UL, 0xa8a51aa8UL, 0xf34a1bf3UL, 0x1b151c1bUL, 0x40fa1d40UL, 0xada21eadUL, 0xf64d1ff6UL, 0x28382028UL, 0x73d72173UL, 0x9e8f229eUL, 0xc56023c5UL, 0x2d3f242dUL, 0x76d02576UL, 0x9b88269bUL, 0xc06727c0UL, 0x22362822UL, 0x79d92979UL, 0x94812a94UL, 0xcf6e2bcfUL, 0x27312c27UL, 0x7cde2d7cUL, 0x91862e91UL, 0xca692fcaUL, 0x3c24303cUL, 0x67cb3167UL, 0x8a93328aUL, 0xd17c33d1UL, 0x39233439UL, 0x62cc3562UL, 0x8f94368fUL, 0xd47b37d4UL, 0x362a3836UL, 0x6dc5396dUL, 0x809d3a80UL, 0xdb723bdbUL, 0x332d3c33UL, 0x68c23d68UL, 0x859a3e85UL, 0xde753fdeUL, 0x50704050UL, 0x0b9f410bUL, 0xe6c742e6UL, 0xbd2843bdUL, 0x55774455UL, 0x0e98450eUL, 0xe3c046e3UL, 0xb82f47b8UL, 0x5a7e485aUL, 0x01914901UL, 0xecc94aecUL, 0xb7264bb7UL, 0x5f794c5fUL, 0x04964d04UL, 0xe9ce4ee9UL, 0xb2214fb2UL, 0x446c5044UL, 0x1f83511fUL, 0xf2db52f2UL, 0xa93453a9UL, 0x416b5441UL, 0x1a84551aUL, 0xf7dc56f7UL, 0xac3357acUL, 0x4e62584eUL, 0x158d5915UL, 0xf8d55af8UL, 0xa33a5ba3UL, 0x4b655c4bUL, 0x108a5d10UL, 0xfdd25efdUL, 0xa63d5fa6UL, 0x78486078UL, 0x23a76123UL, 0xceff62ceUL, 0x95106395UL, 0x7d4f647dUL, 0x26a06526UL, 0xcbf866cbUL, 0x90176790UL, 0x72466872UL, 0x29a96929UL, 0xc4f16ac4UL, 0x9f1e6b9fUL, 0x77416c77UL, 0x2cae6d2cUL, 0xc1f66ec1UL, 0x9a196f9aUL, 0x6c54706cUL, 0x37bb7137UL, 0xdae372daUL, 0x810c7381UL, 0x69537469UL, 0x32bc7532UL, 0xdfe476dfUL, 0x840b7784UL, 0x665a7866UL, 0x3db5793dUL, 0xd0ed7ad0UL, 0x8b027b8bUL, 0x635d7c63UL, 0x38b27d38UL, 0xd5ea7ed5UL, 0x8e057f8eUL, 0xa0e080a0UL, 0xfb0f81fbUL, 0x16578216UL, 0x4db8834dUL, 0xa5e784a5UL, 0xfe0885feUL, 0x13508613UL, 0x48bf8748UL, 0xaaee88aaUL, 0xf10189f1UL, 0x1c598a1cUL, 0x47b68b47UL, 0xafe98cafUL, 0xf4068df4UL, 0x195e8e19UL, 0x42b18f42UL, 0xb4fc90b4UL, 0xef1391efUL, 0x024b9202UL, 0x59a49359UL, 0xb1fb94b1UL, 0xea1495eaUL, 0x074c9607UL, 0x5ca3975cUL, 0xbef298beUL, 0xe51d99e5UL, 0x08459a08UL, 0x53aa9b53UL, 0xbbf59cbbUL, 0xe01a9de0UL, 0x0d429e0dUL, 0x56ad9f56UL, 0x88d8a088UL, 0xd337a1d3UL, 0x3e6fa23eUL, 0x6580a365UL, 0x8ddfa48dUL, 0xd630a5d6UL, 0x3b68a63bUL, 0x6087a760UL, 0x82d6a882UL, 0xd939a9d9UL, 0x3461aa34UL, 0x6f8eab6fUL, 0x87d1ac87UL, 0xdc3eaddcUL, 0x3166ae31UL, 0x6a89af6aUL, 0x9cc4b09cUL, 0xc72bb1c7UL, 0x2a73b22aUL, 0x719cb371UL, 0x99c3b499UL, 0xc22cb5c2UL, 0x2f74b62fUL, 0x749bb774UL, 0x96cab896UL, 0xcd25b9cdUL, 0x207dba20UL, 0x7b92bb7bUL, 0x93cdbc93UL, 0xc822bdc8UL, 0x257abe25UL, 0x7e95bf7eUL, 0xf090c0f0UL, 0xab7fc1abUL, 0x4627c246UL, 0x1dc8c31dUL, 0xf597c4f5UL, 0xae78c5aeUL, 0x4320c643UL, 0x18cfc718UL, 0xfa9ec8faUL, 0xa171c9a1UL, 0x4c29ca4cUL, 0x17c6cb17UL, 0xff99ccffUL, 0xa476cda4UL, 0x492ece49UL, 0x12c1cf12UL, 0xe48cd0e4UL, 0xbf63d1bfUL, 0x523bd252UL, 0x09d4d309UL, 0xe18bd4e1UL, 0xba64d5baUL, 0x573cd657UL, 0x0cd3d70cUL, 0xee82d8eeUL, 0xb56dd9b5UL, 0x5835da58UL, 0x03dadb03UL, 0xeb85dcebUL, 0xb06addb0UL, 0x5d32de5dUL, 0x06dddf06UL, 0xd8a8e0d8UL, 0x8347e183UL, 0x6e1fe26eUL, 0x35f0e335UL, 0xddafe4ddUL, 0x8640e586UL, 0x6b18e66bUL, 0x30f7e730UL, 0xd2a6e8d2UL, 0x8949e989UL, 0x6411ea64UL, 0x3ffeeb3fUL, 0xd7a1ecd7UL, 0x8c4eed8cUL, 0x6116ee61UL, 0x3af9ef3aUL, 0xccb4f0ccUL, 0x975bf197UL, 0x7a03f27aUL, 0x21ecf321UL, 0xc9b3f4c9UL, 0x925cf592UL, 0x7f04f67fUL, 0x24ebf724UL, 0xc6baf8c6UL, 0x9d55f99dUL, 0x700dfa70UL, 0x2be2fb2bUL, 0xc3bdfcc3UL, 0x9852fd98UL, 0x750afe75UL, 0x2ee5ff2eUL }}; #ifdef LTC_TWOFISH_ALL_TABLES /* the 4x8 RS transform */ static const ulong32 rs_tab0[256] = { 0x00000000LU, 0xa402a401LU, 0x05040502LU, 0xa106a103LU, 0x0a080a04LU, 0xae0aae05LU, 0x0f0c0f06LU, 0xab0eab07LU, 0x14101408LU, 0xb012b009LU, 0x1114110aLU, 0xb516b50bLU, 0x1e181e0cLU, 0xba1aba0dLU, 0x1b1c1b0eLU, 0xbf1ebf0fLU, 0x28202810LU, 0x8c228c11LU, 0x2d242d12LU, 0x89268913LU, 0x22282214LU, 0x862a8615LU, 0x272c2716LU, 0x832e8317LU, 0x3c303c18LU, 0x98329819LU, 0x3934391aLU, 0x9d369d1bLU, 0x3638361cLU, 0x923a921dLU, 0x333c331eLU, 0x973e971fLU, 0x50405020LU, 0xf442f421LU, 0x55445522LU, 0xf146f123LU, 0x5a485a24LU, 0xfe4afe25LU, 0x5f4c5f26LU, 0xfb4efb27LU, 0x44504428LU, 0xe052e029LU, 0x4154412aLU, 0xe556e52bLU, 0x4e584e2cLU, 0xea5aea2dLU, 0x4b5c4b2eLU, 0xef5eef2fLU, 0x78607830LU, 0xdc62dc31LU, 0x7d647d32LU, 0xd966d933LU, 0x72687234LU, 0xd66ad635LU, 0x776c7736LU, 0xd36ed337LU, 0x6c706c38LU, 0xc872c839LU, 0x6974693aLU, 0xcd76cd3bLU, 0x6678663cLU, 0xc27ac23dLU, 0x637c633eLU, 0xc77ec73fLU, 0xa080a040LU, 0x04820441LU, 0xa584a542LU, 0x01860143LU, 0xaa88aa44LU, 0x0e8a0e45LU, 0xaf8caf46LU, 0x0b8e0b47LU, 0xb490b448LU, 0x10921049LU, 0xb194b14aLU, 0x1596154bLU, 0xbe98be4cLU, 0x1a9a1a4dLU, 0xbb9cbb4eLU, 0x1f9e1f4fLU, 0x88a08850LU, 0x2ca22c51LU, 0x8da48d52LU, 0x29a62953LU, 0x82a88254LU, 0x26aa2655LU, 0x87ac8756LU, 0x23ae2357LU, 0x9cb09c58LU, 0x38b23859LU, 0x99b4995aLU, 0x3db63d5bLU, 0x96b8965cLU, 0x32ba325dLU, 0x93bc935eLU, 0x37be375fLU, 0xf0c0f060LU, 0x54c25461LU, 0xf5c4f562LU, 0x51c65163LU, 0xfac8fa64LU, 0x5eca5e65LU, 0xffccff66LU, 0x5bce5b67LU, 0xe4d0e468LU, 0x40d24069LU, 0xe1d4e16aLU, 0x45d6456bLU, 0xeed8ee6cLU, 0x4ada4a6dLU, 0xebdceb6eLU, 0x4fde4f6fLU, 0xd8e0d870LU, 0x7ce27c71LU, 0xdde4dd72LU, 0x79e67973LU, 0xd2e8d274LU, 0x76ea7675LU, 0xd7ecd776LU, 0x73ee7377LU, 0xccf0cc78LU, 0x68f26879LU, 0xc9f4c97aLU, 0x6df66d7bLU, 0xc6f8c67cLU, 0x62fa627dLU, 0xc3fcc37eLU, 0x67fe677fLU, 0x0d4d0d80LU, 0xa94fa981LU, 0x08490882LU, 0xac4bac83LU, 0x07450784LU, 0xa347a385LU, 0x02410286LU, 0xa643a687LU, 0x195d1988LU, 0xbd5fbd89LU, 0x1c591c8aLU, 0xb85bb88bLU, 0x1355138cLU, 0xb757b78dLU, 0x1651168eLU, 0xb253b28fLU, 0x256d2590LU, 0x816f8191LU, 0x20692092LU, 0x846b8493LU, 0x2f652f94LU, 0x8b678b95LU, 0x2a612a96LU, 0x8e638e97LU, 0x317d3198LU, 0x957f9599LU, 0x3479349aLU, 0x907b909bLU, 0x3b753b9cLU, 0x9f779f9dLU, 0x3e713e9eLU, 0x9a739a9fLU, 0x5d0d5da0LU, 0xf90ff9a1LU, 0x580958a2LU, 0xfc0bfca3LU, 0x570557a4LU, 0xf307f3a5LU, 0x520152a6LU, 0xf603f6a7LU, 0x491d49a8LU, 0xed1feda9LU, 0x4c194caaLU, 0xe81be8abLU, 0x431543acLU, 0xe717e7adLU, 0x461146aeLU, 0xe213e2afLU, 0x752d75b0LU, 0xd12fd1b1LU, 0x702970b2LU, 0xd42bd4b3LU, 0x7f257fb4LU, 0xdb27dbb5LU, 0x7a217ab6LU, 0xde23deb7LU, 0x613d61b8LU, 0xc53fc5b9LU, 0x643964baLU, 0xc03bc0bbLU, 0x6b356bbcLU, 0xcf37cfbdLU, 0x6e316ebeLU, 0xca33cabfLU, 0xadcdadc0LU, 0x09cf09c1LU, 0xa8c9a8c2LU, 0x0ccb0cc3LU, 0xa7c5a7c4LU, 0x03c703c5LU, 0xa2c1a2c6LU, 0x06c306c7LU, 0xb9ddb9c8LU, 0x1ddf1dc9LU, 0xbcd9bccaLU, 0x18db18cbLU, 0xb3d5b3ccLU, 0x17d717cdLU, 0xb6d1b6ceLU, 0x12d312cfLU, 0x85ed85d0LU, 0x21ef21d1LU, 0x80e980d2LU, 0x24eb24d3LU, 0x8fe58fd4LU, 0x2be72bd5LU, 0x8ae18ad6LU, 0x2ee32ed7LU, 0x91fd91d8LU, 0x35ff35d9LU, 0x94f994daLU, 0x30fb30dbLU, 0x9bf59bdcLU, 0x3ff73fddLU, 0x9ef19edeLU, 0x3af33adfLU, 0xfd8dfde0LU, 0x598f59e1LU, 0xf889f8e2LU, 0x5c8b5ce3LU, 0xf785f7e4LU, 0x538753e5LU, 0xf281f2e6LU, 0x568356e7LU, 0xe99de9e8LU, 0x4d9f4de9LU, 0xec99eceaLU, 0x489b48ebLU, 0xe395e3ecLU, 0x479747edLU, 0xe691e6eeLU, 0x429342efLU, 0xd5add5f0LU, 0x71af71f1LU, 0xd0a9d0f2LU, 0x74ab74f3LU, 0xdfa5dff4LU, 0x7ba77bf5LU, 0xdaa1daf6LU, 0x7ea37ef7LU, 0xc1bdc1f8LU, 0x65bf65f9LU, 0xc4b9c4faLU, 0x60bb60fbLU, 0xcbb5cbfcLU, 0x6fb76ffdLU, 0xceb1cefeLU, 0x6ab36affLU }; static const ulong32 rs_tab1[256] = { 0x00000000LU, 0x55a156a4LU, 0xaa0fac05LU, 0xffaefaa1LU, 0x191e150aLU, 0x4cbf43aeLU, 0xb311b90fLU, 0xe6b0efabLU, 0x323c2a14LU, 0x679d7cb0LU, 0x98338611LU, 0xcd92d0b5LU, 0x2b223f1eLU, 0x7e8369baLU, 0x812d931bLU, 0xd48cc5bfLU, 0x64785428LU, 0x31d9028cLU, 0xce77f82dLU, 0x9bd6ae89LU, 0x7d664122LU, 0x28c71786LU, 0xd769ed27LU, 0x82c8bb83LU, 0x56447e3cLU, 0x03e52898LU, 0xfc4bd239LU, 0xa9ea849dLU, 0x4f5a6b36LU, 0x1afb3d92LU, 0xe555c733LU, 0xb0f49197LU, 0xc8f0a850LU, 0x9d51fef4LU, 0x62ff0455LU, 0x375e52f1LU, 0xd1eebd5aLU, 0x844febfeLU, 0x7be1115fLU, 0x2e4047fbLU, 0xfacc8244LU, 0xaf6dd4e0LU, 0x50c32e41LU, 0x056278e5LU, 0xe3d2974eLU, 0xb673c1eaLU, 0x49dd3b4bLU, 0x1c7c6defLU, 0xac88fc78LU, 0xf929aadcLU, 0x0687507dLU, 0x532606d9LU, 0xb596e972LU, 0xe037bfd6LU, 0x1f994577LU, 0x4a3813d3LU, 0x9eb4d66cLU, 0xcb1580c8LU, 0x34bb7a69LU, 0x611a2ccdLU, 0x87aac366LU, 0xd20b95c2LU, 0x2da56f63LU, 0x780439c7LU, 0xddad1da0LU, 0x880c4b04LU, 0x77a2b1a5LU, 0x2203e701LU, 0xc4b308aaLU, 0x91125e0eLU, 0x6ebca4afLU, 0x3b1df20bLU, 0xef9137b4LU, 0xba306110LU, 0x459e9bb1LU, 0x103fcd15LU, 0xf68f22beLU, 0xa32e741aLU, 0x5c808ebbLU, 0x0921d81fLU, 0xb9d54988LU, 0xec741f2cLU, 0x13dae58dLU, 0x467bb329LU, 0xa0cb5c82LU, 0xf56a0a26LU, 0x0ac4f087LU, 0x5f65a623LU, 0x8be9639cLU, 0xde483538LU, 0x21e6cf99LU, 0x7447993dLU, 0x92f77696LU, 0xc7562032LU, 0x38f8da93LU, 0x6d598c37LU, 0x155db5f0LU, 0x40fce354LU, 0xbf5219f5LU, 0xeaf34f51LU, 0x0c43a0faLU, 0x59e2f65eLU, 0xa64c0cffLU, 0xf3ed5a5bLU, 0x27619fe4LU, 0x72c0c940LU, 0x8d6e33e1LU, 0xd8cf6545LU, 0x3e7f8aeeLU, 0x6bdedc4aLU, 0x947026ebLU, 0xc1d1704fLU, 0x7125e1d8LU, 0x2484b77cLU, 0xdb2a4dddLU, 0x8e8b1b79LU, 0x683bf4d2LU, 0x3d9aa276LU, 0xc23458d7LU, 0x97950e73LU, 0x4319cbccLU, 0x16b89d68LU, 0xe91667c9LU, 0xbcb7316dLU, 0x5a07dec6LU, 0x0fa68862LU, 0xf00872c3LU, 0xa5a92467LU, 0xf7173a0dLU, 0xa2b66ca9LU, 0x5d189608LU, 0x08b9c0acLU, 0xee092f07LU, 0xbba879a3LU, 0x44068302LU, 0x11a7d5a6LU, 0xc52b1019LU, 0x908a46bdLU, 0x6f24bc1cLU, 0x3a85eab8LU, 0xdc350513LU, 0x899453b7LU, 0x763aa916LU, 0x239bffb2LU, 0x936f6e25LU, 0xc6ce3881LU, 0x3960c220LU, 0x6cc19484LU, 0x8a717b2fLU, 0xdfd02d8bLU, 0x207ed72aLU, 0x75df818eLU, 0xa1534431LU, 0xf4f21295LU, 0x0b5ce834LU, 0x5efdbe90LU, 0xb84d513bLU, 0xedec079fLU, 0x1242fd3eLU, 0x47e3ab9aLU, 0x3fe7925dLU, 0x6a46c4f9LU, 0x95e83e58LU, 0xc04968fcLU, 0x26f98757LU, 0x7358d1f3LU, 0x8cf62b52LU, 0xd9577df6LU, 0x0ddbb849LU, 0x587aeeedLU, 0xa7d4144cLU, 0xf27542e8LU, 0x14c5ad43LU, 0x4164fbe7LU, 0xbeca0146LU, 0xeb6b57e2LU, 0x5b9fc675LU, 0x0e3e90d1LU, 0xf1906a70LU, 0xa4313cd4LU, 0x4281d37fLU, 0x172085dbLU, 0xe88e7f7aLU, 0xbd2f29deLU, 0x69a3ec61LU, 0x3c02bac5LU, 0xc3ac4064LU, 0x960d16c0LU, 0x70bdf96bLU, 0x251cafcfLU, 0xdab2556eLU, 0x8f1303caLU, 0x2aba27adLU, 0x7f1b7109LU, 0x80b58ba8LU, 0xd514dd0cLU, 0x33a432a7LU, 0x66056403LU, 0x99ab9ea2LU, 0xcc0ac806LU, 0x18860db9LU, 0x4d275b1dLU, 0xb289a1bcLU, 0xe728f718LU, 0x019818b3LU, 0x54394e17LU, 0xab97b4b6LU, 0xfe36e212LU, 0x4ec27385LU, 0x1b632521LU, 0xe4cddf80LU, 0xb16c8924LU, 0x57dc668fLU, 0x027d302bLU, 0xfdd3ca8aLU, 0xa8729c2eLU, 0x7cfe5991LU, 0x295f0f35LU, 0xd6f1f594LU, 0x8350a330LU, 0x65e04c9bLU, 0x30411a3fLU, 0xcfefe09eLU, 0x9a4eb63aLU, 0xe24a8ffdLU, 0xb7ebd959LU, 0x484523f8LU, 0x1de4755cLU, 0xfb549af7LU, 0xaef5cc53LU, 0x515b36f2LU, 0x04fa6056LU, 0xd076a5e9LU, 0x85d7f34dLU, 0x7a7909ecLU, 0x2fd85f48LU, 0xc968b0e3LU, 0x9cc9e647LU, 0x63671ce6LU, 0x36c64a42LU, 0x8632dbd5LU, 0xd3938d71LU, 0x2c3d77d0LU, 0x799c2174LU, 0x9f2ccedfLU, 0xca8d987bLU, 0x352362daLU, 0x6082347eLU, 0xb40ef1c1LU, 0xe1afa765LU, 0x1e015dc4LU, 0x4ba00b60LU, 0xad10e4cbLU, 0xf8b1b26fLU, 0x071f48ceLU, 0x52be1e6aLU }; static const ulong32 rs_tab2[256] = { 0x00000000LU, 0x87fc8255LU, 0x43b549aaLU, 0xc449cbffLU, 0x86279219LU, 0x01db104cLU, 0xc592dbb3LU, 0x426e59e6LU, 0x414e6932LU, 0xc6b2eb67LU, 0x02fb2098LU, 0x8507a2cdLU, 0xc769fb2bLU, 0x4095797eLU, 0x84dcb281LU, 0x032030d4LU, 0x829cd264LU, 0x05605031LU, 0xc1299bceLU, 0x46d5199bLU, 0x04bb407dLU, 0x8347c228LU, 0x470e09d7LU, 0xc0f28b82LU, 0xc3d2bb56LU, 0x442e3903LU, 0x8067f2fcLU, 0x079b70a9LU, 0x45f5294fLU, 0xc209ab1aLU, 0x064060e5LU, 0x81bce2b0LU, 0x4975e9c8LU, 0xce896b9dLU, 0x0ac0a062LU, 0x8d3c2237LU, 0xcf527bd1LU, 0x48aef984LU, 0x8ce7327bLU, 0x0b1bb02eLU, 0x083b80faLU, 0x8fc702afLU, 0x4b8ec950LU, 0xcc724b05LU, 0x8e1c12e3LU, 0x09e090b6LU, 0xcda95b49LU, 0x4a55d91cLU, 0xcbe93bacLU, 0x4c15b9f9LU, 0x885c7206LU, 0x0fa0f053LU, 0x4dcea9b5LU, 0xca322be0LU, 0x0e7be01fLU, 0x8987624aLU, 0x8aa7529eLU, 0x0d5bd0cbLU, 0xc9121b34LU, 0x4eee9961LU, 0x0c80c087LU, 0x8b7c42d2LU, 0x4f35892dLU, 0xc8c90b78LU, 0x92ea9fddLU, 0x15161d88LU, 0xd15fd677LU, 0x56a35422LU, 0x14cd0dc4LU, 0x93318f91LU, 0x5778446eLU, 0xd084c63bLU, 0xd3a4f6efLU, 0x545874baLU, 0x9011bf45LU, 0x17ed3d10LU, 0x558364f6LU, 0xd27fe6a3LU, 0x16362d5cLU, 0x91caaf09LU, 0x10764db9LU, 0x978acfecLU, 0x53c30413LU, 0xd43f8646LU, 0x9651dfa0LU, 0x11ad5df5LU, 0xd5e4960aLU, 0x5218145fLU, 0x5138248bLU, 0xd6c4a6deLU, 0x128d6d21LU, 0x9571ef74LU, 0xd71fb692LU, 0x50e334c7LU, 0x94aaff38LU, 0x13567d6dLU, 0xdb9f7615LU, 0x5c63f440LU, 0x982a3fbfLU, 0x1fd6bdeaLU, 0x5db8e40cLU, 0xda446659LU, 0x1e0dada6LU, 0x99f12ff3LU, 0x9ad11f27LU, 0x1d2d9d72LU, 0xd964568dLU, 0x5e98d4d8LU, 0x1cf68d3eLU, 0x9b0a0f6bLU, 0x5f43c494LU, 0xd8bf46c1LU, 0x5903a471LU, 0xdeff2624LU, 0x1ab6eddbLU, 0x9d4a6f8eLU, 0xdf243668LU, 0x58d8b43dLU, 0x9c917fc2LU, 0x1b6dfd97LU, 0x184dcd43LU, 0x9fb14f16LU, 0x5bf884e9LU, 0xdc0406bcLU, 0x9e6a5f5aLU, 0x1996dd0fLU, 0xdddf16f0LU, 0x5a2394a5LU, 0x699973f7LU, 0xee65f1a2LU, 0x2a2c3a5dLU, 0xadd0b808LU, 0xefbee1eeLU, 0x684263bbLU, 0xac0ba844LU, 0x2bf72a11LU, 0x28d71ac5LU, 0xaf2b9890LU, 0x6b62536fLU, 0xec9ed13aLU, 0xaef088dcLU, 0x290c0a89LU, 0xed45c176LU, 0x6ab94323LU, 0xeb05a193LU, 0x6cf923c6LU, 0xa8b0e839LU, 0x2f4c6a6cLU, 0x6d22338aLU, 0xeadeb1dfLU, 0x2e977a20LU, 0xa96bf875LU, 0xaa4bc8a1LU, 0x2db74af4LU, 0xe9fe810bLU, 0x6e02035eLU, 0x2c6c5ab8LU, 0xab90d8edLU, 0x6fd91312LU, 0xe8259147LU, 0x20ec9a3fLU, 0xa710186aLU, 0x6359d395LU, 0xe4a551c0LU, 0xa6cb0826LU, 0x21378a73LU, 0xe57e418cLU, 0x6282c3d9LU, 0x61a2f30dLU, 0xe65e7158LU, 0x2217baa7LU, 0xa5eb38f2LU, 0xe7856114LU, 0x6079e341LU, 0xa43028beLU, 0x23ccaaebLU, 0xa270485bLU, 0x258cca0eLU, 0xe1c501f1LU, 0x663983a4LU, 0x2457da42LU, 0xa3ab5817LU, 0x67e293e8LU, 0xe01e11bdLU, 0xe33e2169LU, 0x64c2a33cLU, 0xa08b68c3LU, 0x2777ea96LU, 0x6519b370LU, 0xe2e53125LU, 0x26acfadaLU, 0xa150788fLU, 0xfb73ec2aLU, 0x7c8f6e7fLU, 0xb8c6a580LU, 0x3f3a27d5LU, 0x7d547e33LU, 0xfaa8fc66LU, 0x3ee13799LU, 0xb91db5ccLU, 0xba3d8518LU, 0x3dc1074dLU, 0xf988ccb2LU, 0x7e744ee7LU, 0x3c1a1701LU, 0xbbe69554LU, 0x7faf5eabLU, 0xf853dcfeLU, 0x79ef3e4eLU, 0xfe13bc1bLU, 0x3a5a77e4LU, 0xbda6f5b1LU, 0xffc8ac57LU, 0x78342e02LU, 0xbc7de5fdLU, 0x3b8167a8LU, 0x38a1577cLU, 0xbf5dd529LU, 0x7b141ed6LU, 0xfce89c83LU, 0xbe86c565LU, 0x397a4730LU, 0xfd338ccfLU, 0x7acf0e9aLU, 0xb20605e2LU, 0x35fa87b7LU, 0xf1b34c48LU, 0x764fce1dLU, 0x342197fbLU, 0xb3dd15aeLU, 0x7794de51LU, 0xf0685c04LU, 0xf3486cd0LU, 0x74b4ee85LU, 0xb0fd257aLU, 0x3701a72fLU, 0x756ffec9LU, 0xf2937c9cLU, 0x36dab763LU, 0xb1263536LU, 0x309ad786LU, 0xb76655d3LU, 0x732f9e2cLU, 0xf4d31c79LU, 0xb6bd459fLU, 0x3141c7caLU, 0xf5080c35LU, 0x72f48e60LU, 0x71d4beb4LU, 0xf6283ce1LU, 0x3261f71eLU, 0xb59d754bLU, 0xf7f32cadLU, 0x700faef8LU, 0xb4466507LU, 0x33bae752LU }; static const ulong32 rs_tab3[256] = { 0x00000000LU, 0x5ac1f387LU, 0xb4cfab43LU, 0xee0e58c4LU, 0x25d31b86LU, 0x7f12e801LU, 0x911cb0c5LU, 0xcbdd4342LU, 0x4aeb3641LU, 0x102ac5c6LU, 0xfe249d02LU, 0xa4e56e85LU, 0x6f382dc7LU, 0x35f9de40LU, 0xdbf78684LU, 0x81367503LU, 0x949b6c82LU, 0xce5a9f05LU, 0x2054c7c1LU, 0x7a953446LU, 0xb1487704LU, 0xeb898483LU, 0x0587dc47LU, 0x5f462fc0LU, 0xde705ac3LU, 0x84b1a944LU, 0x6abff180LU, 0x307e0207LU, 0xfba34145LU, 0xa162b2c2LU, 0x4f6cea06LU, 0x15ad1981LU, 0x657bd849LU, 0x3fba2bceLU, 0xd1b4730aLU, 0x8b75808dLU, 0x40a8c3cfLU, 0x1a693048LU, 0xf467688cLU, 0xaea69b0bLU, 0x2f90ee08LU, 0x75511d8fLU, 0x9b5f454bLU, 0xc19eb6ccLU, 0x0a43f58eLU, 0x50820609LU, 0xbe8c5ecdLU, 0xe44dad4aLU, 0xf1e0b4cbLU, 0xab21474cLU, 0x452f1f88LU, 0x1feeec0fLU, 0xd433af4dLU, 0x8ef25ccaLU, 0x60fc040eLU, 0x3a3df789LU, 0xbb0b828aLU, 0xe1ca710dLU, 0x0fc429c9LU, 0x5505da4eLU, 0x9ed8990cLU, 0xc4196a8bLU, 0x2a17324fLU, 0x70d6c1c8LU, 0xcaf6fd92LU, 0x90370e15LU, 0x7e3956d1LU, 0x24f8a556LU, 0xef25e614LU, 0xb5e41593LU, 0x5bea4d57LU, 0x012bbed0LU, 0x801dcbd3LU, 0xdadc3854LU, 0x34d26090LU, 0x6e139317LU, 0xa5ced055LU, 0xff0f23d2LU, 0x11017b16LU, 0x4bc08891LU, 0x5e6d9110LU, 0x04ac6297LU, 0xeaa23a53LU, 0xb063c9d4LU, 0x7bbe8a96LU, 0x217f7911LU, 0xcf7121d5LU, 0x95b0d252LU, 0x1486a751LU, 0x4e4754d6LU, 0xa0490c12LU, 0xfa88ff95LU, 0x3155bcd7LU, 0x6b944f50LU, 0x859a1794LU, 0xdf5be413LU, 0xaf8d25dbLU, 0xf54cd65cLU, 0x1b428e98LU, 0x41837d1fLU, 0x8a5e3e5dLU, 0xd09fcddaLU, 0x3e91951eLU, 0x64506699LU, 0xe566139aLU, 0xbfa7e01dLU, 0x51a9b8d9LU, 0x0b684b5eLU, 0xc0b5081cLU, 0x9a74fb9bLU, 0x747aa35fLU, 0x2ebb50d8LU, 0x3b164959LU, 0x61d7badeLU, 0x8fd9e21aLU, 0xd518119dLU, 0x1ec552dfLU, 0x4404a158LU, 0xaa0af99cLU, 0xf0cb0a1bLU, 0x71fd7f18LU, 0x2b3c8c9fLU, 0xc532d45bLU, 0x9ff327dcLU, 0x542e649eLU, 0x0eef9719LU, 0xe0e1cfddLU, 0xba203c5aLU, 0xd9a1b769LU, 0x836044eeLU, 0x6d6e1c2aLU, 0x37afefadLU, 0xfc72acefLU, 0xa6b35f68LU, 0x48bd07acLU, 0x127cf42bLU, 0x934a8128LU, 0xc98b72afLU, 0x27852a6bLU, 0x7d44d9ecLU, 0xb6999aaeLU, 0xec586929LU, 0x025631edLU, 0x5897c26aLU, 0x4d3adbebLU, 0x17fb286cLU, 0xf9f570a8LU, 0xa334832fLU, 0x68e9c06dLU, 0x322833eaLU, 0xdc266b2eLU, 0x86e798a9LU, 0x07d1edaaLU, 0x5d101e2dLU, 0xb31e46e9LU, 0xe9dfb56eLU, 0x2202f62cLU, 0x78c305abLU, 0x96cd5d6fLU, 0xcc0caee8LU, 0xbcda6f20LU, 0xe61b9ca7LU, 0x0815c463LU, 0x52d437e4LU, 0x990974a6LU, 0xc3c88721LU, 0x2dc6dfe5LU, 0x77072c62LU, 0xf6315961LU, 0xacf0aae6LU, 0x42fef222LU, 0x183f01a5LU, 0xd3e242e7LU, 0x8923b160LU, 0x672de9a4LU, 0x3dec1a23LU, 0x284103a2LU, 0x7280f025LU, 0x9c8ea8e1LU, 0xc64f5b66LU, 0x0d921824LU, 0x5753eba3LU, 0xb95db367LU, 0xe39c40e0LU, 0x62aa35e3LU, 0x386bc664LU, 0xd6659ea0LU, 0x8ca46d27LU, 0x47792e65LU, 0x1db8dde2LU, 0xf3b68526LU, 0xa97776a1LU, 0x13574afbLU, 0x4996b97cLU, 0xa798e1b8LU, 0xfd59123fLU, 0x3684517dLU, 0x6c45a2faLU, 0x824bfa3eLU, 0xd88a09b9LU, 0x59bc7cbaLU, 0x037d8f3dLU, 0xed73d7f9LU, 0xb7b2247eLU, 0x7c6f673cLU, 0x26ae94bbLU, 0xc8a0cc7fLU, 0x92613ff8LU, 0x87cc2679LU, 0xdd0dd5feLU, 0x33038d3aLU, 0x69c27ebdLU, 0xa21f3dffLU, 0xf8dece78LU, 0x16d096bcLU, 0x4c11653bLU, 0xcd271038LU, 0x97e6e3bfLU, 0x79e8bb7bLU, 0x232948fcLU, 0xe8f40bbeLU, 0xb235f839LU, 0x5c3ba0fdLU, 0x06fa537aLU, 0x762c92b2LU, 0x2ced6135LU, 0xc2e339f1LU, 0x9822ca76LU, 0x53ff8934LU, 0x093e7ab3LU, 0xe7302277LU, 0xbdf1d1f0LU, 0x3cc7a4f3LU, 0x66065774LU, 0x88080fb0LU, 0xd2c9fc37LU, 0x1914bf75LU, 0x43d54cf2LU, 0xaddb1436LU, 0xf71ae7b1LU, 0xe2b7fe30LU, 0xb8760db7LU, 0x56785573LU, 0x0cb9a6f4LU, 0xc764e5b6LU, 0x9da51631LU, 0x73ab4ef5LU, 0x296abd72LU, 0xa85cc871LU, 0xf29d3bf6LU, 0x1c936332LU, 0x465290b5LU, 0x8d8fd3f7LU, 0xd74e2070LU, 0x394078b4LU, 0x63818b33LU }; static const ulong32 rs_tab4[256] = { 0x00000000LU, 0x58471e5aLU, 0xb08e3cb4LU, 0xe8c922eeLU, 0x2d517825LU, 0x7516667fLU, 0x9ddf4491LU, 0xc5985acbLU, 0x5aa2f04aLU, 0x02e5ee10LU, 0xea2cccfeLU, 0xb26bd2a4LU, 0x77f3886fLU, 0x2fb49635LU, 0xc77db4dbLU, 0x9f3aaa81LU, 0xb409ad94LU, 0xec4eb3ceLU, 0x04879120LU, 0x5cc08f7aLU, 0x9958d5b1LU, 0xc11fcbebLU, 0x29d6e905LU, 0x7191f75fLU, 0xeeab5ddeLU, 0xb6ec4384LU, 0x5e25616aLU, 0x06627f30LU, 0xc3fa25fbLU, 0x9bbd3ba1LU, 0x7374194fLU, 0x2b330715LU, 0x25121765LU, 0x7d55093fLU, 0x959c2bd1LU, 0xcddb358bLU, 0x08436f40LU, 0x5004711aLU, 0xb8cd53f4LU, 0xe08a4daeLU, 0x7fb0e72fLU, 0x27f7f975LU, 0xcf3edb9bLU, 0x9779c5c1LU, 0x52e19f0aLU, 0x0aa68150LU, 0xe26fa3beLU, 0xba28bde4LU, 0x911bbaf1LU, 0xc95ca4abLU, 0x21958645LU, 0x79d2981fLU, 0xbc4ac2d4LU, 0xe40ddc8eLU, 0x0cc4fe60LU, 0x5483e03aLU, 0xcbb94abbLU, 0x93fe54e1LU, 0x7b37760fLU, 0x23706855LU, 0xe6e8329eLU, 0xbeaf2cc4LU, 0x56660e2aLU, 0x0e211070LU, 0x4a242ecaLU, 0x12633090LU, 0xfaaa127eLU, 0xa2ed0c24LU, 0x677556efLU, 0x3f3248b5LU, 0xd7fb6a5bLU, 0x8fbc7401LU, 0x1086de80LU, 0x48c1c0daLU, 0xa008e234LU, 0xf84ffc6eLU, 0x3dd7a6a5LU, 0x6590b8ffLU, 0x8d599a11LU, 0xd51e844bLU, 0xfe2d835eLU, 0xa66a9d04LU, 0x4ea3bfeaLU, 0x16e4a1b0LU, 0xd37cfb7bLU, 0x8b3be521LU, 0x63f2c7cfLU, 0x3bb5d995LU, 0xa48f7314LU, 0xfcc86d4eLU, 0x14014fa0LU, 0x4c4651faLU, 0x89de0b31LU, 0xd199156bLU, 0x39503785LU, 0x611729dfLU, 0x6f3639afLU, 0x377127f5LU, 0xdfb8051bLU, 0x87ff1b41LU, 0x4267418aLU, 0x1a205fd0LU, 0xf2e97d3eLU, 0xaaae6364LU, 0x3594c9e5LU, 0x6dd3d7bfLU, 0x851af551LU, 0xdd5deb0bLU, 0x18c5b1c0LU, 0x4082af9aLU, 0xa84b8d74LU, 0xf00c932eLU, 0xdb3f943bLU, 0x83788a61LU, 0x6bb1a88fLU, 0x33f6b6d5LU, 0xf66eec1eLU, 0xae29f244LU, 0x46e0d0aaLU, 0x1ea7cef0LU, 0x819d6471LU, 0xd9da7a2bLU, 0x311358c5LU, 0x6954469fLU, 0xaccc1c54LU, 0xf48b020eLU, 0x1c4220e0LU, 0x44053ebaLU, 0x94485cd9LU, 0xcc0f4283LU, 0x24c6606dLU, 0x7c817e37LU, 0xb91924fcLU, 0xe15e3aa6LU, 0x09971848LU, 0x51d00612LU, 0xceeaac93LU, 0x96adb2c9LU, 0x7e649027LU, 0x26238e7dLU, 0xe3bbd4b6LU, 0xbbfccaecLU, 0x5335e802LU, 0x0b72f658LU, 0x2041f14dLU, 0x7806ef17LU, 0x90cfcdf9LU, 0xc888d3a3LU, 0x0d108968LU, 0x55579732LU, 0xbd9eb5dcLU, 0xe5d9ab86LU, 0x7ae30107LU, 0x22a41f5dLU, 0xca6d3db3LU, 0x922a23e9LU, 0x57b27922LU, 0x0ff56778LU, 0xe73c4596LU, 0xbf7b5bccLU, 0xb15a4bbcLU, 0xe91d55e6LU, 0x01d47708LU, 0x59936952LU, 0x9c0b3399LU, 0xc44c2dc3LU, 0x2c850f2dLU, 0x74c21177LU, 0xebf8bbf6LU, 0xb3bfa5acLU, 0x5b768742LU, 0x03319918LU, 0xc6a9c3d3LU, 0x9eeedd89LU, 0x7627ff67LU, 0x2e60e13dLU, 0x0553e628LU, 0x5d14f872LU, 0xb5ddda9cLU, 0xed9ac4c6LU, 0x28029e0dLU, 0x70458057LU, 0x988ca2b9LU, 0xc0cbbce3LU, 0x5ff11662LU, 0x07b60838LU, 0xef7f2ad6LU, 0xb738348cLU, 0x72a06e47LU, 0x2ae7701dLU, 0xc22e52f3LU, 0x9a694ca9LU, 0xde6c7213LU, 0x862b6c49LU, 0x6ee24ea7LU, 0x36a550fdLU, 0xf33d0a36LU, 0xab7a146cLU, 0x43b33682LU, 0x1bf428d8LU, 0x84ce8259LU, 0xdc899c03LU, 0x3440beedLU, 0x6c07a0b7LU, 0xa99ffa7cLU, 0xf1d8e426LU, 0x1911c6c8LU, 0x4156d892LU, 0x6a65df87LU, 0x3222c1ddLU, 0xdaebe333LU, 0x82acfd69LU, 0x4734a7a2LU, 0x1f73b9f8LU, 0xf7ba9b16LU, 0xaffd854cLU, 0x30c72fcdLU, 0x68803197LU, 0x80491379LU, 0xd80e0d23LU, 0x1d9657e8LU, 0x45d149b2LU, 0xad186b5cLU, 0xf55f7506LU, 0xfb7e6576LU, 0xa3397b2cLU, 0x4bf059c2LU, 0x13b74798LU, 0xd62f1d53LU, 0x8e680309LU, 0x66a121e7LU, 0x3ee63fbdLU, 0xa1dc953cLU, 0xf99b8b66LU, 0x1152a988LU, 0x4915b7d2LU, 0x8c8ded19LU, 0xd4caf343LU, 0x3c03d1adLU, 0x6444cff7LU, 0x4f77c8e2LU, 0x1730d6b8LU, 0xfff9f456LU, 0xa7beea0cLU, 0x6226b0c7LU, 0x3a61ae9dLU, 0xd2a88c73LU, 0x8aef9229LU, 0x15d538a8LU, 0x4d9226f2LU, 0xa55b041cLU, 0xfd1c1a46LU, 0x3884408dLU, 0x60c35ed7LU, 0x880a7c39LU, 0xd04d6263LU }; static const ulong32 rs_tab5[256] = { 0x00000000LU, 0xdbaec658LU, 0xfb11c1b0LU, 0x20bf07e8LU, 0xbb22cf2dLU, 0x608c0975LU, 0x40330e9dLU, 0x9b9dc8c5LU, 0x3b44d35aLU, 0xe0ea1502LU, 0xc05512eaLU, 0x1bfbd4b2LU, 0x80661c77LU, 0x5bc8da2fLU, 0x7b77ddc7LU, 0xa0d91b9fLU, 0x7688ebb4LU, 0xad262decLU, 0x8d992a04LU, 0x5637ec5cLU, 0xcdaa2499LU, 0x1604e2c1LU, 0x36bbe529LU, 0xed152371LU, 0x4dcc38eeLU, 0x9662feb6LU, 0xb6ddf95eLU, 0x6d733f06LU, 0xf6eef7c3LU, 0x2d40319bLU, 0x0dff3673LU, 0xd651f02bLU, 0xec5d9b25LU, 0x37f35d7dLU, 0x174c5a95LU, 0xcce29ccdLU, 0x577f5408LU, 0x8cd19250LU, 0xac6e95b8LU, 0x77c053e0LU, 0xd719487fLU, 0x0cb78e27LU, 0x2c0889cfLU, 0xf7a64f97LU, 0x6c3b8752LU, 0xb795410aLU, 0x972a46e2LU, 0x4c8480baLU, 0x9ad57091LU, 0x417bb6c9LU, 0x61c4b121LU, 0xba6a7779LU, 0x21f7bfbcLU, 0xfa5979e4LU, 0xdae67e0cLU, 0x0148b854LU, 0xa191a3cbLU, 0x7a3f6593LU, 0x5a80627bLU, 0x812ea423LU, 0x1ab36ce6LU, 0xc11daabeLU, 0xe1a2ad56LU, 0x3a0c6b0eLU, 0x95ba7b4aLU, 0x4e14bd12LU, 0x6eabbafaLU, 0xb5057ca2LU, 0x2e98b467LU, 0xf536723fLU, 0xd58975d7LU, 0x0e27b38fLU, 0xaefea810LU, 0x75506e48LU, 0x55ef69a0LU, 0x8e41aff8LU, 0x15dc673dLU, 0xce72a165LU, 0xeecda68dLU, 0x356360d5LU, 0xe33290feLU, 0x389c56a6LU, 0x1823514eLU, 0xc38d9716LU, 0x58105fd3LU, 0x83be998bLU, 0xa3019e63LU, 0x78af583bLU, 0xd87643a4LU, 0x03d885fcLU, 0x23678214LU, 0xf8c9444cLU, 0x63548c89LU, 0xb8fa4ad1LU, 0x98454d39LU, 0x43eb8b61LU, 0x79e7e06fLU, 0xa2492637LU, 0x82f621dfLU, 0x5958e787LU, 0xc2c52f42LU, 0x196be91aLU, 0x39d4eef2LU, 0xe27a28aaLU, 0x42a33335LU, 0x990df56dLU, 0xb9b2f285LU, 0x621c34ddLU, 0xf981fc18LU, 0x222f3a40LU, 0x02903da8LU, 0xd93efbf0LU, 0x0f6f0bdbLU, 0xd4c1cd83LU, 0xf47eca6bLU, 0x2fd00c33LU, 0xb44dc4f6LU, 0x6fe302aeLU, 0x4f5c0546LU, 0x94f2c31eLU, 0x342bd881LU, 0xef851ed9LU, 0xcf3a1931LU, 0x1494df69LU, 0x8f0917acLU, 0x54a7d1f4LU, 0x7418d61cLU, 0xafb61044LU, 0x6739f694LU, 0xbc9730ccLU, 0x9c283724LU, 0x4786f17cLU, 0xdc1b39b9LU, 0x07b5ffe1LU, 0x270af809LU, 0xfca43e51LU, 0x5c7d25ceLU, 0x87d3e396LU, 0xa76ce47eLU, 0x7cc22226LU, 0xe75feae3LU, 0x3cf12cbbLU, 0x1c4e2b53LU, 0xc7e0ed0bLU, 0x11b11d20LU, 0xca1fdb78LU, 0xeaa0dc90LU, 0x310e1ac8LU, 0xaa93d20dLU, 0x713d1455LU, 0x518213bdLU, 0x8a2cd5e5LU, 0x2af5ce7aLU, 0xf15b0822LU, 0xd1e40fcaLU, 0x0a4ac992LU, 0x91d70157LU, 0x4a79c70fLU, 0x6ac6c0e7LU, 0xb16806bfLU, 0x8b646db1LU, 0x50caabe9LU, 0x7075ac01LU, 0xabdb6a59LU, 0x3046a29cLU, 0xebe864c4LU, 0xcb57632cLU, 0x10f9a574LU, 0xb020beebLU, 0x6b8e78b3LU, 0x4b317f5bLU, 0x909fb903LU, 0x0b0271c6LU, 0xd0acb79eLU, 0xf013b076LU, 0x2bbd762eLU, 0xfdec8605LU, 0x2642405dLU, 0x06fd47b5LU, 0xdd5381edLU, 0x46ce4928LU, 0x9d608f70LU, 0xbddf8898LU, 0x66714ec0LU, 0xc6a8555fLU, 0x1d069307LU, 0x3db994efLU, 0xe61752b7LU, 0x7d8a9a72LU, 0xa6245c2aLU, 0x869b5bc2LU, 0x5d359d9aLU, 0xf2838ddeLU, 0x292d4b86LU, 0x09924c6eLU, 0xd23c8a36LU, 0x49a142f3LU, 0x920f84abLU, 0xb2b08343LU, 0x691e451bLU, 0xc9c75e84LU, 0x126998dcLU, 0x32d69f34LU, 0xe978596cLU, 0x72e591a9LU, 0xa94b57f1LU, 0x89f45019LU, 0x525a9641LU, 0x840b666aLU, 0x5fa5a032LU, 0x7f1aa7daLU, 0xa4b46182LU, 0x3f29a947LU, 0xe4876f1fLU, 0xc43868f7LU, 0x1f96aeafLU, 0xbf4fb530LU, 0x64e17368LU, 0x445e7480LU, 0x9ff0b2d8LU, 0x046d7a1dLU, 0xdfc3bc45LU, 0xff7cbbadLU, 0x24d27df5LU, 0x1ede16fbLU, 0xc570d0a3LU, 0xe5cfd74bLU, 0x3e611113LU, 0xa5fcd9d6LU, 0x7e521f8eLU, 0x5eed1866LU, 0x8543de3eLU, 0x259ac5a1LU, 0xfe3403f9LU, 0xde8b0411LU, 0x0525c249LU, 0x9eb80a8cLU, 0x4516ccd4LU, 0x65a9cb3cLU, 0xbe070d64LU, 0x6856fd4fLU, 0xb3f83b17LU, 0x93473cffLU, 0x48e9faa7LU, 0xd3743262LU, 0x08daf43aLU, 0x2865f3d2LU, 0xf3cb358aLU, 0x53122e15LU, 0x88bce84dLU, 0xa803efa5LU, 0x73ad29fdLU, 0xe830e138LU, 0x339e2760LU, 0x13212088LU, 0xc88fe6d0LU }; static const ulong32 rs_tab6[256] = { 0x00000000LU, 0x9e3d68dbLU, 0x717ad0fbLU, 0xef47b820LU, 0xe2f4edbbLU, 0x7cc98560LU, 0x938e3d40LU, 0x0db3559bLU, 0x89a5973bLU, 0x1798ffe0LU, 0xf8df47c0LU, 0x66e22f1bLU, 0x6b517a80LU, 0xf56c125bLU, 0x1a2baa7bLU, 0x8416c2a0LU, 0x5f076376LU, 0xc13a0badLU, 0x2e7db38dLU, 0xb040db56LU, 0xbdf38ecdLU, 0x23cee616LU, 0xcc895e36LU, 0x52b436edLU, 0xd6a2f44dLU, 0x489f9c96LU, 0xa7d824b6LU, 0x39e54c6dLU, 0x345619f6LU, 0xaa6b712dLU, 0x452cc90dLU, 0xdb11a1d6LU, 0xbe0ec6ecLU, 0x2033ae37LU, 0xcf741617LU, 0x51497eccLU, 0x5cfa2b57LU, 0xc2c7438cLU, 0x2d80fbacLU, 0xb3bd9377LU, 0x37ab51d7LU, 0xa996390cLU, 0x46d1812cLU, 0xd8ece9f7LU, 0xd55fbc6cLU, 0x4b62d4b7LU, 0xa4256c97LU, 0x3a18044cLU, 0xe109a59aLU, 0x7f34cd41LU, 0x90737561LU, 0x0e4e1dbaLU, 0x03fd4821LU, 0x9dc020faLU, 0x728798daLU, 0xecbaf001LU, 0x68ac32a1LU, 0xf6915a7aLU, 0x19d6e25aLU, 0x87eb8a81LU, 0x8a58df1aLU, 0x1465b7c1LU, 0xfb220fe1LU, 0x651f673aLU, 0x311cc195LU, 0xaf21a94eLU, 0x4066116eLU, 0xde5b79b5LU, 0xd3e82c2eLU, 0x4dd544f5LU, 0xa292fcd5LU, 0x3caf940eLU, 0xb8b956aeLU, 0x26843e75LU, 0xc9c38655LU, 0x57feee8eLU, 0x5a4dbb15LU, 0xc470d3ceLU, 0x2b376beeLU, 0xb50a0335LU, 0x6e1ba2e3LU, 0xf026ca38LU, 0x1f617218LU, 0x815c1ac3LU, 0x8cef4f58LU, 0x12d22783LU, 0xfd959fa3LU, 0x63a8f778LU, 0xe7be35d8LU, 0x79835d03LU, 0x96c4e523LU, 0x08f98df8LU, 0x054ad863LU, 0x9b77b0b8LU, 0x74300898LU, 0xea0d6043LU, 0x8f120779LU, 0x112f6fa2LU, 0xfe68d782LU, 0x6055bf59LU, 0x6de6eac2LU, 0xf3db8219LU, 0x1c9c3a39LU, 0x82a152e2LU, 0x06b79042LU, 0x988af899LU, 0x77cd40b9LU, 0xe9f02862LU, 0xe4437df9LU, 0x7a7e1522LU, 0x9539ad02LU, 0x0b04c5d9LU, 0xd015640fLU, 0x4e280cd4LU, 0xa16fb4f4LU, 0x3f52dc2fLU, 0x32e189b4LU, 0xacdce16fLU, 0x439b594fLU, 0xdda63194LU, 0x59b0f334LU, 0xc78d9befLU, 0x28ca23cfLU, 0xb6f74b14LU, 0xbb441e8fLU, 0x25797654LU, 0xca3ece74LU, 0x5403a6afLU, 0x6238cf67LU, 0xfc05a7bcLU, 0x13421f9cLU, 0x8d7f7747LU, 0x80cc22dcLU, 0x1ef14a07LU, 0xf1b6f227LU, 0x6f8b9afcLU, 0xeb9d585cLU, 0x75a03087LU, 0x9ae788a7LU, 0x04dae07cLU, 0x0969b5e7LU, 0x9754dd3cLU, 0x7813651cLU, 0xe62e0dc7LU, 0x3d3fac11LU, 0xa302c4caLU, 0x4c457ceaLU, 0xd2781431LU, 0xdfcb41aaLU, 0x41f62971LU, 0xaeb19151LU, 0x308cf98aLU, 0xb49a3b2aLU, 0x2aa753f1LU, 0xc5e0ebd1LU, 0x5bdd830aLU, 0x566ed691LU, 0xc853be4aLU, 0x2714066aLU, 0xb9296eb1LU, 0xdc36098bLU, 0x420b6150LU, 0xad4cd970LU, 0x3371b1abLU, 0x3ec2e430LU, 0xa0ff8cebLU, 0x4fb834cbLU, 0xd1855c10LU, 0x55939eb0LU, 0xcbaef66bLU, 0x24e94e4bLU, 0xbad42690LU, 0xb767730bLU, 0x295a1bd0LU, 0xc61da3f0LU, 0x5820cb2bLU, 0x83316afdLU, 0x1d0c0226LU, 0xf24bba06LU, 0x6c76d2ddLU, 0x61c58746LU, 0xfff8ef9dLU, 0x10bf57bdLU, 0x8e823f66LU, 0x0a94fdc6LU, 0x94a9951dLU, 0x7bee2d3dLU, 0xe5d345e6LU, 0xe860107dLU, 0x765d78a6LU, 0x991ac086LU, 0x0727a85dLU, 0x53240ef2LU, 0xcd196629LU, 0x225ede09LU, 0xbc63b6d2LU, 0xb1d0e349LU, 0x2fed8b92LU, 0xc0aa33b2LU, 0x5e975b69LU, 0xda8199c9LU, 0x44bcf112LU, 0xabfb4932LU, 0x35c621e9LU, 0x38757472LU, 0xa6481ca9LU, 0x490fa489LU, 0xd732cc52LU, 0x0c236d84LU, 0x921e055fLU, 0x7d59bd7fLU, 0xe364d5a4LU, 0xeed7803fLU, 0x70eae8e4LU, 0x9fad50c4LU, 0x0190381fLU, 0x8586fabfLU, 0x1bbb9264LU, 0xf4fc2a44LU, 0x6ac1429fLU, 0x67721704LU, 0xf94f7fdfLU, 0x1608c7ffLU, 0x8835af24LU, 0xed2ac81eLU, 0x7317a0c5LU, 0x9c5018e5LU, 0x026d703eLU, 0x0fde25a5LU, 0x91e34d7eLU, 0x7ea4f55eLU, 0xe0999d85LU, 0x648f5f25LU, 0xfab237feLU, 0x15f58fdeLU, 0x8bc8e705LU, 0x867bb29eLU, 0x1846da45LU, 0xf7016265LU, 0x693c0abeLU, 0xb22dab68LU, 0x2c10c3b3LU, 0xc3577b93LU, 0x5d6a1348LU, 0x50d946d3LU, 0xcee42e08LU, 0x21a39628LU, 0xbf9efef3LU, 0x3b883c53LU, 0xa5b55488LU, 0x4af2eca8LU, 0xd4cf8473LU, 0xd97cd1e8LU, 0x4741b933LU, 0xa8060113LU, 0x363b69c8LU }; static const ulong32 rs_tab7[256] = { 0x00000000LU, 0x0319e59eLU, 0x06328771LU, 0x052b62efLU, 0x0c6443e2LU, 0x0f7da67cLU, 0x0a56c493LU, 0x094f210dLU, 0x18c88689LU, 0x1bd16317LU, 0x1efa01f8LU, 0x1de3e466LU, 0x14acc56bLU, 0x17b520f5LU, 0x129e421aLU, 0x1187a784LU, 0x30dd415fLU, 0x33c4a4c1LU, 0x36efc62eLU, 0x35f623b0LU, 0x3cb902bdLU, 0x3fa0e723LU, 0x3a8b85ccLU, 0x39926052LU, 0x2815c7d6LU, 0x2b0c2248LU, 0x2e2740a7LU, 0x2d3ea539LU, 0x24718434LU, 0x276861aaLU, 0x22430345LU, 0x215ae6dbLU, 0x60f782beLU, 0x63ee6720LU, 0x66c505cfLU, 0x65dce051LU, 0x6c93c15cLU, 0x6f8a24c2LU, 0x6aa1462dLU, 0x69b8a3b3LU, 0x783f0437LU, 0x7b26e1a9LU, 0x7e0d8346LU, 0x7d1466d8LU, 0x745b47d5LU, 0x7742a24bLU, 0x7269c0a4LU, 0x7170253aLU, 0x502ac3e1LU, 0x5333267fLU, 0x56184490LU, 0x5501a10eLU, 0x5c4e8003LU, 0x5f57659dLU, 0x5a7c0772LU, 0x5965e2ecLU, 0x48e24568LU, 0x4bfba0f6LU, 0x4ed0c219LU, 0x4dc92787LU, 0x4486068aLU, 0x479fe314LU, 0x42b481fbLU, 0x41ad6465LU, 0xc0a34931LU, 0xc3baacafLU, 0xc691ce40LU, 0xc5882bdeLU, 0xccc70ad3LU, 0xcfdeef4dLU, 0xcaf58da2LU, 0xc9ec683cLU, 0xd86bcfb8LU, 0xdb722a26LU, 0xde5948c9LU, 0xdd40ad57LU, 0xd40f8c5aLU, 0xd71669c4LU, 0xd23d0b2bLU, 0xd124eeb5LU, 0xf07e086eLU, 0xf367edf0LU, 0xf64c8f1fLU, 0xf5556a81LU, 0xfc1a4b8cLU, 0xff03ae12LU, 0xfa28ccfdLU, 0xf9312963LU, 0xe8b68ee7LU, 0xebaf6b79LU, 0xee840996LU, 0xed9dec08LU, 0xe4d2cd05LU, 0xe7cb289bLU, 0xe2e04a74LU, 0xe1f9afeaLU, 0xa054cb8fLU, 0xa34d2e11LU, 0xa6664cfeLU, 0xa57fa960LU, 0xac30886dLU, 0xaf296df3LU, 0xaa020f1cLU, 0xa91bea82LU, 0xb89c4d06LU, 0xbb85a898LU, 0xbeaeca77LU, 0xbdb72fe9LU, 0xb4f80ee4LU, 0xb7e1eb7aLU, 0xb2ca8995LU, 0xb1d36c0bLU, 0x90898ad0LU, 0x93906f4eLU, 0x96bb0da1LU, 0x95a2e83fLU, 0x9cedc932LU, 0x9ff42cacLU, 0x9adf4e43LU, 0x99c6abddLU, 0x88410c59LU, 0x8b58e9c7LU, 0x8e738b28LU, 0x8d6a6eb6LU, 0x84254fbbLU, 0x873caa25LU, 0x8217c8caLU, 0x810e2d54LU, 0xcd0b9262LU, 0xce1277fcLU, 0xcb391513LU, 0xc820f08dLU, 0xc16fd180LU, 0xc276341eLU, 0xc75d56f1LU, 0xc444b36fLU, 0xd5c314ebLU, 0xd6daf175LU, 0xd3f1939aLU, 0xd0e87604LU, 0xd9a75709LU, 0xdabeb297LU, 0xdf95d078LU, 0xdc8c35e6LU, 0xfdd6d33dLU, 0xfecf36a3LU, 0xfbe4544cLU, 0xf8fdb1d2LU, 0xf1b290dfLU, 0xf2ab7541LU, 0xf78017aeLU, 0xf499f230LU, 0xe51e55b4LU, 0xe607b02aLU, 0xe32cd2c5LU, 0xe035375bLU, 0xe97a1656LU, 0xea63f3c8LU, 0xef489127LU, 0xec5174b9LU, 0xadfc10dcLU, 0xaee5f542LU, 0xabce97adLU, 0xa8d77233LU, 0xa198533eLU, 0xa281b6a0LU, 0xa7aad44fLU, 0xa4b331d1LU, 0xb5349655LU, 0xb62d73cbLU, 0xb3061124LU, 0xb01ff4baLU, 0xb950d5b7LU, 0xba493029LU, 0xbf6252c6LU, 0xbc7bb758LU, 0x9d215183LU, 0x9e38b41dLU, 0x9b13d6f2LU, 0x980a336cLU, 0x91451261LU, 0x925cf7ffLU, 0x97779510LU, 0x946e708eLU, 0x85e9d70aLU, 0x86f03294LU, 0x83db507bLU, 0x80c2b5e5LU, 0x898d94e8LU, 0x8a947176LU, 0x8fbf1399LU, 0x8ca6f607LU, 0x0da8db53LU, 0x0eb13ecdLU, 0x0b9a5c22LU, 0x0883b9bcLU, 0x01cc98b1LU, 0x02d57d2fLU, 0x07fe1fc0LU, 0x04e7fa5eLU, 0x15605ddaLU, 0x1679b844LU, 0x1352daabLU, 0x104b3f35LU, 0x19041e38LU, 0x1a1dfba6LU, 0x1f369949LU, 0x1c2f7cd7LU, 0x3d759a0cLU, 0x3e6c7f92LU, 0x3b471d7dLU, 0x385ef8e3LU, 0x3111d9eeLU, 0x32083c70LU, 0x37235e9fLU, 0x343abb01LU, 0x25bd1c85LU, 0x26a4f91bLU, 0x238f9bf4LU, 0x20967e6aLU, 0x29d95f67LU, 0x2ac0baf9LU, 0x2febd816LU, 0x2cf23d88LU, 0x6d5f59edLU, 0x6e46bc73LU, 0x6b6dde9cLU, 0x68743b02LU, 0x613b1a0fLU, 0x6222ff91LU, 0x67099d7eLU, 0x641078e0LU, 0x7597df64LU, 0x768e3afaLU, 0x73a55815LU, 0x70bcbd8bLU, 0x79f39c86LU, 0x7aea7918LU, 0x7fc11bf7LU, 0x7cd8fe69LU, 0x5d8218b2LU, 0x5e9bfd2cLU, 0x5bb09fc3LU, 0x58a97a5dLU, 0x51e65b50LU, 0x52ffbeceLU, 0x57d4dc21LU, 0x54cd39bfLU, 0x454a9e3bLU, 0x46537ba5LU, 0x4378194aLU, 0x4061fcd4LU, 0x492eddd9LU, 0x4a373847LU, 0x4f1c5aa8LU, 0x4c05bf36LU }; #endif /* LTC_TWOFISH_ALL_TABLES */ #endif /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/twofish/twofish_tab.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/ciphers/twofish/twofish.c0000644000175100001440000005101210621351501020260 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file twofish.c Implementation of Twofish by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_TWOFISH /* first LTC_TWOFISH_ALL_TABLES must ensure LTC_TWOFISH_TABLES is defined */ #ifdef LTC_TWOFISH_ALL_TABLES #ifndef LTC_TWOFISH_TABLES #define LTC_TWOFISH_TABLES #endif #endif const struct ltc_cipher_descriptor twofish_desc = { "twofish", 7, 16, 32, 16, 16, &twofish_setup, &twofish_ecb_encrypt, &twofish_ecb_decrypt, &twofish_test, &twofish_done, &twofish_keysize, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; /* the two polynomials */ #define MDS_POLY 0x169 #define RS_POLY 0x14D /* The 4x4 MDS Linear Transform */ static const unsigned char MDS[4][4] = { { 0x01, 0xEF, 0x5B, 0x5B }, { 0x5B, 0xEF, 0xEF, 0x01 }, { 0xEF, 0x5B, 0x01, 0xEF }, { 0xEF, 0x01, 0xEF, 0x5B } }; /* The 4x8 RS Linear Transform */ static const unsigned char RS[4][8] = { { 0x01, 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E }, { 0xA4, 0x56, 0x82, 0xF3, 0X1E, 0XC6, 0X68, 0XE5 }, { 0X02, 0XA1, 0XFC, 0XC1, 0X47, 0XAE, 0X3D, 0X19 }, { 0XA4, 0X55, 0X87, 0X5A, 0X58, 0XDB, 0X9E, 0X03 } }; /* sbox usage orderings */ static const unsigned char qord[4][5] = { { 1, 1, 0, 0, 1 }, { 0, 1, 1, 0, 0 }, { 0, 0, 0, 1, 1 }, { 1, 0, 1, 1, 0 } }; #ifdef LTC_TWOFISH_TABLES #include "twofish_tab.c" #define sbox(i, x) ((ulong32)SBOX[i][(x)&255]) #else /* The Q-box tables */ static const unsigned char qbox[2][4][16] = { { { 0x8, 0x1, 0x7, 0xD, 0x6, 0xF, 0x3, 0x2, 0x0, 0xB, 0x5, 0x9, 0xE, 0xC, 0xA, 0x4 }, { 0xE, 0XC, 0XB, 0X8, 0X1, 0X2, 0X3, 0X5, 0XF, 0X4, 0XA, 0X6, 0X7, 0X0, 0X9, 0XD }, { 0XB, 0XA, 0X5, 0XE, 0X6, 0XD, 0X9, 0X0, 0XC, 0X8, 0XF, 0X3, 0X2, 0X4, 0X7, 0X1 }, { 0XD, 0X7, 0XF, 0X4, 0X1, 0X2, 0X6, 0XE, 0X9, 0XB, 0X3, 0X0, 0X8, 0X5, 0XC, 0XA } }, { { 0X2, 0X8, 0XB, 0XD, 0XF, 0X7, 0X6, 0XE, 0X3, 0X1, 0X9, 0X4, 0X0, 0XA, 0XC, 0X5 }, { 0X1, 0XE, 0X2, 0XB, 0X4, 0XC, 0X3, 0X7, 0X6, 0XD, 0XA, 0X5, 0XF, 0X9, 0X0, 0X8 }, { 0X4, 0XC, 0X7, 0X5, 0X1, 0X6, 0X9, 0XA, 0X0, 0XE, 0XD, 0X8, 0X2, 0XB, 0X3, 0XF }, { 0xB, 0X9, 0X5, 0X1, 0XC, 0X3, 0XD, 0XE, 0X6, 0X4, 0X7, 0XF, 0X2, 0X0, 0X8, 0XA } } }; /* computes S_i[x] */ #ifdef LTC_CLEAN_STACK static ulong32 _sbox(int i, ulong32 x) #else static ulong32 sbox(int i, ulong32 x) #endif { unsigned char a0,b0,a1,b1,a2,b2,a3,b3,a4,b4,y; /* a0,b0 = [x/16], x mod 16 */ a0 = (unsigned char)((x>>4)&15); b0 = (unsigned char)((x)&15); /* a1 = a0 ^ b0 */ a1 = a0 ^ b0; /* b1 = a0 ^ ROR(b0, 1) ^ 8a0 */ b1 = (a0 ^ ((b0<<3)|(b0>>1)) ^ (a0<<3)) & 15; /* a2,b2 = t0[a1], t1[b1] */ a2 = qbox[i][0][(int)a1]; b2 = qbox[i][1][(int)b1]; /* a3 = a2 ^ b2 */ a3 = a2 ^ b2; /* b3 = a2 ^ ROR(b2, 1) ^ 8a2 */ b3 = (a2 ^ ((b2<<3)|(b2>>1)) ^ (a2<<3)) & 15; /* a4,b4 = t2[a3], t3[b3] */ a4 = qbox[i][2][(int)a3]; b4 = qbox[i][3][(int)b3]; /* y = 16b4 + a4 */ y = (b4 << 4) + a4; /* return result */ return (ulong32)y; } #ifdef LTC_CLEAN_STACK static ulong32 sbox(int i, ulong32 x) { ulong32 y; y = _sbox(i, x); burn_stack(sizeof(unsigned char) * 11); return y; } #endif /* LTC_CLEAN_STACK */ #endif /* LTC_TWOFISH_TABLES */ /* computes ab mod p */ static ulong32 gf_mult(ulong32 a, ulong32 b, ulong32 p) { ulong32 result, B[2], P[2]; P[1] = p; B[1] = b; result = P[0] = B[0] = 0; /* unrolled branchless GF multiplier */ result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); result ^= B[a&1]; a >>= 1; B[1] = P[B[1]>>7] ^ (B[1] << 1); result ^= B[a&1]; return result; } /* computes [y0 y1 y2 y3] = MDS . [x0] */ #ifndef LTC_TWOFISH_TABLES static ulong32 mds_column_mult(unsigned char in, int col) { ulong32 x01, x5B, xEF; x01 = in; x5B = gf_mult(in, 0x5B, MDS_POLY); xEF = gf_mult(in, 0xEF, MDS_POLY); switch (col) { case 0: return (x01 << 0 ) | (x5B << 8 ) | (xEF << 16) | (xEF << 24); case 1: return (xEF << 0 ) | (xEF << 8 ) | (x5B << 16) | (x01 << 24); case 2: return (x5B << 0 ) | (xEF << 8 ) | (x01 << 16) | (xEF << 24); case 3: return (x5B << 0 ) | (x01 << 8 ) | (xEF << 16) | (x5B << 24); } /* avoid warnings, we'd never get here normally but just to calm compiler warnings... */ return 0; } #else /* !LTC_TWOFISH_TABLES */ #define mds_column_mult(x, i) mds_tab[i][x] #endif /* LTC_TWOFISH_TABLES */ /* Computes [y0 y1 y2 y3] = MDS . [x0 x1 x2 x3] */ static void mds_mult(const unsigned char *in, unsigned char *out) { int x; ulong32 tmp; for (tmp = x = 0; x < 4; x++) { tmp ^= mds_column_mult(in[x], x); } STORE32L(tmp, out); } #ifdef LTC_TWOFISH_ALL_TABLES /* computes [y0 y1 y2 y3] = RS . [x0 x1 x2 x3 x4 x5 x6 x7] */ static void rs_mult(const unsigned char *in, unsigned char *out) { ulong32 tmp; tmp = rs_tab0[in[0]] ^ rs_tab1[in[1]] ^ rs_tab2[in[2]] ^ rs_tab3[in[3]] ^ rs_tab4[in[4]] ^ rs_tab5[in[5]] ^ rs_tab6[in[6]] ^ rs_tab7[in[7]]; STORE32L(tmp, out); } #else /* !LTC_TWOFISH_ALL_TABLES */ /* computes [y0 y1 y2 y3] = RS . [x0 x1 x2 x3 x4 x5 x6 x7] */ static void rs_mult(const unsigned char *in, unsigned char *out) { int x, y; for (x = 0; x < 4; x++) { out[x] = 0; for (y = 0; y < 8; y++) { out[x] ^= gf_mult(in[y], RS[x][y], RS_POLY); } } } #endif /* computes h(x) */ static void h_func(const unsigned char *in, unsigned char *out, unsigned char *M, int k, int offset) { int x; unsigned char y[4]; for (x = 0; x < 4; x++) { y[x] = in[x]; } switch (k) { case 4: y[0] = (unsigned char)(sbox(1, (ulong32)y[0]) ^ M[4 * (6 + offset) + 0]); y[1] = (unsigned char)(sbox(0, (ulong32)y[1]) ^ M[4 * (6 + offset) + 1]); y[2] = (unsigned char)(sbox(0, (ulong32)y[2]) ^ M[4 * (6 + offset) + 2]); y[3] = (unsigned char)(sbox(1, (ulong32)y[3]) ^ M[4 * (6 + offset) + 3]); case 3: y[0] = (unsigned char)(sbox(1, (ulong32)y[0]) ^ M[4 * (4 + offset) + 0]); y[1] = (unsigned char)(sbox(1, (ulong32)y[1]) ^ M[4 * (4 + offset) + 1]); y[2] = (unsigned char)(sbox(0, (ulong32)y[2]) ^ M[4 * (4 + offset) + 2]); y[3] = (unsigned char)(sbox(0, (ulong32)y[3]) ^ M[4 * (4 + offset) + 3]); case 2: y[0] = (unsigned char)(sbox(1, sbox(0, sbox(0, (ulong32)y[0]) ^ M[4 * (2 + offset) + 0]) ^ M[4 * (0 + offset) + 0])); y[1] = (unsigned char)(sbox(0, sbox(0, sbox(1, (ulong32)y[1]) ^ M[4 * (2 + offset) + 1]) ^ M[4 * (0 + offset) + 1])); y[2] = (unsigned char)(sbox(1, sbox(1, sbox(0, (ulong32)y[2]) ^ M[4 * (2 + offset) + 2]) ^ M[4 * (0 + offset) + 2])); y[3] = (unsigned char)(sbox(0, sbox(1, sbox(1, (ulong32)y[3]) ^ M[4 * (2 + offset) + 3]) ^ M[4 * (0 + offset) + 3])); } mds_mult(y, out); } #ifndef LTC_TWOFISH_SMALL /* for GCC we don't use pointer aliases */ #if defined(__GNUC__) #define S1 skey->twofish.S[0] #define S2 skey->twofish.S[1] #define S3 skey->twofish.S[2] #define S4 skey->twofish.S[3] #endif /* the G function */ #define g_func(x, dum) (S1[byte(x,0)] ^ S2[byte(x,1)] ^ S3[byte(x,2)] ^ S4[byte(x,3)]) #define g1_func(x, dum) (S2[byte(x,0)] ^ S3[byte(x,1)] ^ S4[byte(x,2)] ^ S1[byte(x,3)]) #else #ifdef LTC_CLEAN_STACK static ulong32 _g_func(ulong32 x, symmetric_key *key) #else static ulong32 g_func(ulong32 x, symmetric_key *key) #endif { unsigned char g, i, y, z; ulong32 res; res = 0; for (y = 0; y < 4; y++) { z = key->twofish.start; /* do unkeyed substitution */ g = sbox(qord[y][z++], (x >> (8*y)) & 255); /* first subkey */ i = 0; /* do key mixing+sbox until z==5 */ while (z != 5) { g = g ^ key->twofish.S[4*i++ + y]; g = sbox(qord[y][z++], g); } /* multiply g by a column of the MDS */ res ^= mds_column_mult(g, y); } return res; } #define g1_func(x, key) g_func(ROLc(x, 8), key) #ifdef LTC_CLEAN_STACK static ulong32 g_func(ulong32 x, symmetric_key *key) { ulong32 y; y = _g_func(x, key); burn_stack(sizeof(unsigned char) * 4 + sizeof(ulong32)); return y; } #endif /* LTC_CLEAN_STACK */ #endif /* LTC_TWOFISH_SMALL */ /** Initialize the Twofish block cipher @param key The symmetric key you wish to pass @param keylen The key length in bytes @param num_rounds The number of rounds desired (0 for default) @param skey The key in as scheduled by this function. @return CRYPT_OK if successful */ #ifdef LTC_CLEAN_STACK static int _twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) #else int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) #endif { #ifndef LTC_TWOFISH_SMALL unsigned char S[4*4], tmpx0, tmpx1; #endif int k, x, y; unsigned char tmp[4], tmp2[4], M[8*4]; ulong32 A, B; LTC_ARGCHK(key != NULL); LTC_ARGCHK(skey != NULL); /* invalid arguments? */ if (num_rounds != 16 && num_rounds != 0) { return CRYPT_INVALID_ROUNDS; } if (keylen != 16 && keylen != 24 && keylen != 32) { return CRYPT_INVALID_KEYSIZE; } /* k = keysize/64 [but since our keysize is in bytes...] */ k = keylen / 8; /* copy the key into M */ for (x = 0; x < keylen; x++) { M[x] = key[x] & 255; } /* create the S[..] words */ #ifndef LTC_TWOFISH_SMALL for (x = 0; x < k; x++) { rs_mult(M+(x*8), S+(x*4)); } #else for (x = 0; x < k; x++) { rs_mult(M+(x*8), skey->twofish.S+(x*4)); } #endif /* make subkeys */ for (x = 0; x < 20; x++) { /* A = h(p * 2x, Me) */ for (y = 0; y < 4; y++) { tmp[y] = x+x; } h_func(tmp, tmp2, M, k, 0); LOAD32L(A, tmp2); /* B = ROL(h(p * (2x + 1), Mo), 8) */ for (y = 0; y < 4; y++) { tmp[y] = (unsigned char)(x+x+1); } h_func(tmp, tmp2, M, k, 1); LOAD32L(B, tmp2); B = ROLc(B, 8); /* K[2i] = A + B */ skey->twofish.K[x+x] = (A + B) & 0xFFFFFFFFUL; /* K[2i+1] = (A + 2B) <<< 9 */ skey->twofish.K[x+x+1] = ROLc(B + B + A, 9); } #ifndef LTC_TWOFISH_SMALL /* make the sboxes (large ram variant) */ if (k == 2) { for (x = 0; x < 256; x++) { tmpx0 = (unsigned char)sbox(0, x); tmpx1 = (unsigned char)sbox(1, x); skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, tmpx0 ^ S[0]) ^ S[4])),0); skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, tmpx1 ^ S[1]) ^ S[5])),1); skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, tmpx0 ^ S[2]) ^ S[6])),2); skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, tmpx1 ^ S[3]) ^ S[7])),3); } } else if (k == 3) { for (x = 0; x < 256; x++) { tmpx0 = (unsigned char)sbox(0, x); tmpx1 = (unsigned char)sbox(1, x); skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, tmpx1 ^ S[0]) ^ S[4]) ^ S[8])),0); skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, tmpx1 ^ S[1]) ^ S[5]) ^ S[9])),1); skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10])),2); skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, sbox(1, tmpx0 ^ S[3]) ^ S[7]) ^ S[11])),3); } } else { for (x = 0; x < 256; x++) { tmpx0 = (unsigned char)sbox(0, x); tmpx1 = (unsigned char)sbox(1, x); skey->twofish.S[0][x] = mds_column_mult(sbox(1, (sbox(0, sbox(0, sbox(1, tmpx1 ^ S[0]) ^ S[4]) ^ S[8]) ^ S[12])),0); skey->twofish.S[1][x] = mds_column_mult(sbox(0, (sbox(0, sbox(1, sbox(1, tmpx0 ^ S[1]) ^ S[5]) ^ S[9]) ^ S[13])),1); skey->twofish.S[2][x] = mds_column_mult(sbox(1, (sbox(1, sbox(0, sbox(0, tmpx0 ^ S[2]) ^ S[6]) ^ S[10]) ^ S[14])),2); skey->twofish.S[3][x] = mds_column_mult(sbox(0, (sbox(1, sbox(1, sbox(0, tmpx1 ^ S[3]) ^ S[7]) ^ S[11]) ^ S[15])),3); } } #else /* where to start in the sbox layers */ /* small ram variant */ switch (k) { case 4 : skey->twofish.start = 0; break; case 3 : skey->twofish.start = 1; break; default: skey->twofish.start = 2; break; } #endif return CRYPT_OK; } #ifdef LTC_CLEAN_STACK int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) { int x; x = _twofish_setup(key, keylen, num_rounds, skey); burn_stack(sizeof(int) * 7 + sizeof(unsigned char) * 56 + sizeof(ulong32) * 2); return x; } #endif /** Encrypts a block of text with Twofish @param pt The input plaintext (16 bytes) @param ct The output ciphertext (16 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ #ifdef LTC_CLEAN_STACK static int _twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) #else int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) #endif { ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k; int r; #if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__) ulong32 *S1, *S2, *S3, *S4; #endif LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); #if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__) S1 = skey->twofish.S[0]; S2 = skey->twofish.S[1]; S3 = skey->twofish.S[2]; S4 = skey->twofish.S[3]; #endif LOAD32L(a,&pt[0]); LOAD32L(b,&pt[4]); LOAD32L(c,&pt[8]); LOAD32L(d,&pt[12]); a ^= skey->twofish.K[0]; b ^= skey->twofish.K[1]; c ^= skey->twofish.K[2]; d ^= skey->twofish.K[3]; k = skey->twofish.K + 8; for (r = 8; r != 0; --r) { t2 = g1_func(b, skey); t1 = g_func(a, skey) + t2; c = RORc(c ^ (t1 + k[0]), 1); d = ROLc(d, 1) ^ (t2 + t1 + k[1]); t2 = g1_func(d, skey); t1 = g_func(c, skey) + t2; a = RORc(a ^ (t1 + k[2]), 1); b = ROLc(b, 1) ^ (t2 + t1 + k[3]); k += 4; } /* output with "undo last swap" */ ta = c ^ skey->twofish.K[4]; tb = d ^ skey->twofish.K[5]; tc = a ^ skey->twofish.K[6]; td = b ^ skey->twofish.K[7]; /* store output */ STORE32L(ta,&ct[0]); STORE32L(tb,&ct[4]); STORE32L(tc,&ct[8]); STORE32L(td,&ct[12]); return CRYPT_OK; } #ifdef LTC_CLEAN_STACK int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) { int err = _twofish_ecb_encrypt(pt, ct, skey); burn_stack(sizeof(ulong32) * 10 + sizeof(int)); return err; } #endif /** Decrypts a block of text with Twofish @param ct The input ciphertext (16 bytes) @param pt The output plaintext (16 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ #ifdef LTC_CLEAN_STACK static int _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) #else int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) #endif { ulong32 a,b,c,d,ta,tb,tc,td,t1,t2, *k; int r; #if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__) ulong32 *S1, *S2, *S3, *S4; #endif LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); #if !defined(LTC_TWOFISH_SMALL) && !defined(__GNUC__) S1 = skey->twofish.S[0]; S2 = skey->twofish.S[1]; S3 = skey->twofish.S[2]; S4 = skey->twofish.S[3]; #endif /* load input */ LOAD32L(ta,&ct[0]); LOAD32L(tb,&ct[4]); LOAD32L(tc,&ct[8]); LOAD32L(td,&ct[12]); /* undo undo final swap */ a = tc ^ skey->twofish.K[6]; b = td ^ skey->twofish.K[7]; c = ta ^ skey->twofish.K[4]; d = tb ^ skey->twofish.K[5]; k = skey->twofish.K + 36; for (r = 8; r != 0; --r) { t2 = g1_func(d, skey); t1 = g_func(c, skey) + t2; a = ROLc(a, 1) ^ (t1 + k[2]); b = RORc(b ^ (t2 + t1 + k[3]), 1); t2 = g1_func(b, skey); t1 = g_func(a, skey) + t2; c = ROLc(c, 1) ^ (t1 + k[0]); d = RORc(d ^ (t2 + t1 + k[1]), 1); k -= 4; } /* pre-white */ a ^= skey->twofish.K[0]; b ^= skey->twofish.K[1]; c ^= skey->twofish.K[2]; d ^= skey->twofish.K[3]; /* store */ STORE32L(a, &pt[0]); STORE32L(b, &pt[4]); STORE32L(c, &pt[8]); STORE32L(d, &pt[12]); return CRYPT_OK; } #ifdef LTC_CLEAN_STACK int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) { int err =_twofish_ecb_decrypt(ct, pt, skey); burn_stack(sizeof(ulong32) * 10 + sizeof(int)); return err; } #endif /** Performs a self-test of the Twofish block cipher @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled */ int twofish_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { int keylen; unsigned char key[32], pt[16], ct[16]; } tests[] = { { 16, { 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32, 0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A }, { 0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E, 0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19 }, { 0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85, 0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3 } }, { 24, { 0x88, 0xB2, 0xB2, 0x70, 0x6B, 0x10, 0x5E, 0x36, 0xB4, 0x46, 0xBB, 0x6D, 0x73, 0x1A, 0x1E, 0x88, 0xEF, 0xA7, 0x1F, 0x78, 0x89, 0x65, 0xBD, 0x44 }, { 0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5, 0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2 }, { 0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45, 0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65 } }, { 32, { 0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46, 0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D, 0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B, 0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F }, { 0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F, 0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6 }, { 0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97, 0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA } } }; symmetric_key key; unsigned char tmp[2][16]; int err, i, y; for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { if ((err = twofish_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { return err; } twofish_ecb_encrypt(tests[i].pt, tmp[0], &key); twofish_ecb_decrypt(tmp[0], tmp[1], &key); if (XMEMCMP(tmp[0], tests[i].ct, 16) != 0 || XMEMCMP(tmp[1], tests[i].pt, 16) != 0) { #if 0 printf("Twofish failed test %d, %d, %d\n", i, XMEMCMP(tmp[0], tests[i].ct, 16), XMEMCMP(tmp[1], tests[i].pt, 16)); #endif return CRYPT_FAIL_TESTVECTOR; } /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ for (y = 0; y < 16; y++) tmp[0][y] = 0; for (y = 0; y < 1000; y++) twofish_ecb_encrypt(tmp[0], tmp[0], &key); for (y = 0; y < 1000; y++) twofish_ecb_decrypt(tmp[0], tmp[0], &key); for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; } return CRYPT_OK; #endif } /** Terminate the context @param skey The scheduled key */ void twofish_done(symmetric_key *skey) { } /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. @return CRYPT_OK if the input key size is acceptable. */ int twofish_keysize(int *keysize) { LTC_ARGCHK(keysize); if (*keysize < 16) return CRYPT_INVALID_KEYSIZE; if (*keysize < 24) { *keysize = 16; return CRYPT_OK; } else if (*keysize < 32) { *keysize = 24; return CRYPT_OK; } else { *keysize = 32; return CRYPT_OK; } } #endif /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/twofish/twofish.c,v $ */ /* $Revision: 1.16 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/src/ciphers/skipjack.c0000644000175100001440000002317410621351501016721 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file skipjack.c Skipjack Implementation by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_SKIPJACK const struct ltc_cipher_descriptor skipjack_desc = { "skipjack", 17, 10, 10, 8, 32, &skipjack_setup, &skipjack_ecb_encrypt, &skipjack_ecb_decrypt, &skipjack_test, &skipjack_done, &skipjack_keysize, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static const unsigned char sbox[256] = { 0xa3,0xd7,0x09,0x83,0xf8,0x48,0xf6,0xf4,0xb3,0x21,0x15,0x78,0x99,0xb1,0xaf,0xf9, 0xe7,0x2d,0x4d,0x8a,0xce,0x4c,0xca,0x2e,0x52,0x95,0xd9,0x1e,0x4e,0x38,0x44,0x28, 0x0a,0xdf,0x02,0xa0,0x17,0xf1,0x60,0x68,0x12,0xb7,0x7a,0xc3,0xe9,0xfa,0x3d,0x53, 0x96,0x84,0x6b,0xba,0xf2,0x63,0x9a,0x19,0x7c,0xae,0xe5,0xf5,0xf7,0x16,0x6a,0xa2, 0x39,0xb6,0x7b,0x0f,0xc1,0x93,0x81,0x1b,0xee,0xb4,0x1a,0xea,0xd0,0x91,0x2f,0xb8, 0x55,0xb9,0xda,0x85,0x3f,0x41,0xbf,0xe0,0x5a,0x58,0x80,0x5f,0x66,0x0b,0xd8,0x90, 0x35,0xd5,0xc0,0xa7,0x33,0x06,0x65,0x69,0x45,0x00,0x94,0x56,0x6d,0x98,0x9b,0x76, 0x97,0xfc,0xb2,0xc2,0xb0,0xfe,0xdb,0x20,0xe1,0xeb,0xd6,0xe4,0xdd,0x47,0x4a,0x1d, 0x42,0xed,0x9e,0x6e,0x49,0x3c,0xcd,0x43,0x27,0xd2,0x07,0xd4,0xde,0xc7,0x67,0x18, 0x89,0xcb,0x30,0x1f,0x8d,0xc6,0x8f,0xaa,0xc8,0x74,0xdc,0xc9,0x5d,0x5c,0x31,0xa4, 0x70,0x88,0x61,0x2c,0x9f,0x0d,0x2b,0x87,0x50,0x82,0x54,0x64,0x26,0x7d,0x03,0x40, 0x34,0x4b,0x1c,0x73,0xd1,0xc4,0xfd,0x3b,0xcc,0xfb,0x7f,0xab,0xe6,0x3e,0x5b,0xa5, 0xad,0x04,0x23,0x9c,0x14,0x51,0x22,0xf0,0x29,0x79,0x71,0x7e,0xff,0x8c,0x0e,0xe2, 0x0c,0xef,0xbc,0x72,0x75,0x6f,0x37,0xa1,0xec,0xd3,0x8e,0x62,0x8b,0x86,0x10,0xe8, 0x08,0x77,0x11,0xbe,0x92,0x4f,0x24,0xc5,0x32,0x36,0x9d,0xcf,0xf3,0xa6,0xbb,0xac, 0x5e,0x6c,0xa9,0x13,0x57,0x25,0xb5,0xe3,0xbd,0xa8,0x3a,0x01,0x05,0x59,0x2a,0x46 }; /* simple x + 1 (mod 10) in one step. */ static const int keystep[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 }; /* simple x - 1 (mod 10) in one step */ static const int ikeystep[] = { 9, 0, 1, 2, 3, 4, 5, 6, 7, 8 }; /** Initialize the Skipjack block cipher @param key The symmetric key you wish to pass @param keylen The key length in bytes @param num_rounds The number of rounds desired (0 for default) @param skey The key in as scheduled by this function. @return CRYPT_OK if successful */ int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) { int x; LTC_ARGCHK(key != NULL); LTC_ARGCHK(skey != NULL); if (keylen != 10) { return CRYPT_INVALID_KEYSIZE; } if (num_rounds != 32 && num_rounds != 0) { return CRYPT_INVALID_ROUNDS; } /* make sure the key is in range for platforms where CHAR_BIT != 8 */ for (x = 0; x < 10; x++) { skey->skipjack.key[x] = key[x] & 255; } return CRYPT_OK; } #define RULE_A \ tmp = g_func(w1, &kp, skey->skipjack.key); \ w1 = tmp ^ w4 ^ x; \ w4 = w3; w3 = w2; \ w2 = tmp; #define RULE_B \ tmp = g_func(w1, &kp, skey->skipjack.key); \ tmp1 = w4; w4 = w3; \ w3 = w1 ^ w2 ^ x; \ w1 = tmp1; w2 = tmp; #define RULE_A1 \ tmp = w1 ^ w2 ^ x; \ w1 = ig_func(w2, &kp, skey->skipjack.key); \ w2 = w3; w3 = w4; w4 = tmp; #define RULE_B1 \ tmp = ig_func(w2, &kp, skey->skipjack.key); \ w2 = tmp ^ w3 ^ x; \ w3 = w4; w4 = w1; w1 = tmp; static unsigned g_func(unsigned w, int *kp, unsigned char *key) { unsigned char g1,g2; g1 = (w >> 8) & 255; g2 = w & 255; g1 ^= sbox[g2^key[*kp]]; *kp = keystep[*kp]; g2 ^= sbox[g1^key[*kp]]; *kp = keystep[*kp]; g1 ^= sbox[g2^key[*kp]]; *kp = keystep[*kp]; g2 ^= sbox[g1^key[*kp]]; *kp = keystep[*kp]; return ((unsigned)g1<<8)|(unsigned)g2; } static unsigned ig_func(unsigned w, int *kp, unsigned char *key) { unsigned char g1,g2; g1 = (w >> 8) & 255; g2 = w & 255; *kp = ikeystep[*kp]; g2 ^= sbox[g1^key[*kp]]; *kp = ikeystep[*kp]; g1 ^= sbox[g2^key[*kp]]; *kp = ikeystep[*kp]; g2 ^= sbox[g1^key[*kp]]; *kp = ikeystep[*kp]; g1 ^= sbox[g2^key[*kp]]; return ((unsigned)g1<<8)|(unsigned)g2; } /** Encrypts a block of text with Skipjack @param pt The input plaintext (8 bytes) @param ct The output ciphertext (8 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ #ifdef LTC_CLEAN_STACK static int _skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) #else int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) #endif { unsigned w1,w2,w3,w4,tmp,tmp1; int x, kp; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); /* load block */ w1 = ((unsigned)pt[0]<<8)|pt[1]; w2 = ((unsigned)pt[2]<<8)|pt[3]; w3 = ((unsigned)pt[4]<<8)|pt[5]; w4 = ((unsigned)pt[6]<<8)|pt[7]; /* 8 rounds of RULE A */ for (x = 1, kp = 0; x < 9; x++) { RULE_A; } /* 8 rounds of RULE B */ for (; x < 17; x++) { RULE_B; } /* 8 rounds of RULE A */ for (; x < 25; x++) { RULE_A; } /* 8 rounds of RULE B */ for (; x < 33; x++) { RULE_B; } /* store block */ ct[0] = (w1>>8)&255; ct[1] = w1&255; ct[2] = (w2>>8)&255; ct[3] = w2&255; ct[4] = (w3>>8)&255; ct[5] = w3&255; ct[6] = (w4>>8)&255; ct[7] = w4&255; return CRYPT_OK; } #ifdef LTC_CLEAN_STACK int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) { int err = _skipjack_ecb_encrypt(pt, ct, skey); burn_stack(sizeof(unsigned) * 8 + sizeof(int) * 2); return err; } #endif /** Decrypts a block of text with Skipjack @param ct The input ciphertext (8 bytes) @param pt The output plaintext (8 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ #ifdef LTC_CLEAN_STACK static int _skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) #else int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) #endif { unsigned w1,w2,w3,w4,tmp; int x, kp; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); /* load block */ w1 = ((unsigned)ct[0]<<8)|ct[1]; w2 = ((unsigned)ct[2]<<8)|ct[3]; w3 = ((unsigned)ct[4]<<8)|ct[5]; w4 = ((unsigned)ct[6]<<8)|ct[7]; /* 8 rounds of RULE B^-1 Note the value "kp = 8" comes from "kp = (32 * 4) mod 10" where 32*4 is 128 which mod 10 is 8 */ for (x = 32, kp = 8; x > 24; x--) { RULE_B1; } /* 8 rounds of RULE A^-1 */ for (; x > 16; x--) { RULE_A1; } /* 8 rounds of RULE B^-1 */ for (; x > 8; x--) { RULE_B1; } /* 8 rounds of RULE A^-1 */ for (; x > 0; x--) { RULE_A1; } /* store block */ pt[0] = (w1>>8)&255; pt[1] = w1&255; pt[2] = (w2>>8)&255; pt[3] = w2&255; pt[4] = (w3>>8)&255; pt[5] = w3&255; pt[6] = (w4>>8)&255; pt[7] = w4&255; return CRYPT_OK; } #ifdef LTC_CLEAN_STACK int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) { int err = _skipjack_ecb_decrypt(ct, pt, skey); burn_stack(sizeof(unsigned) * 7 + sizeof(int) * 2); return err; } #endif /** Performs a self-test of the Skipjack block cipher @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled */ int skipjack_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { unsigned char key[10], pt[8], ct[8]; } tests[] = { { { 0x00, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }, { 0x33, 0x22, 0x11, 0x00, 0xdd, 0xcc, 0xbb, 0xaa }, { 0x25, 0x87, 0xca, 0xe2, 0x7a, 0x12, 0xd3, 0x00 } } }; unsigned char buf[2][8]; int x, y, err; symmetric_key key; for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) { /* setup key */ if ((err = skipjack_setup(tests[x].key, 10, 0, &key)) != CRYPT_OK) { return err; } /* encrypt and decrypt */ skipjack_ecb_encrypt(tests[x].pt, buf[0], &key); skipjack_ecb_decrypt(buf[0], buf[1], &key); /* compare */ if (XMEMCMP(buf[0], tests[x].ct, 8) != 0 || XMEMCMP(buf[1], tests[x].pt, 8) != 0) { return CRYPT_FAIL_TESTVECTOR; } /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ for (y = 0; y < 8; y++) buf[0][y] = 0; for (y = 0; y < 1000; y++) skipjack_ecb_encrypt(buf[0], buf[0], &key); for (y = 0; y < 1000; y++) skipjack_ecb_decrypt(buf[0], buf[0], &key); for (y = 0; y < 8; y++) if (buf[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; } return CRYPT_OK; #endif } /** Terminate the context @param skey The scheduled key */ void skipjack_done(symmetric_key *skey) { } /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. @return CRYPT_OK if the input key size is acceptable. */ int skipjack_keysize(int *keysize) { LTC_ARGCHK(keysize != NULL); if (*keysize < 10) { return CRYPT_INVALID_KEYSIZE; } else if (*keysize > 10) { *keysize = 10; } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/skipjack.c,v $ */ /* $Revision: 1.14 $ */ /* $Date: 2007/05/12 14:20:27 $ */ libtomcrypt-1.17/src/ciphers/xtea.c0000644000175100001440000001330310621351501016054 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file xtea.c Implementation of LTC_XTEA, Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_XTEA const struct ltc_cipher_descriptor xtea_desc = { "xtea", 1, 16, 16, 8, 32, &xtea_setup, &xtea_ecb_encrypt, &xtea_ecb_decrypt, &xtea_test, &xtea_done, &xtea_keysize, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) { unsigned long x, sum, K[4]; LTC_ARGCHK(key != NULL); LTC_ARGCHK(skey != NULL); /* check arguments */ if (keylen != 16) { return CRYPT_INVALID_KEYSIZE; } if (num_rounds != 0 && num_rounds != 32) { return CRYPT_INVALID_ROUNDS; } /* load key */ LOAD32L(K[0], key+0); LOAD32L(K[1], key+4); LOAD32L(K[2], key+8); LOAD32L(K[3], key+12); for (x = sum = 0; x < 32; x++) { skey->xtea.A[x] = (sum + K[sum&3]) & 0xFFFFFFFFUL; sum = (sum + 0x9E3779B9UL) & 0xFFFFFFFFUL; skey->xtea.B[x] = (sum + K[(sum>>11)&3]) & 0xFFFFFFFFUL; } #ifdef LTC_CLEAN_STACK zeromem(&K, sizeof(K)); #endif return CRYPT_OK; } /** Encrypts a block of text with LTC_XTEA @param pt The input plaintext (8 bytes) @param ct The output ciphertext (8 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ int xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) { unsigned long y, z; int r; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); LOAD32L(y, &pt[0]); LOAD32L(z, &pt[4]); for (r = 0; r < 32; r += 4) { y = (y + ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r])) & 0xFFFFFFFFUL; z = (z + ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r])) & 0xFFFFFFFFUL; y = (y + ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r+1])) & 0xFFFFFFFFUL; z = (z + ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r+1])) & 0xFFFFFFFFUL; y = (y + ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r+2])) & 0xFFFFFFFFUL; z = (z + ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r+2])) & 0xFFFFFFFFUL; y = (y + ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r+3])) & 0xFFFFFFFFUL; z = (z + ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r+3])) & 0xFFFFFFFFUL; } STORE32L(y, &ct[0]); STORE32L(z, &ct[4]); return CRYPT_OK; } /** Decrypts a block of text with LTC_XTEA @param ct The input ciphertext (8 bytes) @param pt The output plaintext (8 bytes) @param skey The key as scheduled @return CRYPT_OK if successful */ int xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) { unsigned long y, z; int r; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); LOAD32L(y, &ct[0]); LOAD32L(z, &ct[4]); for (r = 31; r >= 0; r -= 4) { z = (z - ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r])) & 0xFFFFFFFFUL; y = (y - ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r])) & 0xFFFFFFFFUL; z = (z - ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r-1])) & 0xFFFFFFFFUL; y = (y - ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r-1])) & 0xFFFFFFFFUL; z = (z - ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r-2])) & 0xFFFFFFFFUL; y = (y - ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r-2])) & 0xFFFFFFFFUL; z = (z - ((((y<<4)^(y>>5)) + y) ^ skey->xtea.B[r-3])) & 0xFFFFFFFFUL; y = (y - ((((z<<4)^(z>>5)) + z) ^ skey->xtea.A[r-3])) & 0xFFFFFFFFUL; } STORE32L(y, &pt[0]); STORE32L(z, &pt[4]); return CRYPT_OK; } /** Performs a self-test of the LTC_XTEA block cipher @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled */ int xtea_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const unsigned char key[16] = { 0x78, 0x56, 0x34, 0x12, 0xf0, 0xcd, 0xcb, 0x9a, 0x48, 0x37, 0x26, 0x15, 0xc0, 0xbf, 0xae, 0x9d }; static const unsigned char pt[8] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; static const unsigned char ct[8] = { 0x75, 0xd7, 0xc5, 0xbf, 0xcf, 0x58, 0xc9, 0x3f }; unsigned char tmp[2][8]; symmetric_key skey; int err, y; if ((err = xtea_setup(key, 16, 0, &skey)) != CRYPT_OK) { return err; } xtea_ecb_encrypt(pt, tmp[0], &skey); xtea_ecb_decrypt(tmp[0], tmp[1], &skey); if (XMEMCMP(tmp[0], ct, 8) != 0 || XMEMCMP(tmp[1], pt, 8) != 0) { return CRYPT_FAIL_TESTVECTOR; } /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ for (y = 0; y < 8; y++) tmp[0][y] = 0; for (y = 0; y < 1000; y++) xtea_ecb_encrypt(tmp[0], tmp[0], &skey); for (y = 0; y < 1000; y++) xtea_ecb_decrypt(tmp[0], tmp[0], &skey); for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; return CRYPT_OK; #endif } /** Terminate the context @param skey The scheduled key */ void xtea_done(symmetric_key *skey) { } /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. @return CRYPT_OK if the input key size is acceptable. */ int xtea_keysize(int *keysize) { LTC_ARGCHK(keysize != NULL); if (*keysize < 16) { return CRYPT_INVALID_KEYSIZE; } *keysize = 16; return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/xtea.c,v $ */ /* $Revision: 1.14 $ */ /* $Date: 2007/05/12 14:20:27 $ */ libtomcrypt-1.17/src/ciphers/cast5.c0000644000175100001440000012231210621351501016133 0ustar tomusers/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. * * Tom St Denis, tomstdenis@gmail.com, http://libtom.org */ /** @file cast5.c Implementation of LTC_CAST5 (RFC 2144) by Tom St Denis */ #include "tomcrypt.h" #ifdef LTC_CAST5 const struct ltc_cipher_descriptor cast5_desc = { "cast5", 15, 5, 16, 8, 16, &cast5_setup, &cast5_ecb_encrypt, &cast5_ecb_decrypt, &cast5_test, &cast5_done, &cast5_keysize, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static const ulong32 S1[256] = { 0x30fb40d4UL, 0x9fa0ff0bUL, 0x6beccd2fUL, 0x3f258c7aUL, 0x1e213f2fUL, 0x9c004dd3UL, 0x6003e540UL, 0xcf9fc949UL, 0xbfd4af27UL, 0x88bbbdb5UL, 0xe2034090UL, 0x98d09675UL, 0x6e63a0e0UL, 0x15c361d2UL, 0xc2e7661dUL, 0x22d4ff8eUL, 0x28683b6fUL, 0xc07fd059UL, 0xff2379c8UL, 0x775f50e2UL, 0x43c340d3UL, 0xdf2f8656UL, 0x887ca41aUL, 0xa2d2bd2dUL, 0xa1c9e0d6UL, 0x346c4819UL, 0x61b76d87UL, 0x22540f2fUL, 0x2abe32e1UL, 0xaa54166bUL, 0x22568e3aUL, 0xa2d341d0UL, 0x66db40c8UL, 0xa784392fUL, 0x004dff2fUL, 0x2db9d2deUL, 0x97943facUL, 0x4a97c1d8UL, 0x527644b7UL, 0xb5f437a7UL, 0xb82cbaefUL, 0xd751d159UL, 0x6ff7f0edUL, 0x5a097a1fUL, 0x827b68d0UL, 0x90ecf52eUL, 0x22b0c054UL, 0xbc8e5935UL, 0x4b6d2f7fUL, 0x50bb64a2UL, 0xd2664910UL, 0xbee5812dUL, 0xb7332290UL, 0xe93b159fUL, 0xb48ee411UL, 0x4bff345dUL, 0xfd45c240UL, 0xad31973fUL, 0xc4f6d02eUL, 0x55fc8165UL, 0xd5b1caadUL, 0xa1ac2daeUL, 0xa2d4b76dUL, 0xc19b0c50UL, 0x882240f2UL, 0x0c6e4f38UL, 0xa4e4bfd7UL, 0x4f5ba272UL, 0x564c1d2fUL, 0xc59c5319UL, 0xb949e354UL, 0xb04669feUL, 0xb1b6ab8aUL, 0xc71358ddUL, 0x6385c545UL, 0x110f935dUL, 0x57538ad5UL, 0x6a390493UL, 0xe63d37e0UL, 0x2a54f6b3UL, 0x3a787d5fUL, 0x6276a0b5UL, 0x19a6fcdfUL, 0x7a42206aUL, 0x29f9d4d5UL, 0xf61b1891UL, 0xbb72275eUL, 0xaa508167UL, 0x38901091UL, 0xc6b505ebUL, 0x84c7cb8cUL, 0x2ad75a0fUL, 0x874a1427UL, 0xa2d1936bUL, 0x2ad286afUL, 0xaa56d291UL, 0xd7894360UL, 0x425c750dUL, 0x93b39e26UL, 0x187184c9UL, 0x6c00b32dUL, 0x73e2bb14UL, 0xa0bebc3cUL, 0x54623779UL, 0x64459eabUL, 0x3f328b82UL, 0x7718cf82UL, 0x59a2cea6UL, 0x04ee002eUL, 0x89fe78e6UL, 0x3fab0950UL, 0x325ff6c2UL, 0x81383f05UL, 0x6963c5c8UL, 0x76cb5ad6UL, 0xd49974c9UL, 0xca180dcfUL, 0x380782d5UL, 0xc7fa5cf6UL, 0x8ac31511UL, 0x35e79e13UL, 0x47da91d0UL, 0xf40f9086UL, 0xa7e2419eUL, 0x31366241UL, 0x051ef495UL, 0xaa573b04UL, 0x4a805d8dUL, 0x548300d0UL, 0x00322a3cUL, 0xbf64cddfUL, 0xba57a68eUL, 0x75c6372bUL, 0x50afd341UL, 0xa7c13275UL, 0x915a0bf5UL, 0x6b54bfabUL, 0x2b0b1426UL, 0xab4cc9d7UL, 0x449ccd82UL, 0xf7fbf265UL, 0xab85c5f3UL, 0x1b55db94UL, 0xaad4e324UL, 0xcfa4bd3fUL, 0x2deaa3e2UL, 0x9e204d02UL, 0xc8bd25acUL, 0xeadf55b3UL, 0xd5bd9e98UL, 0xe31231b2UL, 0x2ad5ad6cUL, 0x954329deUL, 0xadbe4528UL, 0xd8710f69UL, 0xaa51c90fUL, 0xaa786bf6UL, 0x22513f1eUL, 0xaa51a79bUL, 0x2ad344ccUL, 0x7b5a41f0UL, 0xd37cfbadUL, 0x1b069505UL, 0x41ece491UL, 0xb4c332e6UL, 0x032268d4UL, 0xc9600accUL, 0xce387e6dUL, 0xbf6bb16cUL, 0x6a70fb78UL, 0x0d03d9c9UL, 0xd4df39deUL, 0xe01063daUL, 0x4736f464UL, 0x5ad328d8UL, 0xb347cc96UL, 0x75bb0fc3UL, 0x98511bfbUL, 0x4ffbcc35UL, 0xb58bcf6aUL, 0xe11f0abcUL, 0xbfc5fe4aUL, 0xa70aec10UL, 0xac39570aUL, 0x3f04442fUL, 0x6188b153UL, 0xe0397a2eUL, 0x5727cb79UL, 0x9ceb418fUL, 0x1cacd68dUL, 0x2ad37c96UL, 0x0175cb9dUL, 0xc69dff09UL, 0xc75b65f0UL, 0xd9db40d8UL, 0xec0e7779UL, 0x4744ead4UL, 0xb11c3274UL, 0xdd24cb9eUL, 0x7e1c54bdUL, 0xf01144f9UL, 0xd2240eb1UL, 0x9675b3fdUL, 0xa3ac3755UL, 0xd47c27afUL, 0x51c85f4dUL, 0x56907596UL, 0xa5bb15e6UL, 0x580304f0UL, 0xca042cf1UL, 0x011a37eaUL, 0x8dbfaadbUL, 0x35ba3e4aUL, 0x3526ffa0UL, 0xc37b4d09UL, 0xbc306ed9UL, 0x98a52666UL, 0x5648f725UL, 0xff5e569dUL, 0x0ced63d0UL, 0x7c63b2cfUL, 0x700b45e1UL, 0xd5ea50f1UL, 0x85a92872UL, 0xaf1fbda7UL, 0xd4234870UL, 0xa7870bf3UL, 0x2d3b4d79UL, 0x42e04198UL, 0x0cd0ede7UL, 0x26470db8UL, 0xf881814cUL, 0x474d6ad7UL, 0x7c0c5e5cUL, 0xd1231959UL, 0x381b7298UL, 0xf5d2f4dbUL, 0xab838653UL, 0x6e2f1e23UL, 0x83719c9eUL, 0xbd91e046UL, 0x9a56456eUL, 0xdc39200cUL, 0x20c8c571UL, 0x962bda1cUL, 0xe1e696ffUL, 0xb141ab08UL, 0x7cca89b9UL, 0x1a69e783UL, 0x02cc4843UL, 0xa2f7c579UL, 0x429ef47dUL, 0x427b169cUL, 0x5ac9f049UL, 0xdd8f0f00UL, 0x5c8165bfUL}; static const ulong32 S2[256] = { 0x1f201094UL, 0xef0ba75bUL, 0x69e3cf7eUL, 0x393f4380UL, 0xfe61cf7aUL, 0xeec5207aUL, 0x55889c94UL, 0x72fc0651UL, 0xada7ef79UL, 0x4e1d7235UL, 0xd55a63ceUL, 0xde0436baUL, 0x99c430efUL, 0x5f0c0794UL, 0x18dcdb7dUL, 0xa1d6eff3UL, 0xa0b52f7bUL, 0x59e83605UL, 0xee15b094UL, 0xe9ffd909UL, 0xdc440086UL, 0xef944459UL, 0xba83ccb3UL, 0xe0c3cdfbUL, 0xd1da4181UL, 0x3b092ab1UL, 0xf997f1c1UL, 0xa5e6cf7bUL, 0x01420ddbUL, 0xe4e7ef5bUL, 0x25a1ff41UL, 0xe180f806UL, 0x1fc41080UL, 0x179bee7aUL, 0xd37ac6a9UL, 0xfe5830a4UL, 0x98de8b7fUL, 0x77e83f4eUL, 0x79929269UL, 0x24fa9f7bUL, 0xe113c85bUL, 0xacc40083UL, 0xd7503525UL, 0xf7ea615fUL, 0x62143154UL, 0x0d554b63UL, 0x5d681121UL, 0xc866c359UL, 0x3d63cf73UL, 0xcee234c0UL, 0xd4d87e87UL, 0x5c672b21UL, 0x071f6181UL, 0x39f7627fUL, 0x361e3084UL, 0xe4eb573bUL, 0x602f64a4UL, 0xd63acd9cUL, 0x1bbc4635UL, 0x9e81032dUL, 0x2701f50cUL, 0x99847ab4UL, 0xa0e3df79UL, 0xba6cf38cUL, 0x10843094UL, 0x2537a95eUL, 0xf46f6ffeUL, 0xa1ff3b1fUL, 0x208cfb6aUL, 0x8f458c74UL, 0xd9e0a227UL, 0x4ec73a34UL, 0xfc884f69UL, 0x3e4de8dfUL, 0xef0e0088UL, 0x3559648dUL, 0x8a45388cUL, 0x1d804366UL, 0x721d9bfdUL, 0xa58684bbUL, 0xe8256333UL, 0x844e8212UL, 0x128d8098UL, 0xfed33fb4UL, 0xce280ae1UL, 0x27e19ba5UL, 0xd5a6c252UL, 0xe49754bdUL, 0xc5d655ddUL, 0xeb667064UL, 0x77840b4dUL, 0xa1b6a801UL, 0x84db26a9UL, 0xe0b56714UL, 0x21f043b7UL, 0xe5d05860UL, 0x54f03084UL, 0x066ff472UL, 0xa31aa153UL, 0xdadc4755UL, 0xb5625dbfUL, 0x68561be6UL, 0x83ca6b94UL, 0x2d6ed23bUL, 0xeccf01dbUL, 0xa6d3d0baUL, 0xb6803d5cUL, 0xaf77a709UL, 0x33b4a34cUL, 0x397bc8d6UL, 0x5ee22b95UL, 0x5f0e5304UL, 0x81ed6f61UL, 0x20e74364UL, 0xb45e1378UL, 0xde18639bUL, 0x881ca122UL, 0xb96726d1UL, 0x8049a7e8UL, 0x22b7da7bUL, 0x5e552d25UL, 0x5272d237UL, 0x79d2951cUL, 0xc60d894cUL, 0x488cb402UL, 0x1ba4fe5bUL, 0xa4b09f6bUL, 0x1ca815cfUL, 0xa20c3005UL, 0x8871df63UL, 0xb9de2fcbUL, 0x0cc6c9e9UL, 0x0beeff53UL, 0xe3214517UL, 0xb4542835UL, 0x9f63293cUL, 0xee41e729UL, 0x6e1d2d7cUL, 0x50045286UL, 0x1e6685f3UL, 0xf33401c6UL, 0x30a22c95UL, 0x31a70850UL, 0x60930f13UL, 0x73f98417UL, 0xa1269859UL, 0xec645c44UL, 0x52c877a9UL, 0xcdff33a6UL, 0xa02b1741UL, 0x7cbad9a2UL, 0x2180036fUL, 0x50d99c08UL, 0xcb3f4861UL, 0xc26bd765UL, 0x64a3f6abUL, 0x80342676UL, 0x25a75e7bUL, 0xe4e6d1fcUL, 0x20c710e6UL, 0xcdf0b680UL, 0x17844d3bUL, 0x31eef84dUL, 0x7e0824e4UL, 0x2ccb49ebUL, 0x846a3baeUL, 0x8ff77888UL, 0xee5d60f6UL, 0x7af75673UL, 0x2fdd5cdbUL, 0xa11631c1UL, 0x30f66f43UL, 0xb3faec54UL, 0x157fd7faUL, 0xef8579ccUL, 0xd152de58UL, 0xdb2ffd5eUL, 0x8f32ce19UL, 0x306af97aUL, 0x02f03ef8UL, 0x99319ad5UL, 0xc242fa0fUL, 0xa7e3ebb0UL, 0xc68e4906UL, 0xb8da230cUL, 0x80823028UL, 0xdcdef3c8UL, 0xd35fb171UL, 0x088a1bc8UL, 0xbec0c560UL, 0x61a3c9e8UL, 0xbca8f54dUL, 0xc72feffaUL, 0x22822e99UL, 0x82c570b4UL, 0xd8d94e89UL, 0x8b1c34bcUL, 0x301e16e6UL, 0x273be979UL, 0xb0ffeaa6UL, 0x61d9b8c6UL, 0x00b24869UL, 0xb7ffce3fUL, 0x08dc283bUL, 0x43daf65aUL, 0xf7e19798UL, 0x7619b72fUL, 0x8f1c9ba4UL, 0xdc8637a0UL, 0x16a7d3b1UL, 0x9fc393b7UL, 0xa7136eebUL, 0xc6bcc63eUL, 0x1a513742UL, 0xef6828bcUL, 0x520365d6UL, 0x2d6a77abUL, 0x3527ed4bUL, 0x821fd216UL, 0x095c6e2eUL, 0xdb92f2fbUL, 0x5eea29cbUL, 0x145892f5UL, 0x91584f7fUL, 0x5483697bUL, 0x2667a8ccUL, 0x85196048UL, 0x8c4baceaUL, 0x833860d4UL, 0x0d23e0f9UL, 0x6c387e8aUL, 0x0ae6d249UL, 0xb284600cUL, 0xd835731dUL, 0xdcb1c647UL, 0xac4c56eaUL, 0x3ebd81b3UL, 0x230eabb0UL, 0x6438bc87UL, 0xf0b5b1faUL, 0x8f5ea2b3UL, 0xfc184642UL, 0x0a036b7aUL, 0x4fb089bdUL, 0x649da589UL, 0xa345415eUL, 0x5c038323UL, 0x3e5d3bb9UL, 0x43d79572UL, 0x7e6dd07cUL, 0x06dfdf1eUL, 0x6c6cc4efUL, 0x7160a539UL, 0x73bfbe70UL, 0x83877605UL, 0x4523ecf1UL}; static const ulong32 S3[256] = { 0x8defc240UL, 0x25fa5d9fUL, 0xeb903dbfUL, 0xe810c907UL, 0x47607fffUL, 0x369fe44bUL, 0x8c1fc644UL, 0xaececa90UL, 0xbeb1f9bfUL, 0xeefbcaeaUL, 0xe8cf1950UL, 0x51df07aeUL, 0x920e8806UL, 0xf0ad0548UL, 0xe13c8d83UL, 0x927010d5UL, 0x11107d9fUL, 0x07647db9UL, 0xb2e3e4d4UL, 0x3d4f285eUL, 0xb9afa820UL, 0xfade82e0UL, 0xa067268bUL, 0x8272792eUL, 0x553fb2c0UL, 0x489ae22bUL, 0xd4ef9794UL, 0x125e3fbcUL, 0x21fffceeUL, 0x825b1bfdUL, 0x9255c5edUL, 0x1257a240UL, 0x4e1a8302UL, 0xbae07fffUL, 0x528246e7UL, 0x8e57140eUL, 0x3373f7bfUL, 0x8c9f8188UL, 0xa6fc4ee8UL, 0xc982b5a5UL, 0xa8c01db7UL, 0x579fc264UL, 0x67094f31UL, 0xf2bd3f5fUL, 0x40fff7c1UL, 0x1fb78dfcUL, 0x8e6bd2c1UL, 0x437be59bUL, 0x99b03dbfUL, 0xb5dbc64bUL, 0x638dc0e6UL, 0x55819d99UL, 0xa197c81cUL, 0x4a012d6eUL, 0xc5884a28UL, 0xccc36f71UL, 0xb843c213UL, 0x6c0743f1UL, 0x8309893cUL, 0x0feddd5fUL, 0x2f7fe850UL, 0xd7c07f7eUL, 0x02507fbfUL, 0x5afb9a04UL, 0xa747d2d0UL, 0x1651192eUL, 0xaf70bf3eUL, 0x58c31380UL, 0x5f98302eUL, 0x727cc3c4UL, 0x0a0fb402UL, 0x0f7fef82UL, 0x8c96fdadUL, 0x5d2c2aaeUL, 0x8ee99a49UL, 0x50da88b8UL, 0x8427f4a0UL, 0x1eac5790UL, 0x796fb449UL, 0x8252dc15UL, 0xefbd7d9bUL, 0xa672597dUL, 0xada840d8UL, 0x45f54504UL, 0xfa5d7403UL, 0xe83ec305UL, 0x4f91751aUL, 0x925669c2UL, 0x23efe941UL, 0xa903f12eUL, 0x60270df2UL, 0x0276e4b6UL, 0x94fd6574UL, 0x927985b2UL, 0x8276dbcbUL, 0x02778176UL, 0xf8af918dUL, 0x4e48f79eUL, 0x8f616ddfUL, 0xe29d840eUL, 0x842f7d83UL, 0x340ce5c8UL, 0x96bbb682UL, 0x93b4b148UL, 0xef303cabUL, 0x984faf28UL, 0x779faf9bUL, 0x92dc560dUL, 0x224d1e20UL, 0x8437aa88UL, 0x7d29dc96UL, 0x2756d3dcUL, 0x8b907ceeUL, 0xb51fd240UL, 0xe7c07ce3UL, 0xe566b4a1UL, 0xc3e9615eUL, 0x3cf8209dUL, 0x6094d1e3UL, 0xcd9ca341UL, 0x5c76460eUL, 0x00ea983bUL, 0xd4d67881UL, 0xfd47572cUL, 0xf76cedd9UL, 0xbda8229cUL, 0x127dadaaUL, 0x438a074eUL, 0x1f97c090UL, 0x081bdb8aUL, 0x93a07ebeUL, 0xb938ca15UL, 0x97b03cffUL, 0x3dc2c0f8UL, 0x8d1ab2ecUL, 0x64380e51UL, 0x68cc7bfbUL, 0xd90f2788UL, 0x12490181UL, 0x5de5ffd4UL, 0xdd7ef86aUL, 0x76a2e214UL, 0xb9a40368UL, 0x925d958fUL, 0x4b39fffaUL, 0xba39aee9UL, 0xa4ffd30bUL, 0xfaf7933bUL, 0x6d498623UL, 0x193cbcfaUL, 0x27627545UL, 0x825cf47aUL, 0x61bd8ba0UL, 0xd11e42d1UL, 0xcead04f4UL, 0x127ea392UL, 0x10428db7UL, 0x8272a972UL, 0x9270c4a8UL, 0x127de50bUL, 0x285ba1c8UL, 0x3c62f44fUL, 0x35c0eaa5UL, 0xe805d231UL, 0x428929fbUL, 0xb4fcdf82UL, 0x4fb66a53UL, 0x0e7dc15bUL, 0x1f081fabUL, 0x108618aeUL, 0xfcfd086dUL, 0xf9ff2889UL, 0x694bcc11UL, 0x236a5caeUL, 0x12deca4dUL, 0x2c3f8cc5UL, 0xd2d02dfeUL, 0xf8ef5896UL, 0xe4cf52daUL, 0x95155b67UL, 0x494a488cUL, 0xb9b6a80cUL, 0x5c8f82bcUL, 0x89d36b45UL, 0x3a609437UL, 0xec00c9a9UL, 0x44715253UL, 0x0a874b49UL, 0xd773bc40UL, 0x7c34671cUL, 0x02717ef6UL, 0x4feb5536UL, 0xa2d02fffUL, 0xd2bf60c4UL, 0xd43f03c0UL, 0x50b4ef6dUL, 0x07478cd1UL, 0x006e1888UL, 0xa2e53f55UL, 0xb9e6d4bcUL, 0xa2048016UL, 0x97573833UL, 0xd7207d67UL, 0xde0f8f3dUL, 0x72f87b33UL, 0xabcc4f33UL, 0x7688c55dUL, 0x7b00a6b0UL, 0x947b0001UL, 0x570075d2UL, 0xf9bb88f8UL, 0x8942019eUL, 0x4264a5ffUL, 0x856302e0UL, 0x72dbd92bUL, 0xee971b69UL, 0x6ea22fdeUL, 0x5f08ae2bUL, 0xaf7a616dUL, 0xe5c98767UL, 0xcf1febd2UL, 0x61efc8c2UL, 0xf1ac2571UL, 0xcc8239c2UL, 0x67214cb8UL, 0xb1e583d1UL, 0xb7dc3e62UL, 0x7f10bdceUL, 0xf90a5c38UL, 0x0ff0443dUL, 0x606e6dc6UL, 0x60543a49UL, 0x5727c148UL, 0x2be98a1dUL, 0x8ab41738UL, 0x20e1be24UL, 0xaf96da0fUL, 0x68458425UL, 0x99833be5UL, 0x600d457dUL, 0x282f9350UL, 0x8334b362UL, 0xd91d1120UL, 0x2b6d8da0UL, 0x642b1e31UL, 0x9c305a00UL, 0x52bce688UL, 0x1b03588aUL, 0xf7baefd5UL, 0x4142ed9cUL, 0xa4315c11UL, 0x83323ec5UL, 0xdfef4636UL, 0xa133c501UL, 0xe9d3531cUL, 0xee353783UL}; static const ulong32 S4[256] = { 0x9db30420UL, 0x1fb6e9deUL, 0xa7be7befUL, 0xd273a298UL, 0x4a4f7bdbUL, 0x64ad8c57UL, 0x85510443UL, 0xfa020ed1UL, 0x7e287affUL, 0xe60fb663UL, 0x095f35a1UL, 0x79ebf120UL, 0xfd059d43UL, 0x6497b7b1UL, 0xf3641f63UL, 0x241e4adfUL, 0x28147f5fUL, 0x4fa2b8cdUL, 0xc9430040UL, 0x0cc32220UL, 0xfdd30b30UL, 0xc0a5374fUL, 0x1d2d00d9UL, 0x24147b15UL, 0xee4d111aUL, 0x0fca5167UL, 0x71ff904cUL, 0x2d195ffeUL, 0x1a05645fUL, 0x0c13fefeUL, 0x081b08caUL, 0x05170121UL, 0x80530100UL, 0xe83e5efeUL, 0xac9af4f8UL, 0x7fe72701UL, 0xd2b8ee5fUL, 0x06df4261UL, 0xbb9e9b8aUL, 0x7293ea25UL, 0xce84ffdfUL, 0xf5718801UL, 0x3dd64b04UL, 0xa26f263bUL, 0x7ed48400UL, 0x547eebe6UL, 0x446d4ca0UL, 0x6cf3d6f5UL, 0x2649abdfUL, 0xaea0c7f5UL, 0x36338cc1UL, 0x503f7e93UL, 0xd3772061UL, 0x11b638e1UL, 0x72500e03UL, 0xf80eb2bbUL, 0xabe0502eUL, 0xec8d77deUL, 0x57971e81UL, 0xe14f6746UL, 0xc9335400UL, 0x6920318fUL, 0x081dbb99UL, 0xffc304a5UL, 0x4d351805UL, 0x7f3d5ce3UL, 0xa6c866c6UL, 0x5d5bcca9UL, 0xdaec6feaUL, 0x9f926f91UL, 0x9f46222fUL, 0x3991467dUL, 0xa5bf6d8eUL, 0x1143c44fUL, 0x43958302UL, 0xd0214eebUL, 0x022083b8UL, 0x3fb6180cUL, 0x18f8931eUL, 0x281658e6UL, 0x26486e3eUL, 0x8bd78a70UL, 0x7477e4c1UL, 0xb506e07cUL, 0xf32d0a25UL, 0x79098b02UL, 0xe4eabb81UL, 0x28123b23UL, 0x69dead38UL, 0x1574ca16UL, 0xdf871b62UL, 0x211c40b7UL, 0xa51a9ef9UL, 0x0014377bUL, 0x041e8ac8UL, 0x09114003UL, 0xbd59e4d2UL, 0xe3d156d5UL, 0x4fe876d5UL, 0x2f91a340UL, 0x557be8deUL, 0x00eae4a7UL, 0x0ce5c2ecUL, 0x4db4bba6UL, 0xe756bdffUL, 0xdd3369acUL, 0xec17b035UL, 0x06572327UL, 0x99afc8b0UL, 0x56c8c391UL, 0x6b65811cUL, 0x5e146119UL, 0x6e85cb75UL, 0xbe07c002UL, 0xc2325577UL, 0x893ff4ecUL, 0x5bbfc92dUL, 0xd0ec3b25UL, 0xb7801ab7UL, 0x8d6d3b24UL, 0x20c763efUL, 0xc366a5fcUL, 0x9c382880UL, 0x0ace3205UL, 0xaac9548aUL, 0xeca1d7c7UL, 0x041afa32UL, 0x1d16625aUL, 0x6701902cUL, 0x9b757a54UL, 0x31d477f7UL, 0x9126b031UL, 0x36cc6fdbUL, 0xc70b8b46UL, 0xd9e66a48UL, 0x56e55a79UL, 0x026a4cebUL, 0x52437effUL, 0x2f8f76b4UL, 0x0df980a5UL, 0x8674cde3UL, 0xedda04ebUL, 0x17a9be04UL, 0x2c18f4dfUL, 0xb7747f9dUL, 0xab2af7b4UL, 0xefc34d20UL, 0x2e096b7cUL, 0x1741a254UL, 0xe5b6a035UL, 0x213d42f6UL, 0x2c1c7c26UL, 0x61c2f50fUL, 0x6552daf9UL, 0xd2c231f8UL, 0x25130f69UL, 0xd8167fa2UL, 0x0418f2c8UL, 0x001a96a6UL, 0x0d1526abUL, 0x63315c21UL, 0x5e0a72ecUL, 0x49bafefdUL, 0x187908d9UL, 0x8d0dbd86UL, 0x311170a7UL, 0x3e9b640cUL, 0xcc3e10d7UL, 0xd5cad3b6UL, 0x0caec388UL, 0xf73001e1UL, 0x6c728affUL, 0x71eae2a1UL, 0x1f9af36eUL, 0xcfcbd12fUL, 0xc1de8417UL, 0xac07be6bUL, 0xcb44a1d8UL, 0x8b9b0f56UL, 0x013988c3UL, 0xb1c52fcaUL, 0xb4be31cdUL, 0xd8782806UL, 0x12a3a4e2UL, 0x6f7de532UL, 0x58fd7eb6UL, 0xd01ee900UL, 0x24adffc2UL, 0xf4990fc5UL, 0x9711aac5UL, 0x001d7b95UL, 0x82e5e7d2UL, 0x109873f6UL, 0x00613096UL, 0xc32d9521UL, 0xada121ffUL, 0x29908415UL, 0x7fbb977fUL, 0xaf9eb3dbUL, 0x29c9ed2aUL, 0x5ce2a465UL, 0xa730f32cUL, 0xd0aa3fe8UL, 0x8a5cc091UL, 0xd49e2ce7UL, 0x0ce454a9UL, 0xd60acd86UL, 0x015f1919UL, 0x77079103UL, 0xdea03af6UL, 0x78a8565eUL, 0xdee356dfUL, 0x21f05cbeUL, 0x8b75e387UL, 0xb3c50651UL, 0xb8a5c3efUL, 0xd8eeb6d2UL, 0xe523be77UL, 0xc2154529UL, 0x2f69efdfUL, 0xafe67afbUL, 0xf470c4b2UL, 0xf3e0eb5bUL, 0xd6cc9876UL, 0x39e4460cUL, 0x1fda8538UL, 0x1987832fUL, 0xca007367UL, 0xa99144f8UL, 0x296b299eUL, 0x492fc295UL, 0x9266beabUL, 0xb5676e69UL, 0x9bd3dddaUL, 0xdf7e052fUL, 0xdb25701cUL, 0x1b5e51eeUL, 0xf65324e6UL, 0x6afce36cUL, 0x0316cc04UL, 0x8644213eUL, 0xb7dc59d0UL, 0x7965291fUL, 0xccd6fd43UL, 0x41823979UL, 0x932bcdf6UL, 0xb657c34dUL, 0x4edfd282UL, 0x7ae5290cUL, 0x3cb9536bUL, 0x851e20feUL, 0x9833557eUL, 0x13ecf0b0UL, 0xd3ffb372UL, 0x3f85c5c1UL, 0x0aef7ed2UL}; static const ulong32 S5[256] = { 0x7ec90c04UL, 0x2c6e74b9UL, 0x9b0e66dfUL, 0xa6337911UL, 0xb86a7fffUL, 0x1dd358f5UL, 0x44dd9d44UL, 0x1731167fUL, 0x08fbf1faUL, 0xe7f511ccUL, 0xd2051b00UL, 0x735aba00UL, 0x2ab722d8UL, 0x386381cbUL, 0xacf6243aUL, 0x69befd7aUL, 0xe6a2e77fUL, 0xf0c720cdUL, 0xc4494816UL, 0xccf5c180UL, 0x38851640UL, 0x15b0a848UL, 0xe68b18cbUL, 0x4caadeffUL, 0x5f480a01UL, 0x0412b2aaUL, 0x259814fcUL, 0x41d0efe2UL, 0x4e40b48dUL, 0x248eb6fbUL, 0x8dba1cfeUL, 0x41a99b02UL, 0x1a550a04UL, 0xba8f65cbUL, 0x7251f4e7UL, 0x95a51725UL, 0xc106ecd7UL, 0x97a5980aUL, 0xc539b9aaUL, 0x4d79fe6aUL, 0xf2f3f763UL, 0x68af8040UL, 0xed0c9e56UL, 0x11b4958bUL, 0xe1eb5a88UL, 0x8709e6b0UL, 0xd7e07156UL, 0x4e29fea7UL, 0x6366e52dUL, 0x02d1c000UL, 0xc4ac8e05UL, 0x9377f571UL, 0x0c05372aUL, 0x578535f2UL, 0x2261be02UL, 0xd642a0c9UL, 0xdf13a280UL, 0x74b55bd2UL, 0x682199c0UL, 0xd421e5ecUL, 0x53fb3ce8UL, 0xc8adedb3UL, 0x28a87fc9UL, 0x3d959981UL, 0x5c1ff900UL, 0xfe38d399UL, 0x0c4eff0bUL, 0x062407eaUL, 0xaa2f4fb1UL, 0x4fb96976UL, 0x90c79505UL, 0xb0a8a774UL, 0xef55a1ffUL, 0xe59ca2c2UL, 0xa6b62d27UL, 0xe66a4263UL, 0xdf65001fUL, 0x0ec50966UL, 0xdfdd55bcUL, 0x29de0655UL, 0x911e739aUL, 0x17af8975UL, 0x32c7911cUL, 0x89f89468UL, 0x0d01e980UL, 0x524755f4UL, 0x03b63cc9UL, 0x0cc844b2UL, 0xbcf3f0aaUL, 0x87ac36e9UL, 0xe53a7426UL, 0x01b3d82bUL, 0x1a9e7449UL, 0x64ee2d7eUL, 0xcddbb1daUL, 0x01c94910UL, 0xb868bf80UL, 0x0d26f3fdUL, 0x9342ede7UL, 0x04a5c284UL, 0x636737b6UL, 0x50f5b616UL, 0xf24766e3UL, 0x8eca36c1UL, 0x136e05dbUL, 0xfef18391UL, 0xfb887a37UL, 0xd6e7f7d4UL, 0xc7fb7dc9UL, 0x3063fcdfUL, 0xb6f589deUL, 0xec2941daUL, 0x26e46695UL, 0xb7566419UL, 0xf654efc5UL, 0xd08d58b7UL, 0x48925401UL, 0xc1bacb7fUL, 0xe5ff550fUL, 0xb6083049UL, 0x5bb5d0e8UL, 0x87d72e5aUL, 0xab6a6ee1UL, 0x223a66ceUL, 0xc62bf3cdUL, 0x9e0885f9UL, 0x68cb3e47UL, 0x086c010fUL, 0xa21de820UL, 0xd18b69deUL, 0xf3f65777UL, 0xfa02c3f6UL, 0x407edac3UL, 0xcbb3d550UL, 0x1793084dUL, 0xb0d70ebaUL, 0x0ab378d5UL, 0xd951fb0cUL, 0xded7da56UL, 0x4124bbe4UL, 0x94ca0b56UL, 0x0f5755d1UL, 0xe0e1e56eUL, 0x6184b5beUL, 0x580a249fUL, 0x94f74bc0UL, 0xe327888eUL, 0x9f7b5561UL, 0xc3dc0280UL, 0x05687715UL, 0x646c6bd7UL, 0x44904db3UL, 0x66b4f0a3UL, 0xc0f1648aUL, 0x697ed5afUL, 0x49e92ff6UL, 0x309e374fUL, 0x2cb6356aUL, 0x85808573UL, 0x4991f840UL, 0x76f0ae02UL, 0x083be84dUL, 0x28421c9aUL, 0x44489406UL, 0x736e4cb8UL, 0xc1092910UL, 0x8bc95fc6UL, 0x7d869cf4UL, 0x134f616fUL, 0x2e77118dUL, 0xb31b2be1UL, 0xaa90b472UL, 0x3ca5d717UL, 0x7d161bbaUL, 0x9cad9010UL, 0xaf462ba2UL, 0x9fe459d2UL, 0x45d34559UL, 0xd9f2da13UL, 0xdbc65487UL, 0xf3e4f94eUL, 0x176d486fUL, 0x097c13eaUL, 0x631da5c7UL, 0x445f7382UL, 0x175683f4UL, 0xcdc66a97UL, 0x70be0288UL, 0xb3cdcf72UL, 0x6e5dd2f3UL, 0x20936079UL, 0x459b80a5UL, 0xbe60e2dbUL, 0xa9c23101UL, 0xeba5315cUL, 0x224e42f2UL, 0x1c5c1572UL, 0xf6721b2cUL, 0x1ad2fff3UL, 0x8c25404eUL, 0x324ed72fUL, 0x4067b7fdUL, 0x0523138eUL, 0x5ca3bc78UL, 0xdc0fd66eUL, 0x75922283UL, 0x784d6b17UL, 0x58ebb16eUL, 0x44094f85UL, 0x3f481d87UL, 0xfcfeae7bUL, 0x77b5ff76UL, 0x8c2302bfUL, 0xaaf47556UL, 0x5f46b02aUL, 0x2b092801UL, 0x3d38f5f7UL, 0x0ca81f36UL, 0x52af4a8aUL, 0x66d5e7c0UL, 0xdf3b0874UL, 0x95055110UL, 0x1b5ad7a8UL, 0xf61ed5adUL, 0x6cf6e479UL, 0x20758184UL, 0xd0cefa65UL, 0x88f7be58UL, 0x4a046826UL, 0x0ff6f8f3UL, 0xa09c7f70UL, 0x5346aba0UL, 0x5ce96c28UL, 0xe176eda3UL, 0x6bac307fUL, 0x376829d2UL, 0x85360fa9UL, 0x17e3fe2aUL, 0x24b79767UL, 0xf5a96b20UL, 0xd6cd2595UL, 0x68ff1ebfUL, 0x7555442cUL, 0xf19f06beUL, 0xf9e0659aUL, 0xeeb9491dUL, 0x34010718UL, 0xbb30cab8UL, 0xe822fe15UL, 0x88570983UL, 0x750e6249UL, 0xda627e55UL, 0x5e76ffa8UL, 0xb1534546UL, 0x6d47de08UL, 0xefe9e7d4UL}; static const ulong32 S6[256] = { 0xf6fa8f9dUL, 0x2cac6ce1UL, 0x4ca34867UL, 0xe2337f7cUL, 0x95db08e7UL, 0x016843b4UL, 0xeced5cbcUL, 0x325553acUL, 0xbf9f0960UL, 0xdfa1e2edUL, 0x83f0579dUL, 0x63ed86b9UL, 0x1ab6a6b8UL, 0xde5ebe39UL, 0xf38ff732UL, 0x8989b138UL, 0x33f14961UL, 0xc01937bdUL, 0xf506c6daUL, 0xe4625e7eUL, 0xa308ea99UL, 0x4e23e33cUL, 0x79cbd7ccUL, 0x48a14367UL, 0xa3149619UL, 0xfec94bd5UL, 0xa114174aUL, 0xeaa01866UL, 0xa084db2dUL, 0x09a8486fUL, 0xa888614aUL, 0x2900af98UL, 0x01665991UL, 0xe1992863UL, 0xc8f30c60UL, 0x2e78ef3cUL, 0xd0d51932UL, 0xcf0fec14UL, 0xf7ca07d2UL, 0xd0a82072UL, 0xfd41197eUL, 0x9305a6b0UL, 0xe86be3daUL, 0x74bed3cdUL, 0x372da53cUL, 0x4c7f4448UL, 0xdab5d440UL, 0x6dba0ec3UL, 0x083919a7UL, 0x9fbaeed9UL, 0x49dbcfb0UL, 0x4e670c53UL, 0x5c3d9c01UL, 0x64bdb941UL, 0x2c0e636aUL, 0xba7dd9cdUL, 0xea6f7388UL, 0xe70bc762UL, 0x35f29adbUL, 0x5c4cdd8dUL, 0xf0d48d8cUL, 0xb88153e2UL, 0x08a19866UL, 0x1ae2eac8UL, 0x284caf89UL, 0xaa928223UL, 0x9334be53UL, 0x3b3a21bfUL, 0x16434be3UL, 0x9aea3906UL, 0xefe8c36eUL, 0xf890cdd9UL, 0x80226daeUL, 0xc340a4a3UL, 0xdf7e9c09UL, 0xa694a807UL, 0x5b7c5eccUL, 0x221db3a6UL, 0x9a69a02fUL, 0x68818a54UL, 0xceb2296fUL, 0x53c0843aUL, 0xfe893655UL, 0x25bfe68aUL, 0xb4628abcUL, 0xcf222ebfUL, 0x25ac6f48UL, 0xa9a99387UL, 0x53bddb65UL, 0xe76ffbe7UL, 0xe967fd78UL, 0x0ba93563UL, 0x8e342bc1UL, 0xe8a11be9UL, 0x4980740dUL, 0xc8087dfcUL, 0x8de4bf99UL, 0xa11101a0UL, 0x7fd37975UL, 0xda5a26c0UL, 0xe81f994fUL, 0x9528cd89UL, 0xfd339fedUL, 0xb87834bfUL, 0x5f04456dUL, 0x22258698UL, 0xc9c4c83bUL, 0x2dc156beUL, 0x4f628daaUL, 0x57f55ec5UL, 0xe2220abeUL, 0xd2916ebfUL, 0x4ec75b95UL, 0x24f2c3c0UL, 0x42d15d99UL, 0xcd0d7fa0UL, 0x7b6e27ffUL, 0xa8dc8af0UL, 0x7345c106UL, 0xf41e232fUL, 0x35162386UL, 0xe6ea8926UL, 0x3333b094UL, 0x157ec6f2UL, 0x372b74afUL, 0x692573e4UL, 0xe9a9d848UL, 0xf3160289UL, 0x3a62ef1dUL, 0xa787e238UL, 0xf3a5f676UL, 0x74364853UL, 0x20951063UL, 0x4576698dUL, 0xb6fad407UL, 0x592af950UL, 0x36f73523UL, 0x4cfb6e87UL, 0x7da4cec0UL, 0x6c152daaUL, 0xcb0396a8UL, 0xc50dfe5dUL, 0xfcd707abUL, 0x0921c42fUL, 0x89dff0bbUL, 0x5fe2be78UL, 0x448f4f33UL, 0x754613c9UL, 0x2b05d08dUL, 0x48b9d585UL, 0xdc049441UL, 0xc8098f9bUL, 0x7dede786UL, 0xc39a3373UL, 0x42410005UL, 0x6a091751UL, 0x0ef3c8a6UL, 0x890072d6UL, 0x28207682UL, 0xa9a9f7beUL, 0xbf32679dUL, 0xd45b5b75UL, 0xb353fd00UL, 0xcbb0e358UL, 0x830f220aUL, 0x1f8fb214UL, 0xd372cf08UL, 0xcc3c4a13UL, 0x8cf63166UL, 0x061c87beUL, 0x88c98f88UL, 0x6062e397UL, 0x47cf8e7aUL, 0xb6c85283UL, 0x3cc2acfbUL, 0x3fc06976UL, 0x4e8f0252UL, 0x64d8314dUL, 0xda3870e3UL, 0x1e665459UL, 0xc10908f0UL, 0x513021a5UL, 0x6c5b68b7UL, 0x822f8aa0UL, 0x3007cd3eUL, 0x74719eefUL, 0xdc872681UL, 0x073340d4UL, 0x7e432fd9UL, 0x0c5ec241UL, 0x8809286cUL, 0xf592d891UL, 0x08a930f6UL, 0x957ef305UL, 0xb7fbffbdUL, 0xc266e96fUL, 0x6fe4ac98UL, 0xb173ecc0UL, 0xbc60b42aUL, 0x953498daUL, 0xfba1ae12UL, 0x2d4bd736UL, 0x0f25faabUL, 0xa4f3fcebUL, 0xe2969123UL, 0x257f0c3dUL, 0x9348af49UL, 0x361400bcUL, 0xe8816f4aUL, 0x3814f200UL, 0xa3f94043UL, 0x9c7a54c2UL, 0xbc704f57UL, 0xda41e7f9UL, 0xc25ad33aUL, 0x54f4a084UL, 0xb17f5505UL, 0x59357cbeUL, 0xedbd15c8UL, 0x7f97c5abUL, 0xba5ac7b5UL, 0xb6f6deafUL, 0x3a479c3aUL, 0x5302da25UL, 0x653d7e6aUL, 0x54268d49UL, 0x51a477eaUL, 0x5017d55bUL, 0xd7d25d88UL, 0x44136c76UL, 0x0404a8c8UL, 0xb8e5a121UL, 0xb81a928aUL, 0x60ed5869UL, 0x97c55b96UL, 0xeaec991bUL, 0x29935913UL, 0x01fdb7f1UL, 0x088e8dfaUL, 0x9ab6f6f5UL, 0x3b4cbf9fUL, 0x4a5de3abUL, 0xe6051d35UL, 0xa0e1d855UL, 0xd36b4cf1UL, 0xf544edebUL, 0xb0e93524UL, 0xbebb8fbdUL, 0xa2d762cfUL, 0x49c92f54UL, 0x38b5f331UL, 0x7128a454UL, 0x48392905UL, 0xa65b1db8UL, 0x851c97bdUL, 0xd675cf2fUL}; static const ulong32 S7[256] = { 0x85e04019UL, 0x332bf567UL, 0x662dbfffUL, 0xcfc65693UL, 0x2a8d7f6fUL, 0xab9bc912UL, 0xde6008a1UL, 0x2028da1fUL, 0x0227bce7UL, 0x4d642916UL, 0x18fac300UL, 0x50f18b82UL, 0x2cb2cb11UL, 0xb232e75cUL, 0x4b3695f2UL, 0xb28707deUL, 0xa05fbcf6UL, 0xcd4181e9UL, 0xe150210cUL, 0xe24ef1bdUL, 0xb168c381UL, 0xfde4e789UL, 0x5c79b0d8UL, 0x1e8bfd43UL, 0x4d495001UL, 0x38be4341UL, 0x913cee1dUL, 0x92a79c3fUL, 0x089766beUL, 0xbaeeadf4UL, 0x1286becfUL, 0xb6eacb19UL, 0x2660c200UL, 0x7565bde4UL, 0x64241f7aUL, 0x8248dca9UL, 0xc3b3ad66UL, 0x28136086UL, 0x0bd8dfa8UL, 0x356d1cf2UL, 0x107789beUL, 0xb3b2e9ceUL, 0x0502aa8fUL, 0x0bc0351eUL, 0x166bf52aUL, 0xeb12ff82UL, 0xe3486911UL, 0xd34d7516UL, 0x4e7b3affUL, 0x5f43671bUL, 0x9cf6e037UL, 0x4981ac83UL, 0x334266ceUL, 0x8c9341b7UL, 0xd0d854c0UL, 0xcb3a6c88UL, 0x47bc2829UL, 0x4725ba37UL, 0xa66ad22bUL, 0x7ad61f1eUL, 0x0c5cbafaUL, 0x4437f107UL, 0xb6e79962UL, 0x42d2d816UL, 0x0a961288UL, 0xe1a5c06eUL, 0x13749e67UL, 0x72fc081aUL, 0xb1d139f7UL, 0xf9583745UL, 0xcf19df58UL, 0xbec3f756UL, 0xc06eba30UL, 0x07211b24UL, 0x45c28829UL, 0xc95e317fUL, 0xbc8ec511UL, 0x38bc46e9UL, 0xc6e6fa14UL, 0xbae8584aUL, 0xad4ebc46UL, 0x468f508bUL, 0x7829435fUL, 0xf124183bUL, 0x821dba9fUL, 0xaff60ff4UL, 0xea2c4e6dUL, 0x16e39264UL, 0x92544a8bUL, 0x009b4fc3UL, 0xaba68cedUL, 0x9ac96f78UL, 0x06a5b79aUL, 0xb2856e6eUL, 0x1aec3ca9UL, 0xbe838688UL, 0x0e0804e9UL, 0x55f1be56UL, 0xe7e5363bUL, 0xb3a1f25dUL, 0xf7debb85UL, 0x61fe033cUL, 0x16746233UL, 0x3c034c28UL, 0xda6d0c74UL, 0x79aac56cUL, 0x3ce4e1adUL, 0x51f0c802UL, 0x98f8f35aUL, 0x1626a49fUL, 0xeed82b29UL, 0x1d382fe3UL, 0x0c4fb99aUL, 0xbb325778UL, 0x3ec6d97bUL, 0x6e77a6a9UL, 0xcb658b5cUL, 0xd45230c7UL, 0x2bd1408bUL, 0x60c03eb7UL, 0xb9068d78UL, 0xa33754f4UL, 0xf430c87dUL, 0xc8a71302UL, 0xb96d8c32UL, 0xebd4e7beUL, 0xbe8b9d2dUL, 0x7979fb06UL, 0xe7225308UL, 0x8b75cf77UL, 0x11ef8da4UL, 0xe083c858UL, 0x8d6b786fUL, 0x5a6317a6UL, 0xfa5cf7a0UL, 0x5dda0033UL, 0xf28ebfb0UL, 0xf5b9c310UL, 0xa0eac280UL, 0x08b9767aUL, 0xa3d9d2b0UL, 0x79d34217UL, 0x021a718dUL, 0x9ac6336aUL, 0x2711fd60UL, 0x438050e3UL, 0x069908a8UL, 0x3d7fedc4UL, 0x826d2befUL, 0x4eeb8476UL, 0x488dcf25UL, 0x36c9d566UL, 0x28e74e41UL, 0xc2610acaUL, 0x3d49a9cfUL, 0xbae3b9dfUL, 0xb65f8de6UL, 0x92aeaf64UL, 0x3ac7d5e6UL, 0x9ea80509UL, 0xf22b017dUL, 0xa4173f70UL, 0xdd1e16c3UL, 0x15e0d7f9UL, 0x50b1b887UL, 0x2b9f4fd5UL, 0x625aba82UL, 0x6a017962UL, 0x2ec01b9cUL, 0x15488aa9UL, 0xd716e740UL, 0x40055a2cUL, 0x93d29a22UL, 0xe32dbf9aUL, 0x058745b9UL, 0x3453dc1eUL, 0xd699296eUL, 0x496cff6fUL, 0x1c9f4986UL, 0xdfe2ed07UL, 0xb87242d1UL, 0x19de7eaeUL, 0x053e561aUL, 0x15ad6f8cUL, 0x66626c1cUL, 0x7154c24cUL, 0xea082b2aUL, 0x93eb2939UL, 0x17dcb0f0UL, 0x58d4f2aeUL, 0x9ea294fbUL, 0x52cf564cUL, 0x9883fe66UL, 0x2ec40581UL, 0x763953c3UL, 0x01d6692eUL, 0xd3a0c108UL, 0xa1e7160eUL, 0xe4f2dfa6UL, 0x693ed285UL, 0x74904698UL, 0x4c2b0eddUL, 0x4f757656UL, 0x5d393378UL, 0xa132234fUL, 0x3d321c5dUL, 0xc3f5e194UL, 0x4b269301UL, 0xc79f022fUL, 0x3c997e7eUL, 0x5e4f9504UL, 0x3ffafbbdUL, 0x76f7ad0eUL, 0x296693f4UL, 0x3d1fce6fUL, 0xc61e45beUL, 0xd3b5ab34UL, 0xf72bf9b7UL, 0x1b0434c0UL, 0x4e72b567UL, 0x5592a33dUL, 0xb5229301UL, 0xcfd2a87fUL, 0x60aeb767UL, 0x1814386bUL, 0x30bcc33dUL, 0x38a0c07dUL, 0xfd1606f2UL, 0xc363519bUL, 0x589dd390UL, 0x5479f8e6UL, 0x1cb8d647UL, 0x97fd61a9UL, 0xea7759f4UL, 0x2d57539dUL, 0x569a58cfUL, 0xe84e63adUL, 0x462e1b78UL, 0x6580f87eUL, 0xf3817914UL, 0x91da55f4UL, 0x40a230f3UL, 0xd1988f35UL, 0xb6e318d2UL, 0x3ffa50bcUL, 0x3d40f021UL, 0xc3c0bdaeUL, 0x4958c24cUL, 0x518f36b2UL, 0x84b1d370UL, 0x0fedce83UL, 0x878ddadaUL, 0xf2a279c7UL, 0x94e01be8UL, 0x90716f4bUL, 0x954b8aa3UL}; static const ulong32 S8[256] = { 0xe216300dUL, 0xbbddfffcUL, 0xa7ebdabdUL, 0x35648095UL, 0x7789f8b7UL, 0xe6c1121bUL, 0x0e241600UL, 0x052ce8b5UL, 0x11a9cfb0UL, 0xe5952f11UL, 0xece7990aUL, 0x9386d174UL, 0x2a42931cUL, 0x76e38111UL, 0xb12def3aUL, 0x37ddddfcUL, 0xde9adeb1UL, 0x0a0cc32cUL, 0xbe197029UL, 0x84a00940UL, 0xbb243a0fUL, 0xb4d137cfUL, 0xb44e79f0UL, 0x049eedfdUL, 0x0b15a15dUL, 0x480d3168UL, 0x8bbbde5aUL, 0x669ded42UL, 0xc7ece831UL, 0x3f8f95e7UL, 0x72df191bUL, 0x7580330dUL, 0x94074251UL, 0x5c7dcdfaUL, 0xabbe6d63UL, 0xaa402164UL, 0xb301d40aUL, 0x02e7d1caUL, 0x53571daeUL, 0x7a3182a2UL, 0x12a8ddecUL, 0xfdaa335dUL, 0x176f43e8UL, 0x71fb46d4UL, 0x38129022UL, 0xce949ad4UL, 0xb84769adUL, 0x965bd862UL, 0x82f3d055UL, 0x66fb9767UL, 0x15b80b4eUL, 0x1d5b47a0UL, 0x4cfde06fUL, 0xc28ec4b8UL, 0x57e8726eUL, 0x647a78fcUL, 0x99865d44UL, 0x608bd593UL, 0x6c200e03UL, 0x39dc5ff6UL, 0x5d0b00a3UL, 0xae63aff2UL, 0x7e8bd632UL, 0x70108c0cUL, 0xbbd35049UL, 0x2998df04UL, 0x980cf42aUL, 0x9b6df491UL, 0x9e7edd53UL, 0x06918548UL, 0x58cb7e07UL, 0x3b74ef2eUL, 0x522fffb1UL, 0xd24708ccUL, 0x1c7e27cdUL, 0xa4eb215bUL, 0x3cf1d2e2UL, 0x19b47a38UL, 0x424f7618UL, 0x35856039UL, 0x9d17dee7UL, 0x27eb35e6UL, 0xc9aff67bUL, 0x36baf5b8UL, 0x09c467cdUL, 0xc18910b1UL, 0xe11dbf7bUL, 0x06cd1af8UL, 0x7170c608UL, 0x2d5e3354UL, 0xd4de495aUL, 0x64c6d006UL, 0xbcc0c62cUL, 0x3dd00db3UL, 0x708f8f34UL, 0x77d51b42UL, 0x264f620fUL, 0x24b8d2bfUL, 0x15c1b79eUL, 0x46a52564UL, 0xf8d7e54eUL, 0x3e378160UL, 0x7895cda5UL, 0x859c15a5UL, 0xe6459788UL, 0xc37bc75fUL, 0xdb07ba0cUL, 0x0676a3abUL, 0x7f229b1eUL, 0x31842e7bUL, 0x24259fd7UL, 0xf8bef472UL, 0x835ffcb8UL, 0x6df4c1f2UL, 0x96f5b195UL, 0xfd0af0fcUL, 0xb0fe134cUL, 0xe2506d3dUL, 0x4f9b12eaUL, 0xf215f225UL, 0xa223736fUL, 0x9fb4c428UL, 0x25d04979UL, 0x34c713f8UL, 0xc4618187UL, 0xea7a6e98UL, 0x7cd16efcUL, 0x1436876cUL, 0xf1544107UL, 0xbedeee14UL, 0x56e9af27UL, 0xa04aa441UL, 0x3cf7c899UL, 0x92ecbae6UL, 0xdd67016dUL, 0x151682ebUL, 0xa842eedfUL, 0xfdba60b4UL, 0xf1907b75UL, 0x20e3030fUL, 0x24d8c29eUL, 0xe139673bUL, 0xefa63fb8UL, 0x71873054UL, 0xb6f2cf3bUL, 0x9f326442UL, 0xcb15a4ccUL, 0xb01a4504UL, 0xf1e47d8dUL, 0x844a1be5UL, 0xbae7dfdcUL, 0x42cbda70UL, 0xcd7dae0aUL, 0x57e85b7aUL, 0xd53f5af6UL, 0x20cf4d8cUL, 0xcea4d428UL, 0x79d130a4UL, 0x3486ebfbUL, 0x33d3cddcUL, 0x77853b53UL, 0x37effcb5UL, 0xc5068778UL, 0xe580b3e6UL, 0x4e68b8f4UL, 0xc5c8b37eUL, 0x0d809ea2UL, 0x398feb7cUL, 0x132a4f94UL, 0x43b7950eUL, 0x2fee7d1cUL, 0x223613bdUL, 0xdd06caa2UL, 0x37df932bUL, 0xc4248289UL, 0xacf3ebc3UL, 0x5715f6b7UL, 0xef3478ddUL, 0xf267616fUL, 0xc148cbe4UL, 0x9052815eUL, 0x5e410fabUL, 0xb48a2465UL, 0x2eda7fa4UL, 0xe87b40e4UL, 0xe98ea084UL, 0x5889e9e1UL, 0xefd390fcUL, 0xdd07d35bUL, 0xdb485694UL, 0x38d7e5b2UL, 0x57720101UL, 0x730edebcUL, 0x5b643113UL, 0x94917e4fUL, 0x503c2fbaUL, 0x646f1282UL, 0x7523d24aUL, 0xe0779695UL, 0xf9c17a8fUL, 0x7a5b2121UL, 0xd187b896UL, 0x29263a4dUL, 0xba510cdfUL, 0x81f47c9fUL, 0xad1163edUL, 0xea7b5965UL, 0x1a00726eUL, 0x11403092UL, 0x00da6d77UL, 0x4a0cdd61UL, 0xad1f4603UL, 0x605bdfb0UL, 0x9eedc364UL, 0x22ebe6a8UL, 0xcee7d28aUL, 0xa0e736a0UL, 0x5564a6b9UL, 0x10853209UL, 0xc7eb8f37UL, 0x2de705caUL, 0x8951570fUL, 0xdf09822bUL, 0xbd691a6cUL, 0xaa12e4f2UL, 0x87451c0fUL, 0xe0f6a27aUL, 0x3ada4819UL, 0x4cf1764fUL, 0x0d771c2bUL, 0x67cdb156UL, 0x350d8384UL, 0x5938fa0fUL, 0x42399ef3UL, 0x36997b07UL, 0x0e84093dUL, 0x4aa93e61UL, 0x8360d87bUL, 0x1fa98b0cUL, 0x1149382cUL, 0xe97625a5UL, 0x0614d1b7UL, 0x0e25244bUL, 0x0c768347UL, 0x589e8d82UL, 0x0d2059d1UL, 0xa466bb1eUL, 0xf8da0a82UL, 0x04f19130UL, 0xba6e4ec0UL, 0x99265164UL, 0x1ee7230dUL, 0x50b2ad80UL, 0xeaee6801UL, 0x8db2a283UL, 0xea8bf59eUL}; /* returns the i'th byte of a variable */ #ifdef _MSC_VER #define GB(x, i) ((unsigned char)((x[(15-i)>>2])>>(unsigned)(8*((15-i)&3)))) #else #define GB(x, i) (((x[(15-i)>>2])>>(unsigned)(8*((15-i)&3)))&255) #endif /** Initialize the LTC_CAST5 block cipher @param key The symmetric key you wish to pass @param keylen The key length in bytes @param num_rounds The number of rounds desired (0 for default) @param skey The key in as scheduled by this function. @return CRYPT_OK if successful */ #ifdef LTC_CLEAN_STACK static int _cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) #else int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) #endif { ulong32 x[4], z[4]; unsigned char buf[16]; int y, i; LTC_ARGCHK(key != NULL); LTC_ARGCHK(skey != NULL); if (num_rounds != 12 && num_rounds != 16 && num_rounds != 0) { return CRYPT_INVALID_ROUNDS; } if (num_rounds == 12 && keylen > 10) { return CRYPT_INVALID_ROUNDS; } if (keylen < 5 || keylen > 16) { return CRYPT_INVALID_KEYSIZE; } /* extend the key as required */ zeromem(buf, sizeof(buf)); XMEMCPY(buf, key, (size_t)keylen); /* load and start the awful looking network */ for (y = 0; y < 4; y++) { LOAD32H(x[3-y],buf+4*y); } for (i = y = 0; y < 2; y++) { z[3] = x[3] ^ S5[GB(x, 0xD)] ^ S6[GB(x, 0xF)] ^ S7[GB(x, 0xC)] ^ S8[GB(x, 0xE)] ^ S7[GB(x, 0x8)]; z[2] = x[1] ^ S5[GB(z, 0x0)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x3)] ^ S8[GB(x, 0xA)]; z[1] = x[0] ^ S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S5[GB(x, 0x9)]; z[0] = x[2] ^ S5[GB(z, 0xA)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0xb)] ^ S8[GB(z, 0x8)] ^ S6[GB(x, 0xB)]; skey->cast5.K[i++] = S5[GB(z, 0x8)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0x7)] ^ S8[GB(z, 0x6)] ^ S5[GB(z, 0x2)]; skey->cast5.K[i++] = S5[GB(z, 0xA)] ^ S6[GB(z, 0xB)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S6[GB(z, 0x6)]; skey->cast5.K[i++] = S5[GB(z, 0xC)] ^ S6[GB(z, 0xd)] ^ S7[GB(z, 0x3)] ^ S8[GB(z, 0x2)] ^ S7[GB(z, 0x9)]; skey->cast5.K[i++] = S5[GB(z, 0xE)] ^ S6[GB(z, 0xF)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x0)] ^ S8[GB(z, 0xc)]; x[3] = z[1] ^ S5[GB(z, 0x5)] ^ S6[GB(z, 0x7)] ^ S7[GB(z, 0x4)] ^ S8[GB(z, 0x6)] ^ S7[GB(z, 0x0)]; x[2] = z[3] ^ S5[GB(x, 0x0)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x3)] ^ S8[GB(z, 0x2)]; x[1] = z[2] ^ S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S5[GB(z, 0x1)]; x[0] = z[0] ^ S5[GB(x, 0xA)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0xb)] ^ S8[GB(x, 0x8)] ^ S6[GB(z, 0x3)]; skey->cast5.K[i++] = S5[GB(x, 0x3)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0xc)] ^ S8[GB(x, 0xd)] ^ S5[GB(x, 0x8)]; skey->cast5.K[i++] = S5[GB(x, 0x1)] ^ S6[GB(x, 0x0)] ^ S7[GB(x, 0xe)] ^ S8[GB(x, 0xf)] ^ S6[GB(x, 0xd)]; skey->cast5.K[i++] = S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x8)] ^ S8[GB(x, 0x9)] ^ S7[GB(x, 0x3)]; skey->cast5.K[i++] = S5[GB(x, 0x5)] ^ S6[GB(x, 0x4)] ^ S7[GB(x, 0xa)] ^ S8[GB(x, 0xb)] ^ S8[GB(x, 0x7)]; /* second half */ z[3] = x[3] ^ S5[GB(x, 0xD)] ^ S6[GB(x, 0xF)] ^ S7[GB(x, 0xC)] ^ S8[GB(x, 0xE)] ^ S7[GB(x, 0x8)]; z[2] = x[1] ^ S5[GB(z, 0x0)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x3)] ^ S8[GB(x, 0xA)]; z[1] = x[0] ^ S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S5[GB(x, 0x9)]; z[0] = x[2] ^ S5[GB(z, 0xA)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0xb)] ^ S8[GB(z, 0x8)] ^ S6[GB(x, 0xB)]; skey->cast5.K[i++] = S5[GB(z, 0x3)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0xc)] ^ S8[GB(z, 0xd)] ^ S5[GB(z, 0x9)]; skey->cast5.K[i++] = S5[GB(z, 0x1)] ^ S6[GB(z, 0x0)] ^ S7[GB(z, 0xe)] ^ S8[GB(z, 0xf)] ^ S6[GB(z, 0xc)]; skey->cast5.K[i++] = S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x8)] ^ S8[GB(z, 0x9)] ^ S7[GB(z, 0x2)]; skey->cast5.K[i++] = S5[GB(z, 0x5)] ^ S6[GB(z, 0x4)] ^ S7[GB(z, 0xa)] ^ S8[GB(z, 0xb)] ^ S8[GB(z, 0x6)]; x[3] = z[1] ^ S5[GB(z, 0x5)] ^ S6[GB(z, 0x7)] ^ S7[GB(z, 0x4)] ^ S8[GB(z, 0x6)] ^ S7[GB(z, 0x0)]; x[2] = z[3] ^ S5[GB(x, 0x0)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x3)] ^ S8[GB(z, 0x2)]; x[1] = z[2] ^ S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S5[GB(z, 0x1)]; x[0] = z[0] ^ S5[GB(x, 0xA)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0xb)] ^ S8[GB(x, 0x8)] ^ S6[GB(z, 0x3)]; skey->cast5.K[i++] = S5[GB(x, 0x8)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0x7)] ^ S8[GB(x, 0x6)] ^ S5[GB(x, 0x3)]; skey->cast5.K[i++] = S5[GB(x, 0xa)] ^ S6[GB(x, 0xb)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S6[GB(x, 0x7)]; skey->cast5.K[i++] = S5[GB(x, 0xc)] ^ S6[GB(x, 0xd)] ^ S7[GB(x, 0x3)] ^ S8[GB(x, 0x2)] ^ S7[GB(x, 0x8)]; skey->cast5.K[i++] = S5[GB(x, 0xe)] ^ S6[GB(x, 0xf)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x0)] ^ S8[GB(x, 0xd)]; } skey->cast5.keylen = keylen; #ifdef LTC_CLEAN_STACK zeromem(buf, sizeof(buf)); zeromem(x, sizeof(x)); zeromem(z, sizeof(z)); #endif return CRYPT_OK; } #ifdef LTC_CLEAN_STACK int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) { int z; z = _cast5_setup(key, keylen, num_rounds, skey); burn_stack(sizeof(ulong32)*8 + 16 + sizeof(int)*2); return z; } #endif #ifdef _MSC_VER #define INLINE __inline #else #define INLINE #endif INLINE static ulong32 FI(ulong32 R, ulong32 Km, ulong32 Kr) { ulong32 I; I = (Km + R); I = ROL(I, Kr); return ((S1[byte(I, 3)] ^ S2[byte(I,2)]) - S3[byte(I,1)]) + S4[byte(I,0)]; } INLINE static ulong32 FII(ulong32 R, ulong32 Km, ulong32 Kr) { ulong32 I; I = (Km ^ R); I = ROL(I, Kr); return ((S1[byte(I, 3)] - S2[byte(I,2)]) + S3[byte(I,1)]) ^ S4[byte(I,0)]; } INLINE static ulong32 FIII(ulong32 R, ulong32 Km, ulong32 Kr) { ulong32 I; I = (Km - R); I = ROL(I, Kr); return ((S1[byte(I, 3)] + S2[byte(I,2)]) ^ S3[byte(I,1)]) - S4[byte(I,0)]; } /** Encrypts a block of text with LTC_CAST5 @param pt The input plaintext (8 bytes) @param ct The output ciphertext (8 bytes) @param skey The key as scheduled */ #ifdef LTC_CLEAN_STACK static int _cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) #else int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) #endif { ulong32 R, L; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); LOAD32H(L,&pt[0]); LOAD32H(R,&pt[4]); L ^= FI(R, skey->cast5.K[0], skey->cast5.K[16]); R ^= FII(L, skey->cast5.K[1], skey->cast5.K[17]); L ^= FIII(R, skey->cast5.K[2], skey->cast5.K[18]); R ^= FI(L, skey->cast5.K[3], skey->cast5.K[19]); L ^= FII(R, skey->cast5.K[4], skey->cast5.K[20]); R ^= FIII(L, skey->cast5.K[5], skey->cast5.K[21]); L ^= FI(R, skey->cast5.K[6], skey->cast5.K[22]); R ^= FII(L, skey->cast5.K[7], skey->cast5.K[23]); L ^= FIII(R, skey->cast5.K[8], skey->cast5.K[24]); R ^= FI(L, skey->cast5.K[9], skey->cast5.K[25]); L ^= FII(R, skey->cast5.K[10], skey->cast5.K[26]); R ^= FIII(L, skey->cast5.K[11], skey->cast5.K[27]); if (skey->cast5.keylen > 10) { L ^= FI(R, skey->cast5.K[12], skey->cast5.K[28]); R ^= FII(L, skey->cast5.K[13], skey->cast5.K[29]); L ^= FIII(R, skey->cast5.K[14], skey->cast5.K[30]); R ^= FI(L, skey->cast5.K[15], skey->cast5.K[31]); } STORE32H(R,&ct[0]); STORE32H(L,&ct[4]); return CRYPT_OK; } #ifdef LTC_CLEAN_STACK int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) { int err =_cast5_ecb_encrypt(pt,ct,skey); burn_stack(sizeof(ulong32)*3); return err; } #endif /** Decrypts a block of text with LTC_CAST5 @param ct The input ciphertext (8 bytes) @param pt The output plaintext (8 bytes) @param skey The key as scheduled */ #ifdef LTC_CLEAN_STACK static int _cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) #else int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) #endif { ulong32 R, L; LTC_ARGCHK(pt != NULL); LTC_ARGCHK(ct != NULL); LTC_ARGCHK(skey != NULL); LOAD32H(R,&ct[0]); LOAD32H(L,&ct[4]); if (skey->cast5.keylen > 10) { R ^= FI(L, skey->cast5.K[15], skey->cast5.K[31]); L ^= FIII(R, skey->cast5.K[14], skey->cast5.K[30]); R ^= FII(L, skey->cast5.K[13], skey->cast5.K[29]); L ^= FI(R, skey->cast5.K[12], skey->cast5.K[28]); } R ^= FIII(L, skey->cast5.K[11], skey->cast5.K[27]); L ^= FII(R, skey->cast5.K[10], skey->cast5.K[26]); R ^= FI(L, skey->cast5.K[9], skey->cast5.K[25]); L ^= FIII(R, skey->cast5.K[8], skey->cast5.K[24]); R ^= FII(L, skey->cast5.K[7], skey->cast5.K[23]); L ^= FI(R, skey->cast5.K[6], skey->cast5.K[22]); R ^= FIII(L, skey->cast5.K[5], skey->cast5.K[21]); L ^= FII(R, skey->cast5.K[4], skey->cast5.K[20]); R ^= FI(L, skey->cast5.K[3], skey->cast5.K[19]); L ^= FIII(R, skey->cast5.K[2], skey->cast5.K[18]); R ^= FII(L, skey->cast5.K[1], skey->cast5.K[17]); L ^= FI(R, skey->cast5.K[0], skey->cast5.K[16]); STORE32H(L,&pt[0]); STORE32H(R,&pt[4]); return CRYPT_OK; } #ifdef LTC_CLEAN_STACK int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) { int err = _cast5_ecb_decrypt(ct,pt,skey); burn_stack(sizeof(ulong32)*3); return err; } #endif /** Performs a self-test of the LTC_CAST5 block cipher @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled */ int cast5_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else static const struct { int keylen; unsigned char key[16]; unsigned char pt[8]; unsigned char ct[8]; } tests[] = { { 16, {0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A}, {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, {0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2} }, { 10, {0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, {0xEB, 0x6A, 0x71, 0x1A, 0x2C, 0x02, 0x27, 0x1B}, }, { 5, {0x01, 0x23, 0x45, 0x67, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, {0x7A, 0xC8, 0x16, 0xD1, 0x6E, 0x9B, 0x30, 0x2E} } }; int i, y, err; symmetric_key key; unsigned char tmp[2][8]; for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { if ((err = cast5_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { return err; } cast5_ecb_encrypt(tests[i].pt, tmp[0], &key); cast5_ecb_decrypt(tmp[0], tmp[1], &key); if ((XMEMCMP(tmp[0], tests[i].ct, 8) != 0) || (XMEMCMP(tmp[1], tests[i].pt, 8) != 0)) { return CRYPT_FAIL_TESTVECTOR; } /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */ for (y = 0; y < 8; y++) tmp[0][y] = 0; for (y = 0; y < 1000; y++) cast5_ecb_encrypt(tmp[0], tmp[0], &key); for (y = 0; y < 1000; y++) cast5_ecb_decrypt(tmp[0], tmp[0], &key); for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR; } return CRYPT_OK; #endif } /** Terminate the context @param skey The scheduled key */ void cast5_done(symmetric_key *skey) { } /** Gets suitable key size @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable. @return CRYPT_OK if the input key size is acceptable. */ int cast5_keysize(int *keysize) { LTC_ARGCHK(keysize != NULL); if (*keysize < 5) { return CRYPT_INVALID_KEYSIZE; } else if (*keysize > 16) { *keysize = 16; } return CRYPT_OK; } #endif /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/cast5.c,v $ */ /* $Revision: 1.14 $ */ /* $Date: 2007/05/12 14:13:00 $ */ libtomcrypt-1.17/TODO0000644000175100001440000000010310621351501013205 0ustar tomusersfor 1.18 - document new ECC functions - add test for new functions libtomcrypt-1.17/makefile.shared0000644000175100001440000003411610621351501015475 0ustar tomusers# MAKEFILE for linux GCC # # This makefile produces a shared object and requires libtool to be installed. # # Thanks to Zed Shaw for helping debug this on BSD/OSX. # Tom St Denis # The version VERSION=0:117 # Compiler and Linker Names CC=libtool --mode=compile --tag=CC gcc # ranlib tools ifndef RANLIB RANLIB=ranlib endif # Compilation flags. Note the += does not write over the user's CFLAGS! CFLAGS += -c -I./src/headers/ -Wall -Wsign-compare -W -Wshadow -DLTC_SOURCE # additional warnings (newer GCC 3.4 and higher) ifdef GCC_34 CFLAGS += -Wsystem-headers -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wmissing-prototypes \ -Wmissing-declarations -Wpointer-arith endif ifndef IGNORE_SPEED # optimize for SPEED CFLAGS += -O3 -funroll-loops # add -fomit-frame-pointer. hinders debugging! CFLAGS += -fomit-frame-pointer # optimize for SIZE #CFLAGS += -Os -DLTC_SMALL_CODE endif # compile for DEBUGING (required for ccmalloc checking!!!) #CFLAGS += -g3 # older GCCs can't handle the "rotate with immediate" ROLc/RORc/etc macros # define this to help #CFLAGS += -DLTC_NO_ROLC #Output filenames for various targets. ifndef LIBTEST_S LIBTEST_S=libtomcrypt_prof.a endif ifndef LIBTEST LIBTEST=libtomcrypt_prof.la endif ifndef LIBNAME LIBNAME=libtomcrypt.la endif ifndef LIBNAME_S LIBNAME_S=libtomcrypt.a endif HASH=hashsum CRYPT=encrypt SMALL=small PROF=x86_prof TV=tv_gen TEST=test TIMING=timing #LIBPATH-The directory for libtomcrypt to be installed to. #INCPATH-The directory to install the header files for libtomcrypt. #DATAPATH-The directory to install the pdf docs. ifndef DESTDIR DESTDIR= endif ifndef LIBPATH LIBPATH=/usr/lib endif ifndef INCPATH INCPATH=/usr/include endif ifndef DATAPATH DATAPATH=/usr/share/doc/libtomcrypt/pdf endif #Who do we install as? ifdef INSTALL_USER USER=$(INSTALL_USER) else USER=root endif ifdef INSTALL_GROUP GROUP=$(INSTALL_GROUP) else GROUP=wheel endif #List of objects to compile. #START_INS OBJECTS=src/ciphers/aes/aes_enc.o src/ciphers/aes/aes.o src/ciphers/anubis.o src/ciphers/blowfish.o \ src/ciphers/cast5.o src/ciphers/des.o src/ciphers/kasumi.o src/ciphers/khazad.o src/ciphers/kseed.o \ src/ciphers/multi2.o src/ciphers/noekeon.o src/ciphers/rc2.o src/ciphers/rc5.o src/ciphers/rc6.o \ src/ciphers/safer/safer.o src/ciphers/safer/saferp.o src/ciphers/safer/safer_tab.o \ src/ciphers/skipjack.o src/ciphers/twofish/twofish.o src/ciphers/xtea.o src/encauth/ccm/ccm_memory.o \ src/encauth/ccm/ccm_test.o src/encauth/eax/eax_addheader.o src/encauth/eax/eax_decrypt.o \ src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o \ src/encauth/eax/eax_encrypt_authenticate_memory.o src/encauth/eax/eax_encrypt.o \ src/encauth/eax/eax_init.o src/encauth/eax/eax_test.o src/encauth/gcm/gcm_add_aad.o \ src/encauth/gcm/gcm_add_iv.o src/encauth/gcm/gcm_done.o src/encauth/gcm/gcm_gf_mult.o \ src/encauth/gcm/gcm_init.o src/encauth/gcm/gcm_memory.o src/encauth/gcm/gcm_mult_h.o \ src/encauth/gcm/gcm_process.o src/encauth/gcm/gcm_reset.o src/encauth/gcm/gcm_test.o \ src/encauth/ocb/ocb_decrypt.o src/encauth/ocb/ocb_decrypt_verify_memory.o \ src/encauth/ocb/ocb_done_decrypt.o src/encauth/ocb/ocb_done_encrypt.o \ src/encauth/ocb/ocb_encrypt_authenticate_memory.o src/encauth/ocb/ocb_encrypt.o \ src/encauth/ocb/ocb_init.o src/encauth/ocb/ocb_ntz.o src/encauth/ocb/ocb_shift_xor.o \ src/encauth/ocb/ocb_test.o src/encauth/ocb/s_ocb_done.o src/hashes/chc/chc.o \ src/hashes/helper/hash_file.o src/hashes/helper/hash_filehandle.o src/hashes/helper/hash_memory.o \ src/hashes/helper/hash_memory_multi.o src/hashes/md2.o src/hashes/md4.o src/hashes/md5.o \ src/hashes/rmd128.o src/hashes/rmd160.o src/hashes/rmd256.o src/hashes/rmd320.o src/hashes/sha1.o \ src/hashes/sha2/sha256.o src/hashes/sha2/sha512.o src/hashes/tiger.o src/hashes/whirl/whirl.o \ src/mac/f9/f9_done.o src/mac/f9/f9_file.o src/mac/f9/f9_init.o src/mac/f9/f9_memory.o \ src/mac/f9/f9_memory_multi.o src/mac/f9/f9_process.o src/mac/f9/f9_test.o src/mac/hmac/hmac_done.o \ src/mac/hmac/hmac_file.o src/mac/hmac/hmac_init.o src/mac/hmac/hmac_memory.o \ src/mac/hmac/hmac_memory_multi.o src/mac/hmac/hmac_process.o src/mac/hmac/hmac_test.o \ src/mac/omac/omac_done.o src/mac/omac/omac_file.o src/mac/omac/omac_init.o src/mac/omac/omac_memory.o \ src/mac/omac/omac_memory_multi.o src/mac/omac/omac_process.o src/mac/omac/omac_test.o \ src/mac/pelican/pelican.o src/mac/pelican/pelican_memory.o src/mac/pelican/pelican_test.o \ src/mac/pmac/pmac_done.o src/mac/pmac/pmac_file.o src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \ src/mac/pmac/pmac_memory_multi.o src/mac/pmac/pmac_ntz.o src/mac/pmac/pmac_process.o \ src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/mac/xcbc/xcbc_done.o \ src/mac/xcbc/xcbc_file.o src/mac/xcbc/xcbc_init.o src/mac/xcbc/xcbc_memory.o \ src/mac/xcbc/xcbc_memory_multi.o src/mac/xcbc/xcbc_process.o src/mac/xcbc/xcbc_test.o \ src/math/fp/ltc_ecc_fp_mulmod.o src/math/gmp_desc.o src/math/ltm_desc.o src/math/multi.o \ src/math/rand_prime.o src/math/tfm_desc.o src/misc/base64/base64_decode.o \ src/misc/base64/base64_encode.o src/misc/burn_stack.o src/misc/crypt/crypt_argchk.o \ src/misc/crypt/crypt.o src/misc/crypt/crypt_cipher_descriptor.o src/misc/crypt/crypt_cipher_is_valid.o \ src/misc/crypt/crypt_find_cipher_any.o src/misc/crypt/crypt_find_cipher.o \ src/misc/crypt/crypt_find_cipher_id.o src/misc/crypt/crypt_find_hash_any.o \ src/misc/crypt/crypt_find_hash.o src/misc/crypt/crypt_find_hash_id.o \ src/misc/crypt/crypt_find_hash_oid.o src/misc/crypt/crypt_find_prng.o src/misc/crypt/crypt_fsa.o \ src/misc/crypt/crypt_hash_descriptor.o src/misc/crypt/crypt_hash_is_valid.o \ src/misc/crypt/crypt_ltc_mp_descriptor.o src/misc/crypt/crypt_prng_descriptor.o \ src/misc/crypt/crypt_prng_is_valid.o src/misc/crypt/crypt_register_cipher.o \ src/misc/crypt/crypt_register_hash.o src/misc/crypt/crypt_register_prng.o \ src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o \ src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/pkcs5/pkcs_5_1.o \ src/misc/pkcs5/pkcs_5_2.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o \ src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o src/modes/cbc/cbc_setiv.o \ src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o src/modes/cfb/cfb_done.o \ src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o \ src/modes/cfb/cfb_start.o src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_done.o \ src/modes/ctr/ctr_encrypt.o src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o \ src/modes/ctr/ctr_start.o src/modes/ctr/ctr_test.o src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o \ src/modes/ecb/ecb_encrypt.o src/modes/ecb/ecb_start.o src/modes/f8/f8_decrypt.o src/modes/f8/f8_done.o \ src/modes/f8/f8_encrypt.o src/modes/f8/f8_getiv.o src/modes/f8/f8_setiv.o src/modes/f8/f8_start.o \ src/modes/f8/f8_test_mode.o src/modes/lrw/lrw_decrypt.o src/modes/lrw/lrw_done.o \ src/modes/lrw/lrw_encrypt.o src/modes/lrw/lrw_getiv.o src/modes/lrw/lrw_process.o \ src/modes/lrw/lrw_setiv.o src/modes/lrw/lrw_start.o src/modes/lrw/lrw_test.o \ src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o src/modes/ofb/ofb_encrypt.o \ src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o src/modes/ofb/ofb_start.o \ src/modes/xts/xts_decrypt.o src/modes/xts/xts_done.o src/modes/xts/xts_encrypt.o \ src/modes/xts/xts_init.o src/modes/xts/xts_mult_x.o src/modes/xts/xts_test.o \ src/pk/asn1/der/bit/der_decode_bit_string.o src/pk/asn1/der/bit/der_encode_bit_string.o \ src/pk/asn1/der/bit/der_length_bit_string.o src/pk/asn1/der/boolean/der_decode_boolean.o \ src/pk/asn1/der/boolean/der_encode_boolean.o src/pk/asn1/der/boolean/der_length_boolean.o \ src/pk/asn1/der/choice/der_decode_choice.o src/pk/asn1/der/ia5/der_decode_ia5_string.o \ src/pk/asn1/der/ia5/der_encode_ia5_string.o src/pk/asn1/der/ia5/der_length_ia5_string.o \ src/pk/asn1/der/integer/der_decode_integer.o src/pk/asn1/der/integer/der_encode_integer.o \ src/pk/asn1/der/integer/der_length_integer.o \ src/pk/asn1/der/object_identifier/der_decode_object_identifier.o \ src/pk/asn1/der/object_identifier/der_encode_object_identifier.o \ src/pk/asn1/der/object_identifier/der_length_object_identifier.o \ src/pk/asn1/der/octet/der_decode_octet_string.o src/pk/asn1/der/octet/der_encode_octet_string.o \ src/pk/asn1/der/octet/der_length_octet_string.o \ src/pk/asn1/der/printable_string/der_decode_printable_string.o \ src/pk/asn1/der/printable_string/der_encode_printable_string.o \ src/pk/asn1/der/printable_string/der_length_printable_string.o \ src/pk/asn1/der/sequence/der_decode_sequence_ex.o \ src/pk/asn1/der/sequence/der_decode_sequence_flexi.o \ src/pk/asn1/der/sequence/der_decode_sequence_multi.o \ src/pk/asn1/der/sequence/der_encode_sequence_ex.o \ src/pk/asn1/der/sequence/der_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \ src/pk/asn1/der/sequence/der_sequence_free.o src/pk/asn1/der/set/der_encode_set.o \ src/pk/asn1/der/set/der_encode_setof.o src/pk/asn1/der/short_integer/der_decode_short_integer.o \ src/pk/asn1/der/short_integer/der_encode_short_integer.o \ src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \ src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \ src/pk/asn1/der/utf8/der_decode_utf8_string.o src/pk/asn1/der/utf8/der_encode_utf8_string.o \ src/pk/asn1/der/utf8/der_length_utf8_string.o src/pk/dsa/dsa_decrypt_key.o \ src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o \ src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_shared_secret.o src/pk/dsa/dsa_sign_hash.o \ src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc_ansi_x963_export.o \ src/pk/ecc/ecc_ansi_x963_import.o src/pk/ecc/ecc.o src/pk/ecc/ecc_decrypt_key.o \ src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_free.o src/pk/ecc/ecc_get_size.o \ src/pk/ecc/ecc_import.o src/pk/ecc/ecc_make_key.o src/pk/ecc/ecc_shared_secret.o \ src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_test.o src/pk/ecc/ecc_verify_hash.o \ src/pk/ecc/ltc_ecc_is_valid_idx.o src/pk/ecc/ltc_ecc_map.o src/pk/ecc/ltc_ecc_mul2add.o \ src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \ src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \ src/pk/katja/katja_decrypt_key.o src/pk/katja/katja_encrypt_key.o src/pk/katja/katja_export.o \ src/pk/katja/katja_exptmod.o src/pk/katja/katja_free.o src/pk/katja/katja_import.o \ src/pk/katja/katja_make_key.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \ src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \ src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v1_5_decode.o \ src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \ src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \ src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o \ src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \ src/prngs/sprng.o src/prngs/yarrow.o HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \ src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \ src/headers/tomcrypt_pk.h src/headers/tomcrypt_hash.h src/headers/tomcrypt_math.h \ src/headers/tomcrypt_misc.h src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h \ src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h #END_INS TESTOBJECTS=demos/test.o HASHOBJECTS=demos/hashsum.o CRYPTOBJECTS=demos/encrypt.o SMALLOBJECTS=demos/small.o TVS=demos/tv_gen.o TESTS=demos/test.o TIMINGS=demos/timing.o #The default rule for make builds the libtomcrypt library. default:library #ciphers come in two flavours... enc+dec and enc src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c $(CC) $(CFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes.c -o src/ciphers/aes/aes_enc.o #These are the rules to make certain object files. src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c #This rule makes the libtomcrypt library. library: $(LIBNAME) testprof/$(LIBTEST): cd testprof ; CFLAGS="$(CFLAGS)" GROUP=$(GROUP) USER=$(USER) VERSION=$(VERSION) LIBPATH=$(LIBPATH) LIBTEST=$(LIBTEST) LIBTEST_S=$(LIBTEST_S) make -f makefile.shared objs: $(OBJECTS) $(LIBNAME): $(OBJECTS) testprof/$(LIBTEST) libtool --silent --mode=link gcc $(CFLAGS) `find . -type f | grep "[.]lo" | grep "src/" | xargs` $(EXTRALIBS) -o $(LIBNAME) -rpath $(LIBPATH) -version-info $(VERSION) install: $(LIBNAME) install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH) cd testprof ; CFLAGS="$(CFLAGS)" GROUP=$(GROUP) USER=$(USER) VERSION=$(VERSION) LIBPATH=$(LIBPATH) LIBTEST=$(LIBTEST) LIBTEST_S=$(LIBTEST_S) DESTDIR=$(DESTDIR) make -f makefile.shared install libtool --silent --mode=install install -c libtomcrypt.la $(DESTDIR)$(LIBPATH)/libtomcrypt.la install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH) #This rule makes the hash program included with libtomcrypt hashsum: library gcc $(CFLAGS) demos/hashsum.c -o hashsum.o gcc -o hashsum hashsum.o -ltomcrypt $(EXTRALIBS) #makes the crypt program crypt: library gcc $(CFLAGS) demos/encrypt.c -o encrypt.o gcc -o crypt encrypt.o -ltomcrypt $(EXTRALIBS) tv_gen: library $(TVS) gcc -o tv_gen $(TVS) -ltomcrypt $(EXTRALIBS) test: library testprof/$(LIBTEST) $(TESTS) gcc -o $(TEST) $(TESTS) -ltomcrypt_prof -ltomcrypt $(EXTRALIBS) timing: library testprof/$(LIBTEST) $(TIMINGS) gcc -o $(TIMING) $(TIMINGS) -ltomcrypt_prof -ltomcrypt $(EXTRALIBS) # $Source: /cvs/libtom/libtomcrypt/makefile.shared,v $ # $Revision: 1.80 $ # $Date: 2007/02/16 16:36:25 $ libtomcrypt-1.17/parsenames.pl0000644000175100001440000000105510621351501015217 0ustar tomusers#!/usr/bin/perl # # Splits the list of files and outputs for makefile type files # wrapped at 80 chars # # Tom St Denis @a = split(" ", $ARGV[1]); $b = "$ARGV[0]="; $len = length($b); print $b; foreach my $obj (@a) { $len = $len + length($obj); $obj =~ s/\*/\$/; if ($len > 100) { printf "\\\n"; $len = length($obj); } print "$obj "; } if ($ARGV[0] eq "HEADERS") { print "testprof/tomcrypt_test.h"; } print "\n\n"; # $Source: /cvs/libtom/libtomcrypt/parsenames.pl,v $ # $Revision: 1.3 $ # $Date: 2005/05/05 14:49:27 $ libtomcrypt-1.17/LICENSE0000644000175100001440000000012210621351501013523 0ustar tomusersLibTomCrypt is public domain. As should all quality software be. Tom St Denis libtomcrypt-1.17/demos/0000755000175100001440000000000010621351501013632 5ustar tomuserslibtomcrypt-1.17/demos/test/0000755000175100001440000000000010621351501014611 5ustar tomuserslibtomcrypt-1.17/demos/small.c0000644000175100001440000000051610621351501015110 0ustar tomusers/* small demo app that just includes a cipher/hash/prng */ #include int main(void) { register_cipher(&rijndael_enc_desc); register_prng(&yarrow_desc); register_hash(&sha256_desc); return 0; } /* $Source: /cvs/libtom/libtomcrypt/demos/small.c,v $ */ /* $Revision: 1.3 $ */ /* $Date: 2006/06/07 22:25:09 $ */ libtomcrypt-1.17/demos/encrypt.c0000644000175100001440000001402010621351501015457 0ustar tomusers/* encrypt V1.1 Fri Oct 18 04:28:03 NZDT 2002 */ /* File de/encryption, using libtomcrypt */ /* Written by Daniel Richards */ /* Help from Tom St Denis with various bits */ /* This code is public domain, no rights reserved. */ /* Encrypts by default, -d flag enables decryption */ /* ie: ./encrypt blowfish story.txt story.ct */ /* ./encrypt -d blowfish story.ct story.pt */ #include int errno; int usage(char *name) { int x; printf("Usage: %s [-d](ecrypt) cipher infile outfile\nCiphers:\n", name); for (x = 0; cipher_descriptor[x].name != NULL; x++) { printf("%s\n",cipher_descriptor[x].name); } exit(1); } void register_algs(void) { int x; #ifdef LTC_RIJNDAEL register_cipher (&aes_desc); #endif #ifdef LTC_BLOWFISH register_cipher (&blowfish_desc); #endif #ifdef LTC_XTEA register_cipher (&xtea_desc); #endif #ifdef LTC_RC5 register_cipher (&rc5_desc); #endif #ifdef LTC_RC6 register_cipher (&rc6_desc); #endif #ifdef LTC_SAFERP register_cipher (&saferp_desc); #endif #ifdef LTC_TWOFISH register_cipher (&twofish_desc); #endif #ifdef LTC_SAFER register_cipher (&safer_k64_desc); register_cipher (&safer_sk64_desc); register_cipher (&safer_k128_desc); register_cipher (&safer_sk128_desc); #endif #ifdef LTC_RC2 register_cipher (&rc2_desc); #endif #ifdef LTC_DES register_cipher (&des_desc); register_cipher (&des3_desc); #endif #ifdef LTC_CAST5 register_cipher (&cast5_desc); #endif #ifdef LTC_NOEKEON register_cipher (&noekeon_desc); #endif #ifdef LTC_SKIPJACK register_cipher (&skipjack_desc); #endif #ifdef LTC_KHAZAD register_cipher (&khazad_desc); #endif #ifdef LTC_ANUBIS register_cipher (&anubis_desc); #endif if (register_hash(&sha256_desc) == -1) { printf("Error registering LTC_SHA256\n"); exit(-1); } if (register_prng(&yarrow_desc) == -1) { printf("Error registering yarrow PRNG\n"); exit(-1); } if (register_prng(&sprng_desc) == -1) { printf("Error registering sprng PRNG\n"); exit(-1); } } int main(int argc, char *argv[]) { unsigned char plaintext[512],ciphertext[512]; unsigned char tmpkey[512], key[MAXBLOCKSIZE], IV[MAXBLOCKSIZE]; unsigned char inbuf[512]; /* i/o block size */ unsigned long outlen, y, ivsize, x, decrypt; symmetric_CTR ctr; int cipher_idx, hash_idx, ks; char *infile, *outfile, *cipher; prng_state prng; FILE *fdin, *fdout; /* register algs, so they can be printed */ register_algs(); if (argc < 4) { return usage(argv[0]); } if (!strcmp(argv[1], "-d")) { decrypt = 1; cipher = argv[2]; infile = argv[3]; outfile = argv[4]; } else { decrypt = 0; cipher = argv[1]; infile = argv[2]; outfile = argv[3]; } /* file handles setup */ fdin = fopen(infile,"rb"); if (fdin == NULL) { perror("Can't open input for reading"); exit(-1); } fdout = fopen(outfile,"wb"); if (fdout == NULL) { perror("Can't open output for writing"); exit(-1); } cipher_idx = find_cipher(cipher); if (cipher_idx == -1) { printf("Invalid cipher entered on command line.\n"); exit(-1); } hash_idx = find_hash("sha256"); if (hash_idx == -1) { printf("LTC_SHA256 not found...?\n"); exit(-1); } ivsize = cipher_descriptor[cipher_idx].block_length; ks = hash_descriptor[hash_idx].hashsize; if (cipher_descriptor[cipher_idx].keysize(&ks) != CRYPT_OK) { printf("Invalid keysize???\n"); exit(-1); } printf("\nEnter key: "); fgets((char *)tmpkey,sizeof(tmpkey), stdin); outlen = sizeof(key); if ((errno = hash_memory(hash_idx,tmpkey,strlen((char *)tmpkey),key,&outlen)) != CRYPT_OK) { printf("Error hashing key: %s\n", error_to_string(errno)); exit(-1); } if (decrypt) { /* Need to read in IV */ if (fread(IV,1,ivsize,fdin) != ivsize) { printf("Error reading IV from input.\n"); exit(-1); } if ((errno = ctr_start(cipher_idx,IV,key,ks,0,CTR_COUNTER_LITTLE_ENDIAN,&ctr)) != CRYPT_OK) { printf("ctr_start error: %s\n",error_to_string(errno)); exit(-1); } /* IV done */ do { y = fread(inbuf,1,sizeof(inbuf),fdin); if ((errno = ctr_decrypt(inbuf,plaintext,y,&ctr)) != CRYPT_OK) { printf("ctr_decrypt error: %s\n", error_to_string(errno)); exit(-1); } if (fwrite(plaintext,1,y,fdout) != y) { printf("Error writing to file.\n"); exit(-1); } } while (y == sizeof(inbuf)); fclose(fdin); fclose(fdout); } else { /* encrypt */ /* Setup yarrow for random bytes for IV */ if ((errno = rng_make_prng(128, find_prng("yarrow"), &prng, NULL)) != CRYPT_OK) { printf("Error setting up PRNG, %s\n", error_to_string(errno)); } /* You can use rng_get_bytes on platforms that support it */ /* x = rng_get_bytes(IV,ivsize,NULL);*/ x = yarrow_read(IV,ivsize,&prng); if (x != ivsize) { printf("Error reading PRNG for IV required.\n"); exit(-1); } if (fwrite(IV,1,ivsize,fdout) != ivsize) { printf("Error writing IV to output.\n"); exit(-1); } if ((errno = ctr_start(cipher_idx,IV,key,ks,0,CTR_COUNTER_LITTLE_ENDIAN,&ctr)) != CRYPT_OK) { printf("ctr_start error: %s\n",error_to_string(errno)); exit(-1); } do { y = fread(inbuf,1,sizeof(inbuf),fdin); if ((errno = ctr_encrypt(inbuf,ciphertext,y,&ctr)) != CRYPT_OK) { printf("ctr_encrypt error: %s\n", error_to_string(errno)); exit(-1); } if (fwrite(ciphertext,1,y,fdout) != y) { printf("Error writing to output.\n"); exit(-1); } } while (y == sizeof(inbuf)); fclose(fdout); fclose(fdin); } return 0; } /* $Source: /cvs/libtom/libtomcrypt/demos/encrypt.c,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/demos/hashsum.c0000644000175100001440000000565410621351501015460 0ustar tomusers/* * Written by Daniel Richards 6/7/2002 * hash.c: This app uses libtomcrypt to hash either stdin or a file * This file is Public Domain. No rights are reserved. * Compile with 'gcc hashsum.c -o hashsum -ltomcrypt' * This example isn't really big enough to warrent splitting into * more functions ;) */ #include int errno; void register_algs(); int main(int argc, char **argv) { int idx, x, z; unsigned long w; unsigned char hash_buffer[MAXBLOCKSIZE]; hash_state md; /* You need to register algorithms before using them */ register_algs(); if (argc < 2) { printf("usage: ./hash algorithm file [file ...]\n"); printf("Algorithms:\n"); for (x = 0; hash_descriptor[x].name != NULL; x++) { printf(" %s (%d)\n", hash_descriptor[x].name, hash_descriptor[x].ID); } exit(EXIT_SUCCESS); } idx = find_hash(argv[1]); if (idx == -1) { fprintf(stderr, "\nInvalid hash specified on command line.\n"); return -1; } if (argc == 2) { hash_descriptor[idx].init(&md); do { x = fread(hash_buffer, 1, sizeof(hash_buffer), stdin); hash_descriptor[idx].process(&md, hash_buffer, x); } while (x == sizeof(hash_buffer)); hash_descriptor[idx].done(&md, hash_buffer); for (x = 0; x < (int)hash_descriptor[idx].hashsize; x++) { printf("%02x",hash_buffer[x]); } printf(" (stdin)\n"); } else { for (z = 2; z < argc; z++) { w = sizeof(hash_buffer); if ((errno = hash_file(idx,argv[z],hash_buffer,&w)) != CRYPT_OK) { printf("File hash error: %s\n", error_to_string(errno)); } else { for (x = 0; x < (int)hash_descriptor[idx].hashsize; x++) { printf("%02x",hash_buffer[x]); } printf(" %s\n", argv[z]); } } } return EXIT_SUCCESS; } void register_algs(void) { int err; #ifdef LTC_TIGER register_hash (&tiger_desc); #endif #ifdef LTC_MD2 register_hash (&md2_desc); #endif #ifdef LTC_MD4 register_hash (&md4_desc); #endif #ifdef LTC_MD5 register_hash (&md5_desc); #endif #ifdef LTC_SHA1 register_hash (&sha1_desc); #endif #ifdef LTC_SHA224 register_hash (&sha224_desc); #endif #ifdef LTC_SHA256 register_hash (&sha256_desc); #endif #ifdef LTC_SHA384 register_hash (&sha384_desc); #endif #ifdef LTC_SHA512 register_hash (&sha512_desc); #endif #ifdef LTC_RIPEMD128 register_hash (&rmd128_desc); #endif #ifdef LTC_RIPEMD160 register_hash (&rmd160_desc); #endif #ifdef LTC_WHIRLPOOL register_hash (&whirlpool_desc); #endif #ifdef LTC_CHC_HASH register_hash(&chc_desc); if ((err = chc_register(register_cipher(&aes_enc_desc))) != CRYPT_OK) { printf("chc_register error: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } #endif } /* $Source: /cvs/libtom/libtomcrypt/demos/hashsum.c,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/demos/tv_gen.c0000644000175100001440000005754110621351501015274 0ustar tomusers#include void reg_algs(void) { int err; #ifdef LTC_RIJNDAEL register_cipher (&aes_desc); #endif #ifdef LTC_BLOWFISH register_cipher (&blowfish_desc); #endif #ifdef LTC_XTEA register_cipher (&xtea_desc); #endif #ifdef LTC_RC5 register_cipher (&rc5_desc); #endif #ifdef LTC_RC6 register_cipher (&rc6_desc); #endif #ifdef LTC_SAFERP register_cipher (&saferp_desc); #endif #ifdef LTC_TWOFISH register_cipher (&twofish_desc); #endif #ifdef LTC_SAFER register_cipher (&safer_k64_desc); register_cipher (&safer_sk64_desc); register_cipher (&safer_k128_desc); register_cipher (&safer_sk128_desc); #endif #ifdef LTC_RC2 register_cipher (&rc2_desc); #endif #ifdef LTC_DES register_cipher (&des_desc); register_cipher (&des3_desc); #endif #ifdef LTC_CAST5 register_cipher (&cast5_desc); #endif #ifdef LTC_NOEKEON register_cipher (&noekeon_desc); #endif #ifdef LTC_SKIPJACK register_cipher (&skipjack_desc); #endif #ifdef LTC_ANUBIS register_cipher (&anubis_desc); #endif #ifdef LTC_KHAZAD register_cipher (&khazad_desc); #endif #ifdef LTC_TIGER register_hash (&tiger_desc); #endif #ifdef LTC_MD2 register_hash (&md2_desc); #endif #ifdef LTC_MD4 register_hash (&md4_desc); #endif #ifdef LTC_MD5 register_hash (&md5_desc); #endif #ifdef LTC_SHA1 register_hash (&sha1_desc); #endif #ifdef LTC_SHA224 register_hash (&sha224_desc); #endif #ifdef LTC_SHA256 register_hash (&sha256_desc); #endif #ifdef LTC_SHA384 register_hash (&sha384_desc); #endif #ifdef LTC_SHA512 register_hash (&sha512_desc); #endif #ifdef LTC_RIPEMD128 register_hash (&rmd128_desc); #endif #ifdef LTC_RIPEMD160 register_hash (&rmd160_desc); #endif #ifdef LTC_WHIRLPOOL register_hash (&whirlpool_desc); #endif #ifdef LTC_CHC_HASH register_hash(&chc_desc); if ((err = chc_register(register_cipher(&aes_desc))) != CRYPT_OK) { printf("chc_register error: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } #endif #ifdef USE_LTM ltc_mp = ltm_desc; #elif defined(USE_TFM) ltc_mp = tfm_desc; #elif defined(USE_GMP) ltc_mp = gmp_desc; #else extern ltc_math_descriptor EXT_MATH_LIB; ltc_mp = EXT_MATH_LIB; #endif } void hash_gen(void) { unsigned char md[MAXBLOCKSIZE], *buf; unsigned long outlen, x, y, z; FILE *out; int err; out = fopen("hash_tv.txt", "w"); if (out == NULL) { perror("can't open hash_tv"); } fprintf(out, "Hash Test Vectors:\n\nThese are the hashes of nn bytes '00 01 02 03 .. (nn-1)'\n\n"); for (x = 0; hash_descriptor[x].name != NULL; x++) { buf = XMALLOC(2 * hash_descriptor[x].blocksize + 1); if (buf == NULL) { perror("can't alloc mem"); exit(EXIT_FAILURE); } fprintf(out, "Hash: %s\n", hash_descriptor[x].name); for (y = 0; y <= (hash_descriptor[x].blocksize * 2); y++) { for (z = 0; z < y; z++) { buf[z] = (unsigned char)(z & 255); } outlen = sizeof(md); if ((err = hash_memory(x, buf, y, md, &outlen)) != CRYPT_OK) { printf("hash_memory error: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } fprintf(out, "%3lu: ", y); for (z = 0; z < outlen; z++) { fprintf(out, "%02X", md[z]); } fprintf(out, "\n"); } fprintf(out, "\n"); XFREE(buf); } fclose(out); } void cipher_gen(void) { unsigned char *key, pt[MAXBLOCKSIZE]; unsigned long x, y, z, w; int err, kl, lastkl; FILE *out; symmetric_key skey; out = fopen("cipher_tv.txt", "w"); fprintf(out, "Cipher Test Vectors\n\nThese are test encryptions with key of nn bytes '00 01 02 03 .. (nn-1)' and original PT of the same style.\n" "The output of step N is used as the key and plaintext for step N+1 (key bytes repeated as required to fill the key)\n\n"); for (x = 0; cipher_descriptor[x].name != NULL; x++) { fprintf(out, "Cipher: %s\n", cipher_descriptor[x].name); /* three modes, smallest, medium, large keys */ lastkl = 10000; for (y = 0; y < 3; y++) { switch (y) { case 0: kl = cipher_descriptor[x].min_key_length; break; case 1: kl = (cipher_descriptor[x].min_key_length + cipher_descriptor[x].max_key_length)/2; break; case 2: kl = cipher_descriptor[x].max_key_length; break; } if ((err = cipher_descriptor[x].keysize(&kl)) != CRYPT_OK) { printf("keysize error: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } if (kl == lastkl) break; lastkl = kl; fprintf(out, "Key Size: %d bytes\n", kl); key = XMALLOC(kl); if (key == NULL) { perror("can't malloc memory"); exit(EXIT_FAILURE); } for (z = 0; (int)z < kl; z++) { key[z] = (unsigned char)z; } if ((err = cipher_descriptor[x].setup(key, kl, 0, &skey)) != CRYPT_OK) { printf("setup error: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } for (z = 0; (int)z < cipher_descriptor[x].block_length; z++) { pt[z] = (unsigned char)z; } for (w = 0; w < 50; w++) { cipher_descriptor[x].ecb_encrypt(pt, pt, &skey); fprintf(out, "%2lu: ", w); for (z = 0; (int)z < cipher_descriptor[x].block_length; z++) { fprintf(out, "%02X", pt[z]); } fprintf(out, "\n"); /* reschedule a new key */ for (z = 0; z < (unsigned long)kl; z++) { key[z] = pt[z % cipher_descriptor[x].block_length]; } if ((err = cipher_descriptor[x].setup(key, kl, 0, &skey)) != CRYPT_OK) { printf("cipher setup2 error: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } } fprintf(out, "\n"); XFREE(key); } fprintf(out, "\n"); } fclose(out); } void hmac_gen(void) { unsigned char key[MAXBLOCKSIZE], output[MAXBLOCKSIZE], *input; int x, y, z, err; FILE *out; unsigned long len; out = fopen("hmac_tv.txt", "w"); fprintf(out, "LTC_HMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are LTC_HMACed. The initial key is\n" "of the same format (the same length as the HASH output size). The LTC_HMAC key in step N+1 is the LTC_HMAC output of\n" "step N.\n\n"); for (x = 0; hash_descriptor[x].name != NULL; x++) { fprintf(out, "LTC_HMAC-%s\n", hash_descriptor[x].name); /* initial key */ for (y = 0; y < (int)hash_descriptor[x].hashsize; y++) { key[y] = (y&255); } input = XMALLOC(hash_descriptor[x].blocksize * 2 + 1); if (input == NULL) { perror("Can't malloc memory"); exit(EXIT_FAILURE); } for (y = 0; y <= (int)(hash_descriptor[x].blocksize * 2); y++) { for (z = 0; z < y; z++) { input[z] = (unsigned char)(z & 255); } len = sizeof(output); if ((err = hmac_memory(x, key, hash_descriptor[x].hashsize, input, y, output, &len)) != CRYPT_OK) { printf("Error hmacing: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } fprintf(out, "%3d: ", y); for (z = 0; z <(int) len; z++) { fprintf(out, "%02X", output[z]); } fprintf(out, "\n"); /* forward the key */ memcpy(key, output, hash_descriptor[x].hashsize); } XFREE(input); fprintf(out, "\n"); } fclose(out); } void omac_gen(void) { unsigned char key[MAXBLOCKSIZE], output[MAXBLOCKSIZE], input[MAXBLOCKSIZE*2+2]; int err, x, y, z, kl; FILE *out; unsigned long len; out = fopen("omac_tv.txt", "w"); fprintf(out, "LTC_OMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are LTC_OMAC'ed. The initial key is\n" "of the same format (length specified per cipher). The LTC_OMAC key in step N+1 is the LTC_OMAC output of\n" "step N (repeated as required to fill the array).\n\n"); for (x = 0; cipher_descriptor[x].name != NULL; x++) { kl = cipher_descriptor[x].block_length; /* skip ciphers which do not have 64 or 128 bit block sizes */ if (kl != 8 && kl != 16) continue; if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) { kl = cipher_descriptor[x].max_key_length; } fprintf(out, "LTC_OMAC-%s (%d byte key)\n", cipher_descriptor[x].name, kl); /* initial key/block */ for (y = 0; y < kl; y++) { key[y] = (y & 255); } for (y = 0; y <= (int)(cipher_descriptor[x].block_length*2); y++) { for (z = 0; z < y; z++) { input[z] = (unsigned char)(z & 255); } len = sizeof(output); if ((err = omac_memory(x, key, kl, input, y, output, &len)) != CRYPT_OK) { printf("Error omacing: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } fprintf(out, "%3d: ", y); for (z = 0; z <(int)len; z++) { fprintf(out, "%02X", output[z]); } fprintf(out, "\n"); /* forward the key */ for (z = 0; z < kl; z++) { key[z] = output[z % len]; } } fprintf(out, "\n"); } fclose(out); } void pmac_gen(void) { unsigned char key[MAXBLOCKSIZE], output[MAXBLOCKSIZE], input[MAXBLOCKSIZE*2+2]; int err, x, y, z, kl; FILE *out; unsigned long len; out = fopen("pmac_tv.txt", "w"); fprintf(out, "PMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are LTC_OMAC'ed. The initial key is\n" "of the same format (length specified per cipher). The LTC_OMAC key in step N+1 is the LTC_OMAC output of\n" "step N (repeated as required to fill the array).\n\n"); for (x = 0; cipher_descriptor[x].name != NULL; x++) { kl = cipher_descriptor[x].block_length; /* skip ciphers which do not have 64 or 128 bit block sizes */ if (kl != 8 && kl != 16) continue; if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) { kl = cipher_descriptor[x].max_key_length; } fprintf(out, "PMAC-%s (%d byte key)\n", cipher_descriptor[x].name, kl); /* initial key/block */ for (y = 0; y < kl; y++) { key[y] = (y & 255); } for (y = 0; y <= (int)(cipher_descriptor[x].block_length*2); y++) { for (z = 0; z < y; z++) { input[z] = (unsigned char)(z & 255); } len = sizeof(output); if ((err = pmac_memory(x, key, kl, input, y, output, &len)) != CRYPT_OK) { printf("Error omacing: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } fprintf(out, "%3d: ", y); for (z = 0; z <(int)len; z++) { fprintf(out, "%02X", output[z]); } fprintf(out, "\n"); /* forward the key */ for (z = 0; z < kl; z++) { key[z] = output[z % len]; } } fprintf(out, "\n"); } fclose(out); } void eax_gen(void) { int err, kl, x, y1, z; FILE *out; unsigned char key[MAXBLOCKSIZE], nonce[MAXBLOCKSIZE*2], header[MAXBLOCKSIZE*2], plaintext[MAXBLOCKSIZE*2], tag[MAXBLOCKSIZE]; unsigned long len; out = fopen("eax_tv.txt", "w"); fprintf(out, "EAX Test Vectors. Uses the 00010203...NN-1 pattern for header/nonce/plaintext/key. The outputs\n" "are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous\n" "step repeated sufficiently.\n\n"); for (x = 0; cipher_descriptor[x].name != NULL; x++) { kl = cipher_descriptor[x].block_length; /* skip ciphers which do not have 64 or 128 bit block sizes */ if (kl != 8 && kl != 16) continue; if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) { kl = cipher_descriptor[x].max_key_length; } fprintf(out, "EAX-%s (%d byte key)\n", cipher_descriptor[x].name, kl); /* the key */ for (z = 0; z < kl; z++) { key[z] = (z & 255); } for (y1 = 0; y1 <= (int)(cipher_descriptor[x].block_length*2); y1++){ for (z = 0; z < y1; z++) { plaintext[z] = (unsigned char)(z & 255); nonce[z] = (unsigned char)(z & 255); header[z] = (unsigned char)(z & 255); } len = sizeof(tag); if ((err = eax_encrypt_authenticate_memory(x, key, kl, nonce, y1, header, y1, plaintext, y1, plaintext, tag, &len)) != CRYPT_OK) { printf("Error EAX'ing: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } fprintf(out, "%3d: ", y1); for (z = 0; z < y1; z++) { fprintf(out, "%02X", plaintext[z]); } fprintf(out, ", "); for (z = 0; z <(int)len; z++) { fprintf(out, "%02X", tag[z]); } fprintf(out, "\n"); /* forward the key */ for (z = 0; z < kl; z++) { key[z] = tag[z % len]; } } fprintf(out, "\n"); } fclose(out); } void ocb_gen(void) { int err, kl, x, y1, z; FILE *out; unsigned char key[MAXBLOCKSIZE], nonce[MAXBLOCKSIZE*2], plaintext[MAXBLOCKSIZE*2], tag[MAXBLOCKSIZE]; unsigned long len; out = fopen("ocb_tv.txt", "w"); fprintf(out, "OCB Test Vectors. Uses the 00010203...NN-1 pattern for nonce/plaintext/key. The outputs\n" "are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous\n" "step repeated sufficiently. The nonce is fixed throughout.\n\n"); for (x = 0; cipher_descriptor[x].name != NULL; x++) { kl = cipher_descriptor[x].block_length; /* skip ciphers which do not have 64 or 128 bit block sizes */ if (kl != 8 && kl != 16) continue; if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) { kl = cipher_descriptor[x].max_key_length; } fprintf(out, "OCB-%s (%d byte key)\n", cipher_descriptor[x].name, kl); /* the key */ for (z = 0; z < kl; z++) { key[z] = (z & 255); } /* fixed nonce */ for (z = 0; z < cipher_descriptor[x].block_length; z++) { nonce[z] = z; } for (y1 = 0; y1 <= (int)(cipher_descriptor[x].block_length*2); y1++){ for (z = 0; z < y1; z++) { plaintext[z] = (unsigned char)(z & 255); } len = sizeof(tag); if ((err = ocb_encrypt_authenticate_memory(x, key, kl, nonce, plaintext, y1, plaintext, tag, &len)) != CRYPT_OK) { printf("Error OCB'ing: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } fprintf(out, "%3d: ", y1); for (z = 0; z < y1; z++) { fprintf(out, "%02X", plaintext[z]); } fprintf(out, ", "); for (z = 0; z <(int)len; z++) { fprintf(out, "%02X", tag[z]); } fprintf(out, "\n"); /* forward the key */ for (z = 0; z < kl; z++) { key[z] = tag[z % len]; } } fprintf(out, "\n"); } fclose(out); } void ccm_gen(void) { int err, kl, x, y1, z; FILE *out; unsigned char key[MAXBLOCKSIZE], nonce[MAXBLOCKSIZE*2], plaintext[MAXBLOCKSIZE*2], tag[MAXBLOCKSIZE]; unsigned long len; out = fopen("ccm_tv.txt", "w"); fprintf(out, "CCM Test Vectors. Uses the 00010203...NN-1 pattern for nonce/header/plaintext/key. The outputs\n" "are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous\n" "step repeated sufficiently. The nonce is fixed throughout at 13 bytes 000102...\n\n"); for (x = 0; cipher_descriptor[x].name != NULL; x++) { kl = cipher_descriptor[x].block_length; /* skip ciphers which do not have 128 bit block sizes */ if (kl != 16) continue; if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) { kl = cipher_descriptor[x].max_key_length; } fprintf(out, "CCM-%s (%d byte key)\n", cipher_descriptor[x].name, kl); /* the key */ for (z = 0; z < kl; z++) { key[z] = (z & 255); } /* fixed nonce */ for (z = 0; z < cipher_descriptor[x].block_length; z++) { nonce[z] = z; } for (y1 = 0; y1 <= (int)(cipher_descriptor[x].block_length*2); y1++){ for (z = 0; z < y1; z++) { plaintext[z] = (unsigned char)(z & 255); } len = sizeof(tag); if ((err = ccm_memory(x, key, kl, NULL, nonce, 13, plaintext, y1, plaintext, y1, plaintext, tag, &len, CCM_ENCRYPT)) != CRYPT_OK) { printf("Error CCM'ing: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } fprintf(out, "%3d: ", y1); for (z = 0; z < y1; z++) { fprintf(out, "%02X", plaintext[z]); } fprintf(out, ", "); for (z = 0; z <(int)len; z++) { fprintf(out, "%02X", tag[z]); } fprintf(out, "\n"); /* forward the key */ for (z = 0; z < kl; z++) { key[z] = tag[z % len]; } } fprintf(out, "\n"); } fclose(out); } void gcm_gen(void) { int err, kl, x, y1, z; FILE *out; unsigned char key[MAXBLOCKSIZE], plaintext[MAXBLOCKSIZE*2], tag[MAXBLOCKSIZE]; unsigned long len; out = fopen("gcm_tv.txt", "w"); fprintf(out, "GCM Test Vectors. Uses the 00010203...NN-1 pattern for nonce/header/plaintext/key. The outputs\n" "are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous\n" "step repeated sufficiently. The nonce is fixed throughout at 13 bytes 000102...\n\n"); for (x = 0; cipher_descriptor[x].name != NULL; x++) { kl = cipher_descriptor[x].block_length; /* skip ciphers which do not have 128 bit block sizes */ if (kl != 16) continue; if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) { kl = cipher_descriptor[x].max_key_length; } fprintf(out, "GCM-%s (%d byte key)\n", cipher_descriptor[x].name, kl); /* the key */ for (z = 0; z < kl; z++) { key[z] = (z & 255); } for (y1 = 0; y1 <= (int)(cipher_descriptor[x].block_length*2); y1++){ for (z = 0; z < y1; z++) { plaintext[z] = (unsigned char)(z & 255); } len = sizeof(tag); if ((err = gcm_memory(x, key, kl, plaintext, y1, plaintext, y1, plaintext, y1, plaintext, tag, &len, GCM_ENCRYPT)) != CRYPT_OK) { printf("Error GCM'ing: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } fprintf(out, "%3d: ", y1); for (z = 0; z < y1; z++) { fprintf(out, "%02X", plaintext[z]); } fprintf(out, ", "); for (z = 0; z <(int)len; z++) { fprintf(out, "%02X", tag[z]); } fprintf(out, "\n"); /* forward the key */ for (z = 0; z < kl; z++) { key[z] = tag[z % len]; } } fprintf(out, "\n"); } fclose(out); } void base64_gen(void) { FILE *out; unsigned char dst[256], src[32]; unsigned long x, y, len; out = fopen("base64_tv.txt", "w"); fprintf(out, "Base64 vectors. These are the base64 encodings of the strings 00,01,02...NN-1\n\n"); for (x = 0; x <= 32; x++) { for (y = 0; y < x; y++) { src[y] = y; } len = sizeof(dst); base64_encode(src, x, dst, &len); fprintf(out, "%2lu: %s\n", x, dst); } fclose(out); } void math_gen(void) { } void ecc_gen(void) { FILE *out; unsigned char str[512]; void *k, *order, *modulus; ecc_point *G, *R; int x; out = fopen("ecc_tv.txt", "w"); fprintf(out, "ecc vectors. These are for kG for k=1,3,9,27,...,3**n until k > order of the curve outputs are triplets\n\n"); G = ltc_ecc_new_point(); R = ltc_ecc_new_point(); mp_init(&k); mp_init(&order); mp_init(&modulus); for (x = 0; ltc_ecc_sets[x].size != 0; x++) { fprintf(out, "ECC-%d\n", ltc_ecc_sets[x].size*8); mp_set(k, 1); mp_read_radix(order, (char *)ltc_ecc_sets[x].order, 16); mp_read_radix(modulus, (char *)ltc_ecc_sets[x].prime, 16); mp_read_radix(G->x, (char *)ltc_ecc_sets[x].Gx, 16); mp_read_radix(G->y, (char *)ltc_ecc_sets[x].Gy, 16); mp_set(G->z, 1); while (mp_cmp(k, order) == LTC_MP_LT) { ltc_mp.ecc_ptmul(k, G, R, modulus, 1); mp_tohex(k, (char*)str); fprintf(out, "%s, ", (char*)str); mp_tohex(R->x, (char*)str); fprintf(out, "%s, ", (char*)str); mp_tohex(R->y, (char*)str); fprintf(out, "%s\n", (char*)str); mp_mul_d(k, 3, k); } } mp_clear_multi(k, order, modulus, NULL); ltc_ecc_del_point(G); ltc_ecc_del_point(R); fclose(out); } void lrw_gen(void) { FILE *out; unsigned char tweak[16], key[16], iv[16], buf[1024]; int x, y, err; symmetric_LRW lrw; /* initialize default key and tweak */ for (x = 0; x < 16; x++) { tweak[x] = key[x] = iv[x] = x; } out = fopen("lrw_tv.txt", "w"); for (x = 16; x < (int)(sizeof(buf)); x += 16) { if ((err = lrw_start(find_cipher("aes"), iv, key, 16, tweak, 0, &lrw)) != CRYPT_OK) { fprintf(stderr, "Error starting LRW-AES: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } /* encrypt incremental */ for (y = 0; y < x; y++) { buf[y] = y & 255; } if ((err = lrw_encrypt(buf, buf, x, &lrw)) != CRYPT_OK) { fprintf(stderr, "Error encrypting with LRW-AES: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } /* display it */ fprintf(out, "%d:", x); for (y = 0; y < x; y++) { fprintf(out, "%02x", buf[y]); } fprintf(out, "\n"); /* reset IV */ if ((err = lrw_setiv(iv, 16, &lrw)) != CRYPT_OK) { fprintf(stderr, "Error setting IV: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } /* copy new tweak, iv and key */ for (y = 0; y < 16; y++) { key[y] = buf[y]; iv[y] = buf[(y+16)%x]; tweak[y] = buf[(y+32)%x]; } if ((err = lrw_decrypt(buf, buf, x, &lrw)) != CRYPT_OK) { fprintf(stderr, "Error decrypting with LRW-AES: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } /* display it */ fprintf(out, "%d:", x); for (y = 0; y < x; y++) { fprintf(out, "%02x", buf[y]); } fprintf(out, "\n"); lrw_done(&lrw); } fclose(out); } int main(void) { reg_algs(); printf("Generating hash vectors..."); fflush(stdout); hash_gen(); printf("done\n"); printf("Generating cipher vectors..."); fflush(stdout); cipher_gen(); printf("done\n"); printf("Generating LTC_HMAC vectors..."); fflush(stdout); hmac_gen(); printf("done\n"); printf("Generating LTC_OMAC vectors..."); fflush(stdout); omac_gen(); printf("done\n"); printf("Generating PMAC vectors..."); fflush(stdout); pmac_gen(); printf("done\n"); printf("Generating EAX vectors..."); fflush(stdout); eax_gen(); printf("done\n"); printf("Generating OCB vectors..."); fflush(stdout); ocb_gen(); printf("done\n"); printf("Generating CCM vectors..."); fflush(stdout); ccm_gen(); printf("done\n"); printf("Generating GCM vectors..."); fflush(stdout); gcm_gen(); printf("done\n"); printf("Generating LTC_BASE64 vectors..."); fflush(stdout); base64_gen(); printf("done\n"); printf("Generating MATH vectors..."); fflush(stdout); math_gen(); printf("done\n"); printf("Generating ECC vectors..."); fflush(stdout); ecc_gen(); printf("done\n"); printf("Generating LRW vectors..."); fflush(stdout); lrw_gen(); printf("done\n"); return 0; } /* $Source: /cvs/libtom/libtomcrypt/demos/tv_gen.c,v $ */ /* $Revision: 1.21 $ */ /* $Date: 2007/05/12 14:37:41 $ */ libtomcrypt-1.17/demos/multi.c0000644000175100001440000001035510621351501015134 0ustar tomusers/* test the multi helpers... */ #include int main(void) { unsigned char key[16], buf[2][MAXBLOCKSIZE]; unsigned long len, len2; /* register algos */ register_hash(&sha256_desc); register_cipher(&aes_desc); /* HASH testing */ len = sizeof(buf[0]); hash_memory(find_hash("sha256"), (unsigned char*)"hello", 5, buf[0], &len); len2 = sizeof(buf[0]); hash_memory_multi(find_hash("sha256"), buf[1], &len2, (unsigned char*)"hello", 5, NULL); if (len != len2 || memcmp(buf[0], buf[1], len)) { printf("Failed: %d %lu %lu\n", __LINE__, len, len2); return EXIT_FAILURE; } len2 = sizeof(buf[0]); hash_memory_multi(find_hash("sha256"), buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL, 0); if (len != len2 || memcmp(buf[0], buf[1], len)) { printf("Failed: %d %lu %lu\n", __LINE__, len, len2); return EXIT_FAILURE; } len2 = sizeof(buf[0]); hash_memory_multi(find_hash("sha256"), buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL); if (len != len2 || memcmp(buf[0], buf[1], len)) { printf("Failed: %d %lu %lu\n", __LINE__, len, len2); return EXIT_FAILURE; } /* LTC_HMAC */ len = sizeof(buf[0]); hmac_memory(find_hash("sha256"), key, 16, (unsigned char*)"hello", 5, buf[0], &len); len2 = sizeof(buf[0]); hmac_memory_multi(find_hash("sha256"), key, 16, buf[1], &len2, (unsigned char*)"hello", 5UL, NULL); if (len != len2 || memcmp(buf[0], buf[1], len)) { printf("Failed: %d %lu %lu\n", __LINE__, len, len2); return EXIT_FAILURE; } len2 = sizeof(buf[0]); hmac_memory_multi(find_hash("sha256"), key, 16, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL); if (len != len2 || memcmp(buf[0], buf[1], len)) { printf("Failed: %d %lu %lu\n", __LINE__, len, len2); return EXIT_FAILURE; } len2 = sizeof(buf[0]); hmac_memory_multi(find_hash("sha256"), key, 16, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL); if (len != len2 || memcmp(buf[0], buf[1], len)) { printf("Failed: %d %lu %lu\n", __LINE__, len, len2); return EXIT_FAILURE; } /* LTC_OMAC */ len = sizeof(buf[0]); omac_memory(find_cipher("aes"), key, 16, (unsigned char*)"hello", 5, buf[0], &len); len2 = sizeof(buf[0]); omac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"hello", 5UL, NULL); if (len != len2 || memcmp(buf[0], buf[1], len)) { printf("Failed: %d %lu %lu\n", __LINE__, len, len2); return EXIT_FAILURE; } len2 = sizeof(buf[0]); omac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL); if (len != len2 || memcmp(buf[0], buf[1], len)) { printf("Failed: %d %lu %lu\n", __LINE__, len, len2); return EXIT_FAILURE; } len2 = sizeof(buf[0]); omac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL); if (len != len2 || memcmp(buf[0], buf[1], len)) { printf("Failed: %d %lu %lu\n", __LINE__, len, len2); return EXIT_FAILURE; } /* PMAC */ len = sizeof(buf[0]); pmac_memory(find_cipher("aes"), key, 16, (unsigned char*)"hello", 5, buf[0], &len); len2 = sizeof(buf[0]); pmac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"hello", 5, NULL); if (len != len2 || memcmp(buf[0], buf[1], len)) { printf("Failed: %d %lu %lu\n", __LINE__, len, len2); return EXIT_FAILURE; } len2 = sizeof(buf[0]); pmac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"he", 2UL, "llo", 3UL, NULL); if (len != len2 || memcmp(buf[0], buf[1], len)) { printf("Failed: %d %lu %lu\n", __LINE__, len, len2); return EXIT_FAILURE; } len2 = sizeof(buf[0]); pmac_memory_multi(find_cipher("aes"), key, 16, buf[1], &len2, (unsigned char*)"h", 1UL, "e", 1UL, "l", 1UL, "l", 1UL, "o", 1UL, NULL); if (len != len2 || memcmp(buf[0], buf[1], len)) { printf("Failed: %d %lu %lu\n", __LINE__, len, len2); return EXIT_FAILURE; } printf("All passed\n"); return EXIT_SUCCESS; } /* $Source: /cvs/libtom/libtomcrypt/demos/multi.c,v $ */ /* $Revision: 1.4 $ */ /* $Date: 2007/05/12 14:37:41 $ */ libtomcrypt-1.17/demos/test.c0000644000175100001440000000340210621351501014754 0ustar tomusers#include int main(void) { int x; reg_algs(); #ifdef USE_LTM ltc_mp = ltm_desc; #elif defined(USE_TFM) ltc_mp = tfm_desc; #elif defined(USE_GMP) ltc_mp = gmp_desc; #else extern ltc_math_descriptor EXT_MATH_LIB; ltc_mp = EXT_MATH_LIB; #endif printf("build == \n%s\n", crypt_build_settings); printf("\nstore_test...."); fflush(stdout); x = store_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); printf("\ncipher_test..."); fflush(stdout); x = cipher_hash_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); printf("\nmodes_test...."); fflush(stdout); x = modes_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); printf("\nder_test......"); fflush(stdout); x = der_tests(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); printf("\nmac_test......"); fflush(stdout); x = mac_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); printf("\npkcs_1_test..."); fflush(stdout); x = pkcs_1_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); printf("\nrsa_test......"); fflush(stdout); x = rsa_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); printf("\necc_test......"); fflush(stdout); x = ecc_tests(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); printf("\ndsa_test......"); fflush(stdout); x = dsa_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); printf("\nkatja_test...."); fflush(stdout); x = katja_test(); printf(x ? "failed" : "passed");if (x) exit(EXIT_FAILURE); printf("\n"); return EXIT_SUCCESS; } /* $Source: /cvs/libtom/libtomcrypt/demos/test.c,v $ */ /* $Revision: 1.28 $ */ /* $Date: 2006/05/25 10:50:08 $ */ libtomcrypt-1.17/demos/timing.c0000644000175100001440000000120610621351501015264 0ustar tomusers#include int main(void) { init_timer(); reg_algs(); #ifdef USE_LTM ltc_mp = ltm_desc; #elif defined(USE_TFM) ltc_mp = tfm_desc; #elif defined(USE_GMP) ltc_mp = gmp_desc; #else extern ltc_math_descriptor EXT_MATH_LIB; ltc_mp = EXT_MATH_LIB; #endif time_keysched(); time_cipher(); time_cipher2(); time_cipher3(); time_cipher4(); time_hash(); time_macs(); time_encmacs(); time_prng(); time_mult(); time_sqr(); time_rsa(); time_ecc(); #ifdef USE_LTM time_katja(); #endif return EXIT_SUCCESS; } /* $Source: /cvs/libtom/libtomcrypt/demos/timing.c,v $ */ /* $Revision: 1.61 $ */ /* $Date: 2006/12/03 03:08:35 $ */ libtomcrypt-1.17/notes/0000755000175100001440000000000010621351501013653 5ustar tomuserslibtomcrypt-1.17/notes/etc/0000755000175100001440000000000010621351501014426 5ustar tomuserslibtomcrypt-1.17/notes/etc/saferp_optimizer.c0000644000175100001440000001774110621351501020166 0ustar tomusers/* emits an optimized version of LTC_SAFER+ ... only does encrypt so far... */ #include #include /* This is the "Armenian" Shuffle. It takes the input from b and stores it in b2 */ #define SHUF\ b2[0] = b[8]; b2[1] = b[11]; b2[2] = b[12]; b2[3] = b[15]; \ b2[4] = b[2]; b2[5] = b[1]; b2[6] = b[6]; b2[7] = b[5]; \ b2[8] = b[10]; b2[9] = b[9]; b2[10] = b[14]; b2[11] = b[13]; \ b2[12] = b[0]; b2[13] = b[7]; b2[14] = b[4]; b2[15] = b[3]; memcpy(b, b2, sizeof(b)); /* This is the inverse shuffle. It takes from b and gives to b2 */ #define iSHUF(b, b2) \ b2[0] = b[12]; b2[1] = b[5]; b2[2] = b[4]; b2[3] = b[15]; \ b2[4] = b[14]; b2[5] = b[7]; b2[6] = b[6]; b2[7] = b[13]; \ b2[8] = b[0]; b2[9] = b[9]; b2[10] = b[8]; b2[11] = b[1]; \ b2[12] = b[2]; b2[13] = b[11]; b2[14] = b[10]; b2[15] = b[3]; memcpy(b, b2, sizeof(b)); #define ROUND(b, i) \ b[0] = (safer_ebox[(b[0] ^ skey->saferp.K[i][0]) & 255] + skey->saferp.K[i+1][0]) & 255; \ b[1] = safer_lbox[(b[1] + skey->saferp.K[i][1]) & 255] ^ skey->saferp.K[i+1][1]; \ b[2] = safer_lbox[(b[2] + skey->saferp.K[i][2]) & 255] ^ skey->saferp.K[i+1][2]; \ b[3] = (safer_ebox[(b[3] ^ skey->saferp.K[i][3]) & 255] + skey->saferp.K[i+1][3]) & 255; \ b[4] = (safer_ebox[(b[4] ^ skey->saferp.K[i][4]) & 255] + skey->saferp.K[i+1][4]) & 255; \ b[5] = safer_lbox[(b[5] + skey->saferp.K[i][5]) & 255] ^ skey->saferp.K[i+1][5]; \ b[6] = safer_lbox[(b[6] + skey->saferp.K[i][6]) & 255] ^ skey->saferp.K[i+1][6]; \ b[7] = (safer_ebox[(b[7] ^ skey->saferp.K[i][7]) & 255] + skey->saferp.K[i+1][7]) & 255; \ b[8] = (safer_ebox[(b[8] ^ skey->saferp.K[i][8]) & 255] + skey->saferp.K[i+1][8]) & 255; \ b[9] = safer_lbox[(b[9] + skey->saferp.K[i][9]) & 255] ^ skey->saferp.K[i+1][9]; \ b[10] = safer_lbox[(b[10] + skey->saferp.K[i][10]) & 255] ^ skey->saferp.K[i+1][10]; \ b[11] = (safer_ebox[(b[11] ^ skey->saferp.K[i][11]) & 255] + skey->saferp.K[i+1][11]) & 255; \ b[12] = (safer_ebox[(b[12] ^ skey->saferp.K[i][12]) & 255] + skey->saferp.K[i+1][12]) & 255; \ b[13] = safer_lbox[(b[13] + skey->saferp.K[i][13]) & 255] ^ skey->saferp.K[i+1][13]; \ b[14] = safer_lbox[(b[14] + skey->saferp.K[i][14]) & 255] ^ skey->saferp.K[i+1][14]; \ b[15] = (safer_ebox[(b[15] ^ skey->saferp.K[i][15]) & 255] + skey->saferp.K[i+1][15]) & 255; int main(void) { int b[16], b2[16], x, y, z; /* -- ENCRYPT --- */ for (x = 0; x < 16; x++) b[x] = x; /* emit encrypt preabmle */ printf( "void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)\n" "{\n" " int x;\n" " unsigned char b[16];\n" "\n" " LTC_ARGCHK(pt != NULL);\n" " LTC_ARGCHK(ct != NULL);\n" " LTC_ARGCHK(skey != NULL);\n" "\n" " /* do eight rounds */\n" " for (x = 0; x < 16; x++) {\n" " b[x] = pt[x];\n" " }\n"); /* do 8 rounds of ROUND; LT; */ for (x = 0; x < 8; x++) { /* ROUND(..., x*2) */ for (y = 0; y < 16; y++) { printf("b[%d] = (safer_%cbox[(b[%d] %c skey->saferp.K[%d][%d]) & 255] %c skey->saferp.K[%d][%d]) & 255;\n", b[y], "elle"[y&3], b[y], "^++^"[y&3], x*2, y, "+^^+"[y&3], x*2+1, y); } /* LT */ for (y = 0; y < 4; y++) { printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[0], b[0], b[1], b[0], b[1]); printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[2], b[2], b[3], b[3], b[2]); printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[4], b[4], b[5], b[5], b[4]); printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[6], b[6], b[7], b[7], b[6]); printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[8], b[8], b[9], b[9], b[8]); printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[10], b[10], b[11], b[11], b[10]); printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[12], b[12], b[13], b[13], b[12]); printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[14], b[14], b[15], b[15], b[14]); if (y < 3) { SHUF; } } } printf( " if (skey->saferp.rounds <= 8) {\n"); /* finish */ for (x = 0; x < 16; x++) { printf( " ct[%d] = (b[%d] %c skey->saferp.K[skey->saferp.rounds*2][%d]) & 255;\n", x, b[x], "^++^"[x&3], x); } printf(" return;\n }\n"); /* 192-bit keys */ printf( " /* 192-bit key? */\n" " if (skey->saferp.rounds > 8) {\n"); /* do 4 rounds of ROUND; LT; */ for (x = 8; x < 12; x++) { /* ROUND(..., x*2) */ for (y = 0; y < 16; y++) { printf("b[%d] = (safer_%cbox[(b[%d] %c skey->saferp.K[%d][%d]) & 255] %c skey->saferp.K[%d][%d]) & 255;\n", b[y], "elle"[y&3], b[y], "^++^"[y&3], x*2, y, "+^^+"[y&3], x*2+1, y); } /* LT */ for (y = 0; y < 4; y++) { printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[0], b[0], b[1], b[0], b[1]); printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[2], b[2], b[3], b[3], b[2]); printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[4], b[4], b[5], b[5], b[4]); printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[6], b[6], b[7], b[7], b[6]); printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[8], b[8], b[9], b[9], b[8]); printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[10], b[10], b[11], b[11], b[10]); printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[12], b[12], b[13], b[13], b[12]); printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[14], b[14], b[15], b[15], b[14]); if (y < 3) { SHUF; } } } printf("}\n"); printf( " if (skey->saferp.rounds <= 12) {\n"); /* finish */ for (x = 0; x < 16; x++) { printf( " ct[%d] = (b[%d] %c skey->saferp.K[skey->saferp.rounds*2][%d]) & 255;\n", x, b[x], "^++^"[x&3], x); } printf(" return;\n }\n"); /* 256-bit keys */ printf( " /* 256-bit key? */\n" " if (skey->saferp.rounds > 12) {\n"); /* do 4 rounds of ROUND; LT; */ for (x = 12; x < 16; x++) { /* ROUND(..., x*2) */ for (y = 0; y < 16; y++) { printf("b[%d] = (safer_%cbox[(b[%d] %c skey->saferp.K[%d][%d]) & 255] %c skey->saferp.K[%d][%d]) & 255;\n", b[y], "elle"[y&3], b[y], "^++^"[y&3], x*2, y, "+^^+"[y&3], x*2+1, y); } /* LT */ for (y = 0; y < 4; y++) { printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[0], b[0], b[1], b[0], b[1]); printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[2], b[2], b[3], b[3], b[2]); printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[4], b[4], b[5], b[5], b[4]); printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[6], b[6], b[7], b[7], b[6]); printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[8], b[8], b[9], b[9], b[8]); printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[10], b[10], b[11], b[11], b[10]); printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[12], b[12], b[13], b[13], b[12]); printf(" b[%d] = (b[%d] + (b[%d] = (b[%d] + b[%d]) & 255)) & 255;\n", b[14], b[14], b[15], b[15], b[14]); if (y < 3) { SHUF; } } } /* finish */ for (x = 0; x < 16; x++) { printf( " ct[%d] = (b[%d] %c skey->saferp.K[skey->saferp.rounds*2][%d]) & 255;\n", x, b[x], "^++^"[x&3], x); } printf(" return;\n"); printf(" }\n}\n\n"); return 0; } /* $Source: /cvs/libtom/libtomcrypt/notes/etc/saferp_optimizer.c,v $ */ /* $Revision: 1.3 $ */ /* $Date: 2007/05/12 14:20:27 $ */ libtomcrypt-1.17/notes/etc/whirlgen.c0000644000175100001440000000403010621351501016406 0ustar tomusers#include unsigned E[16] = { 1, 0xb, 9, 0xc, 0xd, 6, 0xf, 3, 0xe, 8, 7, 4, 0xa, 2, 5, 0 }; unsigned Ei[16]; unsigned R[16] = { 7, 0xc, 0xb, 0xd, 0xe, 4, 9, 0xf, 6, 3, 8, 0xa, 2, 5, 1, 0 }; unsigned cir[8][8] = { {1, 1, 4, 1, 8, 5, 2, 9 }, }; unsigned gf_mul(unsigned a, unsigned b) { unsigned r; r = 0; while (a) { if (a & 1) r ^= b; a >>= 1; b = (b << 1) ^ (b & 0x80 ? 0x11d : 0x00); } return r; } unsigned sbox(unsigned x) { unsigned a, b, w; a = x >> 4; b = x & 15; a = E[a]; b = Ei[b]; w = a ^ b; w = R[w]; a = E[a ^ w]; b = Ei[b ^ w]; return (a << 4) | b; } int main(void) { unsigned x, y; for (x = 0; x < 16; x++) Ei[E[x]] = x; // for (x = 0; x < 16; x++) printf("%2x ", sbox(x)); for (y = 1; y < 8; y++) { for (x = 0; x < 8; x++) { cir[y][x] = cir[y-1][(x-1)&7]; } } /* printf("\n"); for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) printf("%2d ", cir[y][x]); printf("\n"); } */ for (y = 0; y < 8; y++) { printf("static const ulong64 sbox%d[] = {\n", y); for (x = 0; x < 256; ) { printf("CONST64(0x%02x%02x%02x%02x%02x%02x%02x%02x)", gf_mul(sbox(x), cir[y][0]), gf_mul(sbox(x), cir[y][1]), gf_mul(sbox(x), cir[y][2]), gf_mul(sbox(x), cir[y][3]), gf_mul(sbox(x), cir[y][4]), gf_mul(sbox(x), cir[y][5]), gf_mul(sbox(x), cir[y][6]), gf_mul(sbox(x), cir[y][7])); if (x < 255) printf(", "); if (!(++x & 3)) printf("\n"); } printf("};\n\n"); } printf("static const ulong64 cont[] = {\n"); for (y = 0; y <= 10; y++) { printf("CONST64(0x"); for (x = 0; x < 8; x++) { printf("%02x", sbox((8*y + x)&255)); } printf("),\n"); } printf("};\n\n"); return 0; } /* $Source: /cvs/libtom/libtomcrypt/notes/etc/whirlgen.c,v $ */ /* $Revision: 1.2 $ */ /* $Date: 2005/05/05 14:35:58 $ */ libtomcrypt-1.17/notes/etc/whirltest.c0000644000175100001440000000061510621351501016621 0ustar tomusers#include int main(void) { char buf[4096]; int x; while (fgets(buf, sizeof(buf)-2, stdin) != NULL) { for (x = 0; x < 128; ) { printf("0x%c%c, ", buf[x], buf[x+1]); if (!((x += 2) & 31)) printf("\n"); } } } /* $Source: /cvs/libtom/libtomcrypt/notes/etc/whirltest.c,v $ */ /* $Revision: 1.2 $ */ /* $Date: 2005/05/05 14:35:58 $ */ libtomcrypt-1.17/notes/lrw_tv.txt0000644000175100001440000037515410621351501015750 0ustar tomusers16:931b40b97cd1d1338d4a4abdf96d1f45 16:000102030405060708090a0b0c0d0e0f 32:85e82fe5e8b426cf04bd96d9aed318fb5dae89a1dfb854a09f556b61c5ac918b 32:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f 48:dd7aad6c6d10176e25eb97e165ba612a2b6275d97667102f20af20ec2630c7ccb4f5772a3e009948f1ea91f3bbaf7e04 48:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f 64:338509ed021eecd249cb15cdd440a84ff9d6704b99e8e52e9d057f152b742a5e3b9c314574026c76fc887fb404a12d669eea9460c1fa08e1867c2c0274408b9e 64:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f 80:8a9cbff36874de7da3e20e9a26691eef944ff78a72341515ae20c2199688ff92f039a19dc6d517e017ef36647834debee90bf80ba20a7caf24964bcb0bb3a621f8203ce5428461d3ee72ead7aeb201a9 80:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f 96:06eb66a88b9667296b8644cda3464a27e3e2d8b6b3d0a9ffbebfd48f3967952ce161d8867900b0a7a44638a6e41b9a9dc53bf183a85a4ee33bb6f6c2d64b8cb54bfbb8625ff5cd3965aa08b460737b575da0b8f4123751cf8f0ae801c5856712 96:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f 112:7af5a2b1381a8bc5aa2bdd4370b88d680c34ba9332d1d9f6e203c4d9fdbf5ece39fe5afb5871490a180c4b102665823dabe1079656f24969bf84267d3264f92cbbc610f26203536d387333938d1a52f4076df1aa0a114f3b0182da12c3a5d87bdc8eff54f80b0d56f7044ba372ee6366 112:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f 128:814fe82674b98d54671869e3fd705f76e353761bf61cfc635fbb23037d8a0e0dfc13c6c0e34f8c79d4444ac314d4918773265b3fb5866a997e270d5ea8891f0217ec6749df281d790dfbbec8adc504404cc0a6f11e91d0ee6c19abdc67b0c22ea4d9fa218320a694dca53cf522c761e426e0cd57e49b73a5d765cb4bc571e888 128:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f 144:9fab9584b0dd87df42f07513edad3b5e3a35b8871323eed63a48ded1efe4308a9883579f3a7ab830277bda59b1f1c2614a2cabe11cdd87689c0bae80ebad02b76d9300703d0268e0eb052d9956c5648912843b16be988134cfaf65fa87013ab960b190afea879897f1fdd00b360b6bfc6cc3531285682894b707af5914d2d1a136407f869ae6672e096ad7e95f380d53 144:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f 160:95aa16e637f1449d9012237f5fd95a57c5a9e203ca0a9393975e5991cc568f7ad2af3266ab605915af277f4395aa312586fb28a18f22d1644963233e1121472980229a3941c2f24758a51c48aa22b61fa4310ed2e6175a71bd4058cdb070f2b8289a46a39636dbe259eeff3c87f96fc8d46961aac54d7a8491b5d713e6cc0d6551b9e90911947d9fd15051badf67420188c450f9916c2edae245f1f6a67e4f5c 160:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f 176:5cb782dd9e2391ab54378121d0766afe6d35ecef7a2cbd85ab04ea82b06b56ddabd311917093ff16bc1857480f84049d89ec6694414617b1cf3a11778c1ccbf22b81be5f07ed6f978df5089e54561fec53de95205ffa7d573092688fce92cae228f342f77c50df87404d502a9b274bbf3cfcaf4e94a1e8401630e18b79d048a5f3901abe82493d911d385890405bcaf4d5981def670955e95c546da8939aa68aefda56b37abd3bdcd466605f9bcc5931 176:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf 192:e9a7781c750910f265e72edf0659d76a0db2dab863f43ca313b9e67e8f9f97a1ad8ced641c6d8d889ed2d38caa7887ec2eb9242093b39d4633702731b96e11da52b1a9a584d2367e6a0e759baf902eb908b4432ffecd367ff1fde454d4af844e9a10cb260ae222446c179dcc82b5f767b941f75196e8c4b210315d01b006fa6b5f1faf931549044b17b33f567b729ddea115c7b11c90982e1480101e98aab23da6533b40777971b4afc3815d063ef175419dd72bddcdc6bb187b3512c3bff56e 192:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf 208:8fd33ac16f8d9bd2ab24d1d26b267f67222b9309d697502bd001bb48b8c3206bd5c98cc1cff788633cda4edb5aaed2055435c2c092a7c655455d1d01a6d7a449df870dd559e9bae1e0fb0d6e5a98679402c288b87cbda569c3503b4aa9403f80c835c995e3b47e33c1c5b8321e8db1b72955ccbdf640c78aac376ec449396b163b8d16b51b0749fab6ba71d0b563fef6e94702f35ff2ed180f0de1f86679d8f2a26b2b9d8adffc7ad11c5944118e30025c9be26431f130aa2bc238e4b0104ddf9f82630ab7eea590bd7eabb2da745ffa 208:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecf 224:ac2daa6b330224b6f146ad67edebacd98cd2269d0cb313fde49d85ad60f9b21c9926d411fd435be8bd073d294e905acfccea2708f98e05cc9ded3c77e684b671bdc59deff3b43fb931381b12133ce386a0314a939d6c4855bbb7765adf955f4e587bebaf6d3b8cf547b2feda60c326e3409833665f61d91a2451ca2693bad6779094e010a3804993d6078c1ac3c2d26d589a8b3376dd06241b3139d2ae603ae5c4829c297f09a5c535c37998f571b0e96855e7a708d7b2ac42659050547c7bd447bbebad92e98b203ce6e83bab8e94f232417152ac6bfe8f9982012c8f83c674 224:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf 240:5c4d34448cf5b5b385a8aa9e504d724e6e689a35ff36143c20fa16df16f74347df6b65ef354c094732fe1b31e454e319a7be20dc6df4b900dd6527feb5b7c81a7a40df73d513cd40a5e1acfda4ba9e4fed784bb26b2719899c60a54bd8c772f17c95e6100c6def216c9c612a10db62a576cf45392c68736466305f6cb86f218f57b033c3773d0cdd9827f822cd480b60f94d32b28f536e6f0464e63e84294f0c3ab088dbf0efcf95b020f4c2ddc72c5823c2182025cfda510e1a944ac9316f0ceaba7dbd116cef95e051ca9143eebd575ce53c26cab9aa897167d500fcbe229560a85c98e83385ca6befa90726e768b4 240:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeef 256:46d31a1a6fccbff0435e1811a4851746df2af5772dd0408fbca2b3603cc4f92f778dec8f14daaa6f081500de55d036b3680a8a9b6c50bc20eebf09e35036bdef9b3751167e807cd1aa70385ea9f4be42ef4de6211079eb0cd6c3810404a60f09dd4e98cccb09c356e6b4c4cc1da036bc82023b075011cad2d01bf95fc45829c7af484f92562c2579bd3b4dba3967d5c6bfdb3e2236c2b43655e6393cdce8a2cca0affb8e45e8545aaf04049c2789108ac5bc6bceba18bcb9d4944ed81a64ab43e28e28207268464b99dad7328db0059defa25a722cbfaf89e93a20768bbce91b64f395a379ba5580a2ca4ab2d978c6ed3aedc9f53896bdc28aa5f1300473a3df 256:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff 272:96a46190ac8c56cb272488d1db3a6153a4be7a298f200eecd42b0657e7110e879ddaf12a782d3f946a283f23fd5fd98ddce5874ea645e6581284d94c5437a4737921fd1504fded721d9a12c9bac8d8feda0b1a32a5a04e3602dd3befaebb161af6df1590d280ce09fd99e551ab39351dff8cd85dc084920a21f49e726bafdfc75e1cd2c42fc8789edf52adcb8b8f87b0b7c89c7e80fb8a14807c96912fa125395d71f631cc3181cccbf435da014e47c4dd25640cf7953787c3fa2e9de4a867d61cc398724a94b584ed336715ec92a562215bf36c193cf2356973e60b858d3f97a944d12a40173218f0bd2e565833581e51bee580e3b3430b3d41d6d6788b73ebb45a22a548456f393f24999c40136688 272:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f 288:4ea9644990536525105792b735e1a9adaabf7542f8d30f41553f756b33fa90051352939fe2693be9e5e482f9a2fd0ea00ec85abb01a56780b61609ac1364b22b2a1f7b061317995c1d2a8bdd280a7735d1191aa6c546516713577093f17b5696c9f2a2b94b766b5a9d2551891a5c17530bf953aa1dbec6a9560054534163c26973399b128156af6a257e0c591b279ff376d0e2464b06a464bc5e5f3d4ca309ddb9fc96d8c59efe0027389e25aca9106b4a6c0e8e3726e26470f0aa59ecbb1022953312bf5a09db75728ce455f63bd328437622bc61dc5f703e7e0d49a27ccc1fa25439848a1349c7790d1920f465151318c3d27855bd953231981eb903bde19906667d26900e2c233330fa0b6c157db37d5b7c76fdfa7a7e1606045e9a18a0b9 288:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f 304:53ef1d7350ca9c52f3d53b1f3097919a4e49bc48d2e63c571abac2f19f16084b16308dd8cf96f374fafbd1ac7b3f9cf3b9c62af25563ff09f419c94f0530d43ddda8396d99010c861c92d59b3d03bb8423eea55044053b06be07fdab392cff5f85be8119ce3e3783cd03923d28bd6cbecd5620fc2465a9f2b1a0850e4a6f35c1893819b689387e5bd2449aaf8b1497a598a48595030a00b92ce357509f259690823c0d1b710edb36cae8b7653afc183f54b1955a56db65929df6b29880e99eb68581f1e41141ee697c1fa565f0d674a2b9f1e88c3f370d1d5c564547370e73e2f475f52eda167bccbcc19405e1cdd24c13ac25bcfa3f7dd65e233e059b18fb420bdb52969816548bca83ae9d392b8ba1eece0faea2a4d965e46e38c3acdb00466892c1be69ed0e73ad80beee0cbe6d2b 304:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f 320:577d305d82d993adb3fbf1e91bbfcd6d9fd9b7872420dc418825ff0bc791b12dcc5fb56f0a4396131f989cebb7b07b67f6365bf120b15cdf7c856e4ffdecff571bc8b04a10328811401ced98c14b92d667d89ef0f413d2472d039931c33570bef3db3485b4f018bdc771ecad8cdca1ace0ec948591e98ce1e037d33ce00326452fddfc70a340c73b0886b43dd0e9203c11c025af0aa2ef3e3538893d6716574f242657cf1bfdf6d8ca3fabb982866d04554d74a9495f178b5bb68d2c2d026b82a1d65a2a63a5527710c305d6b54e830baa18f692dc0f29815b7eeb717c08d49b696af80db2c05481aa077e52420cbd1ec47c99aa82a0bb730a85bff1a8000c1735af09ac45ad3d0088eaf52f5d42ba1337dfe3ae956d6d7899ac949028ec0f5884ae58d949099505dc9576d204702d9b25a172f81a041fea4e8744605ff0dcb5 320:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f 336:cf3c36fbf2b8d72b6e9e8e9ec871117b2d4dc814e3204a5aa223136f8fb8218245dcf03cd81de80a4d35fc5d0a4f8a31a2872d3c1acdab0846c89bbc8db6f31436741f6e3f21cc1f783bf4eeea9b29415eab9c1d6ed94dbd391a13ba98a851ee0646a378a8d1b25d56de83049fa5ffb33ed2c5f60c6588eaf8e6b374c43cf1aac153dd63951aab2ef10923889af3192bf2adf9eaad048eb8ee3f81916eb589974b5152226c5d1e6f516a82e8acfccbb46ab14d5b901a4b9ad23c3310b0a2d30f0d88d0852e67fd7391c64b9e57800d62d81695d9450e135c9d193fc0efcc8f774e0fab020dff5d0a28390dd4d629f5492a544fcf04811f2b0e3a64d33c5eabc43a22a97c698390d53789935aab90808b091211609a5834ee60da7af6cce5cfe9dcdb438b9e8bf60706696d0a95c5e6bfd25921dee98c47de5d7e4cf5101fc994b062fd2dd01a176358113bafa404bbc8 336:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f 352:7dfc531b8d9b4f8a084ef0f6bca81ccedb88d13f899c64ddae54611d76a0f77ca27d3745860c79bc944eb854738a1c5a1d23491d19a20f7fef3ac6391798360eb210874cec1cedeef549726e533b223a3f3b14d4bdad059920910279ceb49e70c87a84f1901125327a9929f238f5361099425afa5d826c82253d94d83cd291947a7d54dde88aac734d1df8de1f125fa02b6b0983cd8674bf529c97929b56a5ba681c7279461575a7568c7b9518d95e6ea8faa6ab6b4dca7874dda2c8d2cc72577dd67744873da145bce25593511d0bc3d67bf5cb61f9ac53e04701a1a448e80d692fb46651e45b65dae90994c91b83ba4c1ec9f7945187b9e7c31e870401f5ec8322d0a686fc2f9559279de992171957719004de602a7da9ab63a902fad8313b60fd883781aeb1c8d5b99c73e417c821f75859bbaafad40ab85098dae356c996f4274b198536262b2d26b22216e79ff3fc707fd197e1f39bdfb9acb6214d9196 352:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f 368:100e6e817ed865757039f75eb6d15c16c5478784eb9dc70f60e3b900f60fa925404e09e2cfc0450bc89bce115fef62de782a2d7725970e7fe8226122c1ff9ccf142275d4f37d011ca3aad5700e2e8a8d27c7553e59f8173c8117d813e4d237bf906e3499306fd5bee0fbae137a372807caae0619caee51039049a09066b62953fc5bf1213dac7da86b4418cf3bbfe046c1b9fedb6045ccbf25617ea52e2b6fe2cf9a52ed371f864197fbb3ccd27ff2d0e2e7285e29b21632111d2ebea0c8f1a216779aaef98346b84f54fafe46ee3128020434d0fb1291e07c53bdb236e3f476199647bd7366a72dcdb5484e2439257ddc5b2d77b3c033e068c32288d94a72f2c6562c7e1727e4f60fa41a75f5561c4c15d5997db99471ff68b085b39d5107003927dce0060b1926ed8e9144a6ba6d907ecf037f8006936ba536513fb8122b82214162b7735a16f72ffc4773c32c9d694827c3c2ecddf742766d2b742ffba674a04c3700ea52988f6e265925cdcf4ef5 368:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f 384:0e2a132eca216076665bab6f3d1f222a9b502a4830e7a67be3330fb4a4cbc1f2ba2c3891ffd67cca8514739848cd90354e99e489235f380b3727e74467b5579ab2c3661054eac7f9413fe1f5f9b8b54f25b9eec5f693025d300bc70c607f074b640764d91230a6a9753bc403a17009e201cb96b57020b527d48943436e4fb717a5c5ab027e239cb508115244f1ba975861c0beebbfa6a7ff1e47ae135eb2cefdd8976c48ad71ff19549164d22df54044abb8cf86c7281035c00f471514762b6224b2c06cd496e149fe43262c554ba04735df40ae8946a59d87d7bfc4573e5a1cc4bee53a4d33d301503955e405c47cce974a8844ad1990c568dd07dcc1a240dd1dba5f4ce864321967870acf941535926e5d3b511a97924350c9019313a56816a1abc5c51aa96bbfdd2c7837a43320ba964d047fe5d2db2800471679663dbc8afd4fb8ca4d39c5735281b9a668b9dcc46c4f45881a2c9f841dc52f354d706cd32ef5dcb4a9f2cb5c1c7b4fc9e2b56e14fe10a8492f7137e580b6f117d1cae58c 384:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f 400:0195b4bd24e6a6295a3a6ea05ee7717ec07eb6eab50bbac751f66f6a79fc564f7aa1bce8b62b87dc25e7b45d52ff34f4f9d30afd0eb33eedac4eb19241fd80dc05ed8265974d1ed3df48c2e027b77866dbc235536b48ab50f628635a95c4430f8c237d647fd588e0318a5370ee6342eb802c6e584983ec6aace4f486aa05e4ae68da28307cd64f1b9572ba59c0c59ecd198dcae3d6d36e09c80d10c877a88b8779b934c6e39dfe0123c922be796a5d962586b54f6e9fbb467f72534be73c4374a7ec7c34cc1eb3e3934505d9edde91c210697b2e550569bf6a3e1adfc2db5d364336c19ac4dc17e3270601ac88f996a5efbcb2d241a1c7acc8ab4a354533f912c9e51ba898bd41f43486290fa32b36a760de5df0c25d5914f3d56004920c6dc2e1724a95eab88f61cfd154dd47fc8b62702e7780522938fb9c035b494a0ace5a21c09f0cd465a834a61c4c979b093a5d780141cca82324f3dde77f45efbe46d3772831cfa93869d144740bc4d0948bd60df373ea24e4be876b6dc8a338e1853cce36b9415ee9aa9077c4cf9b2d482f70 400:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f 416:5c3985f375cf6cca081dfc118d4460208446d21d3f3d100e883222cabddda538115ccfc37f68739fb6a1649c55fd36412579ad1c66908b87f252cde8ab32386ef68c6205c8994bb7d0f9e0fa5e1e6d8aef7064b0432b1a03b3dd4fea645aea15216c03f58658df21ca8792fd2253a2a889d1b223efbd60e10890676291fedbdc91aff403cb98fcd96de1d1481bb8103f157780ca09ab5490c79fc9c60fe91d5325103441b986af5e9a0e323bdc98150e45a2e7cd20997c58a561c8698a64e7734ada60ad1669160f92c07e56360113adf699c25990d0172cf67fa8e0e4a3687ac23801badd498c7a1a411ffb1f96bdfa5de99d5a4d6faa8feff99f624c396029c5605927ae0b7315dda77d092d6e37ff885669e7e60a823fd06a457785be0a151786fb0a7a3a8b67a4cf47788ff8768e24b38df7338c87c2fe3919e74e923cc8a4a3ab7a21db18ff4672a25d3652be23b4ef02e958a77d7df0254d7d54f6ce0f3a4572ef675782d0a9083c6549304cb302a03b5692137a2fd65f0b5a21eeae19c6535836844445afbbe2a236ec3fe26b7d7615a4171a6900620376bf27db1479 416:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f 432:de81559812d2938cba8075ee1cfb7313173305486f59e53abc00efa276653d6cf200828615a9f51a045ee94017723aa431e0d4252205f8b45afce15d3654fc638bc32744488e97f4f7b9958694d40403bec42a1ca97011cc166580737b6fdd71843b8e9e876793858d5b7a06da8cd7bcaad4ab2db8a5635f3643263c9881a9157e1ad82c2832e5894630dd36cb9c65dd7faf147b57e230b5b94417aa962a3f63bf1594a99adbbedb9c03bb9d1a728614032946ad9743c514948b3e01ba8099954dd5e3a0c157eee3e0038c8254fbedb10c685d89cb0555ea7d3f7bd5bce22431bb274ca8421af1fd9842cc9d8094f2289b6e0f4eaa183f316a203b1aa4e6f8008d8576b5936f715ccc584e4ccf1ae81ba5954ee4f5d78ed17135cb13af0484f3664a6f9639a7440ceffd5ea60cc5f391b7cd7201b0059e3391eab6cee0e9ae0ab7c4b7e6480ce7f315b84d8321ec4d1a33cce3ff8dfcf9b1299cbbfee9a5874ce5a1c1dd89710a3119c1d73bd9795d85ff3a01d88066a7b2377738a2247f3cc02072f0f3ea2e3adf463c157e9d662167422db3824df31c592891474fd4d0268e0c64ee9117f6fa02acbbec532d4f9801 432:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf 448:957c2adc952b9187cc7da773714fcb6fe574a07684c3d5d1e2d633354cfe248406b95f0e9714f276f156d97014cfb35991c359e07464b55ebf67f745168b386bda72f0c2df5a7f830a5e4629303443181cd43cd8d30a415cbce0f503d10a0f63a34eaa3a7ae962111caff5fc33d012549eac997290ee78f4c9cf95c148138b60734cef0612983eb27a160bcf5434bb1e3e6a6c100dd55dff25b04d738bfcedb84ae2a168f3be9711bf74c0c61925b61b321f90bed4018f0798b6aeb99975d26244606e1b5632ad1c1019d0ed0f254273cb6a48494b92e516dd1c90b6e48b407179fb20426ee46a8a0771f1bd67b153bd7625e76ebe052d33137ed1cb8b0574eb7c93176d6ad88c5e4bc47c8c9ef4bd54a46fa8ff32ed284339982a1aafe3752648c55f01f5ea80c419aee39b0590de39f0e34f382e3463bad7b42aa17b5eeb2e5a4ca06e9dc3c254cceb5567acc56fd6848d5d6b259e79452423d1a541c6cbaff928039186f51bf1800d859ed932977df30fe28e00117c1e6e8e77a0bf7ca69e264fcc96c1f75ca677554e9aefd06ce97ce5f0edacd50ef8af9653ec3650dc78693a483cb9686015565ea96fd0c36c13d51af320fb8ca900802ae94fdbcd560e 448:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf 464:1b30a6f0f8275f186d7dc2686794411242cd55389a35c2a8f0d276138b9c1bbd2e12c152def0bcbdc323bd3e3b43fab29cbb67f5ffdf7450acbd8c4844e17b196d68f0ca6c0075bf06b1561432435687a998658d62d2f9945ab9d2a2b9cfd7d4f67bbf4c536ea589faa7a438e3cb0c006a2bbf2f90c139793c6cb41be18b4948841a2d31cff96b25ad0f1377563a4acb28f64efa006834c3335e604d94873e7b8eab583f87c5f4e096bb27f1c1af45eb906953acfd7558c978032624355fb2421a636ac6433e7459b61b0706dac2f4bbcaf18727dea1f6100d34eeed31d2ea2672f9dfc853e408736b1cc03a6485496b6cfccc6f3481b2cd05f5569bb36456970d0289aee8c0442cb85b0659efe9872d5e7eee0218d9da684ed0f11c489b49f5b974d1a397bb31e15a9556dc1447018a4cb40f1e13db643a8769e4be78e22f354390563a7a7334445adc5e70ad26623d248721a0e3b8354e526f573f8a292e7d568e63fa38b48e0a4ce7431e890ed19b3f824cedc84a050d4d2a7818ee26b8ea804700ac840eb4bd3a4c1cc9655380d13a86a69f03f642e7b2337d21116aa7510761704098bde0cd6136cf47858a26e4a11649920fc2cb21a51f2f9330095d9de06b5d72b93a67a59ae3fbaa4652b82c 464:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecf 480:8140b529f455d70afc9ee6018a2e59a1ae060ccc18908f3b0ee9e8efcbd3f0124123252c5a62401b3c30ae2843f4565f19d6f4af186dc35ce11fc8d0d23bde67ac133dea138a5c27712381f148f1756228e0ae06a0795e8fa3e8437f87a6f34db3edd5a679d8b93442e9129ccb3bbd2e79d4e01d57caeeb085b5cf24200150bfa76047b850e96818faabd768ac5e2dfe210846008bd76d956352bcc5600fa77c044ec582c17b8bacbef9075e9f99a2f58fbf8f102825786b6785428f4ac15756c7190ba822ce5c0c571940bf77a22474f8eb6692469a3faf69694301d5c14d92d9995d20afe38b9e58aa6c0bb59dfabdb2aebb0e7b11bd2eba1cfa05ded46cf1dd1cb174dc76ff6784d06f6062fb58a7760284e051cc1ce1144643d902881f1a435130d3a5d7b2442fc03db9896d6d552afc14be38263c63b24659fff6e115b795aa1e1d6415e67637b0bc095de9dc4d464b9cc00dc47cbb55b3b73f3ac03a8ab933be81986e9739c79169e51bb90b1664320193df2368697afc9e02b9d9ca09d7e8710535f512c17ff24e3bfafec233f799999d8be0bc8f460fea79d8459ba17d4efef64cfd90624864fb5b220bc3b77d21a3db10fb626cd8539245398b008c93205254a60c73f9c19f0ed4f4152311ab1743762d859b29af7807fafa815fe9 480:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf 496:569e7fa1c3fb86f2f88b26de0fbbe7332900ef284696d3b04800b0d81d09eaffece090063c472a180f237b2d4e51b2be3f29c361fad95789ef5f1fbb07059133ed74c3cc544032021d98894be3202af6c77e43f55755afe31ac5b9e5d73d1aa8ad059a4efb9fa10f76d88ad0bd792c96f804254566d4c86949027fff96a5d05c673eecb52436737d329298922ebd45d77789104c6b0885e742e45c4d2fd283768377c09a9925b3984828d1a4fc9bc2bc256b28a2aff31a1ead319897441fccc4b8f3f2c82e5c64cd82111de146cdf7652a8147076d828f1c50b67e2d060deecb9bd2b84a8ba13f0a65fea79a0f47af74d3f03207a191e3a5c9087994846cf176063c196b77271c7e8560ab28084fd1e394d9c43b07deab40c48c05eecfc5ba42ec6d36724eb30ffa5e9904318c1242b0b113cf0c7a168da9197abc2a083f371c526b4afdfe1f1424b290fb2bccf48a426c8f321663c767e3708f37fda56968f0b5e787b67d366828a3cc16266268d92c8afdced356463dcaff0ef568c87653a308c12b69649235f7b2eb391f6c54df1e96451419bf412d2ca0f6d34ec92e04b7bc618ccbff4433e687dd147c5b3fdcf4705078adf5d7e370ee992e021329bed281d0c086930a3661541d67d4af188d882ddd020cdb7bd0c65743ff41b6fc7fd75237e02e7d6dd8083afb544080620c41 496:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeef 512:9821b3449869f2cb0ef0a24ecbff9b33a73b3cd54bde63d343c426a36c68d1d166c13d02ca4d65cf78e953361a4d2a4035fcade9f3d35d0ae1cff5b85f1fe5c9f3a9db9dab6c10b8ee7542944c84815ca990bf4bcd7062a8013bf852ff3b781f60e29eb9196f31b0e9cd566b7c906b8d930c4d4f410793c1fdf7c8c8ed913469c2506ccfa1c029f383a9eee5a95f18ffeb1f25084c62d6c9fab1d67213efc1ff08f2a33a20eabb520d6997803ffe382ec2f1879465c8b166b045e8ef6fc27c8182d8969419291fa5641afb45ba1600f512a612e7dfca4f71cd63c5fae50a53fb305650e3805428bfb6689813e342425ac6d5d13c9575b629b9430cbb21bfc41c026fa3f8fcd9677bf9bb7cc14c447706a455e2d5fc90a80ee635fbaa589e2f50d35d1a1d5ded77bd970a1fe32f92fccae831c8e540c5cfbad2162dd0683160f0d614fef933207b4ecb51465ec0063ab31243c9a23a07cf0952b81eb02e628b9e53ed0c27d720f65be8f38b960c0286b8dc58aa11905f3d3c694d364ac0997e6b2e3886a1a11b357ef0b75cadbf77acf015b4cf6bce508f4c27f01048d2f4d811e39ee8501d4fb6d69fbb6159a6ba56629e54e798e872be33c191750168af7a47dfefd989c65f6b2ef8064aef83e2e902f68aa9e10a7d6ac4a2680dd0913aad62b5dbbe2f51b46bf64c950caee3b66f6e7857a64d9ccd4518d955f24a23819615 512:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff 528:f02604963d9dc47382d2b835494b8591deeee437c38d4d23e643ef3d3d3d3d87a6ac3475667a749ee84cac055aa47b531eb22d58cfdcdb395fccd9e34e88ec8dd6d4bdff940e321899b700572badb5e44675f7b425a9c1c1969df684a25ee0974c8a9d5e801b5cd70976a6c5af27937c784f4f8d1c86ae1c265c5cb38ea1ee18bca93ff6019f1927ebe203514bf20548c7efc13cd91fc292e2c9ab9fc014d8371d85a2efae108b2afb8bbafab75e7361c99925a19d83f3d7fa51c0274a7a9796aee7451e783976e679db97baadc4aecbc9d120e01719592e007195dcb7b42439c5403ccdde0ed0ad21a7c5a2798919abe81ff72a2baa033002fe25070e14f3417e7076847e90d21ca9a7fa82b45f62d2340bc2aa729616c83bbbf2a6505f860ceca837c479eead3b18f50f88a63f9582e517b4bf51703e42c3f473f901702d3eb4dc25097169a2fa95729f295200e13d05567e5132268b3939250b8bec170a90bf842c8f2b680fb7dd6bb63bcc1ade151944030c0a58b278d700e3460e9d9a7453f0698de6fe4b3104f048d0d3c2bfd6d71c86d8460b95568df8a493f6e77e1d64b158329bec6ec126a24a1d3cec3beb2749c0d2f2d1c9d03708d0f0a4faf81ab0cc31e31dadba6e7f453f35978d49bd026c145188b042da98795d884256fb7b25f5d6e8ef42c927bb39c921d1e634bc94539076986afc5973e98bbd0e466b2b7e4cfc7831fb0d4da70ab31dd9e1584d 528:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f 544:ab5530701149690a9f3157b9718fb392d2d2c38e57b588c652a9af8580750ef2da9ac7f28442a1a3acc2ddc06e0cca15a6ad8c5a253c0cbb307e7d89ecd6a9d5e72c76f2589e11706713bd0cc4bf524fb5ef3c410eb88e52ec0e52d822f6fe14d744a09ec110171af24ce27a8f116688092d7a7123c2ae144fef01f277876e85bf0bf774350c92c7bfee5977d71f52a0d395003adecddcd92ce6e3a6c73b07786db829396479b10b92938c7b788b897695f74b61bec738526c02865b15ddb8d6a927840fabac0fc2ccbca815ab58689eb73adfb08d6148d9a98e8a5388aa6502458ebf02592178527681a12afacb0e0e1b861347dca374eb38f31d86761b5d933f182cfb3aa48cdcf17f08cb9563ab8928e6472fdf43143454f66b626d4e69b1ea0698a4571387e99fd4ee16faf826c3a5c1110522236345948c594c20e3a61e530dee291b79b7cd0e2b0fe7d0180ba1162bc4b3b1b3280dca81fd5a9ca8a227f77cef89896e5c664a75b787f45e9693147776ca8ec8ed99ced39920b813ae9e1e93214d8cfe5c168ec5f07fca092f6368fd952d0d48a49600fc0b3905486140be1fdbf142d0cc8da446d2ed4b1b42f09f09d3cccb95b50ebbfeff60a1f5bc44a9161ec3bebb94504b70fef1c36035a89a866fb96b12f122d2e5ee5fe85b371223f95664b7737784c0cecea980fa711cc263446be48c07e6da223c4ec856004f99b0b195180187aa73ad3318b7b23c9002590d6b42fc57e9b0891e70406387ed 544:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f 560:dee4d7750f0870bcd16faff4d65a5593f5d86f32a6ad7a519d6b2333e522dccadfab7890d02a6499d6487302aeddf9c52c929486ffb44b9ea9409a940d4486a379b0ed04e00421f6e43e7393f75963e68422ebcb2b87eca211f671dd713d59a6034576a4feb356eff67f33081f7889c684f971a22be68adaceb35d24d1947d7f5a5c03f66f3152dc3bd70f59e172879f50da9038a115986ada1277014958b2b19d8a158c097c3212eab6c6c0e97948ae15f146a245bda2495a5a860da0dea32b7794f77aa4bc91268076649255fb138a4ed831e659a1ab9761e37bc13839d1f419d7cecbb12bfa67c53fde957ef5f5cdf43157517f8021e89eb46df4762cdb992a9285c36b6361561dc469c2e9b5bbf79fdc8779627971e6d6a74e40fb1961933f182a1b270910d7604a680d5bfc2e5f66b6e4098a0b13d4c9b923bb56713012bb63b7a5cd1f9f1a7b42a4e28278e5766a3e484da08a7538fb1b27a15f7eefdb5fe28cf6297d81ce7c464b6f7373783c7d344334beed713e325e1429bd7bfdd1610efa551f0c16a6eee5b787f973a0110754bb681de8d17830996e993a360e1585b12ea8720fdb3227f193a1963f0afa7d59e303c27c70d37392fcdaefd5b85d52c2bbb7f19b3146c2165e35bda3b6c23f16e469281e10bd351a533edc370388a07e63f02b07db8569b8760b7c091529907893133685aec1cabbb8e06752f90490ed49fe4cf5d580c0007ea7e902a71923029237fbcf965859abb2d14f6c89548017eeed6d0d5614d131b6512c74b407 560:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f 576:a1d36653fed5f5d40d1dd0873a07b82e673c63f30f6d7c895ec6eec7fb1e9fce1f3ecc41032c94b3fefa4fe98f66baa353939c796be30cc1668d195eaf5c8556c1a00c4dc0d6ab65919a1d72950231c8969c5b02b7f22b70cc03fceaa39a5adca0c9ba1cfd9bfbbef5d4dbe74d3596659658cc5aa1709e4d60469600324514517e90d203aa7eb44612e58870e3acec3b8c969f47f90c2142128a2a47ac3d3247c67fcb051c82f3bcfc98dc5fdf5bef407e369d02f23d690f62cc5e41aeb2298bf2c971a66744bdaeb9832650edc25d09fbd1314a5d84477d7e552b81b3c5731b420eab4d679bb84e765ffc5bf9b4d19df96b22342ec09d808d509fe8c4d0d40c3ab9b1d40040b4443555d9ce9aa04e216567f05ee286c811c9daa6c1dab198bce81e03d171305f1423626132210f0143a514daa926edbfce9a234b3100590196c424fffe738d0137fba0532a7b9b4dc162b9b406fa06840e49b0b9cad3ef7d71aa767b8b2fbf9780f1369d6c5b34361f403a3516ceb2fa0a89bf1821574439dcf42fb1328415e363d9a306a3f720e23eb5041199edcfa10b865a9f5a32009906512202bb4ed532616b956d0308a0d713c6adf20dc03da7c9b29c9d409b2fbe3c7f30376bace8a3156fcb384a62b93c50561776fc6cf16ded8e968b27391af2b767ac890b57fdbb7d3a3fcdee5467badc7c0d8ce59a17129a3672c37259874b85202902b11a3261ce7a16b3f830d36a173a8dd3623db5f45c233c6456b8a2d0fdadb16356e5c37afeb7f473cb4a55f39b9ffb0e4fd96952b75edb5c7f4648250e 576:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f 592:4231efb1fe07daf9ef1a69137769cce0731aac9aef27cfae5b60094e8e8550cc5b83c31efee907f5aa9fc51fbffe785d7d70ed0b93e918b4d771c7b22dd72b3d78e7eedaba9689eafd5d440897a339a2fd814651166f74636518affd53d96ce9b6b2727cf3b87c1a7e5ad7cf839b244bb2561fb3955d848131efa937cc8f61fa8820496b779498ecb3a3ea1cb573d55c11bcfe1f21ca95110012be5f35ee2d224cc284062b27b5ef85abe933f8bc5f1acb40b2f42b24db4dddaaae33b67653145a2c20ec0b308cb7f2e1a4110033776cdca32115a2022b3427d73d1e3895c9b6f337c6ba7efffc63bfde50b2c43cb6741650a4ec6a742019c65581a6d45f8d62f62d3da161211e414eb6af9894383615b4df3d1ac5d5d878ba72087ae03530013b21d56130782acfe0a9605466085a8c8b8db96827ea4039a77b1d7b95aca25167d37e6d6ca8880da08588ec7c613f06d24f69c3e8bc1f0b9b8bf589b7010671a9737f57eb59e76523b9df0a94edbb85a5ad91a7bc58ac0df86e6fa68b36eac485b497a170bfdd798e1032376906d0b77dfe9335fe47ae4142dfe9da9b3d946af220715dfa7adcb0c7789e4566fb9acad513c054d859ef309cec2a196a5407902ae929aab826cdd056f70a8957e7e001a63522e579986f542297fe07226c946e832554cb4d8a0f579891abd54b7ed12247ed880574eb62f823b42cca3418fd03b9efbd6e490e92dcca2409c1e5530b9a02529fef02114f96bc0ee7739507b22e48510221e218c0bad525dec6a2da81b834134ebf0bbad4638d6e3d781db3335883256d1964bcfd37391e84d128c5c7fd 592:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f 608:7cff31eeaa23800d7147e8746ad4e2b2e041a68804786f51539d19c040c4529d2c8f3a9eb917505eaf9fa09c8ae6e0d8d8f5c341e4f35f0b0f9b4ad99d7996c140abe8adcb81b6c96459f62b7e24e580614f6320b9d9a2f791b7c2aa9de02f0450819411e80cd62d67ab56f207441f823e8a40bb89f41fbbe95e26359f738ec2c7e418acd5c054c18631d573aec346915979d8eda7ef287b96053e6b9ad1ea683624fd02b3ae6ecf0db342a7e5c46b4b39f5fb16a52237689977c1f2d310fa7e940b9a7c6e20beb9e7a8c0727f0c7461dcb6fee73b4444822776345d7db060c7ff761e2246250b2d7a48e4ebd1f084fae6906c3120f59b740ac6bfda70ac6e1168d4572ca2912f6891d33a128e439bda816691e519bef01660a80df5d6e7108b7789950ee523b9b2ac8d998dcd276ad09c479265fc9679008174cac18ab8ba38f0ea3384f3e623daf1fa7081d042203a4777e5a245540bfb1cda88445f056d4668256e719352a4cd9d02cc3f0a3bf24153aeca33ed0df4ba73d5453a40e79a4a1ff462b6c9b3f3a129be2d27f1ee31b5675ad4d9c1a4567c57d039badc19676a6a029881c6c30616a8d32b6af83c6a3fa412a6a383af1f6cd38366c1475670dc15a9406a22e33ca2e149bb7141b8e39f1e437a13cb0ea27a9f73f7f01a02ceb8ef6a70de8a33e68c6f5495058a0b5af933bbcda9451e93f6e8877938ec67728d48fce408e803351928ea05f2d0d53ead088eaa84c2ec158ac9c036ba602399d542b687e8e0c80f7ea642b09abb61798e54c54886c88eeca627a8012254bdecd763c906e4dc7c31249830278dc4ac6a08cb22eb2aca2cc1bd54da06376e741149 608:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f 624:d49acd3a39ebf5002de6a7e435cddbc5df1ee700d41c4f8ae145882f005aa149edbb81506056755bc660208b79ce20927d17f8246689174e22c9e5dc225d86924de4ab1073d6f9762931ecf002c9149d05c715b05d7b56dd0c2d715aef361084073d55b126a9e34390f49cf66fa1deabe9c1191478659be5509462b2bf5c0c6490c4a97aa9343403b5056de209afe24ad277e68bfe19c11e4b99d70bd7f1f0abcdd80ec552392b4e5b385c25e9703c992a340927fe1271dcae11fc44a1060b77bbb42fe8fbe92cee73fb6231e0c66747c5dcd0e407958707745d7a969605c5308ca858641863c8546039bbf78e54178dc3445285f6c4cfa1264ec44e76946b16c7d1fb40370bb7681cc5bd08f1f325517c076b83a0fbc9dd82cc6b4a5fe145df1d206934333f04940bf403f6a0ae6bf2dacd9d240f73d20ae6aa24bf6b8ae918bdaff2615eb6fe2de197420e085ded829a2bcd194043d2c7f4da31acb04a84123ee75cdb611618667b6adcc3677f0c5203cfb9b18d6994e1a3b05b01f97471c374facd2a380c8770f1baeb09a0d9b45ab4e32ded8ae5292c307a8f83352757dbb797c8a7dbac6d2f2c54bf86055e08cc59db82c083d2a4ee16c57127d335dc07a895ceeccc8a8c268873cad5b3b3f9318e5e1b46f1e603596abed2332e79cc8d9835e0d67b9bc9c3192671a812bb80d3d09a95110dd4191bbf76c0eb6665326c753dfa9047dedfb91bf6258e575c0305a46b8f27847f74020fd5cb6306b32f526286d2f69d3c1f7c77071ce622b809ff9706eec156ac3c6b31dc3fc112c6fbfee7e40a86a1bb634dd2f62cf3e7b9885fe6a24db8204e1424bcb996f53ca5a5fb823263e564cc08d0194ef39500c81568 624:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f 640:34aa7620dd642155a71ef5f64dbb6e226780c86774d9892d7cfc2f11876d05a4e51cf71d01479119ee35ba690debba287a0a8a2a5f984eacf6623db41cc5f8f8028cabbb1377d010effcb8cdfad1a9f583e2b8357760ebe68e4d8727844ff55277713d27e1c98290b4d83cdf71a577de138daec9dbe03fa7637e5a42c39fce6540f921c2248c28cea6787f23fc8046fb6efd9b3a1ffc3fc335f130bc0b4cca337dcd8ba050d8d87bc8da7c0e286503526e46385c85a6c8bd36ea803f3bff5d37dc29dd39429a84c6f35e83a3192db15a3bece1fa7648002ebf8feb5a158859831f10946c94a834ebe3922a71bb424e681a18fbd7feb27cbf889443f6ad1a94a0e48ef3ce6378f123acd41abf79621663a75e5f14dacd0e590fd9cb9f50daff9f9f109959474c9841d9fbfc538947dc98221df050732084f672daf8ae517fc9b59617c5667c946f3837a21a1c60707c8f086d27e856df624bd7972aa9149d2d588dcf4cdb66b78b257387d28985e9e518631aa1b4c9e272eec70ee9b2b58e98983aa14461bb6a468c6976620ff76855570ac7a7894199de1240ebabc8d5dd6aa261bfe09d8bf711f2175977d241e5a32bb99f4486a7e023e5c587eb952ae908bf48125a74ed8a675e801151bef8b226d10cd1cb0981697b67fda8064385b3867232071123128619c05f64fdab86fa6903c2651674fc225855317f7bc47a0018db70dad91b08164bef0a2de82e62d6592b42d8e303aea2974ddacec20efa9cebf99ed23a93582388bb75ea7bb93d2447079b8968644747ab32b3ac10f6445d585eb3011e1dc12fa65863e616c0e44fb36a978852a10e913aba4239ce369ea1358f32130aac17be13af5ccb31e404fbb916a2ca902b6c84c2b7b369747454db4844 640:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f 656:f7ed0e6e0ef7d5fa1d23f895db539ad14e024902f30d899dd592a64a4a044b191f545c72734b2ecc70a1a752d7e55acb2f28503e3e9e06569faeb1bec2b6e7f4b9064aeaef41bcfa097ba3cc416505dee7e2840128cb1abef3e4106be9add513c3d22646211de6dd6fa7c7e2a40a2ac70b3724d1e5875c59ad004d82c2d3fda06d9f5dada4345d2f945f0a7c3036ba290b4dfed691688140b9af1b82274ba844a3d03b86556b67babd856e6c812a4c2521ce629596f28267e7d3cb7fe30bd1d693927b4c85fd50445a1c4753ecce75035996f38684685211e5b43ea5d32e54c5db286a70c573681d386480a499488502be1f51bf205ab3ffbc61a86765835d748e6e2a81410389ec98eeeb2bcb2c16cd9d3514e542021ed1bd9a41b3775cee0af410c6e3a29db39ab9a8913d7b72ceedee6f06bcd17178974d93a037ff303ac8a58b50787067ace9ed15d12417964230712cf154d881968ace0cec64721370864714739670441fc421185c2fa57a2a0bf9bc43a1e4cb78c0964ae06789af36cca8f7f85364c6d4be28fd7f275050b0e3b88b3a46739cb5ab2bd6d301c03dfae838b3137d085ff8bcdc593b8f790d6c3b56c8c4901ab23e5fe4f5fbe9b6cceb4beb06e8bdf1d6e8df98b6e4b3c96f2555431f1e634e8b7cd7919d489188c792b89b538e4fd8334fa28bd45bfcfa9dd9796ce0849f99b4c1c915f73ec0e0d59859f3100892f9c9f5793e5d0e908546eaaeb8bf4a8629386b1b28eb94d4b03dedff7b101a22f219a989285cd657fcfd3b5eeea8151e31ab11e38bad33bc40e519a8450b5929779aa90fb0c28ffd45df929c962faa2a342c5d6c7170af7213019e92d84758e41a4545dced705a21b6c857e4a2aa6176e21933626f363ac758b566278016e7088741cb3776ebe0530e26fda6 656:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f 672:c324cc370a3ac69bcd8312a091b00dea07de0b5f3d4335ef68b596926fad005df403820803a80934f87d0ae02bc5ef9c25caf162d5b0638d0ce61b79bc0e0105d3c2df29015dee30fa123be4c5ca9e4ed4f9388bab22e2b7602a7a76206a311d5bb1f609ef60b777227326efe17a648f3b6febe3c64e8160070d5b8f5f81a5820af7b69486051e65779481e7edd4a0326b72d9292bfa5c553384f66c18ac573e848e1e69d9288cb52ab7bba98cadc6be8a71f5cb6ef23baafca64e91e0b451f2fb32479653a4f54e790dd7ba625713a2d3fc8d0c54d2dada99bd4e78e819ea0dab2586fad553dc4d87e8f45c85d1efb0f9d7a8da57184a2daaaad2d174c912e79997269f5e5a1a9c10f644e2280956f4836e8feea9b39557f7a928bbc6641fc61b613afefe04d35feb60fe33d03ed772fda778fa8c6fbc568a3ce516d1d7a731bb4cd3428caaeb2fb72fbd3e320b868dffc0794a0749c7ff42699c07dbc576d6e52105ceb16478683818e6207bbd02b268c45496e7841df2bb49faca2e45aa6cc5f50e8c845fe19faf6e4d79ca84d1437529be69ab32ee97c21e0002426098b9ab6c043f3fca03379d3d047701c43127ffc5d49543435c3c21fc9bcf798dde20b764040061f89293d9f2cf793e6e2afe443b423168a8fa9bc0484bdec7949e6a4be68a7f1afe8e6256b55a49827f18054a3c09dd3bc8c7676e86b1786e04d279ee61faa805d9e574e17d8a0d366f127784cad553fd038e237f6c5e8fb2c94817bb76cf954eb5195ede1ff597690239be6e0f6ceac8107ac4b5c843e4c2edadc7754a55ec64a59c7d88122a8a353bf8b75c56ed1aecb6d3454bc352088ce570bd066afd2402e8da33d4ec1d670a06030165fbd1f25407eee55b554848d0923f77b9a263af75f83b5bf702dc733686d9cdcd977da36d321844ec1e5fbd38c3db11 672:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f 688:d4f095f98c6f6d5e536668ef67014b1cfaae8410377f67505c1fbac8f1d5a9b08e117348803c9dc1a06faa05527d6c9962611aa80a027ba9ab90f4bda65f4ca70dfc0008b18229b4c7e5b8970feac4f5f0b2012f7acde2dd835dcc94175ed97ca691f66ba1e86e86db2e1b546d24b44166061327e5e872829e1693671c42fead9921bfc9a10eb16dac02ab725ed48b34c153716c897ba91e1d55d53e6954bdcb2653f49a5bdd6f25b2ba109ee0f9ccffdde38e7bb5b6bb23ee4aa062e3148ff5e11fca8a484be29849aafc41dd8d23c6d051f58a998717a96c32aef897f80f5143a8d9140965544926540f6a9f33762a97ace2a127839c193aa643d9e7277854f362e4149b39688af16767f20cb3340df8a61a1c850d1c79d5408762985341fa62f2863ff650cbf1676f6e247987e317691dc8b77647db6d26e9ddd53923508343f1404e16e2e13da4dc1bf51c9c2ad2e604d6843f2a506ab32dc893c9f6e392917d04b4b3f18e7cd0e60d170987a2a479570bdfc4a933579a19daea628e3966df59285775da8ed1ef1c60888c7f65f8ccaa21fe4196d638ff5ab9e0948b2b7d6ecbe98f38a22bf9cfac14d5a277c16b6c4b43999c092d0fcd0b6f4d4bd0b7cbe05d03ddac0e2e8cc70d8627a97e2ffe0f7d7d5e82a1a59fa190bf798531de3c130a92cfe737f3d41ae67ff9040ea86bae64f0035765577326e595d08fa90b6490a8960cf636be26f21cf15f9628554e0c55132274a7acf6cb738ad535e872e591daa602b17c64f296950b2f6978f5edb11063d5d838418e6aa960fd09f713426ac4d522fc3ebe1a440c04de7398e9d787a5209d5720e17946543a0251921d1e61cd51a1b71d83cd40a4b190ff58668a90d264576ee675110e17aadb765d4e8bdea5d6f8bb87d558ceaec33f81facfe0b2cc78b37335b91aa6cb7f4d749302df73ee9e01a936c78b2b1a8a3d2e949b48 688:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf 704:52aa88885c8189072ed6fba7972b92b32544c1ffae641cd7704987d5661338d5a86f45540abd8fa9b36df2a74ac0e7fde18a9b863e689ac6c50ec81cdea4ff74ebba9b4a5bf401479e3c7b4c444616f1b385e0b335c26b9ec89ef10fa2f5e6e7b13c7c4ef9b88bb9ba10a8715886d6b0e598dd5a2e8b5ab98f6f5a6855bda241beeb0fbf53869254a39c250395b75ee8c6cde6e911f9d110c19759ee93e90f741b4620b008c9c54cbaf10d9cd39855f6493a612e9fdaf8709552c4f36eae6831edba0bbdec5cde5193e0ca24c7afdcd66ec6d3d94ff2fb1d0a9b71da4f0d6638fa924f780b3cd6c271685d23d6018bd7e87a565ac9cfda02c5d0fda60b2c076ffae6aa94f73a58526c6b7e1c08384cb0aa660c6a8b939f7d7ac7ca57b7c18b9be7e496fa0b94771a8918a57a3fa5dc03ca5b3f47b8cd99ce97d9d01c27cd97050602238ec7fac872c1e9b280dd551ae59734ee935f4c1257e067f5de2b6f2ff532cb5f45e228a6a961d2107835874aa307d7d9e495eefc7cc1039745a478a61eff60083689828f225304bc3a22524a6ff3849ef260c84458884c9b011b5660988de0e8ef47ced9cb5ce31b684c22156ca0ec1c60c2b09d487e5672e5a7ba98a1a4c8d0390420190bf2a3d4d5191f164b248297bec98e656742770849e9abc22156a8a214c464ebcdcc0db0a6b77ad29987b6ffa23cf1281a5316c2db1e8a712ace87d6023f1252ccdda51722dbd47b758dd12c44c4c356cd005d42e1a7f1bbfa5b4b57a0fedbbdce6e0ce0fc69d92417aecb8e7d7c593a1d1e74e58273072da7e4bce4f4bd94a03f1dd87d3a7089079ae6caa80a835109d984b19aa30f3e50db4fc91ea93182418ab500a44f521f8ebf7e202388da49472e7442fa407bc6604b8c0954a40f9c543a55a436a2eac98dd454755137602021130a9e13cc5107a9f23fbf9d1d1448a60d09fbaeb7472ff3d227df70964cbbf9bb0a35780cf7917e54 704:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf 720:17d8ac181eb03a99368dc6cb4a8e3b6ed3b8ebfa2ac6e0f988243b96066031261827c3964295c33a20e45ec4529509e8dfb754c69e5988e7b67a737365980184e935fc8fe51b8e5b9514e2b61283872320e75a43aaf92bb9ac44dc0774068d3be4a1497616d5867321e03ad9e440545b82a48bf5a185701f9683ce291757e398e9f4dec98182493d977dbf57529c88e6c88ba9c92cd6c5af668d9d37c99d85cd11e58dcd6b159dcd1c699c302df95fc9e60b651bed0e571ee6db8e711d0bc7c69e52706be5a181fe213b28c70d2ec92d45056e29ff2314367c1695737e73e75b7be408cb3287cdca8b592f83fb03870ea88343331c3b02f0d91552d673d41c2957be143bd9dae64eed6c71ac8d4a8f627112720b1c5b95c2555bcc4fe8727fdb650f3db80a9c18bb8fdf885efa2cfeb4b56a1f1e78bc670c44fbcf49f84daaa1b9b1c943de2068364674b51a389dced863c8b4950bbf1e706b9d5132319697da0f5714e0380d8d7411e650df78f2e875c2178105f86dd0b7ff49f98bc61115e6231f01954c3c73957d8f26469b9b12232aeec1a592fb1fee638e02c1ac8c795a986734e896e79ebb510d9956e6fdc2421dd304c7fa11db82dc05f053d7fb0b9b77c368379245c2ebc3ff9573548985eead364f65d7737c84444b020b6875b0c845caf9e521500143f732cf13dd493a7fcad33299cec6ef50a088a1ba6aa42b9fa1bcbae6068debf5a0751785ff646bf79454242f784b70b6b36f8c7fa12469faea65dcf2fb8ab7548893c725c139514c0a317dcc6aa76241cb76230e9daeba2853d3aeebd02901038c53c08769abf5d3738750c6f2854071713ea513838d4efdea23f13ce194ab3e3adcb5e66504714ca084198c4fac1ed59e0e112030142aae46f89772a2440555990d659bac5c05c4bd6f7be52de389cb581f7a381759749e103fc184ef880bf6d170beeb5c931ac02ecfa92321013da446d89d6ab564da6d7865cda50677ce5d352ca93bdf702736 720:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecf 736:7d25eb22236666c1574748f0fd631c8694d573df66e16bde87491efaba83b36d389ff10fedf3a8fe4689d57826f47c5e0eb47119f8f6e61c589602762a6c3a7c3be980b9a271f721483ada30887e5dd6d75d906511b6cf422d41aa7adf1d1254fe299aa5faa1be4b95e63f235e26fe10dcb60a189ae415016c5484989a7d32f51494d9ac28c81822eb2760ea734da2320f083d3c2a708b4a68569073b11e634977b2aaa053b08c4ef1c11bf92d4cd9dac7ecd913bdc4ce70a5c9f0d559cfd98cca12c43c8102a9c89349702c173defef8222b486c2fb63e2b0ea9b1a103550cad8719883f349c9b21c135df1cb84d3f5ece4f153dbb661abaed30574c53eb7922a72737a92d4baba008bdf983a56bd58789242f4176e3c65031dc2a418b32a7ff53f4557cda34583b70710c6feec420938087728f9692c21edf00c6a8cb6487d8f51dede758835cb716b383dbe90fdd90478687b1da45905f0ce5f0cc2765c0737da9810c7ebc698bd2f00d0e905fd86bdf9bac5ac7ce4af90cf87242356fdbf3ba0cf19e82daf21d2261363e8b30187edd9b1339f8f48afc8880f71c06bd59ff7906e2847c5129ac20d2e68622b34eb29657fe949ab4953232efac5eb83efc010aada059a5073d8dad10037fd586ac93dc5417c916073765d7e1eacb3dd076f22809d06dd6b0c90bd776015a8d769ee82e9963c6153030a845131c9ce8f8642dee4fc878c7d727ab3982c8c3394482124a32ff12684991fb2114f7256eb3421273129905abc87de9b27a34009440f8d4537c8e6df11209b7289b84ace6f5d63677fda318c8f55f6535c270bc0a39b9a1d05f459db316415021cd90a476e10a342499b88181c2e5985902f761654380c59cafa90c0ca056c058daada2de18fe6860a4a5bd860bb50b348418f668266d73551d38c771266edf1466dd52989f3551f45e3075d9bbb8c95d8c8bd0f062534bca370c0ddafeb08c51781126b785a176e9410b054f66b584c4da0777970a141598adb1826d6f5038da6f25f013fbfa7 736:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf 752:0c2ace6d4227b0314c8c9b39c2090541759f40f9d5d0523b25f081436b9982bd8b2fd7db50b6e6e8cf5ed828854f549c6d6f7b768372e73dbf7c834759b0f01d3a1ecfbb6d19b3ace85cb643e7d69a9af7d591608f266cb347298eb3756da5b92188c6d9e1dab31cee666b5dd06b3077a21bbd14479a35701bb5a21f80417a49cf36333b4da1a7a1871424cf6c3b90a0530c9746d75977b585d6a621d08161a3695e56b569184f8bc7b26519505422f220a4f2e20d5b5dafbe24a0811b675d0d5c85e2180ba194490f9ac758006f23886abce9e06d42b8b7519eb2c77f2a0545fd7b36ff0f15544b15ce100ac7a96ccda5b0a9d7b657f93407c86a9c58e08aa9ad13fec40601d9f7c79225ef8b8b4029f4d470d606b3e30acd463dcdb45c50a8b1dca6063d56fdbd05326a75e6a16e8b6fb41c3030b8b0e613694e8b877662a3361c95f0534599fbfc9a623fae8a119e98cb8068a911cca7c4edc105d65b5395d9ec3b75cf73fa4b371e3319f241f060b84c9760403395913abdd74bb75fbe4693232a853ace148248f218e5e0c175ba82196fd26f4c478014ec08e5bc47b599b6f42483668925d7e45eeb59026a2589d76dd2a6bdc23c292162355938f4f7440ff5eba65c946adb900f1dde05a85b0d82a84a2ae9585695cbcce85a88d99c5f4fff8e153d947b973766c9120b5d1fe2d6e3ea9fad4cd732e3aa869d0a721c188fdead76d98d37a4696bd968e23f069506c525f46362acd222e845cf4c0665e6369c4ca0822eb89d3711b070172485d8447d203f80cc82a174945c094f5e9659fc7e3069c8848efebef09dd3495b06d10a659abbb363b78a79bd8bc2de1beecee979d2b3b504a054c66a98393ab0549311337fc121f3728e6e8821be49820755ff578b3763643dd7f3b54b4ba694609017849c0bda642a49e4a85b8eed67cd9daff10c980869d8e1edf95476e79c5475110d16cad3c271b42d4809c658c2a0cbbc5394fc83dc416d255f814301b8711b91605e73b744db9edcb87fc6b14cca8ffe14d00719b00c4f8f53b4e825acd6b9 752:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeef 768:a96c69c3bf2a4bfe67bc553c6028bb5f42ee4178f87aee7535aada824b72716a40af3bb5bf039f6cee5e4524c424b15dccd1ae02981ab382a6070fc739d8fd5666e097ddf40b0142a9ffcf069445cf50db8c08087d5a78421f526922e7e79bc2a149e585075720c51be341d083e9dcd51aaa6aeb69fb08346e58269cd895ac0bc2fb3291f74a6d71155150b5bbcee52ada0d08fe6e4afd2d7e5bc7c4e18846edf2be939bc46815b68ced4532136bffdd890a83393f75653bd983f1ce52ab699b75d0b7c3293e398c38048e778f42aa988b51fba10b6aa379cc1abd12291eb11a910f927d13b7a74b725c27db8c9f4499f3d3b0d25f2d8738280b73ebb29790ada6e95ff7933a189e34532e3124027e9fccabf23ec6469b425c62ba4e0cd68177c555af0e49bc3d48f4b8c43328b57bdd47cc2c1a87df7764e25d49395c6f353a66b42f41e3bd1bc9f6ba84724990d1978b34d740e0bb84a8dd46edb245259cea37aa1f46cb8fe54802b65c98986fe9dc61a03aec493ecc2b263682d585cbf4162d6a9a7da7660fbe37a2e89cf1d4dac38211cf3cdc0554676e18c1a43e93e90c969da7c1e5265238d55c9cbb1563b07a77535ae14b895c5b020f3bdd7cbea272f79e5a42e23025cb25aef30a7e0cd43d01d93f6dae36c5ccc52d16e9abbbb65928e0eb97d83c184a8e181c9d8430f3d198dc024d757ebca4dd2f011863af893d4b25a434e304f6db5b5d46e193fd83404bd97216c314b9cdf59b68eb3272789472f0e0f077e98fcf53a9979fd08ae339598d57a0e59c0bfb7c6898c042634ee7e32f889eb07f5b17b568c007ba55d05cb33f554bec6f7dfdf165f49b659d3e3af859fcb3024f6610b5db6b176f250e838fe4ba8c21cc5ea2472851853702cba5ba99b17df0a47ae3fa0ecb36099c22df6782f8d45d910ebb2aa701c60af0d55da51659da3bd6054afe5413036532741aeb808932d10a4e5af32ee9b28b6c39a5c91371a58de8c4220f8c65b0458e764dea847b07be78c41610e02588f604733701255b26a5e9ca572c16f32bb92115c078bd76cf270aca1a56b283fb9a67f2f8 768:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff 784:21278770ac93e98b0d7a4a5a2fc7014e8cebba97b575c45dc3beb9edd7e8a07448639bc285c9e7a98014d2b40c2cd33ac6f14d18ad1ffa5d12dae454527ca8d4a832e27e0c94d6b870f77e3c11cf54bcd8a8e49a2edc6ce8e19bea61c7bb5ef4f75342d3f2dc5e694df575ca778c0246da3669553eb58c7da006e4faa9f58d530da166a051cc4bb1ca70092bc58a07fc0cf668558e28471f6f83bb2667e6b131a4ec76c291a027b7a563dcb373ae1de152c17865e254699f5a88662621cbbfae892309cc2f06eca8c2a6275c7a65277b63266b36a8eaeb31a3b76e0cac01b155eb0e7998c30f3c7cb9556cdf1496108fbc6592c2ef7a3bd57a559ce9d9f8dd30e39e223a8090919c302a6d703600ec053f505178e83af97259a5eff1b222ceacc74ba6ac3e46097bb62cdf8ced6b027c68e60f76c222a6957284912ebcbbdb74585c03e8867bea69de6bdd68566873e743eae0857448b03b191890e791529e4e2149f88130ab912bbeba27ecd75ae44d6554e33bcca80e9161b285329694dd246d0b146d8a8918ef68ba5dd49aea22adea00b4dd0167b9a4a4b5f18fa684bec7c7f628ea7832ee6fea16b20ac303fec7a8df1bb39dd8448d192c19e686f90fbc7493898a801f0f231603592caa5fc5e562b737f82b89de49ee5f2cf7ec5be61ad8b145da0f9dd2fa0e6bc6a0dc17613c48f5e1ca260d35fb9c807e244dda3372d61f0f5988b4f2cdf703fe507cd932ea0d0833481d2bca2dfdbad4ab50efd08e2e63a29eaf1e4155d6bc80f1a665c4237cf40d331ac1d52f29667c9581d5a66b7b6c629956553aed47dde70ef3492be6b4a9728f57469db1d3e830a6719533d757f69b6f400c7f6636ee699f0dc06273d70b40335792aabdf8101952f9eaccd40ded5cb911bd3e55d698b7ae4937a619dbb67c7b02fdf67a97253d0e0e3ab0a9e24bde2046ba82a69b7e1bf32bab2fbbbc2b02680e1c2b08c1099b661f5bdb2ebc58fd39e82c5d4ba199efcd73f8a1843fea9c84c083aee456aa811c9d6072aac9868d61f3bccc40c7b1a3aa470296c4ee7525ff29854484a05485c327186394dcab0a9b6fea8a00bdfc5ad667b85c66 784:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f 800:09a0113a78cf09a4a7e8ca519b63004d62f50d84c9570e7431e4a9dc1e7f9b2943374fc3a83961efd9b43c6967d9d3655dad2a1edc70b948c3ff10621aa60d6739da0bb75d434f46e251963be90121c802eb02b78560a0fa57eb0f8b7592caf2a91928c874573da9b859c85c3b82b93bd427a2e1a98ea8fd5337da73f456041a01f824bc3d1042f3dcf73f9c8809aedfabcc982087efa1953bc95d3b33a4627695839badb2ef5b70353e1ec2992b07089c747dd4614de1b1f273e8a22a5002b87d7dd2b92f7c9c5fa3b2c33e4e027e6bd93ca5072de8f918bd49ef3a8191030e83f104ddbdcc0e4f98783397c4e1d2c6fe009c4f2b0042e1c16dbdbb35f689dff9e793496ac33f6c96f70740a2bdb18688fd9b9b2865cbd4344c2a54ddc033a83ef3d134d5c8ee785f9697dbe28de6fa034caff78919b32af62e7cae90cb5b709e07a6ca844959fd5e015daed3d8cee560c1dc95dd5a4e1b30c03569fe3d9262078cbc48c294ac0603325bde7cbb9def6a4d828eaaf68059eaa27b50edfe83545fc7d2e008c046b912719fc7d72622fd73b0744ea4e023206f54797e7b36bee14a4f669226349d6cc2b5550f4543bbbe76e43b1746f52cec2cd735723538a34c9ab54db2edd22e6b163a4c5dbe7cea900b6f1cdb8be7ff25d3f18f2eec7929a4dd3d475d6e526c8644430106d02ffeb300d4dbb19f1f806c750f1838663ba70def27ed20f16515308ce942fa1ad2e8516f5df37751339f6a9a5835e8e848c257d25f806c5d5e0562ef2c96a541a8cda5950d107c23fbfd6947d68256fcba0098591b6b57418919c23d0ba37b2368669fe2701c4d58b629be2661b5f27d2b3de75fbd274c2d626350ee6da7861e5d033fd1905da0c1c72ddfebe92af2e6a6c7881f6a98c4b62057478d4173c6ac8d31a50ef01fed21177bea97cbf382bfd0ad1e5fb5b4a931f62dd2948c3a2b94ea5b4ff55e80187ad453c5b8c430494651f09acb764b8c44d47305ee22dc1289377481cdfd2a8664cc764b0982ac2923a485db4e8f7ad35cd08820f5bf854dc5089a077aa92a2f175c3f1771b14102c52bb2720619ffa98ebd94ff15ed62b8d24f9e02dd8b8f454e0d8c74f133df512cdbbae7 800:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f 816:3563439e39e10a74a84b204c7e3aa88695514c2c2b4575058999b0b2acf7221ebc0efafca23fee6dfec9640a6711d1c5fc903c99df596f43c8ddb919116c3a301a8f526d87b94b41c674093527db68aeb63d1705015d4c5f14099e258791ceea5bbd1369ae632cfa42f5c6d85520a5b8e3bf9691ac41bbb7569d44ab7af84eff60f633fc2be1601778ddb4f8481f940ddd8432d1aa898d2841aeea92dd4ae3b83a2e736454a8e779ee7b27778fc80b35a2c23d87e4b9e3db21cd549fb46fd8d37a883d4d210cc4336dd2aba0501db3c7ec53c5fce208b67b236ce3a446c036872ffe4251d455a444c00c62672b100de3e40118115b82ad2c516c30e49ebf2c3e8b16e1ed575e1c6c200c95a1482d89f769f14a2ad11877cadb3cd8d8ac0e26de638295a4d19d900d0ec6f24d97035e61dc8f4a5026269e205ba1b3bde1c431d56de4dfe0dcb979018ebb0e075fc712bf0114e3788a7cdc7ba93ade53a0e08dee265ae8ed1d6345cc2d5fa931c53e14dfcf3bc61c4803b3e86b702cda53efe0f6f0c9c2e1dc6e754736a276dabd46217b98ba1063a7b041d8d2685d9b36fdb441d3a23c60af648ad504e8c00301eda5b65696cde206d549fcd9822745aab3079d116905652052993e28b89e01a53db7ad3ab4756b33a024930a2b8e4fd39dfff919e8a3ff69d1f09453e0e9662b9a86e9956b65cc1e0ad33ebfddf19d13cc9e2aaf8e6d2c416975ab56f6b2e38c3bc00b31643e9062dd18a39888ebacc284ae73b6b9aac6e6b41e4fc4aa2f0a3c8a5c89e40278ec0649187e8a27b6240f8b68b67c84dc085cbdeaaa0e98b18c97785e8924d6b15899496c1079368dfce78b4e1321cb5b223ebf963231dda79a9c3b2c6f4c84c8b8f6420f474eeac754eaddd8c2b403b5ec2ba9bf133da6319e2a9a33813b94db2d4dadce0c2843a32ea06f75fa9e73752c179d8014def50b102e2018f3e46d00373660a2beb7abbc1c73d352d8e163a0f6cfdbbbeb82634bea3992efc2bc402a8383df91f7fb2ff0b7e5b87ba90ae76f920c7028cbd77fbfbcb6feb1cbb8656e0271223034edcc711a37a5e3d0ea3fb4383a5c2654bac15ce4fd97caa0552673a7b7409ed209ea47e13995467573dd8da2245a5d53223cbf3a1645a0de 816:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f 832:5d06971e1b3999c61b8c2ad2f6c69cdc1c07f5dc736daa78838c68127564bc8925ba600e892c04045667448c9be6101dbcc99b28d8fd809d31c2c0f2a0ce9ee430754588703eb7ed65dfd24f316710267885dd6cbace7d6636d3ac7e4d654b7fba954f2b4dc5164f21e6ccc3cffb9f430e3b673a7c64088adc8e841ee3d1d83b475808992588660e8756f438065f9a93b3de2e3ee0a5229df17c830d4c1a1e3d72e829eb8d77fca6b4cabdf16d0dd00862a08d899062b9e201b38dc0f755f08658a85ad83cd5dcfb289cd2ed3e2c5e4f2fc1097d5748e6e5be88df37f58696d69673408b21b8ee1fabbc63332053c206e54209aeff02bf2c7aa39634791c5d44b9ef2fe117dc9835dd0fef1e18dddfb03ba8f1819983fc7bbd9176e663bfe291c0b655b64d6d520901806a44c670e16bdb551bde314212ea306f440cc3c1ae5fe18dff4d58c595fbcf2abee582344f334eaf7c0d06faa39c6ff9219677675c857254644060f3117cdc9e9574c4af13d2b91103f92fe8aa66874680be0e31f52f7df722523068e5120c6061b50a84599c29fa33403c1853e393b7f971cd94633b9808e9b2b487d2f818dab80399d74dc40d6a5a9f9f0ae86e6b3a404010755b6d91b283bf96eddaac4f6cd918d37e13813b1b9d5fc56d9f6c6b704e845e443f2c7ff15197bf3ad8780a53a45dfd434cec61d6fdb148d3001f6d4d1da11b2440cda7cfc4ecb8a4dda37647b638eed69d15292d4af489bc7207fc562627a2bc47f30a1723a19b956a6747bbe5fef13fb83980730599adf1c8c79f3eb8f8bd16f8872e3d011d24967d5b4df53058bf6d850ea352823cad19a0b1e60c0c2430b899530a593d02721b1015cd334356291ac48bb34b840c8eb2eaa8490e31f0fbb40c405cad0a4a7abb1969a4781d45b39ddf470719909cf853ce0854e4ea742bee2434c49c82cbec4f4ffd6d417751acf04c7aa3cf806a33dbfdbd4b622945eb65eaa698e2ed6e648e068bb6ee917d72f7e1f0c50a96b9f139925ecacf07d5823772f79ef5a0bbe3ea5030b48a6d45a96cce9112ca45632c58629dc7765402d180b7ad3b88e72e59398e0256ed406b5ae58fb91d7263064b78667e37f1bae38d4565d90005d29c2dda4d8421f46671a83e6d457f4843b1c3a40468fb92271f1b085629 832:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f 848:7425c506e34c1f7f41351e6a836d712e308fee8e9b07b0ea43fe7c91aff8b9d2ff367a0e7427d06ca131e396ad7d8bee4d92849deb3fbed9d3b4c69553a85b537b10f671fb5bb18e2c0b81cf3d8c42511db6f70cf8339462d19e0f17872ba0264ebf4ca34e87ab2e633e63f88f8fc69be8bed9638f5e8a33b4ff4b50408c5b640505069e862d3f43ef3ed5fc691b9e2076c378c32a3d92668d169aa44be6ad4259601528fbcea5fa5d48fba49f830f6084481b920e9b9c60bfb1d36c92f8bfba1cd03f75d77c1e20af32457d64a148bd0509fc25b9e50739183346a1e7012d9dec8e9f7f83a48a745e483889c20fc88974cb2cfea5a271a3a48155e23d2f27ff0b9cf92df0bfe67af2e0948355206f2a28b6e984a211d6e2d9d4b4dc1dbecceb26cfb8d61bdd439fa7908c8377e75e3ef38caae86b49978d287463d139459da625f80e5f90b4b210095b29ef9eb54744f9c0e1b409d3105b5583c0774af8a1a496559527b0d6181fb539a1ea5799e5e7b36264024983803fa1c22d5f9fb69ddaabe3b86b67f1a1e28ac4f54bce5095c62c34cf44eb9b4c7dace34efbf79bc064fae5cac01a3f2ff0f175aa44b0207b29e4404f058b633f994d6fa2d87302b0454deed9305b9c6a5dca4413deed61b3d0c13c23b69c291a5197842dce0b787361440b9b8f687284cc923fd3c50c1be290927386b757f9aaeb318a878296c95a243affecf5387b6d2bcf7f68f407dcb2b775262acc0460e516d84f3a46fac4f3a2b6f413d57a9e865a01d9cfb1395742d05cd9932169de4ca1d242e6a1cf5c6b230031ceb0a1bfc09fd3520528f11109bed15ff9fb011b13d956b34c06e7ce5f28693f8a4ab93df6f11e6945b56d32bea6ab4754be8c951abf74833c91e362b50efd26a0787b09c5ccd9386d79c7c2c6eb2da20e873108c16a7658f8b765fcdb6480071a0b8624fb0ca5ee081bc2407586aa6bf5b285da6c10070a068e1daed4502fade3ee5aef733fff590d906cb0aee09061fc8033dfbb6f8e52d98223320c17ae6ac86e1ebfac3beb758b80d0818a02d335544c372f70fb7a602668ab163ec0b9ec5d00cf637ed1aa4e6d8e76668d7ca75a418a71f57c90679af483758cbf5940272a901eaf1ca9aa7335c6ccc1399c8d7f829eb7bc9011c9bc71920d5d80efbea91a2f8d94b3389478a81293e7193b 848:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f 864:764b92fd61e99249b6fb085b02c3b204dca2858aac1b419d9ae16dc7e927aa5ba4971a1a4ebbc54236a86f4372043162ddc4b9c35f4ee43a1cba3f090470e80f5dd1aaad578c518da3fa5fec78d464e74b2acde84e5641b1074868356cf1afed14271eaf705ebdb94234e4c9b00b4f88fcb409b2066ec82f954def23a153b95231d03bb4a1c8fde19187b997555026e19542427f757fd7283716bc0e8d0a4e78c8861e7f49733e89d28179508bb5bf1d03d8ccec34225fe5bf26803456f5210b4a009570d5683a83c0f8ff480b4a4f454edcc2cce8abc112fda27595eba8f3a101597dd2c2d53b073816aff654c35de769b6396429bb9a1b4395d08229968e57666832356f43d61b9132d752e9839659d286dd75667eb320e90b0e6352e0834fb7b18c658ca5472ac0909e018f7f4953affd3529154ad883d2e91d56c41ef85ab7a49a49aac116d0051d8e0f4e091ad6f5ac4273e5e56d8dcb3ee0e6e759eb2a7f54d71f20b7d0250056c6eb02b8a05d812f449cf47ed191196156b2e061098205a9eab3fe510c3691b439835dbb62705553f0edd6fe643fb54a273ab3b7bcb37b9a46a6d5b508f0a42679cf11ed4057c87928018d72222b14a38a1d1e1744eb79ba7d7271403b1fe3ee39d76d94665a313f5932795cf66fa08a5b0e61cd6b32648c628ec0ef0079ca74cb84ba96627e349892636f0783976d16e1aeaa21bd20b8b0c642fc73caa1e5d92fa1b412f94ed3e08e21755d608f5e62e38726785daf73306c082a5ac13690a82465babdf8f154f0096736780136856c86c5c63d95172dbac86476275387658e28f612acbf0ac9d44dbb015d339cc05517f5a0c0bc7c7e7748b91df87b6f8d48b8a8921a7d8737da324767390846b70ef4f5aa81a1df8e16c1effbfd8610fd5f815ae42aae521181b716f42a24e601ebb9b95358a77a80ed2e7da8b54ab9359f9f15c9628eec00b38cc2134a671f11ae7bc96da59da73ef278338716dd85a67bbb507b0600f26186dec8c6ab4e5a68b31c0d0501c69a4964644dc0e4f611b603b4accc295c7be7d6372871a5bcc5be78e6f53689c50a20f0cc1b4cade5c3c3f465337fe7ca320eab9f2e6b4fb81897f2fbdd79f2af5641c41f8efb1c6bd7829c2959946a7671ad4e62916378ee220c9356d54205d88d0f32f128bb80824f2f88506c590eb4faf8fcc9cf28afbd391ecce6bc538a5b66 864:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f 880:29c2f3b2c6bdd1209c76fb6b483a0fea5b269ddce36ca90008cf2cc52cc1e3b382f3fe445523997c1318f50014ce000de365dbaab930c4a8ad0743ba4f8c9fb4540c5ba1296cff579a64b964efd3f62e481944a5c475af35c51394383c80fd5cf37eb969e97f53afcdb4a2914473523a61e8239fd8e441cbb028c23b9a837fd05824972fd9e2cf92876d2dc93641e3500f52be33ca5f646c8013c04a256a71bbb4ca3e4c8ffba6113e34ff2423ee5c623902b47f2a1d8f51bf5f0b33d3c8d948859c9a0787101e126dc8e5e2b5bab6f125605f7b1a3ed85e1484bb6380bb01b44d3b18db78d904fb9f239222926893314d85591c5970f2c287dc78827c3895385c306a6dfe05000f7f01bcabc0e7ea14edf019f20c01f3732e4bebef395834d069582f685157f93e7924fcb0fa4898662fd67144f5b5bd07f8ae60d820a4305151a29e9306762914b579a52ea1b8d6b06e50e039a6b2148dd063c3781db0ce2c0e46f054f41329b57c07e5f571356a29587905be947cea7cb38a1a190a2cdf443514e09fb429a5e8c56a8774ec2344edfebc4aa4088725e7083b9d0908f5b0fbb71876dfd8fa69a0c1ea5cac706c6063c7ec9a2ce986e8ebe5f3cfab9a7bc636666b627d5338d48bae45016c6c98748f852554fff47b0b46f4d2951df9422f839ada5b10aa5c471f359ae1e462a839bad79af26322893533ba119fe5fad16d2cabbbc07210d2cb6eab815a4a74e8aa60332da45a8eeb37916365cf4435aa5b5df3686b299c846bd33412b7f8535e470074a9440702d9f98bf9dfcbaec7c356d8c61077235dfdb66e3493724e93be78c5c114c9e7996733f1c6c618d960b779263c1473b7c0eb6831bdbccccae88a287ab9096f5003a28f9d9026366554177954ab34ac940e33d14e2c61c74628fd617dbb4bd037c5763edfc5243f1c7cd98bed9718e8560c1ede47c5b3201fc47a2ed5507697633fe34bfcb9e40827989378a85f3e4c476f2b1c210cd0940703637ab728614e98f603a46cf5e830ac644c848a5e233349c5d5178c67f51261d1d7ca4aa36e293ef771b61bb81303b4546f1d6c7b84d9e1d47121990c3a7b819d53195b7ece7bc6bb517948cc44778200a7a53b083b1de133e8fbf1e51da9cf49cfbd04773654149bdbd679ed72acab26f301d895b1bd8c045fec96768ba49021fe380ec68ad1d143f26b8d2e873fc8295bba799c953d8b9e0857df2fea790f0d753432 880:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f 896:b3807844dbb30365e6f40f56e7b1f075d50762f12c64d7a7afdaa7da9b9eb80e90bd263a5977f9ce2fc761627fe447780f59fd6f452c0688f5ace451c9d583111523558b007e17db611961a6956e7d778c74384f427eb54ac2321041e1baa70119c81978a751392b4f49704f14c9fdd7f423b7c0c9b6f8e89c25999d7ef008f5397968e26a769bc172b50974f6988d6d92cf783634c79cf804d59c8e9225a17e7c6fe42179f52239ccb1b865c8d4ed5ec8bd7bd63f8cc1a05d6d652f26841937f794b2c0c8c4903e0b8935b1868363798da983541807debf9996bb6cd5f61974e06953c3b72ec70c6b5c69181e2745033b3d7aabf40d84845aa6a33bdedcd6383f7a19506e65ca18a38777768b1e229a13da5c054a585d1ed83d7a7839b780db663b634132d90fd1c3941f095282c760b21889438acb47ae02b9c2f3058f13186b16cf9c374545c804807ce2ddf590e038633619b50bf2b78a55f6c08483563d267ae84924f8b1b6a94572e782c4f86605446d0650556ec5ffcdcb92b33a9c983b2e4360f9887db8312ff2eface3fd92a2b8bf034bc720ec832252a5eb9d81732ca31a926955ba01e2f28699913a4961a26aceee382e3ca742f1b9fe3f53f71ff12f3bf12d9ee7e0f0de6ee089568da0511562813edaef60f429beb76626814d40854dc91fdf6c27831407113074c1661feed01c7a222c2c468c6f4207f625d0a09e5a4ad07f12388cfce72c4b05ba1d6c07c3c60c7c744509777b7e6feb085a33bad2df5538b4683976d3208be57c217eb5de4a5b5844e4ee877381ebf08f975b47ed1d17ba2c541146802658a14641376c13459764e018d7e6320f52c6cd2c7804d78d1b74e860e134b36628b423bc0ab8e45b7db1cd1f4609ab93878c05ea070cf2d5998cdbb8dbd87f1226b24029b53471f68439601e04b658f4269ffe58b070251b2864298adfc6be0a3df6d1c94ad25ac27aefa0cedd1473e9a3808877e1fa65f6411f82c67f42c94c655f3e2e9215ccb082d171feccc6ea0688d29051d6a80ebd36382131933d5d9f9538c35a489446fc8bb2748dfaf232d51bd4986c3dd5df2427696fde8761c695c12d0d291099e38c7abf0cf2e25fd9523f8dd0ef226d23cf69f23db15e46bbc30cc652ab7140f3ed4caf39d26df35d6628cd39bfd4493d535533a61bfe210dc929e8a6f50db5f0222355ed2ba3f6e945ec86c740648bcef4c9576c327f9cb3ca52612c5b72d8f4b152805e6cbf83593153ea0f0b 896:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f 912:b690948e6fbb6d5065e1f143bd8413a18f1762ae4301c9467f31bb75fc73cad9ef44a6f5d22d9813d068b555bb4949faa007568c86f63663a14df9d36c40e329435ac5baa656796e9b92ba26247a266a9d6cef4618ec1fafb730fdb5e417503a1bd061ccda2f93bcab6c8d0b1e11d9f29781c2ae361774b82b0b097be4a6c0494dfdee31d97591c22422a09418082d1c3689fd8b72828ea1730531665ca7264e75aed3b4f22845cb813bc525d877dfe616278e2041505c8bcc0b3d52bc8ef7335ef655733f263413f5493cd65d233c3f0e276881dcb13b27760b2694375502d9de447501dcbdb380e8fb3d554fa2cc771a38ef927cfd4cc3879e497e86006f4aa3b0e9ba3de6844cbdb0e63e04d83bb124ccbeb91aabb4c6df567ff4c4302a9e8ed13c5932e1c8ab03d3d0d6c6e4715a641e82d15f08de55a818b82c437ac039616499da2c3afc9c50e85e7af23801516961d2f4460ff425b10228c42594e78e05a68f238be3957d15e2ba3a227499ff30564f7c2a11ba00fe05505d0664462e301738f37b59bbb43bf44e3afc41e789211b97005898f8edb18231afc26ef98965df9e38a2306c14b82bd995184bcc1078b36cdcba476980a50252447a4f2a5925e311a2f21067b80b35031d677bf3560d5d5435c1131d0eb9863eedc06095c0ae8a4e6b13e9fefad3a9c9b35bd6adbc4db04ada77e3af55181cb17aff5aef861bd05d7ead1f42554a5bac36cd5b2b89cc10cf2b09072d13e517411235ff0a348894df3dc8d37a1828a5ff5dd31c9d04205ba0cb98a51394359e202dbdfda332185ccced81f451e7a7b79576be0bd5ab571c82c5763fca0ca66527dd9f524c85dd06f522d85de846c111ece570d1072dece75853d72d8d2b76677b53877b9586473795ce9d7b59e612023fd08a163d2897b35480b4f3e2d4daa092daf321031878e5432197133ae6a763e336e570f6e0428ea6a2501aee160b3b9ea2e0caa101927b93edc6dcf92cc38c4688989ede312fba3ae35ccb8056eef57668dd46f2f0ed9ba2d35ad450caa945baf34b8f254a3e0afbc3bdd37869f13745622f30c35f380d62990bb5c40a0dcbf6e13ec0cfb569c2581ee68e16d1cdcadf77a15d166c59b7f154aaaea4bd4287c31f2683013facb53bfc69998d5d35a58c4cd90a3aa3a049e06cc63a6d7181a2c38817be9c4721e346667557bd8d076c1224392d039ae243724dc495fe2ec3f2be06107bb91475f23bdd70b91f86c5f42711509222f29783ff066ea43cfb2933ff327ba83918 912:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f 928:bc5df364add8c8b84b3cd442f0cc09d2ac092ab25a81c6c57a5a13f62d9fea43c0fbf314d71e05c4eb01158aea19309efb4a5f32de5f311db43f568b6ec9d54383738ce402eb66a16129c4ab14f01ba81bba99ceae83b1e126f89125dbca89be178c23a5a1a8cdb287369321b95986aeec02c74a63fc32d7364e2e49382d440156be2428a3082c14dd482374a8ede2b3756a49725ae7e3148e8cdff15e8f2c8287d3fd7933e88b1c2439c6b8a0147d14c4bcf39a718ce38f2d42108282fe6ff236957fe5396362eb0e0dfd53e25d7b38e14de45ff451f1b56ec05e5d1a74d3aef5f2c0acd4662b5010af266fd653f3d99ea6e0a538655f1709e221392a7c450cdda6adebbd0f13fd3eb85520a7b8b5ed07926a09b763c6075fe6343d2fda48805d9345a3bff442b607e7d1417ef044d82f32e4fc2f8370fc36eee84854c63d4b4869a5b14874f03bad28b1fd9228f2eb648ae562763582dfe198d1a817ba42e2d9e7785cd54cc934045ac9985c9ae3d5b54dc61ffe99646a7f041a5a424ef909d68b1d8c042952f70533d8ae85e677d20554566dff1097d70780da80f5e6061ca27cfed9365c51a2db775be2e145fef14b2cf9bf671110be653f0781ee8d2b77f40e7d52f6928aa6e3f6dbb4462b0707afb354b2d88f1f6e0a9a687c63e2b0275e9309930956e310e37935c8b142af786bfaef99ef4786b0347c2238d8c468a77724b963b9bd04b85766bf358b44835a765ef105a4f71352f00d53aead6b98799c36dba4f73f6ffff880ffeabbb4c7bc97b61d3c8cdb757459f70a800e68980f120c1c5e9c4fd87d6b8d797bf3474744e42d5075a903d7ec24841b6d317d0e266e96b7fe40c1c65e90b65ae6476fbf4db5afa20d930ea00a5ff117766f300497b64edff10fbfcdb2a5b389c6ad4f1a4dc7338b6aab66f3b1c914b64c980572fb858eeb2364001271f7b3d9230faef634455753123766f14bcd0567905a121009dfdd6648b37a4012c5c534fa097f9e5e043a4dc18e924131cba32cbe91beeee1dbe8be95a91e3dbcb3eacdac1c6ae914cf50df6913f8dec3b17b6536df1fcf276b241f8e3ca34ee37f9182ec7beb3965f809780226c19da869a42aeb0ca0f75d6c8e61cc5241b48d1d0896db21ff6dc242604ecb003d6dfd3d04ff9b3ef1262c5c8a39ee525e642577019d69c5c2d0be5872b85fdab68769bc55658a553d1448918124284ee1a32961f0c6e4ef97ad1c19a5f7e75e254f837560b3c25c31c774248d1e48a5f7effcf96abf9774dcec13e732bfbe0a812ce2a4a9b4a08bf80fc0 928:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f 944:62e7a2ef1ec0ee486b1de8c2d10232ebc0615252f48dc33b7700b64c262849098660a89d87747d7970a029c15fbfc980dc2f780ccf1f3c35283ecdc690412debb3466da444dcc5658b025bbc34fdee1bdd6058064b42ae92fa228f576337e2cb01bd062e5f8a353b027881e5b95aa153128a3a3092a4dcaa6395c59cadfcfc44fcb368c1809cd8f18817c8920e02f18ca7bdd9bd441f4d7a5ba3e3801ca1ab16b16742a77d459055b7fc755e74e525e8d21a1bdc6105c726d5aec9595cbc3b2ec95643739c49678e177165c15a5f7252020e48225bd5b61c0a3021e4811ee6d14a5a3cba357f429d5593a55a58e6b13cb105c9434049b1e86432926efddecfca063e1502ecf33915e00e7e4a03dddfd64ddeec5aeb18a4c6dd054495fe05e0bf83d4d8fddbaf11799fff54fdafd5562d0f0abf1f3bfd67813425b9568c05cb70bae4c1bbd888d3d5d79322127deae89003f857b66d2e623eaa7ca28e75012c669d28a438f1b47d71dc03539f273969017f033cb4037bed293e227fc3d745b26727bffdb313713ad08de751bd9135e8f2e463a1d8b8b8b2ffdb023cc5af4497b0e8dfd19ecb29684a15e5167d9bbc0bcf674a0c9bb454c6e31c81605776af4b640ff35d7a011ed5658df6b7157acd8f87fa505195b5524f3283f4c4e8bffeb7af66cdc233f1af1d9b81c63601eb5863de6d2d7ca892207c20ae6078dd347f9c1464d92f39f55b7a62caa2913bea8e8893f76e92fc1408b4f76412ff5baf04d62766282c23588eae49908c856ed4eece4ede57dca9e745cf4838fd3c7aef6a857a9d9826db5b571928ca1d614467225deb510f4aa24955a00755c64e49d3183715a34f7ab2069e6fa864e5cefcc706633d4543d448ec7a18779cda8e6116bdd4120c0a1f653161adba4c1abca388ae6f40c96d853793e5aef469ca3c57f57f19c09f2eecad6ac0bb687fbb0c71a932fdd80483b85759ba661d3a9747c5131cdfcd7c1b46ab719a0fd2f0a7c1b41fa043177d5187f1cfe9f870a36d7e71f080a286aec0a2c6771e629944551f3692fe91beb59c3fff95470dc42ad077260f0f20912c394e2e04baac2363d3e056d589d763b5963642decd3ff5e345377574e24b87405ca7179e2d6a278089cf89dfe726a3639e4820ba48cf264717343dfa7e0b82a3928fcca98f3e1129837f2bfbd732664583354e71ac115009f3e8a9499694af02edef9d25c95291f206bd931a5d43227e1d0fa1de8ce06f88fc33e70ecbe1b17c5b43a716211f6a26b1fb28a431f3c2ed6b106ada51add23e4eb690a23a91d2db355c880c441390d06a9de6022e499c 944:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf 960:b8616d0a83c9aae9f1ac8ba538c43eae3f5861843787aec8b1189d7c32e072d79fe1f08fe0291740ef058d53e52c08f41cfca7b8d8eed4404a24dab6816003828c083f57152cbcefa411d213211e828efef1669cbec96fbff2f691ae78aebb5ddccf87684cf08d1c243ea7b3c6bac1b11ebe02ff7e1c342e825670ae7b88bcf31c3850f94dc540e6bb9be4ed8fd08113799c539eb97c1342a23448cea9d81a188974d47b6bca7c37dd19b413746f7feb2e49e1f7a61a3e6516b4bd49a2b02a73c27bbcd95b262e57986905eea78a7579b0a01a98269264a5fd2f1297cff5d109c4014c07bb3a98de6ba4490dbaf81ed8c62a6942d7295815f97fac618b3533e8c3d1ffb7f047004ad18cf0278d3d0cc046f67e64914eae29589381ab9b14781c4cf801579d01c5d5472816a6826982d5a626ca4d4404a10bb882b34083b4d2a1be756ded346c2300705c27d517cd2bb607a7e2c2f1b209a3c0ae4dffff1de98f7e64848ad865354919ec5efa517cab15b5f109d2264fe98b019b01665d5e4a73e98afa189699cece78b2ec97925ce99e2a2e195858f7487a199d55eb8ff9a69b11cf958b5d522a23c0bd30e6092e191ca4ae702d21ca3fb0823c57de653a93d7942c7731ae7a530c74fcc18f064f53fa507cc13608625d723ce39bf937a969c68f20c4b8aaba3869e12dfe4fe887d7cdec7d0c6efa9bfa11a949ceea5e16c353ea4f3c834161d3cf991a73d750e32ea75cbf15674a488028c4967569534cf17f587b5cde13d0e39614c46150d48572522fbd1dc4f4e7671b40b9a9c2bffa40084791211dd9e4fda25aa547ca27d6f68569e1cee1333b6fa3ebf7937aa6765a3421a3bfafbb605f95eb5bac77df9530a6a75f87c8463ef1733167316b4339ab8e41d3fd7dd518ae7c28c043fa802924b854ad01e6b2e7166e3f1966bd352943a794b6f4752beb8122103913a0f1a88d2f3cd8a210a54a81b991b3f566b912fc03d133c4fc55537bd0c9095678f7558b400500060f01c179bb9e998361a6c4c140be88070bdad79d40984579cf663db9e5de3d29274f1897d4d576ac3b593343e6d618e0747664429e7c087ce1eeac4e5aab827e24f21ec8a1bea9c0da9c41859ad2b09e9cfbdb88f426c66bb5dcfac33aae44976b8c567fecd0ec0549612d74f1932a571649198c736a602abf02bdf48bdd1fb7677e9aba0dab07b8afa973e1bd50eb9977f6d4779c24ae085ece616dcac3a0c8d6923aed9dc256e48a08dd33369e6bb9d619a3410ca5766b6cacb1cce1fe5dd2119beca4af02889721b0e28b3ce2c14a746a84155cd66408bcdc9d62fc7999eed86d1138aa4bdb5e8639ac2492 960:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf 976:fe8a924f6b473e4252e8306238646b383cb6cc6adeb6c472314b1c21b0d651e2864e875d4f5c47b9c8b74493b153f6795fd0265e9022f93ed363e9e4439e233f4298d859620eb269663a3094ef87a65b8568e8f646bb7a94a9bfb666c416486492bc14783cc1d32a6def86aacd4fb3e808785f796cdb3c67333d14dc611b043ad8d5dbd9ebad1b18f3f243bc67d4578077872de81f660d01a9a0d289d24d224ee33852ba898da68b74612f7140d3151f6d1dcc4304b1677a46f623589d3a1ccf61434dfc23d0fc2e31cb118ba4d02550b0057a261e736d8cdfac1f33373d2ee932bb6c07d3420f5c1791faab4e61ae17f857d716b93ff583883a834e6d878db98fb9f2abd0b1641a8f3904406d536c480f1c6be78083b745f1d8cb103700911a4c8d5b9b8f5a1dc5dcf5cbb021ed9f035ffba62f2bb1ea524e4fd999aa226980633853ff20b4b7094f3e8fe5913b7bd36259bb531ec1a4a41336a855cd8d8712480b380af3e66f8eae13b964fca9b1e1593ecb904cd6b8e1daff2296c268954bb6baf1211e35280c3d0115374055e0dda8a48486f45d1236c04d3e3d24f4aed948bd5467df2468929840ba0af1487e96f8883846fb02a6a20cdb3ffdd280a534c0f4d88743694b8abd71b24ad4dcb7ca7563f01971815b785b4d29c91994776b8a4fac9da0f9fc76488d8016bcb77d927125bd86f2127b85dbae52b0712358908a75f545c83ef81ce34a5f931504ab75b0d1aa12814f176ecec759e9cc8e21b2e92a3e2e6fcca56f8e0c6423e1a93e4c856316d7a6a2cb9ac4400538cecaa9ac7868ce99de9a50dc7b5bb7707c959ab0291708e83395bd142225261ea222b9ef58614f5208848dee2c97baa86ab3e390658803e0483968d6f2a067fbaeba311983066b9032f99cdbfb4d767729bf7d9148345724462fb868297e6b325f289f00bc151110f89d5ea758e9484eb26ba3eaeab7156308740ac499414b5d75d07fdec78843ba261a8c58d03609668fbf55d4ad2eed5b0ea4eca805d633541bcd6e93020003c6ad2cf360b03c71c32673cb34130f7634f8eaa459fa8bcb56f4476738b49aa9c7569672f0a7e58874e8d2b78373150faea04648c08873afd27530b04f9882f9921306fddea77a186605390f40de81efe5cdb48d6a25efbac6f6badfe7e2a7eea7d204151febdad5687c228f22ca4fed8b456cd5a7eeadb750ff29cff75016d8e5a439b735aa9586244300f6f78164b10f27cf311e46ce86e4a387ccf72e277ec6eff71ea62e783bbdf20a4f234d54c0e3d8c24d1fc3c9f27bb5c160d92cfd4b5e789a0f54335f7b16b7226877ff142e7a396f087422c41ea1424c7b89f7b05ac5f16b15ebf37ae8718b511b72 976:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecf 992:af755a7fd216598bcfec0d1398921f87ad8f9a4aa4418a5bfccf00bc9a710a0669ea2cb17cae99ad9a87b731236847bd642a3598c7e590e0135d0aae144d288fa1426ab6c50bbe70a27b72c793dcfddd118373e22ae8f680b0e8b10a3cda8a334a0faa389f56b7807c05d6cefa9560b0467c1ad10d29f83a5c07d6c69e8917a4aa4520cf42c7156ccf114781ee80bf2f1558fd9efdc9f9ef369b219ca8106408d24b6bbf851816e8e0c989615fb2d4c0854072ab3758ffa22c69185d5ff6920cb62fbf786b054353940081a55fd81979b73f5808a9cd29b8d3e4c75a622561375e95d50c2ffd61bc967b1295c70d8c8163c80cea6d6982f9a72db09495414a99247b24bbb64511ddaddb8fae455816d7c12880442001e8d0588180ed69a9a84e975b93659389c986653e8bbee4332b748ee40d8e1b556d05da8a3aa1348972036fb2657f29d044ca0ed4d8ea4030a1b23d0e973958806d8dc806430deabb64d5bd75dbcf2641a6d2ce92f297a8598c7aab436c1485074f244b609aca470151e8f3d54102f0d4290ba5b7722758a363c873fbc88e43afb2437f79ebd38990f72238bb865261bd434f9da58c0a54048494f0746b9690a69510361a02d934b14ff0589353828d375741236f1b45497d8afc1b479779e4f724edae20e2609764fb9613305d370f16afe452be289f595941981b451b4180c7b4b65843c2d99a75e4332f1ab83f8ef22827f94c6ecff6b3ec136033d4839e3518e1f76d734910556bccc0394bf619e209d92275862ebcc19d8be4a68ba52b6ef05db9ce497853bdb31764a351d2d6b91e0f1680b84d154e7f3404b97a0e9643188e27268e73f0740e9ac3c4461c9be061970a7b4a77db5bab38450b4fd0af274fa8c4283b2e95776c63d023991c8b02da1aff122eb9e661bcb1239d67e516500ce626e2000ef9767e75843c5e90679beee9aac3328defc89dcc5da2b7dbb76ab1dd6d84ac22f7e05d9e515b827824482c115d7180cc1b9378fe0eafbe34b545fa52b3fb9a9bdce1e41a80b2f911747f6bdb279b140cf12507fd33ef9eadcafc7ea5dc107a3ff6745a30c12d8ded824580aaa274e49495f017435979940c3a0035be77f29e099f44e1ee82b00a13729b2b90addc549d6799c388630ce7c42691b888380ccdf5cf7a701ccdc3f3422a677dc7f7891140c7fbb5093626349066a7720a4c696ec590fb74a5ca7f6b6774811af33eed78198d5b8de2371a9aa768b789cc0ca1c381cf4b70104204fba70b140a87e6093f15b02625c7b90ac215c3b318c2efc85c5e9baa06b52e426e2d3207b638f28af2814d8bc6dd29204e1d45823e6bca114acc39bae9293bb4b292bdddc457502b6dca9a7a80ba45f528a2234a166924d62b09cbbab14f 992:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf 1008:425b0a3543b047574d63f3513c2fc330437067ea9e14c24487e0fed0a5e5ca8c1e92d8c5015e4d25fb6bb9e7a16b6f0fd54782f84499ea944ef01b05053c004c730c5e229523bd7e017dabb49487f4aa6d93e580d7d5d6f05316f39a2f3fbaed95b615a83b39a4106dbf127e9d1a134cd65780cd9507723e876ff82a63d96c16a50ec0412f977b038e0efae2fcc1203da3ea4feb029a5be2bfd502e58d1f753fefd49bd3c67ed0d79d99618efbafadef0b47327803ea099247f8fb17f7ac8cc7ca37a32f5d1ee27f637db36d3c171af5549f554b4b9422f8bfad644ef9dbd47fc868ce4ba9342888ebc8c69728902565f1b520528fc73dc2bcd7d516d0a4ff9eee95069f487c810efc38bda54933f41ef69b3a39f28a19afaf758a5abf173f7544dea90596ac9eaf6194f26f444ad6f0feaf9c6cf1827a35eab9e4a44f7bcfa085dafd83f5a2ff66b73f58e7415d906312749427ac5625bc70f7b58dc78f2b0153c83f2d2503d670b9da82df1ae7ff567f80464f1a7a7ffc2e69ccbd507fdce91714691582800a07694969536d86f1acaa4bf4517fcfb631f08732a9234e17154ad807d0308aca397fdb648dc49164cfaec222f6a911c4deefa790738aaa7a5c94f1668441c20bfbf7e1a72f9f45b7e62e87214194c9b4e9a4e68702f91d797076c9268dff2fb1bd84b4bfab3af92bc7fbf21610be8819bdee42cb40515676c4d82561a41d930b34790a6f744d05c599256bbc94adeca9be462ee24fce633eac239ff0d1423a51c475f4a51ca51c570293988113c64b921b7496e5a9f0013578bb206819574ee4fc80067ce33df536a8a7fb6b54b16b719c547257cfabeed00c18eb120e019c09e7d275feae4076a1957035e05f9649dd93bec3e56a9aabdaebbe9bc53af637004f35f029e75b44a40989885c7913574fbe040ba059524044f00da3f29d0f6eab71b8508c5693a8401fd0bd0d4312d018b9b26cd2633ee477585affb5a2be73f156285bd93905a227f6794138e18ecc0fedc9814ba806c0bb2087653e02295aa13807908d968d6966c7ec21c936c877b8ba6a76f2dc367dd1b538c0045d211ea81d286a8afa147eabea42802fe01891012a1766551abcdbffdab8191b630c6a98ba91cd9dee647091838cf31454fa7c877418fb10b19ef905408c47ba1115394fbd5af5ce362b1f888124043a5fd3fc78a041fd7240396d61d2fe3fceea37488065b23d9b7745cc46b1769aad936ded16a4fb73b982d24959ea0ec38f6d0673b1e4272f0da01512cca7d2e14bf2481c5fcb37cbae35a95fa417b18b1173413a0d6ca1e548bcdc09b070656b98b0d6a05fac98c986ccad9c6bbd17881412adcef7d041550c753f26320a6e296ac0059ba1b91015bce4a73a7749a3dc02efab9668503d20f492d78be481 1008:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeef libtomcrypt-1.17/notes/gcm_tv.txt0000644000175100001440000003453310621351501015703 0ustar tomusersGCM Test Vectors. Uses the 00010203...NN-1 pattern for nonce/header/plaintext/key. The outputs are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous step repeated sufficiently. The nonce is fixed throughout at 13 bytes 000102... GCM-aes (16 byte key) 0: , C6A13B37878F5B826F4F8162A1C8D879 1: F1, 397F649A20F3F89A00F45BF230F26B61 2: D6B8, 1653F67C9C716D0FC59F3B14154DECBF 3: 673456, E82EFC79B30CA5235E2DC8BE4C14265D 4: 26DD7C26, B8D1F4DB845F7D7079DEB8920949C14D 5: DA62AD1487, 828A42329320764E5FB74D44A6108F4B 6: FB79F7D51742, 865415BD049E86F3DA2E0B6E25E1A50C 7: 9D96D1034166BF, 50669247A5B338E183DE5139831CD6A4 8: B466050E1330B20A, CB264FA7853A1FFE86E1A07CFA7C7319 9: CF16F0B3D9FC6183DF, 647DD6E1F40F385E1DFE6676FB036242 10: 14D90928C7236050096F, 930CAAA5536406218885475CA823A973 11: 4F2322D66A7079BD7DF519, 3B3931D47413042FAF1313F1041509A3 12: F1497906F1D8F4F9E47E4BE9, 469FB0D62828427C2E9BA04041A1424F 13: 2FAFA2A3EEA4C000702E58D1D4, C9A484FC4ED8644A06060DAE2C3D1568 14: 5D707F8ACF319413D220AA2FC2B2, 0EE9AAF5B1CF622ECF6C4F5E5FF4656A 15: 2C19DBF966D24B2713F82B69934060, 8676246A2F7795ABD435B3C6B4EA6E7A 16: B3FED6C2315CE6D98729DBE69270A11E, B8AC739AD154744A33E906C34D91BD4B 17: B2BC44CE088BC3F654B9703D9C691F17B3, BAD8314A171BC0119942136C5876AACC 18: C6E958E3E9AC836C9626BD66478974D26B0C, 4E6D61833E9DB839117B665A96DC686C 19: D40FADD078B474EBCE130FB44DDB4824077988, F43E3CD978A6E328AF039CC70E291E1C 20: E177B3DF83A117E55F255A6C2CD78AFDAFDA307F, EEF1ABAAB9CBE0EE317CC79E7E5E24B8 21: DBB4569B3E305E4525F1F7B3D2AFEF226F397E661D, 65ACFB70132EEE1D47319A550A506DB5 22: AC2CAF77718DE59131A6B745DE9F3A9897B17580EC71, D8DB9006A9597F640F2594340D69E551 23: 8F62022F72A0D769D2D095A55E28832950870B2B44B0BE, A7E196F869071B7BB713E8A2D15627E9 24: 37F5640F820384B35F13F8C8C7DC31BDE1E4F29DCFBDA321, D5765C39DBCA72AC89100CCB8864E1DB 25: 25059BFC302D0F8DD41BB22CF2391D456630C06F1DAF4DFA86, DC2FFD153C788C28D251B78AB8B7388C 26: 151F158CC4BA9393FDB153C4C72911C120BAB519FAF64719133D, C61915006038BF15DED603832FD179DE 27: F5DCF4231482F72D02F8B9BE0A41113D35AEA1CD85021CEC978D9C, 9CBD02C557180FBD0868C87A0BEA25AE 28: 5D88B5554A2ED73054226473676FAA7159CE12B5357D635DDED35B5A, 5AD11CD6B14C59E64B5B26DFBD00FB5C 29: 5696C7066EA09A30FC8BCBAD96D48A5E5FBCC8756B770F0A89B8711911, B9EA5F3BEF0599D385A9ACEBE4064498 30: 1240FED47B305AC1883F8CF137D58E79052B4E686DCA1423A6A2BECBD5F5, 036A5EA5F4F2D0BF397E8896EB7AB03D 31: AD9517BF392C1EB56D78EDE1C41F3C73B72304DA47F400C390C86B37A50C2A, EB3E026D518EED47F6C927525746AC54 32: 2AE1CEED83C6490A7E5752E91532406EAC6FF4B11AA770EFFF1B255FDB77C528, 74BFBC7F120B58FA2B5E988A41EAF7AC GCM-rc6 (16 byte key) 0: , D595FEDAB06C62D8C5290E76ED84601D 1: 4D, 47A6EDEF8286F9C144B7B51C9BCCCACF 2: 0085, 9788DDF89843EC51120B132EB0D0F833 3: 463701, 673CB8D248E6BECD5A6A7B0B08465EF6 4: F5B3222C, 1C424282D7FB427E55285E20FC2ABFF9 5: 3A4A8361B2, BD40E631B054F280C7973E5AB3F06B42 6: A475866BF2C5, 2067F42FAAA6274270CF9E65D833FDED 7: 689D0D407172C8, 3BCCFFC64E56D5B753352E1DDD5CCAA3 8: D9CE4B051202A1D3, 79B0CCDA3D0B9C9BCF640BC9E6D9CE0D 9: 0317D68BE098D276B7, AF35043DB6213DC5D4F3DFB8E29EE537 10: 154CEF0C6F37AA0A73C4, 61E598A8C6D17B639F9E27AF55DD00F3 11: C3DB1B2B6CCC9170B9C05F, 966871DDD6E110711FB9DD733B6B2B3A 12: E4F22383C75BC0FB0E59C5E8, 971536AF878F4EED68F59046C928EAC8 13: 2FBFB99AABC6209FB8664916DD, 68D0BF2144AD1ADECC4074DAE58540C2 14: 5FEEDFD09BF89719A34CDCCD2AAA, 64DEB7D5E6891103AA54C0EB366715D0 15: E063A076E0C770FB010D26C3AC3EB5, 0CA321B2A7448FEEF84D4E0AD5BA2DA4 16: AFB0DB9959F0906BD346C2D81DC5412C, 425627895E2C4C9546D3227975585459 17: 79179C0D4D6C5E0741DD4CA1E8CF28C75C, D0188A344A1CEE52272FE6368DB0FB75 18: 8A75521139B0DE3C08C9EAEB77D8018A39FE, 47FCC200D8A384320D2F1A5E803A9991 19: 0399381D0A975AE3980A9FB75B991C055AF367, 034915370AF94B96A8A4E50FF9B134CC 20: 8C189094DB13FBE62EA5C4A53C29A428ED587BA2, 99C58F838423033298897841ED526347 21: D91F5144B525AF5D47EF4D5F0AF9915447A55927F9, F6750BF7E089515D35B47BC1C65E2E3A 22: A4E26B554AA277057A5FE3FA08A6138CEEC6D69BB1D8, 7BBEBF52D8251108C7AA1025E213EC44 23: 5C1A8C3A46FCA90D73675706313CADFBB90A535A4B3D5A, E35244A2633478BBDAFCC81161F28B80 24: D69F7264FC594057B89181B83582D799AE54E9EE4FE8AD48, D4B29E5C25F9477D9345526DBDE9372A 25: AFD322D0AC4AF38D5B9CBE0DFE85618C001A7A77CD8FFFCB3E, AD06BB9C59D23D258D6A2AEDD946AA20 26: 179CA8395CD8E75B4E5EA07D25C8036AF08B1A1C330492523D36, E3704C4341A834C087500E332B7DEAE9 27: B9178EF7774684F43F1FCE99A4319B5A4D167B0A848551F562CD7C, 5D5082FB02B9B494D5883DF49DB3B84B 28: 830FCD15A09EC61245D7DA258E308E76D3B542F2345DBFC11AE983A3, F50C3332F8D91911BDACCFE228565E5C 29: 179619B8C7EE9B3121405BBED2AC102A027E6C97EAEDB5ECFEB13792EF, 859EBA3BADCE6E5AB271A261B26DE28C 30: 14264C7E0A154119BF24B7FCF434E81440D42D54738F0BAE55836849AB85, 0B6C9B9CADB1B6EC71CEA090C8C72834 31: 0D7A316F8B873F62CF26CFC569179AB11CBF09D3467936A85ADC265B2C9A8F, 866AE7C51EC2D9DEB32748A1C8B61143 32: F8FD1F967CD3632805AD7FA8ECB40F530927DD5C49D31FDBAE49738E2315905D, 9CB1CB84A727C9F42555EB566E0A1DEE GCM-safer+ (16 byte key) 0: , F769B436C7FB7C0C822E24BB2B2555D3 1: CA, B156298625F5634FA012B23044437807 2: 4960, A64C73E890F3D77B2C3B3C76C2D913C6 3: DBBB8D, 686651A017F89A22F9FE96533C85C52C 4: 150AD99A, 177F7DE9E897DACCAB7EACEE3CDE7601 5: 077055065F, 48B4309C76CAC37BDF11842311BA6CD3 6: B2F8CE062C06, ED04DF96C06959524956E8AC5C338457 7: DCE718211410D8, 3F8D8180BDEAC2F018EA81615177CC8F 8: 0F71E2772402AC83, 2130481B2CA7B4B4C8F3EE73B3B3C28F 9: B69030734E5ADF753C, 8CC4B62BFBC3EA56CCDBF0ED318C784D 10: 6B8A91ABC1BF2F2D0176, 86EAAD80D148A48086987A40A5631DEF 11: 44AD00799EC8E62E34D6A1, 016830D58F06F75E54531B45D9E785F9 12: 0C4B9381D78E0F0A78B3CEAA, 4A79C58DAB131A22F172F9177DC4158B 13: 2C56D4625876524B4D8D5F079B, 7B407F704225B25F1F136C984E564147 14: 36424D69BACC56407D345B3D7B4D, EB126C255A2DCFD32F69DD5CB61876C7 15: FDD3E091C0420D1A4D4A848757FCC2, D319C5C07134D67BA42A4BF312CD874D 16: EFAF6F117EA9A4B4B83052BBF5A07DB9, BB09D473FE82257146E7ABC2EFF6F631 17: 19B71383C414BAC3EF252FFF09F5ACD777, 526DC9AE6895ED33A34A9A4ADB07E1B6 18: 9AB6DFDB930D26E00B3D98DD5AD014E08756, D70B95B20C106A5A03F9B803D2CAC3A0 19: EEB3C236C3031DE4C3F94BD746677AE84B271D, 9483BBCBBFDBA1CC5F6392DABA2ACC19 20: 3A0EBC7536F8717E8FDAFEDAC39E8F1F43C0627A, 3DA7DC2475466CEDF01EB543870A74FA 21: 79D28D2F149E1D97E910342DF383FCEECF5AFD4C6A, 2364F33BCF6F07E381F7E26DAF802D83 22: F1D7C319BAFB740332CA19AB0C9B71728D3AE69BFAC2, 3D4AEE9780A5C98CBC69606CDDDB31F8 23: 1A0D80381A186673FB7B52C40AB6C46A11AB0889333C20, AF5C17E3D0D9724EDC1FC438A16B4EBB 24: 5E503440B22DD6AE6401BA4355C8791BACC598C9E0F1412E, 156D8221BD61F5C108FC18FB2F50D159 25: 7784EFDC6F0FC56FCADAFF17BB52DEB35B64FA19C3F391BDFD, A291E8238EF158A2379692077F70E8D0 26: 184B6E18032D1A70CE5027912E447C357C72EEF7B20EF0FB256C, 0FA0138FB9480E0C4C237BF5D6099777 27: 7AC8FCB64F35B71C5ED0CCD776B1FF76CE352EB57244085ED34FE8, D995B3C1350CC777878108640C1CADAE 28: 86C7A01FB2262A8E37FF38CC99BF3EFAEB8B36166D24913BDD3B91DA, 25EC6D9F69168C5FA32C39631B606B55 29: 91F5D3E3FE0B1976E2915B8DA3E785F4D55768FD727AEF19FA1552F506, AF902DED55E386F0FC4210C97DB9446E 30: 7ABF5BD9CB2EFF8382C6D2B28C1B0B25540E434123AC252046BDDA74DA32, 713259EDDA9B1B63EB68E0283D0259DB 31: 5634B23ACEF2874BE0591BE3268C4538698FF2D93D59B39BC86D0137DACBAD, C4054796AFD335B43C60E7E634122BAF 32: F26C68C36B1E56449595EA4E162391E0C6A306592949F69797B6C2327E533ADB, 7B392AF776A94983078814B6B8428BFE GCM-twofish (16 byte key) 0: , 6275E8CA35B36C108AD6D5F84F0CC5A3 1: 38, A714210792F9ED12A28F25CAE3B3BC5E 2: 8E2F, 6357C1F125723F2244DAF344CDFCD47B 3: 900A4C, ED4E0B318346D5B9B646441E946204E9 4: 087EAFF8, B871ED95C873F1EFA24EF8B6915F447D 5: 63FC9EFBD4, 650D0ED98CBECA07040AB97B97129360 6: B6081E94AA19, 6A3BDA8030C5A79B6B9087555A1DA67B 7: E10A7B9CBB20C2, 59EB55DFD0A37C55A869834E597373AF 8: 94E947FEE05780EE, 354918527F855264E37DB6892E868050 9: 9A80C567AA50220862, 814EE57CC9D51D7D900AB4840C4B072F 10: A8741BE1E42BE207C416, 2B28AFD8ABE20664D8BAD7535F82F11A 11: 6AB7E3C68B6682023E8190, 5E48B67541FE83969952394F84D29E93 12: 4F66FB634EB258CEE2955D84, F2632C2135B6E1144673B0EF73499818 13: B29042F3877C2F5E694953C5F6, 03268A30499D57A06AA873EF00160C3C 14: DCC7B5D9F58C88F54A9611389B8D, 5515426FF7CF2EEA91BE2B3752371CE0 15: B665488BCD75FC02A0DF7994B7CF98, B721531E2A317C254FA2ED306ADCF96C 16: 9535DC8A72645E34F948B71A5159AA9B, 5CEED93DE128044F0471C65AA8F21D29 17: 5CBFC61A23D28562FCA929375E5B585327, 3AA842B21631968D1B58B72FEE090EE1 18: 2AC3F780B956A933C0B8565EE527173B8CC8, 16EC4B6D8E2CF3CD0D16E7A5F401C78E 19: 5067FD65870A4EBF6C7FA811A15270E7F8F17D, 9A7563BEDADFA6B6E48F5C13FCEAED6E 20: E3A65A188077E5DC171CFF30BE8B27F10F015166, BD5B3D84D0C1DD51A3909F849141B57F 21: 88D0A65C105823E68BE3987CB205AE0C1A27588FCD, B280221AD0BD83E1D6B37F331F326AB5 22: 7C56D987FEF6807EEFAFD4C7EB9D72AA0E037979D91E, 686E1268A8DC9CD0192A383EA6C2D975 23: B23CCD0A076CB122750B634B9E6551E0585EDEA18C3245, 6DF30A7F0728E2D549AA411AE375E569 24: 767BC3AF206E67C9E27A4D7E814F3B3A65D27BB70BA9DD4D, AB2B16C031FB2C8E85B3B2B38A5CBA4E 25: 9ABF34ABD43705D62F377449461C5DC239A2A86E5A98AFB159, 3DEDEDA85E6BFB53C6F18726CD561604 26: FE756344C05CB12AA0673F1C2069A86556E583FF4B7313A0D395, 21CB0E0BABC3C7E547F5CB207295C0EE 27: B70F16AD19A6B0AF6D8DBF4E98D7D5ADB944D91BD889D9390C3E21, 2AE67812A22C1C785D3BFC184A1C74EA 28: A6389032AA9D08BDBAAA5E230E5130665FB4F0CB868F3F20C4C5438B, ECA054EFA3F39400A587839C4F0605C7 29: A55A41315EAF3A67A0FD0E14C6E04D03A5E38D0F756719F4A0800B290A, 7A5277809D4B65E663603099B4DFFBD8 30: E739633579AA6201A024B9873F28412BB08B08B8616D611BC9D07979BD3A, 390038A93AFD326C5CC1525A24CA91AD 31: ED3266F8B0DAA7C3DB7814427E8139831CFC0EDE668F0DA83FF7090154410D, DE440EC2C6080048BFF3C5455E1BB33F 32: 4D0F751B55DA3A2E0B28DE59E9680669FCB5984E9C0DB942DBAACDDEF0879731, 62F96CFE31D3D6AAA0B9F5130ED1B21B GCM-noekeon (16 byte key) 0: , EB5A8E30D5C16311864E2D8D32859ACB 1: 88, EAB88DE1EB7BC784A706B2D7946798D7 2: BA1F, DC3CEC6AA324AC7D053EFF7A99AD3069 3: 9A1457, 4AB65831DE378DFF71C20249C7BEC05E 4: 2F9496D6, 800745CF95EAE3A698EDF9EC949D92B7 5: 84153177A2, F6A05B654435ABDF5F696C0E0588CB5C 6: F80B7865C766, 2334D0061FD488D15A6AC8E44EA1F4B9 7: 872EA486B4EA9D, 3A49671DE347F675AD7904DDF4255F3D 8: A4EE5750507FC831, 956D09F7C5FE812C6FB982E1DDBE864A 9: B5874AC964FBFC1A97, 90FBC75F45BFF58B3A1100393955D0C2 10: 92FF5FCF1EC675E02E71, 983C96A7BD4A0DB5D3B877911CE8A6B3 11: F7BCA69A9C7033D84A2BA0, D4ECE5BB9FFCBB331A646D9CE8078634 12: 5E1041B4554C8CDD14AAF16D, 1EF777F307CB96788B9120FFF8A8BC2F 13: 7BB7289FCAD209D7992EB7AEDC, E8AEFB830DBAED2B4A790FFEF940A20B 14: 12776A7C937A648F0A8628AD8C5C, F070283852AC030819EA67BF82C719AA 15: 7293476D9E935EAE9DEB66F697F662, D6322603671153A1EC1453CDA5978E15 16: DC12A86C85E7358919BABB15A3BF5FD7, BBBFA467EBA8124DFEC82DB0137D56B9 17: 0CC1DAD00A987F9C57E3660D9417F226E5, BB8AF5A0B5BC79BD11C5D41CA80CDE2C 18: D0049115D6EB5495FB391CDC494022AEAA48, 682FF357B2BC059765C29AE6CA668D0C 19: 48FC54A401B4C06CE8567AD298B672191C7E84, 493A4AF4C2A8828FED8442C4EFF877F6 20: 90779795821CB1B7DBD97028E29DC1CE7D0CFAE0, E126F485F73B6F7B3894B4CF7E1C5DDE 21: 8CA5C246C8B7C04BD7171CAE2D1A892D66302433F8, 5D73149A3635A86B3C34DEA5B95CCBCB 22: DF082B665F7A952B2604C04554B81393FCC7C0B816C8, D3569ED7D431176B286EF22414E4CBA8 23: 761908530C9069E189649ED24B6A68A89B067C31E9868C, A258BCD83D3FBC7AE2AEF7516025AB36 24: 717048F5A31F3C89D3704F90069AC5D5174118770C65BDA1, 067EBF18F7E3DF4EA13F9ABAC682C2A2 25: 08C6FCC5D3099347C3FEBA3858A6C22C51298CB591DDB77827, B57BFBA40BE99DF5031918A1A4E2CA80 26: 2CC53EF7EB954234E64CD4D60FB1D7157A489ABABC10900FFCDB, 236E769611D16EB7F463B7578770F886 27: 2556B46F2E831223D632F2691329A874F517687AF81B8322AC55D7, E213A90DBC31DC261A45A9AE41CFEEC3 28: 71241792728594D69791B80AD6DBC6417D1D14D222DF5E6F834B82C8, 601F97617708B1945BCDA8A82496EFB1 29: 5003DC2EAAA23F9E2221CCBB9E20116692CCC99B3CFBD0DDD3A8491E7C, 3743155B792012845550205C8949B73E 30: D0589675357E850333F854FBA160688F06D122DEC00CC2620DA0B2770765, 20E085752FC4D37791C22501ED1DB6AD 31: 645B46D2D114EE7329F14AC1D94E6817EB385EB80C61F014F90530749079EC, 8A18DE86F9555A1070D0BFEDAC15B14F 32: 068389206D37BF5A41C58075FC98901C3B42E6F2F13C09F4E92524021BB1C1C8, 370B86914D63CFEE8303D538A6BEA0E7 GCM-anubis (16 byte key) 0: , A0061C2F3B2295BFA33BC74C037EA8DA 1: ED, 9E5648DCE40DE37B56C557D26CB18D83 2: 6719, A6605253C59A101FF85C5102CE92BE45 3: B8873D, 13F3E3ED3646BB296EE4ED5D6379A21B 4: 5AA6E2CB, 1812E8385D15B5BAE043E4E860BEF490 5: 4F6F4CD8E9, 8A80BC5E08929C42A5A74C5D9ACC0C6D 6: 2F0D8B483CE4, 316F588F78FC6A9196C97CE59B9B63B6 7: 82D885FDE1F948, 7160BF556614511F53738A92B5277056 8: E4931462AD41B6DC, 7CE24C4D6B499975FCB72B5E2275ED56 9: 503AA70BE698BC5B41, 10EA0C61FDBA8FF7B4E9927BCCEFD911 10: 6B2D213D14B5D25EBE36, DC3222AED12EE26D3D14E2E733EDB2A7 11: 7D8B0BC1B7443E7267371E, FCACFC73E391865BE86E041F51C45E81 12: 9EF3BF8609E133BEB10565AF, D84326D4CAC9D5B74FCFD8CBAFE79E77 13: 59AE7B1FDE1178CEE7F63C4894, E1BCFCDCA86CAB9C684F7D21962D580D 14: 564E7B8BAC5582A3BF1178916569, 54804D8DF4D7577EF65C15487695F840 15: 758A6DC437C8821274B0F16F911BAA, 19DD27500915F425F34F67CC2374DC36 16: 0468C94A88A27AEEE2B3A973065E53CC, C743996C6F49363B2F4613F24703EF7E 17: 3B0CABA5EEE44B7BFF0D726ECED54763FF, 14D9D09815BCD91DCCE2F5AE1A9929CF 18: 5B945D83B98C43B0248F9BC0479E332869AB, 67A275F0313D4245B1965411CFCC8F17 19: 97332441CA96DE8553A3C6D898FC6D90C86DBF, 73150EC3D6327E3FC8015A6192652D3B 20: B9A1778FAF9767160D0D87816ECE1B99AA727087, 0C173D3C4078392CE377313C48D2BAE8 21: 5882B73911C7D26EFDCCA3AED2EDC8A8BFFE75B1F8, 8F8C535639A0B59537E590C7FC9D2E53 22: 70AEBED8CCFFF6E5CF06F3E841D12387EF8D6C7B4BDE, 4B00C27FCA9BEB82331CC8EB13DCC580 23: 345CCB52BC20DC5F1BF5EEDF5D72A6C48F402557FFD342, 1A790A39573B853DBB8E2E73B7331014 24: 0637C78A817E91D63CE18CEAF8D65C6107283A90C5A97842, 52786CB81724E12C76A0D23D4680E36B 25: 59526D1E86A473DFB720FF25E97D6571077845F73C5E8322F1, 369FBA7823FC83D727FFD25D10130987 26: 2933BB4E7603C313B62332827601F8189E14C1F08EA547E15AB5, 204520E365DAFF6551B01562A4CEFDFB 27: A4098CF2A48A1DC2BCCE65CCE8DF825AF51E7E5F94B6186FF85D77, 9833EBB9A1D5CD0356E023E2C3761C2B 28: 26557B942FD6913D806672EB01526DBD5D6F532F78AB6759DE3415C5, EDAACDD101BC40EE6530D8B5DC031F31 29: DB92C3D77DF0C8F4C98845AA9AD43FB800192E57A53E083862B7E3FAF0, 628DEB1E345303A40700289052080FF8 30: FC57BFAC2C77781723C2B721886D44ED67A52D9AD827874BC4EEC0A97281, 9A222DBC47B4AB4E520D3CC5850D4DEF 31: 72DFB9E91A78EAFE758B4542206A4A957B4523A58428398C11BCF2AEAE1938, 307D0B876130E82804C1167E03B69B2F 32: 7275C6EBDC2680DFCB73326A987D2FBCE83E40A9AEFE6351CFDA7251A6FE10A6, 895E6EEAA9BD88594903325A063CA45F libtomcrypt-1.17/notes/ccm_tv.txt0000644000175100001440000003453310621351501015677 0ustar tomusersCCM Test Vectors. Uses the 00010203...NN-1 pattern for nonce/header/plaintext/key. The outputs are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous step repeated sufficiently. The nonce is fixed throughout at 13 bytes 000102... CCM-aes (16 byte key) 0: , 54C92FE45510D6B3B0D46EAC2FEE8E63 1: DA, 7A8984228DCF944903936CA9D7709ACF 2: B95E, 1056DE0CBBEEA760ED2053FFEB554EA6 3: 58FF3B, A42DE1A812D29BBC6C1C5AC808565437 4: 9D6E6FB6, 5E8E0422792999381ED669CE17601D34 5: 40D49E851D, B076B4ED79BF0155B39A743550593944 6: 015356B9A6E1, 8D62CEFC451CAE4A21C1C579C6CAA128 7: A2CF0A77AE0DE2, 97B9D201740FA59E863513EDACC59FFB 8: A44C68E52F95B48B, A461B79D4D9B8ADF6C6618E6ECDC059A 9: F56B8AD68AA31F22B9, C5C7D2E6FE34D94CE72B86DA55679080 10: 5C17EEBF4E348CBE3278, 29FAE7B470CB652C501343FE23B25894 11: 1EE960BFAE360302D834E3, 8F8F475EB9BAB29CE14A9CF42C30B148 12: EFF6BA1F2B1389237C6C045E, C895302DD8E75096951EF5CA63BFDD67 13: 5A1179A4047334CCD9162F36EB, 110987D37F45422625DEA402BD7580EB 14: F26E2C27E7D287B182FA42879978, 530FDE90C13A01EBCA86449073A3B035 15: 77BFE79B4BC87116EC5232606E890F, 280994EB0E16C7CF10F31BB60DBF52C8 16: 9926A4CE1AD70B89CC0050A58B958742, A635B4272EBFA1F83DAE270452D877E7 17: BAAF99CAE4753E3304D6F8F9C0CD366C68, A6F606AACD0B87923B43C3EB61AC3965 18: F72453C6765352A31494FA02B388E407B1FB, 0A446D28B7C5845C3621B4D3A0FA98DB 19: A7372589A86B2E137F124A96618095EB5E1435, 3C59A6A858947FEBFD32441E37309F1A 20: 5683E13A4E82A1AB8B3DC2051B6DBF2E1F2BB417, 459D1B0D2CF2C30B5ED5C237D07DFC19 21: 33594C4B84536C23DA5AB2117E9267258CCE5DEC3B, 6E4BB70A72343E142AC4E31CE0FE6A77 22: 332EDC9A3BDB90DBCCF317AC55BE5855CA9BCA2A73C4, 9FB310E5FFF5C754EE1E5FFF865F1656 23: 734618677055469335FFD574B008F2C68B78633F79010E, FAD31386E42BB4EA76A643A9004A8CB4 24: BA6F6ABA2AF35895F7F966D71F4E91A0BDD1DD551826F861, 25A3EC1C91C26283BAA5975390285AB2 25: FF519213E858E36AC8D92450F81CA46C8CA8AB129A997EBB36, 0D4AB2B7A5EB02242C01A81CEBF5D84E 26: B1F80058C3B4316EA86E9A898CD0B9C0366DFCB2AEC0799312D5, 0F4FF2759EDDF6349F4E23F284FAAD2E 27: 00BDC15012F8183112D5C3A135DC60DC9C764A04BD39A8E041F1D9, 0C68BC9E6A6BF1B01743F3183C9B7C80 28: 3022FD12969D925365C553D98D59E5D1EC494540909D1FA794F41E18, 05E61844943E78DB9BD417DDDE9C98B2 29: 4F4A4554BFED6BAA09E3D8843C4EA3807B8762799C1D21289A46575389, 3A59A6DC9230020FE061466A92BBCAFD 30: 6AE735EB15D9B39C8AD0E54F45307AAD97DB9F8A2A66BDC9BABCCFBD54A3, 0BDB365E493A9E160EEFD7DE24101870 31: 4AF19F00EAE55FED2304B94FBCA29383042F2BE711041323C1D9F14BA63383, 94561581E496553D068052BA698683D2 32: C2438BC46A92A465E0DB41E638CC6C8E0029C4DA842CA4140D73F90985EABA9C, 0F5A69F52AA8D8508D09E642511E54E5 CCM-rc6 (16 byte key) 0: , D01FACF2BB577BFA6194800E53FB4A00 1: 65, 92E48F7300FA2697E9E0FF80DD187237 2: AF5C, 332863BC515649D5BCAB6A2FE5F5250D 3: E7C89D, 49A641F027C65A15100009D99E79CF3F 4: ACB36D46, 53DE328A8B4B14CAD363BED53DACE8A1 5: C3ADAE6CCF, F713F5079BD77046F95D8685CDF522DC 6: 5A8CABC912DA, FB97B059D2BE1273497FA8D2739A1505 7: 27F101DD6D0894, 266ACEF34476A0E64410D209219335D0 8: 66164DA09BE2F46D, EFC64C01890A5B562AF39ADFC48E1CA9 9: 1B0018895394753995, FA894E1C882D96E35A4C238708931F3D 10: D346062826187BAEFC3B, A036AE1D3C02E2AD23541DE095AC7B84 11: EFB375BA1138339FA1B504, CDD4232FF4664D59D5AC6BE32CBE1B35 12: AFCF494078D7D7E6D9803FD5, 07E06ED923F76150BE82C1DDCB62C4DD 13: 75DF2EC91379408DA426A444E4, 440ACDF2A6567FA3A5009DDFE502A1A1 14: 3B36B62B01E324E702694305DD29, 4093598607DCD9993845D1837D211FE2 15: 7DF6595C9711B164C99CB246B4D57E, F364993B2C187058F466B62D11E0F94D 16: D317EE9EE1746D1B89A4CC52D88F0819, 41856B0B229D38344FA718E04CA57A8B 17: 85252277A97CA7553007995BD5A0DCD372, BDEEAB636BD1ACC8D5A23F658150FA30 18: 36FF305AC6EF662C155A1C15A6C195D3EC88, 9AC48EF07A510E308E06E79C0C80C3A0 19: 51645A614313E978F6DCE7BBDDEDC33E3284AB, E9F7723E763AD50161C0671C4034FD0A 20: 3CB9E6D0730FE05F903D338708AD8E34BFBB3285, 8A12185DAD518049F0FAC945A8FB305A 21: 276E37D246C40ABF32DC83007B95390EE801CDA6E3, 73FA1D310D031E0A0A3A1421661B4697 22: 4444BB070EDFBD1AC59D0BF70D66F48F0830069F3562, 9DCB6A99CBCCE3C8AEF29F06AF5057FB 23: D16BA084CF82EDD2E43349311140BF3A2E37DE40544BF3, CB93C5AD60C700D4EA653136101AACCC 24: 3FBAEBB36E2B74014043BA7D72F899B0D8DED883F592D778, 54DEA31D7EEA863A06A16D6C9B25DC13 25: 3614B5428B790793F31E23670A38A070B65DB8E51C61FEA9C9, A91B750FD7ABFF18376C982DFA0C8872 26: AC15FD90A4C254BA1406BE7DBA5694BB2625F634C69F45CCCD04, E6F97BCC8526BE3C04BA139EB50E65DF 27: B506E83557E48553BD8557411D2C17D64005E734BA5A5FF1CF98B1, 6FA001758A19F783A71C97AF1AA61F94 28: F07721663400838947EA1B9404D9683556F2D911429A9F59E3F5AD31, 376A1165A30C919E96C3706A4AB5DB37 29: 98B5EB8FE0005E515A585D8F44D838FA590054EA5201CD444366B6F71E, D8C58448F601F2C05F24ED2CC349C78B 30: E36E2FC225767CC1E2C388BEBC2C81C340FEF5B504575D5FA49682E1C214, CFED56F38CA4F84E6E1E16CEF50A6154 31: 7A9FDD8E481B822B3D282AAF726944101ED61DAE73782DE055D7D305E36B27, 328B10841E977041CBD13C39CD70F03F 32: 48AE8B5FA027930A7BCEC27468D795D0D8E6099C5F0558361B3AD20C1ECFF89F, B180AA9353E9EB6A22710A4DE872FACB CCM-safer+ (16 byte key) 0: , E106F41D61402E532662213EBA471BFF 1: 05, 1749600C7045647DCB3293C0724E7A21 2: 2355, 80DD597665723F4AEFFF760C5C6C5EE2 3: 5F4CD8, 59AE54E63A8CF4DBAD050B42CE922013 4: 75F63A43, C31B6BD3125C036C99507DDEE0197201 5: 51D4D87B8D, 0F3872088CDEB0E958C35F343677AC24 6: 8CF6D81A274C, C8E688954E72A052B5F8D1CA46FB44B0 7: 5EB8283B299AB1, 5977CB96C8D439DE3A86AE0452A2EE34 8: 829B1A4EA8643EAA, 1E892D3DFB73A469035CA81DD7F937D1 9: 0FEEF9504CF0F4E282, EDCBED7C61E8E2D24392B4145218F0AB 10: DEF7679D3073D461A94C, D7ABAE561901CBB30FD7D9467C088B3B 11: 625FD679C7354A74D62893, 450E3954857640DDF4C7A95A6E202A1E 12: 3C9E76E4E2D4D95FEABD5C90, CD4467F695B7ED8973AEED5A822B347A 13: B1B6294ECEAE6AEE4853731CA9, 6042302DAE598822BE8554BE038119CF 14: 204BF480582D4BA408BAD23CEB52, 4D6B87334E1BFB9BA2D42B89B24165B2 15: 277591770E3E2DB97A3011D9616991, 75D0A4B9937748EAE7794056F7A8A7FE 16: 5669F75D0C908BFF7B82095231B86DAA, 3E816776A73FB89276534A3646C0F8FB 17: 37E621EF5A043A83FC98A65329891BC031, 159A823EA61B3A47B42EFCF12F304725 18: 18AC6ECF3F478A0797BF813C871235A9D309, 9B415B1B3A933B22C9027E2D72764956 19: 671484C7587DAAB885C7F2FAF030081B452CC6, 574A63D113A5ECEC877D5A368A3160AA 20: D7AB0F7D46B7ED976C8F6E7D0C6AABE3CAAA5A6E, 266C7A025C4EDF657DD42EB82BB6616A 21: D60E4CFC6500E237276A69F35AE4BBAE17371392EF, 6ED2A1673F8B4DB795547D9D93D76D8B 22: FAC6E21979D8D9896C790CB883C29F84D6820AE4FD4B, 1C7B6D73200E3C2DC5C701152F38EE8E 23: 39240DC2B544CA8BEBBB4EA499FD48A5EE707198AE8AC8, E7FFD169552665ADE7B9C0DFFDD04EBD 24: 6BE2C24172CAA192D55CC3E640E34675DD7F441CE5DB0FC0, 760CA976355281F76E49A2856A4EC7A0 25: 0E20427218D6447D6E23FA4832CB8D2A172B23FDC542B41524, 27D0F37E109252FF5E6F6F703CA784F5 26: 0AF75BD89028A5691B8B7993B9CE4FD24334A312DE28212C8B2C, AFE4C6B193B0F1796FC9E6C23292C060 27: 6830D8E2E6DEC1476796DA44C982D36409E268F966283A66E801ED, 9E2C92D5B30EB0943E17869ED4C789EC 28: 75ED280BEECD7768F7E032071F0E06D9D6BF1C9FF8E5DEB536DCD4BA, BF0DD11D633DBA5DCD25F4172765570B 29: DF1FAECC1DB24718236B18B90B354F405FD5DE1257EC43F811F4A43DCD, 48D182E572E794350BBDA91FD76B86BC 30: 176681E38ACACCD3C625F554C1F7A2D7C2C474C9444EAC8929B8C36EC05E, 080E109FFC5D247F1007217DD642BBA3 31: 8A8172C21D88A1FDD43089C545C308507617F7BDB02C47CF2719F1484407E2, 1A0D10B0AF5BE21BF19D570D3FDA5BCE 32: 0A93CAE2B95517773A4009FD3438231A207B9D46AABAE83FC4E1057EA4E2D6B4, 717AEF2F55DC8669F7E2D0298F8A7BE9 CCM-twofish (16 byte key) 0: , 33B3DF1B59C84DD3C15E4FEB66173303 1: BF, 92DCEBF1C11DD0B028DEC944A555E4C6 2: 8A4F, A859C7F76291326D821BB3C7519657C0 3: BAE755, 14D7C2EFBCA1063460FEFCEBAE3AD79A 4: 25695BC6, 9358BC434B14B59ED17F9C0D3F51DCB1 5: 1D9FC70ECE, 2A86578FA3A8C702E2E6723DB9A9893F 6: AC39F1DF3661, 3F9C71EE0506FD2BAFFEE7200D22CD92 7: D330A915EED9D0, 22DC25EDF5ACDEF8358BE2A3082112BC 8: EF913ADAE6380507, E87D72BB6395EEEF2AD4F546B4033DE8 9: 5EC16994E762BCE467, D7700F7BF4FE026A2076F161C3383A0A 10: 7EEB4910B7C2B540B490, 40C88A977E1DCDDABD749ABC9A0C60F8 11: E5DD32FF54D39451CC2AF8, 541B1558B5AFF6E9EFBEE496D60AD65C 12: 242C2900F859966B6627FF5C, 1CED148098350F3A5D1B5634180817A3 13: EEF025B9E4EB867B127EBD19D4, AD0179A07AD1418C25F40E123C2BEF47 14: C5E812B0AE37098686E2C4452C12, 02FC88AAA62E34742BB8577A651E922B 15: 7BCAB32D1A871A62F9C781AFCAC60C, 2CD1C11EE197D9E130359F76E7F49251 16: 1E82D8B8EED9A730D1670F0DCFF17B60, B7730261560EA6CF715FF7006D5FEFE2 17: 0E1966992E360DC81312B28ECA6865B811, 10C40ACD169CB0F2A6FFC99F9A5516EA 18: 5F5418C1322BF7EB828CF27C1F72086515BE, 90F8ED0447171A10476DED39F7518075 19: 6C552506FA167FB8AA12E9F416930031487D4E, C992009F83F31A7BF922BFAE68C4134B 20: 38429D966676406B17638DB7F9F7205250408BB2, 3385A50E9789D2C63835A80EFE9CFAE4 21: 56EF426315EF96BE4C60B49F41C9BDDE2E0CDB3C22, 2D51D5B4F5B04BEF3BC1A7CF1AEA70E9 22: 314B075C097EE531ECCE6AD7CEF22A72AAFCEFB02029, FB7A7D84D23FF524D060871D90FAC106 23: 61CCCF7E2A9B3E46CD0A94D7F4A7617BB0DBA2D989907A, B3F4D46094732F3EDD81E0755F0C52EB 24: 7A812A3BCED4E0A72FB81218BD5A4E33D69CA18834FFAE61, 487F80588B41F4E1198124708987667D 25: DBFAB77EF07AA4C9ED2B05500BDFA00FE3F19F15F97A74880A, 84504D9EECBC6CE11B18BD105DE55E2C 26: E676D4739B01B5101E36BF8D9F4FAE8F767C028E83A6D5B39664, 3141A05669807BCA30F0934F599FD077 27: D8FEBD069D87C1EE504CB8F72ADFF2166B14BA40B17B4DAA439668, 1D99A301943041C2F7A71432DA736FE0 28: D98E2A1CFFAB28341F92C41971A21AD0FDDE733EA25F2607967CD0C3, 42E05A53BF4F1A6C5B7F84742ECE031B 29: 13FA412B484945C1FE8291A7EB8F8FB78D2DC2C72C5132386EA82BF4A6, A1A8E8B026DD116B0F9C73EB14C1C7CD 30: 10ABD2DC25C8BA594FBFA9312E69C1A2DBF326475AF2080E55E3611FBC0E, 49DF8A5171DAC3FB684BA2CF7FBB3D3B 31: F401D2123619B81F54F307B783362CC40FB4FB2433CF51F5543A147BCD1FE5, ACBB670CB3722059B4B9FBEE67703E98 32: 839A9BFA1D3CA37924BC6648DED2291FC61736A3638906D9C5DA28A66AA684AC, CD07B83C8E0C3E6FB4115A149BDF6FDA CCM-noekeon (16 byte key) 0: , FF73C6775C61DB36D9B5EEC812091FF7 1: 5F, 7D2AEA62A5202E3C4FBE05F33EBE4CC5 2: 0EA5, 312ED15FDDAB6EEEAC6AF9BE9CE698FA 3: 968F95, FA1AD58B85B93B5A4B5096C881F773C3 4: 9A8F4069, 8911063ADDF79E27D9DCEFF3F440E6D7 5: A5C0376E27, 9553F44B0BA8039527F8E05CD70AD8B0 6: 5B097736F3DA, 405B7EC685FC94903B36AC8E700558B8 7: 616810AE303B2C, 64C95A2DF5263F7BE6D1F9F3CF88EADE 8: C8D69A2E1170532C, 073A7E426266237FD73D8109F55AE5D3 9: 3E42CDB7DA4A72F2E0, 48675EA4302CA6BFE5992DE96CE43BB3 10: 88532CC1F3E321F66D64, 528B3516C6D9A4B5390DD32C2A2E6C19 11: 9216A8FC9A961E7F602F7D, B03047186B783844F5B6757057576B38 12: 89B0858D4FDE6795EDE19CCC, F4530A2DCA823307AEDE5AF34E5C4191 13: A676E20BB0A5E84FD0B9149BF7, 11B823B315DA93B0E15780851526D4BD 14: 903AD5C108C43A80436FE2117EF0, EB1C79C7DF20CE2967A99783EA8D6EF8 15: 81774C36F46F67159B7FFC24C080D7, 2E9E4812D9A92977EC34922782B6420D 16: 63FD1C3F692D64B2DA3982FCD474A5D4, 04171AE84857713A9BABBD4564875D33 17: B1BF6AD99F83C9173C6C021ACA74C5431C, 38D17D4F6AA3C24B8F3B465EAACE0A1E 18: 0948D1ED59F07DE44A96A76E05B0B6F7C309, 1848D886FCFF35E85B0DC3CBE5BEE7FA 19: 3458E5911222F9C555A1054C7D9748876DA39A, 584AFAE72FB6065A74BE016CF39D2E86 20: 641F3867185D0605E9D666AB605187E75A1299EF, 6F9332E6FB5EA0CE811E3345593CD163 21: 0676622D07733EF31A765AAB1E713FCE329277FB16, 88547474050FFC986930CC04BA8A03F0 22: 79861EC2FD2BCC5C12B69F30A1575FC66AC1405281BB, FC68EEAC8F39ED69D312AEABF8000084 23: CB2731835A576F7F8F2C2786D786FB6186E2F85D89DA3B, 3ED9E95BC51CF6368E6EF63667B35BD8 24: 3CB1C02FADB6DD5483BC5D3C03D944102CFCEDF82B913402, 1C3F60C989A6FBF41A7AF4F29115C334 25: E69FAEA5E3D0B76EF9E70F99C5918D934D0E9836F248DB9EEE, 7F1916B2CF7C9A5E3F5581D365ADBD31 26: 36779AD755A9DF2DC3C5824DC2F7DD4FFE038628A4E1A1C33AE7, 2BDED3703468D267F8AB7EC0AF8F1E65 27: E9D325646A41EE5AA7DABCDE98DE83440A7DC02714BA0AEE017E22, 972F4D7832F3371C60DCD04A6DEDEA15 28: 0FAAE3F6028A28A80BBFE71FA7AA9042E538B41A0D514D6EB4EE6029, F7B3925495E260249ACC6E1CBE956BC5 29: A9CC39EFFEE354C0E0579256AA85CBAA7B10E670DD3828A7A05DA0F49D, 28D9D20187AFE70AD9DD16759F0EFEB5 30: 032F4BBB4EBF2E65758C541FDAFF2107DDBED399739849F8EBB41AF9711F, A3436981ED637CE5EEE01B380C46ACAD 31: 7B321ED831CE96A603668E3E74BBC7453749A03D04A1B38E95966E6CC488F0, 88D1DADF2C1EE0BA579D0A8A90C1E62A 32: D862B0BD0E2178AE05AEFB14F34C791547C5956F1F3B5BD525926578DE383A94, BF32CFE059F27222DC55D3E7CE7C5F10 CCM-anubis (16 byte key) 0: , C85F41475E06F25682F855C3D45A6523 1: 25, 437BD73ECB8CFFAD9B2876F08D4BDA36 2: 5ADC, 5C762058A5EF71278B69F567F18CBE51 3: 95E541, DF099E8218AEDE8087791B38298334E9 4: 2DAA84E4, 7437094198E4AD2647C2618248769A26 5: B9641C5855, 91B02EC44D22460BFF22BB40C799E20C 6: 102012BCEFA5, E60488DA65D683182F0EFDF9DA52A78C 7: 8F14972CA4F8EA, C26B51F20ACDEC7DCA911500CF1241ED 8: ED2714B652972256, 8BA29459D5D370FC608EE362B55B7633 9: BF58A269A4F59CE0A4, D69080820F836E5B5CA8F393E61ED009 10: 44AF1F715ADAF26C6EF0, FEFBC7DB75ECDDBA4A13CBF9A57873D8 11: 77CDE1B951F0803893642D, FBF8B80B061703504D8D3A7718366B6E 12: DE599BAAC9D3EFD9FCD47E44, F636EC35D172D661F01746FF86688B95 13: A792B8359050C4866572977415, AE67D4EED92E63A14003FBC936EEF43E 14: 62D5A7A4DFB78A175831627987CB, 25F7B440DBE9902C28B28E50BF02C516 15: B6F289459F924C76586F4EEA0C1CAA, 54266B4424C3AF6E81F6CC4F2437F54E 16: 884B7DF3395F063DCA26BDF9F2FEF4EA, E3C2BFA1964EFDF78FDB9559C8031C50 17: 774962377B8731F2F301B930487518801F, F35B54264711D843D23636BA6CFA3E4C 18: E9C8D1164F2B196C7305406179B232E45F1F, 2A13E034A136EBC0ED3361737EAD214C 19: D3DCD242C952C5589E00B65CD826CA87691B8F, 9D624D482042798DB896B55D801EAD98 20: 57065B2655D4799C0478FE7E8463A2215E758875, C8FB052F14F9DF6731A9C8B566E71D53 21: FF736FDBD23593D9BC9A0D8CA7D819F550EF969322, 5CC3023029790BFD43204B27D52D7D7E 22: C562B7387B8F1D3DBA22DD1636C9C4AB443F2FF15F70, 195C928EAF88BB4ACBA8A01B4EBAEE6E 23: D0AC6EA8A804DC261304D4821E6AD7FCC2F0DC1A299B9A, 34FE2034CCF09A98DD50581DA8BCBE39 24: B65933A7D7C8EF19C1BDEAABE2B4CE5E821459D953565EF8, 42B20EF142EB228803D6AF47C6482BEB 25: F1F4FCE842EFEF563F6F047956E6706DC9B178D00D82776D74, 3ECE3050D8C80319821D5F57A7CA7066 26: 4A3F10F4E34210A5CA1B81AD4269CBC3FD68AC662BF0E9DC9935, 0BC0724AA9A194D8C75EE6FC8E7F28F1 27: 077F3C055303FD669BC1A370B18AA7F31D3C8CBFF5A69381404FBB, 872C7946401BE70E677B79EA13FB0F58 28: FD39D32B27FE5BB8E6512C642D490E0AD0866E386580AE115C85ED2B, EE81712EA57DD54DDEE98EAB3285E6EE 29: B45ED179290A6064188AFF6B722B37F8C3E984EC37AB5F47B353229B12, 186B3AD0C9F60D57E84992CBB2B0F71B 30: 83FF1FD179D518A414148C15BE566BE4CC3DBE9FF5319A651E862811F152, 4B2942C66565EB9139A83C2EFD549D55 31: B8176469E6A0D5797ED6421A871FEECDE48ACF011E394981C43AC917E8FFD5, E9B01383DB1A32E6126BD802A6C6F47E 32: AB6A0AA29B687D05735167D78DB697BA2478BD14ECD059AE9D1239E7F2AB48FD, A560A30FD87CF28BA66F5B2638567E4B libtomcrypt-1.17/notes/pmac_tv.txt0000644000175100001440000003153410621351501016053 0ustar tomusersPMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are OMAC'ed. The initial key is of the same format (length specified per cipher). The OMAC key in step N+1 is the OMAC output of step N (repeated as required to fill the array). PMAC-aes (16 byte key) 0: 4399572CD6EA5341B8D35876A7098AF7 1: 580F7AA4AA45857C79BA2FB892228893 2: 24D2D1DBABDB25F9F2D391BB61F4204A 3: 083BF95E310B42A89751BC8E65ABA8B5 4: 69BEB9268CD7FD3D7AB820BD7E226955 5: FD71B0E647ADB4BB3F587E82B8B3401A 6: 07EA46271081840737CEB1AC9E5E22E3 7: FFA12AD9A9FDB5EE126084F82B381B10 8: 8A11AF301AAFEAC8A75984ED16BB3292 9: 368BDC3F4220E89B54C5F9D09FFB8F34 10: 8B6DBFF776FD526147D1C4655626374F 11: C538C09FC10DF38217CD8E799D8D1DC9 12: FC1264A2051DEF73339432EA39443CFD 13: 8AF37ED2FB2E8E30E9C4B75C1F1363E1 14: 4295541FC62F6774068B8194CC9D9A46 15: CFAF4D8EA09BB342F07131344DB0AA52 16: B6CBD6E95959B2A8E22DE07E38B64D8D 17: 3124E42DE3273B0F4806FB72A50F3E54 18: 252D49403509B618AB3A6A1D99F9E9FA 19: 9CDA75594CB696EB19C022DDA7324C10 20: 33BB8AE43B7BC179E85F157FA19607D0 21: 12FE91BCF2F2875379DC671C6F1B403E 22: 416A3E519D1E406C92F8BB0DDBBBB6BF 23: 6F98DCCD5A8D60DEAF612ACCEDD7E465 24: FFCE7604609B2C3C050921854C638B7E 25: DD2BB10AA07A5EC8D326BB7BF8D407F4 26: 468BFE669FCDF354E4F9768FE1EAF8F6 27: 01724D2F2C61EB4F380852218212E892 28: 2D90EC658F57138505598C659C539A3E 29: 6301EAA0E1500FFEB86752744EFFF23D 30: 3CCB177486377616056D835F6F857F7C 31: BFB3C7755C1F4543B516EB8610CB219F 32: D5C505847D7CFFD8CED848F6CB613105 PMAC-blowfish (8 byte key) 0: 3B7E4EFE92FA46AF 1: 746840017C38C892 2: 3B6A92C731465B64 3: D89D3B05143B6704 4: 43F70D54B808B7CE 5: 84E4063AB32F046C 6: A7E78CD5CCD23805 7: A78FB083475FEF10 8: D4F6C26B5386BA25 9: 184768A079853C90 10: 0702E6C8140C5D3B 11: 786D94565AA0DF4B 12: F6D36D3A2F4FB2C1 13: 7BB3A0592E02B391 14: 5B575C77A470946B 15: 686DAD633B5A8CC3 16: BDFE0C7F0254BAD5 PMAC-xtea (16 byte key) 0: A7EF6BB667216DDA 1: B039E53812C4ABDC 2: 87D2F8EA5FB6864D 3: F85E3F4C1D9F5EFC 4: 4EB749D982FB5FE2 5: 0BFA0F172027441A 6: FF82D01F36A6EC91 7: 3BC2AA2028EBBD7A 8: 15AA03A97A971E2A 9: C974691F5D66B835 10: 4FC7AA8F399A79ED 11: 2633DA9E94673BAE 12: 82A9FD48C5B60902 13: 31BF6DA9EE0CE7E4 14: 26B2538601B7620E 15: D103F3C0B4579BE5 16: 031346BA20CD87BC PMAC-rc5 (8 byte key) 0: C6B48F8DEC631F7C 1: F7AA62C39972C358 2: 0E26EC105D99F417 3: 7D3C942798F20B8C 4: 415CDA53E1DE3888 5: A314BA5BCA9A67AC 6: 02A5D00A3E371326 7: E210F0A597A639E5 8: D4A15EED872B78A2 9: AC5F99886123F7DC 10: 69AEB2478B58FFDF 11: 8AB167DFC9EF7854 12: 945786A136B98E07 13: F3822AB46627CAB5 14: 23833793C3A83DA9 15: 70E6AB9E6734E5A6 16: 0705C312A4BB6EDE PMAC-rc6 (16 byte key) 0: C7715A17012401DE248DC944DEEBD551 1: 5B804C6CCDF97BB28811C9ED24FE6157 2: 7528378C052F4346253CB0DFA3D251C7 3: 6DA86EE0B28606861B1A954D7429A93C 4: B4DFF84C25937FB50EE79D4037323160 5: A60FD9BE5E1FF67EC9734776C8781096 6: 81D3F8EDC0A197DD3739EAE648F38580 7: 8BAF47F02120E898916D678DBD0C1641 8: 7A9EEC96F10B7CF557B61EF35BB55B08 9: B88C11221014F8AE048E56C427DF4A46 10: 4BBA8EED89F357861A265006816D9B04 11: 8497C1D55010A65ED8C3688B75A7CABF 12: 95E1720C06A373CAD1A22F432F26BCCA 13: A175FB732692831E96AFB587BC49E18C 14: 54EBC04FCFD90302907BF77C4D8AC77C 15: EA9F13EE5548CDF771C354527CDDA09B 16: 4EDBCFD0E2E6B321530EB31B3E8C2FE4 17: F412304C1A5B9005CC3B7900A597DFB5 18: 3B9247C12BB25DF048BF5541E91E1A78 19: 39626488635D0A6224CD23C13B25AE8E 20: 40305F5C2FCEF34E764E33EF635A3DC5 21: F84499804086033E85633A1EF9908617 22: C4D263CDC7E0969B8AC6FA9AD9D65CB8 23: 6137DC840E61EA6A288D017EFB9646FC 24: 8619960428EB29B1D5390F40173C152F 25: F0464509D0FBDBECEC9DFC57A820016D 26: 630EED23E87059051E564194831BAEF6 27: 4B792B412458DC9411F281D5DD3A8DF6 28: F2349FA4418BC89853706B35A9F887BA 29: FEAC41D48AEAB0955745DC2BE1E024D5 30: A67A135B4E6043CB7C9CAFBFA25D1828 31: EC12C9574BDE5B0001EE3895B53716E2 32: 44903C5737EE6B08FD7D7A3937CC840D PMAC-safer+ (16 byte key) 0: E8603C78F9324E9D294DA13C1C6E6E9B 1: 3F1178DFC2A10567D4BCC817D35D1E16 2: 27FE01F90E09237B4B888746199908EE 3: 4F5172E3D8A58CD775CD480D85E70835 4: 74BED75EFAAB3E8AA0027D6730318521 5: 54B003AB0BE29B7C69F7C7494E4E9623 6: 8A2DAD967747AEA24670141B52494E2F 7: 69EB054A24EE814E1FB7E78395339781 8: E59C2D16B76B700DC62093F0A7F716CC 9: AB227D6303007FD2001D0B6A9E2BFEB7 10: AE107117D9457A1166C6DFD27A819B44 11: F84DE551B480CED350458851BAE20541 12: B0EB5103E7559B967D06A081665421E0 13: CDB14F3AD1170CE8C6091947BE89DE7B 14: 24FA2F476407094152D528FCF124E438 15: 440144B31EC09BD8791BFE02E24EA170 16: 697D268A46E8B33CEC0BAB8CAF43F52D 17: 587CBDE7608449BD162184020FBFCC8D 18: 3EA999C2169CC65735737F50FCD7956B 19: C6D692698CD8BEEBF2387C6A35A261B0 20: 46DAB3AD3C4E2EF712FAC38F846C63E1 21: 7261E68B530D10DDC9AD4C9AB5D95693 22: 4D0BA5773E988C2B7B2302BBA0A9D368 23: 8617154626362736698613151D1FD03A 24: 23CF25F68B281E21777DC409FE3B774A 25: CA626956C97DC4207D968A8CC85940B8 26: 24C39BE160BDBB753513F949C238014E 27: 83CD65C010FB69A77EEDEA022A650530 28: 1A72DC8438B927464125C0DFEACDE75D 29: 546054936A2CB5BFBB5E25FFD07C9B51 30: 0EB81A268F1BB91997CB9809D7F9F2AD 31: 7D08B4DE960CADC483D55745BB4B2C17 32: FD45061D378A31D0186598B088F6261B PMAC-twofish (16 byte key) 0: D2D40F078CEDC1A330279CB71B0FF12B 1: D1C1E80FD5F38212C3527DA3797DA71D 2: 071118A5A87F637D627E27CB581AD58C 3: C8CFA166A9B300F720590382CE503B94 4: 3965342C5A6AC5F7B0A40DC3B89ED4EB 5: 6830AB8969796682C3705E368B2BDF74 6: FF4DCC4D16B71AFEEA405D0097AD6B89 7: ADB77760B079C010889F79AA02190D70 8: 5F2FCD6AA2A22CEECAA4671EE0403B88 9: 70DD6D396330904A0A03E19046F4C0BF 10: 8A2C9D88FA0303123275C704445A7F47 11: BA0B2F6D029DCD72566821AB884A8427 12: C8DF45FF13D7A2E4CFE1546279172300 13: 512659AD40DC2B9D31D299A1B00B3DAD 14: A8A0E99D2E231180949FC4DFB4B79ED4 15: CA161AFB2BC7D891AAE268D167897EF2 16: D6C19BBDFFC5822663B604B1F836D8BD 17: 4BF115F409A41A26E89C8D758BBF5F68 18: 02E3196D888D5A8DE818DBCBAD6E6DC7 19: 995C9DD698EC711A73BD41CAAE8EB633 20: A031857FADC8C8AFEABF14EF663A712D 21: 124695C9A8132618B10E9800A4EFACC5 22: 997E5E41798648B8CE0C398EF9135A2C 23: 42C92154B71FB4E133F8F5B2A2007AB2 24: 945DC568188D036AC91051A11AC92BBF 25: D5A860CC4C3087E9F4988B25D1F7FAAE 26: 6CD6ABF8EDF3102659AFFBE476E2CBE8 27: 45ECD0C37091414E28153AA5AFA3E0B2 28: CBA6FE296DDE36FE689C65667F67A038 29: C4022281633F2FC438625540B2EE4EB8 30: 864E27045F9CC79B5377FDF80A6199CF 31: 0D06F2FAEC5AA404A4087AAEBC4DBB36 32: 0F396FE9E3D9D74D17EB7A0BF603AB51 PMAC-safer-k64 (8 byte key) 0: 2E49792C78C1DA52 1: 7A5136F4FE617C57 2: 6FC8575F6F3D78EC 3: 7C0373CAEAAA640B 4: 9D469E7FF6C35D31 5: 7755D62DD7D88112 6: ADD9E7855A958C9F 7: 752D29BA8150F18E 8: 0954649A99596104 9: 05D4D75A9FAE233D 10: 1AADAFD7B4B250DA 11: E7A8F31ED74DA32B 12: 1A74DF61BDB9DF94 13: C38A67B1955C4E0D 14: EBADAA44746ADF16 15: C0BFBB092CE81D8E 16: 984975657F3FF2B0 PMAC-safer-sk64 (8 byte key) 0: E8917E1629E7403E 1: AE8061A5E412A647 2: C969771CE5A9B0C6 3: 78159C01D0A3A5CB 4: 1DD4382A8FC81921 5: 4086880FD863C048 6: A520B45600A3FA1D 7: 0F0AB5118D7506C4 8: 22E315F2DD03BCC6 9: 5ECB5561EE372016 10: 446A9B2BCB367AD6 11: B2107FE2EB411AE9 12: 5A539B62FB5893DF 13: F44EE1EB3278C2BA 14: 293FEA56D1F6EA81 15: F38F614D2B5F81C4 16: AB23F7F8F4C12A7E PMAC-safer-k128 (16 byte key) 0: 7E0BDE11EC82FDE6 1: 8942FB017A135520 2: 0B073E6D0F037A02 3: DBF88439D671ED4F 4: B89427ED1121069A 5: AA8573DAC66D2315 6: 12DA3144BEF13FF2 7: EF80413CBA281B3A 8: DFA7114D8505EEBD 9: AE53607F3E6F4A54 10: 3F2C9395CFB9F78F 11: 67EB7C5F02760AED 12: 3EF4CBB4AB5B8D1F 13: 83B63AFA78795A92 14: 5DE400951766992A 15: AA8791A45237CF83 16: 7743B18704B037CF PMAC-safer-sk128 (16 byte key) 0: 8F1597FFCF6FB7C1 1: AFF8BD8FF9F3888A 2: 65F89D82869D8B42 3: CBE1F06476B2D5BD 4: 4878D47FDFECE23E 5: 4751A9E6D61AB2A2 6: 003AC162AED4DED8 7: 1F617A5555092C22 8: 088EE0C35B607153 9: F840B485086F9908 10: BA99E0FB5D7D0976 11: F04AF6DC4BAF6887 12: 5DBBE40AF2F67E4E 13: 7F52A93E87E29C9D 14: 7B26A14A4BD5B709 15: C34F26E08C64F26B 16: 291A41D479EC1D2A PMAC-rc2 (8 byte key) 0: E5AF80FAC4580444 1: 6A15D6211EB4FF99 2: DDB95E9486C4B034 3: 9764761DC2AAD5C0 4: 1B1CD2E799D44B4F 5: 4F80FE32256CF2EC 6: 7B70CF31C81CD384 7: 9BC10DD9332CF3BB 8: 628189801879FDD8 9: 5FC17C555E2AE28B 10: E20E68327ABEAC32 11: 5D375CA59E7E2A7C 12: A9F4CFC684113161 13: 3A0E069940DDD13C 14: EAC25B6351941674 15: CB8B5CF885D838CF 16: DCBCDDFC06D3DB9A PMAC-des (8 byte key) 0: 086A2A7CFC08E28E 1: F66A1FB75AF18EC9 2: B58561DE2BEB96DF 3: 9C50856F571B3167 4: 6CC645BF3FB00754 5: 0E4BEE62B2972C5A 6: D2215E451649F11F 7: E83DDC61D12F3995 8: 155B20BDA899D2CF 9: 2567071973052B1D 10: DB9C20237A2D8575 11: DAF4041E5674A48C 12: 552DB7A627E8ECC4 13: 1E8B7F823488DEC0 14: 84AA15713793B25D 15: FCE22E6CAD528B49 16: 993884FB9B3FB620 PMAC-3des (24 byte key) 0: E42CCBC9C9457DF6 1: FE766F7930557708 2: B9011E8AF7CD1E16 3: 5AE38B037BEA850B 4: A6B2C586E1875116 5: BF8BA4F1D53A4473 6: 3EB4A079E4E39AD5 7: 80293018AC36EDBF 8: CC3F5F62C2CEE93C 9: EE6AA24CE39BE821 10: 487A6EAF915966EA 11: D94AD6393DF44F00 12: F4BFCCC818B4E20D 13: 2BE9BC57412591AA 14: 7F7CC8D87F2CDAB7 15: B13BFD07E7A202CB 16: 58A6931335B4B2C2 PMAC-cast5 (8 byte key) 0: 0654F2F4BC1F7470 1: 3F725B162A1C8E6B 2: BCFBDC680A20F379 3: 027922705BCACDEE 4: 44E2F4BE59774BA4 5: 3ABD1AFC8EE291F7 6: D96347E717921E96 7: 96257299FCE55BC6 8: C2C1DA176EE98170 9: FD415C122E604589 10: DCBCA228D45AEDA4 11: 7801FBCFAAB9DF75 12: D38CB38574474B7F 13: F5C5A23FF3E80F37 14: 83FA4DAD55D092F5 15: BDC0A27EE0CB1657 16: 87D907CACA80A138 PMAC-noekeon (16 byte key) 0: A1E4C84B5958726557DF0855B37AA551 1: 5DE20299CA919D3365B493D3D4895F92 2: AF7E70C336571A857F62A18649EDB197 3: C5F55CFE1AA119C352B64252AD246CBD 4: FEF68A0CE08E8BA315B73B62F861824F 5: 8321C2958DE4903DC12C42A8845ECC20 6: 370466D1324AECF1F5B42E0E01381613 7: 5CB900190F5CACBACFE5EAB0CC289D87 8: A13C043E6CAAA1E34601A93C497446A4 9: 865E11622A4CC8A9E1408E00F56C4543 10: 9DC42C26868374649BD17D69D025CA1B 11: 37D33C11B433C91DA09925CA9E86757A 12: 1373D769C270E7137C953AC0F8F37941 13: 7E81DEC583348B1E2F6267ECF82CB994 14: 505B6329338556518FF364CAA730F5E8 15: 0C085AEEB315968B0BDE904E8BBC6FD0 16: 5FED63259364BE7E5133FF0507DD2D4C 17: F7EE5C80A99AAEADB49E7CC69BFFF679 18: 4388FA5E763A641130940EB705BEFD08 19: 1BC31CA79EBE1674CEBE01BC9988267B 20: BE88961637EFFE2D6905D104FEDD51A4 21: 9C341004FB22AFCC496094E3207CA761 22: B9DAA3620E38FFC7C5D5E7D2D8FE3DE4 23: A38D2E571F037061B4400F1131FDBDEA 24: 61DB71AE77A6EB47F2E9E14E8CBF2F4B 25: 9903A072274CC048EF2C51493266D9ED 26: 1EBEA421DD08859C17DDF39B20A82102 27: F425858618E1A86F4912E4714EFB9E75 28: 3B3D4EA07F7FE6DDFDD02D624ACDFC9F 29: CEEE256591D701514EB17DF73B08A970 30: 5CC56D5D46120C530A23B6C511C685FC 31: 68E484CE18BE28EADD0BBF23291B8237 32: ABD58A9CDF8AA68168A1A402074CF520 PMAC-skipjack (10 byte key) 0: 9CD94B75BC43B647 1: B069ACB82B12BC7B 2: 6DD40E71EB03E311 3: 74CBED61D77DBA7D 4: DD1B7E0D181537FE 5: ACB5B96FA0AD1786 6: B34E01EB2567D381 7: 9623DAADE57B9549 8: 8BA384BABB798344 9: B147AA9D5C5C67CF 10: 0033C520F4C67523 11: 42DAC184BEABC3E5 12: 428029311004AEBB 13: AC2BB1C0F0ED649B 14: F7CAA9A3BF749C1A 15: 2C5BD475AAC44C77 16: FEB892DA66D31A84 PMAC-anubis (16 byte key) 0: DF33EE541FFEE6A97FE3A1F72F7A38FC 1: 0AB28675AC3923C6DD9F5A8E1E2928D0 2: 2DABF75D6403E1E1CFAB3E6869FB1088 3: 95835D49E09740180B79E394FC2AA744 4: F364D6DC2C2078A519E5BAEFE858AFCA 5: DA4C66A4805FC91FABAECC0D3AEAD850 6: 487660FADCAC7B326C492AA051A1DF49 7: BF07835AA1A548FA7312509AF35CE3F3 8: 3CE8A8B1F324A700923AC0B830D53D99 9: 3C54D99AACFAB26E34FC1B0B6BB9EB22 10: 0A559F9D107ED76FD19227FDD0752B8A 11: BFD9E74ADC40B9C7446FDD09558FA584 12: F1130F663BC0FA3B1066129E0D1910E9 13: 535EAD786F0D211DE7AA78F3CB480803 14: CDF5855F00A4C310D95B26751B01A28B 15: EF6686E999D5A9C35A96D25BB9DBBF57 16: E795733AA0AAF16D8F7AB1A8E9C55E54 17: E03CA85727D5CF06F56BB6465BB3E5C5 18: 6EDDDB6D2292EFF584E382E1BACD1A49 19: 7B7FE0D8821836C1AA95578071FF2FD2 20: 5F8CC568338400746B61A9286B7CF262 21: 32DEE5A11E9EDB04BDF911837CE0FA4D 22: F1A99914F13B17ABF383F36157FEB170 23: 99F541647F382390043CAE5332E3114D 24: 34C5EBB85693A1979F8CFDF8B431A5BB 25: 1BA7266568F1E7B4A77A869D3021AC0F 26: 0FC675C99C24E859F8CE714E86BF5289 27: CBFAB21F5ABC47356A43BED806D873C0 28: 9659AB1A4D334B622629721F98EECE3A 29: 644C8BEE41F03BDE7652B03CAEA31E37 30: 5B3447AFAD934B4D1E4910A8DFD588E7 31: BFF403342E8D50D0447627AEA2F56B23 32: 19F468F0FB05184D00FABD40A18DB7B2 PMAC-khazad (16 byte key) 0: F40CEF2E392BEAEB 1: C6E086BD1CFA0992 2: 513F2851583AD69A 3: 07279D57695D78FF 4: 051E94FE4CC847B6 5: 5E9AAA5989D5C951 6: 310D5D740143369A 7: 9BB1EA8ECD4AF34B 8: CF886800AF0526C8 9: 0B03E2C94729E643 10: 42815B308A900EC7 11: 9A38A58C438D26DD 12: 044BFF68FD2BFF76 13: 7F5ABBDC29852729 14: F81A7D6F7B788A5D 15: 93098DA8A180AA35 16: BACE2F4DA8A89E32 libtomcrypt-1.17/notes/eax_tv.txt0000644000175100001440000005637710621351501015724 0ustar tomusersEAX Test Vectors. Uses the 00010203...NN-1 pattern for header/nonce/plaintext/key. The outputs are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous step repeated sufficiently. EAX-aes (16 byte key) 0: , 9AD07E7DBFF301F505DE596B9615DFFF 1: 47, 57C4AC75A42D05260AFA093ACD4499ED 2: C4E2, 26C5AB00325306772E6F6E4C8093F3D2 3: 16177B, 852260F91F27898D4FC176E311F6E1D1 4: F09F68BE, 700766CA231643B5D60C3B91B1B700C1 5: 8472705EDF, AC4C3359326EEA4CF71FC03E0E0292F2 6: 14C25EB5FD0D, 8DBD749CA79CCF11C1B370F8C975858C 7: F6A37F60670A85, AFBD1D5921557187504ADE61014C9622 8: 1AACFEAE8FBAD833, 82F477325D6F76BB81940AE25F9801C2 9: 069414324EC293697C, B980E21C09CA129B69E9032D980A9DC5 10: D8174DE9A2FC92B7DA9C, 1E42CC58BA2C8BFD83806444EA29DB61 11: 2C087DEA30F8B7EE510990, 83DB400A080C4D43CAA6EC3F1085A923 12: F36B93C272A703D3422C6A11, 1370C3AF2F3392916364BBBCC2C62EC1 13: A0F33477BAE2E28E6747AA3193, B626DC719528CAC65DB0EF94E35422CE 14: FCF5193506052E8BFA095C1A5205, F5BD02E0B3C91CC7D6FAAA8A9A76CE6A 15: 3797D7F8599B8EEAB39C56241880DC, 0B70003E77146B903F06EF294FECD517 16: C4BAD0E0356FFD369110C048D45D81BE, DE7C2B1D83BE2CC8EA402ABE1038BB79 17: AF5C358BD31CDCAC2F0EA5252F1C3BE1E4, 2D700986F93B22DFE6695C2A243B4E42 18: 7DEF9056FBDAF491D7206B26B19DEF617AA1, E71A7D00BE972D85C77931D7591B2151 19: 6E9B2C0A90BF9D38A6EA3B5D2B9B2D97F938EB, 5B483D7F15C39602C2918181E57DA341 20: 7C5F68DEE9BBA3B04F11D5FC7C9C7FE6E8B5025C, 0AE6A12D37A9C10BB1A494E16705DC05 21: AF0A886BF673BC72045FC074F06A0176C96105E2E6, 06B2DC9A2868C23F86D710E01E37E07B 22: 5F228A986DFE4301EDBAF07A02E114F1B30932995CD1, 74EBF68627C78B1FD024A59B56B2A8FA 23: 911322F60555118CBECD8DD82F186AC19514316E8D48BA, B6A8BAF2F175CD0C71B63B1EF37E185E 24: E7F52730CFB808EFDB376A5D5DF31A7EF8292DC5FC37E9BC, BA2AD158A2D2E5CE01296402B592E1DB 25: B3F8D7CA47D8D86E94D670AFBAFA3B8D9E186C97DC029D4705, 709D2D2B9975D4729C19D4EAC430E65E 26: 7178FEC027AFADDC2C03518E75CF34D207CAC2EB1537A0DBA520, A315F034CE5E66601444402520F55DE2 27: FC230B2B8522F53459D0B968421469BBA7E683ACB0190393B2870F, 48679A78E470E175CF3D3E9B46CEDFCE 28: 35A641127C78C721ECDC50866C21637FDC9515E41CE60F09015EA713, 0062987222F6412B7AAF8A9ABF6FBF98 29: 3D42D6C113421743C08A6F682CFA0E517D5531BB66241C02EC4DCC26F7, B1AAFE11FA2D6E0C870177DDD7F98FF0 30: DAD065B4669B7C59C8392D8E7BD7E64BC01CEFFF27E335B25A328D356F0E, 8973B9B9ECF26DAB58CCF0787EE928E5 31: EBE626F9E241FD233D9781C359430C982667AA26921B62E98FAEC502C01B0B, 2AC0D7052A2CDCCE8E26FEA7595198AA 32: 64D842B66796A797C2B4C6905742FDF2148FFC445E192F9E03B53810C082F788, 9778B345EC12D222DCC6DBABD2651750 EAX-blowfish (8 byte key) 0: , D8C4C23A6AC0B7B7 1: 2A, 5E0E4BDDB60772FB 2: 7695, 7581B16CCC9C45F1 3: EB14C8, 6223A121CFA216C7 4: 5A5C809C, 4A47658796337D6A 5: 8BC2041181, E1FBA8DBA00571FC 6: 89C666F015FA, 2B4A76A0E699FCFE 7: 86C1FA92484AF6, 31B3B738A261D6F5 8: D1F401C145C9328B, 4C4A045EB489F59C 9: 70C9C7753698324A73, AB298B5B20567EB4 10: A50D9D88DC101B6DC8D2, 529DFCBFD13B8E6C 11: 7CC2885C2BE79C44F28FF2, 566255022B40C81C 12: 6902D58347C29250EE07981C, 34619AF18E14C690 13: AB6C3C4AD3EC45143392B642DA, E6D2DD323DA175BB 14: 7065B28BA8AB67B2FB7B6D5E3FAF, AEDCAA54F4B0772F 15: CBBA14A74AD4ADC0EF036EDAE42D51, F2BFFA4D81BAC034 16: 60A315193F58144F5701D547C79FEEED, 912FDBDB05467DF5 EAX-xtea (16 byte key) 0: , 86881D824E3BC561 1: EE, 4C3505F04611D9C2 2: 80C8, 6A3428BEEAD60738 3: BF88E7, 04F1E99E9F5906C2 4: E06574B7, 33B0153AAEF9776F 5: 42D950AF63, 4A0F415640322FDF 6: C30F6AD46EC9, 9646FE909D2B95CB 7: A0049FCA856A14, A0257289C6BBF278 8: 2814B0C1358440E0, C4B0A2354925E887 9: BF4F062B52C1E489CF, B56442A3CA57A041 10: 63DF433956831B8780FC, ADF9ED0B46DCA19E 11: C317FD079817F50E0E8A16, 2EA0EC993FC603AE 12: 2BD12FDDD81EB11660346D2A, FBC6F69125BBA88D 13: 85D356536FE2843C6BBE60EDBC, BB2FEFD04F230E79 14: 22493009DB01B4746F4927A8C4FB, 64CC08471D93C9AC 15: C0F3C0DB08DC93FBA725D1E02DE084, 77B762213DDCCFFE 16: 568B66D3112556BD98FF9339E9C002E5, C8355F508219FE0C EAX-rc5 (8 byte key) 0: , 169C7954341EF44D 1: 22, DABFDA9A0B0BA067 2: 2E54, 6A3D6D9AA5877C5A 3: 2A6ECF, 2A34A3AF5DE8919E 4: 9CC5F84F, D3F673EDAF75E3B5 5: FF5611756C, CC647FAAC8D49BF1 6: 74C939BEB31C, C335999CCFE8F5FA 7: 7976B6F7709B5F, 2A7969C5FD063A88 8: 421EEC5022276174, 2C9BFB1EAC3C54A2 9: 6A4761CD266B1C0ECB, 3EA3CCEBC85FAC4E 10: 7C09201098E764239A2E, 8043ABA9BF4D5AEE 11: 8CE26277562F646DE33C88, D72AED48895E3B40 12: 52150F44D37D121560DA87F6, 58E865E22B485906 13: BA0A73B45F93ECFBFC3AB3D8D0, 683D52FA47FB1A52 14: 96546CBE01054AD24CC95DB54724, D80D0D530E5D1DDE 15: 61E654BB18CD26FC36C09F874DC2C7, C65884CB9D9FEC1E 16: 1D77B8BF02CDEAB4A707C07628826D5B, F18D1730C3D64701 EAX-rc6 (16 byte key) 0: , 1DF8B0B92A3F0C951C425AF4830E63FD 1: 1A, 8A2959EBBE90180999994DEB7036DB85 2: 435D, 7EF00CB57DB7B4155DB530D75CE6B025 3: 08A6CF, 2ED6AF0F2D5BAB05F623D389480A01F2 4: A86E54D3, FC69547C8BD922A5BF2F7B26C4D20F98 5: ED0822E439, 0007A3C6DEFC6C912C0E5B853B520368 6: 7BEFC7FD4054, D32C43A4D1086D57C5BCFAEE04EBC600 7: 5235E58E79287C, A27E9C781327C0FC7C55410EB0C828A9 8: CEB5EE99BE521F4D, 547F46383987F2A3582A81A3BCF9B280 9: 0358B063D5F99C3770, C0A73730512CDA6AD49599775D59EDA1 10: 434B9AEE07DFADD0A332, 499BD88881E558E09A8E822BE27D2496 11: D47849E650F350BB622D74, 638E37A84E7FAAF8F5D77F1B061773DC 12: 814592F568284085E79A024B, 9EB1405E8422FE50BC0D88D837A2C650 13: 6F2B55EC91B591082053AF692E, C48F91EF01AA43A1EE3B36D233DDD48B 14: 506CBDD2901838EE2F178B6953DA, 03778957F536509BFCA577B23A18F726 15: 446EE435D3D1848B51BB8C5F7BE4A1, 1129EAEAADE534940546D43242A4C839 16: FB9D2B150C42465B1685D8F069CC06DB, 41E2940F5DC63CB4E2FBEC25ED8A31E6 17: 9684F683260107BE8FEBBEE1D3EEDAA7BD, BAE7C116F7FF96631F4ACEE95C65CEF3 18: 5082B1FE48CD3AB58F63C2DCFDD4069AC736, 19AC7B8EE315CBB7131A283851B32266 19: 8C72AE495B6F003A3C784D144E84E88885F78E, FA4CEC023740A8D670E351FBCF62C1CB 20: 815D6361C7AE34C9D796ADF9C71ABC46AEF88BC9, 9A1F7288C61A6623B9A82748137ED7CC 21: 904A853E2E96BD2B85AAB3F5DFB900E9B3642EE667, 9AA90DBDD461CAD20495DCFBCB513DD2 22: 79D738A462F727B3D3C529ED999B6FDCCD991D1C5A4D, BF0987BEDDE650D73CAE7D380FED3431 23: B2DEFDB7D503A84E83155A04B8DE8C8DBB68C2FC475007, B7CE900CF43CD518024123C76F6DA328 24: 9E723E15439E12F6C46DF8A309AE1E97B6FD18436259CFB0, DF8B6E1E23512CC4CF5FF531A1908F69 25: A7F0AD03CEBCC9202718AA164886E1026975306A664C5AC7A9, 4A771BF8B9A4325705C85E5499FD98E9 26: A53A92AD1C6835F28E04EF591E783D36F3D76E489B31B87BEB7A, AA263B52A6E6A043DE4D7029D4DC73F5 27: 79BE3C38291A7F77E932C8A9DEAC08DE6442EA9B3895B101A14E7B, 33B84DE06342E675E019CD0237292ED0 28: FA108123C5A69571CFDFE8C3D00535121FDE3096DDC0D700F8F26A5A, 764025D7CA1A3F2C54D28956423B0C77 29: 36EC2D67FD977BD2B73DB6D8EB756B3EADA13690E1B6DFC12A4781B34B, 4BC6B38DE3B02283D92F4DF19A5C48C5 30: 96D3243C945905C9732B5927E46F00886D511463B38C86002FC26B65AB8C, 5B5511CDEC35687AB8425AB22D58B4F1 31: 9CF83B87BEA3374AF7722E999863E3DABB858B0383383EAC7757F5B80FD44B, 1E0CBC961940FDA93B73A92DACFD67F3 32: CE3BC3C9FA5EF4AFE5272B3EDD24B1B003FED2C2E501528CFF44D3FABFF52CB4, DC94FDDC78AAB2B7CAA1E1EF149AC355 EAX-safer+ (16 byte key) 0: , B120C7B37450C46189712E4DFD1F0C44 1: CA, 82BA1869C5FF1EF2A4F6ADC1E7DC1F1D 2: DD20, 6BD5601B16C9943A84AC1F99A176E6D1 3: C1C09F, 0911DC63AA414C004E2BD825BECDC93B 4: 27E43F59, BD858F084B082F76814DC385E1FB20D1 5: 2A9A92F246, 5ADC4A32491934AC0BD00FCE686B26F1 6: 52C78C0CD6F4, F35886F46C03EDCA10B3D01CF07B1E0A 7: 23E0D3CED3795F, FE33D96FC98B78A30C0A412C60E93992 8: CD3FC9961559F239, 9982364A61609FC41068260267231EE9 9: 6EA46CB7AD7505C1BC, BB15053EF0F78B9091B3064118F3E9BF 10: 05D9BA230A56CCA0703A, 1338E68E3DC992B6EB2685C668E75869 11: 7AAD6049DFDCA6771AE42B, 35267E431051E1812495615324C4CBE6 12: 8695091532B83B23C296F620, 7B2EEA861E9A91E6B6A911E10FC3FDD1 13: D909DA4BC7372ACAEA78E6A0EE, EA6C1CD16180DF0B07F4E204A4B4FACB 14: 7DEC8443600D0563AEFE87A2064F, DA454728069B3B409889664783588189 15: C042FE656742CD2FE5D9C212D18C6C, 5929E4AECC2CA047BAE948E7023FE4D0 16: 0B84D3CF59EEF7319633F4A397D47CF8, 31F892FFDB7535DF5D9143456E404163 17: 8C9E57AAFA7969B142742B63AB73286600, C418231C44F96660DDBA8C26B3BB3681 18: E9EED66D370A3A6A39C7E0E570D96F807EAC, A4AFE8D1D3C31B956A3BDBD043E7A665 19: 1A5D47992DA5597D1449B4C8DD47B7404C7657, F3ECEE5182014FC3365FDBC4C33CC06A 20: E7C7945FD1AFD3F5DCE666D8A5A2E8A3C11A7A5F, 86D78B2FBA7597B8806BED505B52BDF6 21: 9E2165B47B29CBC4ACD50660E011D691F061209969, E9B1E860BD02085177E1A94E1EE6F3F0 22: 48EA2945C8DD3FE09407BAC8973A861DB15B788C8FFD, 502926712EDB1B3DD13806052C6C75D7 23: F37D46B35B60819EA52B00457D79155C04B55972D0DFA9, BB2B7D210BF0570F422640BF81F39B9E 24: 12E85C0C78227205CC682360C79E35BF58EC6551CF8FE2D0, 042990D7A58D458C570A15DD375DB4E7 25: 4F6C15109DE980DD14A7F4C27F48671E4787C53A564232F427, B097A5990D8067DD89C21473150C070F 26: AAC472E49DB101B564A8A01E2C80C0C6AE9065D332C2DE79FAB6, ACDD587A7DB86542E195DF73AF1C1CBC 27: B9912CE18019C31692A1F7E11D9CCB20297ACCB9DC62C47C01D2C2, B0ACBF028CA5B15E0035D2EB8CA916BE 28: B4F2B1FE14A1ECDC9C8EA1A0120395E6ED1E69D3FC85DD0F3F90F350, 9A561EBC769369B95B9CB74FC6AC27D3 29: 3FE397C8AD02689B7437A37861F0907AF1F6014A293B46419348771C5A, 6B7BEB9BD5018FECD71BE5081C7C2544 30: 5019089142199F7207E1B7731B8B247A18A685B231499DF12A73F5D67D37, 307E93446777005BA1B088F178A0DB6E 31: EAE8F9F02F8DB3D70B78B08CFB0949D99F1A86C958A8E3823736BCEAB86BE1, 6C94F48591C18BF9C450515B73379973 32: B9C795F7A87305B4AD36DBA10B3B1C70B329D29E49C8C6A932D96A74334AEE4A, D18E6E233FEFD6E5C7148BDC1504299C EAX-twofish (16 byte key) 0: , DB0C02CB069E3773296D3BD4A87A381B 1: 99, 7D21D19E9C440F68E99F1F2EA2668694 2: 0696, EA590EC417C88E23FD23917F9ECFB0C6 3: B9B082, 82D4C9B68DDB02C906496413E13A2D68 4: D6B29D74, 5BCE5CA4F662E883BF7FCAAE5FB2CE01 5: A59C9CB009, CBFB04226D1029A7EC9D64A48A6729BE 6: F4924FE3E355, 3D85B3900DECA0528C815F1447A1F209 7: 679C88D52FB519, 931C7A863C3701D8015FDBD8696C6C30 8: 26DA41C0D115375E, 7627E23E791A4DCB0FA5ED71B1ED2288 9: 8FEC6EB7016AD2B178, F65ED0286A724F0CB2EA317D5022B0D8 10: B5F22415B1334133C531, 87C4F3A8991BBB85984BC4D3305A5CF1 11: 23E1D0ED2E820AFE7DA2FE, 100499F1093FAB2ECF73B643594E98E3 12: 79519ABA91F46B8DAD6D5335, FBDCD1FCDB20AB99135F28A714C6992F 13: 5968D0B4198A0AAD3D0395018F, 781F22E2DA98F83398FCF911B2010057 14: 4E55B14432B601E3EF2EF567CB15, 8BF6E53D7657E56EA3DA1BFD9C9EC06E 15: 6ED89651CE19B3DD1EE5C8780B5015, 131CFD657D32D4E1B35140ADDCA0E13A 16: 2295A968B4D072D12757756247554850, F35FAC95C2AA4155450EAAA6E2E789B5 17: F9B2AA2AA502EA79BBA0C5EAD932B8E1EE, 0ED81AA40B9BF39A9AAEDDDB7A04BEA6 18: 385055F1C1C26C0472A504B4CD225DCA55FE, 24831680B56368231AC54227D737F582 19: 771529585C741A3F8B1C973709892F255A99EE, 2A132B4BF96FD5109DB04459103F5E84 20: E7A2197D9FAA8AB8B303B5EC71AE34AD5EC5DD66, CCAB6518371EC8E0A9E9EE4F7CA5878B 21: 279E54F755EAC6B57375B9EC4406E43DB3139D740C, 7B6F26F2C0ECC9F2DF4EDD7513E6E0B7 22: 27816AA94CBA2BF98E49E595AF5B3FAD12BF1D6F1AC6, D04876C5492D275F15C834E3CF794F0E 23: B5658DC148855F68B282211D879F688F3C142FE555CF81, 4539CDA8A65DB9047AAD76B421B81120 24: 72F0BD4F939C2C9B4FA734DCB0AE4FB9BD342BC8459ED2FE, CEA8469BC0457EBF3418C1114288C904 25: 70568245E6E6BD5D11AD0C74030D7AE08BA05057DEA0FBF4AD, 71554FDE6B87477A51EE4499D78783D2 26: 8702D35BE07D7ADF70684046CC6C72FBBBF821E0BBCCBC973601, 33CC6FBFDA15E306919E0C3BB2E22BB6 27: 0BA23F4A6174165D4A8BA80B7C875340B0F8B2A6967D34E106BC22, 00E6679496714236EECEC84B9AF3072E 28: B9E25ABA84C6BD95B5149E7616FE2E1D6FAACEAAD77A636C60279176, 8D8AD0B9D4C709E1DA370EE01611482A 29: 74759711F6D542581F9F83498FB616638D092732BA07109BF4B5BE045C, 71A40DC777BD09F75362F7B20E0B7576 30: ADBF7E98926484BA2C7F6CD7CD9734FC19265F68AF3BFCAEB025F6296E37, 8DF15B5F69B67F7DABE44E3666B55047 31: 2DC26D449379997D110309B2A0DC2760FCE8CADB4B14ED580F86C70F69C9BA, EFCB60EB2B25737E256BC76700B198EF 32: 2B1890EB9FC0B8293E45D42D2126F4072754AA54E220C853C5F20FBA86BE0795, 1A1B15BBC287372FB9AF035FB124B6A1 EAX-safer-k64 (8 byte key) 0: , 9065118C8F6F7842 1: A1, 1926B3F5112C33BA 2: 2E9A, 5FA6078A0AA7B7C8 3: 56FCE2, 984E385F9441FEC8 4: C33ACE8A, 24AC1CBBCCD0D00A 5: 24307E196B, DD2D52EFCA571B68 6: 31471EAA5155, EB41C2B36FAAA774 7: 03D397F6CFFF62, 7DFBC8485C8B169B 8: 8FA39E282C21B5B2, 2C7EC769966B36D7 9: FEA5402D9A8BE34946, A058E165B5FFB556 10: 6CDEF76554CA845193F0, FED516001FFE039A 11: DC50D19E98463543D94820, 8F9CCF32394498A1 12: 42D8DC34F1974FB4EB2535D7, 77F648526BCBB5AF 13: B75F1299EF6211A6318F6A8EAA, C5086AEA1BE7640B 14: 1E28D68373330829DD1FFC5D083E, 33EDA06A7B5929A2 15: 85529CF87C4706751B0D47CC89CEA6, D031905D6141CBED 16: FE5CB61BAF93B30ED3C296EE85F51864, CC484888F0ABD922 EAX-safer-sk64 (8 byte key) 0: , 5254AB3079CDCB78 1: 75, 798DCF14FEF8F4D1 2: 0300, D5FCA75DAC97849C 3: 520F98, 10E357957CE20898 4: 80E2764D, 5C7F46656C6A46EA 5: C48960CDAA, 3CCF44BD41F01CA8 6: E0E60BD9AA2C, EBB493983FCEE79D 7: D13D8804906A1B, 6EDDCA919978F0B6 8: B7AE14C37A343BFB, 2369E38A9B686747 9: 5DE326BBCC7D0D35E9, 041E5EE8568E941C 10: 13494F5B0635BA3D6E53, EAEEA8AFA55141DD 11: A9BB35B14C831FDA0D83F7, 4002A696F1363987 12: E242043A1C355409819FABFC, 63A085B8886C5FDC 13: 204598B889272C6FE694BDBB4D, 194A1530138EFECE 14: EE3F39E0823A82615679C664DEBF, 1EFF8134C8BEFB3A 15: 8579D87FD3B5E2780BC229665F1D1B, A832CD3E1C1C2289 16: 74D7290D72DA67C4A9EAD434AE3A0A85, 96BAA615A5253CB5 EAX-safer-k128 (16 byte key) 0: , 7E32E3F943777EE7 1: D1, BA00336F561731A7 2: F6D7, 8E3862846CD1F482 3: 5323B5, BD1B8C27B061969B 4: A3EC3416, 170BBB9CE17D1D62 5: 0C74D66716, 7BD024B890C5CE01 6: 6158A630EB37, B5C5BD0652ACB712 7: 17F2D0E019947D, F9FF81E2638EC21C 8: 68E135CC154509C8, AA9EAEF8426886AA 9: EDB1ABE0B486749C21, 355C99E4651C0400 10: DB0C30E9367A72E8F5B2, 631B5671B8A1DB9A 11: D4E5453D9A4C9DB5170FCE, 75A2DF0042E14D82 12: 3F429CC9A550CBDA44107AA7, 2C2977EA13FEBD45 13: A7CA22A97C2361171B415E7083, BFE81185F31727A8 14: 170F79D8B0E3F77299C44208C5B1, D5ED9F9459DF9C22 15: 2E24312D2AE5D5F09D5410900A4BBA, 2FC865CA96EA5A7E 16: 8F3C49A316BA27067FF2C6D99EC8C846, 9D840F40CDB62E4B EAX-safer-sk128 (16 byte key) 0: , 22D90A75BBA5F298 1: 3F, 98C31AB2DE61DE82 2: 584D, F4701D4A1A09928C 3: B9DEAD, 6E221A98505153DA 4: 06D4A6EB, 0E57C51B96BA13B6 5: 7B58B441CA, E28CCF271F5D0A29 6: 7950E0D1EC24, 2ACDDE6E38180C07 7: 65A4F4E098D7C6, 7DC1C9E9602BACF2 8: FEBE4E72BAA0848F, C4607EA3F138BAD9 9: 9B7BD6D6D655985AA3, 8B2C58A9530EA6AC 10: 60C92F925D1478470203, 51E6F5F6DC996F84 11: 7B40769370E651F64AA654, 74F1F8A8D3F4B9AF 12: 7215832C2FB9C54DF7A9C686, 9BF9AEF14F9151D1 13: AD0F9C79008572AB8AE2466EFF, F375D0583D921B69 14: C05076E2C330A0D25D7CEC80597F, 843C12F84B00A8E0 15: D18F0563AB0278140B0CD9A9B07B34, 262B1688E16A171E 16: 650747091F5C532EE37D2D78EE1EC605, 1BAC36144F9A0E8D EAX-rc2 (8 byte key) 0: , D6CC8632EEE0F46B 1: 4C, EA19572CB8970CB4 2: 5537, 3EDD3253F6D0C1A8 3: 206FA6, 20FA88F03F240D31 4: 17EE8B40, 702E8194F1FCBFDE 5: 2A89287136, 31C5534786E15FB3 6: 3A6AEDC7066B, 3C663A4081E1D243 7: 8BC5203947A644, 6AAC806C92BFBD6E 8: 2E0274BBE14D21A3, CEB0E0CB73C3664C 9: 9C4B292B0CF17E3A29, F23CD535559023EC 10: 8E322734308F85662877, 46363D7EFC322821 11: C413C405767FF5F98E3667, E7BA35D8F3678E7E 12: D77806B7A218098B1569EADC, BA67C306E5C0181B 13: 4BE5EF74F9E9799A4D636FEA9F, 4C511C44ADBA4030 14: 7E19969170C2C8D8AEBA8C7FBC2C, 54CC6D466A2DF6DA 15: 2EF1CEDC1DD3403CF440FC5561BE33, 61C6FB277E93701F 16: DE052719153EBACE9D7B19F52AC4282F, 4AC2A96F2FA8634C EAX-des (8 byte key) 0: , 44048B7F240B6F5F 1: 0A, 37009B7D4E09953A 2: 03BA, BFD2FD7758961728 3: 37EE10, 16A6AF96DE888A19 4: 07F44290, 100CA84AA0EDAA1D 5: 389EF0023B, 9614FB800A533268 6: 3F4DBA8AA01C, EFA6B55B7ED5E40F 7: 8C7B837896EAE7, C113CE8F664CE3D4 8: 7011D993D8EDB0C7, B4C370A919F60497 9: 0DEB30A31351B13D7B, 00ABC82DC5F3A1AF 10: 8D3897B2CBE323D6EE1C, 7A2D15627CA1441B 11: DBC002C817DEBFB419F94B, D8EB87F86D6ACDEF 12: 17048E2976FA85AA849E9A80, 229FCD1C9D1E3B9C 13: 30B989EF646544885A478AC198, C1B7EB4F799105C8 14: 5C2E12A7F118A08D6FD585F9C839, C358679FEE6FE7D7 15: 8D1A1E888BBB8648E638C4E74E11B8, 685E006C441448B8 16: 93AE906B8BE4EAC8ED6D8F48F04A7AFF, 71DD7AF752FE28FB EAX-3des (24 byte key) 0: , 8914311BB990B725 1: D8, 2094EDC5D03E54B1 2: FEE5, 781CFB0EBE3895CA 3: DECF5E, 59918E8A5C4B459B 4: BD583AAD, 2013BEEBEEA795A1 5: 2BC01C6C78, 0B1134DBBEAB5D3F 6: 4D5EAF01A895, AB4D17516ECBA50A 7: AF229F90614480, D3113C0A9D133CD4 8: BCA6F375DF4568E0, 8E9EAEC8E77786BC 9: 575F34219E6DD8DB4C, B40C75139E5D1860 10: A199B8AC433B615EC96F, 774AF803698ADE3D 11: 718A2975DD9A872A68AE10, 3B9460F849CBA7FB 12: AB38E148180F6E2FFBB96F91, E3EE3B8FC50DADBC 13: EB10E0233507459D4A6C29EE80, 8D90B46BB1EAB27E 14: EB48559C320DFB056C37458E19B5, 9315F0C4AF8500EB 15: 9E8C73EADA105749B5D8D97392EDC3, 2E749EE66C1E6A16 16: 600FA4149AF252C87B828C780AEFF8BC, 33D7D11DCDC19936 EAX-cast5 (8 byte key) 0: , 382FB8F7E9F69FDC 1: 99, 20DA959849B3F7AB 2: C54B, D05547C6AFA3484A 3: 579836, AAA92B2321FC50C5 4: FEB7AE55, 639EDF01C4FB965D 5: EA8A6023FA, 01274B3ED5CE102C 6: B7C4E995121F, 712BFE27CAFF6DDE 7: F44236660B0004, FAC51D1DF8EC7093 8: 01CD7E3D0BF29E8A, 049C47A45D868D0B 9: DAB170493DFD6E0365, 6F3AEDD9A3ECF4FD 10: 82C9EEC4803D9CD11FA8, 32683C0A9128C6EA 11: 324AC59E87B244ECE0F32F, F6B095AAB49353CF 12: DBDDAB11D02C9CA5843C406E, EA728FC46DDD3B04 13: D67376C2A4AD92E7DD80E39303, CAF72B7E7C237EB3 14: F2B9BBEF08036C2982C6DDD06918, 70A29D780C22752C 15: 96E3D9141F8EBF520540C2BC9A9C23, CEFC86A1CD48203D 16: 70CABBA983179106AE7FCD5F1F31D5C3, BF7F9168F4F82F56 EAX-noekeon (16 byte key) 0: , 556805EEA595CFB9A30FAD196103D7FD 1: F5, 0A7DAEDFB656526CEF4DDBA8087A227A 2: 7B8C, 249895D79962D5B4D18FE07366281B72 3: ACFF15, DCC489D24832EB106F576AE6B6EB957A 4: 08ADE7DB, 0D3215999E9960EDAB29B78744C7F139 5: 66139213F6, 505E1E7141D043E903C26EE0959EEECD 6: 078B79F880A8, 35B7EB326A55E50332866EEDB682EC20 7: 2809E34D9667D4, FFDEC555F68524A09A6ABACA372077D9 8: 93D267DE1EC635D3, 4FF3561990A56E4B374618722EF850FF 9: F377A4D93FF32F4A51, 91D4070423A90FC54D305169C03F49ED 10: 6244B717E082993EB7A1, 2E3A8A354AFA9473667ED7FDD46BE9FC 11: E917559625D25E6E5F2EDA, 19295C37A70314CC9A1D11FDE8D23C92 12: 1E6DF2EE112A893AB14DFA92, 12C4A89D4CD65F8116A03A135AFD3701 13: 47B18CD762E011770E203CF605, 434909A97E118B20D3AEDC79AFE33A9E 14: 72D9A1A7DA6F33D5E0B927F9F32C, 779C23714FCAA2B2321EC7FB5B03E222 15: DA8B830FFCB3DB274807F780D33240, EDC2F1C8A401F328A53392597730B007 16: B53DD2BB840AD933D36A7B5FFDCCFBBB, 4EC0E6D1F916BF633869239B672B37A1 17: 42936BB9A936C30408660855F4F47F3314, F0DAA6DDA15585E1697ABBB4790B15B5 18: 00372E47F5BA016F1B2A1E680B76AB02052A, CDBF3D241BF7FF96D3DFBEDDB872E901 19: 8AA236B0C8BEF6F67A97C2DF90628F6E5838FF, 731DCD61F7F26004C03519F9500EA824 20: 55338647812FC9D86CBDDCED7120268A4D43F8BA, 0E61B3C835CAD95FD49FEF002C014E72 21: 435820B28E52154B47A04D5E635D8FE37FA47FC985, F6A96DCE4917E8D7C610923627E80970 22: 0D30C15B6FEB4A48B14DD15D41A4B25D442AA677B25C, 28E15CCB74AE992C68BDDC8D87802050 23: D9D701F9AD6B0E13D2CDDA15A5194E7CE8BD2C02137391, 2DB9A15884E9C996C3D6B5BDA44B9598 24: E2390AC5CE10CCFBC72106A52C7F180CB477E3C193CBACA8, 22D3F7DCD6947EA4E78DF57A8E1A9A59 25: ADEFB7D9500658D34996AF6BE6336CD78891064EA1DB8E9785, F239D67D039A15C620A7CD4BE4796B3F 26: 89964C90ABF54A6DF9F13C3681E70C702D80A17BE79F8160F30E, 6336F729ECE1ED7368669D75B7E2DCBA 27: 576B2813CECDA4F905BD5D58349EF070FF41B7EB6BB2B01B061B0B, 125324CBF2ACF1011A44A99A11EC8AFC 28: 430B957481748519A60494F0B5F698F34B1A8235B00AC0D1F0A4442E, 1E80A7FCEBBB8E1E12D6831906154485 29: E781BFE5FCDE0BFC056CC86C4A0B9DD3B815BE8CA678204CF47289B5B5, 190D5AAA9EC1CB4CC86FACE53BF1201B 30: 78BFAC07A9B7B2AE9329BF9F9BF18A1A49DD9587001EFCA00E9AD9752764, 4FB5ECBEEB0995C150EBC66508FA19C1 31: 7D6C20694109DE21F7955855A8FF832347518DD496C2A114DF142C68ACDEAA, B25D4BB34056DC091A7A3950D46C32EC 32: 3E1E4395DEC1AFEA9212B95F37E679B6E2D14DF23C5DE49018C2C8038CC4AD45, 9A6DE7BD41A21918AD504490EF4E581D EAX-skipjack (10 byte key) 0: , 85F74B6AFFB10ACD 1: 3F, 604DF8BDD98A0B3F 2: EA87, 792374FE07588BF9 3: 0169CA, 489AB8AF69DA3306 4: A7AC3EB1, 428DAF508E24B583 5: AA9028D5B3, C0A44EDA71FB2C86 6: DA97BA88A061, DA2EC34077F42585 7: 7E25FAA41CEBC8, 36D4987551E06D5B 8: F662DA6C9001CBFE, B7DEF76680C316A9 9: 6D3F73EC716E1DA897, 5F0F83BAE4D3513B 10: 2A300F585BEE9C889743, F4756C24DEB72A9C 11: 80518B010DD77C82D19106, 50FF5CAA365F4A70 12: 6E579A2173C861B6F37B4CD3, 81E3E5ABBA8F0292 13: 5B04829880A72C38871C7021F3, 6B26F463708A3294 14: 934177878E9A9A9FB4DEB3895922, EBC1C32F0A2A3E96 15: 07AF486D1C458AAB2DBF13C3243FAD, 87288E41A9E64089 16: 84059283DF9A2A8563E7AF69235F26DF, 351652A0DBCE9D6E EAX-anubis (16 byte key) 0: , 8E20F19D9BA22ABA09FB86FDE6B9EF38 1: 3B, F4201E546A9160F989191942EC8FD1D3 2: 9F38, 4E3CEAE3E1CB954E021A10E814B71732 3: 4F4769, 3E8F35A6A5B11200E9F1AA38590066CD 4: AB41F5FC, EC4C97A8892AAF5433106D4AC8A49843 5: 414F95D61B, BF831E34D1E3FECB973A8C730ECA2E6D 6: 4798322F06D1, 005BBC30BFEDBE6463536C4F80D1A071 7: F256B6CD1BF4F5, 468A28F0661884B846B191B530C8D064 8: 90906F27A633ADDE, 6D9200A37A7F6A456CB103673184C2E5 9: 16CD3C17C9B4EAB135, 6D716E23D7B35109F55B036EDFA7742E 10: 7AD1C22F1F06298DFB25, B076990F8193543C8F3185D3792BCE56 11: 0476F2ABCD057FE6FEE39D, BB2876DB18C00038FADBBD9B264ACC3C 12: B69EDE336407DBC2EE735857, AB63E5906116A8BE22C52B5DA31B1839 13: C3864C1354065A56470669E602, C72BFD3A0BC73BFF051C9AB2F0DFED93 14: 296D8F183A59020D33890420DD7B, C9D90B9EB42C32EDCF6223587D1598A6 15: 256ED8E9D982616680559979BDF2E9, 179FE4E7BA7E966050D35900317E9916 16: D4ED8F30FF9C0470D75B3B16750A3AE4, 5D50F05BB270A292DFF9F67A3BA84675 17: 40CDEB6388274143CA3C4F6020BD9A4875, B27C7DFB1BFBB3FCCEE0171852C7924E 18: 54EF262EC1801D505C7629D038654EBA0594, 9D2060FCD0A2C577511C7752ADE60BBE 19: F39EE54A37F16DD38B624D7AB8F0D9CBD4B981, BC056C7D2C09D813703CDD63C1C69F44 20: F4E7AD474FCA153ABD670E43081ED09EB2C4CC1A, F244BD4D630272F0D98FCA04226C04F1 21: 039ECC36A0A16273E7246CA1FF19D213AC87B53F29, 3056DB6916C925DF220B6C9980EE141A 22: 7DE1DCDEF01447CA2FE83375A48DD84E4A7CB7C01992, 79AFEA4816EAF8DAC8A5E93960F1594F 23: A886C4B914BF0983003272F226F9B2197EF2DC05ACDDE0, B59D85A0FDA5FA4422F7203C055B97A9 24: 00B3E1E91448E250AAFB695C0643A6577AB453EFECFABF53, 4A7EFF1CBC1AB535122A017203616D85 25: 85E972E774D66D0531E40B8FE9E264A77B50FA883AB0943080, B18E164BF89B7E7AB0DC256DFEC7C72F 26: 004849E39334969B392CB0CF3FDEFB3D792DCBBC15F8328C7EDC, 3C51295711F5F878DE8F0B2B5A26A227 27: A0BAD6C2264AB1578993BA49E59D4598822FFED20A57D88F756FF1, 2EB9D525697A419A10DB2A84AEEA5FBC 28: C34DD806EAB5AD823D78BCA78A7709A705FC94ECC521A367D76C9588, 3C57580C7903039D645C06DBAF07B477 29: C447EC77512938CF7862388C32AF22ACE6B5E4CBAA998BE4F5CBC4D215, 43425D09B7ACFD90371C08953946A955 30: 2C16993AAE624CBA4CDAF34FE3D368559E6BE548292B281439866375013B, 3B7360C3FA8FB1C15D19F567153CB46C 31: 538E5DFAF14854A786851E4165F2E01CDDA963E318FCE4FB58E31A6B5CFC33, 2F8EA13B7A6873FE556CA535ABA0968B 32: 5E29CDB7D9695A110043E9C260104BDF020A3A2A139D4112E918AB584BDD7EDA, 9133213AA7BCF062D2BD37F866683D3F EAX-khazad (16 byte key) 0: , 75968E54452F6781 1: 95, ADAF5949F09B5A22 2: 6B8F, A06B201947424A11 3: 5BE668, 3251416625DF347A 4: 5A92E82B, 33E25772427D9786 5: 62F9F2ABCC, DE714F5F5D17D6D0 6: 0E3CD825BD8D, A7991C8CB8975ED9 7: 4AD0D999503AAD, 53A827D7886F7227 8: BB08E6FAED1DAEE8, 91A118749B7AB9F3 9: 16E30CB12E20D18495, F8F8B8C1280158F9 10: 616DBCC6346959D89E4A, 506BF35A70297D53 11: F86B022D4B28FDB1F0B7D3, EA42220C805FD759 12: 9B8A3D9CDBADD9BBCCCD2B28, BB478D3CE9A229C9 13: CDC4AB4EF2D5B46E87827241F0, 658EDB9497A91823 14: 1A113D96B21B4AEBDB13E34C381A, 63AD0C4084AC84B0 15: 14DA751E5AF7E01F35B3CE74EE1ACF, 3C76AB64E1724DCE 16: A13BBC7E408D2C550634CBC64690B8FE, 3D4BBC0C76536730 libtomcrypt-1.17/notes/tech0001.txt0000644000175100001440000000677510621351501015657 0ustar tomusersTech Note 0001 How to Gather Entropy on Embedded Systems Tom St Denis Introduction ------------ This tech note explains a relatively simple way to gather entropy for a PRNG (Yarrow in this case) in embedded systems where there are few sources of entropy or physical sources. When trying to setup a secure random number generator a fresh source of random data (entropy) is required to ensure the deterministic state of the PRNG is not known or predetermined with respect to an attacker. At the very least the system requires one timer and one source of un-timed interrupts. by "un-timed" I mean interrupts that do not occur at regular intervals [e.g. joypad/keypad input, network packets, etc...]. First we shall begin by taking an overview of how the Yarrow PRNG works within libtomcrypt. At the heart of all PRNGs is the "prng_state" data type. This is a union of structures that hold the PRNG state for the various prngs. The first thing we require is a state... prng_state myPrng; Next we must initialize the state once to get the ball rolling if (yarrow_start(&myPrng) != CRYPT_OK) { // error should never happen! } At this point the PRNG is ready to accept fresh entropy which is added with int yarrow_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng) This function is **NOT** thread safe which will come under consideration later. To add entropy to our PRNG we must call this function with fresh data as its sampled. Lets say we have a timer counter called "uTimer" which is a 32-bit long and say a 32-bit joyPad state called "uPad". An example interrupt handler would look like void joypad_interrupt(...) { unsigned char buf[8]; STORE32L(uTimer, buf); STORE32L(uPad, buf+4) if (yarrow_add_entropy(buf, 8, &myPrng) != CRYPT_OK) { // this should never occur either unless you didn't call yarrow_start } // handle interrupt } In this snippet the timer count and state of the joypad are added together into the entropy pool. The timer is important because with respect to the joypad it is a good source of entropy (on its own its not). For example, the probability of the user pushing the up arrow is fairly high, but at a specific time is not. This method doesn't gather alot of entropy and has to be used to for quite a while. One way to speed it up is to tap multiple sources. If you have a network adapter and other sources of events (keyboard, mouse, etc...) trapping their data is ideal as well. Its important to gather the timer along with the event data. As mentioned the "yarrow_add_entropy()" function is not thread safe. If your system allows interrupt handlers to be interrupted themselves then you could have trouble. One simple way is to detect when an interrupt is in progress and simply not add entropy during the call (jump over the yarrow_add_entropy() call) Once you feel that there has been enough entropy added to the pool then within a single thread you can call int yarrow_ready(prng_state *prng) Now the PRNG is ready to read via the unsigned long yarrow_read(unsigned char *buf, unsigned long len, prng_state *prng) It is a very good idea that once you call the yarrow_ready() function that you stop harvesting entropy in your interrupt functions. This will free up alot of CPU time. Also one more final note. The yarrow_read() function is not thread safe either. This means if you have multiple threads or processes that read from it you will have to add your own semaphores around calls to it. libtomcrypt-1.17/notes/tech0002.txt0000644000175100001440000000520210621351501015640 0ustar tomusersTech Note 0002 How to avoid non-intrusive timing attacks with online computations Tom St Denis Introduction ------------ A timing attack is when an attacker can observe a side channel of the device (in this case time). In this tech note we consider only non-intrusive timing attacks with respect to online computations. That is an attacker can determine when a computation (such as a public key encryption) begins and ends but cannot observe the device directly. This is specifically important for applications which transmit data via a public network. Consider a Diffie-Hellman encryption which requires the sender to make up a public key "y = g^x mod p". Libtomcrypt uses the MPI bignum library to perform the operation. The time it takes to compute y is controlled by the number of 1 bits in the exponent 'x'. To a large extent there will be the same number of squaring operations. "1" bits in the exponent require the sender to perform a multiplication. This means to a certain extent an attacker can determine not only the magnitude of 'x' but the number of one bits. With this information the attacker cannot directly learn the key used. However, good cryptography mandates the close scrutiny of any practical side channel. Similar logic applies to the other various routines. Fortunately for this case there is a simple solution. First, determine the maximum time the particular operation can require. For instance, on an Athlon 1.53Ghz XP processor a DH-768 encryption requires roughly 50 milliseconds. Take that time and round it up. Now place a delay after the call. For example, void demo(void) { clock_t t1; // get initial clock t1 = clock(); // some PK function // now delay while (clock() < (t1 + 100)); // transmit data... } This code has the effect of taking at least 100 ms always. In effect someone analyzing the traffic will see that the operations always take a fixed amount of time. Since no two platforms are the same this type of fix has not been incorporated into libtomcrypt (nor is it desired for many platforms). This requires on the developers part to profile the code to determine the delays required. Note that this "quick" fix has no effect against an intrusive attacker. For example, power consumption will drop significantly in the loop after the operation. However, this type of fix is more important to secure the user of the application/device. For example, a user placing an order online won't try to cheat themselves by cracking open their device and performing side-channel cryptanalysis. An attacker over a network might try to use the timing information against the user. libtomcrypt-1.17/notes/tech0003.txt0000644000175100001440000000472310621351501015650 0ustar tomusersTech Note 0003 Minimizing Memory Usage Tom St Denis Introduction ------------ For the most part the library can get by with around 20KB of stack and about 32KB of heap even if you use the public key functions. If all you plan on using are the hashes and ciphers than only about 1KB of stack is required and no heap. To save space all of the symmetric key scheduled keys are stored in a union called "symmetric_key". This means the size of a symmetric_key is the size of the largest scheduled key. By removing the ciphers you don't use from the build you can minimize the size of this structure. For instance, by removing both Twofish and Blowfish the size reduces to 768 bytes from the 4,256 bytes it would have been (on a 32-bit platform). Or if you remove Blowfish and use Twofish with TWOFISH_SMALL defined its still 768 bytes. Even at its largest the structure is only 4KB which is normally not a problem for any platform. Cipher Name | Size of scheduled key (bytes) | ------------+-------------------------------| Twofish | 4,256 | Blowfish | 4,168 | 3DES | 768 | SAFER+ | 532 | Serpent | 528 | Rijndael | 516 | XTEA | 256 | RC2 | 256 | DES | 256 | SAFER [#] | 217 | RC5 | 204 | Twofish [*] | 193 | RC6 | 176 | CAST5 | 132 | Noekeon | 32 | Skipjack | 10 | ------------+-------------------------------/ Memory used per cipher on a 32-bit platform. [*] For Twofish with TWOFISH_SMALL defined [#] For all 64-bit SAFER ciphers. Noekeon is a fairly fast cipher and uses very little memory. Ideally in low-ram platforms all other ciphers should be left undefined and Noekeon should remain. While Noekeon is generally considered a secure block cipher (it is insecure as a hash) CAST5 is perhaps a "runner-up" choice. CAST5 has been around longer (it is also known as CAST-128) and is fairly fast as well. You can easily accomplish this via the "config.pl" script. Simply answer "n" to all of the ciphers except the one you want and then rebuild the library. [or you can hand edit mycrypt_custom.h] libtomcrypt-1.17/notes/tech0004.txt0000644000175100001440000001102710621351501015644 0ustar tomusersTech Note 0004 Using Yarrow, Fortuna and SOBER-128 Tom St Denis Introduction ------------ This tech note explains how to use three of the more useful pseudo random number generators and their own little "issues". While all of the PRNGs have the same API and are roughly used in the same manner their effectiveness really depends on the user knowing how they work. Yarrow ------ Yarrow is by far the simplest of the PRNGs. It gathers bits of entropy by hashing the pool state plus the additional bits storing the message digest back in the pool. E.g. pool = hash(pool || newbits) Simply dump bits into the PRNG via yarrow_add_entropy() and call yarrow_ready() when you want to put them to use. This PRNG while simple is not entirely safe. An attacker who learns the state of the pool and can control future events can control the PRNG. This requires an active attacker but isn't entire impossible. The pool is then used as a key for a cipher that is used in CTR mode. Yarrow is mostly meant for short-term programs [e.g. like file utils]. This particular implementation is not meant for long-term usage. Fortuna ------- Fortuna was designed by Niels Fergusson and Bruce Schneier [Bruce is also the guy who invented Yarrow]. It operates on a more defensive level than Yarrow. Instead of 1 entropy pool it has 32 and the new entropy is spread [round robin] in all of the pools. That is, each call to fortuna_add_entropy() puts the bits in the next [in the sequenece] pool of entropy. Effective bits are added to the pool by sending them through a hash [but not terminating the hash]. Here's the main catch though. When the PRNG must be reseeded [so that you can extract bits from it] only certain pools are used. More precisely the i'th pool is used every 2**i'th reseeding. For example, pool[0] is always used. pool[1] is used every second reseeding, pool[2] every fourth. The pools are hashed together along with the current key and the result is the new key for a cipher which operates in CTR mode [more about that in a sec]. Now this may seem odd at first however there is a good reason behind it. An attacker who learns pool[0] won't strictly know the other pools. So the recovery rate of is not 0. In fact pool[0] can be completely compromised and the PRNG will still eventually recover. The value FORTUNA_WD is the "WatchDog" counter. Every FORTUNA_WD calls to fortuna_read will invoke the reseed operation. By default this is set to 10 which means after 10 calls the PRNG will reseed itself. The pools are combined with the running cipher key [256 bits] so that a cipher in CTR mode can produce the stream. Unlike Yarrow the cipher is re-keyed after every call to fortuna_read() [so one big call would be faster than many smaller calls]. This prevents too much data being encrypted under the same key [and mitigates a flaw in CTR mode that the same block can't be emitted twice under the same key]. Fortuna is really meant for a kernel-level PRNG. The more sources [and often] you feed into it the healthier it will be. It's also meant to be used for long term purposes. Since it can recover from compromises it is harder to control it. SOBER-128 ------ SOBER-128 is actually a stream cipher but like most ciphers can easily be modelled in the context of a PRNG. This PRNG is extremely fast [4 cycles/byte on a P4] and was designed by a well known cryptographer [Greg Rose]. SOBER-128 doesn't really "act" like the other two PRNGs. It's meant to be seeded once and then read as required. In such a sense it isn't a "system PRNG" but useful short term purposes. In particular the sober128_read() function actually XORs against the input buffer you specify. This allows the read() function to be used as an "encrypt" function as well. You can only key SOBER-128 once [by calling sober128_add_entropy()]. Once it it is keyed subsequent calls to add_entropy() will be considered a "re-IV" operation. Changing the IV allows you to use same initial key and not produce the same output stream. It also lets you differentiate packets. E.g. each packet has it's own IV. All inputs to sober128_add_entropy() must have a length that is a multiple of four. Overall ------- Since SOBER-128 is *much* faster than the other two PRNGs a good setup would be to use Fortuna as your system-wide PRNG and use SOBER-128 [key'ed from Fortuna] for encrypting streams or as a PRNG for simulations. Yarrow is still a good candidate but only for "short lived" programs. However, since Fortuna is faster [by about 10 cycles/byte on a P4] I'd use Fortuna anyways... Tomlibtomcrypt-1.17/notes/tech0005.txt0000644000175100001440000000154510621351501015651 0ustar tomusersTech Note 0005 Minimizing Code Space Tom St Denis Introduction ------------ Tweaking... You can disable whole classes of algorithms on the command line with the LTC_NO_* defines. From there you can manually turn on what you want to enable. The following build with GCC 3.4.4 on an AMD64 box gets you AES, CTR mode, SHA-256, HMAC, Yarrow, full RSA PKCS #1, PKCS #5 and ASN.1 DER in roughly 40KB of code (49KB on the ARMv4) (both excluding the math library). CFLAGS="-DLTC_NO_CIPHERS -DLTC_NO_HASHES -DLTC_NO_PRNGS -DLTC_NO_MACS -DLTC_NO_MODES -DLTC_NO_PK -DLTC_RIJNDAEL -DLTC_CTR_MODE -DSHA256 \ -DLTC_HMAC -DYARROW -DMRSA -DMPI -DTFM_DESC -DARGTYPE=3 -Os -DLTC_SMALL_CODE -fomit-frame-pointer" make IGNORE_SPEED=1 Obviously this won't get you performance but if you need to pack a crypto lib in a device with limited means it's more than enough... Neato eh? libtomcrypt-1.17/notes/tech0006.txt0000644000175100001440000000646210621351501015655 0ustar tomusersTech Note 0006 PK Standards Compliance Tom St Denis RSA ---- PKCS #1 compliance. Key Format: RSAPublicKey and RSAPrivateKey as per PKCS #1 v2.1 Encryption: OAEP as per PKCS #1 Signature : PSS as per PKCS #1 DSA ---- The NIST DSA algorithm Key Format: HomeBrew [see below] Signature : ANSI X9.62 format [see below]. Keys are stored as DSAPublicKey ::= SEQUENCE { publicFlags BIT STRING(1), -- must be 0 g INTEGER , -- base generator, check that g^q mod p == 1 -- and that 1 < g < p - 1 p INTEGER , -- prime modulus q INTEGER , -- order of sub-group (must be prime) y INTEGER , -- public key, specifically, g^x mod p, -- check that y^q mod p == 1 -- and that 1 < y < p - 1 } DSAPrivateKey ::= SEQUENCE { publicFlags BIT STRING(1), -- must be 1 g INTEGER , -- base generator, check that g^q mod p == 1 -- and that 1 < g < p - 1 p INTEGER , -- prime modulus q INTEGER , -- order of sub-group (must be prime) y INTEGER , -- public key, specifically, g^x mod p, -- check that y^q mod p == 1 -- and that 1 < y < p - 1 x INTEGER -- private key } Signatures are stored as DSASignature ::= SEQUENCE { r, s INTEGER -- signature parameters } ECC ---- The ANSI X9.62 and X9.63 algorithms [partial]. Supports all NIST GF(p) curves. Key Format : Homebrew [see below, only GF(p) NIST curves supported] Signature : X9.62 compliant Encryption : Homebrew [based on X9.63, differs in that the public point is stored as an ECCPublicKey] Shared Secret: X9.63 compliant ECCPublicKey ::= SEQUENCE { flags BIT STRING(1), -- public/private flag (always zero), keySize INTEGER, -- Curve size (in bits) divided by eight -- and rounded down, e.g. 521 => 65 pubkey.x INTEGER, -- The X co-ordinate of the public key point pubkey.y INTEGER, -- The Y co-ordinate of the public key point } ECCPrivateKey ::= SEQUENCE { flags BIT STRING(1), -- public/private flag (always one), keySize INTEGER, -- Curve size (in bits) divided by eight -- and rounded down, e.g. 521 => 65 pubkey.x INTEGER, -- The X co-ordinate of the public key point pubkey.y INTEGER, -- The Y co-ordinate of the public key point secret.k INTEGER, -- The secret key scalar } The encryption works by finding the X9.63 shared secret and hashing it. The hash is then simply XOR'ed against the message [which must be at most the size of the hash digest]. The format of the encrypted text is as follows ECCEncrypted ::= SEQUENCE { hashOID OBJECT IDENTIFIER, -- The OID of the hash used pubkey OCTET STRING , -- Encapsulation of a random ECCPublicKey skey OCTET STRING -- The encrypted text (which the hash was XOR'ed against) } % $Source: /cvs/libtom/libtomcrypt/notes/tech0006.txt,v $ % $Revision: 1.2 $ % $Date: 2005/06/18 02:26:27 $ libtomcrypt-1.17/notes/tech0007.txt0000644000175100001440000000022310621351501015643 0ustar tomusersTech Note #7 Quick building for testing with LTM EXTRALIBS=-ltommath CFLAGS="-g3 -DLTC_NO_ASM -DUSE_LTM -DLTM_DESC" make -j3 IGNORE_SPEED=1 test libtomcrypt-1.17/notes/hmac_tv.txt0000644000175100001440000040051010621351501016035 0ustar tomusersHMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are HMACed. The initial key is of the same format (the same length as the HASH output size). The HMAC key in step N+1 is the HMAC output of step N. HMAC-tiger 0: 2EF793765716EE48A671BDB5F002103C43734304C8717C85 1: AE61B56C82BE9FF96DCFBC20DD02B4BEA4FC6B6D5F4EC412 2: B54ADBFB404457E6C5AFCCEC27199D1F259EE1994FFFE99F 3: 08AEEC38E88403BB854935EB6F1464CE95B044F4B4202524 4: 4C9DAEDC1929E22128F2A7ED5F3556D8A6D3A8315A7B556A 5: 764794ED9EE1F94891835CC3A361FE75C600C7951A07F450 6: 1A4C447A0FB8826A0881ED2E7BD89499EACA4B6C49F96060 7: 1396A21D8B465C6B898511DF94846588EE8E35C0095AD90A 8: 7552EB03CE26A8F079AC96B42F556FEAEB756014B8FDE622 9: 835B7CCA9D9F13BA2A36CBD746E5C92D5B2D123CA2EC848E 10: 7CF4EA88FF8B9A5A57E5ABB6B35278EE9D8653F624D662FE 11: D588D953C6F438D077A1E302F84E25EF31AD99B9C5FC9DB4 12: 86EC62CF1A08CEA9171AC742E8E615B3F0C7B6FBC95DC3C8 13: 6EE7C51E26187F86370A26811C75136E28B0C39A113D80F8 14: E1326D54123BC26CF41B30F9F2BA2E732203836AF8A74273 15: F211E4C46862E3AC8B8E69976A705582CF6D1B34A6D342B7 16: 0C6160FEFE70C81C71B7465F42F070F30808CDAE448D1974 17: 492FC6BC091489F926F0F54CBF3E3F6C8CEC6ED14DF2DF8C 18: FD166027ABD1BD9DBA13E3908D16C403E1691FF173328CA4 19: 28D99C64CDFFAC1E6F7B33C8E675E49749CE835A177A1C63 20: FD7BD55BC2A684F4875C811143A2997356AA87A300345843 21: DB8968E787BF65C00992ED9DDE974EA71BA947395111FFB3 22: 4C31B2FA4E6F7F40DECA589F85BB69BFAD1815A73CF9EB23 23: B4D8D7FCB314942F171F85EA0953F7816DA9F07D72AF48B5 24: 9A6A70BAD76203A7A1F64D1EE34375EC8BCB21810ECE0B68 25: D21D7E5EF6F1579C84428AB5D574468933BA037C9B0C34B6 26: 3C5292C87B24626241693F0EBE20A96800905691C5945E65 27: 350BEEC075258BA7FE0314E6803152B021570F067AE0D4D4 28: 6881F892886F9D66E68B937BB3A71FF5CB064611C722996E 29: 07831F1B2D00108386339F192729687B2F57B9DAB2B1210B 30: 38DE8DE8398EEC32939A239BC0198B0CFB18D12E4F2A3023 31: 5B683578F81867054089AE2E1B20E02B3BD92334CBB01FA9 32: E30A80BE07651BA17E2DF0D43A583A9DB268DFF3AB7393ED 33: 42341B1EC4F61E90571188F5599FBA9ACF884B1E15694921 34: 7D98297D65F5FEA85CB967F22AE0707E03F305BF1D2249DD 35: BC8EE5CE0FA8F9E6694406009EC9358BC420B7E5DE07B6F8 36: B8095DE6770CB4CC2127FA672F93F39CA4AF0CCBB9805DDB 37: 20C0E981DF1B763B6BB47D43F66765AD434127C1FC55F829 38: 59795328D40D2CE6CFDED8DD5089F2D5B796C9438E7646CA 39: 0789CAB229AD54416C82CA5A2E667EC7CE66019FCACF766D 40: F7C81B1AE705019FF9A9905972AFD72484A70E11FB81B278 41: E72F52644BF5EE59BE87DF692EF0070D095115B7664BB53A 42: B9A5DD984358D0B0F3C2781BA60E9BD3473C1C89C7982F23 43: F7BA22269249759F1A87AEA0A125D4DF9B58E93714449008 44: 5D2257317F8978576CD7D2CCD346E861A59FE949F74A3D82 45: 199D8D5B0B5C5B61E046F50E0E389DA6F19CB3A7A37C8588 46: F489CC6CB2D3E9F741D6C9008265CCA97E7E54D62F5EB85F 47: A5E7CB0787EB7E62A9CFD8486390A6628C9876654B9E85E4 48: 22FA78EA17F0D29E16276C70A564D234BC4ECA7302301528 49: 4422534FB9EEC601CE7662345D6B6FF932E54BB0483C2F62 50: 5D2E2B90B460D393F36BF32B2F491E224EF388FA72A48501 51: EA5287BCBB856BF04FC785541079087CE24783E9310F3090 52: DEDA3920899FA69F913AE50A4F0D7119C9D3CE8F4E6D5BB2 53: B2F55D8EA64C9842BFEA4FADFE616664CD44C57D53998C58 54: 3D2C72F26188E1EF5C0F0FC8B541224066C4DF455FEE78FF 55: 50BB36BD8A8D97E4D6CA78DDCDAD0690FBBC93DC9A66BF18 56: 48140E192FF8AB74FC22676AAAA186C1A7E2FA0166E986AC 57: 40AFD540C40EE7E598D26AE3FE5A47939299B5DD46B0B4FE 58: CEBBBD763B077342BA16D4B20412C9EDE0F0508ABCE3501B 59: 0FE4DFE539160F5924C324B8B43DACB4F220195D286C6FA1 60: A06D135075F943CEE74AAB1B8DE08B772055551B1E73ED48 61: D4E1B5EBBDA5CDA5040DD697BB96DD702C6730CFCC012992 62: BD5E77B67B42C507C4912130C8880A9DBD66431DCA0C0038 63: D81F583A9B4DD1F48028CA602CC0F131D60561FA34F7B3B4 64: A41F0481EE52842CDF676177F8E43BC1F1B00A5682C63E15 65: CDB29E274ABEB20EECC8378D5BD806997502E4271AB56708 66: B8366ABD45565BB3D26CE46B6F419F74B34851863FF4C336 67: 5AD2C193D6D51C9C7E56C5BFF55C1D61E045366B51E7F619 68: 9948E3AB7D121B15A6CA8DFDF4EE5377C957F0DE891C3575 69: 095676D61096853635128A80570BD1CE803AC7249C0A0F57 70: 354F4CCC1E5112770B2AB035AE07200A6CDC0280AD088AFB 71: A8723395E80BED25DFE8F9ACEDA942A77D225D00440302D2 72: 0D2BCE0F8CF396FD8277C8BD9B19D54965308D3ED04D2F27 73: 54B1939E9944F499798B3DCE3479AC315F2C42A1EF231984 74: 5CFF726EE4B2596240E6CBBC66D7C737A4D12A702B40E81E 75: 82996D7F3F27B473BDA647BBBA7230DF217288F2D1A38B99 76: CB95F63E0E7A2EC4F26E94B81A3C8C757E04EEEAB35A8C2A 77: 057DEDF45207EA885A0BAC5B64240DD21CB9D99CD8F38FEA 78: 27DCDD1ABA459506EF98E5C8D567692264C4153F91FDB269 79: 911C83660F7EE8CFB5F54890AE98CCA36C4C12B8CC771DF8 80: 67CD07209988C517FAEE01E64AC4B5CF261B6035069508FA 81: D9A40C407E2BA852684770A5EB08D8502DFD264F2DE5A5FC 82: 9AAC50A2BCFD74BE3DF85237478AAA833484FA3DF912A3AC 83: 38078488F6183B5A94B655F24212FC9769450D93986C9208 84: 2EFFCBFA4CCCAFCA66BF8B368FB1FEFAC280C20416BB90EC 85: D626FD6D285C49F20E99B88B9F82640D93D9E765CA55B5B0 86: B1DD178943B26AA241D34031D3128344C6955F6A942CC5D3 87: DA0C850E2067F9FDAE433C1230E0F629700FC8896ADDBDE9 88: 58E393E353BD7DF75A591904AA99526E94FA45C98D095E21 89: 323D0E04D239BD70192B2ACCB9ACF06E2F8C3B07565893AE 90: F9C4147C6921640C097534BB08020540B420AD569D03665B 91: 5171DB964AC815B3A6D058419FD47833DDAED71039966E6D 92: E7DC7C574AFC2C9A59E46CB8ADBD03330A5321B237DF7899 93: 97074CDA9FF8D40B0501E9F632ED7335D6A7926101A34C0C 94: BDDCD4D007DE39680B80F9AF9803A9F21C836EA971250CD4 95: 0DBFF45E3155098D4B4C13815FB461D3C4BE41E9E1A68757 96: FC16CB95478E4D23A7AD15CCAE3C24BBB3D0FBDC8A00A144 97: 93A7CB506481D6A72EAB14A2BA544F8631542B55903CCAAE 98: 9CC1FFA19736AB6EB36EB4A2C1624FCB6913B255D2346795 99: CE3526A088FFEDEA4345AB221707848823B16DADD19AB487 100: 1E1D790323586DB8A306EDCCAC8C64A6F29A36F772B8D61D 101: 8C403515F2B9014E9519EC04769ACCF23E522D3E22DE7F41 102: 6B6A634607634804988301240CA5AB029A9E86E51281D64E 103: C7C3483CC8E6B58520B554259EB08866AA7980B53FFB6B86 104: 96E429611C9E411321947469E2095CD9B0EF29578030E40F 105: 5C5A7F2B7F1F9BCE730BE2779304A443188FD3B31DD2BF19 106: 70933F999325353277E0AA1F543B5CBED3F28DAF4FC70A57 107: 5CD6D136FDDF4AE9CE42F008301FB6647096D5007E79973F 108: 1162BA742AD199AC17FC707285301A82BA9CB12C09BA229D 109: C36615F6D5E29E6CABB7EBC44A6D3F7B024DAFBD338FEFFA 110: C29FEF051D1606CEFCE3417BD571CB9188BBF0FA8AB98679 111: F925144EDDD27244E19E4B6E433F312C6CDE43EF4F9B84B5 112: C4230A59E54A34D0709F3F1DB02C18EC8AA270078DE424D5 113: EB1699CAEC36681CCF8A9144DFB5050566042977D15FD1F9 114: 9FBF0D9B2DD9A6E87240E538590E9799B76E22604D22AB75 115: 2657EA06D69A78A5895A9169F849B3DE111B31E5673A8E17 116: D1F9E1BA4F4E52CDAAFC388FA4C366EF4BD5F440608D86B0 117: 049196BFFD9F77175FA936066C3119293EAB79D1E0028C8F 118: 9CC1BD2CADDEC1D82FFAFA7031F2E5C9B6765CF1727A0ACB 119: ED00438670D68A70CE2E0729997CC9648947EEA35809B8C7 120: A520A0089BC16C84CB8E05425B330C6D261108EE3049FACF 121: A55B470483E547D2752EDC3C4FDCF3B4C48A1990AD857941 122: 46A78E772C533EC8EDA60EB4A127FCEBD35E7D0E7F183241 123: 5EB9A774124D571FCCC83D1F36C603D9C387390DFB3928B2 124: E904066FC77F73CA41166297A8FC631FF59634B659F0AED0 125: B85B66AEF7D9904356F1CAA5583757D1D69EEBB8AB1D1420 126: 6639F85214BC798D71B757FCD480CB78D325881781A3A073 127: C5B72BBE80917B55036A9AD6908D59293C49373F0BDD104B 128: C0BD695F6B9B42DAB543C31BA73C9497A6AA6419A007A9F6 HMAC-md2 0: D39AD9DDE006587A8BE949B11B9288F8 1: FCB21B5348C95E8A8DCBEE50A80302CA 2: 2F26B6ACCD0E03FE9B21A1B0E75FF665 3: 17CF85D985D0D85F545897CD42C6EFE5 4: 1537A6943B4F5AC1272E4161225D987B 5: 83E17165D62CA6E4B9ED67DF1E599954 6: 7A3195C863DFF86A98968F254E128E61 7: BD05057AEBFCB92FA4B07456085EC6C2 8: 23AC0D307BFC2E87760F8BDB21851DF8 9: 2CD26A2F2994106A375BEB0433575BDE 10: 1F63BFC44FDBE9A966CD90DF82265EFD 11: 72735FAADC3819CC24CFCE1D589BA311 12: 28B589C3C8078B8FFEF1C8297E33C1E6 13: 70A6DC014CAD2752931A47C0879D2371 14: 81694317A37FFBA816504974F38B4829 15: 72F26208B3051F1B938EA7E03DD8C107 16: F945F57FE0696A4C81EC59AE69384FAB 17: 54D8DFCEE33969486956698495B4BFD0 18: 508B82F88A234E753A9E305E15A14D82 19: 527D77D2AB25131693B02F653ACBD90E 20: 4868AC540FCC3A896D5A89F7A0444D36 21: 6189807C5FDDDD68D20356ADF3B90DC2 22: 0356362F2BC4206F2B930C4282213758 23: 2F59956F19B3CAD687C66C4EC3CC916D 24: E30CEFBDA3FA1A8EDDE3B72614ADDEDF 25: 33E0E6BFCBC9581BBCDF13F4D3F26724 26: B11C6476F9775219A9F18B5E88857790 27: 49C7A9D7F56344BD405E53BE927E3A58 28: 99A06874B0F0CA45C9F29E05D213195F 29: D21A60A18F061FC453AD5AC2A519071A 30: 2F735E82090144C036E3D12DEF2E0030 31: F9539EAC81BBCD0069A31E2A3C43769D 32: EDCAA9C85A614AB6A620B25AF955D66A HMAC-md4 0: 752E874F35085E497D5032112CC65131 1: 6B2CAAEE210F970AB481D6D8EE753114 2: 2162A41522C2DB0B8AF1F0C712C19A22 3: 7C2106C3CB687F35FE2658BEEFB497A5 4: 3715333CA3EB74A15B4B1802A1A78921 5: 403D9A691A130AFFFB81A655AAE1D956 6: E697C3CB42716CA1973DE0D15486068E 7: 99676F34E42C61E396F0E76BCB77BEAB 8: A2B2CE8CF8AC151C5556A36D58894C61 9: B8614BFF1DAAEA90BF319F333024976C 10: B8759E8B97DFCBB2DB94D8CBE2C96B20 11: CFFE6119EB0C649831459339C1B0C82A 12: B2FC0DBA9C4830CA66423728599D3660 13: 454749F1DE579F1918FF046FC1CAE7F6 14: CC625178FEFD46481B7D02618AF6194E 15: C26D523EFCC42C4AF7EEC2EA4B45B719 16: C352DA2D077FA3F493A5CE0E9A79CB87 17: 570DDE9FD220F59867F17484605D2061 18: FF5954A163CBA61CD3C8424CC71682C8 19: 1240D12E3D6C07F6FE1CD595C847C038 20: E87A4D7958C43CA71791B13E16301036 21: B2CEDE4A15F8D64C53D243F8C5763C05 22: 54A9E9EAE155E7AFA6FC8A7E05D7FA9B 23: DF0E79F27CE25E56ABCFF5E74D1212CA 24: D9BE454A95E5D9127990577F7EB7183E 25: 26F9221A8B854767861BF0281303B89E 26: 92BD4CC81A673B254A4AB493864BB014 27: EBC3851E0AD28BE9876BEFD6B0A88B44 28: 1134BC8A40E1D2FB038B67548AC2040B 29: 954700135C4E7F232337C84130B43360 30: 8C3EF2D8F896C8D252851A1543F72493 31: 52817E79D2B0B3A37DC08D18D3519F92 32: DA661A428B9659DD59545E3B09162F8F 33: 3FF5BB67B48F87B4B642DACCD2E4001E 34: C674F95BB622D7B8281FFF34E9EF3E7B 35: 3A4D25E3BCABAD8CD4918CE650EF00E9 36: 2D91248C51837A8B80898E2CE42CBCB4 37: C0B3BD2B36493F0EAF9AAFEFDC37064F 38: 9B4723B091102B480B2B59069317F292 39: 0F8EABB489254491FE19AD0E328A483C 40: 25469BD482E1405E51AA021752394C4C 41: DF1DF50EF9D95892D08DFEFB79D6552B 42: 707A546964CB22710482C478E58C2E0F 43: D1E243DB14E2F946D650C811030ADE9A 44: 11A1AEA678E98A65420747DD6CF9293F 45: 66E735F658BD689A9F1BA0B526827CF9 46: 98170734E67F576CCC3D01D83965A6C9 47: 399D99CB7979E80F6D3B5D5BBA5871CA 48: C26651C32EABC76289CD0843D3BCDD92 49: AE0F50954C90E8897BCF504592D0626C 50: EA3AB701136862428EC326D2551F8AC8 51: 4AE98E5A1E6B1BA8CEAE844E34934039 52: 7C9826187053186DDC2760AE6FB56DC7 53: FE0F555B851CAD830BAC9FBB40705671 54: 221BB509584BCC7E10F3B4FAB2AEB1F3 55: DD93EAFE25EE27C6FDC2CCDE7D273267 56: 535472E1ECD49FAA75CC6621BE7E6210 57: DA4554FF7D5B289A03D195F94154AF47 58: F15A3F547B5A3844BFF713CBCEF701A1 59: 279DE06FD5644C520BADD3B97D96274D 60: B933E929073492EC1E2AEB78071C7B83 61: D1DA2335654AB4CEBAE5C2E78CF27553 62: 06FC50285F4BA5C8B5A478E9C02D6434 63: DB66A5D55224DDB50337B7FEF9A808A7 64: ECFCD0385FB49553EC89DD94AB084D23 65: 4187B0B79E6CB916F747B857AB2F75D3 66: E03E14F5E00B2DFC0614308608B929B9 67: 5F61FC3005167EB3256DB549DA8BA562 68: 21A4D14DF8E934A858569D8BA7F151E8 69: 5955DDA4CEF16ABADE2B551841C69B8B 70: 8E77066A973B60DF64C27DBB93EF204A 71: 2101EE9DC8221FF17D9D887FC39F41BA 72: 6574A9DE32B7A673B5BA20FF18EF8C93 73: F571B14C9F5C5C1858D48AA944A13050 74: 0BA4BE0A5E853D07F79B2D29BCF046B5 75: F240C8C38D71131F510369D79FA32208 76: 920C294DE37C28803FF3C49A4135CD65 77: 38796D25822AD8F2AB4D64E4A65626A0 78: 65A203170FDF794397FD1090E318C5DA 79: 965A767FE4A75BEECE26BAA79D816AD7 80: 0F4B30947B790C47924657648FA1D88C 81: 74B05F7B7D006F7DDAB31DAE251C3BB3 82: 61B0366B57A8F46C2F6C16F935DA768F 83: D4CB13CA922B542980F854C9780A1951 84: 039B2F23A1CE410FF4696D9C35C40C08 85: 2D734E28F995C2AA2A7AE2412EB99A10 86: 1A55FE47703ECDBE446033F492412812 87: 6AF4CED86D0181D6E99EE6AE57F295EC 88: 69C239A875E0352D20BCFBCF8D5CA19F 89: 62723FBBF0AC6F397438589AF06625A1 90: 424EC9353901795251AEF7D7BCFEB8BE 91: 9BBE4ED6C8BD14F85BA86E553B1B8152 92: D7840AA82F788B7D58712E29003D1239 93: 4AA55512DCAF770FE4D9428FB318B0B0 94: D040BA08BEDFFB20D2C499FEB35EE12A 95: 0F295EDEFC85546547860B7F7CDFB1AE 96: 720FCD871B7D8824EE6A7DE9FF1A62BE 97: 2FE3AD14E24C441C36186673A0D60767 98: 943FD502136B66D0313951198680F746 99: 4EE6829F3EFFD0A87115512ED28C85BA 100: 6EE1AC28A320246CA5C37F981E22D294 101: 36BC623D6573C3ADB164F8A6F02315AB 102: 08B3AAED34FB0A0F99C4B22714B9CEAD 103: BDCD10B66096AB992DEC5539773EAF23 104: 6DA36A53A79FA2C68E5060C0D2D43E13 105: A3E886199532C025074D4646113F9C23 106: 00D67A1D2ADCA77A20441CBF593FDEE5 107: 2E4399F5FB44FF5573B73D01C5B248E2 108: ED22A18A8824A30B68EE0EF9907B2B91 109: 36166824634304417BECCC9519899CDD 110: 0757DB01193BEEE90617AA8CAD0360A8 111: F7691CBEF4ED2E9FE4EB992CB3939970 112: 09DC2FA975CBE8CE828919957D110EC2 113: 7DDB74DEC57AE8C318AA5CCFB53872F6 114: A26B7DD0AA30EAAF1F4F8314AB7DF16A 115: 088855527BEBCDB67A40FEA4FDDCC061 116: D0F8ECC0C32B7060CB6128279F57FD80 117: DF5B79D3671CA5E5B44CD395F6FFA551 118: DA8999EA059C463D5F05D04020EE867D 119: C0EE404DD8447AA70D3725D5634E2B53 120: D19D1A725F5E9F0DF21871B31900CA73 121: EC202984BE149C93CC1D440CF6D29E1F 122: 422DB7C21B1348983B75498E270FE6C1 123: EF136334BC30C92DB9082A9654B391E4 124: 0B3526430AE734054873B14DD696CB3E 125: 3BEB77C0F85F8C6F21790ADF30EBB812 126: 4376F8C8EAF5A94871822DBDFBB5F88D 127: F7DEAF52378FF735B2D171B17EF573D8 128: B4FA8DFD3AD4C88EABC8505D4901B057 HMAC-md5 0: C91E40247251F39BDFE6A7B72A5857F9 1: 00FF2644D0E3699F677F58ECDF57082F 2: 1B6C2DB6819A4F023FFE21B91E284E93 3: 04B0ED3E73FBB9A94444FDFFAA530695 4: 1557A22261110DFB31ACE25936BDE45D 5: 54C5A67A9CB4544CA66BBDA1A2B8479E 6: F803D9E43C934545AF078FFBB34BC30B 7: 32F56EA655DF36D845E430D637C85D17 8: 14BD2095F4A478C10EEBFF379DE76DD3 9: AAF6867B3FA01DD26312B0DFD6371A2A 10: 0FA2A6FEFEBE7CE3C31A38400F8AB260 11: 54C37BE13B7333287D0E74AA9D9227F6 12: 385D75A58B0C95E5CDC059DB168BD1D2 13: E73003103ED65C08E62D46AE1E1B771A 14: 278ED4A4EBEA1FFA5EEC874F198C0CC0 15: F65CE9EEA7FDB90B9CC603329D3FB9A9 16: 8640836944EE0009B2CC6FDC3F5C39E1 17: 7819A99F82BABDF060AA51AE109629DB 18: EF26336668486C76921D1DAB67ED5673 19: 13ED7BC140F1496E09AD29C644586957 20: 5FDD337CE9C4AC8D910833FCC2BD837E 21: E9470246ABF7CF4D37FD378738D8F763 22: 384A75C33EFFA12EB69187BB80DF843B 23: 63866A5406B9EA0341032FCFD0244A4B 24: 8042F8572C8A9B88E135ACB83EF1FD39 25: BD1BE6AF2D022F966F612569E191F0E9 26: 9F70C839533EE4C7B3CF20C6FB65C94C 27: 800A5CE92CA4FEE6F1D353F496113873 28: C35E93E1E54C84C4389D2DE71E1B9846 29: A130EF5F91465F5A56999F450E63F4F9 30: 5F16564E05285A099F628245DF9A3C2A 31: A34F7E3DF06DD84CC67E8A922240D60B 32: 945E50753B6E6C920183822D5F280F10 33: 2DDD269DBCDF5C21A1C3FD540FF4ABA9 34: 212FE3E2CEF7DF74FC01CC2CC83119B8 35: D98B2930011649F16C08BC8C0178D838 36: E39E21026111C1EFB0C491C0FDFA841D 37: AE46DE06C3B0D2CEC35352C95A1003F0 38: 5550EE50BF88C9DE5ADA34567FE044C7 39: 6BC486627760373EACFF508F7032BF31 40: AE6E0B8DBCFDCCA4B3449B57647D5AE5 41: 6BE5A0F140DFC4B75439630E6F9A36EE 42: E3E4E735BFE79397D4653A6243DF1925 43: 68C1D9E8973A3F6B92B588469D68A2A5 44: 956132D512118D5F446C8CB912B924D9 45: DF5C2AD650B3CA7A89EBF92EE618C845 46: 14D375CF7E4294ED99135E4237414F01 47: DB966D40B447692E2D13CC0C09C1B495 48: 53DADCF1C6B99BD403052A1CE1ED0D14 49: DEC4A3C1DB8F6AA4515C512C9299C4DC 50: 3B3A51DD83AB1DC56A7F0CBE1C71923F 51: 03C73353B3203EF9CDB95F9DB8750AF1 52: ED9E15FD86D66DA2D546D2BFC55041AD 53: 81B649338F9DB1C6E592427D38221C7C 54: 92E170E13BF40FF65E3B4C665F222DD5 55: 00D5E23F5F829B21D454C4445851AB53 56: 39057029AF0B3F4391A7BDC6DDCE4D07 57: 2DEACEFA698F9CCAD5198C4E17E69A93 58: AD35FD52EA199E26948009DF3546D3A2 59: 4C42CF2CFD4D8FD9A06E3F73D02FE818 60: 4D7C893E4313FFF72103854463414277 61: 3F04E8B32AB56EAF216503E46BD7AEBE 62: F015DDC3EEF41ECC93E944FA3577DB52 63: 31F77A50A2ED96ED8E4A3CE04B9DAA23 64: FBF481373481756E0C88978F7E0809A2 65: 7D8D793B287C04E7D2896D76EAA5CA15 66: DAC74AEBECC2385DD9D0C3147CCA1F78 67: F6DDE50D37B460FF5E8B4C03A0854BD5 68: 5710D6A54A2124E06A6DADBE9BF76119 69: 19DB5D13A53E57184759F33976537AA5 70: 848DD8D32130626FBD11B0133C2A29E3 71: 4F75BE04BF2F6DD85D048DB82F19C38C 72: 4AE9436540ED24BCB5EC62977AC90789 73: 859D1A9FC2B795AD60F24A37EB9EF890 74: CD45865317FD17B652DE9F9EBBBA16B6 75: 52313319D395F453BA2C0A0159CF180B 76: A7B190C0EECACCA4DFC5B45DFB324718 77: 23E85CAE85B50F45F7F48EE0F22FDE85 78: 6A80DBFF139A5345235EF76586CFCBC7 79: 850E638FCE5A2F3B1D1FE9C28F05EF49 80: 797CDC3F7E271FC9A3D0566A905D1CFE 81: 030CE97A9A0B1D5403E253D883FCAF12 82: 648FFFF44E416D9DE606BA0DDB751194 83: FE15098E0DAC65FA8EE45CAC67121CC9 84: 17C90ECD390A8B41046B4C7FA0354E4F 85: 7D149DFF5F6379B7DBF5C401DB6D2976 86: 8D055A4701DD51CB9D1AF8E2AE59BD21 87: F3481CB07B034EB4A023D00D4FDA9A86 88: FEB22562FFAAA9CCE5CDDA34C29E55C3 89: A620AA447216709D8CE5C5F23474ECF8 90: F25FCBB2BF7440C5E3C5B53092B8C828 91: DBBAE1CF60BBCA0B05EDEA0B362F0A33 92: E18E85BCB4633A797FAF7975CEF44B84 93: 1BE27EEC72C2EDE151978705C7C7DED2 94: A15D36C5C5BED77699838832FC225DD8 95: 08F31E68BFBBB420742F80B20B69BE8C 96: 5E9B4B5B3228F533BA8EFC3C0B9AAD3D 97: 1239BA6D941D1D8AD2ED561BF517D4B4 98: 5233F50218E0D097EFCC68F1536F30AE 99: 340B47C78B003272EAA4B9D22C3B0542 100: E7F11759FE8A897364C21767570885BB 101: 054BD6ACBFD5421C0290B0839C0A0ACC 102: CC0748F7B2CC921CF5FA019F955066C9 103: A4DF167697949B1AEDBBA3226A334BAA 104: 29893B9776BA5E750A9FCEA37B0116AE 105: 2DC25C935F006F7965FAB3256D77004D 106: 24089811FFF2189FB9AF38651F43977D 107: 0E048569D634BF652CD8EBF859C9B69A 108: 00386B569DAB73844A708BA5B48BBAA8 109: 8033E1AFFBE1218F81C8331343FBE5B5 110: 9B82008A34F3847C1204ACA89F3D57D1 111: BE1A529F88AA05A42AFC40F663E97849 112: 5237637AA645E83B0E56A1361AB80643 113: 15BC4405E891ADAF48FA56D4356705D5 114: 0820087438832B63AADC479CFC88BDBF 115: B1E3BA7E96605D5FF614B1BEC1F57AC1 116: 838A096D64E6C0DDB069DC89E4C3F839 117: 934BCE159F3959A933C87AB497CA8D42 118: CA501F1DE619A570DC38FDCB8B3F7722 119: 033B27D5994A6F5D5F6800539B69E876 120: B447FC68FEF4E3CF9290B06EB6AECAA3 121: DD3D3F72F0F1FBCD030D839DCFEE457A 122: EE73C4C996E0150D93B3144F20FB2C1B 123: 5AF9679D2441542391C6A903FD8C1626 124: 2BD84B87230511DAE7256B62A46AA45E 125: EB159E5694C191F7708951EBC0AAF135 126: 60F02EFE1DAFAACF65F6664A2321B153 127: 14E5A0E90D4420E765C4324B68174F46 128: 09F1503BCD00E3A1B965B66B9609E998 HMAC-sha1 0: 06E8AD50FC1035823661D979E2968968CECD03D9 1: 0CE34DEAAD5CF1131D9528FAB8E46E12F8FE3052 2: 23924849643D03BBEAC71755A878A83BD83F5280 3: 6119DD9A7024A23F293A3B67EFA2BF1D82EC0220 4: 379DC76AC2D322FD8E5117CCA765391BC0E10942 5: 7897CC86CFF17A3F95C7AF02CCA03546F5CC2368 6: 1FA1EF3980E86B8DF2C8E744309381727ED10E8E 7: 03B2B726D71DAC6A2BEE63EAA09631DA78F5958B 8: B8CAC4C104997A547374803B5898057B3F8110A9 9: E165E07F8D542FB288C7D367198D0618DE3C9917 10: 18125F046C675F434B3C53A28C301FB2D91B5D34 11: FAAB993F2FEAE442D28FDBB613D2C768ED13342D 12: B657E7EE3A65C6484D007E21484813D9AED1264C 13: EEEC2BB7BAC158742711ED13090FA20462A5E5C0 14: 12367F3A4E1501D32D1731B39CD2DB2C5DF5D011 15: 57DD9DA36E7A4E567A2C5AE9F6230CF661855D90 16: E37110DDD295D93990C4531D95564E74C0EBE264 17: B2115C4E923EC640E5B4B507F7BC97FE700E12DD 18: ED20C67345867AB07E9171B06C9B3B2928F43188 19: 6CA7DFC9F8F432DED42E4EFE9F2D70D82507802D 20: B39EB4D2C190E0CE8FA2C994E92D18CFBCD8F736 21: 91BE5ABF1B35F6227772E36337F258420CF51314 22: EB957199EF666C6D0EACC64FC4261D11C715BB23 23: 2A18D8D4AB1F8C528C9D368BF5A7CFFC2168D067 24: D4DC370D482D82932701DF8CEAC9337682C2551B 25: DB9665A6A26DBDE20238F04E9F1A368D26564E4F 26: D5AE212C9E543F2656699B59DEED54CAACA9A071 27: BE8890F9DEC6A02AE2848D8505B6408E884E6D1A 28: E8D9DD9FAA3080560B0EDE798B745FEE2A1E5479 29: E219219D2CB8C363C2687F578446ADE1C0404287 30: E8E7767B35ED8D0965F68272ACE61924CB044262 31: 1B26689C1EF55448A61DFAEF98B6E7206A9675EA 32: FE850390864E98A17FC43C3C871383169741B46D 33: 3F63068D536A282C53E5C003BCEEC96646CF7455 34: 2962C292CE247F11ACB7E1F981447C51E9BBE63C 35: B28909A2B7B2E0E13FDCB1124B0BDC31D7D2FEDE 36: 8DA0FC30C8322DABD67D61E82FC92351894789AC 37: 543DAC6D449FE2DDC3201927D08695F68F832905 38: 371540F3092F77867F0CA9DA69318C7673F68388 39: 7EAF32204EA5993C87E9A12C67ADA4C85D253281 40: FC4994BAA05F592901085ED7DA188EC3A9BF36E3 41: EBFE77592EF34E81BDA05305876411484DC0744F 42: 25F64E8F076305D6F5741EA58232F68B725B8F6E 43: 5DBA03F7E4B4226666F0D8D5BF49FEE77951D121 44: 98E1D56D723DCACF227D2AC67BF2D6E7FD013497 45: 53550BC55A367D87416FFA25261362E7D4618DA2 46: B18434BCCCC5F08B35397C1A6684D60F4F3A452F 47: FF2BF38DFC6909B46A01E055D173F67A7E456341 48: DAFA445432ED37FEC99059DB8A0BC528E788E95D 49: 7FF823C570F8B4C0E483165C076AEA7B5E727632 50: BC4FC948AB621FE1419CF6006DC04E7D7B32FA23 51: 1678AFCC3FBD1063E7C82CACAD5B6A933A93091A 52: 97DC2F9F56738FDAFFD555BF09274153FC2FD009 53: 74F5CB4F0900441B7AFFC278C01A3038DF3D60C8 54: 021F66143270C9D58F26AB193DBA81A811917CBC 55: F486D1C8127813FEEEA8A693C4B8ECB5BB53C3A2 56: 8397CAB8EED5B2164FEC6BE688971DFA2138934E 57: E4477CE9BF8CC5A4CCDE039B4E3000F1A0F4153A 58: D6D2D1E3EE4D643AC4B38836AE54E846F99B376D 59: 9545B2C6279371D4D928AEE24328121D43DE1E5E 60: 947ED38EC087C4E53F417E8216408863A8EBFCB2 61: 32518A2326ACDE1E962B3D0D2BF950F318894E83 62: 5D21D368FB9D879ADC27B341D608BCF860AB14F4 63: E2BEDD94D565A51915B1EC6FA9DE18C62D12533A 64: 15ABF657DB6473C9E2F017C7A2F4DBA3CE7F33DD 65: 0C9DAF8D959DAE3B66FF8A21A94BAFC523ABC462 66: A36BE72B501D435CB627C4555A426C4ADAF3D666 67: 1C171979D67A014A0422D6C3561C817A354CF67D 68: B75485B08ED052A1F4C3BACCE3C563DF4BA82418 69: 17297624219C5955B3AF81E5ED61C6A5D05BD54D 70: 38A9AC8544F0EF24A623433C05E7F068430DA13E 71: 1E9EEEAD73E736D7B4F5ABB87BA0FABA623FB2E5 72: 4B9D59879EAC80E4DAB3537E9CA9A877F7FAE669 73: 7F76F2F875B2674B826C18B118942FBF1E75BE55 74: 1716A7804A9A5ABC9E737BDF5189F2784CE4F54B 75: 168027EDF2A2641F364AF5DF1CB277A6E944EA32 76: FBC67DED8C1A1BEBBBC974E4787D2BA3205F2B1B 77: 33DD26C53F3914FECF26D287E70E85D6971C3C41 78: 97906268286CD38E9C7A2FAF68A973143D389B2F 79: 45C55948D3E062F8612EC98FEE91143AB17BCFC8 80: AE1337C129DF65513480E57E2A82B595096BF50F 81: CEC4B5351F038EBCFDA4787B5DE44ED8DA30CD36 82: 6156A6742D90A212A02E3A7D4D7496B11ABCFC3C 83: 3040F072DF33EBF813DA5760C6EB433270F33E8E 84: EE1B015C16F91442BAD83E1F5138BD5AF1EB68E7 85: A929C6B8FD5599D1E20D6A0865C12793FD4E19E0 86: C0BFB5D2D75FB9FE0231EA1FCE7BD1FDAF337EE0 87: AB5F421A2210B263154D4DABB8DB51F61F8047DB 88: 1B8F5346E3F0573E9C0C9294DD55E37B999D9630 89: 09DAA959E5A00EDC10121F2453892117DD3963AF 90: ACB6DA427617B5CD69C5B74599D0503B46FC9E44 91: 9E1BB68B50BD441FB4340DA570055BBF056F77A2 92: D3E0C8E0C30BCB9017E76F96EEC709BF5F269760 93: BE61BB1BC00A6BE1CF7EFE59C1B9467D414CF643 94: 19D693B52266A2833ECA2BB929FBF4FCE691A5C9 95: B99816886D9FE43313358D6815231E50C3B62B05 96: 7A73EE3F1CF18B5E2006A20BB9E098E98B6513CA 97: DEC620F008EF65A790A7D1139ACE6E8B8EFCCA5E 98: B6BA0EBD215CF1B35742A41EB81A269ACB67C9A4 99: 3A0FAAD14D3B64BE4EDB9D5109DC05DFFA7680E2 100: 12E62CE53283B5422D3EA5D8D00BC7F0AE8A127C 101: AA36F0CC6B50AB30286BA52BCB9BB5C1BD672D62 102: 55120C68B419FE5E12DB526D4ABFC84871E5DEC9 103: 372BF92A9A2507509C3D3932B32444B7BE1C9BAC 104: 7AB4B04EEC091F4ADA0807DDD743609BCD898404 105: 20CB412425E88482E7D184EFEF79577BE97BAFDA 106: DEB91399A7BFB8323BC8E6A5F4045125277C1335 107: 6769F41624E553B3092F5E6390E4D983B851C98C 108: 716760E4F99B59E90A4F914E1FB72A6D2C4B607A 109: DA0AA5548B5C0AF0CC494F34CAB662A30372DD11 110: 17A0E2CA5EF666EB34E2ED9C10EBC5DDCD0D9BBB 111: 1B3614AF749EE359F64F3BE3650210CC3C3498ED 112: 346E604622CF8D6B7D03B9FE74E7A684AECCA999 113: 629E46882D214F9BD78418C2A97900B2049F1C83 114: 765F86114E942214E099E684E76E94F95E279568 115: 002ED578F79094B3D7E28CC3B06CD230163F1586 116: 52CC9748778AF5C8E8B41F9B948ABCECF446BE91 117: 9326190BF3A15A060B106B1602C7A159E287FD4C 118: 18A5DFBAE6E7C9418973D18905A8915DCEF7B95B 119: 6D25BF1E8F1244ACB6998AA7B1CB09F36662F733 120: 5F9806C0C1A82CEA6646503F634A698100A6685D 121: C3362CE612139290492225D96AB33B2ADFF7AF1E 122: 3D42A5C1EAFC725FF0907B600443EEF70E9B827E 123: 7FF97FFC5D4F40650D7A7E857E03C5D76EDD6767 124: 3A92F2A18E8F593E6A8287921E15E2914DF651EF 125: CDE6F2F58166285390B71640A19BD83CA605C942 126: 21A227A8DA7A9F5D15C41354196D79FE524DE6F0 127: EBE93AB44146621BAAB492823A74210D3E9FD35C 128: 6560BD2CDE7403083527E597C60988BB1EB21FF1 HMAC-sha224 0: 6E99E862E532E8936D78B5F02909B130AB09806B2AF02F7CB9D39D12 1: 1D1D08669FC34CDC5FE5621A524E7181CD5B5BAFCA3DA56D2E15FCD9 2: 014A21F82D0CAAD15EB74DD892187D7AD93F2BEB549A596DFF2C9AA9 3: 5F600F19EDED821AEED09781792F9435458A32A60FFC1B678FE2C905 4: 8D933E18052E7FD1F98E5E7D02384DA60F3E743801032256282AE2CA 5: 21362A65B49C33568251CD1366EB13A4E683359855C00F3AD6710896 6: 1E1814B72BFB185265AF94FA622E4A1A70826C06F2BE2EFD96E4E168 7: 118F2E1C2F1AB8AF2BD17842FCBFAC966F5B21A81996E3CBADF76442 8: 2C6C72703E33A20EA0333629503EBCC41B64DB829064A5C7897C465B 9: 794046ABC3BD8165D12C2453FFA3FC518D1A6498A48C91053BEA2966 10: E6C3B6E2DC215702960633C976B86B8378D7780FF884910454032C7E 11: DE7CFF6E85D9411FBD58B28FACF72DFDAFA115614BEF3119F6527104 12: 11CF7495ADC07EC29EAA7B3464F772D49999A5E1832F71FCE18CF7F1 13: A7541E63945FCAD62D2570B015079DF0422E96075986B45772860F38 14: AFD3EB7EBFBA79CC68E4F6F6A2D758969B5C5C014FFB53CFF21C2841 15: 28D942E37CB92EDE2E6F994E9EEE2BA01077D099F3562FEF97A8CAC6 16: 34C7562962548AC9661759B4FC347D6A82CD47991EA06E855571CDE1 17: DA76FA12D69D1FDBA5E544495BBE45F620BE147B73D6AA64D3B3C298 18: FBF1911FA019CB7ACA20E3F93ECC0D5E8D60DCA0A1A7420C63BA1864 19: 565FEDE0EE20842B82D59644929C2A1A426E397B38FAA772781FE018 20: 7B9C2BA77B2989904F194021D308089E23F00954275AE9AD87306A31 21: 66CBF93ED8071FFA36B61F3AABFDBFE714C3C055B2FBDCD3CF369025 22: D96F10ECBFAD7FDDDF60BF1511E94869ED1D992051539E50D5F32831 23: 5473F93F0D979D77C3C6B9CEEB2F3DC1058D81401669EF4AEAFA17E7 24: 5B5A75A7D99C1B40961533C345B95FBF0AFA916D6E133967FCAA15F2 25: 2A1E50E18C37AB7BD928AE14C206FAC9B3E869173CA337FB9374565D 26: BF2B241659C96007ADC25D9567947BAA740555D066636731EEAE3C97 27: 6E1E7B64A70B190BEEBDB9DA82C8E4B160CC73B8FFA224A6B92180B3 28: BE36A5F8DAE9294B3995D278CBE9273E66F04D46890B44EC55028C3B 29: 9983C289CE2F806F41182752A753E0A890217DAF3778B3AD2ED6685E 30: 8B0F08EDF2CBE25E8F9EE4D2948BA6BF81672BF4F509530328A8BAA2 31: B65FB77E6CB86E5F409EAC2F1B5A05E1910213563F816121AFA8CF14 32: 5D15E17C8C159EA5DF5F126B12ACE777EAB36A0082C57DF71E4D9609 33: DCCB3D17C8756F2546B3E5B24B1678438959D83A56524415666DAE05 34: D28DAB7CA715AC86BF4469D743A0005AEE0101F339350661D46A1684 35: E7A1CCC4B2B300457DCC64534152119390B69610C7FF9DD3A683439A 36: 29380148DA403AD5911C7BD52C783EA97EC306F2B32BC426C4D7FD35 37: 56DF59CD635F025925A968591E60DF2CBAB22F98B67C78122F3CE868 38: C20EF10AE9CD99CBB54C94C971780E0487899D7A810FA51A6553DCF5 39: 5B78837F366097CAB6D31624C06B099BDC71286E3AD8873509ABF4CE 40: 8DA09589C44E710B9F84014FE553074E72E0A86C9418EFBBE420D2C8 41: EEE18FA2BB5A5CD16017B4621ACC4211EF7CD60613A8C879B0AFC0D0 42: AD9670FCD043E6F91CE986E6F55905337248B72E7B8551AE72ED32BF 43: 97FA4FBA4815DA49F6127C96C969574AA9543B338F93BF9171D2547E 44: 838D5AC81EA6BACB827327E8EFE96CC2B14D92C55B40CE58F4DA181E 45: CA99480DC8480FA07784EF02074453664DBC92257366514060F07C93 46: 93B0E493D272470F9F274DFE4B9DDF183B26011090E15861FA21CAF2 47: 770CAE487AE5890DC0B931EC17623293EFA5B22EE1ED496A37EB9FCE 48: 6F1D5CA0446E7B82DA02847ED1761CF02D646E56FB0CAB9B120E5282 49: 2A8A1254F6CCC3D656397A5F2D64C266412FC5207866B073B77DBDEF 50: E8CB788AAA965ED87FF2C7B5F3107684326DCBB0E667217E0EA62C51 51: 85BDB6D1486F27827D5870812BEEE2C3976E0DED4BD2F994BBEC12AA 52: A14E0343FAD6BD78E0A8E3BCD6D0B6C83B1220FE6C89F57F44BC805C 53: 2C60D71F2D4BEC90CF10804DCEDB9311637B34D62E9CB68B8503162A 54: 36397D66B434BA744174DA541F080CF6582F10322C7FB1869A100141 55: F612E4EA307F56447112CAB5D2EBEA7D12C7C4427D9155D4085687FD 56: 9798B420980748993BC78E3601B8AEEE2D2CF6E59799C7B07B88435E 57: 50BED37F1EE78FAE16D178FECEC2EBE4776C8E5FC738F9506E8AF676 58: 2755438A9AC457B81999D9E1E479C36DD9AE1F920F5BE6D109ED7431 59: F3DC2238B13BA706A048253F86B79045B72EF767CF25DC62F96DAEA0 60: 11900A3154C4DFC49B941258A134C9201DFD280728BDB3F8BC7903F8 61: FC584202454DD7C9258F72A6258E42F3C2669FD138FD7AEE6200C4CB 62: 185355C13E146EA89387C332225DF31CF114AEC0BA3A5A5B53667709 63: 8194DABD2F7A02DDDD7B752AB5669821519640EE3B0059FD333F3401 64: 2CD6946C6DB676ED1EC272AE34735A0546AFB8D996323272C39A814C 65: B7A344BC5EFFEA97AC49894A85B96F9B570E680DFBB28C76F7F9A180 66: 9011B80655A9CC7964CBC4BEE1CC03074003CCCFF5DA553B289ECF6A 67: 6BDE25371B7EA9ABE31A524E49CAAE40DB220E405463D93FC7F66904 68: 35694194E10D0EBCA6758099D09C99C3CAB37AFA52FC4F4361C510F3 69: 4E7A79F362D7AE5B1680F30E6770CA46FE6264C9FCA566718C01EF67 70: 9DD18D21E413AE12112AFBE16684BFD4FAED7467A2FD5904EF0B493C 71: 7532D374B66B1E5B17EB49810DC3C04264553E4C36F4550D1E860B70 72: 35EB09C82A624B1E3ECD965ED8522E9572EBF26791EFA667B4DB952C 73: B9C17DF6F2A6506FB1DFCF1A9089974C45760A438330AE7547DFE685 74: A7DD0267C15B36D8BD1879F879E894FB9F33F254556B87BFFEDD71A0 75: 68A354D120CD63A5D34EEE84B7E5E5BC1E5DF6E021F712BD4270B781 76: 441DC4884130D48BA134E2FBA86AF643C8EB79CD1AA4688F82E0D3DC 77: 17A3F16DEAFDBC1DA00BD14D9C24497BE765F41E2EC79578421ED8B9 78: 8756A267D0CAD54BFC848FCC4D6B6C94D39CAF07831EE35324DCD35F 79: 004EBADA70F19BAB48E6072E2090941DEDB5CC0A7B624E4BBB671382 80: B7F8D35CB865977423710FA1E0F939808E68ABB54BD7EB0427DA03DE 81: F3D0AAA2F912FF95251D3CF51EBF79B940DB56839DEA8BA5872D1FDE 82: 0835B2DC376BEAE873F1FA337D75C72FD1BF0F72A81669AA891F2722 83: 7CF9A7D57CADEC3F013D4BD87C00B420CBFF73670A9CBB072D18EBEB 84: 68AC0A34930329F5AA40137987208481E34D8B9C08EF7A85AE3AB38B 85: 00492F706D84B903D5355FDC0B68C2C33B484A95A173FDC4AC945028 86: 6F6C509CDCC84CE1C36AB76C9BF30E4422C90C869C164C64696AB5B7 87: 4C0A35D512BD0DB15915DE08FEA8E6027063A1780C104F6273CAD5C7 88: 27087F6425878D64A56BD5ACCC0E303F803B7208F20AEFEF75501F03 89: 4EF78140430EF60F3CA12AAF8132674B0DDB154F495029B4051C2A36 90: BCCA3153EF93AAF21CA02D235A23D3013976295E704223CB37E860BA 91: 20CC8D4C64E09B00ABF23864BD7EDE542F5BE480AFC4B9551B301EBA 92: ECA3F86DA00098D91F866C58558BB7B00C9E4239CF83C5A3E76291B3 93: 7AD9AB198858820D20373C45173D76AF8D68F829D9A250ECADEE0DA1 94: 3E1C202F2D589BDAB015306AD063784E5BEA48AE8D1DAF45D571D2FD 95: 990C44330D56EBC9EDD951F8CB92D5847F4BD3C6442906F57A828FA9 96: C92F9FCC6220EDEF52B6F842635A83914B236862F6CCBED16F4899DE 97: 0E41C85D5C6D625E1884EF7438DD9EBAC818AB50CC265A73165928D0 98: AE087D57F9CDBCDF4DD68A3E8D5BDFEC709A532A4A646CB31785506C 99: 4CB03AEFD24C833B5350996EB261E803F6DB698FB81F37F8A5C3D891 100: E680BD218AE972999BECDC905F4D39251ECF49B29CF0A13AF5FB09A1 101: 64326D6B692B0A17045434BFF13282ACB91E7B690339F7FCEBCC9AE6 102: 20CD91504AB04E2D3CD849808F2362943BECB310F4A0BF6E3BD47751 103: 80F607E2D79E1EFB0458E47C8E5726CDB8387BC05F42D6EAE3239A20 104: F83C023D6F539967AB24309DD28321599782ACFCFC76B77186307300 105: 70164A250799DBE6C5BD3EDCDEDB16D2516A9FC1BBA294C49F753824 106: 1883397C9C4C9D33FB9E1E03325EDCEA1606D7ABF86C4387DABC449E 107: 1355DFA06822CC1F216C131F2BAA92A10BBF109BA3E648419A35C0F3 108: 9E35B9B307990B7D664B9EB7F06EFDD23037F859ACB6B96A5287A846 109: CCCA26C8F8405FF62421558255F2DA06F73F17D1AE1763A0BF8430DB 110: B4FAE909368405206333491674559B9094DA4C48913D9EACA28AD75D 111: 3A5E7D9273F91E10545FE6861D4FC223A5EB0F7B4FBFBC9931634C25 112: 96553CF0C5C6F6A17FEED04024FCE1D292C392E60B3595FF53007AD9 113: CA9B79F403412F71FBC10E094B35088576EB3F7F8B5D08757D89F45B 114: CF60CC5B1822E4A12EEB3E1E5F4AA79E345D8C8FCC546D57DCC7C784 115: 807D65C33E74DA0E2D5E3788084C61AE3E8771FDFE643D1269A7901A 116: A5418DBCA94A1F9692FFDB3F7AEED75806CD9FD47171A6B67921C0A8 117: C2B880C9E9D78B0C397D72C8B6684276E8C22A7F4D6821DB7C998775 118: EA447EA731673E5DEAB57012CC9E0D3A7B2443165B665822963FD6B5 119: 0F6D50C04357DF9240802977779D7F2214FBDBAE95B6D8F59B414964 120: A3B24B29B29BBF32A01F21FFF13F44FCAA5FED50718803AC3BAAC548 121: E31E36C38A7F2525ECADECA047533830A9C46D609E297142AB3DACAA 122: 592FF0C399A6CC1606FA3F404DA4BF8618A4DF159CBB7E05DCD30BEB 123: EEDD6A5902091ADB8EF491F820613740DA73A160D825121912613DDB 124: 3A2FCBFCB007F45CB0EEDBDD5A765EA0CB7A142CE3C024114D6D61DC 125: 5D29E1732898854AF468BBFA5B87065BB811AF8F55C91E82E888E842 126: FD1F646D021EF31F634EF5FB0506620686B9F7D9B5C672734CA10FDF 127: 5E43945BA9DE62C364E34CC1361FFFEE9BE8974D7CF5D2E06428916B 128: 0FF4DA564729A0E9984E15BC69B00FA2E54711573BEE3AD608F511B5 HMAC-sha256 0: D38B42096D80F45F826B44A9D5607DE72496A415D3F4A1A8C88E3BB9DA8DC1CB 1: 12B06C3218C858558CAD1DA6FE409898C31014D66CBE4ECD47C910EC975E104D 2: EDBEF6AA747C951F25AB6AAA0D874648CF18FFECC4C9159F8FC71E971FAC6D21 3: 03436338A166E9051599AB268CD74867C6159378069A9FF46FC07CAE375EDA68 4: 634758DF0774A587F3AC6AD7988D0965524DE24EBE4DFF07EF622BCB8DA71ACD 5: 0C08E52C7CFF8B5F70781197069DC8F209552D241687BA0D24661CCCC28D3937 6: 749F473E0D934694AB9917569A61591CA50BEF18CABDED51666DF243DE879D53 7: B1E12CFE0273F5D27192D1A4B70EEC4DDC714B66C8BB1921C63381F78CEC5219 8: 1C60F13A1C539788E989BAC2EBD4F8E126EE6ED82C2E25817C63B2B633FABD33 9: 5643F445B2C0656A49BB3DB5088C9E2E4B2082C2B611BBA0DAE5791F2FAA5D43 10: C467F47251DAD4694C9C7A6758E54CEBD68FC933C7C57458020774A2A2B4288B 11: 85C90CF2719BEBF40EF8D501FDA20C342BC406E728551BC0275ADA1747BD981F 12: 06B72DAC895B008DA249B7B1D8A5133F09D86BF82DE2C4251BFA6C3D8C4CF03F 13: 49EDB6714A556DF324E41A3CE5B57006E38FD7CA8B90FEEA2ACAB429204747BE 14: 7411921D759DA0B491D6D4CC372DB79CC163F146C345B4A73D93EEB4C262A1DF 15: 5C37FFBD1F0512AF443265B2F3E8B6D01AD9B45FF6F373D2CD0A7C6E48D03E26 16: 773165FD16D51E51CD8A958E548902B47BBD0A6E156C31B6FEA036F6D8C4A90C 17: 5B4BE909754EBC8ECBBB8B5DA6298B8341B35D92E17CE7281909EBA1EF568347 18: C6EEF2D12F54815561EEED3426D7AA7E671E26D42384B9478D91FC6B14CC76F8 19: 4C9FA0575CD96BB1DEF6EA79F5EC7A1F0478E86352812F690C2C2BDB70028BCC 20: 7F87BA45FC41EC30E76F61E4EADEC013CE2B4C49CA6FE6D2FA525F6BBD45E103 21: 9B8CA1D70339A0894E16CE4E76F6655ADDD3EEB598F3DD80FECC5EEEF3F638C3 22: E4608AEA430A638799991B748BB858C91AF58F56B226E1901D28336B30498279 23: AF4F9C52079B28546FBB44EEBA20C7AF0BF493D34EF6967B07CA32FC4DE25ADB 24: FE51F3A9313EEDAAA991350AB4D1D7045D42AACF3AC7155DA3AD9A2F1DE3A73E 25: C1F5AED9D77F85404A4B308A139D33F351B20C91A738E698BD8182F124D96C82 26: 3CAC12A252B93B7D724AF9119FD3C18E85E88401F93BFF42AA05711B9833B1F6 27: E61D4E94C212324A64B1A0C04B2237A9A1C5CC003D83EA80BCEB45452DCB42F2 28: D01BA47DABCE4704B6820EC0ECDBEF137B9C4ACB80DC99B7C9220CFD9F9CE363 29: AED502C53A8B2C76F671376CDDBD0596376B3664B917CD9C9ADBC489543D4721 30: 3405AFD96584C5E5963362948D112A70155877BE3B5EFD479F226B73351ABAF0 31: 5FA0290DC68B72B1FA27DBAF157923C706B3F52CDE9C4EE38CDA31D376B0BC0D 32: C1391C694C985CCBA707A8C78AD05E2180AF6B4DA5BB877AAC5E2AB33B4890E2 33: B018E7B15F92DBEC58F767633BCA3BD0D84B6D5B9443784DC1757166D7AA1C16 34: 8D9E2C84967004E3957DF59D502BC11CF8C8959368117EC5DB56AC958A3E791B 35: B0EAF9C0E869D7A304DDB30061A73C580B0A6F9D49E15442ECFBB3B5A851855B 36: 0B48B0D8C3ACF7B4F9ECF8E46563C921B1B6720B6C650D72DD1126B6763CD595 37: 8879D239EDB09F6606957D96A1F4BF37EAC0F3419881EEA79E8BF1364FB3FF6D 38: CC663E436DE42E32EA110F9D90EB990D9151C9F06D51243D2076B0CC45361736 39: 732DC3B1F809E55C498C53FC75A23966CAEA16BE984F795CB1BC94D026FAB30E 40: F1F0EEC77D97A0234D0F19B2FB12A96B6E2FF8626F79A74D4AF26CDE1344D838 41: 75C9D8C7344668C478D8AE6D9E2C41E336E7A2504CDD43B73CCBF78B4C05EEB1 42: 4B149BCA6429408B242E76C52C4D3A0A5F5437EC0AB6D24D71EB1AC5496D75BA 43: EDB65EBEBC0411B4FDAF186033E306AD500711CCB80E770E99523BB2672A237A 44: D1BBFF5A48346A0DFD5CFFAA7A2AF08C27F3FC2908D7A5D2F575E07CA9E72474 45: E8EFB6373DD3457610E57750738358A50026D2C6704A98148CDD69BFF7B70551 46: 8E3733B729CEB97444BCCA405044B98F45FC59BBA86444A3FC0F4DF4854B5C4D 47: 868F3EE8F4D4DFEDC3FFAEEE1FA069F5FBB2CB818E63C28151C1566634189234 48: 3F5396115DC7F17AAB19A3A9779CFFCCA57DE7A7C1A42F748FEC49B7D8C2B82D 49: DC2A5E3E176A693AD8CAE551A505729B78FBDE778B526E28953BC1A56B54840E 50: DC91FD745E9A7A9D0B41C79B3B3939B84BDF78BEB007F9AAF8FF82084759223A 51: E73DCF5413F17D4ECCEC813DC060EF907C2E952AF92DD247A0AE2BE798E6A40B 52: 696B5EE4C1E1D8B60B0015EEA2389C9A35088022FFF10034D0D09FA722A2A3E6 53: F86C07265389512B2CE240A89EA29D61C6C79C2738FACA157B0DE43294485682 54: DB31CBBFD28D6F8564219911EFB748A5663E482DBA26E38634E8E27E3CF65707 55: 2F9675313AAB7A940AE77CA906D0342A448FDBA3F7589D14B1344D586EA157DE 56: 7D829FD994258EF2AFDEF22C8CD5CC1D29A9A55B62847B3B6F5DB630421CF999 57: A6CDB9BC9AF75EA4680E895E8EDDCE76F536F7CCA571D62781A06DDB3424FA50 58: 1B4186A34EB07F5B3127F2BE0F3943610679DB0F6BABC7DA03B416FA577D36E2 59: 7B5DFF3459DC10B9B7AA2B2829094F97706DB5B2F133B8BF9F48D90253D68359 60: 2ABB68160300028BBF3B5A414970D11DF4FD6F4B4A35029DEF8492ADFB19A480 61: B1B13ABF9D20C42E755D63EC63C016126259C8A6C3F9AB3F0F6AC5D0BD44ECA2 62: 9ADDD17E5CF407CDBB12E5E52A50CE134F1B48A2A2AF90D7308344FB5A70485F 63: 6A4C06DF40BA515C56476471D4A94F87A2B91EAFF6C66510892F2F20A342B736 64: 555D424206C003BAD0B08BEEA76DFC81B307C79BBB6E4F15325B2ECD37E04423 65: 8A58733E0B990D0D82F93F77DF36E30DCFD03B3181B73C544BB097A3A73B6AC9 66: 6FCCCCA4172E30A281A702E36E7BCA07370D4B57272385077A44D5F7933DD2FC 67: 3B1A91E49AF88B1832F8E91109C7CC5DBEE2847D9ACD2A57404DBB565480AC75 68: 69584075C278763CB0B09D4C9E15E9300A191BF99907049F14EC8DE24D86C121 69: 2EE24340D13E68B10B95C3F77D55027F98BDE6BA5328D0C02CF89965687C062B 70: C04B37F5932F427D40E21EEAB7C9594B16BFCF4F5FE2BF175CD63C62F2CEEAA2 71: 058E1AC8971ADD2617A4BF7D02B46A8B74A4D52B25643DF9729A1E7DF6CCC86F 72: 18001F246ABC760197482E25F3AC64B14A795E55B41B505D6027261BFDE7C52C 73: 4AEAAED524B173E08E54A83E2D9A8B8824E6E2F1B89203D698E9BCE7C3242F8F 74: 7D82CFB1D7427302889CADBA23A99154CBAC0C9ADEC94EAF29EB07DC86B0B7E2 75: 18D42E92BA532A409CEDA8E3A07E751B430800827F5A9F14D93E3ED231BA08AF 76: 8CFBA378D8595372DCE5D9A6E726C23512F84C0C1EC3C66ADF6B6C55DF63936A 77: DE1A6E280A9054C91B826785928F37A16E1D2A9A3CEC831185B26D2B8EDE158C 78: 920C40B4204C7F3D4775176BD245BA0276604C568B3C29943C9AEF1A1C93428A 79: 935BB39E5FBCE5C4A15AC2A854475578CF80308E531CA86818DABE69BED8824A 80: D608E561471CC09EC0865C826242CA26AA1C90BDF1625E1A38B96E3EE0CC5F04 81: EFE2A8D806A1A71596A05A2F5F48D18CFD4A742247B04E8089FAB27291A8DD50 82: 80235BE35DDEA5D49F124D8BE3D143F87CCBA7D0608C7E2CABBAAB01BB95E477 83: E9410E0DC14F3BE36A49A5CA673C12E18CBE4F0817E0C1CBD2069349F8A09BBB 84: B2042A81A36F27B4CB96DBB52A61F701A815869FF5AA0CDCAD0327E1ED1C2F22 85: E9E5A9501B24952DCFBB9D59CF95A9A9E6A27FB7315EB472D1E2B7F523D06D42 86: 99193B4FAFEFFC932B261EF169250B96901ABF877424FF667CC0DA0154C50498 87: 1D9C7F7E681D20E1E0324EFE71C8B6913FE8CA87EE52E443335115AB2C458E7F 88: 7308DB7E2591D2342109C5084B1174F07D289FBE91472FB2D8C06DF39F826B84 89: 90F06ADC29070DC50A23D3F093007E273E783491A70A2F0AD6BA40E34F02518D 90: E676DEEDC972019F10FEC24B4AEAC0A97870E924F7B1D6D3ECF91EF38A2AC544 91: B5DA3B40FBF373795E67A6338F9AC3AD742741F34048930D9336D429D02EE78F 92: 6FDE20988863CE157042EE52065EEDA233BB2E6EC0464B9DCF2AAC1F3A18971F 93: 428D4CFF477F0F0379F634D1E7C15E4CE6DA067ADC45221A860C9C3AC4235753 94: 9EC80B57E921DA3F81D13B65AA851F5971E4074C96E0D8B64E50A7F5089C1FC8 95: 9088151BEF766D0896A48EB6DCC8A09D151C3396FBF3A9FE193C5E7BF9030B01 96: 86D853024A762536666316F363BB867EFE25FBD03BDD28EA7522973A1A1BD95C 97: 007104BD935B532BA4702A78C505D67B41358A61DB8069585B91B1445DC346B5 98: 5C5709F6202948E805FAC25C454ECFADFAC693955864494E511F0CD1FC9CFDCF 99: 0B010F71C5323CC96D3B8DF71170968096E44969EA55B4C3DAC632D30D81D529 100: 54621EC4F31CC7F6273601D81674612B44726B5CC4A76EAD2BBC3D32DBF62A9D 101: 28EFE1AB745BE64E5DD7286C97360FF2D287F862ADBE44380F85E1388008079F 102: 831BFA684C25542676AD52819249A10D9EF9C2505D69CC1397D0D39D08B39E5D 103: EF7922C40CD96A47C5E7AE4D958B495F1D6954EDC20596E303CFBA43190A9EFA 104: 3A0262EBC746A7C044C1DB043951F7EAC645C40F554898D3D7B2B7AAC4EBD396 105: 1F2CFBA7275639A12DA7CD1986F920C47850DE3FE13C931618C0FAC765820ED5 106: 7AC8913C0975101E187FDADDAC5B5EC467A25869C4E630EADBB42DD2DFE4958A 107: D386591F326C91D274FE625A667B6F9F6F7D99CF56ACB365A218F1CF8E167A70 108: 66286CB1B61156B005CBFC94C2CAB1A6694D7F123411B8A123F2ACD821C291F2 109: 844D1038E710690050DA737D56FD6B17C261C7BE512713E62033384B53C40902 110: 7EF970C40080F554851277F4E950C6F378B0A3DA3CD1BE250D976162F8A4EE79 111: 9BC20A2B67566688BCAC77FCF30259F11D9B2FD2277D033E6AAE19E36058A353 112: 796C72D95BBA1A4341C6B0397E165DD21CFBEF55555B35C717CE33B6C6ADE490 113: 1E6A9C1F78AFF266EF8FB25C32C1FDFB4A0F64AFFD046D257470BF6DAEF61D6D 114: 0E1AD927AD658C5E0321333AF8AE4ED69903B4F22C5DFF90AC93268507A7C86B 115: 07B7A778E2931704E7FECA284FF3B14071E255A2B824AD0A2272D21448579CEE 116: A8D810DF06368A0E825D6DB4394916E43E217BEE9303AD4096A8E1CAD37B8703 117: 6A9C7D302CCA1EE170366F355D8F40AE3A20D28BFCB2BA163DCB68E08DACB748 118: 40C3A8B08FF9F767491E4243D1808572FDAF1D8CD21AB47115849531513D0750 119: F26EA6760AA80360398371855783815BCD34431E0CCEC58A34A67997ACE43CEF 120: EEA78D68A509988ED6D7E3F27FC22F3EBCD570EF0FE242A0251457EAC4C3C1F4 121: AF977819B87F2E63C0E131DFA2A31C555AD831ADCA6DE0FC1BE48D21A1E7E666 122: 846A75DF3691B2BF224FB0E66E360A2E8BB1DA32422190F2B319B73E6900AD42 123: FFA997FCFABC9FCAD4B58B0EF848890FB23B974CD57FA07223037450C371B116 124: 0028C776965A0AE5E9E70D9B833BF328BDBCD06C5A12A2F1C510911E60AA304A 125: 7FA234C59957C214A7BE8D1B909C540B48E54414EE5FD1081B4C339FD2204515 126: A840BEEBF2C2E80AF2E4830BB26F71AEE48A9C65DE4A9425DA9F98FA3A37DD84 127: A95332415EA29A8CA6FDB0F771E3F2262C6907DC45B0AC8BC229F6009323C3A9 128: 8B185702392BC1E061414539546904553A62510BC2E9E045892D64DAA6B32A76 HMAC-sha384 0: 44BE81C415D283AB7A62A45188E5DAFBCB97DA606BD5B16C92C1FC36F198C0B3A714921848D5E03DF1C4849BB8310C66 1: C1E1E68D864F758941B87E30C262348B373F167CE4629E4117FBA208773CCC2E6C7797AE5D6BBE2ABE6BAD4DE2E1052E 2: BB27A0F06A1BAED5AC4FC2267C36EAB663E11EC5F0FCC0BDC09B9B0E803B0ACAA2F39D2AC73DE489FC7C9AD6DE3FC9C5 3: 70A273A2E9E5092EF8D4C58E99734A911B7CADD48954FD518305313B0B682CFCE192018D4847375D7E311470D05D97D9 4: B4FAF12B325B486B67E38A855D18B45D1BF6CC60E4D00AAA6E58268F524CC1121AD3EDB64D6E0FA524F11C0F139D0BBD 5: B509A325F561CDDC539A3A4680380759747709D428B77E69C4CFE926F65B147D92D2C83692F526EBB5CF606AD162559E 6: 9A1E678A743BA285CE154ADBB555CFD097F5839EEB2DE4147986464C1BF032BA0D80473293467ED0A0AC59BEAE736598 7: 1DF214529464666002C1AF094BB36F0FB14A4923031B108C21825E8C55BF6A0BB34C9AD7D5030B2FC7C83A2CD4C79C1A 8: 86D8BEE44CAC35CD3946321796599F20F3A41BE28F161FDA062E4440CCC16E88BC7FFC714D525A6420CDBEBDF6AE9E12 9: 92417595F9974B44BB11EB9200B7560FEA3382CDCB8BA4C2CC5CFDD019C2B5956D3E78D5B186633ACB765E822B3D4E90 10: 2E87CF886036B7A66AE6581BA0DBB9AC2A39E1C7C7594319184FF3B612A165DC02B3A7133E3AB3D29634B1CD5305A46C 11: A5CEDD2B54657832F946BFBA14ED5106E8EB5937EAC6C5405BE5CBE7C58053514E784E3F6668C20466A242D25A44462D 12: 74475D913659C2C304BA49DD2B39B0C7AD7D537BB2240D8611876CF5955B347694525396C43CA73951E711DA38C6976A 13: B0AEE82D70411F1A79DD7012421BAC1202D7C3BAFFA15B4D8B868A3E6F92B513F6B026E2E8FEE45DB2AE70C15E11D19F 14: 7D06EA64FF5B9139662FCF9318589E8FF1F783754A9116E090B0B7A981A9EF1D4C1BF582C8EF5E71A49DEA2834447287 15: 8F52BB9B0A2B1066AB67603C552C17E983D15114C3B9776C548D747F7E24AC782253812802EC456914444DD67C0CDD46 16: 9DE6587211FE4A232F01D6D20554102D24D98EC140A05303C1893F232BAA2C07C81A10C25A95A50B38E87898900BBE1F 17: E0175EB9DB2649801EC2EEA9DE2C1E950C129CA249C14326614E0BB8C32AEE67DF1DFC6320439DAE4FCDB4B037A53868 18: 0606A848086DDA50D031A585103478EED0259A9167959657050F8D7DD21B4D6B62B93AEB0009B1E878EDADEFAE9B2ADB 19: D4A45DD1A6B613E3D2D72B35E6030E1531D75AF7C3F100934CF27EE9D0E0F0C236581EC8EE74FF759D7A19C5AA6DA9E9 20: 3E0FD11AE4933665EF30E10035B0E686DCA837F6D6FE2D5A10B4EC30F183EDDF3558309905F028DB93323D09A3A2F3E9 21: DA2A204C7908FD27A29415CAE3BD16A0488FA1D42CCFA2E2F5A1EFD6F99583EC6B3B36762060F547C629B9A332585355 22: FFE8FFED47933CC941A8E9233C037080B9465B4F9C25DBAC790825C013545D2344930E953187C77466437BE226962F80 23: 69FE734D5C69F34366E5CA6B095DE91CD4DEA29AD70BEF06AFE9BB232162E6BBB1349263087212AE3AE5D74A3B060F50 24: EFCF1B825AF87FA5199FB3C76783CCD1769E7DC77BCF145DB76FDC622BFA2425CFFAA40E6376086B2DBF6F5D9D97A534 25: 98C3DC50FC08D2A87ABE3FC16871ECB820D530B453C41F83FD304D51660FD29BEC6A7D1C63E3E12B6E80E8C58CB129CC 26: 945047CD723EF4F25AAAC4A19FDEED463EB04CCB78EA318989143298DFA70D793391BB7FCEA6BE0D79187543426AADFC 27: 2718D89F835037C94CD6378A3806614B85365A888B48FFD08C09F0B93360C04E43B7E7A19C79BCDC5DB9F5944579AB79 28: F714F16238075796DD43960E17AE0EDF9990132D690F44957C3DE9EEC2773683172FDCC44ED2104320726BAA7DBDA1A7 29: A87A96ED8FF0E7FD1F235F070CB5F14B41B2C4438A6D7A0A39D038C74008FE9C52497CC506498414835AEA1192439379 30: 31B029DFA85DF545B752506E80675E617549A6725A658CA8123D8C837FB71D8C9961BBC2460D7CCE0CABBDEDACB56C37 31: 0B1A9DD308E5E6E65E4C60861D42B628FBDB2C2280370EFFAB736A77A8004C5ACD5269D090B652B1D8F146C1D518D288 32: 2A160E0B2EC7BC927FFF813A2B56AE61301AA14933C659B3398C7A0B3CA506DD00FA6F1DE9C6D47AB0FB2BF2E7B4B83F 33: 6893C0205F3F4ACE906F2FACC97E2B1624D40997370419E5981E6041D5CF34C77EF5ABDB1AA0D3C8C3740100C2711555 34: 95BC8C72DC8C70ADB7CD38311292ADEB9D7BDEC6A9580EF4E11A18317CB65667D344D8D6603C044454E67F97F4DDFF40 35: 3DD892A4E724376814DD5A4CBE96E4317AA8AF72478D53379247E77C35461BB92CF493851FF1FCF57A6704923099DFEE 36: 3A5DEAF967BFA3EECA3F259307991F7DBFCEC1F354DF385CF0EE8D93291721553EA954E9D6593506E9F3E330E0A02574 37: E00A883DCB5460AAD611603614C7214EC4A566E0580FCAB1CA4ECF1386A42DCDA746D3AE1B0D54E0B9AC1FA336FE787B 38: F437CDEA425E7A70CB4D197C0CA01562532A7C51FFB8462B4796A4FD0A7EC880CB0E5EDDD5F703ADC179374416592256 39: CE69E40F5B5F2F25E0B53281BE76ECB0E5B4558292A1C1A5EC56F2CF11B01BEEB1F0BA01E6A9B3D03BEB69AE0511F320 40: 41AA84D15342CD0675C8C0312C024352E99914C3E01C98F969AD04CB5705E9184F3821CFC6A22D43A77C928F6DB79D8D 41: 74001D972353BB45FF3F7F405FC727CB5D0B00431BC76A57EAF17862BD52949AF884403ED6B2A002D618EA33523DE200 42: 968BC28223799F1EB92F1432B6AAF5CF6953491C3F959977B065BDB800AA438CC8AA7EE1304C18999CB5ED709431CFFE 43: D067EC03F14D2D639C4423A311EC86B3DDC3693A2CF43C259BD0358F8D0D68F41950CB705249A59072A2CE7DF155F5C0 44: F41EB77179934884DDB56DCF83DC90C606D0226DDF94135FF8E1E0AA56C9A90881C4C380CC0AD3BD0DA45A6352BACC05 45: 27BF9A98F9E2732972FE2F35ABC80AE2E5A2BC1D238B9B1D9CE605A89144EE9766987384EBDCD63533E64BEE094E4503 46: 166892E106BBD9D16819D9BDD3601D24C0C11860DB13799F0797F204D07DBE914A7BD286B380EFAC34DFE3C940CDD3BE 47: 2D85DBCFC431A94F8F50132DC8C10B25001EA10AA9DF7C53AEE9E8383EAADFCECC21202EFBCA556BB4E33CC68156B190 48: 086007E2874E779A5EDF0E176AC1A11D241F4AD8D02AA99DF2BC1AE3E5CC4775AAA92ADFE772CEEE89D4FDF1B601D05A 49: 2ECA3144F4F9EA0F37C2CA5943F458590A1D4D19C0ECEA6A55CDCA648C99CD457DC57EAA995042D7FBFAB598B8AFEEDF 50: 9C1F31F5D3A589631D8B7EF89A507011736BFC328071513D64E5432D24B1BCF47EB10139B6410A3103145AF67B5B6C46 51: E0645EDA004D9005399A2C072ED9959E4F8905D15C57992553202A3B53BCFEA0098E6B28BE047A4B29EED7B57602C0E3 52: 6CE5CA92F0B1E84D7578DDB86C96A10924601A3680BAFEE5A0B27D8390B59752205EA483832ED3E9343DE7175601C03A 53: 47F50844C897FD910C5C228DEA1EAF456882C1115AB71DB15E6832D96607CB79C8B7AD1CDDE01966FCDDAA0B0BA9F264 54: C0A7EFA24590833E4788BB117D3AB3CE00C84CB4820AD9FD7F03CF1CE1A8983F9906BDD138E1943D75ECD9B98D5AD8D3 55: D056E9F831B6DBE97FC751453B1C52C8C6C4D18A00050F5AF2427C1123706375A918656D6755A4C950F4E5B5C318CEBC 56: 462650CE3981EDD13D0FD2E5FDEA93A9A18CF8FA74CD6142DF4707E604D1F72745D7EE08AB13AFF3A9F8D166EA90CE3E 57: 2BA5249841412584B161063087AF9F5BAEEFD97989BF8A0455E65C94B0663410F0E1BB22EA6402E59CBC5A23F24ABBFD 58: C3B1E4B05A7593CC315AE15F63CE8D91C4B30E0D846A97B7D8F01FAA1B6BD7C9234EB153372F6CC7799A035E22A77EF6 59: 1E652653B9A3CE862DBBAF2C919E86891C5C03F54ED5970E8028F8D5EFB533B9C111DFD88ACBBDE516F0D4D636F5E821 60: DA773D5AAC336B6266D27A03AFDF3A151FAB302E894CC1D09B6E4ECD07C4AF4BE06A2D28D01669C7557FAE8E513D01D5 61: 8C8FE648A29D4BA78B3E0B944597E392A31E28F98B15280E1EC0A721C9ED5E3639A6A457744CC5AABFB3600501F5054D 62: B443DECF40A5693F67B5BF5580A665DF6EB98FA9F14A661CD50D6635E0F78FB2943731AF363839FE6DFC0B4C49F9E849 63: B22EC4AFEE3EA69364701E5621E453A0C3988C1E2FDA54FDB99353F285327A534F7162BC54D701652744413B9A5D4CBB 64: 40A22B7881AE8139941540540FB37C9AF27BCB164B6D1A3BEC709730BBBB413D1F2FD6BA4A7B7EA747FF45F3ED3336C3 65: 246E426C57E414575DF312223272819B0F49FF94953DCB94665FFF74FEAB049AF15160706AC5F702AF66478CF2BBA5BD 66: 184E6E6D5FB55454EEB6DBE323BF28DB8CE60C271DD0ECC8BD4D3F1C2339B7828C1515F030058FF37BD53568FEA81378 67: 10B23FE1616AD5609F6F6C1D9266F702C1B5E6F7FA0B3A81406B5A766E2179D082854687701318A7B46E21FA67D2404F 68: DFCC1280C5206F99A555E291AA1DE6F0A3AE4B49916FEED4337582B91D7EF094159556B01AC87BF7A8E84F9F53595938 69: 91BA9A641616449084A57221647369E2E69525A30B274EE5403FE95A43D0A7C2B301B61929D89222A3A03303550521B4 70: 94F59A7F5E68B942A5D66D3C642A78685F3BB400F4FF971BA576DECE94A353455277632B70D06EAE38329CC2298ED792 71: 21A9F5C4B1290D95A1F3F051A0158F7DD8A879E7861B61CC757FB5C729FE9A8BD46BC6DCE595D20649092B31AD27433D 72: E4246F7DE67C3A08F18852F6159F5DC9FA4C0129A9F894EB610C10F1FB8B61B1C9947D742A418F03A00A7E11ADF436F3 73: 8D2CE8209B8362311D99D68DC2AAE6BE4CC8E52C03A97D99D0C5C15D8E24F1D3B51738BD27BEB6E773472CD22A1225C6 74: 7EAAB124A3C900F33DE06B84E7831FE327FD638C4E68DC8648EB619E3C7E5736A26BCDCFD3AA6AF34EB137C6A210746A 75: 8B60F61A1AC2C6528C8DB07B6874F19B8D474859F98AF03503B115EEB8082E19D53F63D397647BC2D4278B8C2B741D19 76: A48D92BA646DAFF7D0F8CBCB1D574E9C19D396A30573A7404F6196FBD7E226731C8AB05138F7B1936986DE6C1F1F7B52 77: 2C3ECCA6E7AF0F9587E5A03D462C98F18B8C13C039D02D2D29E06B5309EDC82052EF72C94E0A5EB7FD35827665CA2F92 78: C9B659AFAAEAA8778E9E4E3B725F758768963C55151A54BD9DC191E1302ABA1F1F085D5443C46441793682A8047211E1 79: 9A76E83A301C14AC6AB8CFB29D2CE39E0E86B335F2B20C3C889651B4E0B94C5218E910B1DAD28474251D06D12D47072A 80: A526CFAA2EE981A9A4D0EF12A6FA363F562057BB75A218F4645BC5E9BE7CFE7EADFD87386AAE1C607D812772498ABBF6 81: B747819B54CDFEAA751FB9F5C22FB269151028BFBC6650BC518692944C5F4195D26AEC45C9B4C987ECF4076B3871C5CF 82: D45968D452B5349CA43A0FDEFE4A5379381625825A27259AD9BF5A80C46CB07BF1C919FB3ACC250D73238B11C3A07D90 83: C0B8AB0F8C497ED9562C65091DF1D80C32C57A018B00957BF53C41DF81A2F6371FCFE82624B2E84859114152B36B6AAD 84: 30D2BF3DA80C0F37807F042FE7B878851E0BC4093D987438FC2B993F4CC4AF6F704669938B9E30E59BF8999883639F64 85: BB782ACEE42930922A98F65F319089E9B4F5D2DD2374DD76035E3178DB4468A3C04F5EF878ECF9ED757DF14DD89BDD49 86: 157424F30A10748940BBFAFB6D99B1B06A897E7DAA4F03387E5ED03F02D39AF59F96A20E4E9F3A4C5C07C20A8FADC8D0 87: B9ADED711B1E1537A35AF882F1F868D964B5898E85B07F5677DBF183232F36C14AF4D9959C2108D9313F8BFB14830B02 88: 7C4563BAC3C05444C3682039EAF9F9EC79B96F0CD36245F584647BC444B81734D7ED4380CC1F0A2BA876020E55660BE0 89: 9811A4A45CB28A780C063047EC6CF94328102DEED9971DB99E11C6FBCFC046EE38C1A00F290FF64356B9A304DC0F340F 90: 09A69D3255EB08E9B3CF7CFA73D86944CCC91DEEEFC04214F8982836726CAF006A3FD83F8FB75600CBD060ECD639C388 91: 52D6D0943728CD2EED671736B6B3BE801B811410992E4A3BB50AB4269EB21AB945F6A9F7036DA654A7F2785869335395 92: 8C0E1052EF2B06C0C20F67D92E51DFBADF3655FC6475935426AE1C88F3096628EAB9858E5470FB98A546EB11C7B752DD 93: B21351AF8400B9756F104599BA4BB78C2904959E2B24AC3E15FD0398627E6C8D57A7F9FEED63D8638A206BC1683794A3 94: B9F7CFE97C79568D62B07F1EF887C4391B48CAA669AA8495B71A326B120FA49652F02EC0D53441DABA1E104AF091E0E4 95: 69D2D1773208CE3BF02B38A7F14910187F3476817ADCC7A1D9830C9F25F112E604AEBB95D0237AC8795DCB23ECF52927 96: 57A9FA7CA61FA2FDBF0BC3E3E6463901B3B26E5D9AD79DFC0CC77F79EF3AA1AE3949E7D71CF794E067D2E38E7038EDEC 97: FEE9196A0A1199DA8697D00AC8084D6CA1F867D105EE928FFEE14E5E36BEBEDE5C79509CA5BA05E36C3F0BAFDC9A755B 98: 0E8DAF8BA4ED614B38808B4E468CDF88EC9B148017C6BE3FE593410D37D9B50ADF0913B7844FFDCC2F1917A27A58B352 99: C7FD40463E26D6A21373EAE14BCB7403B127A1E23E4583B2AC727106B07B849F74C0907804AA799C05D9FF324D04B182 100: 16E899F4850512FF3DB0FCC58FEA960831364E5FB077CD8DA3F5B3F0F50AC626601917E8355E4847A00E0A5166E786D8 101: AF2DADB17605DB3CC471C00D63C42F75F815594C1B49D9396BCFE7ED4D4FBB1CF15B542675DE8C9FF50EF81B72FF72CE 102: 1699A1EA2CAC707205A6BFAD8DFDAF09C8D6FCDDF2BC14A9678453463AC80054627F2C39B713861734B0974F442D707D 103: 186DA71D7E913DA49D8D97101882B1282841D41CA12F514C1B2DD61543E330B751E9F97490E18A4A37FF1853EFDD757E 104: D82050038E6DF6EAE9D2D4019827025A25BC8CB15812E0ACF4B676C799A3D80ACAE5706C0FB1FF72B2C4851DC9232B7C 105: 1657C99506EC8B28AFC1684C4A9EE4970F8F426E4BB0C3FC2795CFBA82913B453C87D84AE9B32897A4CE26FF4320CF23 106: 9834E936482592BAC2373AA64806FE0D5C8FA92143070C61E594004F0D3B8516C2A5B0244F273124E83B20FE9A2CF5D3 107: 5C4856A82C8E6E49BB81E89C26E355AFB75EF921E579EC4B97868BE2CFB4B1D93195ABA0500D774C5365C2269FF333A7 108: 67B88FAD5085C8BAB8E194DF73153A5B1D334431227DFC619D5CA5D5605EDC7BC95DE33512B2F5B714F46F54E1E61B0A 109: 90C6A8F36D42C5F21A89417AA04D822A53110DF1D062E0C1A6FD9AE59C6588CC1C78469B94578B6D7C05EFFAF7FEC26A 110: 817C0E7ACD548BD3733792F4F8D845D7E4B3CAA0F0EA943B51235EB82DA7C8B77A733D756E86D57EA303F34BD97BA1CE 111: 7FF397FB43DD909AB80BC381EAA4BD50B7278DBF10F39FE718B421D6C07324F398BA5B1DBAAC64137267DE2C62F19F7F 112: FAC12B732122E18DFBCF8DC7382AB1B55353134F07E07723608825C907DB05B4FDE40FE550878D971F8B0B0953C88C54 113: 4DB0FA3C105D64A9CAE84C0B5D7AF0955F6F58717F68366935FF9F478E94D3969B1264B1F37F8F5538BF116DE29438AE 114: BA6E693A6C3C5B048FB7F232CC5E12CA71662332EBF689AD75F6F2C54715A689CB1F75525313FB8B2713909EC13EE0D3 115: 00BA656BEA25DBA36861B92B356C3DEE0DB1C86D4503C7FEB0A88A3541A7018EA456C95224EFC46AA31CB625421BC811 116: 812622078CA3B4F59141569A0E125B36F7CC471F76B7B65FEAA1F1F656BAB6A3CD61A4D2456E2F5109274B2090C1F4CB 117: DBDAD8926A811DD0295C31D55AE0D41672C7F22B5CAEABFDA2C1505B084AD01440E9B8FFDA4DFCFBE281222AFD547E29 118: A32EBC13D689B31617D24E6AC03CE6FD7B1AAA2BA78CAE2E24C36A8CA7BC74ED9BD4CF6C74E3C96DEFF048FE3964F0A0 119: 095D2C8DCF88F69DA4CC49C64B03B2A1D2C6922CE0C6EDA12642480AE0DF35152B4E4A9AB08D6642DDC313C0FA01444C 120: 578A4BFC0CA83F1B38A0D2EABE2C7D3D67436B559624B92E4FBD9241B2CA8C1AB679B503A754D5029314AAC3AF225F38 121: 25E321E63E4AC8994FA464B3E2B687150007D83ED8D6E1B217E86B0CA0D163B0B9686E4FA2F26C1839F2D778EDCED86D 122: C761BA17FAC3CCCAF2CACE92283DC5E5B8A6571958FC59D0070FB21CABC88A80A40DCD56318988F3AEDF38AEFBB84EB2 123: 5EDF5D71D2CF85E7ADF9C7E964FD628ACF304C4DE3483F672666A583E3D9B1D86E9E096541ADA237D69A140571F5B3B9 124: 401702CD847ECA2BC9208F52F27D84D07B37A86CCA5C3A877F24366CDB9719DE63670E850F02CD02C6227B7214D5DDA7 125: 362C899156DF70FA189A66DAB6DBB3CBF80B629D1E90D9ABEB007C3C5010277EA589C4D73009C81F94AFF3FFACBFCB1F 126: CA43387C71B8245B822D3085CF029004E18CEBDFC9F78C276F3559D962635601957B6D2287089AD43F3179D077F37686 127: 4CE8504297E21812C901E77C6680529103A017553F095913CFF06AF20E3D6DE7EFE911B636DCB5791B292C60147F6473 128: 2AC71958C77E39D4DE4DACE92FBB6A093EABD191320A5ADA7114BD201DD026567D2B799EAC78C1F084BA9FAEC2FC8BD4 129: 87487060C273FE18A2CF1DFF222658E1B50C3BC5A3F1F4575B3A4A6EA2F42238DEB68B3A2EC6A325E3FCA504B2E20E26 130: 4A79A1C3C798D9F26D54715108279948EAB246086EBFDF0EAC9152216C0BA3A77AADF82A230AA84A7C884063960419AA 131: DB0BA43960FA6B763202B8BDF3FE4ADA0BAD78EBB3E6E8E57C2D5640D1ED4CFB4AC18ADB1B9770DB49A4252CDD25A369 132: EECE296E258EA3583FBCAD1CDF2B91F4D2AD1FCC1AA339D8F591F89C7ECB5EA2FA644954006F0A58F2F3BEEA1AEAF7F8 133: 7AFD95C86517BB6050D04BF3BB1448A0608411B612A7C2A939BB44B984E361C40569E5E57AD7DACB018689C2B8E2B3A7 134: 7FCE7894C8E8D1FB187CC35CF5758269E286427A63A522F4BC45F814B316C1DAEF981917642C50EC693F3EF4DB8E66E3 135: F67F56C98221892F64E2AE4325CCB80C2846A43E1629D40BB50845184E9C3B66480B3E9F792389983F2FC48FD2508F09 136: 1CD915561856936AFCC75530DFF151F49A34D0DD0030766FBC1BE47D611F10502BE86C97B91D0E8767D4F38913EEDC1A 137: 80D9CC8B1B2B883C4735B3C0C19AEDAB78A0771753EBB4688A7E584BE7366B3C181C8532FB3A8BFC484C9CB0BBC1B4F1 138: 8ADE2B8527C994EAB0807A89CABD5B075CACFEF42381DA3CC3D702316842E25151C65A22E80885E5CD5FB5870FCE501C 139: 2B403F2188D086327C92169871FD5A7B432D2EB999FFB0F2369B2B766E799AFDC1463CF4D9941F828FE42591D6B966EE 140: 4A0C18CECC0641C28C4136D42FABD0BC27FEC27C2587FE8A57CE0D279ADAD70F80C1E812E01B26F2BF3ECDC7673C349B 141: 8906762B63651DD5948C98DBB1B39BD6095C1438B2E4CA4B5A581D451AD3EF76C8A0FADEC9C0B0036A833D8F5C13F1C3 142: A363BF2A479F67F949AFC151C36B052062CC2CE840974BE2F5E79C0BFD7BA29008A6BFDB55B46527D17F61531C953081 143: 4E2AC5D6EE56567902CC1E02F119E33974762C03885EB7DFF7C58ADE22E56BC384FE74BD491EFDB2E6CF4021E3016E81 144: BDF0AFDF17F7B014A61ECE257F8C7E0B52384EB7DEF60ADE785F273851D645E5D3B4D9534C0E6097A12C3CFF5C11D42A 145: 0CDC61FF0B3D8510C319020B82C1C5AA12C7B6F257D7D4F118A5EC3CCE03C63FFD38710F8A3C621DD8D66D8BF3790B63 146: 19E35E1E785C7A41C523F88CDCD919EDC45F63783330D9033768546CF59D10AEBC77F013057C0E41D6FD0FE77DBF914D 147: 8AFA5DF52F6581794FF014A2E1ABCB05781C7F44AE6F37112B363AB13FF01FE1E8074F14466A365374C29FEB048C5B9E 148: BC9ECD12706BE5ADBA04DCE84AD53AE1B324F99C1F5937774DFE19C5EB4D6A20982E97B8F8E4E02EED13B25B8B13E64B 149: 8D02A1E318DA1EBFD1CDDBB7280F3603AF3AFA21B3D4E0727C7CFC576F55640B7A978B179EECDB8FBE896AD38E82F12B 150: 196929CF0849022CCE9CBE4EB2DAF6E5D8014C5A25E119EFF799A82053035BFDB8B05F6C125B1DBDD4E7B393C684FB5D 151: 58808D04067FAD72BBEEE4F6A355E80A2FF76EDBB5366CA43FF358A842FBFA2F9E1AF5FF266BD2E2DAB1D286AF5BBF92 152: 4A548031093ABA730D8D99A2C1C6EC2A986A94167CF8C1EBE83D52B34BC2068A4C95665988FA93F5246D0FBACDF85FE2 153: ED949965036F16A0B5856EA4CF69CEDA35C653BB56FD0F0B397E73FF4884B3E679ECCB19B07D6A93504E82A1613CB87C 154: DBA644B20B01E4AC5CD0A325CB063EEF53AD77E5A9E7095C1BE0EB0E6B7CFE60BF25F38CD57F2AC055D327EB6AECC7D6 155: CEFD6165F70D9019866374AD7AF9C73F3041B932D61A41734E39AE8AA9C7A4FBF1DCBAE9B2A4E979C64352E3CD4E1B95 156: 732C3B457F78DED89390BC461380760FBEF3CFCB9BF42A6C86ECF120C821CAC79D4D51C71A955309E33724742FE2FA0D 157: 54803568BAE2DB4F143C78FF53B85E6A9D42EC3894FCFB39BED8EE611B36BBCBED834D366A1F797B626DFF3D83CE963C 158: 35A1858E567FC8A11B92737E369069B12502ED3F44DB50434506F2E540FE643655CBF806C06F15CF2428FB408A65C04B 159: D1F9E930418D10043D0E83096CF717B79C1C9234C741C59436F42737AC73BD39B3F4B6D6439375E0D44260131B25FDE9 160: D5B56A1A70C47A3F88C519668097B54C989E119EE9DD5B8B34F0DBC092FE7108C9D396CFC62C9322563EE72A0E324010 161: 1578BB76F87DB309A5D3A2229A2B346DE39ADB623836EF0561348ACA7E315C16C6E31328BC70DD0B0D7D9B7ECE076CE6 162: F8DF4C71F3623ED00EDF8EFC4E0EC154644E21E78B06C9C5ACB980480732E17E92ACFA059BDF299BB6C8351C6CC6AFF2 163: 090DCE25595D7770753B78C410F10E830140B23D779E0F52FC451582CDE7511A390450F8B65D7BDA77A18CD95EE3DD38 164: 5D3A56D23BEF1324B1EAE33B8255F904F7DDF131517200A505031D41A2EC3F2AB03912DEFF6BCECBFEDCB8B948CDACA2 165: EF712AC1E6859F70D0D2CACE7AEE120A666DF9F210512F5C94AA7FB388F1DDD913A12FF92CCD2537675EAEC870203411 166: A0E6443505B193D89595A51BCBD47A46E1B5AEB239D68B8B18A119E5C9EA1EB8863B373F91B9F22FA944C29365406A79 167: D97DACBF80BCC76335C187DA29FF33F6D35EA8A8925709322EF3C0F6FE35D128D9D423F911EE31F1C38E1DF36046E507 168: 67FFCF0A9F88F84B3EE85000B2DE0B7DC12A06160FCBBB57BA291DC04E14B6DBB3CDB81A40C2EE1859956DAD097C1EE1 169: 7AE82196B46DE3E6948D7FBC7383A6F080903D6BE6E357700A87F82A964581D375006DE35169446B447537B4F11C5702 170: 502E0A4CF125EC0640DC7E7264D9E47300814B00D4322F2F62BC1D5F1D0D77173B0E7C2874CD59FD8E056B8F38F78D99 171: 74FDBC4532534DBF24230ED5677A920B12E328E3D073364498D80F0CEAFBEC774EB53F28F0934F787C56AB794B60BE31 172: 3C9BF5EEC652F40AA0ECB82A834C836E495E841D337E1299AAFC067A2049C540AABE92CAEAE02F099BC4D3A383D541B5 173: 105AC61F2D4E586E376524C488C33521C4D49D1F95B752D27F49ACD7181E8FBBCA2E0F0B543EFC0CBD32A5EED2CC08A2 174: 5CA49D8B554D70B3FC467604661DF8FA51D9987F2A77B13DE44D7809FE2956D21485B36F1D17B59F2261B1B40553FBE3 175: 1DD075C696DB9B07510A0D276F8BAD12225E00515D19E3B85583BF97CF82B5FE3F685502F64D91F4FEEE1848BCD0502B 176: 11A018C4B213BC67C09370C8A3D0B720428BE71C01C6EE9EF6C9C9DA8B2E1FBAEEE42FA44EE54D0F526DCDCD3C2BB2FD 177: E188EC519C6E0B8A89DE68A7648DAC6D9F84FDAA678B431794EB4BFE077901C95FAE25CA3D39D48EA0292F3F6C35FF73 178: FABEE0B0A02BA622931A5EB82CD63656B47A20D3C0E703D5A69AFDB92C0A7EC5CF6944D9D7A141C1255D60FF9532B089 179: 3C8E0BB55E099CA9F6E436BB3CA39D511AB9CE5674469DF8BEA4A20193084AF8561D5130FDFFBE62193A712D7C2D4B48 180: 914BE8F0A58082B877AF0DC077ED146CCD8245339A170B4099B146476B0A580749D01F83FB52834A033A3822D12041B9 181: A1B31ECBF451571437DE10330A6E9AB4484576AADC4DEE0B31D9C3AFE59FC6DE028275126D7882A2C225EDFE491305E4 182: E4DD2E805A5BDE3DCD329ED9D35CAEC2D5A97082966186118DC46BCA7AEB1EF52E0C6007CA28131790838DD8C00E96FB 183: 785B81A972DFC6A4982E0BB76F90F26DBB7BCD2D06E872304CCF6AB2D639CAD85FB29124ACE411EA4742468A6663EB2A 184: EEC3CBB5AA129C7206A32A176482C9BA24FE60E71B46F7C3C11FEF8EB57682A3732680E6541D5878CD6A715A48D75F12 185: 254E279B7C4F17B911712BF7138E2C6933815BAB18661CB47388FEEBDCCDFFFB6AE8B4B88072B90074704EB7EC567843 186: 9A8CC3FF0D9637220CF2B4AFC9A8A6CBA4D0ABEA6A0BAEBF151380848E92DFED8C0F0E57B6D05095EEAB0A58DFBAED13 187: 349966E1D59BC9B32E1BEDB050354177868FC07257A3A1800F0E711AD00AE388746DB1E4591E3ABBAD8F418E1AE627DD 188: 84ED950BE54768557475E6B1A256C30F444E12340C29485832439BBB9CBD219050D184624D6282728D4AFBB98CE4BCD6 189: 2A7CA4EF1A9356E853329D336B6E7E033F2CA13677BEA67CA669EB7C78DBDDE67F9E7D9099C68F34E07B96DE4155AFF2 190: 7C7020B0528F1B3F76BA258836A89BD27429110F0AB730FD741FE9EA2714AF827E71B731AFD53A293328788292ACFE23 191: 91400ABC089F8888DCB22880B87A380FEFDAF81F237D424F057E5C4C8E3C8EE4E423930C1D3D9E16199ED82996BE4232 192: 412979E13B3D143270BB41FEBC12196B981E99BFD6687B780812F409C78A5E2DB7AE828994B60D26CA4A1F7A3A44C64B 193: 02BDD417852D9B03A37338549DFB6D765EC4CFE4C2385002848BA4D46F88053FAD2A39DFF615ECFAE0D41F02E5877251 194: 77845BA2210971E362DC117B1BB13D7DFBA62F81EEEC7068D3CB9CD093DF535448CC357ADBF0C2394351EFB07C3E7DE7 195: 0F43AA1739359C14BC5702322F193AF89335887F9175289933B2BB3F00A777D1D1DA74F5D45FC43AA90C9FFBB0CD580E 196: D1D9A7B995B9BFF09252566D2079121AB12B0A5ED06014994464FA1AA18CB1BD8E7D5E07E1C71E2EED9CF081A537F28B 197: 67DFFE8A168B7408B7DDBD10BDF14F4F2244FC904DEC5850F5D8302FE35AD1752BAD2DE50449F9C12182A2AAB8FBC9F6 198: 030B5E833F6D8703BD0C5E36354387AF833F466AC812D4E1FAB6CDCD3146FFE3B0E56722D671FB85EAB22CA5CB0309BB 199: CB992B3785E51EF3A32DE88073586DB045F356F18A09329E82943E29A12B2D1490B386D8CEBF7D90FB492966989A73BE 200: A1D337D363A0BD8A0F2342351519C62318A120FAF88F9B90330845DA682261C64627B67D2F533FC48D2BE394DF8F4F61 201: 319DF6326160C7277A3D3C65995BFB729A69B71B40C149DB1241C0B2376B4205837B5770805C86104677917EE5E5912C 202: EBABE3BCAD828A9A3D5EE05C5EBA9605A67E1ACE73AE69F20BF435C3A14AC63E43B61021CDF3FC2245A14FC14A7AB32B 203: 1723D844C0558D58EB3EEE3286C48C133C5F6C1D8CA512F2BAF1FAD7884D4FD5C3000A6756DD1E34E83DD066AD2BEBE2 204: B048BED188BFFB8FF1B14CAA0BACE82605AEB1C666283FB7A6FDF216742F9F64A89C50B9852B8119B5FAEFE64615C241 205: 7FC6E8633CB9B16F553ECA3C75C0C0F7B610010853EFC94AC330D36977EA8722B970DC264D5FC4D69F39105E7AA0EE3C 206: BBC6F0E0158B6DD549C5BADE0FDFE415747F1FA2D2A85CC9DB758F34998FBC8C8D99D573CD948EC768540B363D67C4F0 207: 5073FA9E162BE773AF5BA1CE5E6FC21F2F0F902C80F09BBC3AECAA6CB1867DAE4DC011D1DB987642949E8095909CB984 208: A641BB0E1D20D5DB0C5CB33D35B73ED83216F2F5DDD5234A0BAA3B209A39E015B7245C40F9F372E618EC73450487B54C 209: 948806B7335EDCC7C4BBE751844DF5717457B223C7A3B81B57AB3A949D0A726BAACFBA228BF6C2CF94E942F9B2F1A7AA 210: 0451CD5EEA206D50A7897F495D648425CA333158C126C4DBA44ADC06447A51D3C7BF2D4D81779535CAE29792C7FE5650 211: B4227FEE0A32009D60C9C30033C12B7143D4C7A1C25F39F3E4A076BC4943992AD299DEB2C15E27DF867BF948DA27C009 212: DAAEA18FA433CF3E117F2D43303139D3F1D8C3BB8AE8EFB30B44B9D5D4BD4E553B9B6EB9019CC4E1AE5D0DBB6C23A102 213: 4434C818BCCFD92189A3A466D2757AE2655BF0D6CD954706C85220A33B95B184EB560FF3CDDCC4DF557E427E60F9FBFC 214: 6AA3B44FA507B6D704A66B4D7F26CBAAB2B400C6BE0A8B61B50EE617A16C2C09CB36E72FC309C6E4DB24961B1785CE3B 215: 63AE9C02B96B4BC456FE5CB9BA35366DD69E78DC9CEEC376C6780703883D609333D45CA577A982A177515674B975B658 216: 3B5DD4CCBE8CDF32009CE29FEE4F6EC7CCB1471A3F8E9BC9A35E8CC37F6C56957B757DA4C3204F9014977B93F9E30DCB 217: 04A6528CDE6BB9F425132CCD4AEA1EC6CEA482249E5F3782B000FB071A4EB2434597A7FCE2A364A9BC9E0643A8403DDD 218: 69275CA1F9F102925165A568C1F152D25DF8820A6F34595C4359159070052FED260C55FFFAEA2116AEE7A63DDBAA0160 219: 584697C23C63904709BEA89F055AC592DF48034F908C9F06C706A51C3F6BE5F0F2A5B953AC2119FBC0855B785326C06D 220: 04221F0A6C4799F9CEA3C1D9E65B9F77F77C613FD114135DB019D8C497B8899513AA4B499E720CC11AECADD1AC071DBC 221: C7B878613C2F2ED10C8EA413970B124838F11F0414AEC89A3825DDC588629A8049E82B461A23F25C4F93E5BD11C184AC 222: 1891E7A51768E05BB1D03A1EC1B844C7C8EF77C433F700175998B2D8E2EEEEC4618F00003793C5873655E093048B674E 223: ADD2B81466BC727AC85DBE258B566C4DB56F6F7D81D7A4E43F86C125F2AB2E08C648E628B9CFE440F8BC06FD5D861D3C 224: B3684BEBA86D275745CEAF0922473CA581CEB7371C5747EB87B407468006BA50D69F9BD8BB7F214185CD0D0C548C5432 225: 0C783882FC826917619C07FD03FFC46DE6CD87BDFA87F1FB872989489C32FE74E8C5660748E1E8E9AE19C68B075B0EBA 226: DF52553B4F7BD148574BB47F61BF8F7B2FDBE5B6963E29CD559F236BAAFC3DFD6A7EB5EC9968E0C2B3A453F982F16AAC 227: 45102671440B04027B1F9966C1013AA351CAA3F3CF42C4D98F5B2D030FF37836E9F5865421D7DC8B037644FE53C6B280 228: 247396BF60C0FBA27B245CFCA061D1F6EC50CB87CEE54E8C4A7186A07745D255E4EF9457C0A329AC9E3FC913DF86A4CA 229: ACC5998C464A26C1719E9B17E1B8F5E3657FF0364C46FE87154DCD1C95A84734214D2B81CEA8DDBA501975281EF4EA9D 230: 163F5AE385500C1A6EA212D6925E48CE2189DB1DD47F7F2D2D889272D17449A1C33EB3970A5982EF2FE5F1255367C33E 231: E8BBFF2C5CDA88CB60BEADB8D04B88795B0CCD89057CEFF1FF588A169363AD453564FE7528D1FB7148845363C3E17824 232: 5F8671B7C62A5EE9717FF80EC2AA0A03E557A2840C0FD0B59027AFC834C051CC9B7BEFFDEE3478165DB9CA303E2D874C 233: E0E4DE22993E4A6B4884163C678A23AD6349DCD4C16B9041D01F8B3FAB1E8D8B07DA78BFEB57F8C235C173B2D238C4B7 234: AD6F58BFA15FD0DF1191171F86F2B4C8729FE407128ADB4FAC3404E15C04752F2A4B5F4BDD488378C56FF8D85A38E583 235: 90C5A75642A1811D8FC1ECB84AF4904C6D9E613353C1B9ED0FCA37D20974CC2425052E2300738824BECFDB981AFF06FD 236: EF73A9E6D23CE43508400163CE6F3E8F7076CEFB94E549EB6116C2557F740D66A1727AD51CA645A7F9022912058FD262 237: 99FA424E413A57DB2B1B851098FAB1B6D3337AC7FA85709121F0BBDAFB3EE291F44092EA7EB28E9BF0EA0691AA531BFC 238: A1E0A088A279E750CEC429D0AE320B638ECBF9EE387C65C66D2231C884D844DCD438D4D4E052B8D76998A444E0666629 239: 0657FBA0E7A73F7525505235120C44AAC6D37CE974FF23F52872D6ADA50DA022D417D8DAE40E80336846E8CE211D5AC5 240: A72ED7917F0F9D0DD888DAB10AF9091A380F518D5DAFC005D1EBF0013F57A7452AEBA98913F509509A02665F332EE255 241: 74CC959DC6CFB31CFBBE9CE8ABF32D1629E0F578F9199B9A2E90889A2F032919923142AB32E1DEE0A53ADAFAEFE0EBF2 242: 9E4D463D2E3DC2B98CBA40EF84B022A76D01926D8DE6AC05F995C07C5F07D01742C5410B240240459280D7D278E8BFEC 243: 0D74C427EE654E4790C7118272998C131337D0D0555B68F488AC7CB8DE3CFB461B0248E78340D74B828C80CA28ADF478 244: 952F274ECBC66B68EA74CC8534A5D7EDB219B755C91266E5A779EC22F52DD2EFA9C447DD311E71C90E1419B4B2F3DAE0 245: B845B0A56AFEC2FB399559FA77C4835D2BC4C3F8D62BEB1C45462BAC661D2E553B43D0A86073F0BA5AB85B129ED20B1C 246: E65B931E25101224A6933FAAE7DFCF22FE84759937F5F3BDAA90D9C8E8ECD0BFA1777B99A77E3232E38917F9432CCBFC 247: 4F69FE2CB97E9233BC873D153ED9D61B88C20FA333BD4137A532F4F703A323FAC6F8675D8B44EF5FAD2314894F7D60B6 248: B36F43A6DD2917A1AA0C6B566599C274701BDF03A5B7DC65E5E9F0ACF882786F07989B106A50D0D89629136EA0E26EB1 249: 8DB7B80635C53DAEF891B777850487E72B67F57576EB05F708786F7665F1FDC2A78F441636569D1E84058A43F0243A1A 250: 14A43F1882AE0214F56819F4AE9276499D39DB4A4A939275DDDCDDD80CB6B70999E6178C4EF295E69A807EE5FDBF9AFD 251: E5AA44CEA67F0821D4ECBC981F258837A243FD901653D484BE5C24EB7F08E0BF33525EE3DDF9A89E1263A853485B5A02 252: 0191F0505CE5512FA08500BDC090570F0C430161595894528FE7AE5DAD8726E110B0676181A228A7A90E21B7B055361A 253: 76FA1230972E771661485546D6CE556FCDA23B6DC0FFE94DD3BF7FF13FE9B46DCBC8D8FFC617F35687903B972FA7EA43 254: FE280E1191D21CAE12EA3B53D77E03EA4D96108D35555CBFA9B156253A011ED91B857B82D644BB94BAC8E4FC4E0142B5 255: BEDDC3C0E168A4B14B023DFC1AE07BE9A418678494C2399695EA9B17843D373077A708F8C82F37657BDC101950FED664 256: AA5D7EA1126BF16DA2897AE036E94D1F96875AD306B19910EFE3F17B7A98F9A4163E4032EFD17DDBF78FE3321047509C HMAC-sha512 0: D29B9E3F87809686F34109FBC718D6ABBB09C278CF05A206ADF21463E1170362122E58272A31679720B254CBD63A7C6D696BF9283F9C6897E7D792483BB0388C 1: 5EC18FCA20788348244720D58E9532B4B699E78D48CF7D7BDD1A4E5C61CD09C075EA7F112DE379FBE953332C6A7D6273B3F6360BC07203A5175FAE618E4A2F55 2: 293D275FDD5021716117D2B85E6D38F8D60D4984BC73E2D8D7EF5942CF1287B65C0675E566794786FEA18AED1192A024FC4B3E0505D91E1F91833B210590BFDF 3: 8D9E222D6B16C58B3862D6BFA556BDFC2A4A152BB2574C2294D5381F6E38FB681500A6A19D55525B337A467A2FC30DD1684832FFF92AD071EEF05BC4F4399FE9 4: 71E7028F8C4CE9C1EAEFE459771528D26993E180E616D68355B9C618153AFF2C0E9620B151C8F733E71180EB87BD773A512B945AA353029A8F807FB2A8FF2264 5: 589F462D37095693ED0C1F3E0DCB892BD19086FE033718911931509EF6195AD17C79939A87665889EFA6DC19A69BEC6E7058531552832CCBBC06F1BEC70D1736 6: D94FC6BDAB3613271522BA05C998A6D1C57CAF0E6EE929651762F257E7EEBC07F5CC7CD3D4064A2755E408B347939B3927434556B4ED49CA406C21D1024E6D80 7: 4D8A886A89E9C60EDA3BF0BC512A295196C3F62018936DDB24BE9F6AEC7AA9511B33CBEC8A22309B6389417F4E7FB0489981CACF03DFECF7D9FE5B91D62BB719 8: D0E00955F0FFF98ABE885970EE44F1B5D4C23C205C64B681381FA13C543106B2AB4E762FD71F47008B4C429C39ED3D66B3EAEA946674F08684AC99F957F50416 9: 4F623E52B5FA2D556D25754FD00BB8429356FD75FE2EC57EB4BA4E25CE03C5332D3A632179C9FCFFF140E6B443A4285F4A7CE881E6D3EEC4FB0DB26C0E2DCDC1 10: 5196EE8D442E5308F9D8911C87050DD3C4842D0CDCF55AC554412CF096EDA94BE1A251743AD5BC5F8AC902A38B66D7D57C90C29200984572D57C04F64166B803 11: EF77019B0F93B1598E38D3B1B703B52660192547353E7FCD5A7C8525DBB516970D3A6F2A94729D90A5A34CEA255F310C1F46546C2A08975AF477DA2F3689F17E 12: 0A77531D7081095AC0D0ADF2B379D3F820DD20CD89610917E287FF57BCA5DEABA750E1E075DAACA9CC4DDC74732E6F7BCCCD3671B6DD27503CA855EACC63FFB1 13: F1E04B1F7B09DA270A44B62DBAD2FC0160BA1D144D7721010D77ED250A00986932CB6652D95B4A977494F11AF7E7FC82A70DFDACFA11232D653B1A052820185A 14: 7BE1855550A49FF66D6D395DA7DEBDEAF674F1AB192DF82D74F6BAE8088F83EF1471F413CE00A404486213E41B42CF6C4F7FF1BFA17A1E28928B7179F0A966EE 15: DFF2CDE8856D811494F559E9F4159065A50B1E82961628E95F04D595F670249A2B71C2625CC1CC2B1F85829255DA007F0374363EB749E935BB72BDA24B8A3F70 16: D2F7FE57D9583EC1AA733403527DFBB118DFE07B2A60C43039FB238A7205A053E0496AD0F3C1896090AEAB3088283C8FAF272D1D53B5F9F88281E0A53FE7F8DB 17: 963F629ED8F0E7D6D4CA4DC8A8B57C825F726380D0BA9A9857459491BA82F64A929EC4ABFCF79374CA68BA812E3A83A643D05454E146E9F4103D17E20B8350F5 18: 1FDAE69CA4A9FAACDDF30A56B23F14768EB7D5616F6666B6F01FE5E216825CD4201A69CE3D2D1D2C3D03246BA7D32ADCAAA4A7D03B9AE6AF4CFBB474E1717BCA 19: 2532E98B6D91D8D658BC1A1FE41AC719D648D47BACB423C031A8E2E9C25CC6650D3E5DF8046BC3532875F0C8DADB38AA911F216E6741E9FAD700D31269EE5D46 20: C81E6E9F4B75A4EB2B903C4DE28CC437CD87BF789F6BE60EF521491CC7E44AF26E9EFAC55961135F79B3591F5F7B92ECDC9917641BDC34943C6759AAD9437498 21: C0C2B9478F956800B64FA408BB0E077FEF48DE4B146926B3C577C00688829FFA6540AD7C211A807286C546F7D146F95989E77B62F5E14D62FE0C77C85FCB6CC3 22: 980D06C1B27EB2EB15069566BD1BD838FD3DA453751BEC564C05941C9BFB9EE8443EECF84CBF8AA7DECAA294C7D1A3FA4A39C20A4659DF332CAFFCB2863A769B 23: 70FB10E482AD19447CFAF10EB9FCFEE67F9DF7164B2647F19CB220E7D83BF892AB7B5C5ABB73B779522012BFD464D9D1B18C37C3F6CB70EC4106FA94F8CEFECC 24: 7AB19BF67380012D3A53B93AC15E353D477FDD1E2E8851CD5AB5F36EA0C8B128D3193934F837D23D232F44009AC60DDD358AFC8D3A201BED3EAEEF74C03617A0 25: AAFC1227AC42CC27BBF78FE26B3FACBB7B15360891C8EAA8C737AD42C00971D02B3A07CA751774D02F402F7E76BE08E2C1241EB66242DB5E11B342C22AAB9FEB 26: D8CC3BE5B48C7BEE8522BD8872419932907B78392B7F2546788477C858D0C7BD772985C0B0D202AB7E69AB5F4E1A0BC848A512FDD79EC29F19BC4BA6D28DEB07 27: 6133D836D68C82658F6263F794073CAD9029F20CC11D0A6CF589335B023CFD66D708F09136546C6C08769139363AE5CB4CC2CC86EC6911237ACBFD8B0423E377 28: 833DAC9CFFBD62FF0749391A42324E2848670913890754E24ECC29D4738AF00A78134660A20078FE59C66113787F4A3E6C0E783740B2F2B2BC8D36FE4EDE39ED 29: A2F3BC0DF058506805DCF5CC3006CC4FC4085FD846C7A7A7DD3A06CD6DF635359F4FBE90A676DABD7F9AAF42577C8E3B07B63B9CEC8A9AD05B38D16F56214E8F 30: A49C3BB487C561E5AADA4FBA2D9F5B42681486AE2DF56087DD65B3D5E03C625F709299C84C64A68D87C92A4CC90246D608E692D1FFCE2C099348CD0A19407C2B 31: C8D7B7A7FFAEDE88963B09A09ECCCB4CAE77DF9D8D242BA19F6485BC7775308E5D11C78FE9C46E609F3AF070F3DA8ED929C103DA1F25BE7867FD4D3E4F2757C9 32: AD4627AFB02DECFF956E612537F011E82CB0C202A5A11AB7AFF55A201016C02CD21EFB4EB197BC2D13D272C6A830FD77F534E800B0AF1E79FCFB626ED6A0D6B8 33: 8D4E232D9614EA1194E60748496CFD32A4AC249BB8F08E55A7C9DFDA708DE90D067FC433EB9DA2A6833D43BBA8E8DBF31137A3C9B26903060EF9217471E9F945 34: 4CE5E4055F10F1D2182A7892F98206D9A120FBDA3251036B7EFEC835C95B4D1FE0BE3892E2363087D01948AA426AA403ABE1CD79F0AA851E2D1195511C7A85AC 35: ABD65F8E9A2B39BFEF6EFC9A9EDEF6572489AE82034EF3BF2AE5F380026FF4CC40AF093F0408445735C0E6EBEF5D7E7ECC13C98B59807AE01FFE1BAB040FD14D 36: E8C687D7AF785B1E547307875682ACD82FB58A8259551D81F309C923C2B1FBAF5935EE059B89070B8420F71EEE3BE7B1E3B55B196872F06DD1FB890F6FED11CA 37: A344BE73E6585E0CC31525BD6D4EC3345D7780CF180D0D5C2D5FBDEDCBEA050A958FEB13C21924E311F57FD6A498756146AAC58412B98E4D2A3B29D9B77A9F53 38: F0A088CC818F76A1FD6B5D707B114BDE24245CD55E48611ACC6AA497A0CEF93768501B5F280AC518CEE48C15373118BE7B72F8ABB2E9FD3526DD1C18D9CB2545 39: 4D56D5C9222BB78E04DC9346FA9C4ADC27AE08DA3E34F490A13F674264896E58F9E9839715F633C7195B40DF722441275C84AEF162B513E673809F7874E7A124 40: C4B3C9E8140F0D5589E326916462354827E491F3444E0C361512E6E761F5E24AE1873B238B73F32F6BF8F1D1D8FF9437A01DACCB749282E776FF66151A4F7E19 41: 7B4E07BAF338DF6479E169EB6CC64CFF88167958D44C5CB6606964B7F9ECF5F3F1B1F695C63F2BD66354722F81EE4BC90B9FCF5345642E264C66F6950CC8C481 42: 8571A8F76A1D5DAA0900A03E236FE965D085BE6035B7C0601EAD338106BE7DAFAEC82F7C3D8AD346FF749B6DAFC69901A6072CA089B7A5724C75CB0818640F7D 43: DF516D84392E571C3FE39F4A0BA5D16D866553644B4C4627D3513F0A1C60D22FC5AA4276A71CB37BD6D6AD05A12BF812A2D5388A606583B78372B84DC567431E 44: 535AF3C73B479B61B8B70E590E335DC4C1E22DCA656454213E1FDD46D026B6D36133BDD372FBFBB27B6DCA8E487F4A54BDA8C5F67B37C871653C656DDE9524EA 45: DBFA27964DC6A80FF76112FC6CC02C87811DF1ECA3A8620A5030C600561032FC374A6B060FEBE0ED67421D9217D2719F5A55621736FFFC6F4F26DD4C6049FC09 46: 6F69BFD2C60AB1554023A6A2094D30CA78D364501F7813A2CB73DEA94AD4B94A0EDF3A3698D6A30C8A5E764B81F51CD0CAEF0F996B8C685A345AA630CD10570A 47: 2769DDB3AF3DD650BC381D7B10CBC4353699A2A352E57FA5D5CC4FB610E498767F49104ED0F4E06E2BD563F7F8045212F5B9C49CBE050A1662F2262BAC4053CE 48: E50169B15772017CD9FF93D1B46AF273B375A39D174E3B8621EAC8EF968BD967E1448DC3B2C72A667EFAEBF2B90D4E6640698CB866075E95817719E0EE61DF30 49: 4212648E8F9ACBDC16D48CD7B355884E0817A95DB03BD9B8AC5B28BE6371D8AF83546DC82550B8B23DC77F6D06211E3AF3B25528BE686CCA1672C91117DF9762 50: 33C71EECDBE503A6AF72EBA8D2B9AA7AB8FA8DE536C87643ABF1BC3EDA535BBA64A8A7F4BAC90ADB7D8C926DCAB1D7DCE15D356C5074BB3EBC7B17516671EC8F 51: C8EE9E57EFA859DC5553D03402AE80B84B1E0032CE3F2CAC43F8422A80E3EF59126AE7AB4893735F9C948CD9FA8793571E4582908DA19FC723A93C7C36F79F9C 52: 7CABE0F83E90CF9A497DCE45F14F9926DC714DEEF05A1A0603F6436E134FC7C8346A19CB92DCDE69D794B38FB22233577BA3905C94A7020841224DA888B9BE1F 53: FDC20554A15B71BA62F896DDC4F8B354E5D2434B0AF719CCA7DC56FBC9BD280B0F80136C4336D605C7C26208649F38C1DD0004C6E0E787A91FAA6075051FFDCF 54: 87387F89646B4068038E011D7E02C353BD5649F6DA1C4C46CD9F7D69EB3A2F6EE84DD42D25B67BB81666CE8F92A5B1A0F3EA58D4F0B5B6E59EDEC86B43BA0CA6 55: 6D0210417671B66D59B8F28CA0EAFDB493C30A7D7329DF29194C53887F05EDC2C3F35853898ED77394CCC650E8D350F69598E3AEF3DDF540DACCED5BBCBAF6AA 56: F14085036C69398BC7E0CD8A9D4451A10B080E7CEDA5582ED396E5D54441125EB3EF6EDE4534E788DFE6DD3DAAA204814097987981EC8BD8E39E8E8B35AD8FAA 57: BA67FB4D7D137531D3F4CD3D91975255FCF8EABBEB97EF0FC7C21C4E25FD034658C63881B0AEBEECD2B7D15357C14542D26EBA3ACCA944EB4C4D7E44E9899D42 58: 4546585669E343AD40792308AB456DF623A6A23CCBE64B26B953D6C461460BBA7A3FB444481BDB3F7FC8D5E825F2527D2DFF193356CB3171CFBB56C679AD1BB9 59: 210F8AD68FCD10BDB8773194FE57EFF566C7E65BCD82BE6196DECB40BF39774691AC6BA718E4B5FF0DDCF2C0510182B9A114C6F0117A0BB0E1AD585C69D38D0B 60: 29003A048ECAC0613CFAE8EC8757F5E5CF80E9B0BBF538D7460765FE2D6B56D6251ABCFD42B56D64B56D8F219868DEB42B968E88D3F3BE3A161DCB43EA98349A 61: A308F9E2B60D0093A7278B0645A471408F58B45B3683531179F34931D06A15F4A502F2F7E1DF8B47830F65387BB9F102646058AB456045267F2DC403A1D9A6DD 62: AD484DDC270FE74E68620AEC882E86320D0D0753E713D9D5C9C7FEEB894DD3FD5FDF4995DDEF87B1126B36E92618331126F5852AA8C0D44404BF9F77B780595D 63: B4BA7B2F08BC0FC901188B50493FD165F659D3226227E2E9892BD70B02312C12D195A73AED3A4009618E6E74799DB158D9AC27FCCA9BC682B09ECF53BD368C46 64: 0AF65ED93646AE826C79BB6E8CD193D5246BD00B0BABF8425ACE03C845B9AEE428045D5F8267F3EA86C433F1A9DBF4AD1883AF164EAFE02C07CE43079668A248 65: 65F899BE2C5E9879F6A3BF7B60E62591B5DC5398283229E4FADB1EE78FFBF962295C427BA0D50BBCB9E2F1DD9694BD36CA598BAE7C2EF1F4D0700DC95BB66C37 66: FA9ACC46F0841962D6DDCBF5D47BBEC43A0E1E9B2A8F8B7970E2E73C06612FD95044B8BEB58C71B19AF4169B7E6500500445490F80EA4E305B6BB00C7181810D 67: E9AEA6E12F881A7AEC3AAF428BBF0DA3138EBF69C6B8E52621609AD340D6537E4A03E2B099B735FA82A3D300F782606EF58598683D4ACB0870D5130B4B3142FB 68: 3558ADBFD411DB8436A1A8B40420EE9C274FA153AEF891290F79DE5714130A50C70EB87E8A901D540ADCFC37E40EF44592822F6ADBBE8E5CB4EC89909633DD7C 69: AF3852A0B4E846B59A4EAEB7A7A451311B1E8F554042CEB2D253F10FCB3067F9CA927C7DA3E57BC9C99E4E7997856B35DAB0645C194AE9F1FA0A92BC218CC9BC 70: 6BD90F0F8FFA39C2A483E8349D2A29A96AA7F3CB4B4C1325FE5162988C9DEE849B8E56BF1423B6905ED3FC6A82A067F850372414E2A4A7E5CA379AB80F1C4F23 71: 6433885A8A39F2E4CBB36191A038EC3E3227BDDDAEAE24FD396481332A9AD7BECCC4E9BDEA0C8A7F33180ECB1EC1DB49218D17C4325B661967ADCBA25B341649 72: C3235054A1FDFF2C0D218C3B54EE6A58FA5AE99040A64A90B9C8DE601B80A7C130168FE7484CE1FD9FBE22E6E794161826730B63DE794EC4ED1D653E40B27F7A 73: 89F4DF5AC626665D9791A1E1C30D1F206D89C4B0C59916DA295931539B0A607A1261B4EF022CCDA6ECE02E99449E252EAFC8929F5074866C3FF59CC58268E2B8 74: 3F1AC15A90C38AA964518F176016FDC73A85B096EFD1FCDCCF38F3EC692635BD4E610F1B3314E068164D02168F73A307AD549E1E7EF07DD374F9697DB6A17447 75: 4FE16A3BF0534DD2E4DACC43E221179C9B61D7D50DAEDA4DA9C45CCFDC76D6FA96EB3CC1C184DD5DDF7DAAA413D05B2FE518117E2C9A880726148C7AE6052160 76: 1EA870E13B7E59B97045F662682F29DAEC4413566DA341468CC9F5CAB733D1897BBAD8E9520B85C43DE33B9B70880AB774EA636248CD0A1626C9CDFEC3F1835F 77: 37AE3A9828B08A055B2E47A613D25A8D43D5A456BF741E7964C0DF4AEC6D8E5F3EF874F2B20606A38AFCBD307C104DFA5BF40BFBB3078771436276E777F645DF 78: 48CB9B779D37299162D2674CE2C2595B2422071917C28AB48781DED5060E76EDABA56E7C538C3182F9D960DC21928E6B3069D510046608C976D7A113DE54DCEB 79: A565459CED6C996C04A21FF0DA10A7F24B1DE22EEAD7FA7FD2CEEAF522A42E29395F771140573D684C94F61F19C771DF68FF8EA0FF727C55294C70E701C8E426 80: 3A0ADB5479E65BE1F00462E60C8F7F74FF5C996680A2A4CF787B5DF65BB2E82264004E396AD7EAFCF8A201E03AA950D42B9A26EF2D24FD2AD7CF57CBD08AFFAC 81: 6FFC799781B2E9F3F573651EB2DCB0771073DA1875CCC3D2B4C6C06F43161195610617007CA9A943B1F2B001E62518EBABD4542E73CA131E20A167FA6E8CAE44 82: 79C9E349F1216FCB295FFFE5771EF54A024306CED9CA111DA3DC629722DF7FA5F0927152E4401E0358BDC16D9ABFA02C709B1C21F6D86905B0CF0D6EC9FD1952 83: 6876CC513300CC83BAFCAAE5DFE4C4A0CB962079523ED475B19568243A63B208301335BDDE10CEC90CA816960013E08271F02111BD18FD03C1B941543FF4A579 84: FB5392BCB60C1329D3FBEDB4DE1131E7B89326A34F34BB099A7EBEE42B985682F52412D3F0628AA72A8C2C46BA3FEA08D5765264E48DDDBB96CB598C9C0BA93C 85: FAE655D7CC2FDB54349870B199FA54CF47BEF2AD98021FA27B968AD4C3AE477C6B2DFA9A10C75FE275D5A32C5E9FA06B03D4C908184F49FCF15ABC409106E951 86: 9B15DD192392017E2F4DDFCD30B7AE58546AB71EC44DB94EE66CA3419D580AA05B5F10E5D36D9E60465FB8F56665366824B5B6E9A63A13F6E83A026F5A8E0911 87: 1A0EC6F024130D24D9740E8037C78A176D9C5933C4073DE3C6B0536E9F7CD20E0E89705953DAC9CD44C85EA059ADC496A7A0EFC40F187DF676D2BC83F80BE983 88: 5E9683BD68FA16BE904FF617510AE99249ED3477276A0B410B269EB2E03A3505EDF653C725811AD9DCD7FCCF6F2411980784F4BE7407D68C02CF6ACD21FA1B52 89: 47CE3079037E396A5B5A1A3FFFC3C60A138AA2C6BF4FFF26D846C7E1E84E31A26270AAC5C688DA7A29DED589018BC349E3247B073B765FDBA4C8BB271CC6E233 90: 280FE2B5B0B72FEFA48A9B6A1B0A3529CAC9D6338E2083816930B14FEA5B21088B1009DE147D81FC7F29B00BADAB32B57E15322A6180D713411F559658FAC715 91: 527C2E33018CE9895C3F84BA5C072055730AAF767DC82AE236F1F7C5511FBF2CFCBE32AAEEFEADE38EED4C0895290D0EAAB38E3A5CF7B2462675D1E6B26CE814 92: 8C0E22F5BE099CEE31C816A0F5DCF9A548B0EAB55AE7CC127D172AA5243A5C73B5BD3AFD77C89370D51460CB7E84F1DD15774D1B8442C07AD21A3B128688E1E0 93: 6CF00F05A9DD7EBA5F1A755987F5678F80AAAF9B5FC44D6199100C062DB50D2DA89096389DB94A6D68BD8337640BAB60AFC8793E1A909624A4E149AECBE415C5 94: 8452FD4AAEB1AF4ACA8192DD59926E7B0D7B295B8FE18DF4DD21E7C7ABE8F4ADE7391753E533EDA2EFA13CBCD96948ACF26B658F1E72390BBCD7C1BDCE8FD650 95: C4DBE8DC875D00FFAE2AAEB3E0BF1F01529A364454D56D329FD493D327287F3E34DBDF2AD54C5BAC5E6059F5897D18157C7DC846F15F2CDA1B2F0A6EEAAE58D5 96: 6C88BBBAD961E9DD1418E9F8EC69FEB443176108F56FA2B0B686E93B0E5F505E56302994FB190787EBA7CED5EAB69DD24CEC39BD566D18ABE337A31414991735 97: 439ACC720E8CD0C4A119B9C318FBC543CB7B35FF12DA190D82A951970248BB47D0DA2171A7BF850A881E8767FBCD542039E483974F18532FDB57DF23CD18B1D3 98: D71EF6284984442D05E8B6B1AB636E0BA013A8D70029F9F1B9BA7927A582D5AC6899B9C8EB990CA93B49E460AE140564D40467A1368FB4A9EFFED4A467E174CD 99: 8B5AD2DDB4F8C044AFE2B0216B7E7D830EBDD285E4D992CA022CA2F59644806D8B7599CEC51DC73786D98B7B6F7C10C3BB7D4CEE3740FA42DB21BB51A1269611 100: 28CA7AF155E9E7E1F5EB64F211F254D624C6C42935E27A91745F2AF2EECFDCF1DBD5896F60520A527499432DD3D0F3981F0E5BA72EF113231A0319467BF5271A 101: 45B69480A77AEE3D83D39A38717EC1CAE1634D2D50D05FD78F70309DDA566DFC160FDA967EA6ADEA8BF45B74557DBCAE4D6187DE1BB82A053CF84B4217F9CCA6 102: BF46E03CEAE3211FEAED2147B3F2909D406A767005F9C8A5CE6139133D41C2812D3225123B3BF0792288E4BB5C8B5ECE9BDFE0F8FF097DD64FB2CCB964FC9862 103: 3CA25AE24E0D847D9552FD74E1D6FAAF91736603DEE98E51922A2923630D7CF35917916A1DB23A758E7F067F26A5DE9135871B3DE508CE4ECFEBCBBA1A958C78 104: 2C4380BB9F29041388A0F8292D97482E1E96429B79162A19F01918DBC2DF0B36244ED9E7D015A20290877ACC4D2FFB14D236CE7FC92ED16C7C57012B0CF6DF70 105: A0020193ADA7F57DA648C1474731F145E6A8E9E7F9550ECE1A841E2D735B18769738AEA78E7AABB8ABB51EF08A34C187478B4C5AB5BFF4932E97F4E246C60C6A 106: 60E81090C365DA5E69E2FC12256131F134F561C7A411F51F72B7649727C9D7E99795D18D1AA54D09F6B2DD7FC556512F49D582BA6006D951D474039095F3ED07 107: B213DA3FB3ABD16B1CF5CA81574D78649382A6CFEBA5A88C0B8DD40B1C6E18520F145968C342DB13A2B4B2659F4F865E8CF50BCF2138A7B09A1FC190676E1895 108: 6862BF8F73054DEF42EF38C4A362ECC8F13BE7E705573D8E9AC6B347EFE6A218950A5AB5ACAC3607C0C94301E0A085BFAE7DAD5E1863D469C113B790C234A947 109: 2D7D3040A495F8C089C67FEE236A07C7D3361D35271B4DFEA5F17C7E80B888EA339B936C4475194BBE35DD9AF3BE112201AC21C9F5858E4F4C39A0FCFF0EB31C 110: 1F995515755C98C5EB95818DAF0C55B51192BD8D752FA35EBBF51176F05ADFDC32E2FA845C1821B6110F7EC1F1D1EA963433194BB978285CA4344A5F989113EF 111: 3F5855B07A4288497533924165E7EAD3D91A16F5E832FB341F5373C118D5ED7E0EF8D837FEF594C2039F08A7870EC1C2770B7C4E7185246908976B62A416DE5B 112: 1541B5A9C84B684BBDB543F77CF384473D007992F37498F07709EE68033E41829E29109E7C77E252C241C78AF41C790E40696206D58B2FDEE768E5B321362F4E 113: 6DA9AC8390F4264064947684F53A1ADB49314E0619509298CFFEA1729A944990BE2D4C0988BD6E8BD1062D574879218ED8FC4801877D637ED3B5383C069A29D9 114: BA0A194D5078019B21910C37AFB81A890C4FECE7B1F4E722CF855A6F2F8B82E4EAD37B7B58C07ACEF1EA2B76B146811732EBE1BC0F76A146207B8213802DFB28 115: 20631BF1D6555C7BA761B0581BBCDCA5A7B1BAACA1B3D3E5B4D70D0C9B0A279BAF00DE093AB1334ED5994FC17386D0B2BE9E0FB67AC1038704891769AE530BB6 116: F31F66E176DF632694A6F7E16ED8F15CE88908EF1D1F0067CC8A5C805370B9CACE0BDC78B1CEF06630012B3A35D129C4E2AA4F7302E1A122C7E53C51DA7F795D 117: 18B5417DC4CEE4387338C63156C34BBAFF19A2BB962E4248B1A1AFF1FF145BA47D84C6C8570D072BBC57D912C8048E0ED50060CA33408A00722A65C194178387 118: 2AE09DC52D7BB9E692822A6FB3D582B805E5ECD2C1C4813F94F555BA2210429B615A2301B3EB7C491153D68AE33AD9D28F2FC11B6C61700D79BC7DDB251BD15F 119: 534390ED2DA55D45402F828D6035819C4528768DBFFAE1039CF0D18F89BEAA867589F78871FBC746E43B59E7886FDF734364DEC4193AABF56E8BEDD801E60D89 120: 231597B2B71E6BE567C86DFE31ADD7B31332BEDA930C4921C4817B7DEBB0282A12D23B076F4783EA840D890F6C571760E70E143F8565561062877D95BD0FF941 121: D60A1481686AB8F889EACF2E9F66BC32271E70E3E04B91ACA6CFB90375860E0BFC5AD9A627BA0C763CD7576811CDE2921E9A63C0F0A7A26E763F7EC7902308E7 122: BA65BE7D1EF697281736B3AFA97FF675CD776C125CB01028EC2894EC2EFB9908835A3882E5E57BD44ACA09DC3B0580145EB2265E1724DA6F01AF5F93022D5774 123: 0DEE2EBEBAA770891C14346A26834CF40212531EDDD64A21EF9FBD62F4728A16E18C673DC8CE3883156F51854A0ACC341DDEE6A0B71C4CBF797CD5327056AAD9 124: 0717C9EDCC2FAEE525A684EAAB79653DD83BF46ECB285E6B154DFCB8A0C9F8D4B28FA200A6C224B4620CB0AB5B33B9C8BE77B2B5A04DB1A3EF8A5951EC46607C 125: BADCAAE4F76006290B9090AC81B807E7251EAC041E6CB10A2C5B58C4F4B2386E065E6D55C46CD888396C86606FACC82DE2F3F88904E15D549101AC7FFBA057D3 126: 751F6366EFC97218AC2E0675E7F375444C8D82AE7A139E78305E14148E07100F5B7EF93B576DCE546A7BAFCE24FE148B248BE072031F89B6AE7BA9CC559E9C9B 127: EC0FCB3E124C482CC8D86BA2CDDE931E521F0B6F3E7F333C4388E7448A7F196D95766CEB8A49A90E46B592958BB85BD7495747E71508877975EB1454A4EBD57E 128: CDEEE6EC4D67DD8698B72C13735657EE9F78BB0E1DD37D0CF06063717DA9DCD617C5F4FF7656AA48CB3F697E36B3904F496136A2B04E19726DEF9D3406F8A84A 129: 81BB692EAF7F5176B6A0E5F2DFC01A045A917649D0B23B22C180BD78672F37F8E562FD006A00AF2D7AF0AFE15C8D191339AE28FF2797E64A3809400E2E73A785 130: 04A8456D131499586CF7B9FC45C2EC96859F3F4BB8240ECD93E439EFD5DDE1DE7B67B688B583598D7FD50CB179D318D4C05EDE04F6FA318AA1E9DD7D4E279307 131: E5C9D55B686DD9D7B1819A6144F6272B1FB5BB3B3034AB9D1BF34391283BA614D57894925C3D589A7FAC0CA1B1E98A12E9DFDDC2BCD85D1E7F2980709EF25719 132: 2C6EF2E1C179BFA8295197371C474081790A63AFAA194E459CDC27AD4453B3A8C0110F9229BBDD4BBA5D6E80F2CEA71059334A97EA34F96810A2EBFCC3B177B8 133: AAD54FE02E67080851DC84E20F7661E42ADB610D0B105B3EA6EB6654DAF64458B7E0F756392196AE2B40626CC2B0D82E47D74D3C50A607F4402C6C6A62999324 134: CF210EE9A800943EAAF4EFE15DB7DEB696233A4DD62206D46BD9C84A7EB13B5EA43FF3CE15ADD8FC4BCFF022196197D1D097B7A893A79C6640135929FCEF10F6 135: C81761EBF3235F4D56697B19F62B4F7445C8FDCE3D7999F3249493D50C19CA57C5FC84CD35CF794F58DDB6AC86E8BD53350BA9676AB63B88214162C8E11C16AF 136: 8E56EB131EFA286A92078F5A3667BC6669D6A7FD9746CA5F208EE38D5265CF27076C1624ED0F98D486C55C28A4FB89C7B667AAC505CA1CFE1E841184615B7602 137: B6CAF44F87688E9E3651C2C98E840264464DE9DFE1F3E4CE5C1BEAD46C7D9D747DFFE282D775E101591A7254112C2DFD543E44B41E72EFEE30B032E5E015150A 138: 8E7851F56585595ABD2B3EBA5AE713672093A3120798506ADD1ACAA3ADD92D737F9AE155B8A5166C0F047801A93731D4B807DFE15F08D67DEF31A7B808601D6E 139: B36B6689A5F391688DA3A0756A15AF15E6E66701E2132CF6F06326AE9C91A0BBAA35664B28BC5B936D2BF1E6653848C5DB57654685124A08C79FD03ACC0681D1 140: 24A23CE3A90C8EC3D10330EBDA47763B1B03035F9E4AAE0AD336169A2F464E067B026D94ED4B9723E969C8AAE7F404F7B4481C48EF7545EAAE4E648525A68751 141: C7ADE61F21133886EE0E0B14438F070DA398B3A5387CABF98B0802662F3BD3AAA8738D36CCC0D3EA25BBE9DD3B59062BDF4BE2740482BF6D4C21D0E0FD7B0679 142: 17EEAD5930DB3A1F8E123AD2E72C38209824F977674A52F380843442F0A5C82B55F8A362527BF5324124401648BEF5E9E26E08050B1FE80886E3856F98AC1EF8 143: 9DE4F43CA8F7E528FFF9F4EF5897652323AEB95DF80049AFBA189C3D142CFF55AE340358A71B01797A8B72F478276E6353421E1C0C22EBDEA0C044EA60865784 144: E259BE34C467B471C94B612EA6BD99A3F7EDE58E237DABA6A6656F7F7EB5466DAF908B7759027C277BD9234ECBB23C5C62DD2C9D248C1AE52865D66B5C256756 145: E49099FC970994F8293E71467BFB1D241FE99322075795FCACFDBFAB396392E37BA09E66BF492684642FF2A03F8CF92E0ACF4677C21AC1C236DDCA103F0B5A69 146: 4338E438D419D8694FC40383EB1045FD9DFEBC6F18A9A03B4914687A8639322E3B050F48E872BB7E2AD9013D374D68BDBBDD0B177024C1185320D04598515ADF 147: A36238A5C795B23F42D0833A5152770A4B0094BC19DFA72C935D32D02FAF5D136BF55D92B022D01949FF04B78507FB203302833AA7103729771A112E4FD1584F 148: 47180F9E838B129A7732A8DAD763B8CC5437BAEF77EFD34D3B33C63C09F6314B87B3A1436C6866614C3B3A693BC7926E9AE876C7BDE9D712FB5198D6417FCEF6 149: A87064FF5DA177F3651488A139E568F6C75722ECF97507316BDAC36393724525291682776843B8563A6B014646F6B19F040B17B62BEE4A0711A7B06A67DF75C3 150: F358321DC6A376ED500A2DABA60096B817D13B59AA02B56C1F51E2C6804F5D2DE2028409964D5755BFC6424287504994C7605749A5E5D9D802BB42922F444D76 151: AC4A9999133546B8452047EE31B398F623E01DCACED7BAE4CB0B4DF0DD53B8E4921109308DE53C0924E0006361BC8A480AACF798D6B403F338357E8DB676AFBA 152: 0E73ABBEB68982F163257C1145FA2E465FD6E720EEAF5E532DDD1ACCC690B37A8FAEFF8D7D41564A9C86C2F185E0FBD0FCE75259D34A5E96B8C514EC83CA1382 153: 094503A1B90D71960F83C91D76754BA6B05D670EC6A8EEE1D3CDC652DA6E52B196E155F3BCB62A9E4EF8C507F377AC1321C4C0D7A03F7D8A5286C0019C358E92 154: 12803349F15FCBD53F2FE11B67DABCF3F470B8E3AFE8A855D7A918E611A2D5F4DAE8FE847ED1FAF834BB3678C6253111636100A991A80C1EAD0D35E28DB3AC85 155: F489665F4D8A4AAA679D5E5A1B7C501DECE2E0B228630AEEAA1F5643FC4BCCB9E2F018FC2D7C44ABC4AC0861EBA8B7700A49B42486DD13263D978F8A7C9CA306 156: D9DFBC3DBF0E3D247C95E16D376E7098A92EC59A54FAB482C330139EC6E06ED514D5C74F9604D1171A127502811A16D1D3039BD03C4DBED20BB765EFD34C5F0F 157: BA56A64D01FCF392A6E2F73D791D6C5A57AB40A376E73388CECBFDB910402043B4DB2F2D2B86E3510986CF1DEC3880E3C739175D5C0AA1DCEA18959135E2CF48 158: F4B07B0A063AB240E5A64F1C494FCD9839276FD9689AA6720A94B83E579EF1044997F6506C1AD82C2CABB9384CEEA0B77D3970C1B7E13F8DE98AFA869F1F4D2A 159: CB4F232024B2D0C48E415D73193CD83C1A6BB9806CA336AC4F3B8FF7BF992B200504ED5E539CAAE68B1E47D4D8ACFD2E6B4BBC1B518689BBB5BB4311C96FE06A 160: 1E67E36D2EC5D0591C0171E7426A88919EA5A17470DA305CBA7BAEE90002E23043FAE1F4BE003EDDC2520A404E639B03880E3CCC68243C60E243A0E7A02E2CA0 161: 40E46A8F257265A1E57A09B43890FEEFA57F56BB47551BAB38BE2BA8D143C176749484ADEB2D833EC9D6B70FBE872FA53618E64CF0AED24D51BA982D29E730C8 162: F399712E5EFBA3FDF6B7D04600C16F69260179AB79545F44EF5849308E6FA589721CF7E6FE384461D05EF02BE51E50FA93C5FEEE9279A953C57EC07CFBE53E1D 163: 58DEEE13BF73ADD8B49EBBA90A8EDCE7030C17D6E6C449726D094F90A35A07759A3BEA031EEAF963C4753522EBBED1482789833D15D6EED7F5214E1AB93C174B 164: 13B2F766E6B796C44429A747CB46D99A9866115C78D2E94DAB52BBC9269B6584D26676CFECC2A9F026AE8E0162B6BB8DCB2242659EDA67CF793BF66963C69021 165: 992B995865F57633665483C7C3ACD34BD108B5DDF151CED97C0D7AD134A8D9250CA8DC17C5C2A76C1C07989228F8B474814FB116C98D25D8F291D10CE259570E 166: 1C5D5E9C29DD91877E279DB679ACF0EFD8464B0A58EC9A3036EDB2621E8106FCF2A81719FDD1B89F13FCBD20960387754DD0F12876DAA911E793DF8F1991C043 167: FE7F98A1D7839BB417CFF65A45E2DE806C74ADF2636385FEB16A34C890B524A75452EC096849EF0F905FFB38A0319D31A886DD840FE2FA66E16AC7C68B0D7FCC 168: EC67530458F01366BE95049FCFBF65465CEC9AD7D12332CF898DD72ED4D275F9C9EE96AD02603E8032F9B3B12615329CF0FEA564D278B1DC3B47EF304BF901B7 169: 77BB3F5E58AF174DED0B31627648A1C7B5B8092C829020A6FE4CFD42CB51143E9DE20E3D827FB070DEDDA94D39BD0D330604DCB190E7252B12B03F48072B7E27 170: CF33E5358E518807B70D6DCFBFB1CBAFBA7B2BDD20931B2A3B08BF8C6755367AB3BBB2FDCAE305F04812460FAD37E9AF70F1905D2F0D3E7628DD1FA453E5AE63 171: 0739D32112107994BF3E6EC3A107AE3BDB9E2BBDA1D7C10D9AD6AE32952649007F68D28BA0DDD1F1C45F7128C1D3C42EBFDB1975A143A42949C7D97D9F9D3BA1 172: A4F0B775988038E50429428C8526793AD8B6EC1F0F3AB7F6B33F716C61B7DFC49E254EAA01FFA422A31D30A8268E1BE99D385907479C7E2E0492681B6851DE1B 173: D2472E93989E1F29BE0DCF991A65BFE0E772CE77850A2F96FC6114EBCD78252DFC17712AF193FC5ECBA371B8FD27B0DAC44AFF6140923885F403904F1664AAD4 174: 6696E09A153B0077D3586705E4A19FA6B3B2DD8621F5D13D7003017A0C569B7483C8CD9218ED1A252EB160C3620FE96A00E267DA0FA8996B417F64DD4A22153B 175: 2337E38B460CDDB026CB81B59B99572D45BCA4A43949440AA5C9F2502DBD8906453FEE23AC0AE47AB77214E52E7CF06ACE73DD8565BDD315F49A460996E08DE9 176: 068CAEDFA329C1FB00BA02C80877E0E2B1CB6127FA2224BD14FAE5AD0AAE6FBAE052A145F5A8340B446F54AC9BB2108CF6582AFA0FADE91CD3568B604F68F470 177: EBD69C96F4F2DB05350B74A475CA8C1FDC671B018A47072A11A8DC082C418EB20466720AF12E113C2D507F02596CB022D2BECC4EF8486CB54260020EB6C36481 178: DB0770922005DE66FBC2B05B1F863ADA569B76DA9B8CA433C99C2F2B4AD60BD28B19A5B3820C0D8B6B2E443CF54A942B961E5EF1D53BAC4CA379964D701070D3 179: D435D7240B8C6A6AABCB026EA53BB8DE58C5DB471EDD8173AE30C81BEFA9CCDE8E30758CBD7DED822410576115C2415D9DA7FD8A83CBEAE337E5908A012AE1E7 180: 838AFEF97BBCFF7692C731D55442140D58CABFBE81BE76D41652106E215AF4E934691DC20F181C2123CF091B6D7552115F59937E165F1645CE0E14DEDB864B11 181: 771815708A3D7BBE5E00FD677E4EB76B2B9A03A09412284A236401E7FCB19B340782C81D1A49371609DDCD7E38F9448FA657533D53280B3D6B492984E9C9CBC3 182: 649EAB3244AEDAA18CF0A1FFF6619D63BBB66955C5D58E3A592E53F537FA74C60616B9E4483BCBB08AD7D1F5B6B91ED3176E89C03C224F94E5D3893FB6D01CFB 183: B4B6C653D90EDFEC3BEA0FE1FD766D5736DAFA184C360C8B036B7CC842E8C76BECFBAA7046AF087831E322FFC181073C19360A269851FF4DFFB4712E68560C3A 184: B0C0061EC50BBC67DA4765FEBD4033B8A204260177F9CFD451E97B93F19736D4B0B7478E29FBE76BE17AA6B0DFE9C4CB9C6E4734DCC8AA5EA825F101E5C9B02C 185: 54EB4D2C9B26B8B17818AD702E065407A19A711E22C8E66163E7311D8ECFA54448453890194C3EE892A599125AAFE1CB230C6EA268ED68ACD86DBBD17432352C 186: C049743F49D57D9226AFD26B94BFE9165BE5A8CEA9DCCD101F837F29C63A4201B1D4478EB5C4CE9D8F5D6E91BF89D09E6A0D918EE7A6D58CCD0A46D36963BCAB 187: F11AED8EC2B1C003B8E35F8F2A05861D9DD6B7DED02E28EFA4EDBB0BDA0DAA76EAD810CF1C78F50668D50DBE2AE65009C2E12504DFCE9F9BFA9A14969E1D0622 188: 1CEB4106BC700F76F4825E6790959CC6EC85AD93D6FBB9783098E367E5C9676AA0D6B8CF9A7DCC67565284E71205551650557D556870B421273772524463245B 189: 9711275100A787D9678CEB38981A2246112C2FB1F0EEC1F844DF1703DE5B0FAD995FAC983526E7E3336B8CDC9DCE56FD66B73811201A2DA6783309AB6B9C0546 190: 81E9DC0CBF71797104A44E72841FAF7F9CCF35C18EFEEF873450A25AE56564B0E9DA98598C527D5629EEF7F0571D9AD929BAB87A27539CE9898ABF4C57C9EBB5 191: 28F4214D1C8C5B9291F2E1F7FCE732C3290A691432A65A01F7EAB1A313B83936DC98A3B39B5F7712DDEEB8968001C93A102C7FCFB8AD7D49B29661C9A9867109 192: 78C7A025ADB85145CA8C6E417C4E68A9DB83FA78A23D0CC3DF20AD1409B936686FF756EB51BD8901157B1D031DE6848D97DC2E0F137BCA1D49EE3FB2D5A5E83F 193: E2C25FC61AFC794F65AA57DCCC4111D4B15331842493F93E9500AF01E2017CB226444E208BA9C841DF6D7ED28955B318511335F842AF3C2C0573227AFD790739 194: 50D768C744CDD318B950986E305BF74B77396FDABCAF63AB786893B5F4104C2525F2F69905955A35234BD6BD85DB17B94AE7008F2E2C368E9639ABE8BAFEE4CA 195: C4F1BF6C56C494351A880172B9CBB59BB0D1A5955352E10A868D3C33BFEA0484EDF6ADDD009A20C8D7B59B7ABD5115D595B026CCA6442921038D9BE860C44CBE 196: C782CE6A141EF9E6CAA61853588B8C75B3A39CE191C161F43D7C5F88FB77BD5055B21F37D4A49D65CCDBD0E6BFD98193FC0092A34C21D5ED0CAA5F129D462073 197: 1B2F68D7DC7563C286612B3D708AA725923FC9A2FEDCD4B1F1E2557CC70F3BF65944A2BAD9705303207B00F6DBCCE245C6E653C38EA0896DEF4150DA118A699E 198: C1248D0A6B75BEFFFD70EF17F2D0F3CE3628BCFB6A634C93E8F0ED97BBFDB48F6E5608511AD7091D7B062B795EBEDEC67696679EA092F7B84A64C99BB224D387 199: 20A3D3F3676947173C7FB824B40069A202ED3A5637DB41C97ABFE9E7036D6C009BDDD5BFFF97FE80EBC40355A535D7D3A4B2FDC09B809D3BAE2DC31803413B27 200: B85500CB777B14592A4562A26B13AF3F08CE74E03372D9622E29C1FB7988A86B8C00DDB2049C1395B43B17CD5C415A5AEDD71E05CC0980EB9520D4CAABBD6FDC 201: DB553A36A3EAABF7BE6FAF85DB96D3D0F207EA1E5B55DE589A116DB80C21AE5B1826A5FF3BB9D84C26A403A1E5C00BC7D2F6DE3F6A9661899D6D75373ED76B71 202: 5580422E6393475B7C1F5010FA7F4395B969E190AEA056ECC88783A8B5FAB8ACF130DFF39DC0175E9BA8B63B4FABA7E4A36FC55FA1504468727086B2D26B5818 203: 1CA3DD194E7BCA2591AD1B95D0CD4CF7938334C95A1EBE2C8C1A9B75E6A85F534C094E652248048923CBAB97CB1581E9A2D1AB8375C506159B724F74447A3201 204: DC525D0EC1E62EA68C013470D77B61377398EDCA82A91C1C3E4D7E5D910A9D556B3AC810FB1457BDD70A18B063523C39BD806A2227C7E057CC6B018DDABFF73E 205: 2F0B9523725B27245D2A1B635DB5A3A3800099546ABFDD95C8E86C67C378D91E4711AD1927E90CC9B50A1A7BE3D60414E487E72445936FD0FA2BBF541F1394EC 206: AB6EB21BC802EB0854F61346F7BFCFFF738EA39829AB2785976D869830DBAC367D59D50C3873B960AC5185F3DBCEABD4E4E594C5C2916A8DC304207E887473C5 207: 8E1C160A334D41F08918EC084BE12872DE79D00473D1B6ACADABD67E2A6827FB1DDDACAD9BFCF27430AA84F3F7A0D6CF2FFC91E7758F471F2739D51B60125D46 208: C135532CFE84849FE9F40799E1F2CA05568868C0D44E6832A05C29ED17C5F6D0FB844485CBAE5E50A67F2319C30526DB444F4B45CDAE01A9D0542427731DC175 209: B1FBEE68843D42FB558D1D9E0B759C168D6F84D07B2E90B646F45F1708B0D6AFF7BA8959EBB6AE4D5DF9A9951D139C81BBE602671CFDC618AA1EB63288DAD72D 210: DC11C3D993F59473F64F16F87D5F085E834306FC1C40D12CE7D6E44C59C31318C694282B0FE53B4B60E1E5DB546D930AB741A8DAAB8ED67C3D87E8E76B8C025C 211: 85BFAE07EEA80F939D52CB18C970C8ED9D4035B57391739C44D7973223C51344B9BE28C16EA29B35AF74A2F8F7581C766D61525DE5922A83A1BB600D97F7A3F2 212: 26E52AFEE0F11DD79061EA3E4F97205729E6B61E50B69CC2894CABB08CFD3A10C41662CA6F6FEC9B5B80ACACBF968C5B75BB8CFA31D06C82D9CFE97F6E1F43FD 213: 74F18E92D85D9AE79BD62C4B8FFB2116DA8157E17A6927BE2B2D0D79CA101F7CAD6A25CD623C8756D49B9CBB903477B9CAC67734F84F0915ACA9025A9D5C6DD2 214: A51B45BC09382F85334EA58CF7E7747457B517118042D53D773C66668CD6D5059B9997DB183B1C0F2900AC9949028D8F76DD8B7259149388FBF340834A3BF4FA 215: 59DC88A518FE44A7FD0F316BC8B5C865D370A8BC82533037C9872B24390F7969ECA530911463520218D00B415409AFA90A63F88EE729A252F1B747C414414091 216: 146FBF362ACCEB8DF79A761285A0653484C38585817E26A7B8906FBBEAD70031160C7B924D3BD3A9ACE28A5712ED0E6E89CE4E71493B27F87BF73BF592D80600 217: 74B6738B2F0904FD59F3A680CFBFE4E466FB5094037AA1942DB3A0017260D75AC5916E044CAC6BD0E25D176FDA267542B2C7EA201F7237E18B9D00723E98A239 218: E821A4033FAF0FEFE525115109D0B836A22C287E3B157EC302768BEF7989AACE853218E5AF7DEE9F6E234AD50ABCC8A9658A0EE4D9FE050235341C94308D7A4D 219: C3EDD652D2F831B1C783CE1B8BB8CEF9453FC71F519A4800EC2362ECDBE9EC142F768185D55E322A32AF421DC84EF84615F7F3DBE6BC6E702B4BC8625CEB5BF3 220: 6A3CA0B5A43EF42A1D6526C2F1507785248374C7D2602079A923C841F775A652724C29E788695B52387778CF2E2BBE2213B2FE212D729E3718D946238FF0E57E 221: C425148335AF813E36D072DC64C7EF6782D7DB981C5142B5D32D6D4338E06AC64363E86E88DF018968FD659DBF50A4B77BE2A02E71B243D65024B36CD71C1796 222: B796D1F5AB11389EC7EC8DD4D1D5AAF17262C8522A4AACF454B44A7ED71E20F7028169F3164AABEE4C716B38271D72D7ACA3E54B30B9E05616AC51594995F61D 223: 113A56E96ED6F8613705B5CCA6CC4F2138204D7BC0C8965162597C1FD2F6E8143F57FF1160F4B482F7430536A349D20918064AAD2BB38A9D4403C16977B9616D 224: 9590A3BD7A0613381159E1E26342C150DD9B0A937855BF78FBF625648448B540158196A2855E7FCB967F22F5AE927D60E97D0C1C17A01E8D07284FF985F54B8A 225: 74B11968CC7CD925E21037DF011F1C93B2EC34C34A3224AA281ACE7D6F1B10F2A755DD6DDF33F1A4630123BC1CF875894FBD8D8B70AC05F8C3C1076E346A45B6 226: 85A08D6993B7E5C014C3CA957D6B53EC1B8A5CEADD5060BBCC350915D3278F28E238425DA3A95AEF725A23B1BBD43E5D8832382BF76603F7E2E4FF711D540980 227: BEFB08F621281473943AF153124256386570261916E5238FAFE44A72801D7C204A974B38696C102748CD1DF65BE3EA8C45A40021C28C7E4BB143800A3F38A93F 228: AFB97494318F31A4C6813246D125217242247D4EB6CF884B244E59655DF866B2820A8E1A7123DCCDE98ECBDF1F6125EC5B95A0D9F85F05CB09537B3FCFC2CF3D 229: E8C2E1D342E6503D77328A2C1336F95939B0E8855F75CFC61D4B03F4AF2305AB57C7DB383055A51E61AFB75494C222B01967BC74B4574B8208FC337E09E57075 230: 0B396D0F15F49E60994DF4FB1E7E526A272A5B41FAB67EB8A41547CA6CE5B7F3FCE404B6A46BE79AAE37B4DF2C2EF68EAB71F39D5908760FB2124C7C83B0AAFA 231: FE86580438E8EE3459A62E73AF0E14F00F4F0FAD0447921FAEB2B77A0D8786784659B1F6D3044538300C759EBEF7066F9218F9386FF6C8099E6C71B5EC6B721B 232: C7E45B1737EBCA62C87A8F0C46F661BF7D3FC020C3B4B91988FC36C38BBC8DE05A22D4BF148F96D31115605D7B04D4CC8AB3F8738B652E933D76CD6966604CAE 233: 2C43F84381FB618512EDA0278FD382AABBA41FCF5546312DA565F4503CACB86B8A704B3B49C0C86B2207E4641F71FB5E72654B0AEE705C52ECB2E8FAF109FDF0 234: ABC4EED8635DDFFD9900F5DF8C6246CAF12D8CD9333F38647255DCC52A20B6DE8D4109957CBCC2F48F52346579E008091628FD7CAFA092F2568828F424EABF26 235: 14672F19BEEF8896F751B0BCF40FEED78A8093AA4DCB590D7AA588DDEB3170460381FDEF3CFB608D55F9E8A295A36DD64DE058C9EFF30B1D1F1A3671388B0AB8 236: DB87424F975B03F925D8B99A1DD0967D2283E408B6B0155851DCFD53C0C00B05A42CFE14B10408E0F5985809813D35D7AA7C70C1A7BC852C7F254F0303103628 237: 095D34066A6E202C896EF29F3481EFACBBFA622676F58E90FCD5A0591124E489BE3804AFA9BD3E4C92A9653EBE878A88B275BF9B5C8EF8EA0F01C89CF40E5FE0 238: BB5BC80C718B85BB3C3DCE95D186711D5B90827B2097DE63C647E5B6C14B4766BF8EE8ED395103030F72ADF0C8992AE836086571908DB4A6258616EDB4BDA878 239: 9A18D6DD0F97B7407DB0F17896DB2A2751B76C69B6F91E821A0DD717DFDEF630EEC1427C2D190C095DDB07601DC0EC8687B7411D735A9A6EF0EEB84A60948BAC 240: 60A614BC40A7DE580B6ADD05279A68DDCAE79EC3DDDD2C6FFF7B77BE9DD0260DA5241660982B77BA9C4B904075F39612F514BC86DF6F68E189FAE2C84A32CCE7 241: 5CFCD44DECBE3D74708C620C70DA807C5AD58072F7558D950F519691FC96F98B760B02897C3A85F68EE37B2735931660106670C4DC7FA98EE2E18B6DED532A9F 242: AFBE6D9871AFFE6D201E2E61435703856424301ADD5152DC745D96D1BAA3ADD4C78F2D7C5057F1AE8B21FB91879562050C84144A2042AB2CD273025FA03839F5 243: CE9C1B19D0E0FFD3085D28C5B2176A741A3034C1B76C54740AAC3470C1C8C6E77BA765AC4D6D90D4DAB0A89AFB17A8863A2917674F5A189A5CBF721C14F5D637 244: F2F065927839C22DF56960845E27868BA8F272A464619EFFD9AEBAF1E40A72DDA81CFC67DEE13C351736C407F59DAE8EE6F2BDA17521CF66F10C73566B7DA891 245: 24CD3AFA2218863437C5518021D1B96E0A80EBD14EBF2FA161A5E7032FD985BF71EA59DC5E35DEDE5EEE3098EAF6A16698F5BD5903C4ED218868D1E96E4B8096 246: 1C6AC311730640FE427C1F23B60E817C25E1318109643A8AB51DA74995FFC3F156F098AEF97F37CD9746002DAD22FBED1A1F222511B92AB5F39DA9B53BD62AF2 247: 37609371EB63AEF0CA6EACED8388D187203A88C379F24970434D87950C9B7DF9A68B618E9E83E3EB10376504F8FEE2505830EFE3FFBD23EFBE081325AA171482 248: F0C06F6A2C7AC3F0EE428D7D1BA893E73D4D2F417999043BEFBB3CED51F95F7EA3CA882B9E8C1C973DD8A7F450CD60BB5A0B30D44A574E43E71D2533EFAEC6B5 249: 3A9D1BD43CB3B7D3E9364F05987DF4CD99D573C036BF1337988751658EAF2896244DF5E4DD8984DD494709E587A75EA8AFF93681787AD738A95C5E98616115F6 250: D42E2D57B36095F0CFE8F771A9B198C7B7E0433763341D35033F32D21C638CD948D8DBE75F533391347C440F208D17F20614309DBF1091DCA10801E16F5D03B5 251: FBB964B7865A889433E99C4B61D3CD069DEB99E44673068771030EB1B8F1FD3B3ECAED1DCE8ADFA44F9A625472CD4D987EC7ED7FDA0DA912C8AFF5B20BED7F04 252: 13F67CAD96C3304FF3C2E45D71A2D69301695516EA384F6001850A46A7F93CB74C5A4CBC1C56544166ABB6C9BBF90B9559320F5F75ABBBDE34C7B8B45C783BC1 253: 78A609196BB40EEEBEBC04A8794C840A6F831680864D65FAAB093A499A3CF152EAC96865747ACA28392E9F102962C49247E0EDA424A345C4AC6F4B60CC3D2597 254: F199515CF806EA25237EB93D658BEDC994E61EF70F5665CC2F230E7A40EADA14BFA00D56C1249F2E5C8920977A6C85017F8663BE9422762CF88487B76EE7EF9B 255: E8702ADD4B9034BCA0590FF897C10022C56D08FC4EEE0A43BA85E9E9C2086616B1BE7B6F928A3C53755506ED2D9D62DF5BA4A1862FBCDBA20683931A2244AFBE 256: 6E6A3CDE12F2CB3A42EC8A5D21B435C4DA4DF6CA7E41537D361D8169158287BF1D2241581DE07F88FE92F5AE4E96EB9C489FC3B258EA3842EA2D511CE883883E HMAC-rmd128 0: E9BF401EB338AE9ECE9F2DE9CC104A5C 1: 9536B19B029E60F979B3A6B3052685BE 2: B52F90B48846959EF56051CB6ED21588 3: 0811D2108413D9B64ADFA78B05EDF1C8 4: E06414189CCE13B61A2FC3CE9BC11938 5: 8BA02647A4914BF4248F6C799055ABA8 6: A3D5D44CBE30E23D20643E865F28B7CF 7: 459DC8A812BBB840CA10A49E10F240E8 8: 26131CE4DEA7D66E5B3E6ECB1DDA4329 9: 5EB41B6A8F140E49BB4EBCB76EFAA0A4 10: C5E076890071C872B071E2D068EAD1E3 11: 476474365DEBAFE39DE7830A0BC3ADCE 12: 3E9E0D4B41D740310572562E5F7F0CFF 13: 9BA99B782F7B79C9C19D40EB27033941 14: 8E9931A75435B113C7E17E94E22D0B7C 15: 1977BEFFFBF378633AD22D9E489FFB90 16: 9CA06536713225F3A5F67CB6510FB165 17: F46F54B012982621E33BA13A871F82F8 18: 73F925BD50E603A66B17D8D926CAD1FF 19: AC74EC692DDBEF86570044E1B5F31EF2 20: 4F4F95BC7487A8F07B23C11F700F9C4A 21: 02CE78131B27AB77474CFAE5EEA37055 22: 1D66BAD41487BA6C238BDAFC04E9963F 23: 79058EE7D70C9D19058BE2E1D5383F39 24: 773EB9C677055286C84B39D2344C43FE 25: 414A4816C124BB62DBA3BF65B6276208 26: 350DE5DF46801BAF8B12D4516E82EF43 27: F31C58CD73A3D8AC050BFFA5FDB6200C 28: 5D7489AAD6537DB3DC27D43F698F6E79 29: EEF7FC37DCF2AB96328E62B8097203B6 30: 8FD428368B9B52F25C47E74C0327DA52 31: 923B6ECABD0337E39E6D068CC98F71A8 32: ECF2239FC767105FC69F46FDA5BA37CB 33: EAEEFEDEC3B1E74A029683FC21F03B40 34: 9620C4913123F3A718D61C956673FB23 35: 59283EDEA3804ECD6471EA41EAF89A8E 36: FB5B60685DC1DAF0C6557325DBBB32C4 37: DB71D12AA3B97C421FCBE45F8232F3E7 38: B0849EE5F1F9484514F5512BD928148C 39: C73A777E20CC49AD33DBCBB16DC59A84 40: 600BF6FB779EA2F7108D1F7B8FE89F45 41: 0BD76F07D4C433E5BB9FC98B7FE49A2C 42: 209E2124DAAAB3B5C6D2DD9A79A36E4F 43: 907E4E2540A6794D6526A44FA08CAAC3 44: BA1BCEBA60F32ABD0EED0A1A56748248 45: 31F8527CCDD022CB9439F8B39ED70D11 46: 05F429D6AA9FBB1723D81AB268F95963 47: 7B91D5409357FF13F9B92ED2C6D63B66 48: 30AA88DDC6D49AEF0D4058616EEFD9D9 49: 16C0B4F46936AD501EEB5BEC8C699EB3 50: 782DDC3AA9B3E498767AA310D7C32CDB 51: FABED92C454544588965E4CBBBDCDAC5 52: 7B04EC847F160BE26FB4A7C6B111EF91 53: C20AC6220BD352F8D53F0DEDBCA97862 54: 2EB8A89C854AD2412E5E2DB8638550C1 55: 390DC3D1C6EA4CD7A381BDD9F0B505A5 56: 1D86B9AAE5246182EF76456E9A8F2CC3 57: 1759BE8033CD082D771127CC81435696 58: 4F230D4174BBB11231ABD4AB58D6FB80 59: 9FA21699DE8CDE39FE4C9DF25271A87C 60: 7658883C002D62D33EA21AC43E26C355 61: ED1CD4C63C40453677804FD66BE3E068 62: D715E8E09CF4C5A34793FCFF0A7EF0F9 63: 86C450794C4F920138A8CF2DD9221826 64: 2AE1A808F63CF7AFF39FE9595BE540EC 65: C8E550F520B0662100FF767FC0FC38E4 66: 1A4CA5249BA8BF8E4AF50BD01B89C13C 67: 25A3566CEE5E0921857048F4A54BF745 68: 4D76448CE2C08EBCF6C21FD304973DB1 69: 83BBC6D82633974D76A1B0994DD8891E 70: 9F322885EB927B8C4F93AAC081C7F378 71: 7E0DFB22C9433A0A66A673ABB3E81B4A 72: FD3DE62829CCF2AC389581D9932E1B94 73: CADF66BDE69903E9E3117DFE75EB1C6C 74: 71DD9BF191A5A1A0311BA19BF0568727 75: EEC05781AEED255A8DA730399ABE8929 76: 07E7E6E57A239F659A6B17B695161878 77: 6E7DC67642EB72C295EC12C009902577 78: F6AD3BF571AEC27B2C99AAD4A22B9654 79: 0F38A5596BC9BFA1ABB7318A35E5841A 80: 987BA29276694A84DF6F3448D2FA36B1 81: 3661D8F157DCBA761D1292FC2FB332C5 82: 81834820599DE6624EC116A651FFA2A4 83: 59E556C023829D31F76ECB5D2D5050FC 84: 9389597634228E243808C1CCCC71627D 85: FFD30A17850DB17BBDE7C3EBC8482A95 86: 0297895965B8C96F95A77E6A1BEB5FA5 87: 46185FBA371A282AD8251A8DA93E7A10 88: 34940377228A73C2CDA178635B8A4827 89: 0737C31BEFDE68780EB3A5504F295809 90: 3DEE2B38EAF96BC620785551C926E9AF 91: 719B32410E625DC65AB4E422E24C8663 92: 5B9AEA802EFFE00D19E746E0684993CC 93: EE96F9B8F8FFC084C0EF8C28ED0EEC4C 94: C6575E5F4CDEE50C0C2F41ECC33BC9E0 95: 000DCE0FA82C1422ABF37EF1971B4B1F 96: 83D1C6EBEF52D1B9DFA3F439BF8DCE25 97: 657AFE5CA6D54F9083F02C257CE7E3DB 98: 9E65239503BEAB92716D5B504358352A 99: D8375320E32FAE3BBABD4620B1231315 100: CC8914472A9B5862287D695AD0A88BE6 101: B0E0D8EDA1BDBEBCD0A78678AD7D6A64 102: C8EBE9364129E651BD4FB491FE035433 103: 2A6DF032E0D615DB3BE890B0B6D3349D 104: 975F0E184517902F1C239684EBC06314 105: 5A86E403AD3D0B9EE5CF87C32482C6FA 106: D3E986B5231A204C88D7C2FD1ECA40C5 107: 891ABD274D024F8B04143DE588A02AC7 108: EA619405003DD17F13ED5BFB29587568 109: EF5CD5EF1164A2E5BBC2D96360E55B87 110: 07C74397955571A7E4025BB9EC555846 111: B5F20FB0AC1C1DAA0DEF8EF78A9BDDB5 112: 88D91C18A4AD272B4C1E2C76BE217BFA 113: AC548888F0E5E559777568ECE71E2007 114: 816071E2B807CE6EF526E423BBA252D5 115: 0585A675BADFDD749ECADE66BFFD0546 116: 964CA97939664EE55B8B973D044D7695 117: BB8FAACCE9D3238714C3934E6FEE2386 118: 2BB26CD61B24CB5CB9E2C5FF40C51A00 119: F5332DEBA64EB35CE3B5C7134C4C8495 120: ADE7A5C99757D216D10E1F13E3A91F1F 121: AE98C3C4FD874CE0B8501FE4C428282A 122: 04D7625B67AC3F9D117AA45FEF6C6AC1 123: A05D3C933DC8C8A1CF48290A5D52644E 124: 078F882264317B0C00383FBA7E079301 125: 44023F3B109763A53FDEFF1822488855 126: CA535702BAAB858D5FB5B79895E0E1E0 127: FE1C2C02B7665895DBD2F4D2C22A7232 128: 75A182DB4FD99599022F5A03F1427289 HMAC-rmd160 0: 33528FDB4FD0640B4C4363CEF1DE795719EBC7EE 1: 514DF566C6204373EEE6020054AE7DDE2B0934DB 2: CC8A5C8D2EBA02BF4474A4CC05CC2D863F1AA392 3: 27D731E218C369A32BE4B2BB29D2F1A0988BA583 4: 091245BFADF5C6635298702F233ECB3265E85460 5: BD2C07FA2197201DCA309063881F2EAC9D925A21 6: 480886856354E6FF34B3AFAF9E63FB794BAC4521 7: 258D58532BEB5EAD28E9BCA52AA4C0444CC2467A 8: DB7513F824B42A9E1FFC1369F22F61054A3EB7F0 9: 3A4A258F23675EE02E1AC1F72197D1A11F32DE21 10: 9315ACAAAA8DC91A9AAF8DDD4CD000AE04F70E1D 11: 57D60D77E1D78D23D3F184740D9DE392FC6C3C40 12: 950395C815A3D1A4A8BB25322333FECA15445BFB 13: F8201A01C30F3B569B7497B5191AE16D1705085D 14: 08DEA1A0CD4BD6C9031C84FD2005F15810FF088B 15: CF41D88EB3921FA137F0203C2CB8BC5200FDE7BE 16: A07100AAACF5253501A6643452D07C7DE2EA824E 17: 19DE22082D1F4535A733F16262A135358D651737 18: D50BD92902AE0127AC8DD85E9A81ADB7EF3F1E64 19: 3FA34A3C02E06DE451794AB87C4FCE6877458CDA 20: 5928329E4D830E8B2F7608A4ED46DCCFD5798425 21: 2825DBD7989A8978904A654E6AF125608B0BEBC1 22: 9C812424417D47ED7C78C7A049D4E6CB906DCF3C 23: 9518A473A902DB6BB56F7A767ABA13C8DF306D37 24: 439C444C7AB4395C4DBA32E4F8CF4F76207E5BB4 25: 9021FCB087269457ABAA8105D4DAD8DF8904A2F6 26: 8B7B686199BC73A175940686BD57F45B2329D895 27: 0F50FB7AA9425975BFBB6AD65CF96284F768BB75 28: BAA1B7749A9CCAD7105E9ADEE499058A7BE4BA70 29: FBD3413CE89DFFE2F0A869036F5C4265D5B14743 30: 7CDB257E051ED0EFB761A5A044ECE5B0C1F12033 31: BB1E5D495074594534AD523987D8438CF1632425 32: CE6D7BEAD1496190F0F0E99B0B0C9BECFB7D9173 33: F8BE617A3256EB1C4BFC04CD386EB7FA46603926 34: D1A1F489434C458344239A75DA4241A3A94BEBA2 35: BEDD951DC98BD5C4138C1F8531D8288BA3C51B87 36: 9C2357E832CE87A227F6919B50A0A9D3A29B7CAF 37: C9FCBB9A1AC48B71B2AA20AC992821531F1141EF 38: 0B58D56923F9620BCD072703FBA71EC2172EEAD2 39: D97480E09FA6473AF9AAFA14FA9589AF65E62328 40: 4D5C56D0EB0BAD64FD0B0FB7F87D05EB551951CE 41: B7EC2D13EDD3603D1BBC8CD29F32B43AEAF6EB4E 42: 9BD5300B02C9432F686842E7900F3D2A085C5008 43: 7E8787C8780C64009216324802958E1D845332FB 44: 1A3BC1AE95380D609571B01D8C3458B2566B74A5 45: 9672BD12EBBB12F398CEFA089BD3282A2D2892FB 46: D5D3CAD705E2B0B6E0CBFBB0E8C22CD8EB1DC4C5 47: 408D84FE0B28A3B3CF16F60D6207A94B36219F81 48: 0B7E3D35C292D295797E3ED1F3D8BD5FD92A71BF 49: 18AC1EA3406D69CD9E9C801F471AEA3A31C69D51 50: 98E40CE293ABE4ACFADE7D81371FA92AFA69248C 51: D95E38F2D0C5ADB478A9BFF9F8E7B10064455C31 52: 6246C69FF502D453950BFEB5DBEF68CE76D70F12 53: 9D788F02EEE675F47AB4498B1337C6D83A37F64A 54: 139387D749674D0E84F3C2BFBAFB3F0CDC4CA273 55: 09406CEDC1C37D275EBFE02CC707229244086CA2 56: BACA138E6EB6E5BEF150083CE0EFC64FB163EBF4 57: 87CF4CC4500A691934C2C6607F3296A0BEC980F6 58: F8E4DB4FE6879870E9F47BA29F0DA843342953CE 59: 52DDF305014F1C68A34ED514B10FAE3B1B91F383 60: 0D568164C300BB14A4571A73493C02E4165383E4 61: E1DD806961D718F8C085CEA11A140900FE8064A4 62: 6470CBC7FE079B684D108550698B7C5D265736D4 63: DAF83273B2F16DCC69FD55DC84835931E75FF5D8 64: 47F4D7724BF49DE885D23D84D582EA3A00E1C2DE 65: DBD6BD40F804E38963EBD2E81CE5196F6E69AC48 66: BD96E9391148957BE64FE6DA89CBDFF45233FBCE 67: 20975680C2E31D61D7F303215A25CFAB4479F646 68: FFC321ED45ECC1A9FCDBC28ABAE0DA1FD27A628A 69: 99F90008F139FA442C152706E522CEB349EABB00 70: 288C57DAD9D1174F4EBA92F7815B93C0916E8157 71: 8380FD083E742776CC32971B9E088B894A6A0071 72: B0F44C66552ECE94502597B6B100CC64561E6F1F 73: AA0465458FA1F285F5A4530035F84F844D545A75 74: C90EE3BAC92FA4986C850DED11D728A78BE85543 75: 3E525BBEB158B246A3F4918B6D634CE8EBE4503A 76: 7B42675AAE1D0DA5A84623E47C618744249384E5 77: F50AC31B43BC93D1BE2A4D9C40FC4D3593F2551C 78: A31AE398E0D6668A52DAFE37D019F7571E0F681B 79: BF10B29B4DC7C848C5192631E59E0EED32B8D81C 80: 77B214EB3617C372C191D1D284FCED04F5AE17BF 81: 1B17DC33F5966621F4BFA93961B1A8FFEE1AC820 82: 5A07D9861EDA6D8698E12FE5250CCAD882628B44 83: 176F46FF2202307828D7F62D39330444D688FDAD 84: 59E94CFA3AC2BE8DC6098840E888306764308DE2 85: 679F243847C647FCC3F4589CF87972558350DC98 86: DB97F5EF492C7380472E16E3B055567DAB630153 87: 359CF9515F6B2192BF0E85EDBBC81D51232210B7 88: 30B59B3CBFFC08DA7D9514AE7627460BBBDED722 89: F31D5E2866D9726051B6E5AC9B846DB36EB705FD 90: 860A58DDB6119261646907E251D60760099CAA07 91: 22EA0278EA053175C2F12BA4ED172FB0B518F3BA 92: EC68297334F421AB3F2EF3518684E8E1B548BF56 93: 5C1405CC33D9025DA265FF4F25942853721489E2 94: 8AEA8E9EAFBF3BA597B65BBCCEE59013C8E6AC8B 95: ABF7CCD01374D5DDAD6EFFB19412EE772E663DE2 96: F7F28E05FAB93A3D089BBFF56D4E462F0BEDA41A 97: B6C4199D504E72793EEB49611E28A82DF5CD7905 98: 0B0916C89F1D9F1134E9106FEBAF4169DC49F752 99: 4F18AA0E88A01ED162D08F35300B1C3FCE1FE8B8 100: 5D4F3C473D5859C16F70C1566F9800B3DBBBC643 101: 02C1A5F34232B8900E6C7DF2BED957BCAE529784 102: CDD46E434331D7869A27EA096CAEBF586D93CC2E 103: 492C04E69F0204F150B63022C7DBD28116458F97 104: CDDAB90168E934E69E942B1F1EC0D0AD7BFB5B43 105: F433642FA8091FB2517F3357DD30308B4A2AEF53 106: 537B2118792B6A419C438E58CBB6C5BA887AE257 107: 753728CB39813C27498033A07DEC03D1FA720FE9 108: 119A6C5BF3EA8F7A78DA9ED2DE7ED9AE3942964A 109: A501EB611542A2A2CCC68AE754D2EAC17942BD8D 110: 158FB54E37C7DF54B29928B5DFA53A560DC09A5A 111: 15F5380252E23B5C37EE7E8D1F5963FBF8788577 112: 735F2C3CF7680C63F33AE2D4F3569FA8EB45EB93 113: 67AFC501C6582DF2A9DBD713F206041E5F3E1DEB 114: 7CAEFEC1C6E8232BCB90E3FE3523EE06496F36A3 115: CC90ADFCF3F9AE777B30EAA6206A34EF54F74C02 116: 974E0E85B47CCB870A511810DDEFE81CB85B28D3 117: 516D6BA01E0186CB7D796FCD9DD169C45B63A93E 118: A1CE534BDD6591AF4EBF61ED75636C7BFF670658 119: 1E4B241D6EADD77E046BDCCD25F70AAC969262D3 120: 7F2F1B4B77C3170A9E015DF4E8C6EDFE736DFFC3 121: 89A3BF181EF195464DBEF9576873CA2DF7D16268 122: E1F96A7C9115E3DBF28E10D62F2D6EC89415B6D7 123: D75C1081B3C2720D030EC5DE13093357A0EE6E51 124: C11603CDAD8DF271093CACDFB5AA4E113A270EA5 125: 39A9E659DFFDC2ABC88ADA2B6A7445090C7EFBF7 126: 4132330C5E3344818AF5C054AD55309FF7B767A2 127: B107A8B0C7B68581969A0F6DB95DB2F790098F1D 128: AD090CC9A6B381C0B3D87035274FBC056012A4E6 HMAC-whirlpool 0: 5C36BE24B458FD3713761955F28353E433B1B818C8EF90F5B7582E249ED0F8C7C518ECF713410885E3FA2B1987B5DEE0FBAC210A007DA0FE995717F8FEA98995 1: 30C66EA7CE95764F4CFCFBBE4C166E80A1F23E8C88D2DB7FAC118BCA9EE28299778610D94CD545C18C114A2A144F9E933CD80238E9F1AC737F7149BA232FB846 2: A61FAC4DAAADF3DB746DCDC24CACDD8C2B74429CA812D86091B5E7F8186753B34532047B3263D2E231074CCDFB18188747B657E0B685693901CBBEC524949244 3: AC3BBA8D998C234F9BCE9A96643E8EFC342F4772DF5606A812C1C6CFD644E8F2B8F9BD724CBC8D769B74C52669705BD3AD390CA61DBC7EBE4438726A91FB2455 4: 59AD4171B4C33E09312A01B97B3BC2B7DA43F8791561E32A9186C9B0C418BBC31DF54D6A9ACA00910C0F3DF5D7C2DD7CF5634B76506646B7D4EE5C60AA7C7950 5: EDFD9FB5B7BCB39811D87A890171096AD2237B78862C4921191F8B0B137DE5178BE8DA898B6A895FA6C4F401714D2AAC743F512F8989E39081F02A2A0F9F6137 6: 6BBE26824C7582213F89F773C520710AE400F01B99BCE126C5F3ABDE79C8B304139352427A3E25A313A5F753A94B55F1EE9D3A0300E8E987E98004F58707F73F 7: EB89DDACA2BA68940C4616B3B1BDFC25D94A78B8C3A533F1231A259BAF6A6706E1B90CBC2F21A76210C0322C7E4286E393B167A2455DB24C6B52B0CEF3EB78A5 8: E8AF385440589959D67746FCD40E295026E942E44259169780B3954D20CBFE2586D2A8BBE408AC2D707B0FE539DB43B3E9B29A8D26D09A41FA6F191999A45186 9: F6B9CF6E0A337906517DB09EFA31E91D57D6B908ED5116C13B49B8F1F3C3A872EF42DED53F939CC4EA4122FD8580D528AD2DA72BE063251CC89FB52741E2AEB2 10: 274FEF3E5EF7AD7AFB1161A29492F0DF44BA9E1C30E1E88CD708A5D27F2B35C45085A200E9F42F340B0D9B3A1A354B1F5F6D0D1A754D51DFC39CB2EE213112DF 11: E2EF7A0A64A3F384F95823201823BC95060707F273E395F46F3C0627E1CD2BCE97DB2984C0EE7A11B22E617F0CF64A3F44BE9FD6B38C3A07A504DDC1D33C73B4 12: 681D72B9BCA446200BA7578E038A8FC418225BE5F02D8DA3CF085182628B7BE587DCAD4851863CE1CE8653E4916047F8E92E91A6B0D7FFB065F316DA93C4F44A 13: 2CC82F237ECC1B9B0B9FB76E6B9651C56AE57CAA072A0C20B968F2A74FCA6A9749FA264331F4F2612AE0DF32810B0CAE95E5861473F4675766459B7380F7B9A7 14: 1F3818CFB04AA3882442FDF1F5CB0DB2FA9604228D3CCA1F14DA16B35D9B2071B372996A176AF0592F00175EEA4C16A6E0162DE62DE30E8A80FA669FAE9A33CD 15: BFE4BF868A8AFED289DED5F6E7B21E6856107EBEFAEAB5CD644FB5634181D52D8DEAA203C468ABD279E9BE73507A690C0B715869F6E722C4512E815FA4EF641C 16: CCBA3834AC7BF06B16675376ECCD96A0F91E3E3C588C5BEE1711A00C107B35D603B20DA8E5CC5FBA6937A24DA53D8F55C907F3E53F0F255E080396426E7ADF9B 17: B09F6898640E5CF77B6DD3D5A8A4452F4F1D25C90F7AA55A205EFF2C319EC0BE245CEB4190F11D85C2F7234BEB899BDA465C95A1C59568987C4C020B9A7AFC00 18: AA7FEEC56E16AD79990B003AD51626C87C9CCB90EBFD748DC268C0C8C1DEE1BDCA1C8064FE7570A5C624AA0CB6BEC163E63680377A16AD49D1AE166090DC0D80 19: F755304A4694DBBEB0E59B978943F3D4E429F8123B3D6CE27AB400D3C4BD81A13A8C3C0BA0FA7E5F13BCB0B48290933A05DCB49A5907C074039427F0EC9004FC 20: CB8B5804EF0478645400B1655DC6E194C8DC26112EF76C57823A02F39C8ADB42F1225B130FF0D40F580DA8CA95D82C0441E3A82C206D9D8D6DBD63B4BB1BCCE2 21: 4EEA4AF294C458BDBA7F49AC0826BC295BAF5B16D16F40D379F6B7C3456EF4145B5EC7F7CFB85638F641CF4D07FE3904DA891E68288FC11C0C72F54430915024 22: EC52FC8CC0F849E633E3F7339031DCBCEAB69B6634D3E54E7C153CC63DF7D3D3F93B13C8E751E79290ED4845FAA3D5A79A7DE6B100F538E0FFF470A51CD630E4 23: D44419C0A36FBFD0FB441B596E8821D3F543D80FC7EB5A3389037BE0139921027571502B5C53BA30D31D4A053E830E610A394842229E08485A2376CB9766313D 24: 3F4BDBC8A4C86B3F646CC445E2CD54B4C786BAEDEE9FD91A879640B4085D46FEBEECECC95E819ECF6AA9085C2309E79DE1A988C6B68930ABCB9BBAB90F1C2F85 25: E5EBC015269E0E61BBD1717618C15D44953AB6F854D962A04FE88865626DCDDEC5F094AAEDCB708D947A9547A985F0B287CA0FBBE3FF2ECCC4C0C4FEE4FE74CB 26: 010C622DF84E677805108A2C5FB1E8BF5922D35CFAC2408F2AE174D353AF169A40169709C39BFE90E51B095C8C0D2886B4F10B37BEFF805D384E29CECE89C4C8 27: 3E9C7BE96E03C48DEA773204E1EC3721EE817ED2403E3C8F950A4C447949438037E2AF0A030CDB983D3FBE5B82226F510FD91CF8830F59212F8CF26C2B5E4DFE 28: 8797C9C14CD2DE3CB1D29808DA9F23A5502A7BA579586DE9513B980FC06990DE0E29837ED06E24B15DD0000697666B8D3DDC556D818E87F84D125697D5E2F8FE 29: 93DFA3DEB3258FC7C4F5362D36C2AE21AC0471AF8B895B5AD1C407E8D50DDCD0111AF76EC500D7BE035E6F9CE932190712A3F52FBA4BB0DFCE74400C82D1BD8F 30: 5587EF7A31353C0E9C346C837EA645770BC5F5C541B72886844B4B0789FF1D95134F558B29385B35960AFDFEA7E3AA40562C12683CB7DD9A410873565CA10880 31: 052CB0FAABB263A49516E39525023E2A02DCDB2D5FC78948E042E59F89363FAAF1869D42EC9D7AFB0DADB7D4E99544BEDA92E3270544900A5641F059571B6238 32: 2FAEBF049CC4C9C2770E859739B1774EB6E6AC2EAF1AF7D3EB55774C03ADC4C865A65C82E795959CBC4BF00A64AFD2AE0CCA16D58AEB874E253FB9FB9A266790 33: 82FBFD2A46F2102AC27089B6889024FA9172FA691C1E3BA9B44A394D52EBF5A7A8BB2321708ED9AF2776D8BAEA13A5F2E9EA4AAF420A24B6F59E2F583D54A797 34: B306D18161C766DBDC734FCEB08D14248EBCC63FCBB5B9CC0AE9D690E20E7152D771B3D623D7ECA1CBD305A31EE10C220FCDDC2CE76B578E2F15DE4741E9C9AE 35: F527D57F0A5F13D7FC6A30A84BF414712044B56FB8F6C1E1375A09783968A851DBD495D51C693590E7A8BB570A7F1C0C9ADAADB74EF8EC71A0093D8D1A4285EE 36: 0D9F9DB43A0FB4BDF70487002943A6CD3BF200518500B6934BA518B3B0958095930EF59BAC48C84C1E1ADB815A6569FBBE7E61F039BFD8C2F727EF4636542A5D 37: 614CFB257400128FBBB7B56550E86198155A5647FC11111FB4D36073BB57AE4D9C0A54BCF0DCDB8B54ADE4FF8AE5645821CF9C83F7FA9468FC2CCB552E30BEDF 38: 7032724503FA5B0765D610D3FA4609F4537F6EAB75D7CC4E2A15D2B1421293D9411C9E8F38999F7D64D607EFE95224331E47FAD4F9BDB6AC19CD3ADE47C17E7D 39: A8E4316126475B429E72432073CBF26E94DA450DB553D46667D597F0AACB99325C9EDDB94F8CE33551857827AF3935F2DFFE1EE69A20884D58E095390C04B925 40: E7E90B19E76017EE80E4979FE56A488AAEEA011DE9DC068DBE53AF06ED44DA4CA3BF662358F191FE2842B083BC5DF2D4183668F4E7FA9E2750869DECA7302202 41: 818D734A02A0AE76A0012D7BFE983B17CACE37D4890214C7C53A81CA9F42EF0A472101D609BE5D3DF4F0A55DAF154C20A1A97D53112E22D136C03004FE09149C 42: 0B9F5B2D4BC3DF781F55ECEE149470F3BF68FC51D121D021DF0CB8D4A5EDA42EA6840DD735ADF8DED72B325662BCEECC6195AE831D169A891F6663F8D7C6E0D3 43: 7A5AE42C635B250598C536E531FDAA1746DE2EC7984DC1BE488DE4766D0CD544AB51AB1E62A8A170D120999A61CC6920DB96935F295817851A4CE285D2755112 44: 95093085CFE52D746C54DDF8D2FBE33EC00D71C39BE0865B896C331C7E5682FBC0DD84ED15B3F790166D537A9A68EEE5FEEC63FC761EB854018CEB68245CCB90 45: 8BA177C495E9832CA8EB55E67E5D7F34C59C4C59D56D50BF6982B36AC341CBFDFBF5A98BBEBC26A9509FBDFB239312DF3B3D5BCE70386EF0E593E17A621F41F5 46: 6DD39D94235D012C89FD030341392AE42BE7702C4D8E725C4229940BC273EBB8EDA7A6893B4FF86D1EF84DFA119058BC6C8CA47675492A0D37C859E6D9BD5471 47: 13A2FBE3DBAEFCAC5AB8BBAF91BAFDEF5FE38B7F2EBA8BFF0F44B4BBB236613B8BB122BECAD9852BF7638E48F0FC656F9C432D9A66C1188DF3FD1D2A88161139 48: 33B9B7EF63B302C1C79E0A43D77487C55D38C53F29C800B4CC287A99A440435121C7ED78BE7406349E65AAF991EA0EF19D06C1AFBB814FE4E0BD68613AF0C760 49: 720E1005ACE28903D9C2B6EDE02A52F89860788AFB35208B4B7C147E43BAB3D06445DA138606F334624C606DFF288B0C70B487679685D1DDD26F1DA0A5F6839F 50: 2A742F1E8CE6CDB501E8AD9BD256786A42E7F1888D9803AA8D5750817B3EA101331D7266298962FA28AF2232BF956FAC7C1C0B1C3DE4C5B3FDDF8E63BEB02185 51: 05CF6361A4A238091A1FD011336F7F53B9ACF78BA1B96997EE49B99FE36F0F1163E04B446EEFC117B377593EE078B85BB9588918C76612E2A6F9515E0CA244B2 52: F510C877546FD2D022051364A09F2051523F8E7FDCD3E9D2AC5158205FB36CF25A9E0FC394ED2FACA7CB4F0639B33B706FD4D072D62F6EB229E4D7879DFB45CD 53: 2664476D94776DB52BAAF3B2DE05A36D3E35EF44ABB6F09670F37EEE00C2C54B38F70D06359B20F7E40E22B42901863864EF89EA473A1F3C834D22176E87E617 54: 62620CBDA92EC8241DD3A6A0EFB28254B0CEBF3E2351B10CF93029244A6A3D1DCE10D9A895EB6E8A33108DDBAA897DFF2703757DA3706209A7871F4274901E3F 55: 51282A90B63998F7AE7ADE4787D957992A81D3009D6AC5BF824DD1507B53F6918E9AB6AA1F36373D5E5D3EF8D01AF9D05FBC224781C62C1DCB4A2089BFF5496F 56: FE1C4394AE26E4B85752045DB14E0AD378726BC1C985C8805222B614C62721E40B2A0D21983FF40AACE8E5F9CD57BA62C37C8F0968EE12FAE14267D6AE906A7A 57: E570E1183CC6AD7A2C73D7D0E96D3AE0605039603B6F6467FA5CA62E4C1424BC14B17E9614F0ACACCAFC2B1B39D8C081B05DFE2B9796F32C0C742FB09DC7B8DD 58: E690D667A94344E267A6EA7F3F7A6A5385C961BB6139800CD5257BFD6C4A672DB576B52335D22160A372987D652741EC3AA9439B35D8975AEA49698F8D5528E8 59: 59FE977EC1D9927FB09389E3D31272E625F089AA75401D1B541DDCE8C6983A363622CA4F2AA9741F0D1484195CA31D6D315DF6B66E74888D111FEFD249FA0174 60: 2CAA990D06814CA73ACEFE0D9A815589958398999707BD52C3773F61B2DC2F20EE7AB7F66D643BD9686C4C460AF45D58BE9F8DFC1B5CFE3A5C2DC2C93D9491A3 61: F198E9238E9592A97DDFE1B0B56DE5DC05D358940672D84F15E1CE71ECFD3854CDD38762DF11E1871EE615EB6080E329495B37B23710DCA9F4179F5F95F3E2A3 62: 3D7C45603510C6916226B192C81B90EC213D30C11AA21C8520437CA5639D00EAB529A4C443C9A39C5E40DFEEA0F685B3D0E1277BEBDDBF80C3D5F9C8326765D9 63: BA081CA12FFBE3CA8F1E2703C96587634F8EB3BA140F93D997B6D0FAD1C1915ECF7D77CC0421E639B083451EDA605571D68DE81E7A4BFC183D7A53A07122168E 64: CEFE2203F6428D267CD2E284C3B8C31E1946558A56A33291508093DCBF64FD5FA4D33FB723ED49CBA02D97743312138FA77AE960EDF5910E3ADBD02B1203FD97 65: DE0379336B1C7421AB4A7F5708BAA3D4E15CE75CEEB8C7349265E71942A963216559FD628C52F71356134AC328D0315ACB63A06382D4251A28127380CCEB08FA 66: 95FD3399270415A80C2F295957C0BD8E33E35C679C31B2118DFABD542EF02F6E2E432559ED4066954AFBF90C982F60D73DA8BCC94DD48BEDBB00A8E458CCB6B8 67: DE49AD8262EACF733B567D8F7752711ECB5D0FF5CB18E5A99C6C35442E652643149A51C820E6D4481AFE63F5B6955105F8173DA57DEFA392E43F7285799A32B9 68: BED41AF0733EED85BB26E8A06949AFA1CBCA9BA87C085BDE29FD38F94709F4AC20360F7C7958457D2C49BC5A38FBA06D6A6AF77ACC883783B357032FBA9F93CD 69: CE72D475D983EB5E528C4D71EEE48EF337E1723DEFDF142598E4CEB3B2978B1B4E36A69EAB6CEE8F3DB2EB353CBD27BF7D41F73FB184CC8785DDCE8EC22E9741 70: 24A8A7C759F59CD3DE2E3BA953EA975B60079D9B331AEC4D1F4586FFAD190EF53C2EC6BAB566660EB5D652D7D54265B8584C6BBF986537F54F9D8E4068C01F67 71: A7CBE72C99EEEACB387D4532BDB651EB46B8D30A9D5DB8095C9B3422D9D5C9480AA820CFAFE4047AA0546C03DBF07424FCF7B812274B3CDFDC76B9FBBBF08190 72: 16D536D1D673F74D9E298B16AE65C65E467131FDE5B4356FE16E3FC36624E19FA7B55727240C51C20491F3122A1AB073B98E095A24F4B3260EBE5211EA2DCB0F 73: 692189C1FF6DA5862657623BC862F5041D63A2A1EC8986139CCBCAB114427B1A2500B152CC611C5D5599E9792F014A640FBF7C6D944EDA811CD92374326B2C52 74: 273E18F4B94E624988C47CC45820E4552DCC53BB40A9A24F744A14E56FB1DADD3EA4087A785AEDB5400A65971709DA1AAB9C18EF534087EA73A1FC8FDC865170 75: 8F048230B202743FF1DEBAFEF8CC93244687A58A8E5E3E6F7D85237ADBC724641431783E63FC8EF2FBEF9DE9CD50C9FB294341654706DBEFE6B05CA8588E1A3C 76: 7AEF7701439F9DB556AD3B166B0B25A51795638A83E0EE25E5244BBE9D2E8CB6A8242D81E78E4906AC9CA0AD4FECD1006D89C5A8582D1BF51C278EE7A357232D 77: 55CE718F7686A0692B3727BB5C24B16FCB87D8E8EC943A80236CF3E9B37A4A20194243E461B453CF03AD846A0B3287A2005D6603D5E080D700ED2FA25F0FCA87 78: 3378B07E0563CA7BCB91F29C8ECA876AD748760748AD07DE0208BAC227E0EED4A4834B8879F3DFE51FFA27B70AAD1F3E9FE1586B1D6B2B9757D545D9CC5DFBB2 79: 040E1EC767CDD85FEED2AC6767F0B3C17CE4579FD9525213A682A9B49ED03979144CCE2B94026AAF7D401355B90B25259954163E0C9739CB9E756177ABA053CE 80: D1CAE0E4FB245C1AC27659C2EE86BADCE26228CF8EA24AA62B69995FF02F9A59B1ACC1C959EF91A7B6EC90EA9D57F49CD0E7621D09E4016676953A3F9B9D40E9 81: B41EAC0850797959C62DA2750F2BCAECCDFBAB843D56C034E4E0DC15C961FA611C50F22BBC135E5D99DC4E4B7634A8DF4B0262829593A8A86EF6C265DB9AE907 82: 66BE82FD1582736D0DE7861D9DF74715658CF3CD2BCED12868EC4D92F4B015B7BACBB331ACA8D58386AE6B0642C3740BF5F3CB26E76551541AD57E1C303D4527 83: C38BC2639AFEC1964C89CB92DE5ECB78E0B2994EF37F839D0A61EA688CCEB068B1A590D6CCC929EFF1145F5A5925A17BF2FC0AD352801CB92651F08352A992D5 84: B699ADFC29C54F178B3EFFBF8FE8BFBCD722F2997AC30754A8FC5CC6D51352AFFF7F31D7F71FD9D136E78D1C1E040B05E25CCB75C7AEEF714018F51663C7AD91 85: FDC4207E97D12B7A8D05F5073D47EF32BA32961568599ED34CA160F2EDC87726C53087711A63F6BB7E840F305477B931D1CBC1939A8B80205565D453675FCFD7 86: 07E1DDE64790A279B69873C6887FBFCA69B87C97BC25B969E2B16040CDD2051BCF43637F490EF1B051CD882B64E22DA55C253A5E796528526EC62A305FB05621 87: 3ABE353A4291A3A0ECF204994D49443C1FCC60C80BF6096026551048533E02C475B905046C7708F4852645168C88125221504E174A8B7E67AE424C0077163E0D 88: 33793697140180A04DA72C0F74E1F845139937CD6F05AF74E3F3C5031D1D2DE571BD72916CBE67859FE501C0E56354C1360E3EBC36EBC11D11C1EE08D158247C 89: 9E5A386AA9C4C5A2419B902D239E49ED84E542A6F949895C88129DFC2844FC77FB132592C7C1474E619C55FC2835F0810F227799984777CE99D586C158C8F9ED 90: 6E0D9841C04BB47DEE30F6AB430E53FA1637421E460BBBD7BC8EA167B9A341DDC5E933B6983A025226B1FB3CC663EDC3477F8F0C8FA109A8B97B4B17AF3C2774 91: AA0218FD54533314F62390B8C02219D26801C249D394E33981E3B853C5735E331826FA02697DF54C9268B891592DBD876E25C8D985DE8752ADAA0CBE55AE7FFB 92: 23905B9273CA17D80D9C877DD78150B5382744896B073DC636618C540876B9BA51EC60F5E45DD53BE210B6076554238A3B5EA95DCE3481F0FCF2825B852BDE3E 93: 1815D1AA4018626EAFF051AFBB92E91F6D6D136F58E8DB160C9E85BEC027B6CC92F0F0760DFD722BE12A97F7D29EEC341BD309F230B55B81D146B409EAEEB7D0 94: A2358789A04795BB20D2EDBF95D5DA28A1FBAB329F99DFD0B103304F868CE5AA2DC1F52FE98CC84EB095B9C5ACBD6DC05FD03CFBB3F1D26675D0A8F652D38236 95: 2C4DEF028098A0680DF15DEBFE6A7FA42C7A7D75CF410340ADD5257037F0B2F98FB5A068361DF33010FD48A4B41E0E40A2730FF2148C45FA568FAA182589A543 96: 360F3B6819EAFD9B3D6BC469F4272F9458C0791759EC1136FAD500F3FCB4FA0598204669E865D7D5F8C289043A2A1CCB47F55CEEFAEAD98C7FDEF38FB22D3A29 97: 1CB2E98EE8795761EDB7579583EF86E7223A2109267E5234663BCAAF9FBF28EAE35FE362AE9AD075023C1D36672002E08CB36189A603C174D73BB9489E13355F 98: 9B3F2D2B2E3D0401229F11E6DED451A1289C631122684BB32B8C0450043ED2267AAEA20E950F52B44EA5941C507F38D23CA76E212593B65BAB347841179BED1D 99: 2E27C53324017626F7EE7EE26BB0C88450B3D882C2D8823647ECA7650CADDFF3E4201D7DFA2A07A51B9372FCB04C1A79A264DCD3D260DE135D08DBABD2C5869A 100: 0B3D7FFC5DC1CB18B867D995E3D02FB2FBA0DE27BCC85E49A3B01C5581EB3B14C19254C87D92D2EEF952C98E4E6F51C9662CDB982BC95B88C11CB2EECF032576 101: 85C0B9C8AB8C670C01E179F495DE26F818EE772AAF6FCE4ECBDB4FFADEB1CFD8EA86E42020B47894301920B86082DE52A7E7CDC6DB4904F8F0D383D9CDA312E7 102: 0C6637D399CFE2734AF7B63F81B7493158B7842E3C5B72E6CEA4388A5C6DB7222D46727B92FB82D88551A227703B8BB6A1AAF47247661E074CF6AE4277D586DB 103: DC54B4ABBB7942C502BF3275E37570947FF7162B6831AA430566E69AA80658C6E792B78EA081611256C64552A9E15A66000632116AC83769B7C58B809FD96021 104: 532372848D0F525884E5ACED9A727E96A8D92B484DC2D4089206B001CF9EC52902E49E6FD9FDE634941BDF5AA2B45B0787D0B183B895470BF1E79B57DC976EE0 105: 4B6CEB5AA2174E6486ECB185044629BE6C280807F102CE52D2CE2DCCCFE96E5586A6888DF7500614896C9FE70CF7BC83FE755E88170B3D39EF9B218BE809E495 106: 6D506B4BD3F079EF4818FCFDA519E7E2AB6A03293525711142C3CDC5236A7CD82A880D9CEDCBC089F7A3D5D3E48BD75DCCA7ADC53B13A2FC9CAC80C037F2CE5D 107: B8ABE308840CC901C6C5FD908E2680886AAA0BDF7085C1A6ABC257186AFC52C522528BD7BF4E82553D9E64CBEE09B9318995E13715AB1F7809EF185E8473D70E 108: 9790A198DA7616F4D8ACDE68DE19635A555874EAE77AD4ECFEF7207DC305D475FD250F308F466B189425AB6A9722D744AEF14541FEB83698943E87E8A39DF838 109: 816678F1D7484660F4701CE77F4C5E13E5DFADEE6622411BE86DBA4EB71A110DD1087AF7D3F37B8ECB1B9C44A3BD5EA73901C21AAB51E569E61EFF25B5E955F9 110: 51881FF4B150EDC3542CA12CE6554A40415AFFAA1197FE7CA4B8B065A4FB1DC3B924A444CA31776CED52514C525261269895EBD8584C29747F8D527213534E49 111: 6D8902F285029EE683CE1803B2D9C6BF6E4B7B59C0ADBFBCED3346782A35652DE3F304ABBDE9F22E4960DF6049431139EC6AA023EE2B013A426DB9A816D92699 112: 06E5847A060BBC4FCE1375DCC15AEAFBF514EE1ADCDF42AFF932AA277DC09EF614651255E35C499D6BA1BB875EA3E80F80AABF8B7710AA5696B058BE91B99B01 113: CB1859580DCA13556FAB791572E523C2E888115C18C043B0E33F2268DD0056F9A60EDBB65DD9C8B552CE2299E847ED4617BEF3A453ED2AC3B5366B4D9A651B61 114: 39778F80D346E53D1B0E60FF7B36A92639D9E7F11548C9326A59D9311D57BF09F33BFD6AC5352F2F041BD07A6D26A181419F5FCD1D5FF8AD38E485DA7DBD5419 115: E508C9A77F53E36F76F0E477DFF076DE810F9F1599A16A3EFF1840332B26D6C7CC40E03CA8CC212FDA776F4DF968FCF92CE492AEBAABD65F069D1AEBECD11B7B 116: 4659D0E1F9E5318D7B92FCF7700C467429B63F27188C0BA168F0D5696DC764FBFE2C5EFFCF6DF11EA77A17B0565CADC04F95FFB0485CE6900161B82608B1647B 117: B3DB7FF2F08F57F0CBF2195BB9600E9AE5D86A15921EB164A98D25D559BAF5FD740D68430653DE73F3277425DD77CC3FB0CB44ACC5FDE693D59D5FA6DED84597 118: CA4559843946A7583F944D51E31FDF32BBDBBFC049724454C090A6DB9C356739F2B7E254CF9746521D965593FBBCFB26092069FBFB0D17A1593416D69681B687 119: 27CB8A2143D1073AC17009C31B28DB95DC195E20AD7D245D8AD880789898F043F0565FE41485EDC239C7129E4B7FB693D9044B2C3D34C5648E4FD8447E85FD71 120: 99811490C7FC83A10AAD197E95D3618ABF5018E9AF7EA0AA2CC0C771FC11FCEF9FD6070A0962A563D260E8CCFDB77B48745C8C27018F9140870F146F124FF14B 121: A1537FDAD7E18F732181CD9EC9BFD3993FAF5F994A8809A106B59D13BB70FD8D7D4E6A4BEDFA806A9D434AAB0368DE840FD64395B4A9A874DB39405707AE3AE3 122: FB0D6D962055B47D3A72371BDAF77BE7BF965EA7D53018CAE086E3536804AC748E706E89772DB60896EB8FE2ED8F580866BAF3108CA0C97938B69830FFBC14E3 123: 3C947F4136D9E780A7572CA4D5D7998DD82D3890CC3F1BCB59A7FE230E31DE322DBA7CF7C1DACB33A3EB1F7E75297C056570D2846EDF756D36C1AE92F8DF6954 124: BC1BDEFFC6AB779A7ACFE53A3F9DD588CD3C77C740F944C69E331C38F162607E0D4A0CA874AC3D1D74965468843133AA9F961FBFCBF59B58818577132B863181 125: 51143DA8F5D6E68EC97CE22A4961EF43B3AB658711280587D9ACEE701CA65CAE90D34B66DB52D779A8E2BB6204FFCBCA945C6B98B2C17C8375551FAAFE4C8A44 126: 2550FCF54872616ED31C60FB3FD97B9AEC7A27B3CEC07D774FCE694ED9D60C43A968251C5F3C5B50E6214426B00C55D7DB1DB31CFC4BC07F6ACEA222052AB796 127: 1D8B2525E519A3FF8BDAAF31E80EE695F5914B78E7DAB801729B5D84C3A7A2B36A33803F5E0723981CF8A9586EC1BEABC58154EFD919AFF08935FBD756327AAB 128: 4AABF1C3F24C20FFAA61D6106E32EF1BB7CDEB607354BD4B6251893941730054244E198EECD4943C77082CC9B406A2E12271BCA455DF15D3613336615C36B22E HMAC-chc_hash 0: 0607F24D43AA98A86FCC45B53DA04F9D 1: BE4FB5E0BC4BD8132DB14BCBD7E4CD10 2: A3246C609FE39D7C9F7CFCF16185FB48 3: 3C7EA951205937240F0756BC0F2F4D1B 4: 7F69A5DD411DFE6BB99D1B8391B31272 5: DCB4D4D7F3B9AF6F51F30DCF733068CC 6: 1363B27E6B28BCD8AE3DCD0F55B387D7 7: BB525342845B1253CFE98F00237A85F3 8: 89FB247A36A9926FDA10F2013119151B 9: 54EB023EF9CE37EDC986373E23A9ED16 10: 2358D8884471CB1D9E233107C7A7A4A0 11: 94BAB092B00574C5FBEB1D7E54B684C4 12: DF1819707621B8A66D9709397E92DC2F 13: 3044DFFC7947787FDB12F62141B9E4FB 14: 9EA9943FC2635AD852D1C5699234915D 15: 1CC75C985BE6EDD3AD5907ED72ECE05E 16: 1A826C4817FF59E686A59B0B96C9A619 17: 44DB2A64264B125DE535A182CB7B2B2C 18: 4741D46F73F2A860F95751E7E14CC244 19: 13FDD4463084FEEB24F713DD9858E7F4 20: D3308382E65E588D576D970A792BAC61 21: 38E04BD5885FEA9E140F065F37DD09FC 22: 5C309499657F24C1812FD8B926A419E2 23: D1FDB9E8AC245737DA836D68FA507736 24: F6924085988770FCC3BC9EEA8F72604E 25: C72B261A79411F74D707C6B6F45823BD 26: 2ED2333EBAC77F291FC6E844F2A7E42D 27: CE0D3EF674917CEA5171F1A52EA62AAE 28: 55EDEAC9F935ABEAF2956C8E83F3E447 29: 820B799CB66DC9763FFD9AB634D971EC 30: E14B18AB25025BF5DF2C1A73C235AD8B 31: DE9F394575B9F525A734F302F0DB0A42 32: 625ED3B09144ADFF57B6659BB2044FBE libtomcrypt-1.17/notes/omac_tv.txt0000644000175100001440000003153410621351501016052 0ustar tomusersOMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are OMAC'ed. The initial key is of the same format (length specified per cipher). The OMAC key in step N+1 is the OMAC output of step N (repeated as required to fill the array). OMAC-aes (16 byte key) 0: 97DD6E5A882CBD564C39AE7D1C5A31AA 1: F69346EEB9A76553172FC20E9DB18C63 2: 996B17202E2EDEBD63F414DD5E84F3AF 3: D00D7DA967A2873589A7496503B3DBAB 4: B43C24C0A82DAA12D328395C2ABD7CAE 5: 9B902B6663B5FEDC6F9DCE74B35B91F2 6: 06A9678C65D7CE225E082ECA31788335 7: 7D67866CDB313DF65DED113DB02D6362 8: 259E28CF3E578AC47A21A77BA9EA8261 9: 32F23C8F93EA301C6D3FE0840CA8DB4B 10: C2B06388AD6F8C43D19FE4F6A8ED21AE 11: FA8622485DB2F62F84FF46E532A1A141 12: F312D9B2E6272578F406B66C79F30A0E 13: 7A5DE06B2BFB75ADA665E96F680AC098 14: C3B00380F0BD8E2F5C9DD9945E0F36EE 15: DDD87974A5FB2E7A4514241E94526B5B 16: AD24FC47A0FEA84C54696DE997A94F4B 17: 7538713D8AA2AE3726307EFF087BBF5E 18: 7619A52B4C34A98440812F5F28F8DC4F 19: 7E797B8846554888622CC5E400B2FA44 20: 61E8DD3E09145F5657DB4B8F7BD2D7D8 21: FDAE2A3FE60DDF1871C2613A293AB6F1 22: A186D6EFD10DFFD2C088480B0A784185 23: 3119D337865618CDA55C06FB992427CF 24: 413E3EAD7E3F169A37C49F9CA92E235E 25: 37A55AF22373B9A1E2F8368B2FB992CA 26: 4941F604C40EEEE1A16CFE073C12D1FE 27: 3E8F4A0876BF12A2DCA87157F15DC884 28: 5DFAE292D8EEB13D8FE5725E5D169742 29: 59160455E0C0B35D950BA67C77F9FB05 30: 5AC0D736A06A7DD146B137ADEE78EE06 31: 0CA1178F28B953045EE76E2E760036CA 32: 025616215F870D1EF838AD1D2AE0C649 OMAC-blowfish (8 byte key) 0: 2CFB5DE451FFE8CC 1: A5AC339DB44D020C 2: A3CE0CF62249444D 3: 3076B7129CE3F6A1 4: 9E091A637DDF70E3 5: 275199AB20A5F09C 6: CDEDA8D16A401E62 7: FC980516CF5C9E30 8: 659D0B31D21B622B 9: 8306847B5E72E018 10: 7AD029BBF1D2919F 11: 133181425C6808C9 12: FC5AC60E367F413A 13: E0DF8BCCF0AD01D9 14: AC5015398FA64A85 15: 1F068F22AFFECEE1 16: 8E6831D5370678EF OMAC-xtea (16 byte key) 0: 4A0B6160602E6C69 1: 1B797D5E14237F21 2: 938300C83B99D0AC 3: F989B99B3DE563C6 4: F65DEA2A6AD45D1E 5: 1DB329F0239E162E 6: C0C148C4EE8B4E1F 7: D82B387D5DFFE1FB 8: 1D027A4493898DF2 9: 196369F6B0AF971A 10: 2A37A2655191D10A 11: BD514BE32718EB4A 12: B4DBC978F8EE74ED 13: 8ACCAD35C3D436AE 14: 73ABDC1956630C9B 15: 73410D3D169373CE 16: 23D797B3C7919374 OMAC-rc5 (8 byte key) 0: E374E40562C3CB23 1: B46D83F69233E236 2: 7CB72B1D335F04B0 3: 94457CBC97B31328 4: 543D0EDFCDCD7C76 5: 5164EFA8412EAA5D 6: 13CA0717EF95F9A7 7: 2AA49A7AA7719700 8: C9E7C56125C3D90F 9: 2BE3E15FE58648AA 10: 77D0B90372D6D0FD 11: 17408F62ECD62F57 12: 7864EFFA59DC059B 13: 3212E76E25E5DEA8 14: E2424C083CDE5A6A 15: DE86FFDBDA65D138 16: 85482C24D61B8950 OMAC-rc6 (16 byte key) 0: E103BD8BA47B7C1C010E1561712E6722 1: E51AEECFED3AF40443B3A1C011407736 2: FA6506C5ABE03381B045D28D1D828966 3: FAC4237FFE7772E2299D3D983BB130DD 4: 3A7E24D41121A5D4F96FCECF0C2A4A10 5: AA44291E5500C1C8E1A14CB56E4F979A 6: 4B8FDA6DA6B3266E39111F403C31754E 7: 4DF5F1A1C8EBC7F56D0D12EEB63FF585 8: 46A6DDE419355EDE14D31045FCA1BA35 9: 71756D4D3DF59578B7F93FD4B5C08187 10: ADA292A19F8636A03A8BC58C26D65B0D 11: 703190DAF17F8D08A67A11FDF0C2A622 12: D2B94CAD1AFC5CD012575964D1425BE6 13: 45FD0069FCA6F72E23E4DB41AA543091 14: 36F652600F5C9F226721400A7199E2BA 15: E8CC6389ECF8EF1DBB90A0FD051B7570 16: 8125446B975DBDA742A903340D6B96C7 17: 00B55E4399EB930E592F507F896BF3DC 18: 33E58F42A47C9543A851D6CA9324FEE0 19: 9F28FDEA3EC7F515128F5D0C0EB684C5 20: AC1DAF6C01AA28BCC0A819189FA949D7 21: D0532B5F54A179444D052A4D2AD6E4F9 22: 58B80A66549404C7B9F64D5AE3F798AB 23: D0D6D586477F92311DDF667E0749D338 24: 0DFC0FAA67FF114398CE94D0688AE146 25: E163B8C00CF5CC9FA23ACACD62B53D64 26: ACE9270456AF9BD388BA72E98825CFE8 27: 4302EED9BAA19C7A296585E23A066A44 28: B3EEABEFAB25C7478419265564715387 29: 9F0630ADE9C74AB2981D63F3B69E85BF 30: 1215A9446A275CCE2714F94F3C213BB7 31: AF43D7F748DE0E3458DB970BAC37E98D 32: BF871AC9E892CE0DCD7C8C7ADDD854C6 OMAC-safer+ (16 byte key) 0: A2C8C7FEA5529D01C3FF4E9359EF74F4 1: EAB87021118FF24FE79B69ABCCB14A8F 2: 789566F467BAA68F4CC3C4B61901D6D4 3: 369F41EEAF7D628F9E0D77BE43BFC1D2 4: DC46A20E1F36F45006ED5B43BEC20DA6 5: 8F150CE34F57BBA2E6CE3431B78E4ACD 6: 61CD154478BE20F33B26CD8FC58091A5 7: 4E6DAA575CF28F1F48B256262B7D558C 8: D21FA4F1859571DB91E92767C5487AA2 9: E3D009DC7E71FBBB030B8FF0B544A2C9 10: 094C236EA48ABF7DBAE5A88AA3DE07D7 11: 00C401996F8224359566660AC1CEDAA1 12: D580EC60F712558D875F01643D96653F 13: 8482298027C7B4D5969787A1DB1B1F2F 14: AB726AE3DA95CB242E63EF876A4BC446 15: D668ED4919003F5E45590663FAED41DA 16: E4CFFD7E0E7B176867C386001849FD6F 17: 37B3C6DEFC5573879006D15F982A397C 18: 0AB8847EE6A41A0E960080EF0D1BF1C5 19: 2C94FCA2A685F276A65ED286AE12FD9F 20: 23383032032D7B5165A31ECA156DBD23 21: E1EECFB3D671DF694FFB05AE4305AD4C 22: A0F6CA99B96CD1EDD04C52828C8A4D74 23: 12D6B7053417AF3E407EFD6EE1CC38FE 24: A566D1C39AE7A1A0A77D5A1F56C5FAAB 25: 81C9FAECEAEA326140AFCD569668F669 26: 6A00BF1D0DC893868378E4347CB4A1B9 27: 98842956DBE7AFB1BF49C46497BD54C7 28: 88EFCD5A1644B75BB0B3F5DD338849CE 29: 77EC62C278C61163B1BEC595A11F047A 30: 147424E817DC69413CC657E0CB292F7F 31: A2946CBB910743EF62D8A3C7391B9B9B 32: 00EEDA55520B8A5B88B76487E80EB6E1 OMAC-twofish (16 byte key) 0: 0158EB365FCCFDD94EBA6BE42B6659C4 1: 17DA580917D147D10CB73DB6800B0E59 2: 3F185CC15EF3328D3E075665308C07C8 3: 5712A97ACC9D08FE9D2087D0CA16B0AD 4: 90425A8CC1C026DDD896FC2131AF654B 5: 30A43D4FEAE71F5396308C16DA081B4A 6: 6839FEF605704D49F1A379A9E9595E6F 7: 56A8F06DFEE543971B351B07430E2026 8: 36DD0E4B55C5314F9F2753D7EB6F0849 9: 8E319249A3CD456460F410F518F8CEDB 10: 463978BE2A063C22E71DC71520723517 11: 1B735E45FD3DF636E0A6104D4A2E9CB8 12: 628A82213148AD9791153D5AAFBDDFDC 13: 21AFDF08A36ADB6659B656C8EA0800E5 14: E5C3E58803DDBE174E0D4C2B8171AEF0 15: FC6981F2B4359BA05988D61822C0FA88 16: 7B03498FAFB04A6542248852225F9DAE 17: 9B173E91E59A940186E57BB867B8307B 18: 470BF2EE614C8423AA3FDF323F1C103E 19: 6E664AFDFD8306547BBEDA036D267B79 20: F61AEC1144C3DD646169E16073700AC6 21: AE503B139707AFA494F7F2DE933EE81A 22: A0A8BDD4ED0DCAE4A8E1DCEE56368FF0 23: 460B8207930DA434AE6AFECC305D9A26 24: 7F03F8C7BA5365CC65F7864A42693BC8 25: 31448849D6190484192F29A221700011 26: BDA941019C75551D858F70FB1362EB23 27: 2880CB3E62447AE8EACA76C17971BB18 28: FC8D710FA3990B56357E61C2A302EB84 29: 793CD15348D7DFF301C47BC6E6235E22 30: 6FB0CE69A15A3B6A933324A480077D35 31: C24FCA5DD4AE0DF2BFF17364D17D6743 32: DC6738080478AF9AF7CA833295031E06 OMAC-safer-k64 (8 byte key) 0: 726FE2DD40A43924 1: 2A138B65EB352621 2: 9588A1B53E29616C 3: C025DEFDE1A59850 4: 73D062F1B6D8E003 5: 944598A2FC8A2D76 6: B176C25D8CAFFC98 7: 14F05014DE6A090A 8: A7B9847B2CE22D0F 9: FCD71310CBAA3A62 10: BFF00CE5D4A20331 11: BEE12A2171333ED5 12: 333FD849BEB4A64A 13: D048EC7E93B90435 14: F04960356689CFEF 15: 9E63D9744BF1B61A 16: 7C744982F32F8889 OMAC-safer-sk64 (8 byte key) 0: E96711BA37D53743 1: 7DCFF26A03509FE1 2: 0A20EF19C8EE9BF2 3: FE2883748A6963CF 4: 557060195B820A18 5: 771A7931FBBE5C0F 6: 6BDBCE5F96CF91D8 7: F3B924CCE8724595 8: EC7191286D83C2C3 9: 94F55B19BB7A8AC1 10: 2189F4F2B06A8CA4 11: 99853DAEBCA33A46 12: 66EAC37A033802D7 13: 845D7AA866F8A8AD 14: 33A874DFECAC22AC 15: 63DD9F7A7F3683DF 16: EAC277D951676C44 OMAC-safer-k128 (16 byte key) 0: 8037B89AF193F129 1: FF2314E87BA6AFE1 2: C3243DF896B61D85 3: 0F61C715CE821AB8 4: EBFDC6A9CFD2F5A4 5: AB6497D7AF2C7FFF 6: C920CEEB7C1819C2 7: 3E186951B545A7E5 8: 5EA36A93C94AF4AC 9: 6A2C59FAE33709BE 10: BF1BAFAF9FC39C19 11: 69EB6EF046677B7C 12: CDDCEE6B20453094 13: A3833BD3FED6895C 14: B6C05E51F01E049B 15: 90A2D0EAB739D39B 16: 07BF607A161D0A66 OMAC-safer-sk128 (16 byte key) 0: 5E8B137A3946A557 1: 0228FA66B13F3C7E 2: A6F9BBAFF050DCDD 3: F75880F684A796CE 4: E0AEFB8E32040EBD 5: 9F65D658B86D310F 6: 3FA52804FB46CCAA 7: 2F6D12D199FCD2FB 8: CB56AF60AFB4D2BB 9: 8E6F0FF6FDD262FD 10: 490245BE3CCCEDE2 11: EFD319AE46C73005 12: 43E00E545C848995 13: 10444B41ECA15EBE 14: 521775C389D5BE71 15: 9B683EF8B097FEBA 16: 3C5D746EED09530A OMAC-rc2 (8 byte key) 0: F001FE9BBC3A97B0 1: 8F8DC9C952897FBD 2: EC82EAD195AAC38C 3: 53DD52269B19E9A4 4: 9B86F64BF72A0647 5: 664A88A29F2898C6 6: AFEC3F71C1415666 7: 9BA1F2C1A2E765F9 8: 402A12120908B436 9: 03ECCD4C6AF44144 10: E8CA3529B5D9D6FC 11: 951EE10779CC585D 12: B9083CA88E7E819B 13: AFFB9E884DACC5B7 14: E942E8BC241343D6 15: 9B190489091344FB 16: 9330A9E05554A15A OMAC-des (8 byte key) 0: C9085E99D74DF01D 1: FAC84F0EFBEF8630 2: C37C5FECE671CF16 3: 45B2CBEE8701A5B1 4: 53665E1F024EB001 5: 357123CEDFC9FF61 6: BD2CFD33FB1F832B 7: 1AAA9D8C9120BDBF 8: EB9F589AE9D4E78F 9: C8F9D2ACE691922D 10: 81ED6F3611DDC0FD 11: 2965ABEAC46839EE 12: 2208B1E095F7AE2E 13: C0414FE41800113E 14: 653A24119CF43D97 15: 7FB7CE0862958B37 16: 55097816B10C549B OMAC-3des (24 byte key) 0: 7F07A9EA8ECEDF9E 1: 4E2A652EB5FBF5F8 2: 4F84E3779ACCB9F5 3: 7134AB3463115DC6 4: 82327BE8EA2D7E0B 5: 24950B9C14D87CD9 6: B25A097BB7E0E18A 7: ED51BAE55ED925E7 8: 56B79E7644556975 9: A65BD98E4D4E31E2 10: 11145BB51514482D 11: 397486787E676BA6 12: BD1F6DEBAF6D9AEF 13: 5CC3921F7DB815CF 14: B0C0E60DA5F727F3 15: F8637AEEFF10F470 16: 0EA19531D42706EA OMAC-cast5 (8 byte key) 0: 7413DCDB9F0C3100 1: 423799EDF1472B79 2: 03856F0CB4F11606 3: F152AE6360813DE0 4: 853998BD980AD146 5: AE6C3D667DB8B414 6: B5A4986A34BDE20F 7: E5ABE5B979798942 8: BEE8DFED4555F405 9: 6B5339E952AF61BE 10: 5E867CF34D9C1149 11: F9C55CB3BC655E08 12: EA09A2929AC7D915 13: CE8EB0E4370E1933 14: 749A424B2AA91B98 15: 8DDA93C2B814D5D1 16: E8B0B219D4CB699B OMAC-noekeon (16 byte key) 0: EC61647B281C47C1B43F9815064BF953 1: B100B1B6CD96DCED8F47A77E70670A92 2: A96CDE3C48831A6B0A5ADFECA6399BDB 3: 14E75E7CAD840208834918B29A5D4430 4: 9577083713AE6E44EEC987C77C93C072 5: 2A738C02841E461238C02F5CFC8E66A6 6: A901327E451BE0D2D9DEC83DEEA9A022 7: 5ED7EE1BE04A64A689D15F6970A821A6 8: BA053E24FCFD02C731A8CFCA19EE66A0 9: 57139CA8C91072555B29F85A19E2C84D 10: 4585EAC7EFB84869FD96EE7A5FDD350B 11: 62AF6C415CA73E54E82EA306254C1BDE 12: 75304F9724BD364F84371EE154F5210E 13: 7FE5DBCEE826760434745D417453182B 14: EC98DA2A580E9131218D1CDE835423D4 15: 631BD9EAFD1AE445F2C1C35E2B4416ED 16: CA2D902A1D83388FE35BAB7C29F359BA 17: 0DBF0AF7FCBEEE21FB6159C0A2FFCD4C 18: BD7CD2C49241032DA33B1975EE2EE982 19: B30B090EE8626D77D310EDB957552D46 20: 64F608AC5707C381AC6878AA38345144 21: 28513CA7795B23A02B37DC3732413D23 22: 9F440700094517847E9E013C8915C433 23: 8CA483F313D20BFE7E0C089DAA4145BD 24: FA44872743E20E5E0A069B3C4578DB50 25: F6DE8FFBECD52CC1F213CD9E406DF3BC 26: B9702B7E846735A3DCC0724255F88FEC 27: A1DDAFED2B1732C7BA89C2F194AF039E 28: 2549C5F0E30F8F4002431D2C098805B8 29: 52E3836181BF5C9B09A507D5330CD14F 30: 01C55DCBCCFD9D7A4D27BDE2A89AA8EF 31: 3CF721A0CF006702CDA91F2FF3E4D5E3 32: 6D264B9065BE98C170E68E9D2A4DE86E OMAC-skipjack (10 byte key) 0: 84EDFA769040603C 1: 7DA58A4CBD642627 2: 118F60115CFC8229 3: A7F7346D34DB2F0E 4: 35615CCD526CD57F 5: DE471601A3660844 6: 15FCCE6D6D883D1F 7: C6F694861233151B 8: 3B762B397F16E807 9: 976C6AB59FB3AB12 10: 6810791F2C595961 11: 7FA3478286917F17 12: 73DEE44A51C6B610 13: 89EE8B253B1ACE81 14: CDF2586A56C8A0B5 15: ED91F98DA98F42C4 16: D8D0FA5CE96B08BF OMAC-anubis (16 byte key) 0: E672617CAA1E641C0E7B4B4CC4787455 1: C0C16E8FD63907C08A8ABBB7B73376D3 2: 23F97CED54939361830396224A7BDD91 3: 7FD87DEA9F05E07212DDF61292D9E13D 4: 929A11A4D0991A6446B1051926A6048D 5: 4EB74F1CC0150D86126BC6FE1FC8253D 6: 33C2C3C072D05BB6D54F87579C23B116 7: DE350181C9E90A79879813A609BE77E2 8: DB519EB9EF0E154D9D248734FD3D3724 9: 4F7F2E6D3FC72BA94FE24EC0ABBF4E66 10: D646389DBCEEDD59EBB6E8F09C422930 11: 8547658AE1CE6A8B8D010A1E1FEA7AF4 12: C9BE2B7F3630EFDFBD3AEA6A108C86EA 13: 290417C57096B8B9A1BA3C20FD91285B 14: 9AF60E99692C5F911CBF969A6E11DC14 15: CDA433BE58C98E49EBA8A7108E50DE2B 16: 7430D0EE631A4659351B8A4489A78D46 17: DCC74C0FD0415768FE00225CA14B7DC2 18: 0CF2432B1B465F2A8C5FACAAF2FEF619 19: DA020680C64E93AE5FCA3D71466D01C1 20: B9C33A86E6ED9FCCDCD973382DD1B6A3 21: 6631236B9F2F810DD4D97E6046F41AF2 22: 0312C322F4D634CF4FBC0C2624E3E9F2 23: 111E3E9F8FBDC1E4364622723F1CB524 24: 6D2608D7AAF243D5219E14513895BFF6 25: 683BD01B43CBC0430A007ACBAB357DC9 26: 01B8FC65C56B0F1A5BFEBEDCCF6748D9 27: 4D6298D63A80D55491697A6DD8E3694C 28: 6F0205E4E083CAB00747D723300510DF 29: 5183BAEEF05E9402A935EB9AFF0AA2A9 30: 1E673BFAD4944643A740C59D96A5925C 31: 940FB4000E34EEE78E8DB402E4A76502 32: 87B0C48F3D155AD85D0502D94A4572DE OMAC-khazad (16 byte key) 0: 4EBEFA460499424F 1: 97AEEAD51E541D16 2: 29A35212910C9595 3: ABD1577D622074EA 4: 70A537DE14DD765C 5: 240A19016DE99C51 6: 4D42C10A9F803177 7: F464BC3E0DB5A909 8: 1C65A01A7C08DAC7 9: E49A1428C230C209 10: 16DD0FEB7A6505B8 11: 2DDDB3E35A05C220 12: EC88910C799AC6CC 13: B2A65C9EF39BEC8A 14: F0D2366BA91DFFD5 15: BCAB623CAB7AAA23 16: 9BCEAB857596E478 libtomcrypt-1.17/notes/ocb_tv.txt0000644000175100001440000005643010621351501015700 0ustar tomusersOCB Test Vectors. Uses the 00010203...NN-1 pattern for nonce/plaintext/key. The outputs are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous step repeated sufficiently. The nonce is fixed throughout. OCB-aes (16 byte key) 0: , 04ADA45E947BC5B6E00F4C8B8053902D 1: 07, 987354C062CD6251CAA6D93280EFE9BE 2: 1CB7, B9F1620EA8374E1C2D05110878D93069 3: B98C59, 3793FB737C2DFB29E73DD1AD8B8F71C7 4: 8978F240, 5E25316ED13D3300F2EC12D718A0BA8E 5: CB4D261594, EDA252A1A5C7D0A4AB4620F771446DD3 6: 30D6B6688D59, 684037DE07832C6FC38CA42BDF2A7D53 7: D0583F9741BFA4, 3DF53DFF73431C0245982F4EEEAD432F 8: EE3B9596CBEFF520, D283D1B9D990739EA05F4BAE2E96BE4E 9: 6570FC25E6103AC125, 90D3F1FA6595B775749FAE7B00A8E5B1 10: F56750C98C370DFDC4A0, 19389A6875FAB432B72D64BCDD6BD26C 11: 3344AE6D9528603CC1E4E1, 87AB6FBC7F919125A7DB0D17D19056B8 12: F3D9D816A727D3E67330C779, 07AC0F3841DFCFEC58A5AAC22270538C 13: 976651E63ABC3B276799BC1FE4, EE603A8C66099AD6FF8667B3F34ABF29 14: A48E3ABC31336C6B717A96170A9B, A9D1B973D84D3125F5F9D7923BA0A8FF 15: F60E9B2A911FAFB0080FAA3ECDEE42, 4902F8AEB7685F7B255ECC45B5B7D3D4 16: 0855DE488940144AF18C65A9966DDB66, A66B3E7A75D394273AC196FFD062F9DD 17: 172DC1740F75AB2A27B2B80895961A69AB, D6986BB95F7E4137430CAC67F773623B 18: A414234DCCC61B65A79B7C618A6B91ACA410, 6CE32E55E158BC3E51E94116A615F3A2 19: 16A1B16BC0F63D63179901F1CBC772D612C102, 54007EF9822E0E4A4F953838577C76FA 20: 539788EBF85C15B3A638017B4054D71315BFF25F, 9B2511322E16CECD53E3241F3D51EB97 21: 7E74595A3DCFE1EA2C91B67738765463D50A22924A, AC9C9B526251C16F112E769F9FBE74E4 22: A2B61792102B2E44F1DC0E48B40472CE883730504FEB, 76452A49C2524404C8A4B098D6390F98 23: F58174BC06A022AB7D81991E9346F5E4B0AEC535D93473, 47F96374BC094BB2C1A5D1D291806912 24: A3A7713895D178A85D9092EA6138323DC2FF9090D7F01AC5, 3814208FA7009A2934F9A172D029667D 25: 385525DAF9949DCDEB22F7518AF96438E40F7D94933706A9F2, 1249F3DF50084A6D1A76AA350FD85B0B 26: 6838E207D98A5BF8D8E41454CF51663D8F8B76FD26092D45D1D9, 301723D0F49BF8CF37828340B894689C 27: 736413C025A549CB2550E93139DFD5DC3CE241C296C9FE641FF520, BE07259963F251743A85DF51EB1B47FB 28: 7F2CD26367A885BD9E2B515D4E871272AC1BEA1C650B530E5616B2D3, EEB37E8451597E5A53CB49072EDA9346 29: 68F23DCDEF223B60B46E3D724A93BEEF8B110D4394C990AC3D0E34E1B6, 9A60344982F852EFE02CBE9CBBAB60F1 30: 66C5DE3EB27139983D48BED81D0E5FCE6BA1AB402C357062FE989D31C69C, BAFA0A7997A529039F0CE8528E670415 31: D3B9009C1A930EE288C61B0B15C7E92CB73484C345594DC5A3F377147981DB, 1EDAACF7F1F3AC7EA613F94DA4DEF930 32: F7818DF15FE6FBC42A28FDE1D55A2C07EC8D82AA0E7A680DBD3CF26C13448F9B, 67FEB344108008A88067E92B210766D5 OCB-blowfish (8 byte key) 0: , 07B7752047F9E0AE 1: CE, 7D69017C42B06204 2: 1D6F, 4DFD4BD58439062F 3: 30A011, DB49D988798F8842 4: B71C8951, AA3261584B0C20FD 5: 06F89957DA, 88BFA80D36427F64 6: 45BC4CE5FABD, 4CAF71136ED166A7 7: A7405F124D0296, 5D8993CE64FFF0E7 8: ECABEFD9E6574E4D, B69349673CF86E41 9: F7D26A7E82A34ACC71, AFFDEE843ABEA68A 10: E225C5F0FA1D649F81A3, 03AC1D5DF1323EF8 11: 58722FBFB86C2697061217, CE731D80E6355710 12: E577EB8FA70225C5A18D31DC, 2F08B140F0D3A255 13: 92154A94CD7D42EBADB6CFEE14, DC949170E84D3CA2 14: 5A3C08744FD85CA262D51AC6CD25, E83CE45547403BAD 15: 8B2E4980ABA10A20573A402D89AD12, E3D978611DD831D0 16: 3EDC4A0FA95BD8F944BCE4F252B6470C, 87B54BBEA86A5B5C OCB-xtea (16 byte key) 0: , 56722ECFE6ED1300 1: CA, DF53479333DB86AA 2: 9529, D0B5A859106FCC9B 3: DDBAB2, 3B31FFDA57CF51C8 4: 22EB7DD4, 2BB34D04FFF810CB 5: 108693761A, 7AFF6F52574A019A 6: 391FB7C61E76, 616C5E66297F2CCE 7: 3E22E4A4A0BD13, E84C385ABE25C8D8 8: 94FA11D5243EE34F, 8F017DE96049D0F9 9: DADB6B5D27049240A7, CA69E14047C6BBA7 10: F79C8EA83C69DE914DAC, 1EF042DA68106C64 11: C5B6E04AB8B9491E6A99F8, 143515779A55C972 12: 33F493AB7AE62DADA38C5B24, 531BF7799A778620 13: 6DAA66BF02E66DF8C0B6C1CC24, 6CDF72786C5EC761 14: 4940E22F083A0F3EC01B3D468928, 185EE9CD2D7521AB 15: 5D100BF55708147A9537C7DB6E42A6, 78984C682124E904 16: 744033532DDB372BA4AFADEA1959251E, 438EB9F6B939844C OCB-rc5 (8 byte key) 0: , E7462C3C0C95A73E 1: C5, 83CB00E780937259 2: 1533, 022FF70566E0BA87 3: 57543B, AC4EF15FC83BDF2D 4: 01E4474B, BD817C06AC2141E0 5: 4CD7E850EE, 7BB6B3BDA5373422 6: 489C0CD1502A, 23DD4406F87EB164 7: 0CBAAE08E07EFF, 92569C958B722413 8: 073612F283F8A6E4, 1DD978D01CE8D1DF 9: CDE676B1A3AC98B00E, C033F099E2620668 10: AD3BC88EEEDA40A83685, 36DA44E13C0C8A4D 11: CA60E8B918F73E99986021, 45634CA0E43E4B13 12: 3B3CF82157ECEACAD8658EF5, E681F57616146CC7 13: EBC1A7068346EC1B7EB815A7DC, 2C806D2A909CCAF1 14: 97CDB3EF8276F1E7D6B6677DA2DB, 53F00B9A2E43DE08 15: 44169B3EDAD9506C51A6DA055EF9C2, 5BB6DD996130896B 16: 35EC29065B1FC640015B0F779E7A358A, 867EBD0E86823F09 OCB-rc6 (16 byte key) 0: , 27B9E3F544B8F567EEBF98ED5FD55C76 1: 92, 219FD2D74D7E3F21AA6C2A507C0A546B 2: BECF, 96A656A16FB3C4579E6955D592AECAE1 3: 4DDE09, 7D1882879B5D6FD8C151502BD8AB220A 4: 0D6B4FCC, E01FBD1ECA2A6A8DC6697A06AB12BDB0 5: E5E19C973B, E5A86AADF2F333D5DEDCE410688CC6A4 6: 90BA7D2A6965, 80523A2CAB2A7BB2E90B121DE80F46A9 7: 6FE258148EC8D0, B7254B11276A77C5F99FE5EC91D81F57 8: D887080095DF8817, F3FB938068A01EF89DE0F1226C544362 9: D9823313289D597614, A547764EF20BD4B4B303882B64FAF2C5 10: FF68942112CF01701E86, 94F3860D4438428EE296CEACB3EB67F5 11: FFD390D3E0B64F64D3192F, 99D2E424C67EBACCD4E2EB9A0CDB8CDD 12: 3162235748BDDECC84FC8C94, BDD400A58AF59100A731DD5B4386444E 13: D2A0EC8B1F20672289F7236C56, B245CF42644BDAC5F077143AF2A57BA7 14: 830929B2850E22F6C1BA2027248C, B6B522F7D6BA3CFFA92D093B383542FE 15: 2A5FCCCCF43F845AA77750D3BC6B1E, 53A0A0882C7844636900509921661FCA 16: 8480234796F9EAC313140CE014B0265C, 0656CA8D851B53FD5C1AAC303B264E43 17: F011A67C22F16A42CEA5E493CB766964AA, 830B8158B7A96224A53FB7F3A08CD128 18: F76274A730A608C2AB37497A049C3699882E, 4DC4DD4DF39D0E68D6169F9DC7F4A6D5 19: 7B38DD237DE552A72E4369A81C30AFEA5E5063, 01A62CBD30153702A5B29FB2A1683899 20: 58EB866F1FCB060ACC821D776AAC4AD9E87C326A, 25AFB8FC48605E1396EA8471F55C1294 21: A25F2C0FAD66B3580627498EC66C994B49C5445911, 0182A951D9A3DA53675612DE8EED1FB9 22: 8813977F092F07F251A1497C898967F3F98F5CB878CB, 80BC353E310880A83DD4DE4FE96AB6F0 23: 52DC8B76F5A6F78D51FB7DB51048E2663563335EC876A5, DC3689AA079C04C19D83646B272F9DEC 24: 965437D3FDF91784B63C73C8CD001BD9372167963DF36B89, 9FF84E2845E3C1E3E6711D1646B18F21 25: ADD40F674BD56FFC8F9B4047FAAD2471F0A48F4544C894F806, 9D684F74F9734F1C497E33D96A27E00C 26: 7B049B688839BC62785082397DEC7AA94B837D094AECA4B14571, EE711DF1C15B5C9E36B6E38B6F7152D2 27: DD4681F9C498A3CF69A9AC876E02BD9CDC4FB1F6798F772013B62D, C5A50676EFAA2A56CBDBE55CFED3050D 28: 471B5E89A1337E75E88AFBAACA1C011790F1657425483229E55C34EE, 20F73F2AC452FFEA423BE2EBDF33CFA1 29: 71812C83DE34DB329C8DCD98890AFB1F7719E890DAE5CEB7AC9668CAD0, 6FAA03E10C6FB67D425C683C6D85FD76 30: 4BC2DB33786CFD29B5CA5B804454169906138E90E29E7BE9197971027AF7, 75053C433EF5572A70C58EEC96F56C53 31: 5E3A0AB41264AB65365458ED3B7E6A25827E50075A9E347F1622ED0723E229, C8F1ECD19AD5FC970CF0D31BF46B0F2B 32: 2E48DEE4B379CD59F5367D17DC397C1BFD53B8C4CE46A8202518614076174EB6, EFCE758ECCB6BE875D16B7E03A498D31 OCB-safer+ (16 byte key) 0: , 88618DEF98FE588E23107E9A5D89C26B 1: 39, 2B01B202E751F957E331ECD1CEDE3456 2: 13CB, 17071E5AFD5D8CE953A73F49412BE8C4 3: DC4428, 4B0B1881C2540FF92E7DE63C479A7750 4: 120382B0, 0BB11D57B5BD9D846CF31033CD4CCB92 5: 97F332F95B, 335E0424D0A820F60DBB968B8B5AA057 6: 3C7AAE72037B, C8034C2C76C1CCD7C1B3F36DD8907E1D 7: 8A99E4A1B89B6D, 06A8165DFADF1EA5ABD89E574422DF7F 8: 676587065F0342B8, 93ADE63994DF2189079234DC204BF92B 9: 8EC394CBC6877B245A, 1A89F0AB0B44BC708EBD9DE489E2EEB8 10: 5FB5366E5CAE4DB72411, 5CA5881A5805D53ACA4904A5EEC01550 11: 72A1994028F09ED6A4E45C, 0FFC0052996CE45DF4A28F7A6E9CFEA6 12: 1D5EF20F52A9B72386D1A601, A697DF1179628DE1120D5E8D9F39DA6E 13: 79BD002AA59D74F125AD9E32DE, 2F02CB6F70BF57BBA0DF100DE503F633 14: 442C6F9016DF4C090056258756A9, 58C6FD3180B9B74459D70B5684BE3F4C 15: 4FC5543D9A892B44ED04EE8B25E232, B8B858B3D3EB4B26E867E429F88A56B4 16: F06E7503167C2210AB332259BAFD6AB4, 73CE2589D1DF34CA3DC2B14CC9FA6276 17: BCCC260BD4823B64090FB33E6816F9C330, 81ABBDC83B2544907840FEB5AF4479EC 18: 450C1105B76F960D1A5F33D7F9D37DAE20C3, C41DDC8980E88E3986D9C84857BBE1E7 19: C9F36EF3A990E0554EDB59E6788F8E9BF1DBC7, 90DD543E148D9A0B79A8B376C5509E09 20: 3666FEEA98A4FC434EDB7517E7FCEE2320C69BCB, 99F11B360DDB3A15C42110831CCBF21C 21: 126F39C19D1E0B87F1180F6589A75712B66209E2CE, B4D268FB8EF5C048CA9A35337D57828A 22: C1B6D14EE8B6D0A653BFCC295D5F94E6BCA09E181D8A, 4B4883B614D5CC412B53ED4203EA93B7 23: D1F2A10F1A9DAB738C61CD0EF66FE5F6D1DA95DC671128, 3F1EFDA55EFEF1A0B24708E132BC4D25 24: 9D457216C584F43DBA1DD55C54822A8B6A86D22DBFFA14D4, 53402970B128E98A5F0D62476A38F959 25: 012828614B5D67C9A1EE24A1EBCD322FE9C8BE0C3F20A53714, 2BFF288D90DBDC638084F80F3F7AADF3 26: B1904AECF599F6C74557475E409E75E646271DEDEC7A830260DB, BF119BDBDA27773E038B7067D2B0EECD 27: ED831771C4346FC19435354AE29F7A9436D6E8D4D42CFF26207DBD, C3F029FC8AE690E84FBD0EF806B801F3 28: E051B958601223FECEADF932A277BCF18C25025AE4DA791155B85035, EB75E56BE7856F1B5ED3D125C092D38A 29: AB3449537C5E22125BC32D483F74C3A3DBDBD5232839A85D300F65B4FD, 851B0FBABD080F783BDE4F47ADCD6D76 30: 4E68550837130652795A8C9D68530717D2B0AA5A17F3AEF92FFB502E46AC, 10E222706527A64E757EDE4B9EFC09DD 31: C2D7033DA7A1857D79497EA6C64779EB969046CCEE6C74E6592FEE6E7C94C4, 2015674ECA80AC9B67AE854E18A7D56E 32: 2F3F0374DDC24AE21F02D4DA74D46C71F0CD2269A68F32F7FAA0BAB64AA8E9BC, 737C8BA1677A8CE97D42FBB07530EE99 OCB-twofish (16 byte key) 0: , 2CD8EF22E5457C7FE4016B0FB82FD204 1: 64, EB7BB60E4932C0E97A7A5906BD044ACF 2: 3A59, E3D2024241666369BB542ED096F20C71 3: 67C038, 7E6F1EB3F2088F6416BB675DCAC0D484 4: BB36BF02, BDEEEF07EBB7A50A5201C8A2D72C0036 5: 6F06C0E293, C63557681D84ACCFFBFEE87D82EF1D3C 6: 2015F94CC5AA, EF1DEAD4134D2A1A47A20F26FAA3554D 7: A5F8CDD07964B0, 672B74D88C8AA7567C6AC4A896E0F6D1 8: 5EFC9D8C3B9E7F3F, DB9160C53AD429D4C22BC0E2E6C509C5 9: B62CB80F75594BC54F, 20020A798FF59F0472E750C796B5CC94 10: 970983B0F889760EEEF0, 360AE43CEBCC27755548D4984CEEA10C 11: 75C3A8CCB30A94CD57D1F8, 79820F3B1625E216B5BC1D1A22B198F9 12: 033DA41CCBFE3C6897230FCE, CFE3EDD11627270CD63916508B058B7A 13: 15358032F30043A66F49D3F76A, 98B8056A7991D5EF498E7C09DAC7B25D 14: 71FBA7D6C2C8DC4A0E2773766F26, 22BA0ECEF19532554335D8F1A1C7DEFC 15: BD761CD92C6F9FB651B38555CDFDC7, 8E3C7E1D8C4702B85C6FCD04184739E4 16: EB6D310E2B7F84C24872EC48BFAA6BD7, 12DE548D982A122716CEDF5B5D2176D9 17: 8DDF6CE25A67B409D3FB42A25C3AA7A842, 3E9FA2C6C65341A8E1101C15E1BBD936 18: 5563DFC29B750FBC647E427C5480B65846DB, 90881C6820901BD41F7B3C2DF529B8A9 19: 93343C1E9624321C2A0A155BA8B4E66FD92BE2, 71A641DDCD49825E10880D54BEF30E91 20: C256BCA0CF0ACCEEC1AA4B9372AF27D2C3C65AFC, 91D45C4DA49BBAD1809A11F4041C7D09 21: 3DE69FDB72C93518A3E317F7B26C425EE3DD42DA7E, 85E37B3E8EC3AF476DB7819D739D07D5 22: 676AC7885C7C8FBE9862242FCCC46C181440EE49AE59, BCDB42B53AC4FDDF9C3BF8849AB96EEC 23: D71B98B88F46CC47D90BB931564CDF0157F0ABCB5E6954, 289CD5799D9E49F36D70F67726A59610 24: 669C16DB9DC175200C08476832155DAA52F1F8969DF3B79A, 835B210EBBE5C9D34C2E052E1843C1F8 25: 2F39346E14A34BBED0491929CD9F1FB3CEC412C25AB703372A, DC4B42E8BA676BA100B87BEE328C5229 26: 1FD0F8BD0AC95E91881635EB0CF0E4FB099CBB214CE556422E2D, 898CEB3CA8FCA565CE5B01EF932FD391 27: 7FBD32B3D88B7E002BA6055585B5D0E1CC648315A81CFECA363CC8, 804820B1E3813D244164F778B9C2A8C8 28: 877A5F336A1D33AB94751A33E285C21666F0D8F103AC1187FC205372, AF9F0AC165EAFCEE8C2A831608F166B4 29: ECCA297705B0395E71B9E4263343D486B29207DA188C2F1BA626EDBF46, A05DC873406B236E4DDBC038DC4D2627 30: FF3BD8D4E1108E98FBAE2E28BC12819CD7956BC491C0B3A291FBEE739599, 68DFE58473BA2818A23095D1D6EC065C 31: F175230606040ADACEBAFE4D58BBD140B2D45E8BF7E5C904510B58E4B53D3F, DAF579E1A12481D39F4DCFB7C28794B1 32: 261388D491EF1CB92C261FD9B91CAD5B95440DE0A747144EB8697699F600801D, 749056EBEAF4F20CD8746AA8C8846C47 OCB-safer-k64 (8 byte key) 0: , 0EDD2A1AB692AA7A 1: 3E, 306F814F3C2C109E 2: 0593, 063D19B734C34715 3: CA72C6, DF6DAAFAD91BE697 4: 08924AEE, 15095FA49E789483 5: 359908A6CD, 16CB7F0741BA4091 6: 97F3BD820CF4, A59DB15B67B95EE8 7: 0A267201AC039E, B4FFC31DBCD8284A 8: 9F6ACD9705C9ECC5, 6B41A938F0B1CAEB 9: F355D5A937DD1582C2, 9D1F932E521CB955 10: ED39758CAF89E7932E48, 398EF517015F118F 11: D8ACF19363A0E0ADC9321B, F98B2A30217766AA 12: F8F54A8202B0F281ED610F33, 36EF7FA4A20E04B7 13: 0F8677DF64B5982DB6E2299140, 4DED2DA806834C81 14: 0C357A9DC321C93B3872881503B0, 7814D1C0C6A8900A 15: 10B6B1A261C3015A18110AD200A7B6, 9A814D6D2BAD850C 16: AA9EA9D1BA7818C0D2EBF23781A5467D, 236A24FC98826702 OCB-safer-sk64 (8 byte key) 0: , 76F16BDCE55B3E23 1: 63, F34B0B471F6F8F75 2: 8651, D7EFE17943D35193 3: D45504, 263224E50E7E9E75 4: 57B414C3, A553D6CABCA0F285 5: 4976E3B303, AC5E9969F739EBD9 6: F10AB8EB94E0, 8301FFE68848D46D 7: 6E954593AC427D, C1CF93BBC0F92644 8: F48F44441B898C0F, 698FFAED1A95E8E4 9: 1DC60156D62782E3D0, 6AFF0DCC65D4C933 10: 71920ADC8997CB8B3A72, 1C101C6A27CFBBBD 11: 890ED7492ED914AC20391B, F66DCD6205D945C6 12: 1B9FAB84A8748BAC187C7393, B450757FCAFAAD52 13: B4C89E1BB280DBC265E43ACE15, AE6BB3D2E6A371FF 14: 24B0C28944BDF22048E2E86644F5, 84E93E2191CEF17A 15: 8F2D5694D55EE235168AAA735943AF, 514252AEF2F2A2D9 16: 568B7E31FFDA726718E40397CFC8DCC6, 3C80BA7FCA9E419E OCB-safer-k128 (16 byte key) 0: , 4919F68F6BC44ABC 1: 65, C6785F7BE4DE54D3 2: E1B0, C197C93B63F58355 3: BB7247, DFE092EF8184443B 4: 38C2D022, 943FD999227C5596 5: D71E4FD0ED, 51040FE9A01EA901 6: C4B211EADC2A, 329429BE3366F22F 7: 426DEB3FC3A4BC, CF1C976F6A19CE88 8: A6F813C09CE84800, 98D9FF427B3BD571 9: 4D1A9948FD157814B4, 5A389FAEEB85B8C6 10: EC3EA142C3F07F5A9EEB, 31E26E13F032A48F 11: A75FB14365D1533CD3FBE7, 8EF01ACC568C0591 12: 891582B5853DD546FF3EA071, E013CFFE43219C21 13: 54CA848C49DCDEE076780F21F4, 298EFC7B4D6B6CFE 14: EA7611C69A60F1A2EF71D6A7762D, 7D9AA51CFCEC8101 15: B2D1A211BC524B965A084BB4B21710, 7B2AC0EEB5216892 16: 5E81F1BFA270E804A488C9BFAB75811D, A67F627CE1E37851 OCB-safer-sk128 (16 byte key) 0: , E523C6DBB3CA178D 1: 5E, B1CB7EBE5780DF98 2: F4D8, 8036235F2BE7A817 3: 4FE268, 123320394EAC24F6 4: A5BA02B4, B8276B5E027D45DA 5: 1571859CCC, 29406C5F2DF2CFC4 6: CA1E47447B95, 5D4FAF8FD5341791 7: 8710DB37022D96, E10040FEA9AEA9C2 8: 205990DC9A34DA3C, AE25CB49AA7A697B 9: 757AFCB3191DC811C3, AA8CADA8638D6118 10: 6994F8C153522361BB92, 1BCEE09E928EB18B 11: A86FA0CDD051BB60AF5AA8, 50A38F8E9889354D 12: 8D3FD3EB7FF2269AACFD24BA, CB51CF84CEFC45F0 13: 03D2A313925D9490FC5547F95F, A1FF9D72E11C420B 14: D77C0F0F600FE92F14F479FA457C, 1EBE1B4B9685EDFA 15: 0CAF0A8BEB864E26058C7DF8EBA0EB, 1B153DDAE807561F 16: 113D12716DFE0596A2F30C875EC6BA0E, C61F5AC0245154A6 OCB-rc2 (8 byte key) 0: , 1A073F25FF5690BE 1: F4, 3D3221E92E40F634 2: 2C76, C22C20B7231A0DB9 3: C647CB, 3E6348D996399629 4: 2021891A, 8EF76B24E9D55FDA 5: 1966CBCBBF, 310D24024D573E8D 6: 42C15AC9AAF0, 217E83C0CDE4F077 7: AB70F3F73DF0B6, 16AB2679D96A591B 8: B7C7DD845D7E76DD, F33065EA531545CA 9: 468CC16A37CF63EA73, 88879733F70AE3D3 10: 4F769E25A7346E22A932, 26E1A92FEDEE0597 11: 304A8B53B1CD24C6C27C17, 48B46E9F091B0B2E 12: 4E3DF867FEFF0B8E06D5FA70, 53BB48BFB8AB4750 13: 2BAB3F0A8C38A3BD3C49DBBA5A, 52303CADCBB6D312 14: 3D04A29924589AAEF93A29003EE7, 120EF9364B83748F 15: 486127A80E4EC599C461451CF1D79B, 2245D51599CAD629 16: AF8FB3FD2DB343F1AFF564FCBEA58785, 805BF441E660B0B0 OCB-des (8 byte key) 0: , 8A65BD7DE54082AD 1: A8, 3A83897CC8EC7CF6 2: 9256, DC66C39C7DD87D93 3: C145A0, 45967F3764F62F48 4: CD314BAB, EF38B0213259C3D4 5: 7074014741, 6748F4BAF06DD7BD 6: 9A874CAE01F1, E382DB7235624104 7: DFA0D86DC4CA84, 627ABB432E50455E 8: 685C2B2CBDD8D144, D166082E085063BA 9: 53515DAAC7F7B8CE1D, 6680B6C26E1B0994 10: 2B3967812BF4155A8D36, AFED7F38AFEFC543 11: F4E5AC3CC5913B8A7F35FB, 6181DD3C46A6C24F 12: F3EC89AD4235287D53715A81, 12CC354833FE5BD8 13: 66D554AC2CA85C079F051B8459, 097F31088CFBA239 14: 8746061C26D72771A7586949A3E4, 6CEF3565D0E45C6B 15: FB3BCC650B29F418930A467EA4FB73, 64D12723E100F08B 16: DE1C27E9B3C391AF5DF403291F2C084A, 6BADE4638AE46BE2 OCB-3des (24 byte key) 0: , 9CB7074F93CD37DD 1: 4D, 51541A838A154E0B 2: 5C77, 60E86F2F1F4C6F96 3: B3D2F0, 7D74A9E6A061457D 4: B3556075, EAF7A89A07453460 5: 1B61CE7230, F90D18620E1AB877 6: 3987FEC8D0D7, B5EF04DEE2E528F9 7: EBD0A7EBEEFF3B, A72CA24DD77A5DDA 8: 429FB38DDABF76D4, D0578484C37227C8 9: F8DF28BF5C4CD28B1B, 5E7C4DC8E694E3B4 10: 2BF436BBE063F7E830C2, 8D919637C973C71B 11: ED21656C8878319F1B7D29, 8813280C1277DF26 12: F45F90980D38EDF5D0FEC926, F9619341E273A31F 13: 52F2D3CACC294B141B35D73BBF, 7BBC3F1A0D38F61F 14: 2E6DA0FB55962F79B8E890E8DD8D, 8060799DCAB802E4 15: D6F9A6B2420174C499F9FE91178784, D3AAF969ED2F7215 16: 4F1CF285B8748C4F8F4D201C06B343CA, 203A2692C077F1B5 OCB-cast5 (8 byte key) 0: , 77E8002236021687 1: 52, D57DF1037B6A799D 2: 31C9, 7E781759B057D695 3: 5C8324, 56965D6CB2C97C0C 4: 17D99099, 7C52B5D09475F5D3 5: 400082C475, 3CA5CDB9B4A0FAE9 6: 4DF0E4000C24, DCFEE2C3384F9731 7: 10004C3CE32255, 0A6832F985F61658 8: FFA6EA76B346893C, 6202693B153254D6 9: E96378C94D246AB51C, 5B259FEB715B9159 10: A9BED2D59A92D3D9418A, 1E7E066C098A023D 11: 4EF144B7D4622BAD4DC840, 5DAB2C1D0DF56B08 12: 6DBCDF56E57CE47DD3D0CF44, 2A24F2A224368F55 13: 43241A0AD933635D7C8EAD47DC, 86B4B5AC22177F19 14: 920D6BDBE073F3C75052420C883D, 10943DBB23BD894D 15: B2C75DF024269833B039CAB19EC865, 84B7DBB425E45855 16: 6A9424B6A873BB7155C01DC87E23EC52, 82C5047655952B01 OCB-noekeon (16 byte key) 0: , 72751E743D0B7A07EFB23444F1492DDC 1: 61, 41BDE9478A47B2B612A23752B5A42915 2: F4EB, 90EF542D89F867CDFB1A0807F8AA3CC6 3: F5A59B, 1BED873B613096546D4C201347CC3858 4: F454610B, FB4035F28AA75221F599668ABBE21782 5: 382FC932F1, B40270E2084E8DCEB14C6603D080D7C2 6: 18F921441119, 47F1F889B307298150750E81E94AB360 7: EF01C70C9D1810, AE0439DBB3825F27CF846B43E4C3AA80 8: 89863EDCAD471C3A, F4E8AF73BFC4CB79AECBBB3774DAF8C2 9: A6F494092E066A70F6, F73D3B04752B7D913420C17E656C7F86 10: 342459682E0A8D53AF4F, 61E7CF14E9878E0726C64B1E8CA08BFF 11: 65E520D5A99825DE2441D1, 7A2AA740D786EB7015C61B31959E55D9 12: 2F96D0BB72E37DA202410302, 1A313242527FB522289094B9AFDB5F7B 13: 3E8F8A1FCEE3F866EC29128BA0, B8065DA2DABF04129E5AE28ECC11A15B 14: C2C15976D3C2499ACB9454878131, 372CAD486E104098EB1AA78A2922A1BE 15: 1F12CADABAEE80E448B7EDCB42F8FE, 86A38DE5363787F55B16462C684E08DC 16: 3B9ABB3304E75BF5B63E7F5B5A3F3980, 1FBD6B93E457B9779E2D12D78301EFA9 17: DC0CD805E43675A4317452E378AD48AC4C, 40AE4AFA4B3E580EFDB4AD0AF5BC4E4A 18: E9DD52EA7264C6C7BBA39B761B6E87B65687, 4061DD65D5E7FFFE8D3D4261494D4F8C 19: 80A9735CA1175072823828123413CCE772D521, D3378A12E79C49A37378DF527A460AB2 20: 09AD495AFFBF7CB8841262E7E5E8952878D4391A, C25D7A98C6F260B5FBCA3B8B5F7F33C1 21: 3925615707CC40C351D4A49794778545BC1F683175, 97622437A7208383A4A8D276D5551876 22: 5BB0D41ECD7BD2CF0B12A933255D95A3FE35E4C896BB, 4B8AD84EEA3156765A46AC19C68B6F88 23: 1EE71FE23CBFD5683AB1B391FC12B4E5952E4E6AA3D189, B0FD75996F28E071EB6C86BD7102BAA5 24: 0AA3D8C98AADEEE1867B13B017DD263BD16E960DA64FD071, 5204780963A62C2F4F7B3555BFF73836 25: 3A88B6F2AE321B226DA90B98E04A6A1589411BEDBE994632D5, 5638AF04EACF1EB986AC0702B4373A22 26: C2731661AC634A4DC0345F040DA7AEE507A3B9D019B5958543BA, 4C67D3FE37ABEE928B3BB812E7346823 27: D3E7651AA6DA035D05D599EFB806E8FD45177224593B5974758419, 5814E84258E1B9BD56A188AAE6F25138 28: 17818E7102B8C123230C5D64F18BE94C3159B85C8F7B64A7D4712CDA, FAA905B587A93DCF600BA8589A985432 29: BCA4335C6C29D978032C216114D39C01C6F161BF69D5A1CE55FBA8C575, BE24424A162E43A19755E2EFD274DBED 30: 24C33CEE022F8A633DE9DFD009F535B52BCF64F390D2375E5BED65B70D08, 138F21D54B6B7E34628397DCDE0D33BF 31: 838FE950C8165ADBBD6B61E9732F9A727CA7AE74376981382F0C531C331915, 0742E769CCBA2D1CAC7CAD4E0F012810 32: 57CD778DAD477271794FBF763662D97F8A10B17D70A69FDCB974FFE67E558519, 942C7D1C200C3845748F8131DF71AE26 OCB-skipjack (10 byte key) 0: , 90EAAB5131AEB43B 1: 2F, 6274B82063314006 2: DAF6, 6A6BCCE84FD4EF02 3: 5C2A88, C83D54C562A62852 4: B6E8FB5E, C44459EF41C8F296 5: 6C0888C119, 269DD7657BD0225F 6: 1FD9AD7ECCC3, 3CA090F46B107839 7: 1EDBFF8AE458A3, 440380BF9745132B 8: 04DBECC1F31F9F96, 2653620A4877B0E6 9: 908AE5648AF988A896, 00180FF33C1DD249 10: 53E63E0C297C1FC7859B, 36616209504C4230 11: 407BE16144187B4BEBD3A3, 4754B7DD4DB2927B 12: 9961D87CFEDDF9CC22F2C806, 5947FC41E6B9CEC9 13: 9F5254962E4D210ED8AC301252, 97A392BEAF9B3B04 14: 379FDA76ECCFDAAC10F67FBF624C, 1D895ABD932BD5EC 15: 1D5A7AD556FF3078284BB21A536DAA, 01FAE2F4936ED9D2 16: 4B8B71396924880CB33EA6EC6593F969, A0F4B1BE3B9B4CCE OCB-anubis (16 byte key) 0: , D22ACF880B297DB0513DFAF0D2DF57D9 1: 59, 210A179469D6568AB9470C760415574E 2: AFA5, 1223F9CD160ABE2F257164C6E5533C87 3: 969BEC, A57EC767543CA2ADBA4F5A7423ECA78A 4: CF8B31F1, 13B5BF9CD87CE15CE696F3AF1B082650 5: 9B22DF3852, 4937FDDA0AFDDA04CCD53CCBB0A82745 6: E11719B2F0F8, 6847931DBF0223F5CEF66AE3F4DFCF9B 7: 5A85E0F6DD2266, A1A0AF45A68A681CC396615FE1E1DFB5 8: 7F2DFCC65ED86976, 13614A3C6E0E08611D8DF8EE5B7D788F 9: 1DAF10DFA3F1D53E50, 673632B6DD553BAE90E9E6CC8CDE0FA5 10: AF74FD9671F9C0A9879C, B8B4DD448FE967207227B84E42126D90 11: 49421CED1167A882E26297, 21C8951A1761E4BD13BC85CBD14D30BD 12: BC0BC779B83F07D30CB340DA, FAABD25E14FFD8D468AD6616021F604C 13: 843D7E00F94E61AE950B9AA191, 08933ED5FBDCAF72F788393CD5422D0F 14: 296F15C383C511C36258F528E331, 8BFFADF5655C1864057D69A6706D1739 15: E31D2E80B2DBA4FBFAF52DB0513838, C4CD36821EC631CCBF1F258EE9931288 16: 87F319FE9A48E2D087EDF95563896EE5, 517960488E5A118D150A1573E76C290A 17: 9632B7DC1740BBE0A7AEEFD0F535B5AE8A, 0C24D0950873621D319A928862D3A6AC 18: 359431ED4B3AC537238CAC2F86126972D403, 4A0CED2F4BFA3355C17D6C5DF9FABFAA 19: E15B50172EE8DA9C552D448A5A48BEEAA2F11D, 8166B2A2D3A0745D1055F9F503FD6C03 20: 75842DDC0D5E3BD80225E4BFBD1298421244D7EF, BB957BB2582B67B63978BCFD7A949EDD 21: 3DD69162716D5F3E096E614991CAD7ED8E01F926B8, 40A954F31F5B0A2C5DD220ACED8D2B3E 22: 8A49AC14F59593D5399A10F9346E2FD36F47F64ED419, 4324D408CE7F86370495AF14FBD1A859 23: 6AA8FA353BCAAB4262211D75F13D27BE173526B8BC3CFC, BA3A27D79EC8ECBC5A78CB9FD095B766 24: B918192BB72CFEF980298EEE570460356A4BA1755576FEAA, EB341ECE0A070E769F498600EE4EBF77 25: BEFAE0B77E42A2FD18958D9E43202E8A338562AFF8317461B0, 444C1D6BDC026A01012BB2CEEAD89C2C 26: 07E86D49CFFE6FB08FDF44584033AF321447003D8AD3862C00C9, DA9355A79B224EF662DA65F19BE494A7 27: 911BB223AC6F6E54082FBFEDEC300D73FCAF715CCA35949212B372, 3496160A46A21DCDB5A4C179F159D860 28: ABB563FC803715F59AA35460E98470E2E94E4270455ACEBF4297641B, 899CFE1946A060DE620879B8A7464718 29: 47D98E83B5849CDE19B14ABCF9EA6CA9684AB49A3AB36BD14F328D808C, 6D76CD5EFF6D4AD3B67A56DF1EB42E05 30: C8BF0B71A95884FFB93D64C57E327A4754EC5A1EE26632CF8E0B6B26CBDE, 2B3BE785263B1A400E5893273AFD09AE 31: 9804D668CF2D75CA58C9671F65630E33909269B9511AF9119BE88EBB35F00C, 3DDA028B1A2339CA817DC8D9371E0FF8 32: F6E038A82A09BCD20BAAC7926B2296B78F9CBA9DD12C497C47EA08DBCD8CEA3A, A203FC1E68E21A52E72224891AC10EE2 OCB-khazad (16 byte key) 0: , BDEDFF7AA0070063 1: 00, 67E951582D66ED93 2: 5FED, 09DC8AEAD70673DE 3: 26A7CC, CE1436CE1E37D4B0 4: 3D2BD063, 574C24395F31511A 5: 597F1AFCB1, 6FBBE820C6F26CDB 6: 202DAE442DF6, 58CA6E5706C9852D 7: 7C20EDA18E9444, AABF0DA252A1BAAD 8: DEC02BF76DFD5B77, A0A97446B80EACB6 9: 5D7A42F73843F9200E, A1DD603372D124CB 10: 0D4710E454C19B68369E, CC78E9D7EAA6A39F 11: 126694191BF09A29DCF40E, 76C9B84FA3E8913F 12: A94EBB86BD325B4FA1942FA5, 613DE312DB1666F7 13: 4F9462386469EA0EFDC1BFAFE9, 5247244FD4BBAA6F 14: 4EB794DFCF3823BDC38FA5EF3B23, 0C12017B5E058398 15: D870479780CC5B3B13A7A39029A56F, 003D3FCD31D497B5 16: A47BF1218AC86A60F6002CE004AF5E50, B4EC27091D5DCD58 libtomcrypt-1.17/notes/ecc_tv.txt0000644000175100001440000076067210621351501015701 0ustar tomusersecc vectors. These are for kG for k=1,3,9,27,...,3**n until k > order of the curve outputs are triplets ECC-112 1, 9487239995A5EE76B55F9C2F098, A89CE5AF8724C0A23E0E0FF77500 3, CFC1E3447FC33E5C2A7D2BF71298, 5BD6AC32F0A9E7AAB6AF722C3CB7 9, 3F37CF870B918CD41EE58F58DF14, CEC3FA5A53FF5A372B583CE40F20 1B, D5E45D28A47A0819F3AA3018E58, B05DB66559FB78876CF830A6ADB4 51, 869FEFA6DE5F619CA54CA719554B, BB93E27BBC3FAD016BC369766F4A F3, BF1784B857F668E9459714D80D75, BEE55B564CB923C7018E855A2E05 2D9, 27067CAB2BC8C9201B1E8F1D54FE, 4A9BCE40D87B0C82EA66D645C931 88B, 4E9974D7B890442760FE4D05FB8E, 96BF4DDF0043AB6AB78E373DF010 19A1, 6CCE9122C482A8EDC2DE37142043, BC64E1D358F7293FC9B0C2B81D3A 4CE3, 48268EA8193D8BD0308108411368, 127A6D8E01399DD3F654F713B5AB E6A9, 46154FB1028BFD86CB29749C1E4C, C4FAD064CA84566739451DC6DEF 2B3FB, 11F16DF4A122B5C99B897921688D, C2CE146C26BB79F7CEA74A40665A 81BF1, 86023D4E9A40252B9943323AC6C2, 98BC7CFD540529771336414B0240 1853D3, 9FFAADE7C13872809428B28FFEF1, A3383F446BEBF57C93213A70B155 48FB79, B16EE42EDA484E3E32BFCD300A56, 8D0FEEE47DAAACAA9D8BCF69D2FF DAF26B, A5B330E8EA36077522FE1C6FB7C3, 88A84BB806A6F5A4BFF3E551AF00 290D741, 3C586EF3F731E651CA6002C7332F, D059BC68D7BDBD36CFC989CF7BF0 7B285C3, C2C91FA9E776ED3BA285AB5E107A, C93F41A8A39B2BACBE05E1F93428 17179149, 354AA3FE191A506359EFE3B9EBC0, 7BEDBBEDEC768086086C474FE9DC 4546B3DB, B0C34C7B4EC509BA7D128D7B880F, D176BF07B375EBE808FB57863382 CFD41B91, 6752AE66F3D3302EDE020EF64CF5, 7ABCCC45227CE3FBA57F036E5180 26F7C52B3, C292C0F2205C7DD85C160500C39F, 44704F5CE0FA803B44BA85BD4D26 74E74F819, 560A5FD4CBEB26EF2C4A81C3AB99, 9A685B6C7F8BD203764B64980068 15EB5EE84B, BFEC2498A5C662D7CE0EC0795D86, 81EFC44FFFBA1FE5C10EA50E805B 41C21CB8E1, 3EA8636EF746B6A7D42DA2E631DD, D23DB097D9F656B902E5BCAE5923 C546562AA3, 1189BF2ED2A10F7312F0DC6AC131, 67ACBE20F636DD4B5B342A3C76B9 24FD3027FE9, 288B4BBDC29EA71196301B8AFE99, 873196BCFCCAED2E2233525917E0 6EF79077FBB, C89009F3E7A92102202082A4BE35, 84DA334BD6DF4847B23A2204BA5E 14CE6B167F31, 1C3C9F6D15A9B366431579FB48CF, 9AFB81BE81FA8D1A6D067D7CC28 3E6B41437D93, D96F30DEFAE1F3445067E1BC5126, 5F94C2A388F7F4E7EC9B783DB0CC BB41C3CA78B9, 5E85D2777031FE74B02214A898E9, 56BDEB0542BC36CC3F6A269667EC 231C54B5F6A2B, 150A2E2416E3AC315569A3820D92, 4DF8FC1F8ACD06B742E611626199 6954FE21E3E81, 541D5FCCFC84A2C05E8A0145BFC2, 28BFDB73DCF4206857D022AF52FC 13BFEFA65ABB83, A990A2BC3B113A648B9E00D8E750, 3DEB9F5B4AA6913CAB843B8F2BB2 3B3FCEF3103289, 9A0FC99B826CC66625274DF01B38, A0570619D2047C864B90C0513575 B1BF6CD930979B, 3BABB8E3761B38E004DB334E568D, 169B474A41D6D0605A39D45C0CE7 2153E468B91C6D1, B12E873F58C89718B6DD46DA6C05, BDC3684AD8177FFF90861DEF3497 63FBAD3A2B55473, 6B9B195EA91798FDFEABACC415B7, 40A0693CFF52DE53819A9704DCA8 12BF307AE81FFD59, 8A0AB24E8E9795B8482FA478A71E, BCC991821FFB5738E066733633F3 383D9170B85FF80B, 730E403E64D699C16FACD6738B21, 919761D719C12BD2BF229193746A A8B8B452291FE821, 3333B47B85D23C6D8300F5229461, 48D6FECEA3083B9D31EC469C6B43 1FA2A1CF67B5FB863, C3F5AE461252F5B26EBC9DF1B5FA, 16DA58A6C565708C13823D1B2E58 5EE7E56E3721F2929, 6BAEED3E90E849B001207107F7B8, 5E1C7B8EB4B3E367A4CEAF4B73C6 11CB7B04AA565D7B7B, 3385AC6BBD490AFF201532286DBF, 7B027BFF07B56FDE6F0BCB37752A 3562710DFF03187271, 8146FD74592B1145492D39680AD8, 508AA9E106E7958CF011D8AA71E9 A0275329FD09495753, B0FE244CAEED9FAEC678BD22CCD2, C97B3257468A23C4F6E883737FBB 1E075F97DF71BDC05F9, 605DCAFF23DDF804CB1CE4FD847D, 68684076591F042B98CDF14148F0 5A161EC79E5539411EB, B65AA0ACF8A9C8E99A3F64930DF1, 34613D915630023826CAE908918C 10E425C56DAFFABC35C1, 16CFD49EE4D4850F1689FAB0041C, B50DD3663AFA67A306702BB0582E 32AC7150490FF034A143, 4E0EBC80756B99D91663DB7EE498, 6A22D944B1BAECE8B2EAD6AF3F3E 980553F0DB2FD09DE3C9, 603221615965C9EC9E587C34303D, DCB1EE7A0C41E65C08CA8D78983 1C80FFBD2918F71D9AB5B, AB82F4270F8C35C774344595F48B, 3B4007030E1D65C6F8544508F5F8 5582FF377B4AE558D0211, BAADF5F7E998465DBFEC5A7A4847, 1282C981EA4D0B8E7C77DE905D5B 10088FDA671E0B00A70633, 6D60A5CD3CA86F79C566F81AE66C, 22587D260CD8D45DAD2E5CE9C2EB 3019AF8F355A2101F51299, 6805F4FC0B350109728B3F56BC41, 63A9870300ED7D0852DA7163A9CC 904D0EADA00E6305DF37CB, 183156FCD56D11B82CE4B689323E, AB6145C5F793442B022B76251767 1B0E72C08E02B29119DA761, CD59AC87B06C5D8B1EEB8C59B29A, C956728D4A8CF105F2F15B7F128A 512B5841AA0817B34D8F623, 90AA398DA812A180FE8F6C8CCC41, 9EB2C705EC011EC23345E6148DF3 F38208C4FE184719E8AE269, 2198735C806266C1C47C8AC08161, 5FD1A06C68BE0F8D08A8EE9A2C4E 2DA861A4EFA48D54DBA0A73B, 2F7E0DFD695A6FB3085C4F3E8C91, A51B8EC5C0C1989073E756666E03 88F924EECEEDA7FE92E1F5B1, 782D992A0601EF4DAFF89C133151, D52680F34F0E03B54F76E4F49F52 19AEB6ECC6CC8F7FBB8A5E113, BB4C8DC0FE6FD008C8177F0D0C01, 57574AAB071C6338598333210100 4D0C24C65465AE7F329F1A339, A12F5BBFD3757AD57EBF19FA89AC, B5F12289CFBED9161324EA137009 E7246E52FD310B7D97DD4E9AB, 6FB82F9A01630129D70A2855DFFB, 32E0E55F5B39C0FD6042126860EA 2B56D4AF8F7932278C797EBD01, 37F034607B71FD0BE1F85ACB818E, 34CC63FF7DC6E54494BE65F82BD8 82047E0EAE6B9676A56C7C3703, 920ADE8D3AAF24783082AF163FA1, 13A02EC88C9AF237467FAECF980D 1860D7A2C0B42C363F04574A509, D2790CFD605F2D322D213092A58A, 1BD7AF8E6F3710909B7D400F3B51 492286E8421C84A2BD0D05DEF1B, 7F5E570FE30F7211AF05E245C3FC, 7EED46F891C350470AB27A1CD0F9 DB6794B8C6558DE83727119CD51, 7541506150DBB1D4C44CBBD8E025, C83F59D03595F97F6FAD1EF00D77 29236BE2A5300A9B8A57534D67F3, CA36DD2689FC281999437CC412E2, 577E04E806003AAC5A4E27D496B5 7B6A43A7EF901FD29F05F9E837D9, BA57BDF8F748B946F34F0CE6BA64, 6B9B5A5A98D4D1F0BBA56489B259 ECC-128 1, 161FF7528B899B2D0C28607CA52C5B86, CF5AC8395BAFEB13C02DA292DDED7A83 3, AD632F542942F23AA423B628A304B3B, 7AA67EE421C4E78851E4B4679BCDC41F 9, C732AE957882F6ADEEF94EF4FDFDB5A, 5F832D3A461B9BE0DAB9B6EFBDAAC16A 1B, C3E7FAA2B004CC66DD779D4D4CCC92A3, 898A5F77130726447D7C6A9FF7BB55CA 51, 882E79BE6E2A92F17FCC14EA8F4A004E, 81EFEB830764DE30840441087E0269A7 F3, FC8786E47911BEB448FC8614FF44F929, 5FE26C7837CAC0E72CC392ABC915BBE9 2D9, EB3002AF9DE4BCAB7F00CE22E61E638B, BA9555616D61C3DF55F940D9BB9407E6 88B, AA37332C95651AA27D6C14B1BDC4B9, E062A0B2F0CF02FD0859E2AD452E12CA 19A1, C5364D02273F5AE032FFE5C95BA33FB, 21359BF3D455E8E4FA1B6498CF03C667 4CE3, 565406637B339CD9E514048D0C1B6669, 33657B7FAE1D43ACB8A52F5D7F0D46F5 E6A9, F686D8593E675C596913DC20C39196AB, EC3DA164F561288B3BE727ABA99A5BA8 2B3FB, CBB20B834591ED538A32B71DE5AA1694, 84CC322D35B760E1422B85AB39500CC6 81BF1, 5768402750F948709BF083D3B43D7062, 7FCB8577F1466DD3B4ADDA5431E601C9 1853D3, C63158FF3359CE48ABFCC553F4D372B9, B6F020B6798EFB8AAF545D1B9CA83214 48FB79, C8B1549674C6B1BEEB462953869C1B89, 61EA95C1FBF57EED2FD7443E667D5EF8 DAF26B, 93D97715A671D51D5901C41772EC79DE, CBC8994EAF9C478A08B6D2E6F95CA1E9 290D741, 54C38EA59EDE54565FF3B44D0B805C51, 4DF1848B089AB3E49808DC6CFD682BC2 7B285C3, C51B5FB02D8FF4095E1AFB276A4B7636, E4403921DF02292B81A41CAAD9E2A686 17179149, 39AF1443D88EBAAFF645D16F7281728B, 79992D9CABB675B1A3067D7CB4C7D2 4546B3DB, 4B549361136416D85AEB0ED0FCEB3288, 7F1DAD94D1A72737286A3032B6D15639 CFD41B91, EC268299DEFC5CC003B593F8E9D9D496, F3744002B83FFFC6A545A7EAF0FEFF6A 26F7C52B3, 6710D002065B89EF2277E6CECA7DA7E6, AA5A24DCA5010A0A026F905D357CD35F 74E74F819, 909E50A61A9634AC70A1F36B5EEA62D6, 1EFA89A81D83CC9911CD5E9978878EED 15EB5EE84B, 76AD0DCDA97CE86AFA5578E05BE3EFC4, 7DAAD7E724AE5EB4B3C9D4D0FEB2D30E 41C21CB8E1, 58DB151CE74B0E1242065F332EBC50A2, 8E65CA6336413235C7C1AC14AE2A90C6 C546562AA3, 8440EBD3BCB98DBD710835CDA523B048, 3B0DA47B14728C63811054EC0F81E8F2 24FD3027FE9, CDD14651443254E413C608F12C61A7CC, 550272BFD6373BC4FC1831B37BD5ABE0 6EF79077FBB, 4C192607510F362548461733029B3ED5, B7979006BE6A92F246D7A099F769D35F 14CE6B167F31, DEAB8C0525BF41F5C7B0CBD67C2AAB50, AEBC99F2E54D009E5E2C320F60CAEB7 3E6B41437D93, 2FD0BB2280BC6C722FE5E80D12D195F, FCA37EAB062A9462C03CA98821509D09 BB41C3CA78B9, 8A3D3FCCFD5BBFC94D16B9829527ECC8, 7B9FD0406FD2080B8AD0CD3E1783991F 231C54B5F6A2B, 3810114B6C1FE3C3ACD5522AC46AAF97, EC32DBEE521BAA4F82EF77E0619F5C18 6954FE21E3E81, 405F7016C928A10BF66DA9B03044BB9F, D4698929696E3C37AC7AC9FBBFFA4472 13BFEFA65ABB83, D67FE4FDD2ECDC8BABAF926A6781F95B, D1D6DC7CCD9136ED7F1A317C32CB21FE 3B3FCEF3103289, 19891D1CCCB0D82DC07E55D8AFD84043, F94A2B60F3612F2F93F089F4C7A7D651 B1BF6CD930979B, 420D29204148F5C5AE3E01F851DA4999, CED9F97FFBBFD48DC47A73029CCDD177 2153E468B91C6D1, DAACDE05B55CBF0390619094A2008488, 56EA7F89E84711803150BDB0421763E7 63FBAD3A2B55473, 6E5E8684280C87E1C00AD9E3D61CDF6, 52874C99CB842257C0B0F379B8BAEC93 12BF307AE81FFD59, 202E8278E8C3F2C1AF84F5A0F76F2385, 6844CC669644B1AB8EE0FDFD9EB957FB 383D9170B85FF80B, 1076688ADD5CAA1B9DF02110172F23A3, E42D03AE9241C34F9835B58086176E24 A8B8B452291FE821, 44D019D2CCEAC749E03FED3C21604CFB, FCE1C2B98417DCA06124B3AE6BB791C0 1FA2A1CF67B5FB863, 127A50F7AB7BEB412F93D71A5CF60EE3, B48160DDAD09C097CB759E77DA097FEC 5EE7E56E3721F2929, B039E3D5C41FCCF03D679CA633E467BB, FD56EF249B88F9F8E94B55531DD41DBA 11CB7B04AA565D7B7B, 604E6D877AEE8F5F9269C930C127D7D8, BE50FC8BE50F050B06110DF717825357 3562710DFF03187271, E226E23826D762D6F35BC3B3BD3DB950, CFB94DB91B375BF813D12D85245388F7 A0275329FD09495753, 83501B5274973F7AAC7E3F79952B13EE, C990598F4525E33B280624A451CCAEA4 1E075F97DF71BDC05F9, DC941F53E570141D154C8A8F6BE9696D, 69E268FD63702FA8EEB92245A64173FD 5A161EC79E5539411EB, 95582E3BA2B92671D1C55968FBFFDADD, B2D2867D6E68519E4972E107222CC2 10E425C56DAFFABC35C1, 9E55507068B0AA334B61061B55A3FA4C, 76326CA07A608EAF2E44B2850BEEE7D 32AC7150490FF034A143, 645C473D1D29E12DEB103E33788AFC31, 6DBC857B8511CBEE87DBCEE51F1BAFFC 980553F0DB2FD09DE3C9, 972FD74F9090821E1BD8282DAA179367, 31594172934FC8099FE3243C7093A6E7 1C80FFBD2918F71D9AB5B, 72508D40467FA52802A5E3EAE46A17CB, 6CDBB3294FCC463054987835AA2CF69F 5582FF377B4AE558D0211, F44B0CE30AE8581BF0276E6154BAACF0, 9DEEF0EF522DEB481A57AA528A9EF389 10088FDA671E0B00A70633, 7CAD62F23B498A629F61C277B78F53DA, 8F848CA28D10758AF2620948FE7FB18D 3019AF8F355A2101F51299, 674D4F80D1E6E600660FE8C745C35137, 8113E9FEFEE67BFA1C5F84DA37B85AC4 904D0EADA00E6305DF37CB, A2E3298F5B8D5BA408FBD59A0BCF21E7, E19DEA06A7CB2513672EEC09747311A0 1B0E72C08E02B29119DA761, 82D4054101D260AF59BC6B34D9F7EF0, 44B2678278DB6E19D6D7F679C64E2A83 512B5841AA0817B34D8F623, 7FF216DEBB005D7D53E8FD83CC0B7399, E326E0E156FF26FE96EB3D139849C187 F38208C4FE184719E8AE269, 98A614DBD92CAD5D17A0A51BBA6651C, 6168C46592C07BAF794C2018483DF4E0 2DA861A4EFA48D54DBA0A73B, E15AE151CFFFF7C9BAB06C0C4E02189A, 4FD57A693728B5851B96176BE8A020CA 88F924EECEEDA7FE92E1F5B1, 626AD277498319CEAB580C3DAD611364, D635A54D313CA01AE564D15090E8DDEB 19AEB6ECC6CC8F7FBB8A5E113, FBB841D08716F39105F0C6A0E6B44D34, B23848958CE5573D5E61D77AE65AFBA5 4D0C24C65465AE7F329F1A339, ED6A4EC608872EDDF0DCCFAB98CAEED0, 380D8EB7DFD27459673189FD0985857C E7246E52FD310B7D97DD4E9AB, CD713A6FA65C4DECB2E919D81FA26EE3, 7C76DE743916BFD44823F21C97FE6F17 2B56D4AF8F7932278C797EBD01, 129F5F40B7015CA3182E56DB5BB94527, B547386942DC53B940ABB4D710C573B 82047E0EAE6B9676A56C7C3703, D61FE443E8768B4A7C75C51DFC79B3C1, 3D4EB1AA062D55772A54FA4082629402 1860D7A2C0B42C363F04574A509, B65B5424B49167FAF49F45D0F95E6BF5, F5B3477C391B4A0DF92B5F54A633225 492286E8421C84A2BD0D05DEF1B, 9DA44051B7F939BBD5A4D0156AB26975, 9E9A77EA27C4B6281A04C2E8B20C2440 DB6794B8C6558DE83727119CD51, 4C6F67B418FB5E4E354DCB622F55893, 9CE7E4249148A54EF9F75A23BFF7E163 29236BE2A5300A9B8A57534D67F3, 84FBDE461ABFB4C47D9F9EF607390113, 2DB9ED91647C0BB98985BFF0BC652C94 7B6A43A7EF901FD29F05F9E837D9, 111A425699A95CD6E6CFC8B2DE7982A8, DE3C25EB858FF46CFCD755C465EE0EA7 1723ECAF7CEB05F77DD11EDB8A78B, 418DDDF6455242DC8E3CF706F7357A31, 9874EFD9B781E72D6DEA50907E09F9F5 456BC60E76C111E679735C929F6A1, 24B1B158EB838752EB7EE82661942D6B, D630B06558D5C804203229D23CB97B1B D043522B644335B36C5A15B7DE3E3, AA62C51A16D74D572E05D72465A9EAE8, BA546EF43C8432DD112F6F3F33484FA6 270C9F6822CC9A11A450E41279ABA9, B17D5A63D3E50E0759FACE17139F4C9B, 59F0D096D23A72BCF3990DDDF9B135F 7525DE386865CE34ECF2AC376D02FB, C394A85DDDF3E8DF5A784CC2D94B87B7, 4B812AEC48DCD1A8856522862CE11FED 15F719AA939316A9EC6D804A64708F1, DA54D51C35FBF5D55CE16C5D3551A64F, B5B46E38541FA7D4E8B300F3ECF46299 41E54CFFBAB943FDC54880DF2D51AD3, D52F7E4371E70669479959E67426F091, AA001B1E7714D0E2B6DE83A839CF3083 C5AFE6FF302BCBF94FD9829D87F5079, 81C87D44A112676C129F7F0A8AB2FC2E, 734E4D8902E68F34655AD425DE9C4D8F 2510FB4FD908363EBEF8C87D897DF16B, 56CD2AEED77F0DB901402C32DFF4C325, 4AC2237E19DA29D0F281B2B4F18953A0 6F32F1EF8B18A2BC3CEA59789C79D441, 356212C5077F17620E6A781AF20CD65, D45C73449F6B5F7F271DBDCB09AE90C0 ECC-160 1, 4A96B5688EF573284664698968C38BB913CBFC82, 23A628553168947D59DCC912042351377AC5FB32 3, 7B76FF541EF363F2DF13DE1650BD48DAA958BC59, C915CA790D8C8877B55BE0079D12854FFE9F6F5A 9, 25393E48E2B7B5DF8142CF731E3F00664D93BBB, E75DE5DF76185C0D233F23A2E7B973A954694156 1B, A3E33AEB16B8B30F28BE00A54ED1D1278EF7E4C3, EA331BABC1F9C850CB6FE00C6E8D595A2F0A526A 51, 734F0EC134FA53E573BE31828ECDCFE969230F18, B39736E2FE9A766947CC8F236627E6551C74F1A3 F3, B5C70987F380C3A1482499B7E38DE108E49B1B7, DA72E3B069331A4CCCA6C6770C1B0E95BED8F3BB 2D9, A2DCEB63F2DA16B8ACD68B6EFFCC730BC767D400, 23D6DEFF4A0C085D623627D28E991EE25D5AE745 88B, A33D980E4D1E6EBDE888380645B1F81C28340F61, 47D8D18D8D640105CE735D0570D16B578F7552C4 19A1, BD52E5C229FA5763E2F048582672D779960952D4, 8EF1779DA5A8AEF223E0AEEC19DC315E19A3402C 4CE3, E7D4964676C3994C0619030152DD1E739166F2E7, 20E6BC678D4C3C0B05147A2DEB123CD659025CC7 E6A9, 5D0C33FE66FD1DA56FA31E0C1570286875C7A5C3, 917773615CA2E1DE0B6A7E14BC5EFA8AB86947FA 2B3FB, DC7520AE8A604FB5BAFCB40BAB185803F5012D89, 3ACB6E6F454DEEE809D36113FB941A319C004595 81BF1, 968191992AEA557635F337FA23CD88DA24DEBF4A, E3035E5E5AFFA7019DB899FAF65FAECD2757EA60 1853D3, 6D278B8467DA43BF84B72675DEC87ED91A6D4893, 2EB55C1C3AD1C98C553CC6B2CB98E6CEFC73C8B5 48FB79, 31E014D27430CE99E8F8932F36D9FE1321C9AC9, 4EC4FE2EF24BD4244F872AA286ED3BDC182EA410 DAF26B, 26919D4E3DE999CA8BFA6D00FA8E97C42FAEA85, 2DB843F7603367F4B1F07F6B45403A8F88324BC7 290D741, 4B7D7FE3FBF73AF19CA0EC13A7F22B8EA31CE7DB, F82DC14B5E53CC35E4275BF639DC21B49F24EBBA 7B285C3, F445903F825EEB5A3BAAD6DD5E7B319B0E9ABC2B, C5BAECCFDEA34B7032BDA2932DF4C9AC10CCB4B4 17179149, 4183B5F938FBF5F0DC8A95704096DB5931A5D627, 2D7E42949C7703BB0149FF95815F2DFAABB6A73E 4546B3DB, 67EECA2A2448A42FB50F6321F3AB4C06E3D10DA, D2DE1EFE80A29F460F7F7B2DFBDD93A3B87BC1FA CFD41B91, 306D5FF90BC57AE7B347E8938FBACD5E8C3CB4ED, 3877474EABC5B88D529EA9550A3EB445A4FE01F8 26F7C52B3, 30DE6E2A4370693BD9FA7D8A600EA5E6D75943C1, C288A48857FA2E8F677DEED44A1DC5B167708287 74E74F819, 71E796FF669023C714A0A5215D7DE249B96E4CBA, 1D5AE16000FFA8FC848552E930E9D00E2DCFC4CC 15EB5EE84B, F8A8781D8F0844BA0F689184FF56AFD53D876557, 840E775C494738E49D3AE5D0AB7BF6F25F50F385 41C21CB8E1, 48B5F313F23E31A72D61337E56203892FBD4AE68, BAC7A49986E06088A62FE1AC07CA2B67CBAFBEC7 C546562AA3, 73CB8D5A5C2941C636B5D7E9EC69C1015982154A, BCB81976F0CF4F9E55887EE4AE7CB5274944F28E 24FD3027FE9, BF90E02AFDA1EBCC34B02D695CB360B150EDE3E9, 7361D6BD46767F2605995A7448154541ABF3A996 6EF79077FBB, 93F4B601D818A4C11025779BAC80913BA0858801, C31A64DF2E600901674AA123A792168E17AFE90 14CE6B167F31, D7D857B44C53BBCB5C3C888E15FA2FB31451E28F, 2E0F00931FC5DCB0049FCC78BD2F4B2593FA8F6B 3E6B41437D93, A29B3FFB401FD76A45DCD8F5E87C2133C36FD1ED, 1883EE891DC09A914AB0B456D78876B89F455266 BB41C3CA78B9, 9FC8C86A7E9F2958C8CD957C89B414A759586954, A76C1576AED305C9491B7EC075D3C7767777C37A 231C54B5F6A2B, 6D348E7C4A319BB00DAA66615C113976AFDBF66, BC6DA4F9545617DD2F800E74B22142EBD2DA2FDA 6954FE21E3E81, DDC68F983A0D9EDA70E0B9E619D71A8F437B6276, 726642668979300161F48BA9696ABC855BB4B795 13BFEFA65ABB83, F638399A8904AF059B46A6B8B8B8CBDAF598D9C7, 6F267B6C287DF615F54915DC922EE4AE41126D93 3B3FCEF3103289, FD136674C5A9E5909FF90397A160EB2232983B44, 5143E198C0B9E3F70215E0AF841BC841F7F7F6B3 B1BF6CD930979B, 483832C21A3569E8F58AD8FCAEA84F7FC4559663, 5CDAA7FC128E85AC5BEFBD9D94AEAAC681F7AC2A 2153E468B91C6D1, 9918DECF01630EEAA5B226AB6AD577A4D9044F8D, F57AD0162569CB722C85DE7CF98466FF4AB0E09F 63FBAD3A2B55473, 56AEDFC9DE5293FA3FA625D6D8F5B54F95754160, 26D366028621815862EC3CDEDCA7BD09654605E2 12BF307AE81FFD59, D70777E9F2381429250279FFA09A27A1AA7EE866, FDF2FF1D369ED1003C1BB3AEE3F5F6DEAABC0E57 383D9170B85FF80B, BD3A19DDF16D9281B8F5A35E0458229481ABC2A, B35E3DE71303702A1AA8F9B4845E3B660EF3F4F7 A8B8B452291FE821, 9D7659C6B17D17DF5104DB2022BC059D85170F82, DEB9A9B784E14ECEA14116443C2FC6D46F723D 1FA2A1CF67B5FB863, C122BBC2034E30588D106375C098006F80DBAAFC, C31567A287D0CF0DF1904CDA7B239EDF4DEF83FD 5EE7E56E3721F2929, 1A1181829744B2D0DBAA23570C1450BDAE6A9388, 23E295A382E8CB2CF6822B7840734712427FBD60 11CB7B04AA565D7B7B, CCAC921924E4E2CE73B1328BB65D1BEB111D05F9, B6DCF138575699B24E65F8E4509DE3656AB670D 3562710DFF03187271, 46CAE3F8641148620DAC97B2269086E1034508CD, C466FB97D2B63A866079C4EBE5FB6147C4D41C84 A0275329FD09495753, C3D05A02C096E19F6B823D399F177F33B6661404, 19EB1CE2B123F8AF342A70DBA6BF1B0904DFA277 1E075F97DF71BDC05F9, 355F10F526DE3DB79A28C4AE4AB83C91F16DE2DA, D93A8F2292847BA20C54E9D4FE376BEC9BDBAED6 5A161EC79E5539411EB, 69E617B5E403AB15B10932003AA4C754FD585888, 6199B97EB0B634DF4B51987DE8730F7E364CC46B 10E425C56DAFFABC35C1, F230C76976E57CF10DCE884D10713CAF8B46955C, 80C1A15211B1F06919D56CC86360AFF3522AEBFF 32AC7150490FF034A143, 517ABE22245548B18CB7CA541852FB4682C92B54, 7AD5AD7E91F8A28D842F38C1277553D14C1D8EC4 980553F0DB2FD09DE3C9, 4AD778F7AF703238A93EAA761B305AC36008AAB9, 296C7D40D07C37D5190B9FDB55ABEB8363D598DE 1C80FFBD2918F71D9AB5B, 34589A4F974E2772B581F8B1F9292B4A3221A392, 95F634C03F3461C88C258B6C3496CDF57CA94855 5582FF377B4AE558D0211, BA1FC48E95584F0881F117C52E9B84D70ADB8CB2, E34B05161D00DE1B9235538B4E6402F8D62DD13E 10088FDA671E0B00A70633, 9EE3D749EA08A4DCF3A7AB51C15A8ECF8F41B016, 3A21E95620AAB5F8B829C494810E9226AA78060F 3019AF8F355A2101F51299, 86135777B50119CEA4C54A768B4D55C14B6EEAFE, E848B2F0072DB1E57BB2BB41FDBEEF6134101918 904D0EADA00E6305DF37CB, B3EF2035AF9A8FF6A1D541D0F1C6D56F25051C35, 72DF35F50E4540C80E07AD5D49E9F182CEF78AF5 1B0E72C08E02B29119DA761, 6F8E9E9456805DB0C58ECC6D596766A1A244F60B, 3EDCDBCFACA7A9D5A1319E8AD429A320DF4354C 512B5841AA0817B34D8F623, 93FC2F22165E8A22439C9AC49D0BECE1E2BB8716, 751314404EE1091A09864791FCC91780F94057EF F38208C4FE184719E8AE269, D341F5018D6AA45C31DEE5341D09E3E04814B56A, 7A3FD8CED82C7DCBD444C2E07691B1711C96C56E 2DA861A4EFA48D54DBA0A73B, 8960BD4CDA88561DA4155542FCE995FBDEEDDF23, 797312B7B2B5E29279A3273192E0A0E148BBCB8E 88F924EECEEDA7FE92E1F5B1, 59396BDCDA965D15F1FC0BF0222F0FC86B2C300D, D4283D03C78C717445AC36328C1A64693FC7BDB4 19AEB6ECC6CC8F7FBB8A5E113, 40A00776282D3C393BBC1DE7C9D1C1FBBDECF448, 512DF328AAFEE099E889CFB2C6FE9927005FD4EB 4D0C24C65465AE7F329F1A339, DE65CA9A566D89C6788655F1E450324D554B84DF, BF508E8B4FEA2B015E96C03FBE31268A6ED591AF E7246E52FD310B7D97DD4E9AB, 1F680491EF657A5FC246FBB202A0002923325733, 5553CC698246C9B786179BC5037C9FB01713814F 2B56D4AF8F7932278C797EBD01, F333344C9F419569DEA6CB228D8938CC69FB81E6, 5D193CC5C5A830A12AC4F6C91FA6253E91267B15 82047E0EAE6B9676A56C7C3703, FD6623768A2373B6BCC6D84569818D332E27B1EC, 72C39291859E0AD1217D23A34B662C4642113024 1860D7A2C0B42C363F04574A509, 95761AD2BD51DC587A418ACDA16076A4DC844E22, EE5D215DDF7FE9F6EA2774845041EDB2D61C6E85 492286E8421C84A2BD0D05DEF1B, 4A3C6077D76D09148B0611C8746EC56D0DEDC031, BCA3BC2177F774CF3B15B6E2128986FEB789322C DB6794B8C6558DE83727119CD51, 2A3C6AD8102997ABB372D9D9C97C4E4EC8BAFF96, E152C4D5C594088B278E2A935EFCABE1E7B1FD6C 29236BE2A5300A9B8A57534D67F3, AB097E5ACB02E4459030895C6E354484EDF251F1, E6FE3BC507244169DC7CAB7DE32B6AE92AA1A6BB 7B6A43A7EF901FD29F05F9E837D9, 129D7BE9C4EC8914B41A2C766D476879D6F76BE4, 587962443B8E295B1CB893E4ED281558A8C8EFBC 1723ECAF7CEB05F77DD11EDB8A78B, 1C96D21218F2851F453D52871557B037B3512E0A, F6B977791E1C83A34B3EDE67CAD7B751CD0C0E92 456BC60E76C111E679735C929F6A1, EFBF075A3FDCF11C6FC8C3EDAEAB2768A6D30731, 6B729DFA5729476544770F50F915D458B678341C D043522B644335B36C5A15B7DE3E3, 36BDD9FC45AB77B06CE2173B8B793427D108EF81, B96612AACFB4C44DF74B6E26B12038BFDB7AD69F 270C9F6822CC9A11A450E41279ABA9, FC4D15FEEC11A0EF59622B7D2895970552345A56, 1AB20573F123C149D487E3B1336993D3EF5AD1CC 7525DE386865CE34ECF2AC376D02FB, C4430A83572A1BDC98CB1E457781A43C35050B2A, C3DE096745E831E6CFC7EBB98B747602C96096CB 15F719AA939316A9EC6D804A64708F1, AD78F890515B436B7BAE6A083B2DD5E1C1F7B70E, 4E849C221A61E5D46DA23E3B2F74B8B8EE14E075 41E54CFFBAB943FDC54880DF2D51AD3, A53BB39DBE63EA5BB49D5D85991666C3490CAD02, 88479ED000F61E28450E1AF1E0F62F5AD1E3F905 C5AFE6FF302BCBF94FD9829D87F5079, A653F42589F8B26F03067FBA1D3F20082632CF0, 8625B86D912D177E139E4A0FEABB68DB28E8D84A 2510FB4FD908363EBEF8C87D897DF16B, 6A5F2C81A3BA8543858ECC97FBD98BB0990B851B, 20F3777694592F1FFFFC055B716919C1EA625385 6F32F1EF8B18A2BC3CEA59789C79D441, 1D7A2FAB41A5CF1DB3A235E261C5E3D2B4F92EF4, A1BBC0E673FEBD4D5F409907FBE404B41435395E 14D98D5CEA149E834B6BF0C69D56D7CC3, 2F885A7A345B99E03192A6EED5F969347DA805EC, 623B9D1A9A9012DCDB9BA68958A47ECF4C3CD0AA 3E8CA816BE3DDB89E243D253D80487649, ACA5A382C70ACF6199716A36FB9666F71F8DFF57, 62BA96DCDC4809E71C659228E6CA1FE80597B8AF BBA5F8443AB9929DA6CB76FB880D962DB, 6ECFE7E695F17D048C516C35458CA3967541651C, 1036FD8DB26A743B7DB499F42C4301F079E5D567 232F1E8CCB02CB7D8F46264F29828C2891, 44E0AF7A04FE3957C608146CF14B4275C3D7B666, 38A0714252B9B7D3A44EEAE50086DA06A9388999 698D5BA661086278ADD272ED7C87A479B3, 7088D973680A53E9479DBFFA467A2111BCD3BE0F, 7D5D05994DA529E8E004D671E788FF3BF888CD7C 13CA812F32319276A097758C87596ED6D19, E4A9C3225C1C2EB76CC58CDC6E894973D58D70DD, A7B92C8791C5E5BABAA17466564A7281F9222F36 3B5F838D9694B763E1C660A5960C4C8474B, 5739713DBD47167D3E32CD79B47A4A6E275AF078, 5DB73EE6DA8D4979FD94A281D633B43AECA6E9D B21E8AA8C3BE262BA55321F0C224E58D5E1, CF96DC40E4B69CD8C790FBEDC0BB25952C9DE5EC, 366881EDE370510AE1E82532147CD8E01752E8C5 2165B9FFA4B3A7282EFF965D2466EB0A81A3, CCB043B608DBC63760B564CA50654FB86817EFC5, A0CD38CE52DE2F283CD2A7CA558ED9BA01CB56F3 64312DFEEE1AF5788CFEC3176D34C11F84E9, 9FA21A21FAEFBFB6E12775F9949ABE24429110FA, EFAE412FD472D2A05ED3F46933B3EDCFB203E723 12C9389FCCA50E069A6FC4946479E435E8EBB, 5D876339E7170085A3A74848EA70B60B6588BD71, 65A7DA5C09F645BFE10CE52CD00F63B00350388D 385BA9DF65EF2A13CF4F4DBD2D6DACA1BAC31, C7EF4CF57F0BE40146B2D5F6B14443B6D96171E5, C7B0BF0558433FBE1018FA28A80B384596A6B9BE A912FD9E31CD7E3B6DEDE937884905E530493, 57863906F760EB7472FDBBAA7AB922EDE99A30CD, 470EEE35775797FD7D756306011784D4D1A94B3F 1FB38F8DA95687AB249C9BBA698DB11AF90DB9, 4EE1981D55A77FFFC3844C7DFB87FFEB33D2287F, 411D7A29479A565BEFC56F5FD2952DADBFE3B736 5F1AAEA8FC0397016DD5D32F3CA91350EB292B, DA706E4409447F41D36634A89DEADD450031EB07, 25E66A476688C499CE354500B69ABF7E54C83CAA 11D500BFAF40AC5044981798DB5FB39F2C17B81, 3B492E0378D8BAC27FCDAFEB53B6DB8E88A678EC, BA3A45947418E51A09B5FB16C808B4A256112E51 357F023F0DC204F0CDC846CA921F1ADD8447283, 201D6DB45EA1F22E7AFD6D1E226F028123EE9EC9, E69423D5D87FFBF101BA7C85CC3D2F63CD013BB1 A07D06BD29460ED26958D45FB65D50988CD5789, B23E082FEF3C87F6C431FA42CAB2E70E6B22165A, AAF1370FCD36AFC7EBB188EA3CAC36B6143C4324 1E17714377BD22C773C0A7D1F2317F1C9A68069B, 2A808829F1789876B2FDE344382EE0B8690C2B00, 3273FA8D18A239DC81FE8294352CD40A408FECA1 5A4653CA673768565B41F775D6947D55CF3813D1, DFA008B9187788078297F4A9FA02192C4FC0DAE2, ED0614DACFCF34F0125FDA6F9E7AFF7C5DCACCB6 ECC-192 1, 188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012, 7192B95FFC8DA78631011ED6B24CDD573F977A11E794811 3, 76E32A2557599E6EDCD283201FB2B9AADFD0D359CBB263DA, 782C37E372BA4520AA62E0FED121D49EF3B543660CFD05FD 9, 818A4D308B1CABB74E9E8F2BA8D27C9E1D9D375AB980388F, 1D1AA5E208D87CD7C292F7CBB457CDF30EA542176C8E739 1B, 1C0A558549162FE7C5D7274A730E9F58CE960BC9958D3288, 618AEECD7C6D796F0FA9BA3312490CDBFA0F3488F2FCD59A 51, 46AFF85827C9065133AD79BCF0372820C81880C645F2D928, 1B8911D44F06CFF14B4222E19BCBDA59194F970F34A103E2 F3, 1C142C97C6CDD5A87475E04FAE2E86708EDCAAA2F33D97D0, 67793727B60FBB2E8D4163C131D2D72F6774827109C02B69 2D9, 6157465770D08B8E53FB60AC57DD68F88160FD474B9B02B2, BCF67CF4003CDE95B507EAF4E07CD713C2F7A9FB3202B49C 88B, 767B00C09E0D583CEF4F301B727777673EAD242F2593697D, 7CF2510D4FF604A749FA3918DCB4840455CF7E68AB245A0E 19A1, 5A15B62CC74FBDEB931F1271CD38CF9F1D86131213248677, B69BCF78F9BA76C45601EF2486C166D04F34417804E913EC 4CE3, A51BC29BDFB0993FEDE91916D06D609FC744A813033B2F26, 6B0D669EAD4945315E92989358ABE363ACCA90FF09C25120 E6A9, FF714040AADDF96A94380ED63FDB4D4207E9C94664724C57, A8B1A8B19F339AC663919850BDDB8A43DEAA04C861735987 2B3FB, 35F80DA2E24E3523F1CF19B44A5C3B3A58C96AE146464293, 7E7B7C4AFFCDD781F641F9C2376E5E24121CCB2B9957901 81BF1, F29F6F84ACBF1EEE1A4C3CD4D6006E0EEB0AE0A9EE08EE2A, 43CB330E3143943CBFF1F0EB889258E12353A2777F61FD4B 1853D3, 2AADE7388043FFDD4D4ECE26ADF6C85E564AE7119AD601D, B0136CD55AF4DD76C090358324B2D4044FE78519AFD2627F 48FB79, ABFFB427AF19C1618934C4ACF80A73D30CDCB3F5647361B, 577058997D7AF23F88D039AE8D195E1CF20E94A9E55CFEBA DAF26B, E44F89F1FB04FDBC19DAD570D1EF3588EB47F799F3B31F40, 47509D6BF8F7A072255D4856B021543AB17DDE0F0EEA046B 290D741, 85E180BCF6BE779694A2C71D393AF8043A7A74F076778283, B0D254C1E67B7ED57C4847AEDE7F110FBEB337106517353F 7B285C3, F15B9270198F4ADBCFF3E3719F20F44E9C0786EBF5116BCF, EF12D95EFFE8FA9E4574B948CCB009C59B837B2065D4E754 17179149, 76D8028D35E2B6760E4270781E2CAF51310433B0A7A525C4, FC2969795EB4BBC23B402842C4BA723D361AC065966C4927 4546B3DB, 115569333F111A12BE5556453644F009567F4C7B40C5712A, 95776EFF47496BCE215E608F57E2731FAC2445666855BCED CFD41B91, 181B8097BA5677CB3A3C3BC977AEDB8E861DC7374D5C9D82, F95ECBD7B0952380C21A214F75A69DFC486F2316A7A2BACA 26F7C52B3, B43A147C979080FDC8360039F4985EA31F7CE7D049478450, FB4687DD7D77359C497216FAE50F953C38288FAF271BDA68 74E74F819, F16191FD000EDFC6F3D0E9C75DDC56ECC0255BD0874B8B40, E6FF81A430405BF3111AE21B28679D3FE6BCE570EBB3ED6F 15EB5EE84B, D88192214F0A25FABAD10EC7A4F7FE0EA6CD328D0E81784F, E8D10332314077FF28378C0D404FDAEB3508BF11C025DB9C 41C21CB8E1, D797A077FC44D1A5398FBCF648FE3CF921EDC23A59C6AA57, 197EBA01F6EBF058D4E19BBCF358EBA512DD4C403095F96A C546562AA3, 1EA9FE83CD362F5A675DAE672D1229D37FBD501C0DEA7021, 5EB6874C8853B0FD10662F3B25FA9A21F4A66315E790FB8 24FD3027FE9, 1E3628D25F1AF3C515C0758723BBE2D111AF7E4779DF425F, F991DAA7AC2BEAA1515D823283B67D9FB1B91C1E043B27EF 6EF79077FBB, 6C3F8E8C135BC46234D8B85AB9BA94A9ED2E7FF9B8D9D84D, 1710D8B22CA3F572CCC4F3F7D29B4508FD0EB49737ECFB01 14CE6B167F31, A1DD7DC14AD895FC0E6DE95019379A4FCA488996903320CA, 34CB85A2D98AAA0FEC199A6DC1F5BD239F9E3AD45D5F9C63 3E6B41437D93, 8A29236CFDDED1F057141CDB01E2042A36C8584BD1F7EBB1, 41DFA388743EB780842CFA8E90360E21BC957EF0B0943AD5 BB41C3CA78B9, F0D31E7BA6299CF97D49459746F376976F3F69A254FA430B, 816B3BE3CDA212DCA47942E839460AF55BB368CF82443FD4 231C54B5F6A2B, B61E3CE7469FB46A5A75E6F369319E86B3EDFDC15FD71139, 6E4A91ACFD67BEC34120A13329B9B94E9334B440F5BF929B 6954FE21E3E81, 1075CC5D277AED7E0603C852EEEEFE98B0111577047C239D, 82FD41C0DBB75F8698F96262EB53EF6C6D166AF078519E12 13BFEFA65ABB83, C5DCEF887D8AB1FEF1DDB523F4F13B3B9C6692FC8FD8FCA8, 108EBDDDC411685D240CCB72D9046F60388C45D4B380ED7D 3B3FCEF3103289, 1214A2F9361F8F7E450D576A8C2316431EDCE1E0B40A180B, C47699ACD4F1B58348F5AC484B98A91ACD3097E1DD88C01B B1BF6CD930979B, D590D2A3B6DC021E4E32CDC319EA48CB68FA7E953409C71, C06ECB0FD72F556006DD810E84E0DD1B1209198F013A86D5 2153E468B91C6D1, 7DF6201144ACD2F93FB748724CD4E4E6F35FDC8C94CB203B, E9A12B853E94CB76FC0BEBA53461441B71C53B5C1061CC07 63FBAD3A2B55473, 760FCF9057B0FEA16B60C8D3F754D9E2C18B973ABC701BC1, 92BFBA6E586583F61FCFF086CBB54AA070C273D847576A81 12BF307AE81FFD59, E462BAC637E80D709FC2026CA864349722CFFEB2A8C14034, D6FC9AD4D0D9E3A80900DA823A02D01C20C05CD208217CB3 383D9170B85FF80B, 2A20664813D23476502D4C405D7E073570F631E4E2527E87, 97F0E060BAAB21323695BEE672AE1A15D7B496176B1F7C25 A8B8B452291FE821, 8A9FE5C70C8E1B73C0E2A3E5ACE91741F248E36F5E9809ED, 70051C26F338D61010A95921117E6F0B6E9BF0F9CED42EC5 1FA2A1CF67B5FB863, 22834749F02FBB2D964358D12A7133DBDA532549F1745F35, 673546F13C6994B970C0376F96BD0051D19EB0D7A0CF09D6 5EE7E56E3721F2929, 4A31DBA1B4EA6F5F5A166B73CF7E83BFBECBCD2CB22D0A65, 89E8AA2325C986557C262BDB2BE805222875242E276D7E6B 11CB7B04AA565D7B7B, 4FE579CA87A004AD36CEA14292F91BB85A6F5964760433EF, D381D212DAED188E721AFB8354CE0D1B7015BA8D8E8244E2 3562710DFF03187271, B804A5F404DC163EED2D2E571F5FB77F35AA8B078586AE73, A6071F8E16F8C2FC4EC87B3FB20442F4E1A3738E91304568 A0275329FD09495753, C7F9292AD9FA97DA3AFAACDA2B6D0B9D83E7116F0B2A2B76, C2499ED4938444F34F1D89136C7153A683A84F048A6DB9DC 1E075F97DF71BDC05F9, A5F5374B2F7E07EB06562A1BD3F8F53140F3D43472D1DE8, 5E94BDDB00BE4723D64F58D1C76A5916EE79B9BC08E65754 5A161EC79E5539411EB, 54665882C939F6938E006794AB3F2EA50148C77F2F3E09A6, DC19F80B200FB36AA3933E7DD2B8BDCD9DEFBFA094C068AE 10E425C56DAFFABC35C1, 6D32C477B9B88E4A2984996C8F586E4CE670ABA7F9317BB7, 47B1FAE5A733CC165666A8E1B1B3C9D36520CA82978B3C4A 32AC7150490FF034A143, 704962F0155A1907D04C921D773827724C1550C9B321E07F, D65D2FDD10F3569EBE0F71CADCED6A08C30C79EC221FE703 980553F0DB2FD09DE3C9, DD2B09ABEC03C2B6B79C59527BC2506AE8ACE5F5BDF8C9C4, A0F0FA28A86BF4A8EEDC13A4071CA4799E3ED3B7A551FAE4 1C80FFBD2918F71D9AB5B, DD8D44CE64115353C51BBFE970E1B7F8BEC0A56815641AD9, A1678B2557AF4039AD5FF55592F1B62D16C493144650588C 5582FF377B4AE558D0211, 9F49FC1430F451B4239C265C6FDED93866D82DF30233296A, C5B07F840EB2F171CF4A6786473096BD94070F3D8F9FD80B 10088FDA671E0B00A70633, C3F8B7CF57A281463239C03C51AEC841435FE7D43F1E241A, D9474297A32209AC6577ACDBE59482971D25C811A83524A5 3019AF8F355A2101F51299, 2F89FF42A3477AF0099EB8D20BFBF246A42BCE28C041BA10, A3958623E8ACDB16662C3F5EAFB757CB912F0E55AF480A6E 904D0EADA00E6305DF37CB, DE9877B73B97DAC40E06560B53557C093F46E2A9FAA70020, B7868444CE638BEEA8C062AF8FDC3D42BA3ED8D384368196 1B0E72C08E02B29119DA761, 87411F357505BE61E8A2EC83A1C73D414893421E7942A63C, A2F641BA92F59BC2FD0051EC789DC6A22D1B790431CD53A1 512B5841AA0817B34D8F623, 33EA40EBD183D3CA2E967763711F5EAAC247A83D10F4D8CD, B501868B4942D1DEB3F4DBB18C938BAAEA097B5DC8DCAF06 F38208C4FE184719E8AE269, 9758347531DE82D0487EA03FE4245747640FA7CC1089C27C, 5F37E601C56ED8B600CC9D1B57B909D21A12EADEB917636A 2DA861A4EFA48D54DBA0A73B, 63D7007A3B25A362767A40411B2A0394AACDBF13A7EEDF3D, A721D1395745E4031DF177B535C09FC94756C0FDA0AE6631 88F924EECEEDA7FE92E1F5B1, 6C8A8C2394FF380A228917B08B111D76A2A4E9EFD7E4E66E, 2EA61738C24D33C2789A186A5CC15245798CBC62F5A74766 19AEB6ECC6CC8F7FBB8A5E113, 8DF315820BD24BD6F20122ECCA03EC60783576FF1931D06B, FFA2AC7836B24C3C2EEBB76F24B5A78CE8BDC8144545EB9C 4D0C24C65465AE7F329F1A339, 3CBCE069C8034D233B9C2ADE3C8F3F26D6004D6851BE36EE, F1CCE453C42F608ED79ECBE9DFF05E12D7843DAC2AF0165E E7246E52FD310B7D97DD4E9AB, BC6196B8E020F764A84E9A7032B2AC38460015DFC3EAC411, 924EB9460BD723CB9ED2DD3E894CB24CC412B0CAE2AF8886 2B56D4AF8F7932278C797EBD01, 1F9E734CD4742FA8537DB9BBD53A9EEA94D4CD47BCE92196, 2F2FAE55F79ACBE6223AACB30255161AC9B99F3A77087416 82047E0EAE6B9676A56C7C3703, 6A00F547D2CA07929AD0382EC1CF2DE4240CF04E2ADB958, 9F6A1D2003032B61F65ABA33469464AEE22FFE40BD214EBE 1860D7A2C0B42C363F04574A509, 8607DE682EF40AB177F96540C70830855C1D8A3BB3340364, BC5B59F9E8C983ED333DC75231223668C20CD7D818FE09B1 492286E8421C84A2BD0D05DEF1B, E40E7B5E5CB42241CC23170739DE4978F0C1FAA44C3B0A66, CAEEAA3DE08BDF32427CDDF8FEBFC42C2555FE38702227A7 DB6794B8C6558DE83727119CD51, B72BF024B3D76D808D554D4A65334D4FCE8D5010D822C0EA, 3504AC222FE822E481A27F9C16EB584FCB390CAD0FEBB46B 29236BE2A5300A9B8A57534D67F3, 886AEF669BC564617B66F6057D040E60A3AAC8ADFBC5883, 765D1317E730E046228634241626AD17A004D0DEB3E6B8E9 7B6A43A7EF901FD29F05F9E837D9, 919F5CCE4A889BAA1DEB916BBAB5C95163935DC7D78B35B7, 2AE6C9F8C027135C88DFB1223CF7B9E198D635D7BC8FCA2B 1723ECAF7CEB05F77DD11EDB8A78B, 97564D4FAC349DEAEB4AD24D9C2565CACA598BAD07981E2B, 17621261F147574DC2D663D58A81011CB42C5787424FA570 456BC60E76C111E679735C929F6A1, 40677079B500B3DDEAA6B0D519C51CC99954B80DEFB416F4, 7A80B080F44C4F71A01CFFC33622E3DFC98656B3A5CF701F D043522B644335B36C5A15B7DE3E3, 78EA536B23938AF681E0DA7B216815C3A9D62AF7CA76CB8E, 4A44318E21F72E0CF092DDB80A9A145D423505C775330BF2 270C9F6822CC9A11A450E41279ABA9, 1E4296F8BBBF2BA1416B131712D0D0323CD566D288617A38, C4E33977F7CE998528ABE9899BEA3312FAD976A9D07FDBC1 7525DE386865CE34ECF2AC376D02FB, 5D37F277984FA15FB5E47EF1B4AB48DA0025E01C70BCF192, 53758437DD9F6CE7214ED99806350E5822C1C022371C986 15F719AA939316A9EC6D804A64708F1, 45F0D931BE0BECFA19EE77C69F2D6EE2BFD46A3ABA9E7860, 2DD205C736CF8D474508D1D9FEDBAA9B398124C8963AC9AF 41E54CFFBAB943FDC54880DF2D51AD3, C4148ED33A11E3B919F678D0F6DF2E5F19E888252337502, 6BBB5EF5AF0688950B4E9A05B69F3AB4449724CFF38B6D17 C5AFE6FF302BCBF94FD9829D87F5079, 1F5855C573EA7C76D6E6B34539885B1CADF69A26C4F4D42, 25EC84477867183873938999C5445871630DC9EAC9331B7C 2510FB4FD908363EBEF8C87D897DF16B, 2275194E1FF9F071D0B9D4DAA0C859E9EFAB5DD0131B86EF, CEBA1E77F349F3A9E4E9CD42689FB29E0633174627A9892E 6F32F1EF8B18A2BC3CEA59789C79D441, A2CE1B722AEDD1C545E1FB6E6A3018C2EDCAA5DB7D4B523C, 759070FC0CF663F1D84E885952FD9681898ADCDA47D3DA88 14D98D5CEA149E834B6BF0C69D56D7CC3, A7BF44284B9EF496941F31B6442EF663627427C9DE50AA10, 993CA2E4B263BAABDBB58D27F3E3C72BC71647D9EC3D0ABE 3E8CA816BE3DDB89E243D253D80487649, 3DB825FC33496FEBCA37FFAF958DBEB50EB870F7193D2BB, D59884A0FA78538B678628374DDA23ED6EEF75A863E3F53A BBA5F8443AB9929DA6CB76FB880D962DB, 8D6011151337C570552757A22E3A302FCB7BC3D61DF6061E, C455C35E4A071CA2715C80121BE43DAEF519B5D1B768B849 232F1E8CCB02CB7D8F46264F29828C2891, 1371514D33D4256E50425500708416E4F8706EE52F803A90, 892FC707DCE3352CE8ED23ECE989825FDEB32E79C049C2D3 698D5BA661086278ADD272ED7C87A479B3, B940EA3133CBF5A3E287F71ED5DEF98FB931BC0965BB6B36, D272093C69411C10DA893316831A3DD11D76C441AE0E38D9 13CA812F32319276A097758C87596ED6D19, C1BF61C85F79B24A7B30240D42A70BE0BE5E7DE6A0563471, DB49E02EC0BB0401BD566B072013552266F518DF05987BE5 3B5F838D9694B763E1C660A5960C4C8474B, C0ED93B53A193A35D1794337F74C4DD58D8BA88678929E68, 7DE86FD1C4693DC901A7890DECB307F00EF432CD17A9669B B21E8AA8C3BE262BA55321F0C224E58D5E1, 71E6E0470A2A76566ACFD8C69786213DFC50FF8449FA9D00, 6FF8607F003A90FB76840D8CA367B4612F8A555BA2C7D07B 2165B9FFA4B3A7282EFF965D2466EB0A81A3, 162376F28E53249611556C1ADD58DD15AA66451D49BDB18C, 9A246765E6CA5B19BF853332B39FEC421739DB52703B6513 64312DFEEE1AF5788CFEC3176D34C11F84E9, 7F3355A10C96EE64DE95CB40F2C16C6A8BD9AB19F243EFAC, E25ED7D4BF395ACE15CA7AD9CCEF8F82C3B8680B40C5AD8B 12C9389FCCA50E069A6FC4946479E435E8EBB, 65801BF19C26F27BE259A68033096C0F21CB908C2BE431F7, 1CBF7FD180A1FA7673BB20DDD3DEAFDD224992B000DAE969 385BA9DF65EF2A13CF4F4DBD2D6DACA1BAC31, 2434447503C73CBE250329A649A71BF7FB9235B4D7DB5AAE, 4F1E6B3691512BDFD642B837035EC68B3DDAD08306D0E7BC A912FD9E31CD7E3B6DEDE937884905E530493, ABE1D7C9D4446CAD96B696E129225ABAE79BFF43CBFF4EAF, A07CD0DA6177938D334381A6CAD4FE2A54189E157DBFB657 1FB38F8DA95687AB249C9BBA698DB11AF90DB9, 45B3A8DF8C53006D2181D52E578502906DCF166E53B2E490, A4C15F301AD5F5B61F603F93230CC3A817C6DC86AB842DBD 5F1AAEA8FC0397016DD5D32F3CA91350EB292B, CA66D4AE5E37980E54A32EC981AD6FB8F130A811DFA9F283, 2E516FD1176602D650B7687449E87127583E18F8E8AD6B67 11D500BFAF40AC5044981798DB5FB39F2C17B81, 673AE0961D0B12B6526E82EBF3244BD9C392B92D52ADD0B8, 56F605CEAE8E71F28DFDD4CBAC06CAEDC3EFD0F4FF0C7D7B 357F023F0DC204F0CDC846CA921F1ADD8447283, 2BB6D5B9E52B42C17E34205A523FB4596E83B34E653A1B20, A1F89B4682D8A6F1D07F8CA40A456962BFFE0D0322EA5BA1 A07D06BD29460ED26958D45FB65D50988CD5789, 5C16C7F871FAA2972D6C00EECCE62B9951CCA91CDD44C978, 53379BC875B840940BE2F0BD83C3BE3A4F73898B2D243D72 1E17714377BD22C773C0A7D1F2317F1C9A68069B, 985E2871102C0F5BFA09E1D16F677E1076123BEA019DFF0F, 3B0EE452994A31EE10E8B76D4F1E5AFBFEBADDA52BFE5238 5A4653CA673768565B41F775D6947D55CF3813D1, 85A95B40A2408C88065A6B06A2C70C0F3B1016B850B03FA4, E123762ED9FAADDBD571D4D9D55BAC21635B8F23432CCDF7 10ED2FB5F35A6390311C5E66183BD78016DA83B73, EE9BCE88E1300A048C6EE04BC7C4D6B14F9C46C4E5E0DC5C, 426DD5BCBADB2B5831B05AE0EE36A4357A9CCB975BE6D97F 32C78F21DA0F2AB093551B3248B38680448F8B259, C8F67DBFA81A917ADE5BC7C680466B6C59A0614CE37CC492, BCBC3245DE309B260381C29A51A08FD7AA7A897A57F60C43 9856AD658E2D8011B9FF5196DA1A9380CDAEA170B, 102F282C7749464D0B5BAFE7862ADB176CF528959E6FF16, 4471B34D0C427D1B2E6BB4D1D1E7019B19FB29AD3508FD55 1C9040830AA8880352DFDF4C48E4FBA82690BE4521, A9D88CECC8F30E7367B1826614750C5E62DAC63B4EC69F65, 1DD5CE403B28F8E828AD61FBDE8DDB29AB799E322EE5B12C 55B0C1891FF99809F89F9DE4DAAEF2F873B23ACF63, BBD9BD8DB52BC779DED4D10D87F9A51D6F688EF2AB24DA9D, 3B81E803B4947D886C31DE671C257B8D4AAB9703B1425FA7 10112449B5FECC81DE9DED9AE900CD8E95B16B06E29, 4D17C614554EF49C3ECA4174BA73E5118E5E60AA0A77C63, 7B6297E167ECBFA4B7BD7FEA88BCED0D846FEE03DD3DCE7B 30336CDD21FC65859BD9C8D0BB0268ABC1144114A7B, 14D38246CEFA8D9795894008CA0C0D126F83C78C83DC92BE, 36411B77CECDAE847590B5677F59939973BE6FF2F64A9042 909A469765F53090D38D5A7231073A03433CC33DF71, BF7AC1EB3E7190BDE4D71ED57DBD52DE03050EFB40CB5EAA, 8FCAFA78361658F188F43142956A156857563AFE6C1EC45 1B1CED3C631DF91B27AA80F569315AE09C9B649B9E53, F8D28C0DCAE91C461C70A234D69A2538F29308A11DEC6B7E, 81F11659C6F8F433DAF384B0677656D43AA1043655DD8E5D 5156C7B52959EB5176FF82E03B9410A1D5D22DD2DAF9, F730589659E8FEE715F0A3398A547498C858172E776C9E33, 7725C13706670A811F93D5FB0FC7BEDF0D439335D2FBA1B6 F404571F7C0DC1F464FE88A0B2BC31E58176897890EB, 3B666DA46C5BB9CF8D8444366602DC2C793281C9FFA16E2A, 933B3919778A797358D4F485D911ED7B8C8C3A3C9B782CB9 2DC0D055E742945DD2EFB99E2183495B084639C69B2C1, 251F31E3F7B52DD8BD58E5D15E5AE490923752672A578D78, B5D6D075DCD78583BE68D8F37C3A4E6BA38C478BEE16E90D 89427101B5C7BD1978CF2CDA6489DC1118D2AD53D1843, EE4089782BEEEA54B8CE2A2165A343D8D1D111F8BEEA6F7A, 29E6B9FE3066CF09CF8227D8E559A072F36B2382FD3BFCA 19BC753052157374C6A6D868F2D9D94334A7807FB748C9, 87E107AD5A9D73AD3575BB56785B149C7C548689290DE1C7, A57878A169EED1B6D2AB99F88716ED86D5FF090D3C72BB96 4D355F90F6405A5E53F4893AD88D8BC99DF6817F25DA5B, F0209D045652BEC6993A3B280AB6584EE0FA4CDA8451CF67, FB02EC759B638B43CC694F1FFBFE8DA49EA76C2D17A3793C E7A01EB2E2C10F1AFBDD9BB089A8A35CD9E3847D718F11, FD1E7CF082B2DC167E1428F12735BE092F295A4A8E1E760D, 3544868B55914D92838E1203C31317C641815972FA81212F 2B6E05C18A8432D50F398D3119CF9EA168DAA8D7854AD33, F0DD616A23DA61FFCE001E709706367C9B3E362E741B638F, 23DCED8532944C2CD408745053B4D8566A1222B4FDCF779 824A11449F8C987F2DACA7934D6EDBE43A8FFA868FE0799, F7477B1F68BC6780620B206B46251DB5BDB3C3DF7E1E27FA, 31BA57AD0B0BF24867480A9F85FBFB9930274616EA260236 186DE33CDDEA5C97D8905F6B9E84C93ACAFAFEF93AFA16CB, 96AE79EB0A648DAA2EF738CA6A4FD4DD171A20DD0A36E7F5, 1DA556917FD6DDCFC2ACF833D2DD9D5B8071C305EA1FC052 4949A9B699BF15C789B11E42DB8E5BB060F0FCEBB0EE4461, 94A09B7C63E9B75B117E09E1784125C65B2B67F98D3F46B3, 922B5F92BA51AA72C51FCE3B6FF14ADCE1248EC839984332 DBDCFD23CD3D41569D135AC892AB131122D2F6C312CACD23, 59777F6D3BB4D0FBB4030BFB59261F24B9057A9DD29BC2C1, 1C450FC266C1A45AE52864DEB7390A2947BF0C5365092D38 ECC-224 1, B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21, BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34 3, DF1B1D66A551D0D31EFF822558B9D2CC75C2180279FE0D08FD896D04, A3F7F03CADD0BE444C0AA56830130DDF77D317344E1AF3591981A925 9, 2FDCCCFEE720A77EF6CB3BFBB447F9383117E3DAA4A07E36ED15F78D, 371732E4F41BF4F7883035E6A79FCEDC0E196EB07B48171697517463 1B, 1989153B5F6636B610854BCC50AFC929E914C03DA51A4A8239F4865B, B9381E6DC79B58E0443CDB009164837AD450A68C19192F126542796C 51, F92767380D3731F228A44AA785B413FD807DBB30FD6E11AE45D1EAC1, 82FC1287153C3E5F1CEF13FE31291C43CC54F10169FC9CA22E5083A6 F3, 9799481F3A9E0297A75E32DFC88512E777EFDC48E977349C4FC68C74, B6E8E987474C0C8D13AF4F7B8AF9A1F27667ABE8D6571E71B7D8359E 2D9, AB94C2D7A56E82D79C168B3DA45E33D72D45A5B25FA4AB096898C10B, 24899FC8552974E40FC2A5EE9690D11BFF96A38D84FC79DEF9EB70DF 88B, 5AF579EAD2DC6E6B52430A2F79A3BCECDC2B9952F353AA12AED13393, 30379F3012A1B94F83C5B4AD6580D7C8D42001FE29FA6D06F4C49C96 19A1, CDC4EBC6434E16ED2A94AD8FC5325D69EDBA5FC3F94940C37BDFBB93, 6F3DD0D2C4CAAA54DE14DED296B8067EC04F5EE1709C27E90CC4748B 4CE3, 362946F3E1813D4DBADEA15A78CDF4D04B9DD573B8CE48E082DD249E, 4632F24D670E17161BFEB43737A29FA7EC19CAE59C994DDF38341A05 E6A9, 198F000B110BB2776BE024C515BC56186CAE13FFA1F420EAFB7D1368, D47DE0455E35D402E5E7D7689AF837621F1E5067C7FBF9653D6D47D8 2B3FB, EAECA0011B1AF3CC2C81C542AB82C18C5046B4DD642091467B05BAD0, 823E2074A55D4ADC32787285F42B9E6186D38428996442042884E2DD 81BF1, 3FA4321CEF75D9C148069871B21E0E7D621C008CC1E3EB41CB63E306, 674C08B2AEC76DB3DF5FA9FC5F8DAB6CAA14C605536B0CBF26E91E17 1853D3, 750F11C5424EF88D236F8C0B8F3B858568333C2ACF4C17084FBCB243, EF8D1C2B5094B210852D8E751F28E23FAD4DCA26B985E54B527482ED 48FB79, 6129013EA424933A18B3986C9DCC4166C7A1FC13C0022358894D6F3C, 7251B2A84BB265DC493617FD712CB971FE10C6903FEC82CDA8631312 DAF26B, D82B5F8A652AD0B923557D68CA5CC42CFFBDC73DF3B00AA8F9F3799C, 5EFA86F7149BCD9FF4A5227C1E331487B9149262561A94E635999A6 290D741, EE88DEB98E68A56E4046566812F68193A1B8856D09CCF33D6EEBC446, FE5E7FE985E2DE483CD0B6481A1A1900CC3DA0567AD7BCB1AE54B597 7B285C3, CE9184F33548BA664AE32AE3613640988CCAC3A4A6269577040633B2, 6AA351D10075F5FC6BBAB3E1D6592A258CBCB6D1D6C828B880043A8C 17179149, 3D30DC993405651CF936A840EC2758454B71AD7DBFB9EFD3216B46DA, 8F1E7837F24D3E04F734FD6275C252E56B9F61F40056AAC2CDACFC56 4546B3DB, CD6075F48F57C66341B821BB05D75E8C5F68C0EC9E5C901DB6E16A96, 2ADCB9E834A6536D26C0325D0A9B8A05F32523B77AAECBB39025990D CFD41B91, E700466493B51C521C4A7DE071BCB89635ADA469B7CCFBAEDE84E6E7, 2DF8808FB469DF1A5762291BD71A6F47D5A87C8F77849443AD08B3F2 26F7C52B3, 985809BF0BF34DA2C90ABEDDEB5426E779A05144C233715EA2F1E2C8, B42E15230584FACC51355E602CB536A89EBDE854C1B411313DB3292F 74E74F819, F4183C3B4AA8694A581F6FFC811E8FA2973DB1CA2721C1771DF7B741, 981354E9716A0B3CBB78959211642C5AFE7DB94E7D874B716EDC96D3 15EB5EE84B, C90D782309B6C358C6A040936A326BC4FBDDD5A3016CD04949F64941, 4C08C351A44BEB5608AC72E9CFEC3BF6D63DDC289023E067870058F2 41C21CB8E1, F15788A0BBD53A46BAE249FE197DD5DD6FE0E8A0FAAAF9F31DFE0C95, 11F66BEB06E4DCB13B97EB80D31402734EF078D341522662458D33F1 C546562AA3, FE978F3F57441E1E0999BB12CC774E32D9C8928EE7FF589D21CD90C3, 9E7ECD938870A5E3AABAE92FA7535707777D9D80F9A14DDB31042A50 24FD3027FE9, AFD87F62D228450B96109E5206CC0553D9DD8760A9FF052B23095339, 56F145952A468E31AB06CACFC7850EFFEFEB6DA967FD39C4FD8C89BA 6EF79077FBB, 5ED036592516527B62775793FF08D45400E50F198583F29BCF6A33E6, 2B9073611B24F7CA6255B95BCCE19A3D9554AD10C7F188F78DF5065C 14CE6B167F31, 60A0A5676AABAAFAD67595EED957F060A8D9342985CB607BA210DBB3, 3AB05338FA134C4978673E91D790E6F5ED28A46DA9433DABEE72024D 3E6B41437D93, BA33BE7DEF4864D1D40DB7E258658258E04AD1D1221909B5BCDEB9ED, 96DA7AD512B69C87A3FF6AF89C146C73612C8FA17DA6FC39ECC2C000 BB41C3CA78B9, 56591F0AD7964EB69D2C422C7009014FAF45D3C4FC4DFFB66170DF72, AA3DCF0450F22193AA586D18090DE2C2DC456E7017701C79EDCD4BA 231C54B5F6A2B, D4423739B5D2E81AB85B2D9F9BFFFA4D9E2E97238642A1C2A5FCA5B2, 281817D29BCFB1677208EA276B4AAAA031017C252E3D7429604744B2 6954FE21E3E81, 2FE618ABCD354D14D175B89C2FA8727F754ED05408F8EC953D7A029C, 8A0F74A70F6BFEEA4825AC6D4940709E38A9D241B9B67BC15C1329D1 13BFEFA65ABB83, 1E79CFBD171425E53246D1649632EA82320D09D104541BF644B43276, FC4265BD80FB46A4694E221E04EF6CE85F2F349476351FBBCF098B77 3B3FCEF3103289, 2531CC4E788EEE33FF40F03E63FEF997D7BE20AD5AADC02DF93AEE42, A738D399C5B3538219E2121714A316F427B2555F7899F40A6AD899EC B1BF6CD930979B, A5AC42D6345A9D75DCBC35F3E9895D953EF7D15B54359DF6BCA1D15C, D55EAD112488C576C751C832176EC7AFDD7D31440BCEA86B93345155 2153E468B91C6D1, 6302D07975E9BC0E0C794DD36ABC39B153DFE291C8C1731DE4A73926, 6032CC140FAC1603602354F3FF99F60FACFFBBD4393B24EA0601A407 63FBAD3A2B55473, 1FE003B196E5F0BFB88AA343D5919E7C5E19026956DFAEFF10B41D6, 624EB829116A336D847259F80EC45B6B1D644C1F5D8DDC83404D35BF 12BF307AE81FFD59, 907A212C20C70A7E53A9340330BC05493DD188A7CFEE5FA372889778, C3A13E3D77F269C67C6543678E61A35F392DA85F49B992105350D00 383D9170B85FF80B, DB42BDBE076F7E75C34C2B927E73EC709265995BC4512A7E6F04C132, AE2A41EE109CBCA26E318A18003E2D7D1B557ACC196244CB175DD865 A8B8B452291FE821, 17F0BAF1779E31ECAE02C138D69109CAA1EBE101F9AD91D825E1D3D5, 24B76AC081C96497AA7B8CDF614E5A5AA53FB53F1D93369B9DA8190E 1FA2A1CF67B5FB863, DEC95AF67977A90F2C831F822A9883FDD3B119C9CCC552E714907F21, B161B842051D2CD8582CF365E5F919411C9E27ECDB896BA6DA21DFEE 5EE7E56E3721F2929, D34CB5030D6158A0BDA99A9AC40235591C0409BECE4A28AA7E989128, 78D670AF8D31D053B53F67854B7755F38CDA6731145F89378E2EDD12 11CB7B04AA565D7B7B, 806023F600D2D35B2B9DA9BE107802FBD9B04F4FB569055885F84174, 8463DB49296E86750888E06353ED42732C95F5C61AA4696508F9BAB2 3562710DFF03187271, 24F8274CA5282CD9FD95B53022F5CD1B878ADDED1D7A3DCF46D25786, B0485DAE467D6795EC97DE1FB4487FC2112D5798B77605E5C8D3F77F A0275329FD09495753, E7D0B41DD20AF5A36176BCC234AEE25FE7F9A12360E62043F11FF2AF, 982BDB1CA14088CF6A80E3A9CD5F329A8CED5AFAD519FFD7A7CB3DAE 1E075F97DF71BDC05F9, 418DD0F298DD0261802CDE28BCE840A007E09CFCFE85F518F7AE4C7A, 766C0AB7B8D4B2351F72A927583A927A46546931BDF66E9D53E7913 5A161EC79E5539411EB, 26D81F8AAF392DF2216B68C2125115B3AED117A4F20588A13C2D1EE6, BF9575307370151F7F217482C63851895CDA7DF49B406AD83449C633 10E425C56DAFFABC35C1, 2A2BDAB9F1E3426526EA8A02EDB7504793A023A7B94F1750A35F1290, 46FA41933EA40F859D230D2AF76D309F4B42831964131DA7879AFFAA 32AC7150490FF034A143, F8BC0F7FB724B0E98068DC7C649C86439D9A0CA110D70534C249A957, 567D9D1611222829F765E233F2865CA765C533A75DF52A8CA6E2EE42 980553F0DB2FD09DE3C9, 3E52D85CBBE66635CEBEC93FFDF099863AC3532248828404C4488A66, 6E32E7FDBA3D4121370E6E7419258EF83434AD93AB0BC2C42ABDD324 1C80FFBD2918F71D9AB5B, 6B1FF073A3CD8A64AE76CC428B83D25B9DAA0D80830E98B8D30B1AD8, 5D88EC8A26D1CE0065466721A5EBD21983E5212CE7CE0E86412CC4CF 5582FF377B4AE558D0211, F866E3EF3FA7E04BDAEDE69793A48B1A11F184007E2E8BF3E7B0B13F, 89CBCADC39970CDFC908391FC332BE45AB7040C154908B1FA9363E41 10088FDA671E0B00A70633, 27088BE15042726C5934504CC097EDB828B808E274382184A04865FC, 7E28842B3D3B141A8FAFF4EC5FB4523A817F533BA3878BF62DE490D2 3019AF8F355A2101F51299, 7612A5EF2A4FE2ACC965E9EA98C980414008820044C8D2494A6E48A1, 804F8875E4FD670460E6E8774E3F8EA7ABE132EB4F8538C0F263E753 904D0EADA00E6305DF37CB, A2E07EB44A40264D8CFA93118985E2AA715D9834A7A2FCA5337105AB, 82EE99285D88747C9A969C03DD91F97749A795556206937E02EB7070 1B0E72C08E02B29119DA761, D130DBB6587C74D79A7B2C25467D87D63290201BC142A26A3F7729F8, 593F7B51E5DE8439291758949A287941E2D0C9C16D257B50E59E5657 512B5841AA0817B34D8F623, 4DB182A30BBE6B0F0C1733FEC0EDCF0F29F6FF3C3224EF165B40135F, 2F1B284FB92E47C7BBE9C49B99A6E63E95A929A2043A3AD156A831C8 F38208C4FE184719E8AE269, 91507DC0D051315B394C9D8868B523C1580CA006D12AF7A59B742595, 8C35E6ABDEA10E34147ABDD51A338D043A7DE36C66CCEFAE82388521 2DA861A4EFA48D54DBA0A73B, C869E191772D7416E0854FC627CD4D52C8E1DC706368EDED86C0A5C9, 1958DB34382603897FA5DBB481AB9491B0B4563D9411707DB27E75DB 88F924EECEEDA7FE92E1F5B1, D74520FAD09C24D7C8229D21268D9F796CE671646C7A1F663112E3D7, A39D0856AB0790FC41750BF4B44470685847810C591E9C65497A7003 19AEB6ECC6CC8F7FBB8A5E113, 6A854252F1E6A0B376BEDAE354AF23012963364589417EE9A0E0C8C5, A8DBF75C9AE8108AEA6407839DB057455E75EFF24B126782DBF17E71 4D0C24C65465AE7F329F1A339, A7BE78954E6711850881AAEF30A804E95091F4ACE0A451C4EFBBFCC4, AE45F4111709124C24656B5D9A00A2EC632DD1F9E0D19B7C4C74E2BD E7246E52FD310B7D97DD4E9AB, BB6BF6D52101D7171692B076718926024949B2FC1CACC4C217E22A49, F4E2E945D6A047AA3C19E8AAC06704D6E6A3E6597C965222EF146060 2B56D4AF8F7932278C797EBD01, FDCAC4F59249609AD294C519C8AC53DE2F000BED9FC04C4C6B8F2B72, 3D2E5C42C563572BC901E922FBEAB3F05362F30FB064927C9F12B6CE 82047E0EAE6B9676A56C7C3703, 78841771E59617F86F26F54E29FB34D0BBBADBE036332D95CDCF99EE, 4301EE6FAB7416ACC553C2717D7CD36D5545F1BBFCC3D9D1AC99CF73 1860D7A2C0B42C363F04574A509, 34F8CD3C4075CC243E90AD791FCAD0863A0B8780E807349CB95F8356, 66FF86AB3C4FE675957707DDE054751EC4F630313DA1D3EC3248599E 492286E8421C84A2BD0D05DEF1B, C063400A25BC0F494FC7C150ACAB7A62B117A708E912C1898BECF607, 4EA8F6FBB32B3E8919891173164A63BF8B8FB964E0B004E56379E049 DB6794B8C6558DE83727119CD51, 1C9455B676487BAA9275CF474F25B77C05CD1CEBBA5E83B72E84F8C5, F771F0402BCD3FBE57BA3155E76AF6F1EF4895C072F27575EA674B38 29236BE2A5300A9B8A57534D67F3, 3E246D1BEAD5B9A65A6462B144D74E9EC9060D5CBDF7199D0271D3BB, 4D96FBC404BB208D2283DCB44F907E563C3725550EC601D11464C4CF 7B6A43A7EF901FD29F05F9E837D9, 44809885890A682AA2E5A3E36DF30F49650E53597A90EDE162E0A663, 32F2EFA01F22C2F5C35E715BCFCCEE8A1D054E31D6BA67E6F66B51D2 1723ECAF7CEB05F77DD11EDB8A78B, 1ED9A1DA3FF1D896E53DA5AE2D1ABB5531F29D8AECE017EC27333099, 810A5D32B852640F61043D8905CC49F6B9E5E1A8675E114DBD10E28 456BC60E76C111E679735C929F6A1, 963BC62E52F3E9089A4CFAE8889AC36C02CA5CA870255BBA41D80992, 8283036EC72E77656965A322EAE1835DEFE81BC2BB606BE039AA08B1 D043522B644335B36C5A15B7DE3E3, 59513B27D32F5487E7BC263CA8163825CA301AD4FCD2AF6BC38CD8A0, 86F10C63D8DDF602FC5FD1FF212BD6018FD8E84EE2DD8AF699030FDD 270C9F6822CC9A11A450E41279ABA9, A6FDB2969639E579FC432045414BE41C70DDA2E08F038A0A5BB42AE3, 676F76DBF44A80DBE674C97E925AD073A225ADED52A66EAD1743E349 7525DE386865CE34ECF2AC376D02FB, AE3C55F9F92AF86E2E24690093279721BA8BC470C0BB30629DE7A830, B89FD0207A227000BB68B30CB54E30F4FB91D5530153B82D52EC8688 15F719AA939316A9EC6D804A64708F1, 340E2C333CBC4F554A9D395F81FDC65134504DD940C5C169096B2E6B, E46482D2ACFC6B7DD12794118B3FB4844702E6AD410EBB2572D70C2D 41E54CFFBAB943FDC54880DF2D51AD3, 3DBC30E4C85CB76E7AB13CE933C124BBCE4780ED0E5DD209EF3E0D79, 2436FD101DB483C4A9AED4CA46524814763E33DF799594196FBD5FF0 C5AFE6FF302BCBF94FD9829D87F5079, 8D232E2CC2BFD2ABF2381EBDF8E2F208EB7221D6051AA3F848BAD7AA, 84379CACC97CB4CC3E038F03F9C3E39A95B2692EF3207992F6BC5A71 2510FB4FD908363EBEF8C87D897DF16B, 474E806113EBED5D3207F369B9025C92E5781882FD8283DC156FEC94, 92C1255A2357F57D2033F648A07CB8BF6ED976DF92723F83C1742C68 6F32F1EF8B18A2BC3CEA59789C79D441, EEFFEB6E96579EABA84813CE7D7D8684BC4526783BB99D766412C93F, 7A882D966C41A7776DE16D83627BF26E6AA2438AAAC509ECB59FC188 14D98D5CEA149E834B6BF0C69D56D7CC3, B6D1C744E5F1B500F7C00FA3ACD776A4D4FDA70A1AD6FF2A28CB5440, B6B1B53BDCF1D5C3388C7B9E89D13B317935DE42E0EA796DB4CD4F95 3E8CA816BE3DDB89E243D253D80487649, 565A2413DAA241BD78E000D4514586C32A3618B0540EA46E6E404DA1, CE6054C367C0108D3AE4BA143353D0E88B48507206BF70928F2D612C BBA5F8443AB9929DA6CB76FB880D962DB, FDDB75542EC1312CE37D27C86B713322E71DBD862F7C32225A3A1ABC, F89EE7A1D1C4E4E211A7080BDEC6A5921C285ACBA7F6971C031F1387 232F1E8CCB02CB7D8F46264F29828C2891, 13957BFCE2EF1DA3867BFE22E31E40720E4D4A58803579FF12CF72FE, B82DE7FAA2528B4A77D62559ECFD2322A4FBE18EE5113D1E43C24D85 698D5BA661086278ADD272ED7C87A479B3, 860F61F11AF83C2D6B66DA9D942C2E5BF6B315983A58FE19F3827010, 1A6894B0D572A2D5940F2CE046AB40334FC1145DBC8E2DD87FD1E33B 13CA812F32319276A097758C87596ED6D19, C7C67E5E063741E3906B13E7C7D165C8F16D90B837B5294ABB02CA3E, 91394812FD3A35E358B2864C9E9AAE270F948390B3B1B9FFF5D2352C 3B5F838D9694B763E1C660A5960C4C8474B, 8E0628DC2359649255B2FB0BCD820AA5EF46D52FCD4FA9C6D2935704, 815596DDA0D138F90381FC63591F92F6D0ED19028DD6457B8D56B988 B21E8AA8C3BE262BA55321F0C224E58D5E1, 79C4ADB605F9C0B34F52281817969775FFD63F36B4F696B06790E61F, 22171C082EAE8EE539438A3DEE8404A94A1737F08645403FB32D76FF 2165B9FFA4B3A7282EFF965D2466EB0A81A3, 83E2B541F70B5F49DF385A40E91EEDB42430A123C73BD71573C4AD68, 471064372661A3CE3FD801604676413F29F37E5A076F307D685F8627 64312DFEEE1AF5788CFEC3176D34C11F84E9, 7E4C45B94EAAC7A463DF23F5D330F9B7D7A130CAF6D9AE253015054C, 4DB6EDDED348A8E3E3260EB7D6A702A7E9DD3706C3EC4001AE1A1304 12C9389FCCA50E069A6FC4946479E435E8EBB, 5B0E2714AB739379A642EBBB6DF9A42FF8BF3AA08DF2C874E340AD12, D13787A422669EA964C6E694C3E6A2FED4A5BBC54BF7EB6E5CFF54FC 385BA9DF65EF2A13CF4F4DBD2D6DACA1BAC31, 835CEDB242D2FCE30CC25ED413002AF81CA3BE6694BB2740D2C7AFE6, F4F2FA5A1390F06C10373CEE927A2753AD4E6E76E16E82419936FA5C A912FD9E31CD7E3B6DEDE937884905E530493, CE8ACEA7322FCB9D00F72613D70EECF3634C18CB7CDB86B85DF25B16, F8D7423C003EBEDD38FD283A4581B016554B3B6F19C7A3B21F1B5F49 1FB38F8DA95687AB249C9BBA698DB11AF90DB9, A5388908704BD7037303452C9CD652B019B90B9102E34C62995109E2, 57B7FBDC820539E6975600AA55C452180385AB6CDB9FA9CCCB39D5B 5F1AAEA8FC0397016DD5D32F3CA91350EB292B, 1846C2A8382CA7D35AE259A5F991765B0FFE6863984CFCB9C5E3F18D, 9217BB8675E5AA70DDC907F9E7B3704D6F7CA78E7AAFA78F4BD3D326 11D500BFAF40AC5044981798DB5FB39F2C17B81, 4AB209E645972B5875BC6FB67F451B89E1D0E9982FBADEE7F8AE9AE7, E5108B1082281FF1B7E1C00A0AFA7925469B765385B039CF0ACA4A8 357F023F0DC204F0CDC846CA921F1ADD8447283, 4938C6436695D4BD1BF9390F81C74F9C3F409D29CE8D1C724B1D93AB, AEA0DF59B29A08951F32001E0EC78B67E8BD026B0B0A5E5E8B67A67A A07D06BD29460ED26958D45FB65D50988CD5789, 513B8E07F4F315E84EDD6AA65D8EC03DF324D3FF8CACDAF578C19BD8, 171A0D3BB9031D3B1A3F395A89BADE2C015FB77FE2F720627913DE5B 1E17714377BD22C773C0A7D1F2317F1C9A68069B, E85227C4F5C7049F7A3E2D1AF6F809D4DD4060586A7DCD8A9632E30D, C50E343E07A9B62BC3F90F568BDBB438119AF291F784F3CF94170B32 5A4653CA673768565B41F775D6947D55CF3813D1, 5004F41DC75A5100D0C4C94B5F4ABDC830BB70D8A3EF8BA80F8B0106, D01D936E9B1275413D6F5A3AE69C53337F92A9999AC6A174D4BB7BDD 10ED2FB5F35A6390311C5E66183BD78016DA83B73, DA08B4FA25D8EFDAA21CB16AF0BCCC5A1FB84F36B04F01F9ABF7A466, EF5FD5BCA10427BC9E9EB97FE64B52538BD2A42767EE24E28D998F79 32C78F21DA0F2AB093551B3248B38680448F8B259, 5A3D7E4FF4ACB9E2E42E291CB0A00055E8D564656BF80140A69AC7CD, D44465AB9889071B964EA9D6DD2293C2FD5DEC5F2DA19647E2ADDEC9 9856AD658E2D8011B9FF5196DA1A9380CDAEA170B, F426C8B26E65590D7E482ED14E0A753A04F748E6CA68A95B109422, AA91BC40AF7E2DB5310AE16A791546327B3F65C6BE9D0D48ADC16B2C 1C9040830AA8880352DFDF4C48E4FBA82690BE4521, F871C97FA218C2B9A246DB1C983950E8ED2A5C1F780D1BA90DCF6D30, 596300CFDC1B550F7AD7073FD71DE02CD7187A9B55E4695364534EF2 55B0C1891FF99809F89F9DE4DAAEF2F873B23ACF63, D6BD9CE76DB2389E2A9F0282FE09650599A0EDABEFAF94D680041035, FA546DEEFED7B001A773FABCA8FE96217409BD2417D0B3AFDCF9A622 10112449B5FECC81DE9DED9AE900CD8E95B16B06E29, 5DC7A99F493CA394F30A83B8C3EFBB4ACEDEEA32742791B6E4D96D06, 54B0AE3E89CFDF50F2673CBAED1A2E51FC3AA88D231CD755F3E865F4 30336CDD21FC65859BD9C8D0BB0268ABC1144114A7B, 3B704A574160450486E281407FCB9F385887E9CED024E0772D956F7F, 7867D7C0F8A58BA59B9ED64300AC618A35D112D7D02EC6630CCF8112 909A469765F53090D38D5A7231073A03433CC33DF71, EB275092513826241ADD2027C318622FCB610FC48886B0C053F66B9C, 4752DAC073728D4B3E12A23393640A0F38A1ABA1FE514AA952B071ED 1B1CED3C631DF91B27AA80F569315AE09C9B649B9E53, F3A80BEC6326399E5D846455D2AB4D26F80A5467A344B6E53DB51308, A2DEFFF968EB3D918D3348639CD9DFB31DF0A3BFEB8B0C6D68132B2 5156C7B52959EB5176FF82E03B9410A1D5D22DD2DAF9, 5198983342D72EA3323004852DBE34D2D19BC0666746CD4DBA5BB4A0, D43596CE581C07801F494EB0D2176A71076C5C560039CE26FB2BD990 F404571F7C0DC1F464FE88A0B2BC31E58176897890EB, ABAFB40DB81416834897227A8062CDB4006F8A2376BC5309787049A7, 31EA667608996EEC5BDA680378000F7246E3728F8F6CEC7989B72F40 2DC0D055E742945DD2EFB99E2183495B084639C69B2C1, 49AD83CFEB347D0B79D44A50F4EC30D4E50EBE9CBC15208EC8A75E2F, E37F7E851E485A9265037E548F318D689E8213D76258FAF7B70C5179 89427101B5C7BD1978CF2CDA6489DC1118D2AD53D1843, 84392061F665B5AF5AF5D40C958CA52289AD4F17212C7E25103EFE8E, CFBA07E2045F60399D7E4B11EC70C2ECB1B5EB26EE1557D28D54A5AA 19BC753052157374C6A6D868F2D9D94334A7807FB748C9, 751E83A6AF15280FC00AE31EA3B3607AC9CC25462E8CCF6CCC13C691, 9DB6DBC34AC49A3D0861AFD9C441A1BC177BBC617D470D48C3F5344E 4D355F90F6405A5E53F4893AD88D8BC99DF6817F25DA5B, 646DFFBAD04916E629FF52412143CCFB2EE3A66388BE2F784A67633B, 66D781B41F6D348179275BDC06D41DBC6E8592CC4AB489D246752E0 E7A01EB2E2C10F1AFBDD9BB089A8A35CD9E3847D718F11, 64CF8470EB59EAB6FEBF0FF401D163EED509CC225A11759D893EB01A, E239DCD5315AC07B34C598E164C23A022660D6B943402173A3E0D85D 2B6E05C18A8432D50F398D3119CF9EA168DAA8D7854AD33, 56FEDA7F730804922645928C5EC38B358B16F5B37F07562CA988FCFB, 3EDCD377E4B203D860DD24FE73D18CA02501FE8F1B9E14EF817D53E 824A11449F8C987F2DACA7934D6EDBE43A8FFA868FE0799, 603959E0F53EDF19D13140C404E972C587A34BC7DAC54863BE600240, 5A729278913677FB173E9F33F4C6B5F2D4F23DB09CB1A491419B46BE 186DE33CDDEA5C97D8905F6B9E84C93ACAFAFEF93AFA16CB, C0BD22730FD9CB9CE51E73FB04300214B11D028EA97FCA25630329B4, 400029E2F127F00EE09724769AD4EA2F0219334A865C466FB686B120 4949A9B699BF15C789B11E42DB8E5BB060F0FCEBB0EE4461, 8928662533735CC4D2294BB65D62C9348DC54860651C5D8ECE9CC4A2, CF38DB1A99A04631C3EB3D91B75D324B7EC158898847C8E97D0D1CEF DBDCFD23CD3D41569D135AC892AB131122D2F6C312CACD23, E31F70D450B1C4D908D42FF14ECC288401B4B2351E09039AAC06760B, C05385585CC321BFE1E9CEE4B724B27A1A44073047B2DB23218B8D89 29396F76B67B7C403D73A1059B80139336878E44938606769, 540CE2017428F8F2C685D3E026400B8B7F85A9111AEB1C7E732EEDCA, 3FAC5B38F1425C92BF205C5807EF49B0E18407015BC8CB8E48BCD654 7BAC4E64237274C0B85AE310D2803AB9A396AACDBA921363B, D6DEF929A63BC8925B4A4E63173BD90662A8F7FB9D88B4270DE2CE69, 9F4EA22418479B10B4755E8FE107D8ED866CE49DB22A1ACE76718996 17304EB2C6A575E422910A9327780B02CEAC400692FB63A2B1, BB4670CE0329AFF79258EF269A7BCC959D87DFE80BDCE8BA6459936F, BBA1D31C04E781A900AA8BAF2988D34F340973192F981CD1E83B4564 4590EC1853F061AC67B31FB9766821086C04C013B8F22AE813, 45E6B1674732B7D2338DD56A0ABD9B3D9A9A59D86BD455DC7FF9616F, A2B85EC52F699E000507B6C8B4660AF31CCB90CE106AF94CCC78BF78 D0B2C448FBD1250537195F2C63386319440E403B2AD680B839, B837F43BE73BC0B560801DE91A7D47A558D25FB1E4FDAD26357CEB8C, 6789EEDD114F7A3A1B18C5737DF2BCB1FB9EF1996B5DD03EAEB9F10F 272184CDAF3736F0FA54C1D8529A9294BCC2AC0B180838228AB, C8B5377944667B0C017AB22CCC734EF549632F406104D3C1D2FB19D0, 805A0F9CBB7765A78AEDB87FE42AEA6E360C37A4116DDF9BB8329954 75648E690DA5A4D2EEFE4588F7CFB7BE364804214818A867A01, 4F400F7A8721EF9FC9CE4AD8A8068F74B51B197400AB38B4D10E6C87, 5F9423C807D049F2FE86443FE8F0C6F1A1F656F3D35CA7106D74F8C3 1602DAB3B28F0EE78CCFAD09AE76F273AA2D80C63D849F936E03, 838D9F9EA47C47AE25896303825C31C1ECA75F22A8D3165BA1B4F090, 9ABD33EC035B387A845CE11E42EFF71C8742DB5EFC4C61B201A96599 4208901B17AD2CB6A66F071D0B64D75AFE888252B88DDEBA4A09, 9B589D1A1534080FD91DF288F0D88C927D27557FD0A1C6F196A9E3BA, E70E4D2B95236DD2B6573945FFEDAB3C02179D2940B75335444E72BE C619B05147078623F34D1557222E8610FB9986F829A99C2EDE1B, B60C05EC716F5B18362AEFB4BF529146EB2A3C2F2946FCA74078181A, 98F6988C710D73932AB7F72AD0D91CC7D7EE23DED80CA0C582F473B4 2524D10F3D516926BD9E74005668B9232F2CC94E87CFCD48C9A51, B1130EAE2B5733BE78E54DC9070BD3ADA67EB19421C9FC19563D2EA7, EA34001A4E9751C94446E85701671D73C8B668E67F950B25660016DF 6F6E732DB7F43B7438DB5C01033A2B698D865BEB976F67DA5CEF3, C91E72D890018B343D3D6D90572BB75000B26EEA1DDEF16709C84F1, E8530B7143DD8E828E10A06135C12CD002E5EFB35F5D9DFCDD636320 14E4B598927DCB25CAA92140309AE823CA89313C2C64E378F16CD9, 496C1AFC7DCC2F878B24443D4250EE53A2E576FA8DF2DA47AF4136B4, 34B68FA994B037B5DD758CDCF737AC97DAF04C8C6FACA4A036EF6935 3EAE20C9B77961715FFB63C091D0B86B5F9B93B4852EAA6AD4468B, D92253DC324640172F572A67CB7FDFA2FDAE009020E36F59673CF795, 713535A0A4F70093D3668264512A154FB47A6E63883ECD4627532486 BC0A625D266C24541FF22B41B57229421ED2BB1D8F8BFF407CD3A1, 9829981ABC910F195474EBA80C8105570E7062D5CA2F698180896058, 2471A6945484D09320F925B9666DCED662FBD278480935075B1080BD 2341F271773446CFC5FD681C520567BC65C783158AEA3FDC1767AE3, E738FA89F04B3B264E3D9148659F8E89FADA75CA07EF94D99E5E4049, 8D7189B1F1E7121972AEF7EDD22F646973F77B7FA2E9BD9642C974C7 69C5D754659CD46F51F83854F610373531568940A0BEBF9446370A9, B3FC9DE2B39001A55875256F0D573F47E1178870A2EA8749E5F6B0DE, 175F7C353FC68068FB501F3F6A0E6B104322E6430E14B46B3623DBDB 13D5185FD30D67D4DF5E8A8FEE230A59F94039BC1E23C3EBCD2A51FB, 832264CDA085803F497645A5841F9E4AECFAEBB1B91068D05C20D2A8, B0032AE2BE48983FD9696331C744ADC95D2A706D97CE5F6CCC8016C 3B7F491F7928377E9E1B9FAFCA691F0DEBC0AD345A6B4BC3677EF5F1, FD00B3858B888CA0E7A44E42656765F775A748BD75E1E3C6D6555D7F, A6E710390E0AD2AF144746F59758C92C08A9F4B666879B795E9AC9E4 B27DDB5E6B78A67BDA52DF0F5F3B5D29C342079D0F41E34A367CE1D3, 23B97099A944244533AC76542AB9A004274ACC5ECC9819474681C068, E3C1C5EB1806DA05C3F40EE0296991D5F9019CA998F70E4509EACA4C ECC-256 1, 6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296, 4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5 3, 5ECBE4D1A6330A44C8F7EF951D4BF165E6C6B721EFADA985FB41661BC6E7FD6C, 8734640C4998FF7E374B06CE1A64A2ECD82AB036384FB83D9A79B127A27D5032 9, EA68D7B6FEDF0B71878938D51D71F8729E0ACB8C2C6DF8B3D79E8A4B90949EE0, 2A2744C972C9FCE787014A964A8EA0C84D714FEAA4DE823FE85A224A4DD048FA 1B, 184FFA5819D80D51DEBA2FAC4611F378576355BD683E54ABF2E201173B0883D1, C0A66E276688F359A4C6D90826CB999545BDECCC63F0491620D242C260906E6F 51, D829AB2D2EED358C8464C3093DC72E911E2A1B96700BB9B12CDCF0C2A8A3B072, 3EC1BBE459CAE899E1F6C7BE2A598059166273E2D406AAF7CF3BC0B0B543775E F3, A392B26B0503A71F0CE1E02ACADF19D72A84D6211B21C914EE8BC58DFEA92529, 90BB3C9F9F1B598B6F97AED2C48F4C59F12194D8EB011465FF88E7560D1C5493 2D9, 78D56FA935996DDB7565CD320D2F264F5305BE551F411D49CE17944BBD8009CF, DC5B53BB32F4D146A93A6DDE353B6E25A9FCAFC7A5DE15E01F7746239B88C07F 88B, 51E39E9F111A1FFC74D63499CF065324B86A479BC0FBB3DB0EBB77E95DFA86A1, 8C945F778CDEDCD2DE6D7768005041FFB91C6BC2DA656C104373132AB0C9102D 19A1, 9EE8C552F615C8D0E86A7B983EF37F69BF5906DE3ABB7584493EC15E8C803EF7, 2B0363927BEC85207FFAFF4FA95C20BCF723AEB67862C5EB892A726A41500A27 4CE3, B97B92F86F23855AE92E8578B23FB85128CE00A4428EE1FD91ABFB48316FEA58, 77DA430A9B98E46C9EBC9F627F507467D05CB06172EDE14FA580CA2782184805 E6A9, 82D3B3A3A5C7E5B34187CDC1AA0FA9FF0E8AD81F269EBE2A079A1CF9837C0794, 8413A7951DAB0CDB00C790192CE9D7FC142AC2E8BDBCBC37671764B264087D8D 2B3FB, 84D845BDA10BD468A270B290020C440958F2CBA1345F77097590E4F0982C5A97, 952F9B537E6E32499A76AF3432CF0B47C9EF5DE39E7EB8B5D5355C30BE1CFCC7 81BF1, 48FB22AC3EA85118E91EB21C22CD06C0E9AFF19DB827439BE275553C1232DBC4, C1F09255BE08A671628A64F25A2B562618F0014DD092BBC12FC2FF8A3E59BF6F 1853D3, D547A583C479BDBF65D90A6ABACBE47B2ED9BD5DDB848DAEFC3ADA9F045F8DF5, 7A7E2AA0AFC241FF6B254CB58B36125B87E560AD50B469E562CEEAA1BC626C39 48FB79, 26A141A8ACBB471D3F3BDFEE5889D101F5F244A1ADA073A28A1ABE4D66AFACDC, DD5E7A714BAEF3F3D20947A3EDB6C9A11D221344B572EB75F075DF225514AE4 DAF26B, EE8A3A9A685BC75A6A6329537AB447B4EBEFC93DEEE05D92D5481BC5FA2DD2D4, 11C6F3406FC0871FA80021D28B9252BA2A4401CC6DE5DD887E1C102F89194236 290D741, 6777D49BC45F54537A46598C9EF93D4A260CB2E223883131F90EC013AFC3CA9C, 1B309AD15E576A8F6AFACCC30E14BA222C8278D5942B1D3C4D5F3B2E926E9D8 7B285C3, 1C38CDF2246338A098DB0E2B0E438FDBC1C9E598BE6B661AB5413D7AAC7365D1, 965E5C9AD86C0BD83BB0EB34F4742D02B4C12372661A5A7792FEDE41A036363B 17179149, 2E1F9230C1189F7303AE23F85A4DEC206FCB2C9B9DAABE775D4350759887E3E7, 853E17E5254608B15FF68DCCE6DD47F5206AD0545A70B0BB8E38AF816D9CF154 4546B3DB, 6DD8BDFAF3A6ED8A97C35E0B8C0889A45232E5ED8DB12BC03C18B5CEA4D146B1, BDAB741CDD72401A40D3FF40F2FB6C8D49AEDBE01AC8221DA68D922E4EFBF0CD CFD41B91, F11C444EF887CA44ED031DDCEC54AB09CA839113B84DA5478F5990CFDC4A280A, AC2D493266FC8E5814994EF40C6612D15B8A5FA6435C4499A1ECA1783448EE4 26F7C52B3, 4CFB521D25D4841B3B3AEA60BF54890744FB04AD389D90751CAB408870AA96E7, 63FF30C411688891F322842464D50CEAB09508CDFFB2518613D07493A68E7D53 74E74F819, E33DFB2BEBEA0F89F7B24E912C309F1BD2201385E7195A7F86EE8D827D252C48, CF788477541A99C605A5A49A445AE2DC83D332CC2E25C00E8DA74DA1816602B3 15EB5EE84B, B6F05F7350F984E483866624FD32F344571505D798AF01C76B0037A161898402, BEC64BB72514F0302CD84ADD7F8B839914D169F32C4D7DD7E75BDE14610EFEA3 41C21CB8E1, E4BE38E3A719C76CBE660756EEDCE585E836F79C252F14ACBC347D1F2B005D03, 6F69C0A3DCD5F48BE6EDF0D787AF6C985591C93FBA8E9844B2E2BA83937A3F06 C546562AA3, BE14B442FE165FE657CFC0CA8A1A765FAB5D14F96988FD02336F03B96686FD3E, E6E8020E81856E788370FACA0708AFF83831A25F751A8F192BB13B9039338DBC 24FD3027FE9, FFACC9CB1F8FEDC112BE4EBF255956A8C8770686D236862AD1AA51C655A8D6E3, 8301B27043EF5D774421E58E3160AC2B82DF8FEE0C97E0A7D2C3499D1C2D1B91 6EF79077FBB, B192264B1A443E9AFB9CF79B1ACB997B6664A92AE1B8C84FBEA2FAF6E9FB1841, D499FB416CB4709AF072C78A4CD5ADD0926BE45964F09A37E9B3605B15F62F27 14CE6B167F31, D4C9949DB9AC21F126575255AF2E99EAA6EC3E2C9658D572594445699B0A811F, 6C88B1474CD419D6D7725FEB2EAB9E0F007DC873F12B11484A06433AFA0ABD54 3E6B41437D93, 5B582B68144EEB9B4921D698129CC87D4DB79A8057E1DFDF87031FB59617C6EF, 43E9A8B669B41532768550B6FE7885F5E75B114D9802A777A9D6C27224C8F361 BB41C3CA78B9, CC026A9D0A728EC8994DCBAF79F3CA6BD3A935AD808C606886BD333B031940F0, A44C9033F98079E7F2621A921BDF565C861C125A8E6A977F1847B90F34A0495F 231C54B5F6A2B, B4D0291977B7338239B0087DA7205FEE91AFE4E9502AF60A686F0A4ED6E898D4, EAA998CDC7F5BA3ADA9B4FD1F031C0439B1901FD7839C4E6C57D34981598817 6954FE21E3E81, C84EFB4200A900E25C11788DCD6486271683966891A1720D4E69A05EFDF75CEB, 7927618CF298C706A84F263214389D2ED3590B0CF56616B17A4F92578AA66F79 13BFEFA65ABB83, 6873677B3481510BA6C07094667A74758A95955382745C2DC9BFD221D86220E9, A996843948A68261819C67D9832431FDFEE4C4B740468B1D32E634AB54FBE56B 3B3FCEF3103289, 318D2083EDBBDFF616035068099DEF9F8F301C18862819572AF983C0DE1B5766, CF4EB2E4EEA21CB80737146A9FE0A9FA8ED27BA3304B591D044F0B5844BE2440 B1BF6CD930979B, B9F8D2CD8605FBB34FB2E45CA1B7B551290A9756E4E505B8BC1A24D573A2315D, A7DDE469F7EC6C41AF7106D876E942D6326B0B080FB8974B5FCFF4F57B2FE3DD 2153E468B91C6D1, 4F34B85A6E86EFCE07F2416EA5207584EA73EE563AAEB8BA5718998C3E6BC837, B9E58B8C624FC69CABFFF05F0AE627831D321A7CEFB9B46DC00001BE04557FC3 63FBAD3A2B55473, C72747417F3EDEE3A825D6812433A765B86A5232C6C6A659C9A4B191B1E1DE94, 6CEEF872773D01CE3DF28BC9CAAF7FAFB99DF1D959F68E72E35B6857E0932F8F 12BF307AE81FFD59, 81FD011C8A99A40DCA8A7C32C79162A5F2D4890896CC78B3A32ED717CA5FA2A4, B9D74EB358E8317836B4AF55570A1D3D12860572CD2A5B2D0DFCC4BD3C4BC987 383D9170B85FF80B, 40AFAE4C462C69336D891960DFE6E196E9993833E665E049B1954637D43A129E, CD4061C098918CE5A9C8AA6834BB03BD772075E65A409E46D714F355EC60EB8A A8B8B452291FE821, 74704BD80D4E27078A655E706E2A597ACDC29E436EE80BCBE18FAA84C15C6DA3, D1B40931780C1DA6335FC44FE4692B6484F60E252D02F83BCADDDB3EE7A896C8 1FA2A1CF67B5FB863, 6B439DDBC100DEDEE0483A0C4FD5A8CDAC1802CA3F97293CA725C279CD7BB08E, 59140C0741B1FA234AAE1DA31DBA65D9791F33969AA7061B0749FDBF88758FD9 5EE7E56E3721F2929, 7668C2BDC91D291B02650789062D5E751BAFAF59CF998678B898823961062D01, B34EB15AA456E24AFB98C5E6E4DF372DD91D129AEF901E0B130BCF7E9331F5ED 11CB7B04AA565D7B7B, F92C3A38FA5E7DFBEFC60FA0E2456DB43753A261BFE6FF63C62E363EC0878113, EEB2E1B0276140E9BE5305B50B749C7B86A03E318DC329631BADBF3887482246 3562710DFF03187271, 29E7020497D6ACA67F6763F75F4B42AB5AE4EE8A13AC502FCD3D360F4ED642F3, 4CDE12B3883D75D2E0A6D7609B0AFBDFAC4988D9705AFAB4EC0A1589514E0329 A0275329FD09495753, 1FAD5E7460F6DFD39F30175930AF50D1BD7C5D7DC6BD042D5C41F2C50CDA39F5, 621FF115E20C9EA82F065D44A3A8E1A5ADFE5BED5A2CCCB7CB41EA3011DEE37 1E075F97DF71BDC05F9, C32260FF2CA314BF21C9657FE2A67DBCD42F8FEE94801DFBF19B90B5F0391D3D, 4D5C4D7A51DE0E13C84D9F73397E2B60691641DAE21E8A0EC176099E53CA25D6 5A161EC79E5539411EB, 27A7C9B7C1D4890DA2D7EFF72817674AF89B0252D4C5D475BB3A4465E447FAE5, C5E46F8F273374A13C5946F38885C32EC2A74E0EA841FCC7B89BD8D83F55FB7 10E425C56DAFFABC35C1, 118A2CAC0A483723089A3E884871DF85AC85AF79F585EBC3DE428161FCDFF17A, 25755E6E4CBE651A0FFADCB9BA725B814120B6C06CDFE5A84F907E6E2A6470DB 32AC7150490FF034A143, 8449173F1EF306C543D0C4B9F2CB93429F34637236E309BE67D53D4157796723, 781842F7C978BB63AA594FAD8A68134335C945AD09177FFE0301E67A0B8578EA 980553F0DB2FD09DE3C9, F5E177E4C208EE73EA60F93CF55AA29C7432F64190151C3C9120EFF544507895, C3A1129403AF90EB0144B02064C808A74E77FF1B8D5D20959F2D1C6485D8201B 1C80FFBD2918F71D9AB5B, E97A1033D8D47612F69417D75A39F45E4D3E2FB2BEF8A236C5B1378403C3C82, A1FF6F7DECBD7908319D1735F7E9FABE8A65C6496586B7773B9DD7F3C8458AA 5582FF377B4AE558D0211, 9B62C7D0DB0A1F1F71060373F50A34A3A8956CB4C6ED4AB95B400369E180F74A, 2074BE51F968B87465918C164637E3388C151DA1454F9F5696D93C0B89F5B795 10088FDA671E0B00A70633, 57789C6F63C6D8B3E1B8D2DED479226BD3C4E15D76A8F184F6434DFD51C95EB7, 2CEA6ED3DE8E8DA3FC023B7EF1879D4035F6FD58A9F5B2CFC3AC0BA58C6CA623 3019AF8F355A2101F51299, D8BFACB83417C2B665562F70C8AA2A54049B5490BE83D35219E61F4F3AFA6DFD, FA0EA105DC3EDB5BFB57AB2EB0AFE60439F6FBF7ED372C41E23CF87EA1D7D7A6 904D0EADA00E6305DF37CB, E05FDA5A217409FA3682C6E5707D440D3DF750C185C58CDCF9FB96D7029E6727, 4E336308069F06AD9140C23FC466A16156F5E96E838213AE77F98CDDB1C36A1B 1B0E72C08E02B29119DA761, 84090FDF8B97262415190B79DB0D272ECE5CB2F374E4C05A524DF214BE291BAB, 1F40013072768A2CBAC51F4C1F1C03FE57BE78DD50630416450C9233682514A7 512B5841AA0817B34D8F623, A3E2C85B131943FC0D17EAEF2B5A417D31C82139ACB2DBCCE2ABBB47AFB8BD1C, 9BFDD98C5698680E991367A49595BE03693E633F6D3ED8D798D8D16F3B4AF3B6 F38208C4FE184719E8AE269, 38F0BE60E0FC25D6408D876E330CB8EF1EB27187B105D16B1629173F8D68B2FE, 5EA95CBB1C921B1CDF7B3EAFC19B38B86C0C014C8310ABCD47AE72332FA3476E 2DA861A4EFA48D54DBA0A73B, DC28C706097F7625A596B6A820CBFE34152C1CB3B6E98A45CF408B2FFB9A4212, CA52B09F3E15F24719FF2957437117225F89CD191B926868DF67ABF6300A628A 88F924EECEEDA7FE92E1F5B1, 757C39D0DF71B146F31A43DF4399E4D48D2F4310B4686065D1151C00BA3DD58B, A9EAEFD96F3B04DB4CF7083552BCC39490651B3D25939B976273172EF2148CD0 19AEB6ECC6CC8F7FBB8A5E113, C5CF26F8A81A725795FDE9E4D87D5D3A65D02C62BA9A314FF3C452287CFCB3BC, 7A6E7E4F2F6F5B01B6BD56D85D5A521E202DBE1C92C26E4EFB53A42E82132FE7 4D0C24C65465AE7F329F1A339, E4A096A0679B179692D761649FC84D12633A45835BF68FF0F6363BB7ACDA2C20, D583B39C13EB95321119438A0FEF948B6FE153AB86CD3B04D68C1C996E0077F9 E7246E52FD310B7D97DD4E9AB, 1EF7F3BC67DC61B3FCA443E1BE7D775B88F177DDE0DBBC4F87747F8E1FEA5773, 49D9B998A6E36EDCC36EC02D8FB19FB7B9C62773EFFAD5DDBCE44EA8536DBA19 2B56D4AF8F7932278C797EBD01, B62940D11E471FDB4D19A1C031BDD77D03D9EB7872F1E346C4D71C84A5FBEB2A, D6A251B89ACC62DE0C334E772BB10CF98D42213CA33A7D80E1D5FD97A6BA7588 82047E0EAE6B9676A56C7C3703, F19C132F1A7081351289273DC31E2383DCEC911C26A5E72B479310EFDCA4956A, 5DA7EC8045266BCD898B3B74EC70C50F3018F6358DB778DCC03085327A5289E9 1860D7A2C0B42C363F04574A509, 49E7608848B7D6FEAF1C2E3099BE6C27CB12FA90C152CFF8079245EC7C99FDA, E2D3BEA787376ED5A8068D0DFFC52DF910979622F4C6E7B8C366395E6D79EB1E 492286E8421C84A2BD0D05DEF1B, F1F7EC33D596D85A2DD9F97761DA0EC886A28A8E3785B1C431C808BCA54AB101, F5E265D2AA027AAAFF41EB6C62C0C2B45EA12EB74BFBE90BA24F7AFB2023C613 DB6794B8C6558DE83727119CD51, A8AE6416C72DA357FE356210B220922D91459F8017B948C939968BAE6A816FD2, 19192FDED9B5BE5F6767116343ABAD2B918D3E1E69324E8394C3AE15D18B363C 29236BE2A5300A9B8A57534D67F3, 802604495D3CAF58CB2DB7EF1B5A9489E8F1EC87EC2FB8755D13A712B9F29F28, 8419F80449048AD209258E35789417524E5279FDC69291AE75C1E2E0FC3BC923 7B6A43A7EF901FD29F05F9E837D9, 3256A959AD2F07223CCE16C4518C5FC0A048C2F275D6ABF5A0E75D89B4AE4641, 5770511F6606B0A9C31BB70996580A9D594A7352E9F0EAB145521238A1D0E141 1723ECAF7CEB05F77DD11EDB8A78B, E3DEEE86BAB797332DD6C21DE8E6D3CC40236C52A409B2B2AC77F2EB450EB271, 5149CA7FEAB69D29F8636DE57E8BCCB7D2DB60F41C8D6294F6863E29AD46B6FC 456BC60E76C111E679735C929F6A1, 639346FC6E6328306F4EB3EDFAAB0032027423AC593C6BDE70D6D15FBDFD94FF, 648B19BBAA5AAE60A88FBC1003CBEBB684977372D1DBB7D06109421A3BA65043 D043522B644335B36C5A15B7DE3E3, EDF2B3D2431C8DF28E2CAEEDDF543B82EB427F9C176F3D6E7A7E2F796B01BB91, 803FA14E1D972D8D1B9731C69B1BECE49B8B5DB5F0F35F0DD83E58960F8067CA 270C9F6822CC9A11A450E41279ABA9, C0851884918A2A184BF17459E52C18138489928D34EB18C4145110525CCB70ED, 5E2BCDBDE7699A6C49D22217799C78B881D07A3F6968F21294AB9FB9BB80CD05 7525DE386865CE34ECF2AC376D02FB, E86A26AF7DF39DDC653ACDC0FF0C106E9CC39A52950B66C813ACACFD7EAE0396, 894E0A381D815ABFBF2935DEC8B5FCF1AEDADD8C8A733991B7E6A1F46B22E5C0 15F719AA939316A9EC6D804A64708F1, 3BA575814160D9E223A87EBEA660EE5B7801E07C94FE56CFEBB8C7740B2DCFFE, C057035184B7BBA91FF3B71297AD8482B9DFC0B1BF0395F0365AE5E0EB535019 41E54CFFBAB943FDC54880DF2D51AD3, 26C0625191AA21183B99D36778865073A8A07CE5EBE1124BC796D027EF884B43, AE8B3BD095D79CB195CDD9FBC1078878B7EF018902B504A3F1B8F8B291C655F8 C5AFE6FF302BCBF94FD9829D87F5079, 2EC7445C966E75B5096FCD85DB95E5A46B8214C0B412E6483A70DE7AB33E9F61, 1F06DCCB29051713852C3D9120D5DA846B868105F5838993B48E649BE7660104 2510FB4FD908363EBEF8C87D897DF16B, 515259E8C7DEF6D58539D142D4049D6C1CAD70C1EBAB248E7ACA4113CDA147BB, A25072696182B4EF15DB2A453D4253491A86BEDB929A1BF10AEC1846A68B2A9D 6F32F1EF8B18A2BC3CEA59789C79D441, FC9D89DFFCF825FDE96C6A3E1185639B51ECD409A6EF3FB016D825BBD0275A91, 4BE6FE0665F733F48827BDCC02E14FC0443D3BB6D165956A12F6A49350568051 14D98D5CEA149E834B6BF0C69D56D7CC3, F43AA390DB46C4DD0B16E616CFB9C56556AF36E3208B7AE109BC31696A12E8A6, 7B26118F753416608949A5425AC4FBA4C73C799A92EA56A07D3C70A60A37CA6A 3E8CA816BE3DDB89E243D253D80487649, C519979CB8BF80734D6122317A41B2B028C00F9D670B2351A2556150D3AF52C0, ACB6ADD534B0D4272B93EAE9F8D77A064F51F9A110427694EA8EE9549C5EF270 BBA5F8443AB9929DA6CB76FB880D962DB, 3EE87C4796A96E074122A62B1953BD3812489741BB88CA714F20798F8B27B487, 2A8B7621DCD56DBCDAA3A4AC5D7B1CC1D78586969CDC9738F97A0DE7D469527 232F1E8CCB02CB7D8F46264F29828C2891, D37321D22010BA39741189B284438540BCD88595890B8AEC37C8F50A106214EB, 9384CA1E485F0C77E3CE399D1518021D33F1C09454924EA1C7377BD9F46E4064 698D5BA661086278ADD272ED7C87A479B3, B0063A950C72BED8F3AA2D87E7F9728CBDE2AC10AA203CF0A507EC2B1F431972, FC9D164F254D82AA6DFFA81F0C0AFBA525B2AF3F5AD1914081A3AA57D8424A0F 13CA812F32319276A097758C87596ED6D19, F46A205F21E8560CE289D4FC7EDA91AA9302B722435F24D3168FAE1176B0EBCE, E1F04C816D7EA9783538D556B58A83DB5ECBC835559CD620D7527BDEF66D2AF7 3B5F838D9694B763E1C660A5960C4C8474B, 27ACBB5308966BF46CD907C16A73EEA175B6A8DFF72BA8000CFC0C5D8D3CF1B1, 4BA2797C5210175846145355E7DBF420DE8CCED60A0F2C3130EFD226C66C0084 B21E8AA8C3BE262BA55321F0C224E58D5E1, B5C3E7F3488FCD747D7A654DF687E7229B48D8B4350F3C48A28BDF16616E9989, 6425C6B6A515EC5152ECA6AAA9B7DA7636DADF51C2E54429828F0938BB4934E0 2165B9FFA4B3A7282EFF965D2466EB0A81A3, 379B3609C349B0E1DAD8C90EDD479E70F278F5BB7CDB365316E23DD044A0516A, DC79E2235CAAFAD8163120508E6A233A60883119E36A625E8A11328957072B9C 64312DFEEE1AF5788CFEC3176D34C11F84E9, 7538AC4A0F08CCB59A0193BFCE0C12DDC80C84807939190B0629C510C804B714, A8B3FC8066FE1C94383F4C4188271EAC8383F2BA6353E289518C7F0F7B04AF7A 12C9389FCCA50E069A6FC4946479E435E8EBB, BBC2076BE1060AD9806A9FEE9C39DCF83E8911CF108ADD64DDD9A1F5913022FB, 99BD974AA1EDC414FFE0CAECB42E3AEE437DA6480E93C5B8A9DD476939B4BAD8 385BA9DF65EF2A13CF4F4DBD2D6DACA1BAC31, 75064663173439F4642B322604A5CFDBB542E474555FFEFECB1FCE3B5175412, C33956CC23C2B31CF01DA801E18571535C27C5F5A16A868034571259786E3C3C A912FD9E31CD7E3B6DEDE937884905E530493, 41B3248D83A738F9D18187BD61E3A3DE66127F8C7598320653F4827E74F1ABA9, 535A0212A912E134E0AFF0792062A7E8AB70DDACD27A84E15771D52789D0BE83 1FB38F8DA95687AB249C9BBA698DB11AF90DB9, CB0D26B71EB1A3F0B6734AC607DAEABA8FC174E58F09431022D27A7EB3E0390E, 98F49A1576BEF607E105FD66233F5F4B3EC2E137E3191309E025233F12338CA7 5F1AAEA8FC0397016DD5D32F3CA91350EB292B, BBA6B4AAB4E9AFFDA12A1B46BDE8BD974B9BE34927CA1CF60414A9A118145EEC, 1506C0C1C16DD4EB36FC0CCDBF62FF6E83338A315D4FE7D198C41021595C9FED 11D500BFAF40AC5044981798DB5FB39F2C17B81, D31396ADAF5CE28C15DAD95035DA92470821F4EF5F0580A76D47F01A595336DE, 6E15BC1BAF9CB2B85ABE5863AE8174D9C7E7AFF65A253D7627100F21D5805E8F 357F023F0DC204F0CDC846CA921F1ADD8447283, 9D29DA456BC96B1A6098E5D33C6A28D09E30368D2864EA09A392FE65903B926C, 3ED2BEE9A1F81625B56BD99534F4F332FC590960BF879251028785D75AF8B015 A07D06BD29460ED26958D45FB65D50988CD5789, C9185F8DC5E5920FDC3E7BE8DC01E225FEE33FD36878AB8509F85B5306FFA9BF, E3CB73400EF954633EB052C2521D0AABF57C3E67C24DC52D999486D553C7E85 1E17714377BD22C773C0A7D1F2317F1C9A68069B, 42A227EEDFAD4F956B08220D22CA0BE899F4B53407968C28DA2D8A1B7DB164AC, 4A907645D663C2685F6FD6DF0DC5A6B6EA158D3711D54C20E269FCDEDBE315BA 5A4653CA673768565B41F775D6947D55CF3813D1, D0D9EE4E36C677D83C325453BF023BDA5AFC8D58E21D23C1054F1BFC64BB53C6, 2AFD68ED137B3D199657BA1818CED99986F51FD25B482035544E6DB6EEC374C1 10ED2FB5F35A6390311C5E66183BD78016DA83B73, D5B0A27331B72048E0256C1889452B91E366A6174BCE131707D7714A77EAEB72, 5677E46D5757EA41DAC027757C3FA37167EFE9899882365A90088AF78E70864C 32C78F21DA0F2AB093551B3248B38680448F8B259, 601B3A7F661400DC5FE42836C3179183437C2FAB42D177A9B4DB1E3C3D001BCF, AEE8201AB9C8A131A9BE793AA5AD2656E617C9F6756A07A21B6D0CEAC1F986D7 9856AD658E2D8011B9FF5196DA1A9380CDAEA170B, 20B5805698BF8ABE22E9EEAEA3BAC3997386EB8AD44978C74A96C82285954243, 74717E6B981FFA53DFC4DA6A594F5D1F19502DE455F4E76FD452DBC43C006EE 1C9040830AA8880352DFDF4C48E4FBA82690BE4521, 5DD4513D170D41F1C44A39BD70BA0F893514E621938B46BC7ED527BD56CF229B, AD7E0A11FD54CF08360541F956DC20981C338736AF5CC9CFA02944C25E450DFC 55B0C1891FF99809F89F9DE4DAAEF2F873B23ACF63, BCBA4F7644827255373B8438FF87536AB8B311403E566509EBEACEFA63795C53, 6B33C2E0F5E5295A540DF25382ACF3F7A43A2BBF87F07362500846A09A995928 10112449B5FECC81DE9DED9AE900CD8E95B16B06E29, 2C4DD6E270226605AA870A557478C45818C2FBE60A3051602938961A898A47DF, 67809BADB323B5771403E5451F1164D30B153BF06264D95C5506ACA551808494 30336CDD21FC65859BD9C8D0BB0268ABC1144114A7B, 172E760F60F5832A4102279B67D7DBCEE5D6B160D08B3406291B2602B6380123, 6BCF9F3127D34CA4018B2A353188139AD5BB27349343973BFAC8C4C8F7B06FB 909A469765F53090D38D5A7231073A03433CC33DF71, E5EFE6615988FDC242F4897408F12A775E9CE30EA49E86768A50D75B1D29EC2, 811C3E746DB0213AE68C4A59DCEFD8D97B025642ADF378D1D8DAFBEB00902EEE 1B1CED3C631DF91B27AA80F569315AE09C9B649B9E53, 11230F173782A6F4015B5C73F19BBED3B4A77A42194CE966634FBCFBC55FAA79, E7F5601F7142B324399DBF432D96E3EC7DC1E9C1B3038EF671323BF544B3472E 5156C7B52959EB5176FF82E03B9410A1D5D22DD2DAF9, 2932732777DAD6699B771BE1588FD7A8755125F75211256AE80882301402E8E2, 21E71D0914D952CA1EB4BCBDF5245D6063E4F414DD38E7DCB9FF35CA2328D644 F404571F7C0DC1F464FE88A0B2BC31E58176897890EB, E1DC9FBA51344E8961A9F1BC2457BFEB72E012FFFACF6B7D878AF94685A99783, 2C73575BAE8AF4E6729AC50A8BA3232CE3A508899B82BC40124EDAFFC148662C 2DC0D055E742945DD2EFB99E2183495B084639C69B2C1, 8C4E50B668E48CF16D0424D5DF62FDF56D81664BB1C86D6E227E1148E57F875A, B5A3360FDEA16D4B198319417A0DA67F61B05FD17545DA2F102347D9B854A965 89427101B5C7BD1978CF2CDA6489DC1118D2AD53D1843, A0E92557F24612657AD7F806B01783729DB117684D1CFD3EEA21AF00239DAC4C, 1E5DBDB219B477DCA45F33FBDCA3563EFC0238A800FE63AF67E229346C093EAB 19BC753052157374C6A6D868F2D9D94334A7807FB748C9, CF09FEEC622B4510F5454E6D607D6A0DEAB9747859F04675E6C82DBB49BC32BD, E4D6AEA583107B538291B8CE6D18BB1D8F88B52613C8DABEAFA634D472EB47E8 4D355F90F6405A5E53F4893AD88D8BC99DF6817F25DA5B, 9F1E4A1D7B7102C71B2C94FF205E3A5B466D61BA76A38DB5AF85A2FC47A57865, 7A0B26C93C1E627E33806C188F92341507B172B325836CB3A89F9DD153E2C652 E7A01EB2E2C10F1AFBDD9BB089A8A35CD9E3847D718F11, 6915B63364675BC7AFBAFFDF78D9238D3D7FE8525AE6E40525CE9164C5900F47, 1F922B67DF773EF9DDC0303A9173D4A0D2A294AF23AD0629B8C9D84C29B061D3 2B6E05C18A8432D50F398D3119CF9EA168DAA8D7854AD33, 88E314A2C7AE62DB858AA1E9795A5A89F2FB360A2AC6D4426D7A3A455EBD3BFF, 27CDD0A660FD359BB4EB9CEA269BBD47D4D09904CE636FC6E470CC7B212AC975 824A11449F8C987F2DACA7934D6EDBE43A8FFA868FE0799, ABA0CF697B1B733B287C0A97ED1FE76E29ABB4FC913E67443CE35082A92CB204, E4517A1AED272352E021638B812635F6C601BD46D04DF1EF3B38D4136C46C556 186DE33CDDEA5C97D8905F6B9E84C93ACAFAFEF93AFA16CB, 5E42DC088B475F6118D595BB3E79E896F5B2D8704890A1A0501702EDC00E8994, 1A822DB338757C5660D439700AA2183DF58FDABCB75E7ECDE52727FE5F18B220 4949A9B699BF15C789B11E42DB8E5BB060F0FCEBB0EE4461, 408FE43D610E979002BCD4BED86DF136D1A75ECAA324A7B9BEA97520C3854EB0, 7986FE1E891C6207C55AF240C7DD10F69A819CE9F62FAA1CE2BCC0CD701EA243 DBDCFD23CD3D41569D135AC892AB131122D2F6C312CACD23, D16513119B25F3BE15558FE23F5B87BC28C2189B706EBE95719DAAF309273834, F0173989C37D2E786E3110CBD4B6E56C4FDB00D4B21B85723E1784316AA1C047 29396F76B67B7C403D73A1059B80139336878E44938606769, 3DAB6AD259B5F731E52FBAC416D3BEC5DD302D6EB68C518F7D8D930A134B36C8, 7FF5B6B018B0EA0FE9ADDE3E7375545098B5E3E259CA449FE20C56C2FF496F26 7BAC4E64237274C0B85AE310D2803AB9A396AACDBA921363B, A5C296195DA154D92C3D19541995F590B88AC659F9F74B9897230977BFDD2D5E, 8904813927D5C1E6B4F3905C8C51C3B14DCAC2719201A8EB05D689628148C1BF 17304EB2C6A575E422910A9327780B02CEAC400692FB63A2B1, BB9CF3584D191A4AEACB45036D831C849DF57560084E52A72067D3BE614E750B, 54AB4A833C01CC422A1A253EF92A60FFA34A20BD82E8BFAD6E15558ABDB6226 4590EC1853F061AC67B31FB9766821086C04C013B8F22AE813, 5FBE2FC3B80AD6CCE2607AC27C6BAC3653A234BFC23B57A030DAD8514A2C6216, 1ECE4BF22FD472071C1C9F236504A74CC79A830DAC770D5197F39396AE2BFBE7 D0B2C448FBD1250537195F2C63386319440E403B2AD680B839, B353A8A9EEF105CCDB44FD3199CB6F125CCA844DBCEBD50CA02BAA1600BC50CC, D02DF9BEBB10D532F76D7311D563CA98FAEA4CBA7875285C846A8EA76B0D1EEB 272184CDAF3736F0FA54C1D8529A9294BCC2AC0B180838228AB, 91D63516B8BB7FAEC5F621F5A9675F3650E4C816CCF87E80094CB7D6817A366B, 51747822D2D489E1A9D5082F36C2C15054B2747EF232DD9D08BB1B3BF944BE20 75648E690DA5A4D2EEFE4588F7CFB7BE364804214818A867A01, 15E0B6AD6FFA887741DE3014BF4FBCFA1022FA8285382D8D5C69EE243EB3541F, D04B1F1C77EDE6A5579397AA35EB012EAB1C31423B2224AA972CD8471DE8D3D8 1602DAB3B28F0EE78CCFAD09AE76F273AA2D80C63D849F936E03, 18159E5ADFA2E5478A196D3E973758F6D6A24E90BFE666FE0934E3567F212D45, 4241715C90E432F154949B3D82CF2F2EF48F0C17FFE7F532347C8DB4B30DAA1D 4208901B17AD2CB6A66F071D0B64D75AFE888252B88DDEBA4A09, 55F7D55C605C0358BC078616EFAD8E90CCB6E737BD9D1CC10F5BB8A83B49F257, 39345974E4659E643CDE92C9EA5383F2FC74B533B359A701D4369E87C5A87384 C619B05147078623F34D1557222E8610FB9986F829A99C2EDE1B, C5012B7A288170DA3E0C9B30C558424060777BB1AA385D7BA777D3F2A5CD570B, 269487431A01A4958ACACF309193F80E09E762CD45C228B31D7CF3BE064C0F6D 2524D10F3D516926BD9E74005668B9232F2CC94E87CFCD48C9A51, 494002E29ADAAB3BD42DE827969021162576E562D318A88E6839B0632BEDCE3F, 4B659BC6EB77EEAC9AA62A9B0A25283C285D350002865ED266357C978FA9AFA2 6F6E732DB7F43B7438DB5C01033A2B698D865BEB976F67DA5CEF3, 8937CFDC5B97748769F993BFF1FC5300A102362694F9CDA200F5A3917E734947, 3D77B10A04A27B8C79375F6CA5F24DB11A02620065B9A5DB088D246DD25BBE52 14E4B598927DCB25CAA92140309AE823CA89313C2C64E378F16CD9, 2496ED6C44A9C788229A5205D2AB01F491AE4217707F18C27F5E63B567581A1F, E394A06C008B80E00BE7FDA6A79D45D13422B5790A871F010B6C92EEC8AD15A4 3EAE20C9B77961715FFB63C091D0B86B5F9B93B4852EAA6AD4468B, F21CFFB3EAEE40BA9DF1DACB4CEC7F65DF71910445027153231DED0F452DC3F0, 1D03B97F11FE7BF87ED8485583EC19B6AEF9A236F3DCCF88689EF77211E21AC8 BC0A625D266C24541FF22B41B57229421ED2BB1D8F8BFF407CD3A1, 645112B55D4EFC904950086C082DC4D3D41A8E164E86C01554909C0118686C2A, 6B68130DCD38D7DDFFB0B6C24F63BB856995DD1A1699847F67935A7EBC07ED95 2341F271773446CFC5FD681C520567BC65C783158AEA3FDC1767AE3, 93F17111EFE40A080B8ECB79E19B0176E9D80A46C0AC6F68799DEBF64B31F72, FF64A78282EE7D13EDCA84C46F0869C6BD962D02460EFF4DDD8644ADDAE46556 69C5D754659CD46F51F83854F610373531568940A0BEBF9446370A9, AE69334BA71DBD00B72490AA9EF5BA78A2E20D515F2CA5C6F926D9C08E3B3259, 797BF85C91245664BC1EC92B9A706977FFEA62465783AE9D93FAC6385A74FDA2 13D5185FD30D67D4DF5E8A8FEE230A59F94039BC1E23C3EBCD2A51FB, 5F038A8AC8431F9321D202C24005781866563A68A2BD832BC55CADCAA0A51AD5, AC0696E2796C5A3112CF6ED1A7D9A08FC3D98AB9A24C8FC23A24228D5AD8C8CB 3B7F491F7928377E9E1B9FAFCA691F0DEBC0AD345A6B4BC3677EF5F1, 82DB9DB3EEC13250057CF1BFE491A65657160DCA8D8B2FEB6FE6FAD546D4F2A7, 84B0E6C31FC401C5305381127E0BA9D69270B4013C54F490E153A075827A6908 B27DDB5E6B78A67BDA52DF0F5F3B5D29C342079D0F41E34A367CE1D3, 34B824BB7171AE67B8D36BDC03BA146348E472024C48336F253A55FFD92EB98B, F86CB5EEECD0A02BF01D079BA5CF97C797C5AC68FA2710E396C9BD45E0407C69 21779921B4269F3738EF89D2E1DB2177D49C616D72DC5A9DEA376A579, 279DBD6D1E7C0856C628499CED784DA0E025065E8CD73CF468281147F76695C0, 15C322F07B13711DFFC4F90149E49679A3478FB598C013724570F1C042B1CA97 6466CB651C73DDA5AACE9D78A59164677DD5244858950FD9BEA63F06B, 88F6C763894E985C100A297CEBEB74F0AC2200A6CE73E1968973F6DC093EE523, DB6E1A86B52B180EC1A61C61CC574DD86F9A75503F905679DEB642617BF36EE4 12D34622F555B98F1006BD869F0B42D36797F6CD909BF2F8D3BF2BD141, D5D356D043B1536C5D197072C9D15592EFBFE8D34250CF7D20FB1AA7AEB348A5, 56A5F938EDD5FCF99D493874F71D6D893635255A88726D9C35AE85D77194D385 3879D268E0012CAD30143893DD21C87A36C7E468B1D3D8EA7B3D8373C3, C14DB8C85E0B6D2B676E4C0A250649A85FE73C8D0C7B453F1C4AFEDF67454ABF, 895257DFB694ED1FB4485800DE790065677C29C0EC2D052A884C07D480933A54 A96D773AA0038607903CA9BB9765596EA457AD3A157B8ABF71B88A5B49, DF7D5C7CF72E94C8C8BBC544B593AC942345A022B8F252D517FEC874AEBB57DB, C7D88559EFD4407D8BCAA17618E49AA4CB144788696020A15507F2FC9C287EB7 1FC4865AFE00A9216B0B5FD32C6300C4BED0707AE4072A03E55299F11DB, 6F6ED9FE2B4AC0DA65688AB6597A4FECC2569C7A40B8EA464A433C399801B87F, F6081F2CD5035CCE5720C1994CAF29AEECB703F862D6041734049FBF89D00495 5F4D9310FA01FB6441221F798529024E3C715170AC157E0BAFF7CDD3591, 8BB82D1D4814E632E56B14E7E14A66EB4D199B8DB27688D93109C02A83C03717, 98269529F24CCA3CA4385B62FE340000A315A5BE887C6C914B58A0E71FC2B113 11DE8B932EE05F22CC3665E6C8F7B06EAB553F45204407A230FE7697A0B3, A33FB3D793FA380AF2F28AF7A62D59A92D6BD0C837D01BABCD439C47C270A090, 4B7DABD362A3CD41D839684D8F247DB031B9EB5A06F808360288B0AF42A645CB 359BA2B98CA11D6864A331B45AE7114C01FFBDCF60CC16E692FB63C6E219, CE26845F94DEE7E0061E9E5C14A7CEA984708362168320A5A0E83029C16A2D9B, C02FB0DF34C761734BAEF1573B4854E24174372E735AAB81E616326D406EF10D A0D2E82CA5E358392DE9951D10B533E405FF396E226444B3B8F22B54A64B, B859547C4E7207BE3CD43268192AB88A88BBFBBE5687E8533C7AECC6A1D2BF61, 7E53936BC792436E53C10B930321945784E885B43626B26739DB84A713E002C5 1E278B885F1AA08AB89BCBF57321F9BAC11FDAC4A672CCE1B2AD681FDF2E1, 22CE0FBE44DE6BCDF09CB9D85FEA1FEE51E515EAED6CB21B8977C7BAF5981C38, 1DEE07C7AC027A082F77EC582E2EAFE281F7AC1D709788323DABF79E5A73FBEC 5A76A2991D4FE1A029D363E05965ED30435F904DF35866A51808385F9D8A3, 2ECC1298F418914C6AF79DE90BE8021E3C7F81ACD61F0449D3ABFD9E3DC63997, 8D229C381A022D2AE62A7B4E481F2564202867A4FCA904D4E91CC6B70C3BB10D 10F63E7CB57EFA4E07D7A2BA10C31C790CA1EB0E9DA0933EF4818A91ED89E9, F8F4F6A1955A9B753D766668CE35829F70030A14CD05853AA09E6F610CCB168F, C6AE8802312258020113FFA9576856155057345E8DE06B43F5D8EA9DAAA9942B 32E2BB76207CEEEA1786E82E3249556B25E5C12BD8E1B9BCDD849FB5C89DBB, D7428B9DDAD0BAABB29E93E13F764F941A00E4645F2590D7E2C1EFC84D91568D, 196696F277C70CB49678359D63AB99AD479B6B9644CA1CDFDD2A1BB3EFAD249A 98A832626176CCBE4694B88A96DC004171B143838AA52D36988DDF2159D931, B8E809F295A7623691734C066D59C8FA0D280159ABCBE1D42967A513648664F2, 280F44E7306591A76646D5FAD6869034A5176A4C361B374E8C6D3CFD333D5DA 1C9F897272464663AD3BE299FC49400C45513CA8A9FEF87A3C9A99D640D8B93, AEB5B4C2AAE2B8F67DF988F43BA523740CBA257BE4422213F4F2A162E4A5BE4A, D42994CF1C0EC81D51EF67AC67F7E77FCB1DFF4A0E031ADAC893EFC3EA9C0AB9 55DE9C5756D2D32B07B3A7CDF4DBC024CFF3B5F9FDFCE96EB5CFCD82C28A2B9, F9BBF4C0749790F216CC5CDAA17232BA85B3729B36A4547F795A74BA4BB31F3, 322EFD9EBCA43A2625AC3DB8A785DB6FDE7288258B64FAB6C824013568E1AA34 1019BD50604787981171AF769DE93406E6FDB21EDF9F6BC4C216F6888479E82B, 6336F3F2C0287F1ECA291AB6434163DE79B45E68DB62986970DED3A46D38A43D, 4D91C779F2B3505E0952D2BD1C3F59FC91B625546C5087E9E7D39347DEF446E5 304D37F120D696C834550E63D9BB9C14B4F9165C9EDE434E4644E3998D6DB881, EF7444E99D2F2A08ACE89C4143B0F95078F15B7F4FC7D9341766429383589095, 215F00149824E1739E36F1E6FFE3EAAD9C08DA5CB082F3B1DF0A3F2349DDD9F0 90E7A7D36283C4589CFF2B2B8D32D43E1EEB4315DC9AC9EAD2CEAACCA8492983, 4B0A4283D9A07E54E2D09B415DEF9C09C5230568EFE290E696F2957F75E2EBCF, 22FB66F09632C8A9B39DAB9BAEA63D364B93FE0D4B508DEEA6F4716C4E5616F6 ECC-384 1, AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7, 3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F 3, 77A41D4606FFA1464793C7E5FDC7D98CB9D3910202DCD06BEA4F240D3566DA6B408BBAE5026580D02D7E5C70500C831, C995F7CA0B0C42837D0BBE9602A9FC998520B41C85115AA5F7684C0EDC111EACC24ABD6BE4B5D298B65F28600A2F1DF1 9, 8F0A39A4049BCB3EF1BF29B8B025B78F2216F7291E6FD3BAC6CB1EE285FB6E21C388528BFEE2B9535C55E4461079118B, 62C77E1438B601D6452C4A5322C3A9799A9B3D7CA3C400C6B7678854AED9B3029E743EFEDFD51B68262DA4F9AC664AF8 1B, 9C5FA2C13F418E623C316D5A82C8B70508E3ACAA2B4A8D3A4ACB49C0D7BA04E220761BC15898E1B06B4EEDFA23E2E546, F641DE0CB075851A5AFE81503CB7BF6194FDF1B7DA9E59556F015651BD9218E30EF2C4B2213F519B529FB56479F48752 51, F0091B1080B24C407E983FC77C0527861E28CC8D5C9C5B48B1F416FB8F72FDBAB1BA877E2DC9EA82187A3E46D072AA44, 22492B56C351FC882CD63A572FBB7A794EC8CCC18F16F8F352071D69AF769F4E7ED6077A9A08429B58810F8CFDDCFB8 F3, 5A815D846315E5DBD155BC729B098C810D68B92B05ECA2849230F66A356158C4A1856A11CF7BA5D563BAA6F3AB3D0087, FB880F0D6F85075B70191837CC459851981406857F03F6C8EA0D2ABC5042F0EFB9FC97561A63C71CF8159381F038E7C 2D9, 2CC6E0DE17D86C60A9D764CA17E6B3BF8FF48AB9E6E38EB0996BB6CB36DCD276B61B24C5DC0F7C1083FCB2A87B493240, C86ECBB06ADD45F4FBC5D411AC0B9BB07292D7CB6FDAC1167728A7B825E226D225A3F90DC40DC7DA4F10106A7412E7A3 88B, D5BECF937401D03C63994BAA76FF1F359A554953B2613F62908B47497CBE15A5F124488C3DBB9F13DB9409751AC6B9D0, ED2841702966C15664AEA733911FD1C00FF1258A5B6C9F00530C0BE9EB940909D8F519D50D08ADA801D35D6EA04C05EF 19A1, C7A8AC69A56E8F724AFD6FD01CA9EDF2D427C332C596992C5F3B54D57911FC5323D21242E4942135649F382EF9A2CA8B, 4186C16218EBBFD84E4DBE3583E37D7158071639B84B9FAAAECF1FF6955F6AA4B0BD21BD5DC7C2927E76C7AE49585543 4CE3, A4B32813B19844D83A31C9D638DD87F16D7EE7A32D49A6A99D6A902AC26082E41EB9E77B1D44C02E9F48F247D8DEBF11, FB66140C5C887D1CA28EEAF5B8DB7B25AC4DB1A49FA6BAB93639E4A1DAC6479447E8F4BB1312946E0D07CC09B63FED51 E6A9, DE58069466D407CB27257473DC08FD2BD09D262036D56ECBC0BA9F582641294B18D7B1285E9290C55764CA0E7167B05A, 4248B42C8B6FF55AC40A50191D86129375C7A6C3595EE62A12F74192C9A431EE1BE1341D824CC31AF10370D8DB358BED 2B3FB, A9EB0041AC0EB5825B04B81B34D2402E1F14638B62F4BAA5E9E3F47320AE724F7257387BC470A0B77E1F9855155018D6, 707400FA47C87C696AB61A610D68A34482EF3FF32D2D954E3543F27C2A9F04B261DD53219E14F61B4D5F9CF9CBD4260F 81BF1, DB70CB69AFC2C9BB0EE647BEBEE4F908F43E04800B8685726E1BBBD19AF36B9CA47D1F460923A00CE54E9F03A462B4D7, 7FBB8BECBB33AC921B3C58DC62ED4E339B1A715D5A24137B5DA6C48D8123DD5A91D3A4FCBF8E1C8DC4FD80F7541202D2 1853D3, 5B513BCC210FEDDABFAC368CA876F91808FF8D082DFB3DC6DAB494797A547F2643BC1C3D05770E0F39F08A1C52599BEC, F6D2A470961AFBA04D94E96A4DB1DD413DDBFA0449C16A72EB95D39CABA47A3CB4FF90A7C8085CE7CDA3564D0DD971CB 48FB79, 2AEE1407D07D4B8101A86061486B19D9399CE28345A1992A7CB9EAC43F3A13941CAE792E3402867B080BC5054D259F6A, 8383EE4A9984E0CC3F51CB1BDEE6BBA3A14E503D09EF36FBA83BDE79A17BBBD9663CE8AA4CB778C8F8252B309790B120 DAF26B, 6E640CD04E1AC2A7957987D2FC85EA7688625CAFFBFB587770F26E1A44C682A0D947BE7BE485233006AE59ED12B25625, 1CE1DD4F5752F802D264A68F5137CC5F0C76F24007ADCD6C2585F33A21BF4FEAE0C8E450A6FB79A0B091674BD22BB668 290D741, 9FBF2CBF74EF244D733676D051D0314BEACE57207E02A53BAD5BF777D99EBF3B217705790EE17CC41EC09809E64F6A27, CCB0A336CF5B42BC181EA33476CC4F348710CBEDE690B39C578115D1E085CFF5E51EF95634C23A71226563FA80E55AF7 7B285C3, 9D94D0999D059A6E294DAEF56F75809D824E8AD91026BF00C792953330B5997B51848ECA853F5969FEF12BB877A7EC8C, 46C61C9C588D5814B789643D945277D6E7801877A09B2EA726567F11B2DB7A06526FBEF365B6FBFB4D56497814BFD97A 17179149, E6A9F66A755375FEDFE9EF57DBB63A784D541BA6BCB6FED27FE4D4B5605E5A6F83AFA71EC1436091B8B64E2FCC27F5A7, 9E5BBC160854223B74CF1E0E26C7AB304A3BA3E6392C1F74EA1BA8C55680171B01D278EEF74CB3B4D7F390C86005C21B 4546B3DB, F806B14FA71B88D0F6A8B54E3708E45040A85999A70C13D40E06990F3630793A141FC517E95CD0021EA1621C951A4A2D, 72870FE8BE24B5F749322F9197AE03DFF1E4689AAADF78BBD4DF16421D5D59E2AF2A5B499B7A1919EA311053E6EB813E CFD41B91, 139EE0E2DD813FE72168E8876E14A03EF31F4C3FBFC01595733B809A7C1B8CFE6014626622BFE2F6741E77B27123815F, 3D2F7570CCECF08D7ED8451AFAF7A06D94BA65545A20B8ED6248B24988B724F234962DB05E2A6394D344FF64C772B9B6 26F7C52B3, 13BAC5430DDE14CDBA331A82158D3A45D2CF09D30CBD950F3606103BDEE195179ABBFCF3BA58B664A5C97156ABFE3374, 74A00DBF0C6E447031269B041121D7C928179937EB907FAD50DD4A9F128FF462BBE3021B01F9DE9C712425BC7508C0F1 74E74F819, 8959A4D72613CC021D691B8DFB887C22870C01354A6B0C185CBB535945A19AB5AE476A58605A48A2568F3A1489B9827A, E49AC7C932874225A94A3020CC9E83415E9F2FCF77A2D70CF6BFCD2F890D2719DB4E3FD816C76D4D3F3F104AC76C0353 15EB5EE84B, B54125CA1A5CE47ED09AB99872804FA8149E5B11FC65AB34CD2B30DF03965D147CD39471C2A59549A95D6DD850666D3A, 2BE82D08A0CF2FD28CBBB9373C40A5874F8A155650E860A0B31D19F81B94550B065B405245E0A3A683E35B25214C609C 41C21CB8E1, 9E639E290614EE79CEC390A013A4090318FCF5744AFAD91A33634DB4BF5E36B488FC75E21EA5FC23217DC3FA3E006D69, 2E192259B316A4EFF05925CC2D59571A0197E9D6E06B0215E15E3F3F4DC4E67A9D896FD25A256907A34156B72CD9BFCD C546562AA3, 358CE79F6387AE804C6EABC6780CFDCD1AEEB836B8F94799CC5739B895D603940C52850062824C35BB8A2B199DC4B617, 6D7EF97FAC79F796FA7704F07FE682AAC28EB9CBCFAA2DE4FBFF47C71673BDDAE56316940DDE58B40B8B7A7D0A5B86B5 24FD3027FE9, 423CAEFA17D4E092260A7BB3E2DA55D2DFB2E12938BA950E0E6E4BD4FE8B0AD48B0A05DE009DF4B5AFCE1C2868418A91, 69B2DD050A77CC4D204492EEF9D929CA7828B3A322827333F37E82A0E76D34470AB332C981995BF1495AC997724634DE 6EF79077FBB, 618FA99EFBF4A6DBADDBE9A1B0EDF34F5CFB93FE5591E3B20B5488ECC48C79C7F8431175F87F1229B87FB2F211328B04, 48DF2D31CB4625EA7FA198F4142C6ECC70EAF215B8F54B5CDFF0988499559D2AC1154B9D9152A83C462E41291B121A93 14CE6B167F31, 34DEE1D270606CC9B48F3151F8D3490C37E339A9133D47746D2901DAFFE5D6C5F8FB205B66812B177BE43855D2CF47BD, A20D5FDECCB8DB396B9574EBD8B05A7360BD01C47FC7944B46627B09A4990494BE2FAF15938D83FF4F0038DF61348B13 3E6B41437D93, 7ECD0A221205D3BE0069AB3C5CA03C967E9F27AADEA2A52C8A0213CCB8C7A20AC299EA5AE268C3F5F7763F5B6F2BDDAB, A4ACE46D02BD9C63DFDE827C213D712AB8F01A8AC000995DC39006A60E0CCD233F8CF069BA9620731FF6FC77175DDA9 BB41C3CA78B9, FDED8D3CB351E254D1E0726D6C34D7B4A6646F9778C008BD0CC094B803DA1A985BE039CFB438326B7EEF7C55C4B23DF5, FA023A32F20E217FDE376F4C775C6A41121C77B79D5E652F8DB71E7564B0D6B8DF83EEDFA246487E94DC53CC4089F0D5 231C54B5F6A2B, D17E9C9792D9D2E438536433C676EFDF6BA1480ACB525A12947BE7B7575B873948ABC34A014A4E09BBC7BC766FF1B785, 60416FBCBFAB85E393972216B2675BBE25D050F2AE4CCA15FCA0E9F2803F1C873BE66895C3F3BE92D037FFB0972A7B3E 6954FE21E3E81, 5200FC8B4BDF422B0183CB0A4DABE978847983772893337FE827A02A2791BBD720A6C8FD46CABFD32250C64B5D67DF29, 7B47EBE2F9E20842E512D353E5CF2CBFB802567A6C805EDBF1856A9B46D0971FE5A2494EC51751518F9FB1EE036E62DC 13BFEFA65ABB83, 79609210110637883B2BB4CB017FD531F2F85DA33C75A0BC3FED33B885B31D684B76DAE207A6CDAA91370455FB36814, F4FFEAF18C196E94CDC1BBD09FF52ED957F433F23BEB3751003E2C3FDF037F9F8DAD43DDC956220DA5D69B0D47EE1534 3B3FCEF3103289, 8D6F8533C380A5CE6B07F860644087788F06E65135CD58D44FED92282A45EB99793CFF0379F81FADC2EEFF5B9FFC4C5E, 1B5302FD186E2C8E57A869470F542C4B633E48A026933D95E6202455262AAEB8015DA857486D2D2D1B45FF07AE30828A B1BF6CD930979B, E1C2553F742CFF283D608E226C5E762EF88DAFD75A6D68DD79A6E94EB094D4D04A40C8B4BB80B5F4999C3A44151DA19C, 974EA4ABE8955CEA715F0441070BBCBB04ECD686C50EFB44B07E830E5765928495D0635AC8AF0CCC829E7DEDDBD1698E 2153E468B91C6D1, 10821F1D9AD2F1C09929D08F2292B58156E94C0C729DF58BF3AF929E79CE011D3BCA116FD47B21DB9F043C17E20521E0, B6032D349B49DFA2C97EEA10A605A097B51582D653D0BF297CB385E0EBA2DC982CA7E9135A0196031EE0700C8DCC3DEB 63FBAD3A2B55473, 1BBD5C55CCE19CCB0AD30DD7405F5E91E2D2F51DEB09ED974AE09EF7666A8C74616D7779FC5BA74E76F39FE4AABEF089, C827ADAFD48192B2B995FC8378122BD8A360298C79B36643DBAD49BED8453711AE16DE6A1B146443C19BB59E439B14A6 12BF307AE81FFD59, 4035E13EF898A12EF15E72CB79DF83496D5B3CB5A0BBBD6800193CCDABFB20794297529F34F935F1D80DFC69B3144795, F2E854351506A1C15CD2E2E6DA7ECFD10A0AC16DB2FA937A03AC6C0B874BE34A2438906FD3F22F5E50CB52D2E84D5675 383D9170B85FF80B, 2AA4B819AC5737D89948634E8A92968B0A9E70CBB47EB67AD08F14B8A59C978C944FCF5039D4032B41C8BA24A6B08069, 3332B17A4F66A018B7398F793D5438C48EF88F9A8B439800B4A3A38E483727871683286179494DD4C84130DB63B98D62 A8B8B452291FE821, 551AFC585E46CDD5024AE80BEB75B079B435F90FAABBEBCC0A7615938A83FAAC3B51C42B295B8BD7472AE9E4278B5072, 5EEC8C5C1AECB5D4329738942D4004654AC375E486108FEB24FBF2AAD5FD457BD32F6563281A34B670D100F196E563C3 1FA2A1CF67B5FB863, 19E89C4E47EEB8970573C05931D43B8083D850494645CD6C4B378B3C90CA8015EB9B22C79C8876B3AB7815DC1C9C9620, E97B4F1C222F10610F6DDFB5D18D3FC1993367E2EBA32B94390573E89D43A1658AE798523A114E6AD58A56CE5ABBAE6E 5EE7E56E3721F2929, 3AA7711700EBA565E90B25BC0A1ED92395D92D9DB8FE06A54E455F9FC9C0311882C470E519B2AB2748A3EA8ED5934BF9, CA0EEF27B7FA621893B155320A8CFCC7BAB2C4C0567523A34B3FD17F843226022E5D87025DD4F87B1F6CA4376BBFAFDD 11CB7B04AA565D7B7B, 2BD895DFCBBD85950FFE675BD6CC298963B99DB909F627A5B2B08BE481D86FCC9640823964E2413808625511E3F8DFAB, 5161CCAD4A7968B685ED3CD380F9BB391BC59D9DE08F4C467F0B65F70DD77A367EDE2B66551330E5FC8898E1446E39B2 3562710DFF03187271, 4A55371E09700D7F1B9547414D6B3E4071F426A30F1580690496F7DA06EA9290D3A2F68EDF64BD75145AC8D60E124ECA, DAE73F39BFBD3F2A9F3AD247EE94FD25AD9E891A079F2AE191625632D9D511DD777FC32E2AE930C5A5B6337385618AB1 A0275329FD09495753, 6B45A93F4BFC9F903B6380C8E1BF23D330FF66978031B2BC2BA2F9F112E04C242B7E1DB73C7B28BC1FF12A1999249229, 94667AA038152520F1C8CFED64D8C65F60B2A68F1B5F9616A6656FC5E91F3447A35F684187DE651C517A4AA8679B2C8A 1E075F97DF71BDC05F9, 7F0F54C1E4FB427556DA4581F48013F3A2CE46BBED66E872C287120F723818B9CD6816DECAA6E215D629AC01BB5C2078, 470121A7E34B39212107BA473B7DC132E2FA3239DFF3C9287DA6AF1AF46591F015BD962FF0F8C66DBF55DDD02579ED0D 5A161EC79E5539411EB, C7E85917B65250AC843FA5FDA808F01CAABD276DE03A46F54CE92C17ED6019D353FEE8BDEAFB646EA6B645E16D822039, 6D38FB10252426C24D77367F6ED6CD68C1CB3EFAE0EF23A29B8FFF5072C32199D71DAE1204EF30AA8405C2428C093A4E 10E425C56DAFFABC35C1, 36A8B370957DB1F875A6D916D84608B1D4902183518B2E2A3409961E852DC422769A7C6D871996FAA0D68A87D73824E1, 7C0B56B029CCDD9D106E88A8CC4A5384697EB9A5D66041F438753FC0724FC8C32AB2001531AB37BDDAFA2F666A7A8F57 32AC7150490FF034A143, 65E8324C8CAF05BAC68315E1FA3BAEAA4D7D07B42A0F341960D3881D88AD11D3823CDC06717947BFBC47CF77EF02A288, 236A05EA0CFE71B5D2E6AB212281EE351E380150733F52FDF4097D255994FF9D5E5817B114C1D7E259FB45D61675DEEF 980553F0DB2FD09DE3C9, A7B928461464C1A9873A0BDD6D48B7EBCE933FEA1F455B21B5225B3D1117A5E77EFBBAF60EDFCAA51BDE34E069B539D7, B4BF3523C06B1A71D2217259F39056BE28C34F0862DC37663954111458D8DADAE5CBE146DF1A9033B173FCF5B2C7F147 1C80FFBD2918F71D9AB5B, 87B28B4555AEE7C57918FDC6B416098D30C9F380228B6227AF9AE72CF98550CCD5B4A5566CEE6FFECD9B8B0E024ED8F8, 70E5D13FD11F0FB5BEF6FFF84864B2C7A50B56B5C25FBF811673011CC98531B15F3318AB9287C6999DF07422AFD1D898 5582FF377B4AE558D0211, 9B7DD39A6DEA392C0971B2303CDFF0F595B6D9C6F7BA2278FC6B1A292455199CD38CCDB75C6359C7F9FA637735E294F2, 4CBFE074C529177CEE79A3889C2906F51CB420DEAB24D1A2295D14BAD2CE1E63578F8E363266122A5553B095F257C3CC 10088FDA671E0B00A70633, 8EDE71C80007CB8C4066C7593C3139DFCCED7FE42B3F64A1F6CD10DBABBD1E7045579F746E2F8C8ECD83B7F38A0059D5, BB79F8822EACFA328432209422A511FFE4C4C1AFC8E02A826B4F163D886B58541BE647FE9B3C78A8906929E8D76BD966 3019AF8F355A2101F51299, E49ADBC7FC61A49FF1F42CF80B980335A892F6CF196854A21D7C021821C760797C715E7DE1E985EBA92A2D2A6DCFDC68, 117B5A3BE910325BEE9848A9CD4B80A04A3D7E965D25B0290C7586536F2EBF609520A3D294F75D6FE4033EADC3066FB6 904D0EADA00E6305DF37CB, 3F7D97C61511354B7012FAAA7D96CA248D218712BAD609F8C8BB582A4390A6FFEC4D84E7BC8C5275D3689280EB3B8F3C, C53855408A0A66DC02FD05315CBB896E4C267FF86927FF60A38FCD6E805285890F2C7A63BAAF85A76B220EE363855CE1 1B0E72C08E02B29119DA761, 3D47F8DF16209777FEDC6E275C860D4D9A56E8CD3444637C0CA0CD85D2E6178880A962B8E40DFD0DCB149DC6AA93787A, A5D39B548BA391ADB45EF05C36488890D705AC1FCAB71987EDC2802BE6BE90A731598A382482B3BC96ACCD6F6EC59C85 512B5841AA0817B34D8F623, C322629B606B407C8F1C5F604AAEAA423BA63F61AE9BE78A2B89B47AD8931C212F5CA0A95C1CB320A6B1BD8ADF139255, C6CB476EF4151210C3B251982E760E13E4E5C1441A8283C6F08406BB84CBCC4EFAD80A3C64F9043F31193DF5324DD82E F38208C4FE184719E8AE269, 3E538420C3C76466E691B6247B0BE38DAF4798B81FD55C709C7C619D4B15D60F883E48D08FA6C053A24FC06E843C3783, 5A6462B1894C0CF98D111685EC276E5FA1AA1B9417A739FEE271668766AFA5FAA2B5B98EA63A5848C858CA487A9DB837 2DA861A4EFA48D54DBA0A73B, 290B7D67190B64B175521392B310336F3B51EED4E82CAE26BDE9111D40D5A425B8CD7C492B3B428653D4428F21AEA32, FC2CCAE4FE20F15A659B6F07952D7C23DD36E771511DDAB346EFD02713F78F68827B7296CD6EC8BB98F9E53629F967C8 88F924EECEEDA7FE92E1F5B1, 469599F3D1D7285564D2D19E9FB20E374661B95959F87497F6DD3019DA7D123A7A2794F97F61471FD435C478C7871E52, D6BCC6D99E3F448E7F6786FEC721E8408168CC3A49BF3A5D12D635850DAC424F8AD6CD7908292AA7CB11841B683A784E 19AEB6ECC6CC8F7FBB8A5E113, D8486C5E2126B1C0C745F38AA9A7C2CAB8CDC62677DB993C9179E3E72996CDE33C773D4F90DDEB6BD109EC9D295B3754, 180CAA2EC87EACA14D93E5A8B424090A76DD7E9E53299010848A771B4E565ADD29752719D5D69930AE8DA4662A7133C5 4D0C24C65465AE7F329F1A339, 2F1767176C2E58E0F08B4A51F500F2036EF4D00E163504A2EAA75A374B2999F0486173A22BC4BFA2131C11590EA9749, 293A321223DD7EEDE4B1FD6C5CAD51FDEC7E11F19BCF3BCD15CA43DBC184944CB382D50E435AF3A7DF069E690FAE6A85 E7246E52FD310B7D97DD4E9AB, 39C1DB044294452FF3AFA2ECE3A2A5E16D1A239C0B63A22A52386CB4546DD87599DCDD9894B95A9D17D0F15422A64244, FADEDAF6E5224FEC08E3A2B3294916FFA178F12984C3E777E1FBFA571E858F7B28AFDBCC0E24BFA7CF84352790BBC942 2B56D4AF8F7932278C797EBD01, 9A23F134256199B6922DE8BF63A334D48D13823DD447E505373D5AFDE4FCD39329B5D1DF0A33B0065B769A278A07E525, 88EC25D8A2E33B51E8CA17D685FD9D48C82E420F1B9ACA9E789CF5BAE95BA8579F7D2884C0B61A400B69E75F6CC8972F 82047E0EAE6B9676A56C7C3703, 5DDF3AFB5D6453AFB90D7FBBF3F73EE9C15443A82E11A6E719F45B764E0DAFEFEEE11F1ACFE188F75AA277214E580F13, 220B6401CCA494C4E93E478DB4788C0173036AA99EFA9BA4405F2F82B110D68F24FE771078661FAF4FF4CE87DBB50A31 1860D7A2C0B42C363F04574A509, B32F67F1555963943858BA0AC73C2B4FC2BA2F54681B923EAC5B129E832BA9AD25028C8DFDB250606E937277A3A85B1D, B0F39895C81FA823465E9DB3008DAE9DB4E7FA06B31C61539CF23429F9CD58FD296AF6761D8B258643C779B932A9A67C 492286E8421C84A2BD0D05DEF1B, CF13701368E0B66045CFC41D45E197A675F4B4C4C5D41BF6CCFC908C3826C6C2277B68B52995F9BE860EBC293A59A56B, 6D018EA175D603E924B10DED802836DCE9F0A44EB36094FD1CAA79B0301556B8FB62DD8886D5B2214F5BCA6731477AF3 DB6794B8C6558DE83727119CD51, F55FF1C787A82E6DA78187C53100B3186E96DA39C7FBFD7EA069B28E1D0B2A1C67A3A93A0D5C79390CD1E2C9E03FDB3F, 541F5BA6D856B9C9BA325F7F0E60FC23E3CFEEA0D5C1316074ADE10586A292937DBE8D8EE191A5884EA9756A53DFE6EA 29236BE2A5300A9B8A57534D67F3, 3A3868C5F9CD908C3B0F19943EA5552364E99755BA974843D32609F63CC9483645365417A34670EE6D0B53D3ABBB1BB6, 8BCEE0B863EADC2DD0D5E528E9F4F6FE549E84DE48958F61201F3A7782D0FAE523791653CBBA5424B17DF7C650759E8F 7B6A43A7EF901FD29F05F9E837D9, 78D503528BBD16DFEE6EE4A6DC1F395A6F5595184953A790EC01A3B61EB8C5060FA3C5BF362FA6575F8BA54698231748, 10EE2DB69F3B9CC49C55547A1A765DC0D6B738E3EB6ED5FC48311358B5A660EAAD585B0DF4D7D5AD0882E8434FA3FBBB 1723ECAF7CEB05F77DD11EDB8A78B, 83925EB0FED9F743B04F4B5B343F649095C14C8EF51E079DB96936096B3E80B7A2A05550202926D63B93C92A737CB862, B4116BFC49CD206618C3ED100FCFC7789E208F83E5D9D95917FD45A5346D4C37CDA6AF21049E160A628B06A139562423 456BC60E76C111E679735C929F6A1, B17AC741C6CADF3A76DE0FDF1F24B20129CE3B7249B8ACC3DD8325C09B1708389BB28F7F3DD4C9A0863D076DD614EB81, 1E42CBFF458CDE07A8A615D3E5FE7B519EC20071EE1A82C6B32279F823DB84ED192F310E6BED4F24780DAEA76E1541EE D043522B644335B36C5A15B7DE3E3, AF1FDDE67323B8ADA15C00E1C5B1622C7EC3D4306AF6BD2CFD1ACC443DED11631E39C851A3564646A2EC4748AE6D2B25, 8FDB4636869020D89FCCBFD052B8ECBDEB72004D6F6745FCFECC1F3C66376DA7312203518B26C4D907C2F4208BF1C24E 270C9F6822CC9A11A450E41279ABA9, 801DB56BD43A50C4857BA92264D312816A1455D6686746FAD8158C380841C578750DC162B7546B14E1BBC5DBD43A5DBD, 4747FD5874A10E40E76DAB3C8D274426946D710857501D1AC4F32D93B3551C3A8E37C3EE12C9D6BE425F26A33BC8B953 7525DE386865CE34ECF2AC376D02FB, 5562E0CCD78C58F382B98659B6C0BB6071EFF74A52BB1D90DFF09462CE1E1B3D3CF24CB722538E992DB861E8B0459C09, 48DD52612E8E79EB8F68B117A579EE598C4E04997BFC71FDA1E51A98F2E1A071CB95C6D40BC32C1330DC85C52398037E 15F719AA939316A9EC6D804A64708F1, 3C720118EACE572081ED712457E028E01A637A131FC16EBF34DF0B65142A6D66B813DA68A66AD213D18DB5A0A562D0FC, 806E1629250396C00C35240719499C02F8AE734C49BA2ED9095BAB5ED7C1743DC8C77478EFF551B25BC16066BEAC8EFC 41E54CFFBAB943FDC54880DF2D51AD3, A665E9B0F5EE4FEBC8EBAA787135EDDCD4DD64F5566F8C4A0214642D08D2C8E96D4A9F8B6A1DBF946AFBD47E8CC1F6C7, C793540EE4FC8D84C7C7A5C5AFFF7B9213E294EACD48680F184AE550C35C3B609C4E4524EEAC301FB7CA87B89255A9 C5AFE6FF302BCBF94FD9829D87F5079, 698882343467EAC6E642E0634AE74826F0F8635825CB8631FDD461FCA776DAAFD93AD926AF0F1F723643DDABA86746FB, A15F7C8B2ADDDA5A50E830C56F5637A2701C5AB8E0F3AF776E746F35BDDAFA81200428BDFFC3BBC398FC22D942A32F8C 2510FB4FD908363EBEF8C87D897DF16B, FD10B62E5826880EC655B8FE38D8837F111FCACA1E3389DC9645350A8B17F0F12787B654C02B7D3BF6A72883552B66A, DD69AD5311B203C8709708C2AE9E5ACD6ECCBC71CBE837F05AC59188B2CF5364F9449446899879A40AF9A3C8A94D5172 6F32F1EF8B18A2BC3CEA59789C79D441, 7D3DE83A27F5501DC3AEB5246AA159119CC20BC592B3A04EAC140383178FBD73DC291C6976DBF62E8FBAEB47E4EEC242, BB6EEA3848808EBA89EBE470AD2C79639BAD34367A4A9FA2BCE07D594416A87A03AD56F47A599484923E3B884CEA2897 14D98D5CEA149E834B6BF0C69D56D7CC3, 56F6423CA135EDE0065ED6853DC33A5CECEA4BDB0FDCA5DC485812695AAEC1EA62E32F362A89AAF790CE385AA3B227F8, 7A23245FD401F4B8F806D92CB0DC01D070A17200105482F24B334C29DF436C8DE4BF74004C36F1716CE85539315DD47C 3E8CA816BE3DDB89E243D253D80487649, FB7ACF54D6BC1F87053A2A68EB73DB8C041E9BD90BA2D7384C2404D3BA6B989955A23C4A42CBBE592119EA57C7D130FA, 804F17D4B2F4347AFEA0046AD2E3AFEC66F320A40B2EFDC02FD2105A44FA3A4A39D75F8A2349DADF154830911D4C4D79 BBA5F8443AB9929DA6CB76FB880D962DB, C6051F6AC7C8D3A0FB9617CF6B935BE246366DAC40D6DAB7D5CA3271109E74E9DEF5B5DCD34054C3148E09A8EE376F96, 17D5118CD46CB520EAAE22A5CF953AB6C6BF30C4E9903E5646AE4D3DABC0112D8A9DE529A9A730E11C97BDF6E24CF37D 232F1E8CCB02CB7D8F46264F29828C2891, 8226F16EECDCED762B53A5C236CB0473B1E426B7514DFDEA8E1D5E2236CAC6516A8354C0A9D8AEF2AB25B0AEB5642CDC, 8141785EECC969BA58EBFC3A0E0F92C17878E780C6823DED77CC8634EDB5151A13DAA506436787FBEF21FD02F43E1B0F 698D5BA661086278ADD272ED7C87A479B3, 7C6954982B5BAF090627E007EF96BF45BD189BD7C0AD6A22E5956739B60E534DBB10D4B52849E7F230BD8B0097E27848, 4414332E5758586C495E14D6501BF0BB312A7A93ACA75B4DC3C2E8295469039864A70CFFC1416D17C1D558AAD1B55656 13CA812F32319276A097758C87596ED6D19, 845E24A572803B02599739D0210BCAE6C383FD36400A5AA96B09B89D88916732A039A546F77EA90718971D2520EE8F89, 8974A58DF0FE67F1B723EA739F578733B40BDA73EEE3DA2BB45BE94D485186CC3E76177C0EE81A32BAA03C681E4AAA39 3B5F838D9694B763E1C660A5960C4C8474B, FDA6AD1957A6CF2E377D1E44E27DE0DFDE39CDCEAE40A2E830A00D2D514F939B3220FC1DAD3F08FA7EFA9E1D15DCD033, AD850C003BDA4DB0D2CCE0B47476AFAA63087A066FE9D9AB8E50B1E6980A810A485759238FA8FD45675BB4E04253D160 B21E8AA8C3BE262BA55321F0C224E58D5E1, 430CAEBFF1D8578CF05091DB0C810C191E48C4A7B46A1623862DCB8992C520E62130F66EA8DF65A80874CD088B9172BF, 1360132ED83FB5FE4D26E29B84B4747C0C00E884A2E9FC206D54DC70291B8DC2F0BF0C84EB0FA93B471DC10D49DCE982 2165B9FFA4B3A7282EFF965D2466EB0A81A3, 6739E6A985EA9F1EC9C93887AC7A821BF68B1833EAC32833602DE1BE88259C01BFEB412BD9352744DB2AA7E099F65C51, 8E364F68331A2812476F1AD0C35366CBF08FCBDE69BE8F74C33961F47212BDCB3F06B1B374F03F81AB41306A10692FD1 64312DFEEE1AF5788CFEC3176D34C11F84E9, EDEC4A7A3F5843004EC311096F8353655986118E7ED362D24F31A214F9BEDC78BB0A1DCFC3B2826F45F9E5CC423D0915, E0BCFC02BFC1B3243A746B3BD9AEE8CC30861D93A814B41DF90D982E72A95C4E3639448C3BDF9581F1C2F3E629C31F9 12C9389FCCA50E069A6FC4946479E435E8EBB, 58C6EF296B7580441B6F638E39610323882456B0367745A88AFC81787F1A39B6EECE6CD8E17E9010A9069FDB54C0B4AE, 3287198D302A7CDB02E65472CC8A59B26FCBAB2A3FA5E7A13B29D2A56E29930D9C0A55294507DC563C96010D89897DE1 385BA9DF65EF2A13CF4F4DBD2D6DACA1BAC31, 8F460CAC5C0E019B2DC8D38FD9D74FC3E0BBCA91E1EBE5DB396CB991B23AF91A763BAAA0E1B192E52CFDE09E734B0675, 9CE93A27A6CFEA9B6928521EB9BBB07CEAD33D0401193CB279FEBEF0C2F5327B2E89EE0DE36B804F5898463912026479 A912FD9E31CD7E3B6DEDE937884905E530493, CC18138D957D582F79133F05A4C8DE1443E6B02797C255A29C05E99BAA764B1DE0CF9759E5FAE7733AE10CDC105818D0, 82D4403C3DCB1607AD8D980895859E251FDD217725D1F6E543C284E75CB23AA8D6E42F824A943F05F1F1590F2B5194EE 1FB38F8DA95687AB249C9BBA698DB11AF90DB9, AE1E98C0EC6BFEDD0D6D06DFCE8BECBA637BDE30229D08E07BED521F3BAAEE494BD05C044BC69335DECB16A7DDA79863, 33EC3113A34D25DF5837E0A7AC4928C1322BA285F07F4543DBB67D79D9722B2D3A6E11E0C04B3967F422E0E19EA1A4D6 5F1AAEA8FC0397016DD5D32F3CA91350EB292B, 59EB072C6AF606C6F56CB4EABAADB7FF55CA5F373C968D6D47B2884549AC41C61FC0C7A54928FFFE412D1748827C3797, 7366C6427125F79910555E2724556992738BE7FFE6D74C2211FAEEB7C64DC4DC37EB20B71A1815EECF1CAD70828742FA 11D500BFAF40AC5044981798DB5FB39F2C17B81, 34DCD5BBB389A5288AEC85E92DD3D603A6BDC4B912344A37B3906087666F63A9A5E1B98B51CCC55D8CE71E2C609786E2, CC0592FEA9284D16230652ABE63501DB123F74DFB960E5803B29B5488B8BB6C85F0B16B5CCF652E7E2F6E6F797E9925F 357F023F0DC204F0CDC846CA921F1ADD8447283, 6DF7DBC6C027088596D82132A7CE15311D34D06486A9698B561AA3B8856FC66419FB551B0B070DB0D38CFFCD1FEEAE33, 28FF1E1E95640E7CCB11E267C06284C3E6FB36048B8CE07B69FB8D6050704FD3DB2899A3C795A287D5CEA737BFE4F669 A07D06BD29460ED26958D45FB65D50988CD5789, BEAE9EDD444F66A2EDC62B5BF8C0F40AA330F1DAD2D9AD97BAFD1A4DF7E126E9E8B48D05324A44C3B2CAD59A6B8ED27, 45CB5D6C9806A848325ED1C701C8D194C4697A4D9907ECE4322980E2143DBF7D300ED3A9F7C27C3A237881A71DF57EA8 1E17714377BD22C773C0A7D1F2317F1C9A68069B, 8AD64B9BF757181B9C147A77403A713202106DB926B838F1E42B8074650779A3A585073FDDC369151840F72C846FCA80, 41669D2A06284F90A37175944E0AFD30512C02838BE0D3759B8827904086E35F6FD9B7ECE02700026100DBB1C129DB95 5A4653CA673768565B41F775D6947D55CF3813D1, C3B69AAC77A2DFBC5D3544F50A09FC113E0A5FCB6B05144B9863DE64B42571C2B960DA075BD299BDA28F1C7F553EF53A, F6E91117168706FEDD13B5048AFB9255D8501CF8DDA48CD1E3E9E11D6C520A48A1ABCB7FF39062E7AC44D07001BF1AE0 10ED2FB5F35A6390311C5E66183BD78016DA83B73, 535245AF848D7BAAEDEE934B11A06399F48DA9DC246649F037AB8FBA0D943667B589B229F3ECAEF118AC301AB40EB26C, F3C69A881DDB19055DF5278E6597220BBC130DBEA8074DD98D8F58F155EE67A180F1DF613749A788B9E1E8A18FCDA398 32C78F21DA0F2AB093551B3248B38680448F8B259, 6E332109579449BA6BC1159763DD73DAA750407D51A6057F719643B1EE06C6C23D4061768C56C8F991A6DD6A48C045D4, 23D28B89995E355F98AAB3522B85682FAEDC9969D711BFB7907269B1E96EC48EFA09225EB1F0C2772CE3A6022D23564E 9856AD658E2D8011B9FF5196DA1A9380CDAEA170B, EEE848AF3D55232914F20D9D9858F0DA7D88608E3F95DEA3289EB042655E5BFCAE1FEBD1E4757E9A0A87005E9B77331, 9C81AF59270DA297E5A872F7A0295794AC84E9D85DE0C65B4A1CD40AE0690CC98C6E0CD89D6E689758116D1BF4EE7920 1C9040830AA8880352DFDF4C48E4FBA82690BE4521, 4B44D4ED3C2F032A81CE01F5C3049B9F1E1028A9022E3B0B3C7A4476E9BDAB5FB7BC0CC016456A1DC16AA72838EA56BB, F36803A7483D04F05FB0E0EA52ABFD23AA5C2EF8E2B7097C58BD6FD9DB83AFE98F26FD21EEBC1BACE257FB41071A8356 55B0C1891FF99809F89F9DE4DAAEF2F873B23ACF63, 6336A76D5D94FDE2A1A625790B044E38959C462C38FD202048B3A81DB7F27048085EF06D13A0F5DEA359285F636F42E4, C52923D0F12679656B59660FFA4BD70312045985A040CD858F7CD07E8E1F03923B92543186D2E87823B64F7CD9981986 10112449B5FECC81DE9DED9AE900CD8E95B16B06E29, E1FBB64EDCDBF21B448243896D0DC028DFA9CED2AE3F184D978F29582FEF39643F36E0A0AC79DDDC13B5299D20BEBEA5, AE25787C0F1B3FECE1851245D98A149B7877EB90400C23A792145CFEFA26958F187B68ABB7C7A10759AA56FEDA55CD9C 30336CDD21FC65859BD9C8D0BB0268ABC1144114A7B, 269B83C644BD0217E3254DAEE476D3B8BAD3A7854B26A2DA8A49445DDE2D907BAB408CF736F02A654C4E104B82163271, DDC4F14FAB24E5496232BE99D74546EBFD28C9FC486F2EF27908C7A3C44D5248CCBBECA1645E327ADEFBAE66049A2D5E 909A469765F53090D38D5A7231073A03433CC33DF71, 60DE6F9CDB270A1813608B46B985565C1202EDDE62C3750A97792AA1F833A91093EF8F86DEC018FF2D427B849D966BE8, D6AD1734E5E3C4AAAB583F75862868EEE4D6EF2C6E7EFB22E73EA567854BECC038AA804E757D93BA6CA41165C9795E9D 1B1CED3C631DF91B27AA80F569315AE09C9B649B9E53, 917B6E9836F425605F20B8A77749A729C7E4F37A728363B03813AEA1B7B1BBAC195C6254EBB52EB9C5AC8026729E6D3, 77CA655D0D540EA8EFCDC1013A5E6C1FD4B4C9D4070A81047C476B2B78910ECC97DACF8E1A96708BD50F82EF4F13D19F 5156C7B52959EB5176FF82E03B9410A1D5D22DD2DAF9, 3A4894159A887E6C56EF92C6C88C6750BFE1D2D13647FB1B52623C8E96BBF4E4B61C1F0742859A18878A2A4965E685FA, F9E93CB6DC1BBBDA7F4B78CC4F64DA85CF8C70F099DCF2DC1648280B96105EF082140144B244A20249620F2CF5E8925C F404571F7C0DC1F464FE88A0B2BC31E58176897890EB, F094C286632F41143FFB04A0B2CD8E5B787F09E0C3451DD5318528041D0CA63C5104D91A59640275CE525C0C8F067D76, 67024ADFC008C46A0D483ED77CD5814AE9E0D53C60C60D4D1C7ED25480A1E96002878118055414E1D661811AC3F1822 2DC0D055E742945DD2EFB99E2183495B084639C69B2C1, 50C86496BE68E05F94DE7582524168D2D2CD8CC0276F49591D5FF71B5453FE91A11A6514C434960FD8C5B81956450BC3, C938D1C2209D48E5433B296B7FED13590C1FA6EE09FD4BF5FDC64743AE764DDAED4A086976530F6F25F9683B153C3F7F 89427101B5C7BD1978CF2CDA6489DC1118D2AD53D1843, 16FE8D74114511776207D5260CB7A18DCFF4BA22B020031A69A674107B65E87989DA9A0F72F63528E70F9915C8203409, 7DB56DFA23AB19BBF58F56576E30FF7D69FF5B5231AD17E315BFFCD97898F70F1A6FA88FB74F11FBA6329709D3EAB05B 19BC753052157374C6A6D868F2D9D94334A7807FB748C9, 20FCA562C8571FFC1F577B5C94FAABE2D5380E392DA26C522A85AC1BBFDA4C8C45806775FFC28A24F5FA0A4A964E9749, 2D2465AF770DA93F5A3F992E2FADBCC6D3EA627D6B32804838ACB0978C4F8C0A26C686C03C49E98F943AC8E7733A92C1 4D355F90F6405A5E53F4893AD88D8BC99DF6817F25DA5B, E68405FEE3EE25E42DA1AD218C20AACF30D7448C4CF150A9622A8518D8DFC6F1D8469CFAF1C2C979443CC8C2EB1B088C, 889CF33EDE61331625C9F87C68F56417D125FEA6110B72EEF8569A5D005C0BCC8F2DF0F65B068DB4FC4A9AC5C0045D3E E7A01EB2E2C10F1AFBDD9BB089A8A35CD9E3847D718F11, 4EDBB67E1894CB5A1B274499DB09255A8664299ADD5D4BD7194DD165ECF1F93939422E7B37A91E7DD2A017931F77ADAC, 2541889DFB620C0A68FFAD21565BDF7D1C7EB43A37C428EBCB8BE6748BF04A3513791A304BE52757CF925C1CBE06F027 2B6E05C18A8432D50F398D3119CF9EA168DAA8D7854AD33, 23EEAD8B04C990E245822318E65390210C6CCC496252AA22BEA07F6BB4E133155E8FB686A27E74660E02484BAACF68A3, 756FEA2D2A57C404D5BB305017064DD529AB9140465FA3E99F812083D6281BD55C2FBB3BC2BD49AB2A8510190E935261 824A11449F8C987F2DACA7934D6EDBE43A8FFA868FE0799, 257D81AC8456551EFF4807051969ECFF195098C16F7284260A74ECF69326D04269A31C9FD892F61C6DED793838389DF2, A019CAA36E0447BD5EDB2EB775A625024A5723C4296630B4EC4C64F5B4DFF7CBB270705A53C59121BE38A418A0876D1D 186DE33CDDEA5C97D8905F6B9E84C93ACAFAFEF93AFA16CB, B4EA5DA208AB4AC5E396DE24E497BA1AE849E1C051748F9521D52B0FC34220F11DE6D1B2DBB913910A4FA8DC302375F3, 7C9E108A52DB2853D5CCABAB873BBAA565746DD426B5C9C913DB934AC5881ACA09D13ABCC4EAF4C2C2E8807E2470B03F 4949A9B699BF15C789B11E42DB8E5BB060F0FCEBB0EE4461, AB164B4CBCE4672AE7FE5009859092D08DE511B15AC5D93DEC0174AE4183CF3B8E48DFA0E5EB56FF8C1B3DD90A2B58D6, FB3FB21AC0899F5EE414D74B727726B77927E5B803A86618178EF1AE684F9AE59F4AAA0BE668BD2C612225601D76B3A6 DBDCFD23CD3D41569D135AC892AB131122D2F6C312CACD23, DF4B2ED8CBF816C905D49AB05AEC9207594DABBF714EFC8F4B042F4133B740FB4DBF2180D21A6E7F167F7958489D406F, 346D924EE85217C15047D68E5253C2B874EFA2DC5626572F34765006E0C802E2E63CFC90830E0E56D90F408099188F8F 29396F76B67B7C403D73A1059B80139336878E44938606769, 5A238C0C26189BB0B65A54935B9DEDD95393726976440BF373A6CFBBC6FC4653145CC89BC8B006A07ED37F2A0ECB0BDE, EAABAE89EFC6B022EA3AB568441DCB57B66C6D33C3E419ADBD17787D90FC0436B970DD920EF8417C6BB1D941C9C37DDA 7BAC4E64237274C0B85AE310D2803AB9A396AACDBA921363B, 6F6FD3AA2E7311C2E92A22EA7E6C3328F12298C2C963BE81C6F020F2708899AE1FF38BC6378DF21BED067EE89E78E938, 5701988546F00FC727989B485A1B61B06C2F8E6B9DBC924719F6685B3BC3D6B00EB2E8175217B04059606B2FA0245019 17304EB2C6A575E422910A9327780B02CEAC400692FB63A2B1, 1CCD7B257AC9A6872C8810A060AB7E19430F7E4CA055FCD3611A3F2144C457ACDBDC241420B559581D2904FE211DE99E, 6492BBC9ACBEA3A180F8DD8692C08287C5EF99197027B35267023B898C97E59F3C97E80F37DF21C76FFA5E3DFFF064F9 4590EC1853F061AC67B31FB9766821086C04C013B8F22AE813, 26E4BDCB7E4728FDD66386BD84DC8F9D1F970225DFBD3C0FE2F67D181650E1596D7EFFC026BCC5A1DC308E7DEE1E3BEC, 380E5C9DB3696B6FCE63A57F7C07D3B81A8E8E58986AA355AC2C9660B9921403AE264BD6BE95A007E6BCCDA136362967 D0B2C448FBD1250537195F2C63386319440E403B2AD680B839, D2AA21E3F8C0BF9284D2E68C6825DC582F562A97B7A7CCEB465D842DEEB769A359012496E5CC04D171D4FDBF5982F8DB, 1C5B56811ED04F7178AB50C29B6E3D3D27755BC3359C1EBFF91DD3C768D6333C67074E51A7A349F9B723559177F5E42F 272184CDAF3736F0FA54C1D8529A9294BCC2AC0B180838228AB, 91AC5FEC6C41D4425E3897CADD5AE51ED472C57B703EFEA6AECFC67BE673FB27D8B804F503EADBC871CE70C9D0BE4F93, 47717619E6C0CA27B810F03E29869DB7D32B3471F1DE6B54657FAC227436EA19DDB03638ECF556C684426FEEACD6B87B 75648E690DA5A4D2EEFE4588F7CFB7BE364804214818A867A01, 5262D4A1DD05B932C7111E5AABDD63B28BF8D3D6722A69AA8E519BBD4F2D87EFF12AC973F4DD91BD98F2163F8E430C9D, B212E52DB29F450107779ADB7859DE9978C4674A06D9ED513FC68E4BB363B382486D06760B38B548E0C89074B01361B3 1602DAB3B28F0EE78CCFAD09AE76F273AA2D80C63D849F936E03, 3EABD0CC3A97810473133BF0E8CCEDA93B3A16646F942219B55A767BE749AF9EDEC5B86FB10CEE90CFAAC82BDE809BCC, EF5D3C16700E6057A37109AB95DD32D86E6702A8A103CA0BF0E95600B128BD0794DC236F442288FB818419AE2D0CE047 4208901B17AD2CB6A66F071D0B64D75AFE888252B88DDEBA4A09, EFB51FABA5E00921B4FDC615C3656C9E32C6E3FB0319C08E720C0537B42A037CA0D7DBEA1A9D1817663B919F50D6A19, EC313A410871C71DB05472484B0792E8257B781D366A9206AA53EB8DB56F3FE5C25A094CF2D84B147F696B6646EC984B C619B05147078623F34D1557222E8610FB9986F829A99C2EDE1B, 661219AC4AF8FC7BF8BD2B25F39000A4397C9FFB10FC23440F5A7E33DCC879A1A7ABBEB89ECD462F7B7E895EB7EBBDDF, C8206ADD87BEEC60A01C55CF114D929E2ABFC2F51C8FEE12FEF28379EEC12254F9DE7111D4C1EFF50477C3BB0412D826 2524D10F3D516926BD9E74005668B9232F2CC94E87CFCD48C9A51, C55C2D48774AE739DAB54C3354FD2FD48663E6CF1CBB52F746E91B8E96BA820B4365F4BB5EAC8ECC5198BF081DF7D44E, DC442CAAA1405C10CC8652B3263C52AA99A788B53CD14D256C1453D20911FC4973E77A5396D064C8D15570AD0177B993 6F6E732DB7F43B7438DB5C01033A2B698D865BEB976F67DA5CEF3, 654F8444B40DC6ECCEA01F6FCC83E4CE74D39F33612C575F92683B2782A63DC1E34587BD40EDA8A69776E0945CA1FF25, C2D2275E31F42F004918F91901E663053392C1E49FBF375BC7B2188024CDC5499C01367BE41E0820D1F5868133BF0C6A 14E4B598927DCB25CAA92140309AE823CA89313C2C64E378F16CD9, 3F216AA2F0175611B41BC07B9B81F10F84B5469A2DD56BE4E2BF76948B9BE2E88A41A98C1E5CB617FB77548A828605FF, FC2986A007B72EFB5E00BB3E7A4366E08060A995DDF4FF49BA59CAEB193A3DD4BEB1ACF422F9069C59B668CBEA74262E 3EAE20C9B77961715FFB63C091D0B86B5F9B93B4852EAA6AD4468B, 49EC115431A5A9DC1FD1CDB9B3C46C80AB42AF7B02521881F5D2BDF9C14B5CD5D8AAC08FCCDED7B8A05C54F322C700BF, 90DA3972F2DAA834EEB421C6B557BF274410DFDD362410AA89EAA3D9677EE83A4B6EB5805D918E1805AC5AF73316A389 BC0A625D266C24541FF22B41B57229421ED2BB1D8F8BFF407CD3A1, D0724A40A6DDE3428D9B2BAF2E00DA732AF48EC07698CF79A7CA9EB67CCBA3EFB901DD0063C085B085B9247B6A7AE89E, 72180D820606E4FEA96FD856BF0117AE642FD3D72E26296852D6EB984AFF90AEDE44380B84F8897045EACB6E38E173DF 2341F271773446CFC5FD681C520567BC65C783158AEA3FDC1767AE3, 833ED3838161710EEE4FC1F626831804802621B49ED0374D46F96B647C326F48CF96690B69893E489412B7FD9318CF07, 96FB35E7F381526147249C998456C7C3D7F757499A6D33F7C5093E019C2612A8FD24F7F1BAA032E9B0D7B46CEB052A6 69C5D754659CD46F51F83854F610373531568940A0BEBF9446370A9, 40F2612CC9F0E96C6879CA085A5616E49DA57FEC8435FA5EBF939CE788845246970CB0E3CE1BC5B2EE613581C60A4A53, C317A1E6132860FAB9880F037C229ED821D812F7833743E6EF1862187D210462A6AE2BEA291A3457A280066E05894BB3 13D5185FD30D67D4DF5E8A8FEE230A59F94039BC1E23C3EBCD2A51FB, 501750558640FA04A14396E4942F19B56AAC8BEDFE6F0CEA9162FD91DB0ACBC027BF394BC3C5454CC2F14353EB85AFFF, 48AA1ECA7DAD2DF287751FBD4CCA886EBDB1D384757EC24997C0F3D923884103EF6EC9AE271FB548D6715F1640C4E3D3 3B7F491F7928377E9E1B9FAFCA691F0DEBC0AD345A6B4BC3677EF5F1, DA71BFFA9B3DFCC1C8C69F399535620181F9746CC43D11B7D18A6E058325494AE62D2770FC152C036DF1C34844DDA551, C59A5AF3370D830693263F0995094CC583E3DBA084F4D7A38F1DD12DD23D6F8E112A1B8EFE0B9E9C061931CD6071AD09 B27DDB5E6B78A67BDA52DF0F5F3B5D29C342079D0F41E34A367CE1D3, C7B30F1ED4C3B57B38B529ED7406C0A3B2BD8B61CE67C1541AFD0CB78D14015271FC4A781367FF73BAB6063B062CAE1A, 8A884288BF9A200A768843EC58E978AD5FCB4D9DB5C3FBBFB46079B58D8E6FCB99187742AA4CEBD9784735107BBC2C36 21779921B4269F3738EF89D2E1DB2177D49C616D72DC5A9DEA376A579, BF927F2AF838FAEDF98BBAEEF2659F53F63E4E9B56C0AD4B68650A420F70936E1FEC3912DE76ED20BE8A21D0DB77A422, BF0847721A506302EC96C99E6D332B92B09E0897FBEE42F4552D705F3458DC12F47CA0DD88F0D3E510000052D320C011 6466CB651C73DDA5AACE9D78A59164677DD5244858950FD9BEA63F06B, C9BD2B3FD0F566D809EC8D7B7FD72120B2E626C0F8C641084B6A19A318BEE009A6D53A939E421DC87E713F8D9DEE1F24, 19EC304A50124DDEB962755B2E778741FA3B632B4272BA187D17A7D0EF24AED57AFA884118C32474E16454A5F4203335 12D34622F555B98F1006BD869F0B42D36797F6CD909BF2F8D3BF2BD141, CAB3A4A9782F3622F212D2D7C0C2D9B6D4129A4A91A93D646BBB5EFB09C822E25800E1D2DA6B7492C4BDD5263C9791CB, 5A495C63C88F6A7BCC513AE17B32B1D787DCFF22EA60ED304158EDB9EE3C9B0D86AD42F77764D6900DF50A4B2EF799C 3879D268E0012CAD30143893DD21C87A36C7E468B1D3D8EA7B3D8373C3, 893E42A8127814CD00941183603F65B853DDE5DD89D33DBD2C7E2BF9CEA93F60B850D70C8CAA53143F6BFD34D9BEE20C, F71C691901A5B8198F97F5AF432760501A8C4948CA35A51EA6143D8A64587F78F794172ADC560320AFCCED3C6FA1567F A96D773AA0038607903CA9BB9765596EA457AD3A157B8ABF71B88A5B49, 1A94BF7387BCDA5301E6B192C85D2DB9E77A7A018C4156BF22A58D501412379827E113C64E047DCF69BC2A9BE6203, 22434B28AF8DB072919E660298AE0B325B3440E366A6EDA5A22E2BD9A684E26909183EAC51B4DFCDB7FC1C9F497F0162 1FC4865AFE00A9216B0B5FD32C6300C4BED0707AE4072A03E55299F11DB, 5F83049AD2A8EB2F763D965E30C08DB85ADCBA02904E9FF60352E04C592A2414FF7BDB87A622CEAEEF82B380DCEC45B8, B884E47A9BCD85D71B52B574202973FD66C49D5ED9896ACD9AA95CD70D40088AD0A88CAF5E5D8D24AE541C0118680FC 5F4D9310FA01FB6441221F798529024E3C715170AC157E0BAFF7CDD3591, E6427E2A57BE5CFC7B823528AD5100BC4154789A9CFB5A1D93536A24E72A4CD0D3BD385E4AFB5ACEC9E0FD37F42B832, 775AF7E903ED68D4456252EBEEE04FA5C1FBE917742D179FAB27A2AF16F1BCABA2131F6A66842C26A406098BE0778F63 11DE8B932EE05F22CC3665E6C8F7B06EAB553F45204407A230FE7697A0B3, 892FD294F87BDDAB30F383CECC76D1597ACF09DF87254C3B4E1C6C8B5135FCEB17A6D37232EFA3D8C45F16F3110B17AC, 4385E858C8E3471A4DC02ADA4584808333B2531B6F5D23466BDDF2A545ECE801B44F800A82357080E53D254436436953 359BA2B98CA11D6864A331B45AE7114C01FFBDCF60CC16E692FB63C6E219, CA910127E96D2E00398B88A8933D9CF5DB362BEF06FB9A9A465C64C76749F847B914F5DA1761AB26B194EE879F081F5F, 98327BD190C9F4C1B941789842DD0B475B5B81670F80CB823A77901CFA8222D99E538D72217CD5DB2D2834122A711F01 A0D2E82CA5E358392DE9951D10B533E405FF396E226444B3B8F22B54A64B, 8C4944FAAD1A578DF285E647447C815DBCBC7070CE37468C4F1DBD28EAF0F05375DF76411B609B71042839631F5A858D, 64958FA8D1DF71EA39B7DDC72CD2043669FFDA77B02907D1F34D763645E013019A0A871D73D01B340BC4F45E6340EA4A 1E278B885F1AA08AB89BCBF57321F9BAC11FDAC4A672CCE1B2AD681FDF2E1, FF7E584C289D4D97215C9C4372ACEC259B694574A8AA749056181FFF3F601716FA972FD2DBB10452DA351F10FFB630C0, 108F5B4B48B0FD567D8A7A6DFC3A7FAA288503581320618BBB9C200124D4CD51E479CF32096C3E6DEF66A548A268BB66 5A76A2991D4FE1A029D363E05965ED30435F904DF35866A51808385F9D8A3, B533B5DCC6D8C4666AE835793FD39E87CEFF57FB7C113A3B99F82D3448FEC01D088F7DB750707B5573ED055E755A320E, E6478E7F94BC2338C551AC03C60D868B0DF6CB6654397F6AC90B8C1251D2A1E1D2FB71D5FFBAF46875FE0CC10B4CA7AE 10F63E7CB57EFA4E07D7A2BA10C31C790CA1EB0E9DA0933EF4818A91ED89E9, D7DDCBBA259A6E4018A0F62DD0DC6AF8412BBA1F0909C88E71B83D9A75CEF1A66F8A27B5A8754AD77B0A9A0C64B8F0FB, C490F422E5A8F64264DA5E82693640C5F0505F924F553105130CC705D4F469E3768D9A29DCC2F9C1FE6EBC4ED8340349 32E2BB76207CEEEA1786E82E3249556B25E5C12BD8E1B9BCDD849FB5C89DBB, 3AC066784ACFDED2405E992A297EDBF9970631B2F73A069661887ADFFC84DD35121F3C61A16A9DB441A256CAE3AD76FA, 2902428EEE224C9406A319FD6068F958A7AC490A6DFA71A0D5D6DCDF06412C68C2FA3FDEB0D8266BACC42F9B6CEA601B 98A832626176CCBE4694B88A96DC004171B143838AA52D36988DDF2159D931, 90434B263679BCBEC06BAD5BB43B185E912831A31C0622629F80AA005A09C34B650FBBE82E735F4B9755157E1ED7F619, 5FEB842F99CD571202E05EDD9DCEBEEE7133A387A3CF3114DE210C2B076FAB65166B4AD46211137CCBC156446F348A01 1C9F897272464663AD3BE299FC49400C45513CA8A9FEF87A3C9A99D640D8B93, 2216B8FAEC60F877265A440D0F311E65E6AE312BE03260408A01DAA1DEC1C18003C2965461CEBE6145B99FAD6A4EF282, 5FB5B6A1C7BCAA608AC9C68AB4D3EB4194A035835D45519F34DE59AF4D34B6887C3394500AB59193B7F6458966774AAA 55DE9C5756D2D32B07B3A7CDF4DBC024CFF3B5F9FDFCE96EB5CFCD82C28A2B9, E03EE03D488826AE89725DBB0038E503F879AEC7DBD3C7A88E522246BE8B2C4FE2F1FF10D55B749852AC2BC9F54C5078, DEBBE08771240ABD85A508BC64ED09CC78787F97393C58BAA0748BC9D31F8A107FDF88F018596C200A4EEEF0303D10CE 1019BD50604787981171AF769DE93406E6FDB21EDF9F6BC4C216F6888479E82B, 6CA1BD5FF27D68C0635823A156C58CD842077B12D050729DCCFEF7BDADD7A700ECF11451991C3A304EE485072DEC2339, 75E0EFCF80D47859E030BB4E89D25F36A6E93A4FD19F8193FA267752304C8B084C426C0CD2811BF188603E19B639694 304D37F120D696C834550E63D9BB9C14B4F9165C9EDE434E4644E3998D6DB881, 6E7FD0CB368344068BE614E8D3C54E920DD4337ECB645AB816BA42032C40AF9E44A78D478A7D00783FC23AD0C6C6D3C5, 6B8146C68094E6FC6877EE99966A4C9BD7B172755454A90BAFFB9B9ECE25D0C1188E723E783D6C2C4A11E22B65DCA5CA 90E7A7D36283C4589CFF2B2B8D32D43E1EEB4315DC9AC9EAD2CEAACCA8492983, B796AC582388B56FEF9D37755BB7E529FC393C59817E2C2A30365352E3058BDEBBC05A17474C9B21BB177E4DADC90A38, 58112D40D3398F49094196A8FD81090B1CF4F60C8FE567D2521C8C0DB5829B75824557C00105D9FE407CA1F222BEFCB 1B2B6F77A278B4D09D6FD8182A7987CBA5CC1C94195D05DC0786C0065F8DB7C89, 6722763349DDE6305488A56BF54C65EDD505C368D147C7C5ABAE253EDD874D927E270641EF606DCC5944EAFB5C816755, 67BECC5F12221AEE2F18EA6EA98B1AC354480566B271A2A95CF15D7AA7C4B40EE41E2A7759D4223E9DF3061A972B9994 51824E66E76A1E71D84F88487F6C9762F16455BC4C171194169440131EA92759B, 1D7D201EB1E6DB52E1D4EB87C857E0933378768238B02CBF74864BCD3585432670F7970AB150C6CAD21C4CCCCE9ABB7C, 6429429FCD058769C0557F1F591D22804C71E34CF62A92AF3398CA296A3D422DA76326AF7D3401CB0D922C35B60468 F486EB34B63E5B5588EE98D97E45C628D42D0134E44534BC43BCC0395BFB760D1, 818DDB262DBA224B41A4E6BCB3BC5B06D2E1215295A5795BEE762A2B1AB803ADAB1CF78CA1E9B428678766C7889DC0B0, 2851BBC399216D09B52E3D0F518FC440BC11E65B8F60FD5F61FCDC544740F4AFAA080880158B1E899F4CE19427F89E4F 2DD94C19E22BB12009ACBCA8C7AD1527A7C87039EACCF9E34CB3640AC13F262273, 60D6926E594171B8C88C1B85A317653FA0A5BECF9138BA15BC5CDC34DA139DB3840B90274CA4D92F47BA84D7C045D616, D0872A2E735DEB24AF801252B2096E2A340671F7B4B2B89063C2F2E4D51ED48978B99FBCA36F781F0A805FE8F4AA3304 898BE44DA68313601D0635FA57073F76F75950ADC066EDA9E61A2C2043BD726759, 6CE00FFE436BEAEB07C97C3E273DD166D9F292D8CDDE885B04697A77267E99C7B3E84CEC74B08974764EFAFCED7971CA, 12FC43F043C8B8BEA9C9E1CA67602DFAE22C2D1B9754CB44F453FAE6710A31F338924DE4FA9AC00DA116B61382D03920 19CA3ACE8F3893A205712A1EF0515BE64E60BF2094134C8FDB24E8460CB3857360B, 9D96088E2D41DE9BCE458A6AD83BFE9631CF5461616B5CA08F300DB605A0FE950D76176D31B7225F7E13866FB57FE5DC, 5FCBC3C27E8A2E16B95CA9BF832A7EC4186429291164CC134F6DDE96DA9240F13561D5E84FA4EB13A1E41BD6837B4CFA 4D5EB06BADA9BAE610537E5CD0F413B2EB223D61BC39E5AF916EB8D2261A905A221, 2D3410D1606FAC3B4DBF1265C82F2D5F211035E0C2E928D0A9D151323F7B32360E52238D422679200EF62DA2E6C36013, 79B4F256438C02B3DD0A5CDDBA9E1F6E18A9D669D3652F8FADD79A530F8C22C54029015F15B1094179AF5D9B4B9089E9 E81C114308FD30B230FA7B1672DC3B18C166B82534ADB10EB44C2A76724FB10E663, 172FF498DBFF706541FF31AFF32E3EB9F07FC81748CD84A8AEC1EE9CF35C2E17407A812DDAA5491E32E83F69AF427086, 6F67F66B7BD3FFDE4C80AEEC026E31D1D7CD459A6360ECD900A879A8BD427D340B0A925DA83654C9855C04910B11768E 2B85433C91AF7921692EF71435894B14A4434286F9E09132C1CE47F6356EF132B329, 31626266CF735F78C5A9BA98EF6A9EB3B714077365DEA9ABEDC4CBFE1812E4F819B5FF3123A2A7AC683EA42E578B6DA7, B0FD65EE7A38E4A4389412811F42A0FB7B223183A2292FA0CD8A5C66F054C987D8C1FEE7A571A2B45D8BF126BC1BE5A 828FC9B5B50E6B643B8CE53CA09BE13DECC9C794EDA1B398456AD7E2A04CD398197B, 49B9BE9070D4BBCAEF23333DEAE2A7E39846EA57C853C59249048D6CA3C72EF8AC5C159B371E16F599BFAAA358FCCFC9, C440C717EBFA22023D74BE6945C7F0040B52029A42AC9FDEF1EF3675478C56F01B71AA26BFE0F30E7194C4A9226839FF 187AF5D211F2B422CB2A6AFB5E1D3A3B9C65D56BEC8E51AC8D04087A7E0E67AC84C71, 23D7F597BBA17B451745CA23428D62BA70713DD5B5B5B8FD060BA4D7070F3A8530996EA96CF6C423FEE9F1D28B12C222, 1EB5C7A12590265923F5C803E51052B75479B2AF848C4FAA898C9F93132C3731BBB62E20B33F7069645A6B9802140E57 4970E17635D81C68617F40F21A57AEB2D5318043C5AAF505A70C196F7A2B37058E553, C52B3E6360111931BBD8070F79BB3F2B1C594D7D8F2900AD14243F19A9D5D739FAA0C88F30D7C6BF9F9832B4230D8D71, BB82ECF98204BBCE23A794D5D049C9925C1321E8F7EDC9528DCAFE06FE96ED1E11C99210CFAA67AF4A70B5551E95B337 DC52A462A1885539247DC2D64F070C187F9480CB5100DF10F5244C4E6E81A510AAFF9, B2609AFC57A8238AD4A3C14077736B32493452C962D369BA4ED8182550EACE70252EA9DA790C98767F46A8603EC0A53B, 9E83C5FA32789C1E8BD7DBE04D0B96780C93EFF30FCEDD284D023E588FD1268CAD987F5698362DE3ED24D9BF3E29EC97 294F7ED27E498FFAB6D794882ED1524497EBD8261F3029D32DF6CE4EB4B84EF3200FEB, 2AE916732DE7DCD8C8527890C10AA218688B578078A25033CDBC57FAFE79AF82E308D860BEFE747EAE19F5ED8FA9D136, E5993D6EC3EA6D8E0CB58D40379B6A0C489D455F9AC54297A41D20CBF958CEC7B35A0259E0E244FEED1EDD5EA86B9AC3 7BEE7C777ADCAFF02486BD988C73F6CDC7C388725D907D7989E46AEC1E28ECD9602FC1, 7A74434DB230C40AAA6E6696EB973AA6A02BB1A85EA9B403B21B7F4F83404FBF79D11B4DC4264C848EE9863D49DF631A, CC6DA04984781D57199BB36EAE63B650402DEF1968216EE194BA36AEB176B7BF40DBDE28F6465ECF3371F040B9A6AFF1 173CB756670960FD06D9438C9A55BE469574A995718B1786C9DAD40C45A7AC68C208F43, B8F7F463E8DD26A1A5FB48D3DF0C08A4F2ED37877B4A055FE4DBE0BA4E8761C1D572BAADAF2A999C4148B41DAC692700, B9141FD5AC249FCEF63CA1E13852ED4A874314E74C8F7F1595F7742A8626D2852F9EAF31AA1986C3E57A80826D3F4C58 45B62603351C22F7148BCAA5CF013AD3C05DFCC054A146945D907C24D0F7053A461ADC9, 68E34CB48DBB00929D9BF6FCEF98A117BBD510C2564FA29FD2735680550BAB2CD93DF8AE1E6A4AEF1156A7093BDD07D5, 74FA37802F53F3682BF03F2BCA48C833A7B40D1AEE181FE764459A62EB99AE94E0D92048186717CCF2AAD7C483F6BF19 D12272099F5468E53DA35FF16D03B07B4119F640FDE3D3BD18B1746E72E50FAED25095B, 4BA1856FE53A35E25635AAB9F080EADD97F9C96CC49D01293F6178F5B09B736C69692401143D1200CEF4E8B52C5984D9, DD8D0BBFF3E6511AA4530671F525ABABFEA2C5D4500C151029232172FDC69CE5C69BB53A2AEAFE99C8F7FCE1EE25FECA 27367561CDDFD3AAFB8EA1FD4470B1171C34DE2C2F9AB7B374A145D4B58AF2F0C76F1C11, 23C4C7322C274C1FD10B4AEEA784FA4C8A7A8E72536EAE3F8A97EB3FB1B2B8D7E880A39B3B0E4DC95F1C704F0ACE2F38, 36FB622E09A43F62A4C543488A3239F341D231115C4BBE0D7577883A109ED94B19974D2B87B6D1A324DFAB73C6DAFE03 75A36025699F7B00F2ABE5F7CD521345549E9A848ED0271A5DE3D17E20A0D8D2564D5433, 29E716AC4CF5EFA90E79D99EED9DEEB46EC39229B477F887175C6A68CC6345B5ED1A760FBC997E6CF3EEE584679271FC, 2DAFEAD17CDAE27C83A8ACEEBEBD1655719C74495B1BD05C123254CEE24D348B0E6C3649409F391AABE51E6006E45A5C 160EA20703CDE7102D803B1E767F639CFFDDBCF8DAC70754F19AB747A61E28A7702E7FC99, A840D7F9FEB2351C3C6BF1872AC022AC068F265F3FA0D814762119C514BE0010F62DE741E466AEFD5E7F72190AF5C7D, FB0E5DF0996F206E7154411E990D83D0E73397A27FA795B814B68B344F172248B0F1B7789840B792564D83AD898510BC 422BE6150B69B5308880B15B637E2AD6FF9936EA905515FED4D025D6F25A79F6508B7F5CB, BF0DA77B49FBB8EA2BB433C8873D96485B4A623820B8FDF825A34B7BB5EA6F0C415102C6BCE038424BF3D313BBD3E7BB, 38F81B9F33DF390BA1D1001A09530E35E77F91FAA3FE35CB5C95FBE7DB45E89D9BD081E98A0A1D7250866B27030F11D C683B23F223D1F91998214122A7A8084FECBA4BFB0FF41FC7E707184D70F6DE2F1A27E161, EF1240F5396B769ABB10781B79F9A1D04C94B089512298B1EE4A1E5073C21FDDDF9EA1106E9C73DC0C27636F6B11993, F0451FDAE15BD55E1992AEDB6D907DD0A6EEF5E9A0872BE6042F8E848F536180FD13EB71D792E0F8FA485C8F658BFD13 2538B16BD66B75EB4CC863C367F6F818EFC62EE3F12FDC5F57B51548E852E49A8D4E77A423, F3B8A70AE9920F885DA2487B839FCC238E78D3D98B24EAB8B29F329159AB1A28557B0154C92F7268CE9F48D8C47DAA92, 7C544793B5EDD523D217EBBB4EA3C36F8075B1166C06567F6538C3FF5212EC7AB422CEDCF5B4CAA86DC9CE28E780F66 6FAA1443834261C1E6592B4A37E4E84ACF528CABD38F951E071F3FDAB8F8ADCFA7EB66EC69, 5B9900B2E181437F20C7371C9EFB6DDA9709AB3E8320AD75BEDA3D0A2454F5B84CFB98311F0EB15CE447A395482A31FC, D16A898817F2C9FB2DC857485F9BB615A5AE7258BD5992A565FA74D2232FD754E70EA35EAA181355AAC3374B5BD9FED2 14EFE3CCA89C72545B30B81DEA7AEB8E06DF7A6037AAEBF5A155DBF902AEA096EF7C234C53B, 3B8F1CE353ACB011F49C9064C619BAC0DCF51E18ABE28DEA414A81531A565D5BF948659CC68A92060658E8706B1254B, 6E9316CDD398FD11D8795CA47382106FD573838D14E6125F228D75F9CB9C0658E4583CE3C6A72A977C29F3F89141FAAC 3ECFAB65F9D556FD11922859BF70C2AA149E6F20A700C3E0E40193EB080BE1C4CE7469E4FB1, 6AD6980445D9CAB83CD3537B2EB1672E3FCCFAFEEE9B71367E60A47790A0D46C1DB962810D734F207A1422034C055926, 61CB8721438BAA0F4135DBCBF1FC357611944DBC71C99436874AA3CE288410C02CCBE22225588524E21794FE443C8DDD BC6F0231ED8004F734B6790D3E5247FE3DDB4D61F5024BA2AC04BBC11823A54E6B5D3DAEF13, 16F274584C49E3A1F20AF403B4F8440FF0D6AB32A1A23C07DA5848183CFC509401EFF5114818FA45ACB81903040C2EC3, 23FED4B22E70E6EA699F33E154A861E4AC2782AEA62D54D7CA1FC5893A584CAC39443F8FAC3AFBCF9C1B07386C209D1 2354D0695C8800EE59E236B27BAF6D7FAB991E825DF06E2E8040E3343486AEFEB4217B90CD39, 1A5825D393E1A47191EBA134E7D60FF6113489F99384AE7000844A47EF1781079572BFA26BDA0D2951C7BDA1FAC20999, 752EF2C8EAB59125A80DD0FE3C442A2E0D50A69D7E01BF0DFC3A98413C041CA449B8BAC885BCF6F8BD58C604A12B6967 69FE713C159802CB0DA6A417730E487F02CB5B8719D14A8B80C2A99C9D940CFC1C6472B267AB, 3B82F8F2C80125EE2A43235037F5B95373B0422FA2F571B50F88EB80C2C8131C8D8B3F64DB9FA15CE443CC15989B2BF0, 5D6B663E995289465BBA3CB4288FE2931243CBBAC8B11A24B47F1C9D8796FA8DAB75973446211400DAB640F13E6EF994 13DFB53B440C8086128F3EC46592AD97D086212954D73DFA28247FCD5D8BC26F4552D58173701, 6D23BEF6019F6DBC92F4397AF380D0BAE72D88EDE78F62C1AC8A66A5B9F7423F3A57362503C9AAC6BF098F3863BE678E, 15621BA770C918EEAC97C8EC21C98FD27DFAFFBF9A2993AD6C111E0070A2E7140ACCB878C2FD39D0D32346C7C4231A47 3B9F1FB1CC25819237ADBC4D30B808C77192637BFE85B9EE786D7F6818A3474DCFF880845A503, 516A07F49BDDAC28057A613D5C5E8B3DE0B7D33F3DA6FA38DB282959CB5D0DEF0656CB453815DB5D27E04DEE3D5C4979, FC0892ECFD57BCB0BED19F4E9391CEEFA5867C2E497A0B8D537A5B244985A305DEF1E28BD873622A1FCC9DDD20D69B82 B2DD5F15647084B6A70934E792281A5654B72A73FB912DCB69487E3849E9D5E96FE9818D0EF09, 663334009EEF0F5BDAC82A98842DBA6C290AF03FDED8E8933800DFC77CD1F21F47E19BE9F0E916D6ADD5458FA9AE757E, C145C26410F722906D5AF84E072D953B6BC2A07C6C8966008FD38D12D1B8E514CB467250F0C5BC0CF80D4FF056D1ED2A 218981D402D518E23F51B9EB6B6784F02FE257F5BF2B389623BD97AA8DDBD81BC4FBC84A72CD1B, 695892E7A578108D9605017456CCC44A0228E3A0CEDEC67A8A5CB219F35626A73228C602DFF9600C2481E1A52F881B5, 803E5E1E1BE9ADF9F8B30EFDF941BEB8AE011BD1C2E4C6AF07D20ACBB88E9DA82F24348AB83E3941B75A3D0008A341B2 649C857C087F4AA6BDF52DC242368ED08FA707E13D81A9C26B38C6FFA99388534EF358DF586751, 8B86E7D53BC4234563A036A2AFA90A98A9FDF86687A4C3BD60878AEA479DA1EC10A9821CEEF5F50F4C72CD8B58D64452, 2BE84EAC8BB312E4B313DD09E302854C38BDF82A1B5E9C0907F1477D8AC09E0E1C77803827E5E0DCCDBAF0B309E37330 12DD59074197DDFF439DF8946C6A3AC71AEF517A3B884FD4741AA54FEFCBA98F9ECDA0A9E0935F3, A796AEA61F3BB341C35F547715FEACC5AFDA9D48985E424B89251D9BF11C99A5B10F32A8FC31FF136D016E74E7C7415E, EDF583406BFB78341830245DB5EEC7F601CD84AEB9D045A6F1B0AEF7114F5B7D4A6C9A1FA61A3D4C3A16E2FA1056E191 38980B15C4C799FDCAD9E9BD453EB05550CDF46EB298EF7D5C4FEFEFCF62FCAEDC68E1FDA1BA1D9, 4AE935C284776ACD166F4C343D5D12720C1BE8C88CBB9C7BE9EA1A70466C47A58CA7B5A2E5B8FBCAF23C0DAFF65CFD31, 91F85E4F305B7F1716C9CD45AFE07B797E70EA8B823F25721C58BD89EFE71F7C978D4B1180D7A88AD6883DAFB5B2D40A A9C821414E56CDF9608DBD37CFBC10FFF269DD4C17CACE7814EFCFCF6E28F60C953AA5F8E52E58B, 63F40B7C626645481A5B538C360EB288121A3EEEA90DCAF7177E7DF8041655109424A7BBDE730D1E09D690855A7B4A1A, C28E69941D0632596D822EC58B9B6AFB16E303D3C63302A9BCEDD5A96E06B683E6ACF1BF544C83893E9E667A425BFFE4 1FD5863C3EB0469EC21A937A76F3432FFD73D97E447606B683ECF6F6E4A7AE225BFAFF1EAAF8B0A1, 8431F65646F1A9FD64333DA2687925C55EAFA25A69E476E3DA1CF415A1F05DB42C4C05EA4469179EE0F90C2D70213DAC, B0162F02D0FF9D64A3F6F92C0017504EE441EA61242F1BDBDD6FCAB0EB2915B91C538D435C6D3F400315C42C60E7A4A5 5F8092B4BC10D3DC464FBA6F64D9C98FF85B8C7ACD6214238BC6E4E4ADF70A6713F0FD5C00EA11E3, 720CB31D6AF250CE026759C170577B008337D57F53A751EF3A9FF29F89601490E5F69EE0E2344481AB8C8809ED64910D, 7483272A9609DCB8BEC8FC7127F05F6AD620E65351DF224D768740B155D7D13BBBA239B38640AEEA65D5FEF11C39326F 11E81B81E34327B94D2EF2F4E2E8D5CAFE912A57068263C6AA354AEAE09E51F353BD2F81402BE35A9, 3DF3D364A95EA24C74117A960CD50445ECB524933484713A87342B06622B975313AC26A82357C46824A50E983E794194, D8008224ACFFCCBA4A2978C20794F25215FE7A5767218CF26B017EF7E1DAB692E2A2CBA87E7A95D3BCB35A6110412906 35B85285A9C9772BE78CD8DEA8BA8160FBB37F0513872B53FE9FE0C0A1DAF5D9FB378E83C083AA0FB, DF2C5508681B1AC68D71B67556F13BB4A0661BD8266593FB948379D2CDEB836B49B5170A9C309284ECB59929B0AF5434, 906F784289214F86A978A719108537B813E3285290705F2F2E10D617554B898F98B72286B96643D7B17D6BFCCE75E72F A128F790FD5C6583B6A68A9BFA2F8422F31A7D0F3A9581FBFBDFA241E590E18DF1A6AB8B418AFE2F1, 7B07D208B5A058E7D09112F3A875A58D0D080BEF1F931D83C6F276F85398FB7ED40DD192F0315D7AE8DE0DD00E40143C, 1A7551F40AD14AB1911F794C368A53E6735C3F3A5EA54DBEA88D99BF4CDFC051BB6FD19185CF15ADE25859E4C82AFBA9 1E37AE6B2F815308B23F39FD3EE8E8C68D94F772DAFC085F3F39EE6C5B0B2A4A9D4F402A1C4A0FA8D3, CA85DC8914314A4F365B1F278F28E0A74EE41E7FC277861406E74E23F6B6FC1A4BD2C3858C71098296B98CF738F47105, 4A964F885C21C5F5D39EB292D2449571D1255459696C4DC9C71CDDBE7408538E33DFB7931530F27DE203B1758AF5FBCC 5AA70B418E83F91A16BDADF7BCBABA53A8BEE65890F4191DBDADCB4511217EDFD7EDC07E54DE2EFA79, C1B9607B4E9DE23B63A46331D0C4B5AB9E6EB094EFD7552081A6B2457024209B108BCD6CEA1174282BD06B34DAF330FF, 5B1C62CDC41E849CCA465468171DB1F5484A0EC6C62D5F94DB5C2FCA5CA6D65322A6F36375D810BC5CC972185F843728 10FF521C4AB8BEB4E443909E736302EFAFA3CB309B2DC4B59390961CF33647C9F87C9417AFE9A8CEF6B, 8B8B73F58F59088BD5E624F68B426656FC6D90812AFC7AE3D4E28F3532F218C65D21BD545D325C4B6A6BEF298894ECD0, C700E0E02F65DB161A44B5A83492654FC519D1CD37C190DA83077452D21681DF52F06DC3C4C44B830A115BEA40B96A2E 32FDF654E02A3C1EACCAB1DB5A2908CF0EEB6191D1894E20BAB1C256D9A2D75DE975BC470FBCFA6CE41, 440D5BC580B0671558717901C5D909422E72AEF58AD0CFF4A2232EC8BCD98619E81B131583F8F7589DB5DD58D9E557F4, F868CD69FFC0AC254E75BE18F5650456EE793CE63DECAD62F674CB71A9B80A010D46B5E4A9CD3FE2DE626873F7E6BE5 98F9E2FEA07EB45C066015920E7B1A6D2CC224B5749BEA62301547048CE88619BC6134D52F36EF46AC3, BD75A8FD05141C42E256A896D747F31E1FD5E4D9BBEBC6B03AFAF2D787A060582C097329F581B6D39B0A1505FB8A6780, 9E26B1552C65DB9475D1BBA9911355EF925895C906C9C836160192BAAD415C0B1BE80E280E19A3C60B761AB675308060 1CAEDA8FBE17C1D14132040B62B714F4786466E205DD3BF26903FD50DA6B9924D35239E7F8DA4CDD4049, E5FAC224173981787051EABC0D28F0420B0DC0859F0675E306AD76AF737F5D40821AD62B59035EC94AD2BF9A72FF7A9F, 39F695FD0A751F8910AFF1ED0C9CBA4AD1015C9E098078532E5CB579357277F29D61039650B90D3AC4BFE6C2A34FCE75 560C8FAF3A474573C3960C2228253EDD692D34A61197B3D73B0BF7F28F42CB6E79F6ADB7EA8EE697C0DB, 2889DF3262DE61C93D8A9AC7A33E9EC88268D744788A4ADE8AD19102E3F647725C622F80AB654275CDF450239027D9A7, C330BB3D4BD5914FD431AB21612DE48893A1A3B25BCC1E9C03E926280BBFE5E5D8DD7A71449707B11B818C6035CB1ED9 10225AF0DAED5D05B4AC22466786FBC983B879DF234C71B85B123E7D7ADC8624B6DE40927BFACB3C74291, 807E3BF550B32E277C88533440666708A429FE39EDD1FDBFEE02FB855AD4BDBBCCF91048F74A61026C44F550BDCB305D, E7B5A99A3C298578676B57D21B9FF5C0B2A499B1494016860F14F781E21FC883DBD6A5D6F47E2E6143E1BA2CF2E22F58 306710D290C817111E0466D33694F35C8B296D9D69E555291136BB787095926E249AC1B773F061B55C7B3, F7EFDF8EBCBD56156CA8D4A9F5568481919826980B4F7E667C00FB84360BDC99E2463C7A617B6B81FA6BA95E9E88C098, 327A298A1A2306076C1CB70642AB1DD09A26502D450D370BE6D7976651839A483F015D9042F6906D595FC75C80005097 91353277B25845335A0D3479A3BEDA15A17C48D83DAFFF7B33A4326951C0B74A6DD045265BD1252015719, CD8AFA2E883373AB1647AFD64DC8A80F61A2003B3A4ABDC2B7576196475EA14E434A874CF46A58F68396B918B1109915, 5A3BC4B19FF83A1F3CCF539475A8A4A0E50F9055E3B381D6A366F4DE1E5E15E7C782ED26E192158E0DFF52934CEE6FE3 1B39F97671708CF9A0E279D6CEB3C8E40E474DA88B90FFE719AEC973BF54225DF4970CF7313736F604054B, B778EEBEFF27BFE361B2C919A12EE43AF10DE8A0F09F77C682917949CB68AB1A47B8D9C3B414D493A41FDDFF0960B378, CB71031FDC86DF7AC19BD60BCEBFB1B6934E662F83B41326C8247DF23F3ADBC857AD7105E9BE30D96FBF7F5438C7E1D5 51ADEC635451A6ECE2A76D846C1B5AAC2AD5E8F9A2B2FFB54D0C5C5B3DFC6719DDC526E593A5A4E20C0FE1, 7150F2DBA77739F4177B6564316E12B6316CA42EE135DE214918C4AF468C07AEA8A7F7378689BAEFF4D334D04D418479, F5D215B075DD96B5DF1CEAE9BFB8CD5B77C1D9CE8F28E78A3B000FFB724D6F1D36F15CC6C4138BE0503FE49504F14D9 F509C529FCF4F4C6A7F6488D445210048081BAECE818FF1FE7251511B9F5354D994F74B0BAF0EEA6242FA3, DC61DBAF71F48C4FCF89940E18949B92B8B6DD2ED84597727FC1676B21D1A6F2C317995A9F3FD7F35ADB0AAE0F17F7AE, 330C903F413F78030C1301ADEF491CA62A5EED46A7B6F3AED2D0124FCCAB7056C25582139A05EA9CA06932A257E7659 2DF1D4F7DF6DEDE53F7E2D9A7CCF6300D818530C6B84AFD5FB56F3F352DDF9FE8CBEE5E1230D2CBF26C8EE9, CA764475D35AC4A15EADBBF53EBD3D8694B1E0A832793BECE7CDEFCFFA11E75A5DDF23CA2433BC3DED213DC364E50D1C, F0F6559FAC131174B886F2BF1112759FD0A21F9F9991001AFAA28C72D11C62807107DEB6F256A2E0EA935333380608F3 89D57EE79E49C9AFBE7A88CF766E29028848F925428E0F81F204DBD9F899EDFBA63CB1A36927863D745ACBB, 4385C0B8DC024C0E4E891F56C58987A8DC44A92F6F1CDE15F327D66EDD3A2248D6A733A913A0139DBA833235E6A476D3, BD8B69A56D688E8DDF2E696E363F1C119FA4F9102F4015E99E37C821DD8093984D1888CDB3A45305D2F25DDDBEF2E0A7 19D807CB6DADD5D0F3B6F9A6E634A7B0798DAEB6FC7AA2E85D60E938DE9CDC9F2F2B614EA3B7692B85D10631, F26EEA9694983171D70E3A5A4FBF178A08C1C087B5452BEF59490F688D3972FA8CF05B9DBB4DB5FC97B71EF47EFC7745, E14DCD1F6B3392DA3E2D39B93D9042435393206764228FC2E07A5A0C9D95655D5F5915551AFC31F8BDE0873A0D2F4F62 4D88176249098172DB24ECF4B29DF7116CA90C24F56FE8B91822BBAA9BD695DD8D8223EBEB263B8291731293, 469B1D8A201CB9C63D915BA76C776B04DB67DE4A343709F8FC84C3A7569757A14C738A89D1E093FAC28D84E81098C208, 4585BAAFA636261C5FD8B417B98183E8DB4A5FC31F15B9F3607BAB58A5DAA4CDFDAEA9EEDB2C8423B53EE439D630E9B8 E8984626DB1C8458916EC6DE17D9E53445FB246EE04FBA2B486832FFD383C198A8866BC3C172B287B45937B9, 2224A5B8D0E6DF5C14303F40BA3FEC51120D078CC9E2D3E085FC2E002D79344B5432C0D78C179B5D64B3D26C29E943AE, A055CF02A96E37559A219599FB3DED8D753DD9AF7F2DD3073D6D60DB00593058C12430BAE9668B7F5B1F3C7247121581 2B9C8D27491558D09B44C549A478DAF9CD1F16D4CA0EF2E81D93898FF7A8B44C9F993434B445817971D0BA72B, E97D762CF98BE3BD1D4421FAC2EDB20F4E84E6D938BF969AAB005123AA6FB407164013C9C33D9983D11D14BD922B7929, 31842B2BE7B7F860187A6D89515656872296A3E190933868AD6B27035F6B8A5FB7701923243A802D4E9625A0209F9CF4 82D5A775DB400A71D1CE4FDCED6A90ED675D447E5E2CD8B858BA9CAFE6FA1CE5DECB9C9E1CD0846C55722F581, 25915C50000731C1EE573D1977A5B8CC724F0663838BABE67EE11980BDC2618AE387874403DBFC0D3AC4D0DA4CA078A6, A3B49BFEC66C5FCFCAF2ACEEE28A8D01F4D57296AB730B650F488CA03BB3C90E758BF6558DF5D9183920CEC2EF5A1A7D 18880F66191C01F55756AEF96C83FB2C83617CD7B1A868A290A2FD60FB4EE56B19C62D5DA56718D4500568E083, 68582E393203364311515678FD8679A1778E6EF1D69EDBF93F45ECCE63B6498501ACA1EFAEFDAF7433B3A3FFB6208CCE, D34FEF465EBAE7912B706EE27B62BCB27D9A44886B3FD502BCEE62F043383335D1A1209B5932CDF9EC4CB31B0E154E28 49982E324B5405E006040CEC458BF1858A24768714F939E7B1E8F822F1ECB0414D528818F0354A7CF0103AA189, E319DF8E341DA59683C28497E8F01110A036805A0547AC8F0550A5DC0A98A315C19664457B517FC68BA31E498A593FDB, D28C5DCB4664862FDEDF90C3C9E1C0E187D79F2994F7D1B24E1431D5D037A69D65EF285EA3E690474B6DB46FE06F10FC DCC88A96E1FC11A0120C26C4D0A3D4909E6D63953EEBADB715BAE868D5C610C3E7F7984AD09FDF76D030AFE49B, D904A712CA3DE0A765BC1E4324D6D501B1E34C0C8223D8A51CD12BAF9F6EF03F3D02BE88AC5A9645C1C91B132E2D8EF4, 25F54CDE887A4DA40FE21141E431B0C4D4985DBB7FEAB4B7FB2070AD309A78AA21DDAB4BB1A34BFC4F29C47C5F1A9E50 296599FC4A5F434E03624744E71EB7DB1DB482ABFBCC309254130B93A8152324BB7E6C8E071DF9E6470920FADD1, E1030CF841E5BEA460A2BB2BD04162CAC55629B2424D04DC0F653EEF2D139BF86EA6E885A8B7BFA30114FA978733FB26, 6A4AE9C945427E1CD30AC2C2DB4CB0793DC9A1FC31A587EAE1FB86DD800A3758B4C44C3013F815691019DE1EB343B716 7C30CDF4DF1DC9EA0A26D5CEB55C2791591D8803F36491B6FC3922BAF83F696E327B45AA1559EDB2D51B62F0973, 552AC5C872630618A2DA71D90E05B80D707262AFFD89B7BF1379911B43AE303EE4796FD4C11D9577D20A78D8F8A07670, C6EDABEB5325FAB19B27AA2692CBB58A4AF57642C7E35435EE1A118A618C6FF921715D62FE85404A341877F6429BEB31 1749269DE9D595DBE1E74816C201476B40B58980BDA2DB524F4AB6830E8BE3C4A9771D0FE400DC9187F5228D1C59, 22541C181BEF319BA4DE0F5A38E5E3AA178683D7359594C9834A698B4882F8EC933B0C2530340861A6458ED7AA3E30E1, F10BADAD71BE09E1B9DCF0D56C22CF5C0AE30DBC3293B97C9F0C76F0A209F72F33CA699D0E24FBBA50F8E73440C920D0 45DB73D9BD80C193A5B5D8444603D641C2209C8238E891F6EDE023892BA3AB4DFC65572FAC0295B497DF67A7550B, 702A63CB0B2FF15F9319DA8A4CDA259AFA8494CF9F1447B743EBA7EE13BF717754D0E7D207B86F4B1D3E1673022ED9B, B21CE14F336590C7B851224E5C2E480932792034CDD49464EA85C8AAC6FEBF2BE68A7B7B7ED28166FE99741D9456A47F D1925B8D388244BAF12188CCD20B82C54661D586AAB9B5E4C9A06A9B82EB01E9F530058F0407C11DC79E36F5FF21, AA9985D7AF3E2FB935029511CDEA0DB144B3D8D67E523E98E23E2AAC3469B46DAD414B4522DEB39EC90907851C9D3CD6, 6513494B1E10AA85D4DBFE8992F61A1140A1E7D066DD0C2E7C5C34DD8AB649D31A555A41CD06DFAC4ED92FA325FB748A 274B712A7A986CE30D3649A667622884FD3258094002D21AE5CE13FD288C105BDDF9010AD0C17435956DAA4E1FD63, E8C81D1BC1C3FF2CCEF60F5029D4A63BCD22FF762032AC65B302A0445F11A2EFC60E46BCE00D714E0A246276E9706428, 7B5565840FB95A2D76313483E2DCDF4B17F0F37C6E67B9A998937791323A310D3E75C30F8E40273544F0ACEBCAAE4F9A 75E2537F6FC946A927A2DCF33626798EF797081BC0087650B16A3BF779A4311399EB032072445CA0C048FEEA5F829, DBD7AB5BBA5A5CFBAA7A1416BF065B07B7E3325742AB9BFDCBF78DE111FEABB9F04532FE06604D6056CF61336EE1750B, 66A3559D318D264DFEE5DF77CE521A3F53857383B89800757866D78B64173F1C3F24206DCB8905F5AC0E859ACBB71547 161A6FA7E4F5BD3FB76E896D9A2736CACE6C51853401962F2143EB3E66CEC933ACDC1096156CD15E240DAFCBF1E87B, FA533E8AA1FC1203A3C8D8E9A9405C71699B75EA71CE0B1246ECDEB000B1BB8117A1377EBCB2A431FB63F4E0D90CE06C, 23A480D5A4C528A8B9A8D790A03D9FE76D9CF8DA3C5370C810B62A1C6F28A0169B3EF0933484DA685DCE40CC5E2D6607 424F4EF7AEE137BF264B9C48CE75A4606B44F48F9C04C28D63CBC1BB346C5B9B069431C24046741A6C290F63D5B971, 8BF66C05DB5448E6BF481285A14D38ACB18740BC28FD8F77A2CB3049F894F14F6565A0C2E7DA29E387C191B5E3E19D43, 637CEBAEFA425A2C23E6167589A0D68DDE19AA465F59A1E08C46A64383A1A4703FE0510ACB504CCF2129479EEA3ACEE C6EDECE70CA3A73D72E2D4DA6B60ED2141CEDDAED40E47A82B6345319D4512D113BC9546C0D35C4F447B2E2B812C53, 9F776F4942E963364B571CFE0F2743030869C03A56D35D0F3928F43EB2D9A2179A6D3D4F2BACDAD96F3304EF7FA941A9, 5B0D270FD2C9BDEC2871510D56B5386D52B2B0911AA180EEB027802E5A25A88674C3CA0A42C204E73411877DA612806D 254C9C6B525EAF5B858A87E8F4222C763C56C990C7C2AD6F88229CF94D7CF38733B35BFD4427A14EDCD718A828384F9, DAFDCAE4D6C475716EC405C348AC9A2343D5D67F9B10082B4D3E2675BD85E32785D536C13BEC607D41410BAD609742A1, 2837910E8A7C8D3ADD8BFD714FF5730614698C4D32B8A9828C42C28869F90254DBEF41A5E43B71E78A2069AC85B05666 6FE5D541F71C0E12909F97BADC668562B5045CB25748084E9867D6EBE876DA959B1A13F7CC76E3EC968549F878A8EEB, C47B4D6351C30544BE020706A3713B8C9BD48BE44FECABDF134B45AC705B7AA5E1D2E0A4C5CEC413591A93D5134AA50B, C9CF3149AB16FCDA4CEE3BBB757AED324007869C47819656EEA647EC16F896C9919E7C58624BEE371C8D4097A204E42E 14FB17FC5E5542A37B1DEC730953390281F0D161705D818EBC93784C3B9648FC0D14E3BE76564ABC5C38FDDE969FACC1, 4D466DECA0E5F2C664B1C170485D0435CC913B4CEDCB8904E7EC68025C5E24F54250FF8EBD1AADBA575CAE796BA20E32, C1B53467F914F7BE0779A44AFC51735B26B644A1ABAFF7027BF87BE11FD80B816CAEB33C735ADC55DBF4C2118608BA58 3EF147F51AFFC7EA7159C5591BF9AB0785D27424511884AC35BA68E4B2C2DAF4273EAB3B6302E03514AAF99BC3DF0643, 186F34F7D45ACBEF7F7F7F93C57758A2A578981E9939AFA22AAD14879905E3694737867BF73633CF9F7E25C6A598FF24, DD0B1F68005D3588418D13E69D343B10722C96285A12B139049B8D3E1644C2F110D36BB7F919BC40DEB99EAF443D3482 BCD3D7DF50FF57BF540D500B53ED011691775C6CF3498E04A12F3AAE184890DC75BC01B22908A09F3E00ECD34B9D12C9, 8F6F64EA2755FDA51C99A50B57D7F438DA05A117322884A8F7F7928BA92C78310EF578005B1FCC2FFCFFE79C0802B2E4, D32301BC33B7B167EEAB552E05A20AF64E86E65986D5961C9E9EBF56F4D7F05D428EBDACFAA30907C50D18E3E7F7927 ECC-528 1, C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66, 11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650 3, 1A73D352443DE29195DD91D6A64B5959479B52A6E5B123D9AB9E5AD7A112D7A8DD1AD3F164A3A4832051DA6BD16B59FE21BAEB490862C32EA05A5919D2EDE37AD7D, 13E9B03B97DFA62DDD9979F86C6CAB814F2F1557FA82A9D0317D2F8AB1FA355CEEC2E2DD4CF8DC575B02D5ACED1DEC3C70CF105C9BC93A590425F588CA1EE86C0E5 9, 1585389E359E1E21826A2F5BF157156D488ED34541B988746992C4AB145B8C6B6657429E1396134DA35F3C556DF725A318F4F50BABD85CD28661F45627967CBE207, 2A2E618C9A8AEDF39F0B55557A27AE938E3088A654EE1CEBB6C825BA263DDB446E0D69E5756057AC840FF56ECF4ABFD87D736C2AE928880F343AA0EA86B9AD2A4E 1B, 160373EDF8218F9B6A762A4D4EB889E646F8739535D0E4F862C33F35187E135854D80B2123DA719D48351353AEDA0D3163CB215604492EC4568357643017002D68B, F1597050014DCFE1C5E5828401AC06A3FA9FD193C5CF52C3BB4A56F78E1A1B22011EFA491ED92EBC5413B874F4A8BB572E463FFE709D45ACB3F3E6AECA5D90B740 51, 1D1BBA380289A7726BBCD7D76D6D63469CC842DE44D26646BBC45381FD72BE7EE8109F67171227B5C923577F6B0A4731872575A0B029A7B251E5A339416299C8AE0, 1703AEE0F7AD8244CC35BD69E91C0670F3E541C9CE6E3529B902A980E93172EBC8AFEC0368616E1E23B04B4D5DFCA8343EB93B0C8870F7A6662EE1B2160CBB90F01 F3, 1CB253227B37965174617D5542FC0CA5EB142B4BCB51BAF2D6495008BF2C90BD93043A7377A937E1050B6BB117A81C461A34B14C0832AB26A2785D76462ABDC8B2B, 12FDF35A935AB3008E037D84F5B637C7A745FB21A00884834C9804B4CD3BAC49C9B1DE4AF315EB36E92E1E4A4AEA8351855E70B0BC4BA8904EA3E74E2A5F2ED15EC 2D9, 189607C1793AF3818DA32FA2F94A468BA69B3EE6EAB818B69F889101494155F9516765A8EA7440BE2930179D016B7DF6BB0D89773B072CBEBECFDCD196A56124DBC, 20FFF32EFEF92D8A2FF99E29C3724399CA1B0FC9430F672B5A82F7494787E4EF0DF0727CAB8B82250B0CABE69ABF34CBF4B194D03FD99CD85ACECE083F2B34E9DA 88B, 4E5EB103B19BBB84C89641B7E507308DEDC56060BFF03325AE009A4142D11438A3B2EA22FA8743D6B4AD2CEDB2F0578C98FB6FA857CE3527DD3B746316530116C3, 716F68F81916580A647CCF3036F3C8140D60A63D105B91AD0173BCF6F84CE0CA1BDB1D4049BB7263BE724FC920208014BCF75404D3300C1CD2CACCB07478308AE 19A1, 1D2EF46577B66170D9EF0F1F1486C3E7DEB985FEE76898575B630042DEEB54D8C3E934E6DF77FA7681CAA1AFC7A7C23053E87086932F561BE9B25FF70318BC495F2, 1B0D12E74EB99A8E16F0AFA3BB928B75D2B03E2889F84F3ABBCBAA77027198D5B8E2F72B6BF16937AE709C3026C74D26F2BABE31CE6E0294439928262D66A4AACDC 4CE3, 531C9ABE51563C7C779E89BB2404E00B47891DE3E465286B5177274B12285AED14935FFA8229705B3BD523C93421282EE4C544050F49A79285C61F8F311BDD0FB7, 23B671A070590887AD3388D92AB2FA6A0196BA044186CEA279BE939CC13053702BBFCBE4A8CBCF162D80DDA67E46EDE513B57E5B7D52FDBE040A91C497A2F35CE8 E6A9, 1EC7605CD3363B524A70C0BC1A258A53FE8F61A982FA3E86337C2B9AADA6C3683717982A9546CD1CC02FCB1F1EB9CD45D91DE8CA29E61E8A88323A6E237A62A28EC, 17CEC602FAA9164AE7D8D342FD9B8A47848D1780F92CB00C221E3A32424DABCF89EE805D1BFC602BC6110012352A15185CC5513116E370B46057A8DF61D9A60F3E8 2B3FB, CDD2F0F3012DF190BB260CC871FC42A9F17979A329D683503E59E7D4776D8F10F62C390E045D847E7FAF9AA1CC077CDABA6D87F4B1125886F25AFC4D6309199F5A, 417903A05C021068B2FBB9F2009317DC0B51D8A5A1C89B9824D99089D0958AD488C1001BA16E75873ACAC17E0CF711856929255B40B93CB2B95FAF77AC3C8EBF7A 81BF1, 3D8825CF08E2EEC0FCF1BC392D7019ED417E5DDCA47546B14A82F8D7F2EDB9D2DC774C0AC9E9F5478FF1CAE8CCAD02E00A25B8D8179B812D14FBEB962169397004, AB19E783633A89835F7389184681A605E6D5E4E3E9BBD55792E1F05A1EAB5B0F3F72F7333E659AC5EEBEDDB0F6D3E80922C19427CE4E391AAAB8F709613EFAB86F 1853D3, 425EFDBC284A04B79521998BD8199C9C2CA979A33CED4D78A27320B04BC460AB5F504FA2A3B85B09D709B16440BE80DA6391F448C134C2FA99EF5E7D6B0311852, 5B15B0C9DCAC88A1E0DA573948D3E637AC33B3D52B5C365B5F56ABF002624FF68CBC554C37706F33AD005CF0D2F07122AD3A35C8E80389DAFEBB5DBA489A1474E7 48FB79, F4666458E61E777A01C5CA195BD0BC48C3BDD5F2721F624C448034CEAA54638D8574E56DF526A81CCBB4652BA243713F659B1EDA90CF2D7AB62BEF511B665F843E, 19450B9BC802D91034E580F9568EF80B45DA1F84C1DB1D1D55400D3D3CEDAF64CB01606F3D1EA3C06A5975B09E91173E1573C910F84A98709EBCC9ED1386687D3F9 DAF26B, 130A85002F8B5DFA04E6AE28359493A64CEBA9CC6E69F799FA502A3E07CC534D9A1E7B3758B6A3C4F95088E03AA1619D778C833EDD1FBA196EEB6AB19FED3D64486, 18233CAC49290DD86F4CFCFDA74A217E141497EE6D3EFCCB1B32C46802AA3ABDB2CDFD3CAD19705580A2BC5C03D42F444AA8B9D98A51634F3B5DF048BDC17D633CA 290D741, 1A55360AB86673AF294A626616B918EB6BB916E45179AE4CB70F5981D71C976BCDEE1979FB76E3F8B04A60D1823E697D7C37168D34EA018F08A79CE901418186E26, D3ACA61B48D79BAF9BF060A0E7E1D9D99C8C1CBC3DE7F8E976EC0786A8075AF407C9B42CC9310D16CBB493CCBC8E816F6CB650C1F8FB5843E5BB43EF79FA639B82 7B285C3, 15DA0FAD97C5664A014EEA2068AFEB285536825108BC34A61F087FAF171A99D33671EA45F649A5DAF48F34EF86D9808AD8C15FB1780C15399E1E4BED006E11DA035, F78B2177D18B6C6C5FAE8F0EF19C8FBEDB436A41E3495B8C6D0D7FB1FC714E946FAD13B2C1D440C6629C2CEF0766E5A159321C696603B575489CDB5495E69BD8AC 17179149, 1BA1C685592B7F42D16E61C809DAB11F052F214BE908009B25101E39E52F44FBFD0D28E679DF4B830F75A63FCC2EBD52AE1F74345E281DCAFD3C93F5F9F939788BB, C4A69AB266A89B3ADD952780C9B744ED9BE8FAD135579ADBA4E1985872E17A44EC68A34B179E2E5DD6B7590220F5D7629AED0A51184FDFEEFBE69754528F441359 4546B3DB, 12AAC7907677FFC2B0EA828F9B62CC1D078295332C882FEF4E8D6D83D9774C84DDE3CEAA863B36916728CE0873CF8CAABF1122927922EC7DD748578DD1430F54936, 93DEE239B6A969AC8697F2E66DAF6D86DD382949FE36C628232FAAB7F8ACE756D35F8770B84C0CD91740263801B86EC85D84A707DFE8236920DAA0DB61DB0DA21B CFD41B91, 1BA7B15DECE55F529F1860709D825B96A0DA2F1B10696EA1411B83E0B1A60AB48419D6332525140733F5A39EC66E9A7E6041CB291BB4A650D28E12E60901151E778, 1124E66E982013045FCBF3AAA04CF16E919DD9584A0ADB75B155569F037F037C9E463B4DC781BE70FCE6E4FD6D064A03DAFBAFB2F1B3BF98AC081A58D9655BFE3E1 26F7C52B3, 1D5605150C9C55F2AD48D4DCDF57D783CD0FB107F899ACFA8044842BD3EEFF0E14C35FD9D6AF8F5C8CCE32652A44D0485F64D3BB2272B478A4052C07CE083645ABA, BC7178CA8B9F702147D51D9C227AB4ABEADC91CB315BFB4FA0741CEA14A1F093CBC1C9F08070E03E5A363ACCCE3526B398AD79A19B98907C4E83D2F020A615D836 74E74F819, 881A1909C05C38ABB0B34FB973B0E7F2E67DC887E27B3CC5233F8B4537656DB0B174F85F345B26B26F1691A1C1308E1EA8A3CEEA5957566AC29923E74305027B2C, 1E266B9DF37F657891919442B7AA3BAD7918D1A5BE12CF04057DAB9F2A0548A4473C6114955AED0ACC4E193E185F762F16C8D135C43059083EFDF8FD2E04DCD7BF9 15EB5EE84B, 1869716D001DAECCFD6765136D256680A68837DC68F2BD235F1A1AB286791F8488373122C50CC598CE10B86845BD722AC0ACBAE9ADFC3A75B77617AFB6481CAD729, 436FE2AAC82F0FE513573C6F2484FD302A46B3D4827BE3B71A26A909479436C9A58D7510CB4FA9435DB86EFB17230EDD1CACA27445115E7B061A62A924444D4B7 41C21CB8E1, FE3826BD84AB28E075AEB1477999DAF32D238A95CBFF442C09BD1B5EF9447BAE6798F2D8F6FBE0C71CC18F1EDD5A0254D966A6AD84977B88D4C96EE48EBD457AB6, 98C16083605208DB3FB220383B4993E15F5C150B31386642F0BA05F8997713A9238E599628E12BC5B8383E658063394A7C20B0D24C4F7EE5294ABA596D5445F1C C546562AA3, EC6F7EDA0EB724FBBBCD1642B71BBD0D40F7FE2E47D31C7D02A7AEF1BF89CEFC184B2B6AF7DC8AB5ED0520239EAEB949BE69BD467F0AAA56369A2113FFD5793B76, 846058E5FB3C6F251B6104B0CFB3874CB2DA880F88C48B4C454B1793F0683D21944ECF45D421FE165BF43C1F071FEF68EE89434CB7D540D49500747877255F60F0 24FD3027FE9, B382CFAF97D0624BD9EB280CEF9DB56B0486194A4CCBAFCBD85AEFC95A12CB624126246F01D1540EA22E94779CA825FFA1DAA6178AC1304F86475D4BADA8D367A1, 1F2BA28968FEE1B6D87B34588AD9636ED261791F2DA1238C5D01A809A01BDDDFBA72C30526542AEF9AD883722BE392D083309705E1D0B79A36B7341E165E3C11B55 6EF79077FBB, 1781C76DCF27574470E3DD260059BF8A683C7B035EE47DC890A0F22574D58165594F37D2D0723C39C72ADA10E51E5081C60DDBD167AB620CE3CD081BC4705A6D837, 45B969A054784E6F13E3EE16180E1CA0A8D181421D99CF8893A5000435456CABC0DCD5D2369C422D87018B15A81BCB33203A2E48D366D162CB5F4A4EEF0B4B0546 14CE6B167F31, D3FED2DF278619FA7A3859FB70B813D86E67657BF4E7E3E95D0A8E7B018427BD5F105B54AF8FB6A72E7D8AB8BBD828E5EE05A535E8BE183861163DB1537496F9AA, D8157793E51CD1C45AF217AC773ED035065C5A3E78AD7B14890C66F2403091E7CE1DDDD95970793209CDF9227668A7BC620832D6A8CF8FD07787B1C5E62A1FDDF5 3E6B41437D93, 1110B187C53AA1B25912B804E1011A16DC86D532691FC2C749FBD2071CE687322798D50FC7F3DE67A6F150D4CE081077F872532FEFA87CDA9A64090A9D96548AB23, 1345A97C14F469E58CB8B9598CAA1E4335F3AEB9174F57BC8D12ACB74995A881A5D4215D834C71CBA3B7EAEE8990AAE324E964A1FE99E4EBDF39D0E30B013E23740 BB41C3CA78B9, 7EF65FB33141FC3CD577E83C6DD24C9960469C1BA9F8939E83C39E0C561A61C3DDB78B6709FFFF0CFB7300E4149D65554F154D5AC9401C6E6663D1B19B245DBE43, 15E0841BFC562819CF29F603B16F3B4B6ECBFAEA980FA99CAEBB586020182DD2AE3AD469D8E4506A620A261760A08E89D7ADFA6303676DD9B2A2C356A07A21E7558 231C54B5F6A2B, 5C3F8CC55F447AF2EB183605C74A82F3C0503FC590C286DE08377DC1F84150692145DBEEDB8D94DDD70A2E3DB7C1B20052D9A38A14BF0EAD75E1AB7D96A541DCD7, B2E19C85DF2FA1A6D189A6C4F8F8691E3A535EEE83BC98686A80C6FC5E941AEBDF187964CB68FE5724FE84B51B5B14ABEAF7B9BBF4E9112E29A2F03F83A51D6777 6954FE21E3E81, 181F180ECA59385A1C1CFD5D73D3D0933E21C3718F5D1EFAEE38A87731B9E337C61D4C1DBAC9FD9C817B1E0D748EC2B54B396C14DAE674D51F1D007A3331F1EF76D, 1A04D11D9CEF25742E0732AFC481E1D86ED617252BBBBCB2BB9E6441167EEB9F5EE4B5CB9DE320C12873A20CF3F9DA34658B3054E17B30939612BAE9FAB3A4572F9 13BFEFA65ABB83, F09AEB4174243A39E411251C72FB8A141F53F78F6437A92D9F860E7773B8FA2581D9B925EC5AD1A523AE5905F7413745F52A7D8159BDA1C696829F251AC2C87D51, 1FECE716F47B3CF77F2C8564FD0EB11C8705635F31A9B9F456FAD7F7416D2A21CC59AAD8E3A7340F1097164E467224E7553A7C81A279187B08BD8797080334CB642 3B3FCEF3103289, A4849FFBC7142570E096397E16381C45FCE90C3940F5C506A6DC4363D1A8491A13357ABE330BCE6A9764B8CC517D03038046481FCF18A503C5D8D5BB047311C816, 639FB120417256BB3CE1D55C5F5797D3A9BA21E9E2BEA415536EF6548C2214E80D3D81620702E7EAB848801A408EF6BC9D48C4CE90FC68C80566305D88835E6414 B1BF6CD930979B, 12C0838ED0101EA04C5AF21B09C2DA4B3FCE8DB0067FC42ABA1FBF319CDEBF33A384BA9407A550C22572FCD41204B4FF01D65E29B9E875970CBEBBC8E6505849783, 1A2D863319E3AECF20C3E9D6F60624A87361177A696D77C559C3EF166240C6B849A986D2BB5214AFB3C1EF5DB60CA5F22A4DD91B0260EFDBCD947536D634D6E17AE 2153E468B91C6D1, 54B1388159170C0C7C4A6ADD5FC41C74FBB1EDF355ECD1D872F9E9582A00D320D0A9205FD2673D3A09FFFAF58C96FAC65527FE5796FAC796371D81502B93FE455F, FAD84EE0FBF823A557B8CA17B3FEB79EB50B631CEBD7C4E43A3362F36DAA89AE7AA44E49459DF34321F7AC9AFAABFC686A00BF2D783909653B3BDAC7593E8E9E01 63FBAD3A2B55473, 1DD666A051BBAD5E6EB96883A55A9DD77E63C201AB1A143512B774076D0C40AB4F0308D6564CB63D73CDD81DB462FB3C17A57BD33E3B26D7EB96BC2DBBFDE96B260, 50893602BC1EC6F294B5ECD39CE9D1840739C096AC7C1D8C1E4453FA1BAEDD0B18655FF725E6653FDE18EB8FBB6F4F63335FF2DD69AE98F171DCFBF146B86BA08 12BF307AE81FFD59, 1DE0E9F3E035E3F7D564C189397C21832ADE29F85EC8FC9B1D008871D6B4EEBC84D358C704CB4F7E9D12B909D458E218E9A7A8CFBF1D2C4044B6034EBBA8C477216, 10B2ECEAA69F5F89AC4A7B90EC5A0D8D43613F8E281A63E0727E5B08230689142C3A4BB826F8601CBFADD6282EC2929668EEE0B97995AC796E1335AC32C1A8D419 383D9170B85FF80B, 118A8A0B98A299F5FFC7CBDE5D89FFB8AD7C24832DE083022DAD4814F3C7A73959F77B6DE807F1DB1879DA1BA9BB547DB38BEBF82707D6A7E66F586B2052DAC77BA, ADD0F1B8DBBFEAD35FD7C4A9F3F8D2076FE42BD91740915B76D090FD31F8AD3365E5A028AD20081EB78B526AD36D46321AAB2FEDC68F0EA3961B699CA015B412A6 A8B8B452291FE821, C23FC4B56C816757ACDBC3F53C21CD67F660DEE23A06A95D8C8EF751F0060951D343780FB576AB07CDA6B2F68900D6E97C6813E8E3BF40B3D0BAD80909872228E6, 19AABFEB7C4295A5619C5590F209DC72C957654058104E2B0AB4716505C476CF221E541E0264348285961D3ACBB3B148993A06578DC94D7CDC9793C7C2FC8714BA9 1FA2A1CF67B5FB863, 1FD7232A28A4A37238C080753E6FEBDA89A14C9C44224D77E8E89187C3912EAAAD59EAC55420158B02C1290F665F7DF4BA66D02A82BB379BDBBAABC4315B1DB3BA8, 1909AC430FC4A553DD7285019E0D3627062A6B41D8AAEDAF0B907E2BE68887A568D7298795A0C9470ABFD6ADD29E62AC3B690774EF7B1291A05C61D0DBB47B72E8C 5EE7E56E3721F2929, 1EF6594F94654869B4EBFA95DFBB70B9C735505D45833E17F6DDFF6B02B1C560CE8EE7F4E25F7C1A59C167D6F39573A9A4808BD555C8E8ADAE7AC9678DDF5DFE6E2, 1A47987BA40C43D6A93E5FECB0304973D2EC8E27972524E3E95FF7EB3E1857988C1D37CE6CD9D7E5908919869B8A140FE780CF4EA803FB9124E0BE12E1964B6B9D4 11CB7B04AA565D7B7B, D25637FE03EF4FF9A71BD0594EA52CBEBF4F16B56E82C566530B0D1C7056EC19099EC1480018CD144D9C91426BC022715BCB190D9BBDB5AC1605B8A102A1E2F63D, 58BB79C16C10D2FB237EF55BB3401B4B9D9FCCBDEF3683C2F5431D4614EDEAC1FE29DDD23D58DD819F2ED64D9E6FE95F1AFDC3C17F70E32D156B416E6308F8BB58 3562710DFF03187271, B678885DCBE552E09F2C2B9CCD040A76BE73D101CDFF12C1F38427F0B563F2213662D281EDFDD0518E93871490D3C322152B8B99FE156C072AD48A6F246FCEA43D, D98172CD1094736AAA947CBB22A4B9C7CFE82037B816ABBCC70AA20B26B2781AAFD3B8BB597140EF417405AF726F8521918A7B14537480B788DDF7FABD535B4EC4 A0275329FD09495753, 10F8C57ACF45355ED2C38E40BCAD9BEBD2020CE99D2F445BBD1B2A5C2E9DDC8DE00A6BFB51B85355209E80233075510134E8C44576FC3F33C9390562FF2159DE058, 52CB1CD6F1AC84252B5A69AF5168E00C299C359440CC8E1BF03C49B86CE88794F64DF89563D979F68A166A079A7FB01CF118B46665BFE9C2082F57614D9B48F163 1E075F97DF71BDC05F9, 45FD2500C1744A0DBB9A28A832FAEC3AE568A8E77E4AE385FCDF45890FF826FA1660018C246E51FCDA6CE0AD7E7BD1C5B9D586495D1D61E1AE1DCDCD2F863A2305, FC6B68E01AD52855522DFB440A5C46171F69047C164E55CA6EBAFDA5908155B166652C487B4024D5B4687F973D90FA1F9DD3F433423583B4EB1B184C0E753D76F9 5A161EC79E5539411EB, 1496D321897B3869680DB0EF9F0036875B21F27B73E246377ADBB80164A0C8F7AED5572DAF12679DFDA0301B50C7FA50E79CB410143B7E95051ABD52B3DF7944FA0, 12E3332B48AA11E31086040E7B4669F628F17BA333C66E5B4F0602C9348FD5B59333F266A17E7F8185387E4B1B1799759D51DC017811B4E9FD37A506F8656D3810E 10E425C56DAFFABC35C1, AA821872EE88279B74988466C480438447B0B91B8660F1C7427E2A23CC66008E29B5D9AE999C200237C380034E5CEC62C6028DB0B986465EE01EF299FA4051D06, 47871E7FC41A4520303091E7077A820351A6ADDB9B55F75DA39E6C56404EB3897BEA59D9BA933E64A434ECB010256E33B564303B234A8B18ACEBDC9050909228A7 32AC7150490FF034A143, AEFDEF3E624447E87789B37B9B355B51ED382F62AF2BB9B01722C3D110FB865328AE5973CE920E5BCFED14E6E6FF3369F59F0E0B0DC8C2595B97F3093842BFDA89, 11C15F166282F692177A8025ACAA1E27C6CAA771523400634E083DDF03622E6AA0FE32C97ACD80F74A7AEA83E3C1C46620454F19DC44F695692CFF8C9B5924EEA5 980553F0DB2FD09DE3C9, 82CEDE98FDEA05EE814A7EE86F73EB5D196FA0529C958F8ACC5DC65EA8566B0D6A7A069C906803C812774D92EA196403326F5CCD84A6E07EB5DCA49D8457017971, 8021ECB6CA72FAD06B69A0963245C26C9D5782ACB28698E3A8ADE1DDAD20C0A3FB0ED90EAD4A7CF0A533AF508884358A6F709F34D9244BAAC40FFD44B6B17EF00F 1C80FFBD2918F71D9AB5B, 1079E822EF5B40CF8050214A2AE16F24F115BB98C379D1D9718EAA33EC9F8FA94C05C017CA59117D2AA5210982D579889C675D61240DFA3C7060C85730DEB36CABE, 133924F6747F6611A1EE66B2E6FCE491EE18A6BF11DD6C56B95AE5E2A96D3DDC9F22C0C3CFEEE18249A5D8078A785D85A271B0F8A6DAC66C440BCCE6A4DE320AE78 5582FF377B4AE558D0211, 464C7F0BB11C4EFA309221BD9F617FB5C1D286AFE1AB1CF01B8FE713156FB9556592DDF1FC67FD72C382414CB4366E5E17A848928D8DAAD48D1B9D58F410858460, 49D757F4B9D5993E0E7516AF45DE7EFD76E6D433B7B73F90F669ED0084C456F9181E6925BCF62036B9A9CC9E2836B8A3F91CA4E5464DE749392C4D159F681CE6F2 10088FDA671E0B00A70633, 14395C5F8FEC4BE0611A13208FA0A51884B9B64134D0D490DCD3E226818DB25F60BFDFCAA038DE5EBEEA261832450D85736AD1F5A353E0324A905B004F1175565F2, 1B99F4AECF9C15B1D09195840400CAE567D141A068140DCC08EF11BEC7259B13518FF6786354D09859A04D117E94E76592918C21F78101035F3906232E164019DD1 3019AF8F355A2101F51299, 1DEDEB355DFB25C0781BF5B8D9DE88C9DAB56DB998BC5C6B061AAED98EE95132173E81FA1515AA8540150E1B6BB80BB696823810A0F8AD17AA41EF6FE3786C91063, 11575AC1A36A174FC9103F22D997C67C7687941093A22E83D04D889A0E4C4228FD13B01A38DAB15CCD7B49E219A6697339C856F72BC99870BBD5EC2DA02C5E50839 904D0EADA00E6305DF37CB, 16F5861E70F20A1F80908525058B17696A11185F6544C78D4F30258816B2B5DECC7E26B333D31E29DCB26E7B155D34656BAEF5C9D9C9ACB32C5AF0C0571BA8627F4, 1FE3AA95CAE6D2DE7A1CCCDF28F249FBAD507CC03533C992A291429AEE0CE1EB8396F4F960686CA6351C883E5A93628BC28DBDEDBC9CDB89D92ABB6F4DA6D736C45 1B0E72C08E02B29119DA761, 4E45FDE0FFE64B86818146F92783D1E967C8C4BDCDA44E8927D72F269AFF5F6DF8F4BAD6CE3B2A722E5A1DDD8AFC048C3D7CF02DA3B4C71556D6F2F82C207049A5, 125556AD32950BAAB4C37676815F498FB270A292EAA3C7669A0D13614772C8DBB052C6EA9E753E58E9C65F0D8C4B54A58CB1F25E0C4DC167B4AC0942BF1CC5F0C9A 512B5841AA0817B34D8F623, 1EF25525912F28BC6F2B321C13B7D27237ADE5851431A190C619015DC3571360B3E76452A8A904532512F1F210509FA8EAC2D8E9FD3B6B81050C2026E63CCBCBD78, 7AFB8D42BB5B56C73B38A43015354E85D9E654821E3756C2F57FE1B3206F8BDC693EE96C1166B237C90CE9E9B65A49F1D2CAE4BC4B9A10AC94EA0B505BB233CE4E F38208C4FE184719E8AE269, F33D784313B9EFFF097C88DFA87ED80B1BFF56340832B5BDAB35E0BEE1D73BAF183D455C977BA643E42B218400FC5B389B1CB9A55B9FAE1D2F66C261EE24B54567, FF1D6CEF8D0E6AAD96D5C9CA827054937CF40AD2F68FE277436E4966D04B64FA071A56B058CA38807C61C5533C9E6525C2FB02266BE222A5ACDFB059CCBED8E255 2DA861A4EFA48D54DBA0A73B, 1ED6C2C3B4546B41DEC00095940C7A8B629C5C0703F15831096240174D0A18A94376561537C57F8483317B215B00D422D04A7C479035093CD580F1DBFE81BBCAAFD, 1B4AD3B7CDCEB8C34FD7D35FD087D5737A846D7F82C9C3E81D42B35D089E00AAB6197F7956A475727F5FE2899EB19663609C9EBD835C4E066BDC4DE8830138437F0 88F924EECEEDA7FE92E1F5B1, 1F510CF12AE559559B6D56A7C4CD12B2D6F4E9B211AC80347BE28C544560394E0B77D18909751427F0D72757C95B2288AD53B04EB04C1DE823FFB6599CC12910647, 1C825308C453E4BE1BC25A470AAA262CF256BECF6539005B1835468541B9D137E5A20EFEE41B70BC6109E92C1ED2290DAFE20F523433150AC3A1D4B62A382DA6A4 19AEB6ECC6CC8F7FBB8A5E113, 1D96F773C1736D046ADBCE278A48CC600A496AC353FD3A0D85B7A39B4F127964577642183E76283976014BEE00E7F8CFAAFDFBF35FC6E79DD637B67FE8AFC22F018, 1B20DBA2B18E31F5620E2231BCA4B4499FBBA844E1D424D2C295F4114AEA4BBEA643C3171126BC9498400E689DA349F3434C692C5598D93689C9CCF7A0E26D197B8 4D0C24C65465AE7F329F1A339, B69E4A8BF1AA895C618A8DF89CF574C07B737074355578AEEF4534C8D218C975A01D89E699E2BC848643CD5D3D1BCA0468BB0D57AF11B8C90E8C90F415D7DBD14, 8CDEBB41AEF07326AFBBB4CF350B651BE771F46C262914353D64E753FF4616EC07F1421FC38999131449B99A42D460596E53ECAADF9520D8C62936C1945E695CEC E7246E52FD310B7D97DD4E9AB, 2F44DAC7B64226187E6D4A243122268209B26AF89C369614080A0102CACDDF9FF10A3AD4443AC0895D935E76EC7077FC22D6F8148E43B4EE1ABAFE72DFD4A5C45C, 16811C302BAE1D2139926DFB84E07747F2992E8668A438642E42E0371D0964F5B9E544E8DD50FD4DE7A4FC149FA7CE15705AEBAEBCE2430F98F761E41EDB0348ED 2B56D4AF8F7932278C797EBD01, 599F9A9B5DF7E42F73BFF94099111504BC3FE81340CB7B761A904D8F02E57B1130939C5926BA6D8E7A2F16B6EAD185A67E74BBF32D9C35369EAC094E8404DF08F, 151187A64F516FB7E574009A05FEED58FE9651908128303BECECFAC8833DDF5C33E19EFCF088C2DF944907ED1A7222C55844DD71FEDE063447C3D2B900E3B011932 82047E0EAE6B9676A56C7C3703, 1F0EE7B47DF0981FB658EAF622151FCD58856F9EF226296F9265FFB4D345D61EC0BE7950BA891C449B1414CA01E824C219E0F95860BBC4C6BD5D5A8082AE156A500, 136C0FDB133DED142D973CF3FFB7AE59F5E379E53ABA3D5B8A773524A947E694B45800AEC0B8E64B1D3BE54569B12B1E96D6F25B6126F03604EB5F205E0C0D2AFF8 1860D7A2C0B42C363F04574A509, 967C8D057C2C6C527FFEC4B65418CD070D20C917F7ECD53B980352C26E4E8CE1EEF1BD8C18BEC61A3259169AA9573E89BD4A43365AA35238FF792F8831C94F5778, 76A652C96706E490E0642B1B897C1E835FFFF5A0B6B70C7299C0FD1CD7FC902FB5078D58DA583DDC9FAFF4A1E5951C421119DE818EBD78D4B9C645A839DD8FD05E 492286E8421C84A2BD0D05DEF1B, D481529C0B8908B0D26BA5280C36C090539B2C8777DA422782DAC32B8D938CD9FBE48B0F089CCC19E927478344DF6538A12E4C70FB83BB0167BC5F67DEBA96EAC9, 10BCA3006DD8A63F380393337ADA78EA09DBEF67B7341005E5426FEBE6CF6B1D3CE6164C3DA46BB7C583C7EDEE6B3B2CF61DD7170668ECB5780BFBA9363B51D8D7D DB6794B8C6558DE83727119CD51, 17C0CE40712F4B52705DDEB104DABD27FE0DC8252D732ED96B1EB6D0D2ABC4659B11A7ECF21FE1AD66EFDD6436D4983D1D919334863AF043783A0ED16C91B14FEBC, 680A8191E60E5CD6E64C511B271B665A4A7A3325113C96829FC28FB75305D207BE337A77832A461611F76F63637DC8E2B28383025869AFE5B637E0D6AD57FD5673 29236BE2A5300A9B8A57534D67F3, 2FAE54CE1D4AE5B9E83ACDDE92C47749C206F41B72A5CD5BAAD031F0AAC34CA679D5F84B81AE4291C7A98BB2C396C22CDE0D896BE34FE237390D27BE54A7533ADD, 173ED43CCD7FCE3B515C941BC744FC62E2B4193E1D95DF624661F795ABB261B5DA5CBFAAA02CF9988B5EF05E095A2C7CB0ACE356D76D919852A1D672E37FB3CB3C6 7B6A43A7EF901FD29F05F9E837D9, CF6727DD89F1CFC1997BA16862CF19E9217A82FF270B247AED2AA0C992A4526E58B86E23F375BF50B5629312370FAD1E3FA1DA5E3B2E6DDEF7D1F48EB245270489, AB35A48111037289A4C8E360B1AE3000ADDE3FA27917BADEF8245386F1DCC6274522A3D38C74975BFA5264BF1BBCF39E37C7E6EDA0A6D03B896140771991D28890 1723ECAF7CEB05F77DD11EDB8A78B, 15ED4363F07A28A30112EFA8CA8AA56350AF5752D65AF4EB57007025116EA9F04ECE481F90EB53495798F89D4A54040E5FD4C16D368921865BE454EFCF60AD5FCA5, 68039E8220C159DC30F35F437D9D174574C2AC67D388C966C489462217C2189B2AEDEE9602880578ECDB49034C0B1065C659DD043EDE93ACB1B18EA874CADBA064 456BC60E76C111E679735C929F6A1, 958CDFC357EC3618C7762B10E3D45E76EADF9157CEB5236A564898DFC4AFAAAE26A07BE8C653A8E16A36DD0F4E448A1E7CC88D6B7542A8E499EB678F78E4B6B2CC, 19723F0CDF33BD23A14BA13A98043FB63B746B0EDB2852963E491E21AD37B959F512DE84F9958BCDF77D22123F887A659ADB27DB668DEED9C90D7D283368651C7D8 D043522B644335B36C5A15B7DE3E3, 1D6FF827024331C45120C4C71DF35D6888B12C5AF4FB70B5724957FDFE8824A0E713106E888B77D031B740CB73D4D6BD495D80494AD621F0AF8727A6758A455C68C, 19E2DDC3260794B45204C946A2437D266F9F799D6F8AE9886D94ABD5019E7AA7957D5804426AA6195EABA99FD5E2EB8E09363F46FAAFFC262DFBEAA241C79A2E7A1 270C9F6822CC9A11A450E41279ABA9, 8F963C0D060D273C74B097FF5762CF227BD859561D2FE6195C1EF495DE1B79C97562C7866A34DE56D61B3A8EB42EE87C3E437157EEC3064CA0C7BE6B38F7B259E, BFC2A9BD95034A3B05F63CF91402403BC9987B22290288832D84F33B0F6738C7D010033EA032F3321B6D87720E5F6F564B1BF31BD9A3802FBF2E108126591E707A 7525DE386865CE34ECF2AC376D02FB, 7B9F3B77DAB322FBB3DA19EF73F6F829D881619451B0C5DCDACE17EAF0830AF0204D4D0C51B82ACD94341870BA4C4EEF1A177DA2AAE93092D04B4809DEE94A2047, 44BD3C36192CB52431584F01FD2117C61A0D98B9CEF1AF9D430510B9B9629558DE745AA3CEF2B211BE4EDCB9BFD853DAD9F4B0C2F6DA8954AC0CE29565F5EC1F58 15F719AA939316A9EC6D804A64708F1, 1F2C1685E8DFBA68D3759869081288CC99224189EACA61392C72BD4C4964C67E3895CE7B5B414F4C0AF73B77691CCB26B592639E3008DD72BD38EB90238150EEFDD, 1141FB62A9474E430A714A2B04743FDFFC938BFF16DF9D4AA8EACD70CF1F05D88A7B9C5B8FF05362083EA0912D36549DC3AE8C1FDA2E7B3DC17295AE0F027C16A45 41E54CFFBAB943FDC54880DF2D51AD3, 1EA7AFFDECC9D2D173E0B2B2DC0BB570DDD10D7814067F030620B8FD9D8E1BC8B552506418F51396174F99150852490D0F6ADAB392B7C743CF53728ADF7412B3F0A, 10BDE149B34A218B62D35AA3DF252FEF49473C2F730F4868E46FEDB512AC8F176BE2A0C2C339CBCA3A70F9133CE0FEE52DEBB53BE9028901C6CA0B25F7C7F842F2E C5AFE6FF302BCBF94FD9829D87F5079, FB865DF26CB3AC31F6DFE99E723F631A89D632B63715606D8EFD1ACF7D492A9E974B200B1908E0DD532D564D567E37017777A6BCE040A5EE643950EBB838B601C0, 1CAB509D1E0E6A1B59C2A5D3487D7852CB3DA13533EB1C2FA50A256B805B5B0AF35D95384846CAE1C28EC5329F804F6381BB78ACCF3F737373A2A67FE832D71B6A7 2510FB4FD908363EBEF8C87D897DF16B, C9F00AA0A548FFACC5478CFA43A2F9F23FD32392FACA4F68AB3FBE66383B2B6E37BA355326F42B58C3A7F6E93E51908D4ED0185D05E5A7844929AE208C3B51B46B, 5B75696DFC684DC9A8432317EFD07C0B2691A237AC0E7498B96730FF547AA7CD9B51B847BBCF2DED8CB93BB0482B67E135F874F5F4C42A8BBE1B70C58600E98F85 6F32F1EF8B18A2BC3CEA59789C79D441, 1F866ED983E6EF590371618A0BD8FA42B0DD46AAC941F877EC14B24C2B828CEED391ACFECEFC04E35A0DD1FE856426D83AA3FFE1F5556919FD697066BBED3339335, 199585DD07BAFBA24F2DFAE36A30E040AC29EBC63ABDFCFBEA0957702262334EB1A7FA179C3BBFBE928AFBB4D0532A8F0EF113CDB8982134A9D326148CFED21F762 14D98D5CEA149E834B6BF0C69D56D7CC3, 10CD4E393DF012064B73934CFF7EFBDFC72F3D58CCD733D885EEBAD4B91B64A5E504FDE8F2299F704472772D53CE6D81BB39632B81AB25FFFA7C774E901E1A222F0, 29178F12625748895118D70305535EF88A93113FEE977DE33E330633D40181E9F45DAF7030545F55EE8A612C608B7F41F2812B79D9C26CEE3734DE551026E58CAC 3E8CA816BE3DDB89E243D253D80487649, 171E578DFCDA69BD9D2DA57DBE8A515D48D4C4BA222627FBB8B068ABA56059569031113F60CFE8027D77F3FB990C73F70F1A2E4BF31DE19DD0202334CD1157FF5D3, F1101674FF1C2831E2C145BD2ECCABA19ACC2B87B68A4F5BF5CBD68520C679861800C8366D545A7FCD9124349737AFF5478EC4DAE5F1AE2EECF5F9FB8ADDE9A292 BBA5F8443AB9929DA6CB76FB880D962DB, 542880C040CC682EFE7BA92DBDE3DBFFC5780584AE3D1F7C2941368F0B44F59C98F27014644580BBFFA2C62C4A81DFA087ACBA7F0A24E7DD877FC26AD10D074040, 18687D13361B2E4DC66E8136E50BBEF079B5D6AF64B839265EC3871B2A9D034FA97A94DCEB81D154C020638D38B4BAE16C6DB8657585EB4F60B71BA08C9EF05CA2F 232F1E8CCB02CB7D8F46264F29828C2891, 1CB8816EC66D80ED05C3172AA33B4F8C8F023816708F2BCE3B41C42AAFD41C6853796F7D014125124230EC2648BDB7088A1AF454B01B4EA6F77E39361AC698138EF, 16503C993B51F6FC4C3EB4A8D408E7370E6EFAE214DF09850DFE12B1C2E7E9B90831B1F495CA81BEB9A96C662E0B223CF4C957E2B3A362AB603B0DD26770C6321FA 698D5BA661086278ADD272ED7C87A479B3, 3B2C55D7171BADAA27F36255458B30A71749AD17F111408543DBC83DDED63CFCA7A232A9A3FFB18073CF39803E8F6F0C1AFB5E745CFC8F923C410B7AE751BE80EA, 8F56701849C8FAF70AFCB92AAE2B0E48C1E85114B78D545635AACE43FB0B51EA53B3CC6D54F13345BF354924FFA4E26C710173F289E49B9A1E10041C2078C1AA64 13CA812F32319276A097758C87596ED6D19, 1FE012AEF9537E574FE550E8E145F2026F96D3EE1D2301B3D6969D977C4C314E9078F0C5ED85C16C44CBFCE04CB44EC2A7072C5D936495A68A601BE32EDEC595B4D, 1742AC39661002F4DE12307D367F017BB4685AB03035D6B90CFB4389E139DCDFD1B432FE7DA51D87519E46CE9C6E6496A13F59299830B326AA54979477523D547CC 3B5F838D9694B763E1C660A5960C4C8474B, D2B008C3D599CB7CC6C4CCF5F06421B49FA454D80B0503D66E859D02EF0F6A1507FE3B42B5E3BDEC83288AF0C2E79DC348FFC3509A389F223104CFBAC4337B20F0, 158571D28D8179FD934EC4146F45C844BFD806DA4D218567FC4CFB08A1F01B5EC213C8168477816F230DA0FBFB665278E79EE36501C673292F3DE8087B1BD7E16D0 B21E8AA8C3BE262BA55321F0C224E58D5E1, 4C23E297383022249FAEEC517AFBFC0EBE45AE15602AAF45023BE25A933D3A9A85FAF3B72A2E278528B9A753D3005E299764BEF3A475BFE7DD68EA3C72E7BABF6F, 36D4680C53A60472483B7B8F1845D56BF19FEAF97146E16C66D78A4C5B2EE27088AF0DC602652282269A68ED1CBDEF9FBC6388B28BE732A9BF4DD38C599E3143F8 2165B9FFA4B3A7282EFF965D2466EB0A81A3, 2F7F9D1A89B72384CF5B5B604246FF8AB4BF00A68EA1DFA7B1DDF8345D2016F570276A2ACBF321772DEC7524128724938E74D5E369F6EF5F919ADF2E8F0B8F87CB, ADABA23841365A83D287BB51C50E3CD0149C369080CDF2C1082A7E359A16506AAA3F0B6DB5F55B3CE9977772D434D7AA0CF8EED7B322BFC16790E2A257AA00B144 64312DFEEE1AF5788CFEC3176D34C11F84E9, 1EF2DDB94CB948844F7C000FBE090D7878F02C3AE37F722220D92255F5244889AEE0B5D0CA9CC1DFF8EBCF35C4C14D7E33C052C47BC870F5C2F648F3AA9F156E372, 17F3D6D89125ABD457EE45B912AFBE4E9B2008C7A95562303CF7A0F2BE09B69D905E5494E0EB3FAE1C47A48924CAB4C56FA49E970E57599C852E93208AC0B7747D6 12C9389FCCA50E069A6FC4946479E435E8EBB, 11A0907D5B4E6BAAB05F813A307D7DF94FE31024D96233DD9F52966A94EE19BECAF0D93F6ECCA6217FD70954B37929BFE22ED5B529A1FADE6896ED358668E746F27, FA46B3B6C5694F1B4AC9763E9877623BE6DCB01D6A101088DEDDA69FED18D42B0ED1246C4DDC739D03A411EAB3E6316AFDE71E8CC0E2AA04FC8E5F137B84CB8E30 385BA9DF65EF2A13CF4F4DBD2D6DACA1BAC31, 1ED6569F5F669F3E6A55A52546060D59D5A1561B0E8DF439602195CC8BA01C90C3F80D7FED2631BB8153EFA46FD56B8CB0DEDE95F9FFD0B0546D23ABEF7996226C2, F4E4A923720917242A16BB7CC62A07C4D017DE653D76AC912783BDEA237F6731AC2C802C7ED70639B1B00026534A9DEC23D7130BF3117475F9F1A0702CDC6D6D59 A912FD9E31CD7E3B6DEDE937884905E530493, 1EF01E309E9B1FB687AECE947806C35B944D9E5EE06E61DB9390FDE011309E0A91EB0F4FA4A5E62E6D5999E46A4C2D48EA853DCD9313F4BFAF853C4ADD1CF47BD72, 195159841C9D16C350B52E181F559EB969BB113BD08B5159B05A1980F53C799EC1CDB1AA4C8A040B9D9D67B2F794CCA95EE767BB18AF9FD36C45318294BA1668C80 1FB38F8DA95687AB249C9BBA698DB11AF90DB9, BD9334DD3485BEA7DA10E2ECDC8F5433A34C9BFE42391068BB8C061C129F700FFFF83B6FF9D31B0E1D3E2BF65ACDFEA9BD244D055D50CEE355412A4EF9E8D49356, 1B87707BD5D317EB668D0176B786C728DCFFDB8141EE945BD989B27AB1F31320E5A370C582E6F65D91CA166FF8D99DDAACE7AEFBE1576A86135171ADAC1B3FC412E 5F1AAEA8FC0397016DD5D32F3CA91350EB292B, 142991D8B21AB53FBB5380B3DACAA3E41FC1EE1ECE7641DC7158621418523DBCEC0ABC7CA28DBD6BCCB6C3097C67F5B60B203F0636F9479EB1B7CFBB7557C14D5A2, 1434E44D52CDED2ED19B5A3B68A0C618EB37B217F52BE2E56CCA41B32FB1E04424FCD9E07BABDD36958108C77027311DE4935A203DCB32FAF18345EDF762B4FCE76 11D500BFAF40AC5044981798DB5FB39F2C17B81, 74FB515E4078D2CA6B1B17E3297A70726EB56C124EA964EC24FEB6139A5DA47D3F196109AFA5D1115B0C64464D8AB116708DA0B760B9903680AF97F30AB5552E18, 13D19498C65A6D9BD7208ABFBD74BE1B67B113B378B58035C2FA0D0691D72EC683BFB7001080C90635E837B87621E618690179E19F580E5DB4F6B3B28E61E6FEA05 357F023F0DC204F0CDC846CA921F1ADD8447283, 40581EB0C5F1784C5A3173C273ADAB26E7D72EF757D175989BF73BD364812F7391381DC96735990F8F1F0E36E1EACE55F713EE4FFAA31B516838A3C5F878BD963C, 173B41D46C73443E7EED3F153A1744D7047E8ACC8A949AD240F8D315FD681F4FD44855D23C5FA4BAAF050CD21C10F13BB1A041C170295AE19BA25A1DE1C4208E4BC A07D06BD29460ED26958D45FB65D50988CD5789, 1564AA18C5C10364E75E1211E1D5957C673B0640720CC5003A31BD1367E2647937C29C56B6916F44F73F60B1EAF592FD808D4C4DE874BDDA27E5D88C14A71D75EEA, C53D8A2301F213A680F58774FB4CFF9DD3B6E8E53B94B94FA131BED87DC53CFC4C6BE4C084FF9B94F35590B74551C0350E718D994B10B1C9E44373152E76FEC25C 1E17714377BD22C773C0A7D1F2317F1C9A68069B, D1E6F2EF12C66869F67933B64C2F4E16E93476720B87383E61FC410EF3D0F9684C1A21C5B9315C29BD4D631EDA4DCD1078978E678046660A8FE982DA818C32598F, 185D08D93D463230366480261B90AA10CFBCE2DFA484A5F5BE5627354EC75340611E7EBD3B10B03165040C0E5C50345C298FA9FDF937C5B76384E72AA2A01E3359 5A4653CA673768565B41F775D6947D55CF3813D1, 9F9A8B3F2C05FC80D9C0897A82B47D657A0A9172DB16C5EF6BF7B7CCFA589BEA69CC9318A9B7DEF5A4E1D69065B5364CED0F097C073562CFDB61A9D9F3829B2FEB, ABF0E1608D995600118FB59CDCAC5D6337E04A79BECED24697291F011F185AEBABF8A4CE35EF5AC09BD274D21A393FF6A25952D959429E6E00A487941A531A9DBF 10ED2FB5F35A6390311C5E66183BD78016DA83B73, 11717702EAEEB89C79271FD5B6E7E04DEE3550E8F4AB75C89ECBD33B636E3698D5EF69DF324BB8B3EC6B87744718501A2C7CC9A9D15B3A75C015DC310A210F09A40, 1BF3ACE0D121D1653E89459C50FAED6562BA69D2A0CBC65EA92DFC5034C2021E29B16C6B43B436BE76FA7D31CA1AFC06C803D43060459DF22BA75312F158A0E32D 32C78F21DA0F2AB093551B3248B38680448F8B259, A3D261D481EBB0969C4A6767013AFC759D91F214A5EC4F85C7E504955FF6BBBA4F7A9F4883D15C4BA8F4A0AA86E5F70E7ACF8447E44126DF957EE85C4BBB37C501, 62472A2C7D924E1AB0C95C9C5A2A205EA31DDBF4D819A0DA4B9F76AEA610BB2FA8AF486C18FA0DC5F33B4BB2309B5162AECA6E7A76C1D783CA9DB7B0405F6E4B2E 9856AD658E2D8011B9FF5196DA1A9380CDAEA170B, 72A122AC271DBAC95F310F20E8D8A0BE4192A7E701C93B600AD4AECE62ED31D56C4B1F5CB180526FE2B898FEE0CA1392368A11284DA1F0D0CAD7F429B5FD2B7DCD, D09B0D1D5B5CF5F9C068B758E333A1017659ADFC6CFC7D251E67778D8D0EEFF6F1A03AFE47ADEACE046B0B6890CF29746EC4D774BAF26D6E2F7A7FFE1ED0991F64 1C9040830AA8880352DFDF4C48E4FBA82690BE4521, 4C1A20EC2425F70CDCE5358CC7CD25D0DEFB0ACFF160BC4AA218AD3EB91304D17B4A134EA4172933E39EB25D0DEE0B1A0775CE2580B7CFDBB449E2A39B9C596FC3, 1E7B8A2A66FC73F114C81AD17D7FC08DBE776804FD3B83F6D2781B8E87E67C1667461BA0EE0B2BB16A3481E10CD940E8A5815A83785F0A95768358C6D6D43CE2A56 55B0C1891FF99809F89F9DE4DAAEF2F873B23ACF63, BE5C3F42502CA61D1E5E677D4221FC08CA8F1A4ED3820EF4426EAC78043187379E5261254745F2FC875C90446B4A1E6CBD532F276133AB456BDBEB0E25A0D53D41, 174A4B5868018B84BD3897D160E791211889C3CC956E4D985FB6FFDCAE7D2836B3CC542F037971D2EB442D965C373AB5CD51087090CCE1EFA725AE1EA5DA932F70E 10112449B5FECC81DE9DED9AE900CD8E95B16B06E29, 14868EC0DF006ECFC9D030DB5D1EE2009127F2E91CCF2174B3A4611BC5FCA6A36143D312A1A540D4871C123F6CE5517BC6490A874B09CBEDD30B2761F7ECC64F9CD, 1DB894269EF8C3F60BC6998F0EB3D41A2E2ED7484D1CA927F80F3FF0B5EFCB6797857A114F9E38061EDE7D53B9FDC977F7CD6A53E4ADEF5194AC5A6A1238DFD927E 30336CDD21FC65859BD9C8D0BB0268ABC1144114A7B, 169D74D0DF6E55C842F42DAF2A7576785AA500100528F7859AC23B2279F4F9B48AECED1237856844D87DCCE57D75A38AAEC5FC54468A507FD5630DDECED73C6E781, 4C758619304B7209D2EE9F95698FB440F498369BCCAB059A61E8BDC4BE5636119C03B6D2B7524087CF5CF414A2DCA1801BBD04CF066870B83864731422D3619D48 909A469765F53090D38D5A7231073A03433CC33DF71, 1CF38F976E1BCA7C2167355075FB849AF27AEE67B5662CE2A0A1431D4E4A93E1EC871FDD78092A42E13D87E16DFFDAF1139A4C097EC77EA6812A6BF24D0EAD26821, 1DA4F590E499D7787F79162DC89C294C8C5D8051FDDF922231EE338FB111E21BCBCA3A6ECEF2FE6E4F894AA507DCCC5C4191A28D848B8C5E80186FA8514B0DAAC47 1B1CED3C631DF91B27AA80F569315AE09C9B649B9E53, F111900E115DE9D3765613A20DEA4D5E298BED03A193EDF851E0D73BA054F720821B14560BEB25929EA6DC3424E7C7F2D986455A4CA92F96B74B556D6536180B30, 1FA14F416C63E6A126894B3C30B3433A5179A347B0BB479F6F961EE6E3331A0CB4CBA92B0E83976071B67218F8948BBC5F00EADCA8FA26BED3E5BFCF494D8EE358D 5156C7B52959EB5176FF82E03B9410A1D5D22DD2DAF9, 111E666ADECCD8BD3BFE3783FD87F097483AA335F2D8206ED1D37B81F508D19DD61BAF93FCD96AEF68AB142407E61FC8C1FDAA4458D6BB6A0044E6F018AB8686F7D, 131FFCD5B2D80063ED2815BEA13A5A5D1E110458CFCB6F36CCA1BFA55343F8823E68D0AF8043551002A08DBA039245117DD070B88FF61A9A15CFF145AAE0E0F6CA9 F404571F7C0DC1F464FE88A0B2BC31E58176897890EB, F2D496483584F01E1380FF91B4740B51859EC60ABDED4AE8ACE803C66B822B5FF693892A496649415FDCA986541E35863C3018FE33638CE4D2411F65BAE0D714EA, 8C4CF8529470E0D6EC329ABF9FBAFF170D67885F1EE19FFBE6ACF844FBF233CBD595C6534AF1E27C2F63E85D9EC2F9D6952F4622C0667AF9F85A0EF9F96EDDD2CD 2DC0D055E742945DD2EFB99E2183495B084639C69B2C1, 1B4F041AFC25FF407E0038A9DCF5AA42B7B99542F5AC80FACA31458F36B6F466B6F0660A23264F28CD0EB31144D83A001002058DBA811E1AA6265E34F50654F318B, 7E4D4E645B80E8F070DDE8A3A5FEB2F578FCAB84085112D6E9483775159938B53C8EF5DED2CEC556D200F20DDFE651892E009C8D5BF8CCC95F1A0A5F17E877890D 89427101B5C7BD1978CF2CDA6489DC1118D2AD53D1843, 1526597072116E68F74763B7DB91938AB319D8FAEEDCA942A5BA6482356DEC3DF9E8895C88A7D9DE6590AC9CD327E66D9E75613DCE5A8953032DDE0BEB4B85D8B7F, 961CD4191924722C5EACB285AF255E56A2DD4BAE958CA5952C4538FE5E7AFF79D2AB3515A4B031A11B95F2AC76DC763B40257CFD9D10DB6FB5A1C21DD6A53DA8C9 19BC753052157374C6A6D868F2D9D94334A7807FB748C9, 499FCBA3AB753869DF5D089B5508BC7A0AF8F5F6A545C7BAE4C57A3A69F8A09AA3B300389C3A04C70D59F5122828B0E9F6EE9385C512FD3348940605D8A57FDADF, 65AB9CC6B5FE8E00634578331B020C3EF09D51386E1904A1BE07AFE833D018FEAB033CB01E854D8CA3433B693C91676986AD310FBC26BB5A1728EAFE3E4B43083 4D355F90F6405A5E53F4893AD88D8BC99DF6817F25DA5B, 11878C5B974923546375AF0313FB844924EEDE1F76C8035C8EC2A8152D79B03AEB96F71C7618F851B40B4AB5811C402F6B877F233C7F6F77A8CF025BE6819D901C1, 71ADB0A94401E1CD89A353D5089B58493AFA093DCB325D18C3A582AFE1B8B25055467B93C61B1F5C35E8645D90B7E9EB062F36A39D621029BDF6AA0639E25532C6 E7A01EB2E2C10F1AFBDD9BB089A8A35CD9E3847D718F11, 1EB6B4775061A40AB1C7D14DEA339FB0CEE8EF61EFE340F20EC76D52AD03BF60A1B6630187A1D0B41CB0F062C91FB97CA454E77936B14CCCBD6ECFD39207E98D0E1, 119309EBFBB787F62EC0786D5AD5ECF146D7F8D4758C896680180B5EBF119DABE039D55BD1C503252B25713B29EDB52DF67CCDB83F6859B8E66897E3BB3EC10D9D9 2B6E05C18A8432D50F398D3119CF9EA168DAA8D7854AD33, A0289125A717D790905F7B1171158B7644ACCCA44BC9DD67F2778C89DC7731B18908040BB3F891AFC5B2E5168E1BC29442B8BF5B5CBC0F3EB208D9980A5D1A73B7, 129540821B079BB7DB7BF9D9075CEA7833458FFF77950DDC90B7DA4D30EDEE52B4CDEE9519DAF6FF5898CA3365CF0107D07D9CA9DD0DA2BA47FDAF821823AAED34A 824A11449F8C987F2DACA7934D6EDBE43A8FFA868FE0799, 1A0D36A91082C697C7FAC4E50887B8A8AB6AF0C82E29B648A7144F60AF2C68A316A90DFEE21303FFEC7DF1F9B6506747943295529A6ABF42F2624B23A60328C3735, EF0B8E839A394FE4AC141BA2F2DDA0DCC357A5461EDD668BDE46239ABAA3A91BEABBA5290463DABC13A426C5F250F26D559CB9131D89D28A953DE7BFE8F2955A3D 186DE33CDDEA5C97D8905F6B9E84C93ACAFAFEF93AFA16CB, 1B099C1AD9DF6B5773444416A28A28BF25744C9E24F80ECD775417AED062C1874E84E3768FCBD1E2753C43EE7B92ABA6CDC2763296B0E3B88316356517292AE9040, 9FE463186297600D62182EFC6D5184758005A894C96DD177491333ECD2738BE64B5575FB0C453D49DC9348BFD9784B9271233E5C3992DAD8D3ABDF1D4567DCB16D 4949A9B699BF15C789B11E42DB8E5BB060F0FCEBB0EE4461, 103A1AE83D0C63E738F7EFB2A35C4688C93A74FE41D0AFCC3ABF8F5E1558F00A172506733113EF0AA7B41B1D8C3A5A6DCCBD252093EC9BD62794DB6FEE9E86D7EA6, 15E4053454D9FCC2D3CA84B7DBEC5C2450DDDA3035FDA7E6788FFA0F8D0F038753A2FBD4C103AFFBF9D7E36A2F8139FE3DCC137D41F061A5C1328A9901FC6B1585D DBDCFD23CD3D41569D135AC892AB131122D2F6C312CACD23, 662249AE4DD87AB5F98D8BE4E173D91681948232CBC5C3F879AB89654018AE70D797B806967745E9EBDA56102EBF6A72AC9BD5325D3F7551A37D4D123086308F90, 1478866BB350E2AA72AA154037D6D657DD1214072AE0E6BC2B871FE4B178E55F8168A147416D8A90478A4C559C4971CE67C0764D03754EF17100C4A838B82545A6B 29396F76B67B7C403D73A1059B80139336878E44938606769, A2B8066D700AD69186ED471A2015DFDA37D30C72016569F9C57170E78B3B3FD6085B6D2ED83B7FB0FD0135671FDA71375931F4BF21A40600B214F8856801F70BAF, F3C3A4D255BED81E9A43E4417C7F2EF1BB99013BCF9AE93E0AA273DA41B0441E5EEB722558A89A6A5CE50FAC5A513A1C8546845CE4070CBD5A0C520DEA724AA1CB 7BAC4E64237274C0B85AE310D2803AB9A396AACDBA921363B, 6B65E9AE0ADA398071A375F757BCDF809C0DE791D409D711F35278D94A1C56CAE3716EA377E91A5B2465111AA76FD98BDF4A654F975582B7E041E77BCF3B1D737D, D633E4CED977BE21D68CC999596F0ED8C4890B938AB85BC06C5A2EA52A439A8FF5C70C72884DEDB18D90AEC29CDF6B17086C94CE5162E6F84E4A8308C4DC02A95A 17304EB2C6A575E422910A9327780B02CEAC400692FB63A2B1, 17FAA1BFBDADD90A856D9B2FC478F5402B1D2918C87668F55BA10CE65F676F0748168CA0D02BEB2DFAB95ED49399D9C4495A93C6CE137CC3D0B45AE030DE85C41D7, 1163583065327C943A30C9BB603C480727DEADEA437D0D5873E99DF0BD3487DFF2686E8AC8ABF3DAB36D19DB2FA5966155D8AD2C337B65DB70A05D7FB3813B847DF 4590EC1853F061AC67B31FB9766821086C04C013B8F22AE813, 1283BE1296F2AE4C4997BBB632EE6D07944AACA7D641CC8B3DFB8A0905915B005844529B90CBB2EBB4CF6BADD117E2858DCD30DD6560F87CAB349F0501E925ABB82, 13ADC3807C80A9BC519F74419B432F120BFDC918992729A7ADB3AD95206BEB793035960DAA0E5D002EA8E6DFFF927472AC1DDE10AC7E196FE77AE23C5E1A647CCD D0B2C448FBD1250537195F2C63386319440E403B2AD680B839, A8C3ADC331BF40F457720076577CFA98F6B61201E700DB58FB4CA46C1AEAFBE8EE0BA52B1BA72645A3349B63B98DC252C108914024BF8CF706981993DDD6310D72, 18423EC6B5072CF004A624699C003F2D7FDCE5E243DCDAFDA117273D72746FF3A917EFAA523FC2226D9B39F52569DF509FF340B32E727A6A22F3A33C62F4F1C357A 272184CDAF3736F0FA54C1D8529A9294BCC2AC0B180838228AB, 1FCE7ABC8F809FDE63758D1E935AA2D81077300AEC2C16AACE21DD6EDD93FB9333E04B8B403902C9F1B71C2FDF8A3216C20598BB16DC90ECC6D066794EC63CB591C, 3C61DB1B9DEE067756E94A963A2C6E3F4BB681F28EFA3D2084BA6F8ABEF41419E4FA8947B8A02298542F4A3B1F4122745E1DE106C90A69869E0300C68B8CBA169D 75648E690DA5A4D2EEFE4588F7CFB7BE364804214818A867A01, E6BFBA40FF120E16AA00C0F66A80F7DCDBD7D6FBA8EEEDBBA02A98B760A000705E85DA0C7D50C48740047F0DD69BF9DF9C62A11F0F116ECA18E4EA546AFA1BFD8D, 149A3FC28C6383506634926425F33DD05C0CC9BD9480E0612F0A5D628B4BA963D6B297A44385F3D1895FC16137FD2A38C24A023053356A993BD4DEC457A46DC2282 1602DAB3B28F0EE78CCFAD09AE76F273AA2D80C63D849F936E03, 1D4CAF57B94C16D0AA062D2550C98F220D11A3225CA0C7D8E072BC3C241EBFE8D4FE18121599EFEC0BE7EA42C096010B3693CB88F236A53337296723A4D5534B667, 74A7A7D6F099C8B93EB56BB9BFF40AA69B864E8CDC6AF09C5DCCF7B6AB3EBF2FEF2707486074BA12BD1CEFC7D0E3A64D952E4079F7A28CE69FB1E550B66D905FE2 4208901B17AD2CB6A66F071D0B64D75AFE888252B88DDEBA4A09, FCAF330D53AE4078B34A33DCFA771E7DAD5DAD53FA88CD734FF7E32C4C14FC544E0D55DB2CC71F0C877D1C6C8692B582BA5B4C2BE33530E0038495673C8CEB50D0, 569CCC4D8CD0A3B06DFB4AECB1480D22CA7C9212EC22939834F51856FFFA9D4BCE26CBC1F5BB02A19976670AFE3CD0368AAEAF59D859C2C3087B79F9877D404412 C619B05147078623F34D1557222E8610FB9986F829A99C2EDE1B, 13858A26EC38DA9043362D4E5A46F65F9879B95C1F9D577360331017C3C78940FBE597F3CB320B9167C33AA1EC7014C3216A3C74C6E6FB713BEF1720BFAE6B85D0B, 127E2683B280F8214B351A92F95359ADF1E8EE20A57123460696269FAAEDCB05DA8EE020E114E476A07716DC8D2D290097AAF4D09C6E2EE25D6F5A811BEBC554BF7 2524D10F3D516926BD9E74005668B9232F2CC94E87CFCD48C9A51, BC920E011597A73E2EA7EE4340517EBDC3DC684021895227723C47989293D8892799C3910A22BAD473DB9B926D7994D89B9E6364C387ADDA4A7EC4F899EE46EAD5, 17C42CB788E5A4074F5AC52BA2C9DE4141C5A98A34C1BF61D6211EAAD6240CD678E800EDFE55F288332BE5CA9363CD4956AC634A5066EC952636E3862847B11AFDB 6F6E732DB7F43B7438DB5C01033A2B698D865BEB976F67DA5CEF3, 9759EC582DCD5670813AFC147091E485081FF3C3D562AD75F6F568F84F64F5146C47402FF67244B573AFD63955706DDBC77009DE6F74C4B9F9981B978CAF2C639D, 1E2933FBBFE103F66C86AC29389D9DAD27B8762225F73A0F3ECC418A02A63872C791F105C33123C562C0CAC2C6E87106DD93344A311F3AEA85AE4B67980B60C9234 14E4B598927DCB25CAA92140309AE823CA89313C2C64E378F16CD9, 1DBD594A0AF67FC7CC2C2FE844E483B3A597C84573F0FCCD844351D43F5D57ED973880B55C02D48DFC38AFF28405B3194B0A0C4D4675571F2AE5FFCE93F3E08466A, 80D427650E87FC3C73D52BA682597946D0865E3F9B1519B17E2D5FF1C60F2FCF7530EC55FE580F3857872E97749FF95B6D263BC697E29FDC85C51953D8A72096F2 3EAE20C9B77961715FFB63C091D0B86B5F9B93B4852EAA6AD4468B, 190DEFE7D1685379A0003C2A0D82EE746BDB82DABE09510ACF7204360D43C0A3314D4EE74633741A52771723FF1B6C6C8526A12A557BEC896878EF9D11E1B8F8F0F, 5BE592B217845D4CF9059046C53F85B8726FE113BDA0065FCC6E5ECC0A06F93BCBEE6A64061EB48C4929561B3DF8C86FB0BA979662DF1CF3776BC19D74E205A1B6 BC0A625D266C24541FF22B41B57229421ED2BB1D8F8BFF407CD3A1, 11B6D026D9F4851F01D34D7F5780701DACB7AB6DD7CDFEC470E25C3652C9C779A982E474CC1208F9EF2BF596D74E1FAAA49B43E973A243F8A5B60D3FB66030DE7E1, 64BF8C1BD5473B0D461B492183C225F0D0F3AA34DB8B7F4C7C3EE06072C87AD140930A462EFFDDB14FA9E1FE435E7180031B7F005D34A1D0CBE48858AA299BEF1B 2341F271773446CFC5FD681C520567BC65C783158AEA3FDC1767AE3, 164AB3523A729201BD1D19382F1DC55E670705610412A8DDC168FF814FEB847BD56849A951696ECF9E227DE82773B6818C92BB2628561BE0D5A1842794AB4CF1F8D, 22C694371AEEAF25C7BC9072A8840B28B59F672AE5D17261C003030E780FFCA5E9D01D97931D2187DCD0359A4FBBAFF5BE89917A0230A7346577B5D2C93B0D1BF4 69C5D754659CD46F51F83854F610373531568940A0BEBF9446370A9, 4BC724058FBA3F6B8DD55B549FAECDEFF30E9AEC3E1AB403510FABB0F868CF4B169972DE4A859A88C43BDC5203A926582A4826291162059A5F868E08D94FB6A665, F937E3699DC0F1E7516E0CB5ACFB648B32F44E1C2AFA68BB02C512F52723CBE81B887C41CBBA3D694A7C1EAE2395C687CB605F0019E150419D4F4CA4CC4EDFF17D 13D5185FD30D67D4DF5E8A8FEE230A59F94039BC1E23C3EBCD2A51FB, 1D892EDD5504144A3F3B9F007D54525CF4D84A64D2F673559FD7D456029B02C3D7FA010FDCE1CFD670E16376C2DFD746AC5CF39D2B05B6A4545013B78B315A4E55A, C17218A3397CB115A3595DE79809EF3C4BA2B15ADA5EB22CE4015ADE9E4023EA802B8A8DFF386603A670B4987A98421F86868278FE5AA043141596C72AD92A244 3B7F491F7928377E9E1B9FAFCA691F0DEBC0AD345A6B4BC3677EF5F1, 3C5B2B112CF11BB235AC1B800AF6E31E35471CBF50AED698BF79299C08A3738B41C61042D970202C3913F4D498B0B41B20A13BA313119CB532872B1C4C6232E07E, 1D5AA48D23764FC6359A13D989F58F22BFE9207B146993E1EDB3056170EC936540D0C9953252B7EEBF97E13CA04621AB62CBE5F1112A4A3C6E7C1CDE43755B73563 B27DDB5E6B78A67BDA52DF0F5F3B5D29C342079D0F41E34A367CE1D3, 10E8673C755C854DFDA62B87D3BD2D7E63AF695636574BBABF04CD343FA7492FECA79AB043031DD2BDB90CCADFE3F691A89E3A131565D66396CE69E22FD6083BB67, 74AEDED0D962A28B5E758F140239A21455273FA8E1913FD4A53357AD5B54668BAD4A2D8A2A1934D3B33EDADCAB0D727508FBD18E8AE38B5A0600D34ADF1276F27 21779921B4269F3738EF89D2E1DB2177D49C616D72DC5A9DEA376A579, D0729406F428C80837768678BB983027AE7505DE8FE2622C5CC714FBE823AF37E0734CCE94B3B8740489658705A891F8D880C2DBF11A51DFC26A2D2F182B6A68AB, 7CE9DAF11E14AA829DBF52642EDF9B492869835072FB9913CB795BE185C0C3D6AADF859B2AEC23CE27B64D74C2900A9F2EE47A43584EE9F03509C94C6B05A70BB2 6466CB651C73DDA5AACE9D78A59164677DD5244858950FD9BEA63F06B, 29F0A9A453EBCFD62C1FACADBE38D211E7313D6E2FD33D958E9F6C3C6A611D7DE6A3770D504CC09646C2C4D10977EFAB8471EE836A808455418F7BC9A453705D01, 11F9663DF4E4A066EAED2CDAF290FB828D6250EBFA971A845728D0521EFC09BC3A916FBCA667F548216E624BF530BF81128598D8A1061B040DDFC557CC88F9418D9 12D34622F555B98F1006BD869F0B42D36797F6CD909BF2F8D3BF2BD141, 11CE6BABCF9E8DDB31FE971D9E45D4A5C849F9D9595BBD6DFD8EE2238EA53AA41F1B5EBF7D0FEB3362A147A29FC186D8169608EBED6530BEFE559C735B59FEF367B, 3B7C2CA6780FB6E5B8A9C322208D68F5E750408A16D5B64EFA80401871D10EFC5FACC14A2B85A29BD03C1D283ECCB737DFC5083E9BEC57B66388AAC211780C4D79 3879D268E0012CAD30143893DD21C87A36C7E468B1D3D8EA7B3D8373C3, D4767066E75F170297AF0A2DFC8B992DAEB6C9659AE1853C864141DF8986CBA47DB37AFBBA09F3B5ADF21E872A9ACC6B6A55C657BA30A32A546504E05600264B1, 6AF30CAF30BDBEBAE9B7B9E56104D11E6D1A7727F95C0D6B1EA7B2F289D3C422056A752CE684A9A1EF307CC7A343EA4399B09E88AEA783367F3F33BAD7DAC2807B A96D773AA0038607903CA9BB9765596EA457AD3A157B8ABF71B88A5B49, 17B8CDA732A38BB4F2E5EED4598C0F559C09162C32A7B58DFB5313FD14993A33E3A0DD74F40731E39A57A02FA77C096DB8A80214245500580BE4C012FA5E0656448, 1B544800212017D3135D9414D74622C7EB388485F74CCAE80C7C25E19C313A39A048761521D73D6DB4AAA6A9312A6D72CD64E1DB67325E04C74233C6E6000D2AE59 1FC4865AFE00A9216B0B5FD32C6300C4BED0707AE4072A03E55299F11DB, ECDA2A3B7F5A1646BCC1D161E8E1166CC2FC436C2112BF60C0929DC435D1BB987CBDB27DB1CD4A6A4CF270D07C9F90243EBE432ABB6F595134F3675324FEAA24CE, 785B5E021B11C2CCE21EDCDCE3DC893638501F9E78642BC8DF1EAA3BF093441F18675F1B371DE21C912A46594F120299813ED460CE1195E475C6AE1A2A05039CBD 5F4D9310FA01FB6441221F798529024E3C715170AC157E0BAFF7CDD3591, 159F88FF1E2F2FFCCEFD23F8D1A38A4FA2C522F6B9B18147E03D72BB12C9C2956BC994634B0A74DEB22194A011C5B665FA0DB05370781A86D683C9E7564AC7DCA3D, 1E724FC8785486A0F677C45DBA1877FC91C6D7CAA4223B2F5916B86AA814A13337A66747AAC5CE9532C804C03410FB8559397059103147D9EA84BB756E0FD56EA18 11DE8B932EE05F22CC3665E6C8F7B06EAB553F45204407A230FE7697A0B3, 1610A5ECFE3DEF284957B60A5E93D8A1C7535E4B6ED12C761E3B0E471F791D8C18234675F21F30252E776BAC8CD146EDF36A4A8F8E4A53725DF306A0D3673A57E07, 29E8CF5534BF3DDDFE777C2D2990D3AAC191DE1F484A167A58DF107587AA566247DEE42557C156CF1FCBA36F8363CE7C3D84F36CCAFA3E583EAFAA8EF5B9CACFD7 359BA2B98CA11D6864A331B45AE7114C01FFBDCF60CC16E692FB63C6E219, DEA62C72D6C78050E75C00035E1AF8DF2989C894D670DB01F349FEEE0DE4E546925714AF015AB274EC618C4768BE274DA79CFA22E94527DFFCFE14F4354D16E2CA, 123797023635761679034FA1950AD28C33B0F8D96845EED5D88C02E7568B6CEC7480A8770191CB2FA14D2D6486F0E10E307AAA05C1056995BEAB328C9B7B6DA85E9 A0D2E82CA5E358392DE9951D10B533E405FF396E226444B3B8F22B54A64B, B87BBD1F611BF92D894169BFD4F23547E36D67DA0336C63B1533A9CE21CDC96A0C64C6FDD178D3F08F9B8FA67C55F28DC47A6FE8790F53517D01A961B276774EC9, 87F7EC1DB9880B43EF8834F32B5F032F7459A9B9ECB2A75EC011D81351E43A6D5B73541A1D9E5A9E518B9B53C4367330B9492A65DA429EA5C8CFC4DFE6D244B67A 1E278B885F1AA08AB89BCBF57321F9BAC11FDAC4A672CCE1B2AD681FDF2E1, 19A34D1B76A18D0E607EF77C8C814FF033602A21062A1E83A740B2862E66F2A1560D4751ACE19B94FA4CE11C865B64A52519C126A400FA1D4488FF945F4FB5DB60C, 90FB5CAF650751DCEFA16B6E8B0CD5730AB7795501630DA548141AD65516DC20A70FB250991D1791906AA8051C841FC95FFEC14B25E103E3A1471D4B33866039B4 5A76A2991D4FE1A029D363E05965ED30435F904DF35866A51808385F9D8A3, 1D0831B6FD3CABDA8B1D516667759EB49114FFA69F537F417A4BEC464121659E0A1144DE9F9436F071BAFA3D13AB7B4754110B230411F6C5D7B4E56E3B5BEF3D92B, 392535DF0A31A897E6694651A5093FA9A6AAA00EE4CC6BD57469369E023A76E1249117A3F6986AEAD1F62996397319732FFA864536C678167F7278991F7FF35687 10F63E7CB57EFA4E07D7A2BA10C31C790CA1EB0E9DA0933EF4818A91ED89E9, E0B3D3C63E8B33E1ED24CC6DA33B6D72742A545C2158D0451194B3E1090BF3BADDE24EB99F58FB01C62524164F6188B0884AF18AAA6A448DA00744E2D1C893C432, C63F7AA54C8955D3909A8E319C919DD682AEE6C9FB4A91D1E5F3F9CF2962012D54DD1D681DF2C18840FB220A64F1D7886CAFBE7A91AB1E96DBB0476DE75591BAF3 32E2BB76207CEEEA1786E82E3249556B25E5C12BD8E1B9BCDD849FB5C89DBB, 1B418A885DBE10F1DE1D4FAA6625E7C5B50E7F103CF198A5D037719732FB02A24742170611D9A17FF4457DD42F57F31D7A6B9297ACA94F588996845555E9127CC20, 13AB37AE7CC6CADCA4771D9C038E99E1D58874AB894F5B9BE8EC9F14F3A775D0CAC19F8B34A3751896D59D4F0592DEAC2D9C5049176E8A68F298432814ED9773A3B 98A832626176CCBE4694B88A96DC004171B143838AA52D36988DDF2159D931, 1A359A1F3D1667CDC519D36C1962CDCFBCEF7602E48910A5B33288A5EE547B6A3F94EFF8BEC2E547B5A9134A922AE48953B5369CF39839F9A69F11081D76A6BF3A5, 1615CCA77AEB96CE15EAB63C51EAA6EEF5261B162C74B3DC084C90B270DD50EF73FD0ECDFBF4B5BD230C1658BF972875D96165F7591EA4814FE4617F3AC7C283754 1C9F897272464663AD3BE299FC49400C45513CA8A9FEF87A3C9A99D640D8B93, 1E4FE297E703C93E2B75100F44B6A52BEE272AEDE7A21AE9659E4BA43428E4392C1C27E5A6C9B66A3F412F4BF3843ADE045A1C1DB162D1485755F258D365B48F13A, 3AF8C0549DD3F8B0CDAF9755A6492588FB9685D008ED243C25798DA3C09F15795F7F4E1C82BD554B6C08CB80B425F009652D7692F57AD0B312AC9B05C8DDAC1F3D 55DE9C5756D2D32B07B3A7CDF4DBC024CFF3B5F9FDFCE96EB5CFCD82C28A2B9, 20CA37292450109E49A2A9D0686D1B43B69634CDA8CCBF78C6ED7A29FC1815EF3CB53D5222496D5F0EBB9E835C90493B90363E6903A5EEE8B6DB978DE8A5FAD2A9, 730D3811A46FDF1808F58DB195DF5D2B3A4FBDE18C8AA7A4077A76A4EFCAA46CBA96FA112170F6F430373D2CA457B3D57094F486E9B61CF8EDC1552617BF66F1D3 1019BD50604787981171AF769DE93406E6FDB21EDF9F6BC4C216F6888479E82B, 18D651487BEF70163585C3C8372872EB86E6A990D4E719C978C91F3A746F74A21360A64BBB66865C3EDE964DFAA2743DB4E4BD62221AA9AA11BFA9F5395E7131FD4, 13085D837CC678A887A51F8D71EA4C19D1D0EA6045FEFF3880B267ED7162D2772FB1B71FED0BAC58BB82414F56B0853864D32E03EE2069EA5C2CC977C8DAED23824 304D37F120D696C834550E63D9BB9C14B4F9165C9EDE434E4644E3998D6DB881, 180F36A0129B527AA2406918B35317A7B46AA598F972066A1A507358AB092859299D3CC5903E4AC88B338D0ACECFD0EB204A3453E01CE0049C01766EF82C5A34928, 6AD97A0F30FCCECEF1FEE695711E3A496E46DC284ADC1CE2026E14B569F7EE27729D55C1F7C0E4511B3719492A6D3DCA83CF1E28DF77201944FC41BBF73A2CBB6A 90E7A7D36283C4589CFF2B2B8D32D43E1EEB4315DC9AC9EAD2CEAACCA8492983, 1A5B4157F0C5FCB90A58A5DC1D14975B15962F49DBBC2EBA31A65B701C238B0AD022E24E47E587ED570595C9162F3E421B7F7804B6154B8D606641A82A7B5BE5CB3, 12F37607BE36AC4DD47DCBE8015B69BB588E6FA0BC01392B2B36C6E290F5E969BF83A2D1B8CA4EFD79AC7E5B224134650C2C39EF047AF43791A410AB4E68852F186 1B2B6F77A278B4D09D6FD8182A7987CBA5CC1C94195D05DC0786C0065F8DB7C89, E63A4F551D90B514F4832649A06CAD4523914E6BFBC391A726E506ECE986510A5ED3C551794062755E5A228F3E9957B58DEC10D80FF5A0E479809F375F32274A13, 1EAE6C44B101FD4805CAC7FC3BF97BB1A68149BB17C233E85ECF4A8836C5861AC92AA606ED12209EFE1B1E3022CC3870A1D53C9BA1A4348FAA5FB01BD724BCAA3F8 51824E66E76A1E71D84F88487F6C9762F16455BC4C171194169440131EA92759B, 1F02E70FE3DCAC36151EDAE25C6D72813CA6DFE36476FD4682E562E82DEEA12CDD3E0B37B60AA10F7195BBF9B0FF61927F444A80AC0B4ED1DB14074F4D5A5E4427, B128F9D80F6E58DAE2EFAFD9B2C284E9FDF43681AFCEB6692E2EC590C3F52B527FE574B816FE8542C5253D7FBCAFE011BCED52CEE20F51CD612F57045CF0EFEE1F F486EB34B63E5B5588EE98D97E45C628D42D0134E44534BC43BCC0395BFB760D1, 9C0007EA99435B2533454E908173396852D76E54753F270D28E8F0B2E17AC7EB3394A052F105538ACEDDE58FA2B7274911F952015058333A123D5262B241933818, 10C2C8283D9D3709E8297555534587F920ACF83CAA8D6B90EA66486F82B02AD9C0C85AAA0C13E1504B70D7C630F71971ADF6E2DE4D672E1AAC0DB2B8DB0C726A680 2DD94C19E22BB12009ACBCA8C7AD1527A7C87039EACCF9E34CB3640AC13F262273, 10C1903FB8A32CF20C7A12DAD680CEBB307607879242D08DBDC8C903C11BFE85208701BDACFE16108C22B0BD33D030AA9700E9FDEF79C74E86600134A8222D9A502, 13A88FD6D22788E955666D60008D59354B6334AE2516231C5C03C3BEF456BAEA119172DD74301F53E80344D4A7AE740C1F357F71D645E17338587F036D38B383B3B 898BE44DA68313601D0635FA57073F76F75950ADC066EDA9E61A2C2043BD726759, 1A1CD70F1E683ECF127EC2772C379522976477E1D0678A50CDFC7968FDA4927C4DED88D520474D314F322DBD76571A269931ECD5435281D92D7D57E72E7E659F5D4, 1B627A3A526D1D7BC41D5843B213BAFDDA248662BB6E193CBCB2B6DD286960B95DCDCE96403CED7408EE362D21C041BC0F3EFE412D6051D1E59464D472118B87528 19CA3ACE8F3893A205712A1EF0515BE64E60BF2094134C8FDB24E8460CB3857360B, 5A543EBBB1F837274873B93FD59123E0C45FECCC0F0F52A037F10332960AAF0193402A86485C3FD904C349EA2EE2A9AB3EDD1C3707D2BB7EB00727E33B782FFA0D, F22375846AFCBA67544E2716B6A90EB56AFAF8C5B82E8B3C8B8AFC0FD624D079028EF685471D7EEFBA4F27CFDD34FF45E966698BBB058AB20B0C256AAD7DEC026B 4D5EB06BADA9BAE610537E5CD0F413B2EB223D61BC39E5AF916EB8D2261A905A221, 1F3F9B2CC9C1E07880A96698C753CF5697A3BB8F2043E26A211026C0AA9D3CEF50B0F8A12B7D99E8FDECCA3BF921D143739AE0D9EA28A2E3DB4BC49590FE16BB4AE, DFEFF48E42A737A51014392E0AEBBAC0282FF7B3E566D53EAC71DF1ED5251A8EE6FD08E49077B755498FD5E5A6C9E15697B7EEA93AC94B5AEC19EB0EE7ACB99C E81C114308FD30B230FA7B1672DC3B18C166B82534ADB10EB44C2A76724FB10E663, FFC1CBB203F198EF41B40F208C5391AC63C9CB2869E21F21BE8CFB881F832430FB6BAB63B6A3895A29EB3BD5701B1F50ABA29B1EED4B8C3AEDC012F1F08B6C12D0, 1DCC33294F3CB76499A8A19D7F89D88181C0CA4912987F9120C909170CA20D2E6B669E42D46D2EB14CC0552833C71872419E098299EE54D96F9BCAEEA80EBDC5FCA 2B85433C91AF7921692EF71435894B14A4434286F9E09132C1CE47F6356EF132B329, 1D6A85F8B70108861307710CB8D7BB3D1B591CAA4610DE8C7F4DF1EAE6DE9B51320F1E21FC6515B1AE7F2CD3C00EE1C9264BD9696D56A7EC83ACBAB9203EF957BCF, 1006A5B1FA539993E8C089225C958EEE173E63065CA68CDADD692E0BF1CB9B34E2100F62B2AF92AB803C6E8A00B2098EB8402596F1472829B756CA66BA3759BC0D7 828FC9B5B50E6B643B8CE53CA09BE13DECC9C794EDA1B398456AD7E2A04CD398197B, 1E7F332DFF1E2D2459A67A0FF1B84BCA3D46D093F583C29D76E1452BB750A9BB4187B1DFCA2F8B56FF032BD43F0FBB29D6D24933E1197DEFEA1AE89944F94179747, 12CFC33FB4BFEE0FC122E3DE5EDC67ED76B61A13F27CFEA2137B6CAF42C002E8A5F5E61449054FCAA1C5E740E1B2DBF21DE5A816DF2D892C2C20C949C46CE5F860D 187AF5D211F2B422CB2A6AFB5E1D3A3B9C65D56BEC8E51AC8D04087A7E0E67AC84C71, E953F7910E7A89904FB2E7DB9B4F9AC1D62DC5B40173273307270C677B51B36A8DC2FA7953AE188D8519F9FACDE50100063AB4653C0AB071E0596EE90BF675E9C6, 455ACDA2038D64CB38D887D510216B1A1946E148D7955808194CB0680FEA8E43CF69B76C36B79BA7CAB44BE515ECB27D25D96CEBCB4A19AD4927B18CDC7ECDBF71 4970E17635D81C68617F40F21A57AEB2D5318043C5AAF505A70C196F7A2B37058E553, 5383BDA32EDE6A7575F29F48F9D84289D00645674D61DAA74A1ED23CF20DCBCEBA7C074AFEAC4A472431D3E9AB481D6350AC567F818EE71646C579D45763A0B669, 1CADEAC716DA20F02E7B10F8A7334A7692B5BCF85AD19B8F3AE1A4D7BCED238FB0AB6BACCDA35A12A2F2B8CE9A4E02145A7B3B6CB099F0928E7F47097E6F5F2C7FA DC52A462A1885539247DC2D64F070C187F9480CB5100DF10F5244C4E6E81A510AAFF9, 1BD4579B3E45CDD3F5375E28A03264DA8774B801C774CCCAC16D102CEC7C6A5803BE118E1AE9FBE8F3CBED76C3C44DD8216826F32B6B01520C195DA3FC88E4B115D, F0E428AD2666FB219A2FE10824D4BC3252A2DFF7837EF9C43B2086249F882692C38E6DAB2F81968709393012FB6295133656D3C8F8E761368961E393F6DB838159 294F7ED27E498FFAB6D794882ED1524497EBD8261F3029D32DF6CE4EB4B84EF3200FEB, 6B46BB397CE7AB596A2AFB3C34EEE6834DF1491B47F0DE7B3D2990A485753D6C166194484AFB55F38C5175436E5A9F128BE0BE0019B24AB71A34E42842D73748AE, 11925CFEE57807337021C6F47CC72712C03E7EE368DDDC30E0130E9370D807069EDD619A21CE113A07B2063F9839B3954139CE9D1CADC158E638D19307ADB216ED8 7BEE7C777ADCAFF02486BD988C73F6CDC7C388725D907D7989E46AEC1E28ECD9602FC1, 18729744522369D94181089B87BEEA5BBF0C661F21EC5BFCCB5B3880449E3C4DE92641D043B46E5572F2C9AD3836420981156C5F48760E7C393C29B42687EECAFE1, 16917E1777E8BC48D8E68A06A315ACCCB32A37B6E6EC3FE99E6F8A633DB23544A6191730FD4D64CD60256753E9A07E5423AF425955231452821380617FD34E6859 173CB756670960FD06D9438C9A55BE469574A995718B1786C9DAD40C45A7AC68C208F43, B8C1A2FAA4A38C6B5C086B3E47FEF5D32F3AC9CBC21BF67EFC711CE011B443F117208A16C3694C16BA84E0712C243C13B2F4F7BEE7B1A37F2AEB6E7E544F21F0D0, 9C51A7F89AEFAD420E44B4DFD3BE16BB66E10342AC8BA42F929F18E25B59D22EA2EB1F83D39078AC903817136B4F472B5E87EA2F6CBF912BB7038F5504FF8C8914 45B62603351C22F7148BCAA5CF013AD3C05DFCC054A146945D907C24D0F7053A461ADC9, 18AB4B785CBE1161A362E5F03D845438758C58A5EF9620B963D5B42A1EAA8F4C49AD5F9FD2082E22E5065D2FAAE0F0E1C83E294908C99EFCC6064A532E52AD68CF9, 2538470BC76D01561C4666A8E69BC626D44B52FD225043639CC3E9922E38A5C292749F8205D21CFF8CAE96837FE677BA2B9B7C1C8690FC417E8EF2E3FF03F3DD6 D12272099F5468E53DA35FF16D03B07B4119F640FDE3D3BD18B1746E72E50FAED25095B, E4A52924D439236B1A1BAE96F553B2311FC0AC49B5BB80066B00C26AA289618BE855523C7E699B6AD2AEDD03DED3A9F6EDCA065FE37E5FA697E273215ECF45BFB1, 11168C369531E88137F59DCECD60055F4727B03641476ED173E46EFD6B9E89CEFE115AA4A7A9391141F7A84707C78FA2ED89A26C4DC12DAF7C75245F0EDB85151DA 27367561CDDFD3AAFB8EA1FD4470B1171C34DE2C2F9AB7B374A145D4B58AF2F0C76F1C11, ABD75587F23664C736EE9C39EEF7EA79A8A5E756607E6567E0C2E3EB8A3A6BADB017A40DAB56FD0F56572ECDD2986589941DABCF7D46F840323CD60FE200AD01E6, E5DFB5B010DB7E1A6D634E9AE22E141551A6B43D3DE32B45DDABA4096500ABC1F50E2E2522CD9BDF74C6E6D340F35143E9885550FF2319986F17F6B85456629621 75A36025699F7B00F2ABE5F7CD521345549E9A848ED0271A5DE3D17E20A0D8D2564D5433, 1F3DC34CB9A1697825462062316E191451238CB41A9826DB5E53A3A082B9BD41DEDD03E90675302C81A35294F0F337D86DCD7F71F3362DC7BCD37A37622A3B9F061, 7258ED67EE1F89F2D00BFD90F18F8D5405CE23509A3F8893B94683794D19D5680FFE4B05C91207C29DD4F44C8D6C9091CB254463ED419E534115A93857D3D99D3C 160EA20703CDE7102D803B1E767F639CFFDDBCF8DAC70754F19AB747A61E28A7702E7FC99, 197339C4DB2660663C9BA318F1A871179FEDD145084F5A4607BF0BE5892C590271AC7A22DC1888F066931DB069CF1F9DFD4A26122C64DA097581DEED417FF021FC6, 1707C2DB68D0658BBDDF5C311A8DD905538FB345321BCD65B7275983B3599873B631AA12BB911AE829523C5542D2709EE3B9F84BB509EEB70F5CFEFB23720E432FC 422BE6150B69B5308880B15B637E2AD6FF9936EA905515FED4D025D6F25A79F6508B7F5CB, 19A9A57FBA49EE9897F17B0D51802625E0CD5635DD00253BC0F86066AA9CBA83E9A44E5CDE14227C29AE0C37476E38E2D9FE4A4E85BAF6E3E4DE8B1E8C1E2B92668, 1E4C99F87C7A0C6E6700882ABBDF476A7EEFAEED07093D36A212F9512A8321B60E3B2C4FBEB0F5119A33AD5340A162882FEA16841521561708EF5335B9C36B27202 C683B23F223D1F91998214122A7A8084FECBA4BFB0FF41FC7E707184D70F6DE2F1A27E161, AFFADD86FDAECEB5FE87E5D68BCA5D6FC66FAAF75B235D75056C703E5C7D08C8568AFB7FAD0318B455BB742E5C5D573D0E777F1AAA6932F12F1B4CAC01D4F48B9B, 1D46544CE165765D7DB51CF3C4D49E75AAF0D8E19736E38988047627CAABB924A9593FA5F6E986330D6C77350A77B0560BFD3C6A2BE3A4DF3D4A224F033BC1DAB25 2538B16BD66B75EB4CC863C367F6F818EFC62EE3F12FDC5F57B51548E852E49A8D4E77A423, 9D634B0CFF495B37AC29CA30231766588AEA0BF70E3B50A57BEA4159BFBDF3A728D1A4C508A0B9FFCD7A5FE17060BA9C13CFCDCCB48C73230B8D980E62FBFB3E21, 1AF3E53AD7A892A66757823448E49F147D8FE84A0FD56C34C6D536FB2060DCBFBEFE3D17A4981549D5790028D34BA5673F420B1AB09364195E8DE4B3130D6533117 6FAA1443834261C1E6592B4A37E4E84ACF528CABD38F951E071F3FDAB8F8ADCFA7EB66EC69, 1A6571DC66DDC875EBC7128C7FD1DD5A6838546BD6E101B7925BF891C74B3CB50D29E517DBCA28A538C5AFA9296854A263CFE612364EAD8566A11B1552474146537, 1C81C3E9D9E771C0BAA09224BD0008A11F17F14B68136C61A02D03876711C08FFD12227570FC67DB8D5A7DEC702E1BC928EA3EA3370A8F7455113338D8A27965279 14EFE3CCA89C72545B30B81DEA7AEB8E06DF7A6037AAEBF5A155DBF902AEA096EF7C234C53B, 8ECE9055639C581B93707DC57F1EBFA5AC5BC5DBD73A05E230CA4C7C1284FE0D47BD8E42F10BEB6576E2070CA1D307D23E5EFB51D1DC20AE19C50BDDAEADADB666, 16CECEE05BA436340253C616F1DA3DE5CEB5A96BA7C077811E3AEC39A5B06B829A959213655ED6F2646A6AD1F3FCC71D18AB5B6F85BB72A15A8560356D6BF0C43D2 3ECFAB65F9D556FD11922859BF70C2AA149E6F20A700C3E0E40193EB080BE1C4CE7469E4FB1, 108BD3A64E5D20457FFBA7C8D687322232398D44C8A2AA2CEBA2634ADAAC5B95DE65A32B34CC4A9ABA606E2100ED7D968AA2C29B8726D94060CC82D833926D7B9A2, 10D2C7977E4F7CAE8ECF0D06F93766DCDF35DE069D00D26086193305A6197E392FFA92061D019DABC648A9DCF430AB838F2CD46814A3F627618AACDE1756D712333 BC6F0231ED8004F734B6790D3E5247FE3DDB4D61F5024BA2AC04BBC11823A54E6B5D3DAEF13, 14E82F5E00E4935979D0512654B1B9D2CABF8257FD5BE4850FE76DA5EAD5E84804975D2DD2866FC1784EEA04618E183F6284FBC7C62AAE47013EBCD4590F2B3D6C2, 1A7194BE49BE87849376BC8109F94547056936DBEF812319CD75656EE7F54A152576840BB0399886E9F80B76148208B21E53E0CA4D28F1505421CBD1C6821CCE476 2354D0695C8800EE59E236B27BAF6D7FAB991E825DF06E2E8040E3343486AEFEB4217B90CD39, 852E915A7A02E40E80A2A8235C2B7A8D45E147EA0549D43461B4BECE2968967F64D8990FDC738CE9DACBDF1FB766240F6F35998EF1E4AEF80AAE4A6EAC04D820EA, 1767EA9A64894B2F66C3076202B9A2AE8805C46FD459A2C8E6110EC78455439593C5EA721489364487EA6D90F3BF8E67D0A0EC39BB430FBC70527B6EBB951DC0B12 69FE713C159802CB0DA6A417730E487F02CB5B8719D14A8B80C2A99C9D940CFC1C6472B267AB, 1D7C81ED3CE43F21CE09B33EE9A2A985DFF8AABAC817BAD6A99AAD667F44464B529BE9F198546118D5E3525FF0BABAB2E880CBEB0BE003BB04CCC7A5A5D0941894B, EDED4661C5126B5462FB1901A924B7F8FAB742D6625AA9B70DC077D1AC4FB2D30230EF300FBB29B8B4F2A100104A9E630230346EE34DD00B0FD029130CE8880C4E 13DFB53B440C8086128F3EC46592AD97D086212954D73DFA28247FCD5D8BC26F4552D58173701, F5F9A310F3CA4741EE02E3B2A6FD6D74590E9E0F1BCF0CAE1493FF0F558885F75E7A028DB98F343FA0F64D62AF378597FBDE10796267E481C2F5F13C9379F68C4D, 1DBDD5A00E6232A7ACDF3A1C381DC6C6FFD35DF91393ED9FCFF358CEDD9AD0665EF4BDA23D3DF531EE648C42FE52BACCBA29E6111EBDBAE45AFB075312DDEE6863B 3B9F1FB1CC25819237ADBC4D30B808C77192637BFE85B9EE786D7F6818A3474DCFF880845A503, B7AB75D4B652C91083634B8523C1F2113CE5AA18AF727EB9986929BF5817B90B8242869ADCC673A993B688191E06215D208B31B422AE2E7762CB383F3EEA071B59, 40C822C2A70CD378592127F2B43B1EE965CF4C8B25D60E620245F6040378CEADF42112282101EDAD44F4A1C0089ABF8CFBAC1AB25E429E5B0F9984325216BB2142 B2DD5F15647084B6A70934E792281A5654B72A73FB912DCB69487E3849E9D5E96FE9818D0EF09, 23BB0BBE506F35E1D04F7DF9F4841129F90F77B6E8B480055464020125C064FE358CBEB08954ECFF1677CBA0D685433C2D3D927F60B18EC557452B59B5B13C16F6, 18710199C5E7B1DE8A3F3E2F8FBB324DFE81C125EF81C54FBB4897FBBFD753FF1F3C5622C2346909D139BDFA7D8C3C0FCA0FC359F427C1FCEDFBF7BB8A6CBF2B312 218981D402D518E23F51B9EB6B6784F02FE257F5BF2B389623BD97AA8DDBD81BC4FBC84A72CD1B, 19EE555DDFED3875BA08AA6145D62D17D9CAE348EB031320A3CD088150D1F90EDEBDC61B482E97D19AB229EEDB23F1AF9BCC62A6892AD1529FDC7B0E6234222C7A, 9314C13F2224643EE0B019BAD6F3774F7CB60763F83B546D3B8A7946FEC5209857BEF2D099EDD8C2FD215878EE6484B7BE3CC3044EC098CE2FDA83091B264899C5 649C857C087F4AA6BDF52DC242368ED08FA707E13D81A9C26B38C6FFA99388534EF358DF586751, 16075372C721674577CEE52EA455128D3998292A38BC88B4EA697D42143325AF07DA057F65CE57C90C0365DCE08F7E5B95F2550A1CD0C28D3515861FD0177EDD209, F5BED40444A770145B534AA1D862292CB1340409A356555F75F0EEAA740C4F86CACAF244DC66924CB2280E5CBBA6789F4EAE28A1D08CF0F36A6DBB446B87FB2338 12DD59074197DDFF439DF8946C6A3AC71AEF517A3B884FD4741AA54FEFCBA98F9ECDA0A9E0935F3, 15515C1294E288CF1596287A48613C5FEBF86E440338DF09FDCE61A7062FA047D1F1233DD630D625AB52A0E2240FAC6D61026C8A11755F4FC14D90B0DBB229A014C, EB06C276F432EA10AF2E558DBF476575772B86AD17DCBF894E0DA79DE89EE46D55A4D5E96CB1AF668353C1CF6B54B3A4A2EFA65BAB36AFC775432624C1D2D26CB1 38980B15C4C799FDCAD9E9BD453EB05550CDF46EB298EF7D5C4FEFEFCF62FCAEDC68E1FDA1BA1D9, 153A4BC626A9A8D19D8A1646954B1005036DA02A5B519A51540A55C53F3E0861DB7FB007503F805521C6361B6964C3CB41B5FD0902047111A49175F5B24D5F9DC40, 1D5F0402244D4C1D45942553CAAA51107637E7C93FA54A83C9F5D55A80775AFA1AD4374EA2D592008AC100414265377BA8BF3EE11C00FBDFC1DE4CB9A0FE36F9721 A9C821414E56CDF9608DBD37CFBC10FFF269DD4C17CACE7814EFCFCF6E28F60C953AA5F8E52E58B, F1062444D092FBED2979971EAB4D274A10262112FDAD0629AD5ED2232BA94BD9ABA9A3991686823A631E6FC37A7DEF9C9AF9E93769CA10308E7DDEB39ACB042DA0, 18EEA79622BE1B249B37021D0A2B2F3CB16DD80B8834CBB944BB5B7C648C0E9BF6AEE03209992035AD418C6B3998BE7C7CAA2A9C315236CE808CFE32FAC7F9B5DB 1FD5863C3EB0469EC21A937A76F3432FFD73D97E447606B683ECF6F6E4A7AE225BFAFF1EAAF8B0A1, 16A7B3B8A011629BA8FC3D6B73239D53B2AA8123F398481BA5DEAA77914F223F158F6BFE6A43BC783BD36444340CAB70371871835BEB71F25F38150F2BBBF0AAA20, DE1A1D2DC84533D4CAEDF36862796C7EFE8F3FBB2477516AA2316C5DCAB66ED9D158BFD6475925B8EE68A19C506D04B010B76B73C8953947B450763DA698A95873 5F8092B4BC10D3DC464FBA6F64D9C98FF85B8C7ACD6214238BC6E4E4ADF70A6713F0FD5C00EA11E3, B3A32B8F0BF1261463F92FFD6CA9D33B7822DAD48CE12E202380D86C1CFA67E1184981A0C2553D72D4145AD6F8A6E2B6CAAD43E36DED935D27F5E58C8CED0ABEE, 7EAAB85F3096772A6BD6715D78ACAB8F3BED1DA00714FFA32D89C84005D252CE762835DDE9E721102105E475C633181680410B3285365E34AE4F7ECDA742DC404A 11E81B81E34327B94D2EF2F4E2E8D5CAFE912A57068263C6AA354AEAE09E51F353BD2F81402BE35A9, 16293E3C8419D299E80B94874AB33A48B6EF4C68F8BDC5383FBD324DB60722AE3C324E634F5EC766F429AA82F9B37519D306C9A9B171B3FE010BFF6FE248E776421, 1EB9D1B34120CA7A75F4422A7FF649DE4A9053CC549688E06F9C9F1601F277BD8EF927BCC5250429612EE754F95E79EBE89D886F20A639022168AD47CF8E6C5B1A9 35B85285A9C9772BE78CD8DEA8BA8160FBB37F0513872B53FE9FE0C0A1DAF5D9FB378E83C083AA0FB, E8B32CB499ECB3E01DAE281F97368802E734B54A4DD62197D713386ACCC0D268AA6FB0F4B04A17E7571FDEBD7B82D9AAE179B602B002304C0C96B501A601B40106, 185428F1BD795C5C11FB45B9EB69E2D12BB7F2F4608BEEF4C6A9317911B0B8B5740BBD54BF899812AB38EB6ED33A7928AE6B9AC49FDE34C3009281D6C62014596C1 A128F790FD5C6583B6A68A9BFA2F8422F31A7D0F3A9581FBFBDFA241E590E18DF1A6AB8B418AFE2F1, 28328B0CB88F54810A53575CC43C0C8195C0ECED24B4C4668E6C43A6F1C42FB6FAA8D2A9DFE090F135B3FA4FD80208A03CEB8F5DFBBB41204590A670F250F80A5A, 1E646A13E24FD0ED26166AACF070A913B06502ACC9F4BEAEBE1C1EC4347FF0B56A3BF97A11C55C1EF82CC298C393D836C929A43A6E605BB4CA1E72DD4D02D50282E 1E37AE6B2F815308B23F39FD3EE8E8C68D94F772DAFC085F3F39EE6C5B0B2A4A9D4F402A1C4A0FA8D3, A01C54C9314D22DE68E6F90046F8CB4EB4E06D9F57209D3BD6F1E043AEE9A14056B9FED753DD1B054E8104C060637F8FFB22BFFFE77C8417B1977AE3BFFDA8B0EE, 1DDCA880C7AA445F1B154277E9EFDF46E65E1BD60D49875AFCDFCA1041C5D79F15B825B2F77787D0A38518BA80017215CF3A5A77F0A73E4E99FC8E5CAB3FA417325 5AA70B418E83F91A16BDADF7BCBABA53A8BEE65890F4191DBDADCB4511217EDFD7EDC07E54DE2EFA79, 1369E0815170D373D37F3288BBCFDAE28DA52FB130FFA71157E472A05E75E9E945E8E04220B3A578EEA28386611C63AB52967841F102985CDB40A5772F091721979, B13A78147B142DC325879992F8539804AF4674B0FDD63B93E945E9E54C000838E76429441F0E8A0F497B9EDA8BAE28437B4600490A88C7DAA6D10C1125B0992A48 10FF521C4AB8BEB4E443909E736302EFAFA3CB309B2DC4B59390961CF33647C9F87C9417AFE9A8CEF6B, 36DA5963E99910A1A68B127398D3FFAE34EA7CFBA3EDE70E12146FD4BF8C1701FDD1C38CA9F73AED1F6023D5C0A0B2B2B05159464CA22E82AAE4950E46C7754117, 1C7D90BC4A5A2A568E89E2D00AFF0AB0D166581A72786380C5A73FE196B4B5487281681FA883F21BB6C14753E696AD56CF9EDD192B1DFDB6FB9933DEB19F74529F8 32FDF654E02A3C1EACCAB1DB5A2908CF0EEB6191D1894E20BAB1C256D9A2D75DE975BC470FBCFA6CE41, 16A810D97154E1989F831932E98792A3166E6382CEC6B5283EDCF1DB34A1499215B3D11401B0D43CEF4D1F3FF95AD42B4D8177D292EC288564FDFCF4B231C0939FF, 160AD3F0BD27347233370D71201E3356E37D8770C40C56CD99AD699D5C9AD38FBD2167C8ED288A44F08963FDA2820DDA65C36513FE5C42409542E4802E4BE5B5BFA 98F9E2FEA07EB45C066015920E7B1A6D2CC224B5749BEA62301547048CE88619BC6134D52F36EF46AC3, 1807A09363E63533ECCB0ECF180959E7ADA64C6C0A1048D7AB81DEE383C8466F8F8A1A5098EE5CD6277806412947DAD2686A7FEBE93066D02ADC4AE6E0E4758C884, 50443D8C393AF39EBC95BD1F76F288260FCAB0B5A494A064CAD1F7A2AB1D273DDD7BD520C1D7B91D622F2D9D5FB79A46FE5B3C00A17CD7DD8B750B05D50344F8F 1CAEDA8FBE17C1D14132040B62B714F4786466E205DD3BF26903FD50DA6B9924D35239E7F8DA4CDD4049, AD85E38956CCC0F3D48DCD3D46AE51DCC5BFE7CE21F7FA9C1C757796AE8174CFBC0CEE9B1894E52EC8243D012DF6495C6CFA08665F9C931362EEF089CD4F0C4C44, 146336282DAF91B0A26EE20548F978915DC6A84C1361D019587A98A38BA5D0988EFE56031C71BA4E74F0CA01261321DC3243943D7C9D32ADB45909A938DD3A8A248 560C8FAF3A474573C3960C2228253EDD692D34A61197B3D73B0BF7F28F42CB6E79F6ADB7EA8EE697C0DB, 1E66D6896F7302DAA54CCEF2172C0265DEAB2BA08847C246A631CE6907D5EAD4CA78C299D41B35C4EA4477EAAA79BE8FBCF9B41B1774F8B1EFB54CD2689A8D65D39, 63AF0ACA68529DA67E4DCE456F667218A32D15EC4EEDC4F6976AD85543DAB81459B2844A463E1EA2378C3EE981C75C219E0CB5AFC5FEF7F368EC32B1F35DF22007 10225AF0DAED5D05B4AC22466786FBC983B879DF234C71B85B123E7D7ADC8624B6DE40927BFACB3C74291, F5ECF3A8796865EC1A21C55D77D467A56674814842BBAE32EE0A2D0DF0C02EACDAB345798BA853ABEAB13C017B99DA5F7BE4C62950B55263565C7F938D4E8E6EFB, 31BBD71552D2A85EBD6C1C4AE68FA03C8B5C4358F65D39DBFE5F40975611FED7E0068430225CCA1255A1A0F190A81A097243501635111CCAFC62B98CC74587C7D9 306710D290C817111E0466D33694F35C8B296D9D69E555291136BB787095926E249AC1B773F061B55C7B3, 1E958824845860B6DE2C49F60DB58593C7DE3F3D40DB8C239BDAEE35CBA77E86BD9785D9FC738454364898EF682904FBD69284B4CA8579F819B605A00E90F0D3951, CBF7F4DDC6801FA907A0347DFF562B217555DA0CD819409D1FCA92470279E06FEF56514E434D3E0EAC3F4D81B4CE716A89F061A9FD986626EE7A4EA424CDEEF777 91353277B25845335A0D3479A3BEDA15A17C48D83DAFFF7B33A4326951C0B74A6DD045265BD1252015719, 1D089469ABBF7F177EE086B20D8F4D560F9D2F65FE301568FCA0E9FF8DCBD99D56A143D898015694A23F7204744A39053CEFABA04AF3FE0713C8599ED422409C3C0, FA0B96A5638E827A73DD30F585BF1F5BF2029C939E003CEB4E27CEDCD24420AFE4B7868B91B0127E534E9E46366EAB6D142B9CB7890E0470F14F0F34BC6CA987EE 1B39F97671708CF9A0E279D6CEB3C8E40E474DA88B90FFE719AEC973BF54225DF4970CF7313736F604054B, 7113015C26BF1BAE03B69F4057736389DA5467B2DA955CC58518E853F93AB4581A8B30A01E2597CD4425DA9EBBACD763EB41B7A4C961EB6F26A07202F0C9A23A79, B4EF5757BC534D27C76A7BA8563CD66ECF1E8D42D1F5EB77512E8DA4A62C68128389A3F61C4DB8EC4241FC177BED538226A825A2582591D69218ECCE47B8DF7240 51ADEC635451A6ECE2A76D846C1B5AAC2AD5E8F9A2B2FFB54D0C5C5B3DFC6719DDC526E593A5A4E20C0FE1, 1274B0343F67A9984E16FD0EE80743056214310796F34D3976A6A8D43CB020B65C3D88DCF58B6C3B7C75A4F7112DC21B3CEA4BE2A80D099C30C44F3E2F504D3619C, EEC43E2E523577DD55CA396E74B2C6C6CCEF6CD565D5718471A0F73F2F74A152545F336682FDAB3DA0599DD52E46AF2A33F7C5FB466AFAAFCAA5918B7651A9A673 F509C529FCF4F4C6A7F6488D445210048081BAECE818FF1FE7251511B9F5354D994F74B0BAF0EEA6242FA3, 12E87A58496C08ACDE681A371A002932F96EAD5BE0DC83CD756C0C0FBB69CC5CCB27A0256F78751C9DEC296BD9AC216110ABE2D36FF5C6C0E719646CD9BC9848CAB, 13D51083E33466DAA74CE90C42013673B567A1594DBE189EB584B67E9EB02A9574AEA7C9AFB30539B2D82A25B0A10BCF86CDE5ADA0F29FC861C1582AEF897021475 2DF1D4F7DF6DEDE53F7E2D9A7CCF6300D818530C6B84AFD5FB56F3F352DDF9FE8CBEE5E1230D2CBF26C8EE9, 1AA70532FA8B2911D34749E66DA1BB5151C87B1411820B84746DA5D9551987848341D861DAE93FFE3FFB9A213D928CE02092C0BCCD00FAF16D22A8E02C8358752D8, 1AB4A1B3E648A8E3620136FF7445826600E94506F09ADE6B253515F8928C2CA997A1A665324082891388FF046C92E5A33B6F34A289BE1D1D2DDD32C9877287FFB57 89D57EE79E49C9AFBE7A88CF766E29028848F925428E0F81F204DBD9F899EDFBA63CB1A36927863D745ACBB, 1FF46288A30152DA6309081DC1BBA11624FEC902A5A959ABB3A46C03FC445DE1BA6A71C3380CA21D757A1C07AFEC03AD23C0F515F1E9AF43039AF86B0115F13EE6A, 116660F754DCC1AFAD29679A16D50F35C37B60424E29A15D64F4C181A5A38086473EECC9D052E5F87F35492E054762EC80A51892F1A3D8AC963BB801936ADF9E032 19D807CB6DADD5D0F3B6F9A6E634A7B0798DAEB6FC7AA2E85D60E938DE9CDC9F2F2B614EA3B7692B85D10631, E2E2659D183137629CE339815983912705862D112419B5CD3FC4EA51C9544A90BD1E588801913F12BDD30AF3154E116D9CCB5F745035FB4AD89CFA93FE4A25EA38, 148B85F716EB71EF8E4D698A41073FAEF30832AFA80A36A32D40A1F1B2B5D2663187C80EE5A01DA95D88207D6DE6AD84B50CBFC4D3CAE65C9B7C771F3193468D326 4D88176249098172DB24ECF4B29DF7116CA90C24F56FE8B91822BBAA9BD695DD8D8223EBEB263B8291731293, FBC226F86D592BD29142CC8317D5B3ABE29449B677CB1B82AC622039DD89DBE1AFCA884E42CB3E07B2EA8115CAA0304E60DB626CFAC619471B750EFF62A4726E7D, DFE3C45B09642026C6DC0863F6F502A698D7188E68170FB79A46023B2C986C245F246FC0D53EC4409A81B26979866B9ABBD4D2083F23B628260B93BB914FA8345A E8984626DB1C8458916EC6DE17D9E53445FB246EE04FBA2B486832FFD383C198A8866BC3C172B287B45937B9, 7F9538AFB15DD31A0B7EACC6912CC76FE8110FD28A900EEB0AA2910EFB693E2124520AA7DCCA641DF1D78D91091F901C759C932884245DBC6CE6A28D5934515691, 3A9DEBCE202031C250E079E2269CCE0E9E7A1E359E14F3A7F8D54B5A8A65E452F4A7ACDD448849F267C535F9C4DB5DDCE46A5B7F8120F639387415A4C15CA50058 2B9C8D27491558D09B44C549A478DAF9CD1F16D4CA0EF2E81D93898FF7A8B44C9F993434B445817971D0BA72B, 1E5FD5C9C75CA0C2D3C43ADC8CD5C3FD62AF802CB61953315E9D4A1B8C195A62F5C2F8CDFB283D0B0DF7F11B48B138EF0AF7FB0EEF04E521D643BCE26BF6E279E44, 17967B0FAC085EE5D20FCB0B2709B5C248F24B65306BA860B5415A72D4408C8A2A7EDF85BCD36E65F85B545657B94AA209EE994FCA0D8FA2585F58C32F133DF02C6 82D5A775DB400A71D1CE4FDCED6A90ED675D447E5E2CD8B858BA9CAFE6FA1CE5DECB9C9E1CD0846C55722F581, 1BC6904BA16978D90118BF7847B561CCEABDEFF76649BF1DD7C7BFC4866BA3890F36A0436475DAEB48036E10BE570A6F3642BF69124C47251AF89A9278CC6E56AA2, 1614884FB58B7765EFB0A666AF4D03FD52940BDB0020AE8B94AA36B4942CB4709F1264DBE0A5AD0BE53F57F8270FA443D4BB44D5534BA201D4704C12ECDD008DCAF 18880F66191C01F55756AEF96C83FB2C83617CD7B1A868A290A2FD60FB4EE56B19C62D5DA56718D4500568E083, 9B1D4C6D7F418D04F09AC17C612276BE0D03341EC838F048CEE9A2ABB73EC54815C99E20C51FE7DB47F8CF2A282DB44AB14A1FE920413F60449964B742F8B02C3F, DF24FB8FCF13B35DFCD676EBFAEE3E8D6DCD9C3623A9465BEA96ADA57E4B41AF31BE04ABD82400ADC1E419CF1A43AEC9C024703710660BF3A0ED096AB88A4F58AE 49982E324B5405E006040CEC458BF1858A24768714F939E7B1E8F822F1ECB0414D528818F0354A7CF0103AA189, DAE4D9F107CC11823DFE8293A1FB69ECBB9E946ECB97384C444B634C39FC02074DA7BE04D7FC5B68F73BE754DC3B32CDFFA82E9E1D6A3AECDA4699D0CB93F7F9BE, 16841ACF02E71D74B2036B6F1B1A9E060BF30E0F3FBDE6C6100D21040633CE7DC894D7FBDC785498155AB8E84582394DAC0341339C1DFC0078F316F9624285DD2D8 DCC88A96E1FC11A0120C26C4D0A3D4909E6D63953EEBADB715BAE868D5C610C3E7F7984AD09FDF76D030AFE49B, 161107D0364D04CEFA9EC04CA61E26ED28698B8F90C5884003369C845A2AF92396C1501A56A600B818E688AA9B913E90402DD2C11A699640CA5B27961003CAF5C5C, CAE4335DCA78ECC080C6D6251E525E7EA6F29AF9D5220E9100413AEEE592C4C38622F902D5D29B1A8F96BA41E004EA9F3520DF16332A48C5345E600ED1EDAE178A 296599FC4A5F434E03624744E71EB7DB1DB482ABFBCC309254130B93A8152324BB7E6C8E071DF9E6470920FADD1, 1D61CCAAB9B9A1986CFD80B25C58B5BF17349AE6E6AB487D1CE00C445E89568C1584AD342E40F95D39E45008499F525218D7F3F386C8A3818475C4D4D260C9CBF4B, D9052AF5E8194BC8A13EFA0797FD4F1585B4F79D97EE261FEBEEC68C15B0B6E807800483694A5ACBB1993184E7741D78956555510C1CCFE285F7C3FBEB1DD25520 7C30CDF4DF1DC9EA0A26D5CEB55C2791591D8803F36491B6FC3922BAF83F696E327B45AA1559EDB2D51B62F0973, 1516B4B8A638A216CCF3FDA789F265E0710C5AC5CC7CA9ADBC8C21992A7ED6D0BD282056E99BD2FB920EDB5D6EBC4AA1594C2D49B7F16BC4884F120456BD478C1A9, 97A845B03C195EAF74BDAC8ED9808A4655D7B141023599BAAAF4FB9F4F3383875D12BAE755219B7D1840A88A0994222A1D36AB929B9B12AB3F825E7665200A1AF5 1749269DE9D595DBE1E74816C201476B40B58980BDA2DB524F4AB6830E8BE3C4A9771D0FE400DC9187F5228D1C59, AA06655EA7BAA2FDC21918D55027FCB1CB702DC30D410703BCE95272371A138C95BD13E63AA1F5CBDF3EE18457EF526DB733067BDE9F926BE6E011A32F0D766316, 14153B0F8B6C4AD4CEC216C28EE58BA2003B3092CE98995FE4F3D90B0814F71E2E027621007EBC567127CC20DBC01BBFC88BB23FA65E3B5D7E62FD21EE041AD3D77 45DB73D9BD80C193A5B5D8444603D641C2209C8238E891F6EDE023892BA3AB4DFC65572FAC0295B497DF67A7550B, FB33691F370AD3058190F92BA7F06D284FB8DB5B15FE90EEEDFFA7B1DA706AD4EF7ECD864B6249480E8D91FABF770AABF36DBE26B52791DC164ECCFE8647DD6016, A501BB4A888E289FC4EFA7F0C408CA0336725829D5FC875143D4E3184D7C2CABBA5586710AF702B2B45FC1983BDD9C300EA86CDA223B7A59DB8FBB3773A623583E D1925B8D388244BAF12188CCD20B82C54661D586AAB9B5E4C9A06A9B82EB01E9F530058F0407C11DC79E36F5FF21, 5EEC1A628A508CA7A549E77AE683842FC36D7AF0384F54C610A3334E7FF3AD9431BCB451656DA932DA230FCEED26095A0C7BAB19F5D28CFF45CF0C5E0A1E751173, 734279530B1A50BD84B0D0F8DA98800F2A9728333254F29B99232FDA0D6B0C56BA96D5A84E32E5B0704A06D600D6A40DB0B83CA1C6D01C7A29BA145269136E0553 274B712A7A986CE30D3649A667622884FD3258094002D21AE5CE13FD288C105BDDF9010AD0C17435956DAA4E1FD63, 1B19DF6C95BDA62FCB386A76487544965A4542943E7BDD4945DA59E897ADEC0FAEB5C298361E7D97144F890C8F6CB4ED5D139E0F2BAE201A6859D59DE0800F6A7BE, 18878C679DE2FC6FF305A3B61B3DBE608A21CD0109A7E4A9A6A8C516CF393F2B5F90CCDE100A07E9E83A1AB3E1B18E3AF7D533F50EEFE25910F8DAAFC12273F12F3 75E2537F6FC946A927A2DCF33626798EF797081BC0087650B16A3BF779A4311399EB032072445CA0C048FEEA5F829, 175CF3D0E1BBDA63D8E533F978D4B6D0EF6EF292433ECB7186216D15F4D56CDE6B2CD949A58323E7130F9E72A17C89CD58D32A3AB51E2A9E207DEBAAB85324E33D5, 13A0754082205127C4FD65976065B904436EE0731BEB74DD02292431349BFE953B8DCAE9A29AD924F4706E6372F6E30A1A695142815AB6EF3D34208FC8B67D3E2B5 161A6FA7E4F5BD3FB76E896D9A2736CACE6C51853401962F2143EB3E66CEC933ACDC1096156CD15E240DAFCBF1E87B, 1396B8FCC0B17435E67FF47105282E3090A8DE3A75F43EBEC99041CF94D6679ACB215D84E7F30E5CE8B90548CDFAF598647502434C909F13BBBA7CEB824E96B893E, 7551CBCF404CD416CF86112511C97B90C8AE11B9C38156DC018FF8F97CF0A584FFF3A893B1A7EBCBDFBBA7F25975D1886CB435D671645B344C80EC55268980D3DF 424F4EF7AEE137BF264B9C48CE75A4606B44F48F9C04C28D63CBC1BB346C5B9B069431C24046741A6C290F63D5B971, 658D21B04BB7C57461C88434A25D45E0342EF60B29784C6D89BAEA32CEE97E851C142E8C5FBC5C0DE86CA53B402521B7F68EF42D2A9A7FA59ECB2248DE9FC6A6CA, 77480221F9DE981E3F86871DAA4D6B80931F505FDE7FA3EAB499A15F6159CACD3CCEAA18F8E595CF55C15BBA54F5E9FBBCCED5937B0A4935D87635C6BA9FA2A28C C6EDECE70CA3A73D72E2D4DA6B60ED2141CEDDAED40E47A82B6345319D4512D113BC9546C0D35C4F447B2E2B812C53, 121980C2C37BEDCE3326677FF35C771AE76BE229B43A01B3C3F5D0C63C5E8CDDFA0D57E54426FD298543F55ABA17F408BF2589704A24F81377B148F92C9AA21199B, C05D2B359801DBC37651649B512F0B3C351569ECDBE80DE9D3860FE9F2BB38A7E84865634AAEFD2EB95C2E2FEA210298E0C09C50C625D2A2BCE61FD7A324C6CBD7 254C9C6B525EAF5B858A87E8F4222C763C56C990C7C2AD6F88229CF94D7CF38733B35BFD4427A14EDCD718A828384F9, ED37DAE03EF4B2813D2F3E81E66FC87582CC1A5B7032E4E5E63306E079753CE2AC57ABD4D61BDD6ADBA549028144DC56F67B6B63304F38A6934119FD79802C353F, 1E805CD53068D979B31A43CBAC7D2D6449055A6085598CA827FE4A11755D8E320E571FD19F1A761281AC06B2847DD34CBCE12F1ABFD5A1755AD7C167142C0BE36C6 6FE5D541F71C0E12909F97BADC668562B5045CB25748084E9867D6EBE876DA959B1A13F7CC76E3EC968549F878A8EEB, 1C4C0F57168F21D9D13B2FE10315B35D61AFDCCD8B5C97AE71D2E4305F7DD91B81A1C014D3527805717592BD75AD58308656B11EFE66CC2A1394663BFACBDC1622, 1B5EF0897B34AB0A00061B8D69EBF65B3B275F090686273310475D8448F2C1CA49475E7FA4BFA034D1F429A7C2BBC31882B9979E23C7B22F58A1B3F49C3CE97EE52 14FB17FC5E5542A37B1DEC730953390281F0D161705D818EBC93784C3B9648FC0D14E3BE76564ABC5C38FDDE969FACC1, 11C0062E9776CED7BFCF6F43C9E15B6CDF00E76E8784374A406294C96FC223FB0C0B0E78D0841EAE90607787D9721851678BD4AB5A36B851E5A3C3B3E53DB11EC36, D6BE3739431207B31B4A752767A352EE066FDFD4C26B0B650ADACB6535B0FA90FB451EF577EAF681D363FF72D0C82D5A46CC4D02D7EC4F44ED97C625F2E2F30118 3EF147F51AFFC7EA7159C5591BF9AB0785D27424511884AC35BA68E4B2C2DAF4273EAB3B6302E03514AAF99BC3DF0643, 171DFC8EDD79DAE5A63D6B79497C7B5EB4321C8752F0F766B8997AB8EF3B0ACF5A72F2344BB737CD2CBE56969D6CE1A9D71E3C9C53A518C626309D3B9AE0F92F3AF, 183BA878DD292A2271D749D106345546621C5C253767EAC72CA3F0367B50E25EB9201F2A8B3616160115EAE4615625A54646694540889FBA262AD60C3171C6982BE BCD3D7DF50FF57BF540D500B53ED011691775C6CF3498E04A12F3AAE184890DC75BC01B22908A09F3E00ECD34B9D12C9, F207D39271725932A582154650156D6D38BF9F895640D55CB696C4D786AA53ACD7C1DD39EE7B7E0C2E401E0A3FE5FB3BD1C781449A638D55E49114DCF6837BD28B, 1599FD70519256F1DE4C58AEEC3B51C87AF3D186286678630915A355EE234583AF53DDB7FC4275ED66C68AB3FC2FB9403C601421556A6162F33334CA502498CD2B4 2367B879DF2FE073DFC27F021FBC70343B4661546D9DCAA0DE38DB00A48D9B295613405167B19E1DDBA02C679E2D7385B, FCC2E5F471839FD7A4E786834F61EF6953B1F133E0473305C42A47F79100863AC8CEB3536FDC24CF7208FA74CD15969A2EDFC3321E15C467115A148DD5F1731A72, 1D24B7C1566DC10BBE2166872A3D96B18A934089BC31E873D1C4C7FAAE1D60FA400EBB57C2C20CE54F9B76F1C2190465E5C0B40FF2BC61BACBEA1D8C6C4B0E7808C 6A37296D9D8FA15B9F477D065F35509CB1D323FD48D95FE29AAA9101EDA8D17C0239C0F43714DA5992E08536DA885A911, 3DF965C45946AD537A86FC2B19944CBB24F90EC64899B98B4AE59BDBDD2D3BE2ABAFA6300D916DE8596C0AD5D539210E8B5013472022D5B7A543B652C2B91C4FAF, E90E42247029EC1E9AAD74EB38BEF22971B531ADC6DC665A7C492772DEE75372183678E0C73BCCB96E925CBAC19A2BFEA9E40610CBF5499189CDC014640F849FD1 13EA57C48D8AEE412DDD677131D9FF1D615796BF7DA8C1FA7CFFFB305C8FA747406AD42DCA53E8F0CB8A18FA48F990FB33, EAC71B13C1006B0163DBFE5BEE05EE005B56794E505366429AE0000138636EF38C9EE9F38581253984481BD285AE21F0244EAD9BE49B576001A3608BCB9E61D1C0, E815EA8641A20B6E7EA92A82A3D55BD9C4FDF65489CB14B782D11913E0FC0BD546E5BE5D8A8E0334FF7255BF91DA611ADF182455CA65E9BD7C77BBEF0AB33CB658 3BBF074DA8A0CAC389983653958DFD582406C43E78FA45EF76FFF19115AEF5D5C1407C895EFBBAD2629E4AEEDAECB2F199, 137BFE281C39C1A82BFBBF9E4F8B41477D916BFBC30545AD9868D3A650AECFE9CED818BA87FF07D4991E26FCD4A54E4594F91D16208ACA217E3ACD6EFDB47700D88, 578A287AE50EDDAA7E8449AB5A3450AEBFF0A542648E9D99DE733657F2C41D9D43F82A12AAF71C639D530BF30AAC13F430FB64E1F11BF700982DE54D440987936 B33D15E8F9E2604A9CC8A2FAC0A9F8086C144CBB6AEED1CE64FFD4B3410CE18143C1759C1CF3307727DAE0CC90C618D4CB, 14ADF84B7B26C3B76CF0CCEEFCBC09A3A92870F7EE60C6F616A790FE2DC627EB28E06C5B2FC2E6890922EFB8383237A58870360231BC5FA2A48489B5AC76ECD152B, 8CDEB8EA82B077D2C87E3F7108A5FC13E3FBC9FB84413D99E03DE8DCFFC6647143266DA21E581C71C8DC68A7067B6EAB15A4396ACF2A1279F0B3E3E7BE1620668B 219B741BAEDA720DFD659E8F041FDE819443CE63240CC756B2EFF7E19C326A483CB4460D456D991657790A265B2524A7E61, 110959607CECAD1C0EEB261F007276A4B530693EB5B1EE3CC676BD743E0B062E80FAFB5CD57A6FD0A3368302B30DFEC3C160B941BCEA235FAE9E0C8395E55A85F9A, 19037164E32E56A58DE230792A5B3A67AEFE55A82F4A7D1CBE8C1FB706B7367FBD5D49A89D39DB27E85167993E9E5A9B9623E20EE463B49E3D30C048AE13C268F30 64D25C530C8F5629F830DBAD0C5F9B84BCCB6B296C26560418CFE7A4D4973ED8B61CD227D048CB43066B1E73116F6DF7B23, 16F7CA28B99A2EDF84B4BE88B786B6B9A00740C2EF71D1667048A800E4C08C96B278AF7EF10716BC5EBDEA3697530C4D33EDD61DBFDA322DB3E805FAED9595C603E, 1776DBDD44736F14F5965BA7D3494985772D5BFFEFEF6B07109F6EEB71EB0BAA72836F0275819FDAA9F6FDDEB34C79137426EAE4C8BC9DEC3938BD423757E13243F 12E7714F925AE027DE8929307251ED28E3662417C4473020C4A6FB6EE7DC5BC8A2256767770DA61C913415B59344E49E7169, 46093616F98BAF2EB3E175DC458EE3C69E5C6B8B5CF13987E3A7A0A941559684F9229DE2A8E9ECEDD82F2897C03BE32BCF0898DE9E3437489431BD7A123C392F8F, 57381B88BFCE0A557F735D9665C5AB29DF169F254231BBBDE2E155B50DABD5196A9DDD183CCD8176BF4B9FCE09EB011C5FB30140BD79A7440064C90341C7CD89A9 38B653EEB710A0779B9B7B9156F5C77AAA326C474CD590624DF4F24CB7951359E67036366528F255B39C4120B9CEADDB543B, 426C8875006ACDD8271F635D6E3A882C083690635A6C958932723447CB1358D86DCE4CE707B6E50F5476E7E99D848917231FB51C72B2425DDADA401E6A83785157, 16BDE232C303ACD1CA6FAC26991357278F9ED8BEC7DB42BB50D7E22CA0BC96DD316DCD87D4D0F532877DAAA6885AFDB2298720062B9E591451B5FF6CEFCB5B5F7E0 AA22FBCC2531E166D2D272B404E1566FFE9744D5E680B126E9DED6E626BF3A0DB350A2A32F7AD7011AD4C3622D6C0991FCB1, 1292687676096BA03D01330426AD90A3F1D3772AE8197B1D2F6279FA31C14C26034B567BBEB7CDDA07BF26D1809A694CF6274539B42A706A3915C2F44046CEA0499, 14C8CBF78462ECF2090C0098CE7EE93C2358E7C308B17A5D599887FC20DDDF520F3CA8A15D1928E0EC67DBBC167DA58808AF42127B1C6994B7F3B18F51EAC57B860 1FE68F3646F95A4347877581C0EA4034FFBC5CE81B3821374BD9C84B2743DAE2919F1E7E98E708503507E4A2688441CB5F613, 1FBD973F8AA1CD7E7E758F543C4B15962E243BA435A7CE62E75193045D248AC3CC08E7B717D6541F30041C02000311155C2F7B8BC50CAACDF9A20223308BA0B3ED4, 11132F7ECA282F2CD15B135664DC71B307793681D35D355CABE19601048E932287AB606919C7C3196EABE8A1FD7E60BC6EEC595619058B5A3832538FD67ADABB878 5FB3ADA2D4EC0EC9D696608542BEC09EFF3516B851A863A5E38D58E175CB90A7B4DD5B7BCAB518F09F17ADE7398CC5621E239, 1172C5E0FB6D1E3676490A8F6A6F07BBA0168BA6661A2F81FADB201F9522839975840C028A8B0B60A6931692554EFBE883026A2C152DE91CEA777BDDC6F627A661E, D4AC0F11A8727495E69CD5F60359D12A0A1B11FDE3E00934299C0E83DEBBF7CBAABCDB875B24466CC0A43EDDD5F8D7546E4C227B24F7D4F7732B3E6650AA41983B 11F1B08E87EC42C5D83C3218FC83C41DCFD9F4428F4F92AF1AAA80AA46162B1F71E981273601F4AD1DD4709B5ACA650265A6AB, 1CA5C8ED8414E7F8F6845BAFF4C222176323EA57470A53C69F8C43B5D4760E9041FA400BFA27F538AF1A55FEA6D04F5E14D722A1E728969A8704C96423C25AF247E, 166CA93A22B4587FCB2BDE36253A9B9F990C55119E3DA00619E9FFFAB11F979BA125F9864E0BE3047C5F8574AE27B2D39A081CDBE0DFE725D7D05A5D9DA69334358 35D511AB97C4C85188B4964AF58B4C596F8DDCC7ADEEB80D4FFF81FED242815E55BC8375A205DE07597D51D2105F2F0730F401, B7E9D6A27F654531FC0F7C786F000863AD0D08FAA424DB04C37F85E91A43905EC1F50CF7E0DE5771279B6D00DBF2CC797B92F428F408DD4F23AEE37903F0EAB72C, 1986D1216BB254A2D161DE42417B688B83A75462BBD00E9C73EDDE6B1BCD3E7F9F0BE17BD038F9C0241974B294FC1278283527FCC83B8B93A0A6611D4B2C592EF7E A17F3502C74E58F49A1DC2E0E0A1E50C4EA9965709CC2827EFFE85FC76C7841B01358A60E6119A160C77F576311D8D1592DC03, 236D2BF74A2778902DFC71134461968114F6CB85470D0814CAE32C93B1F67B4AD78129CDB257FAB298BCE51088B7C446DC98B20D2F9E591E1FC45737D81B17371B, 764E49450662287FF960F7DB953827D14CA687EAAB6F46FB2754EFAABE7B237033CD52F4C9AFA158494D105F8E284A07CD9061694DEE4AF200144B645BF62FB0D1 1E47D9F0855EB0ADDCE5948A2A1E5AF24EBFCC3051D647877CFFB91F564568C5103A09F22B234CE422567E0629358A740B89409, D6C48BBDAD09D5C4D21C15913F12DE690D298D78919C30833234F234083C2FBE422C99CA3ED62A84C46B5966DA502C674ABB2D445F084F10EA0325DC725EBA1C6A, 1236C9FA47E0DF713E6FB06AE623DFABED654C699A50C9FE01F0473BE37886B96A20AA210441B28C0778057BF8B2E45421ED2941BC9EFA52791BD477EFBDE2A90B3 5AD78DD1901C120996B0BD9E7E5B10D6EC3F6490F582D69676FF2B5E02D03A4F30AE1DD68169E6AC67037A127BA09F5C229BC1B, 10271D98E7D157B7462534EC909A78F441E2A76CB8DB4E70A1C3D0F25322440ADAC2398FA7A4B2400EA173209AE764425C3677B93C192CA2316A81C32B9040AE523, 4E1CBEE003FFC3496359FF19DE33ECE2AD87960998B25B7C744B096D4B0829F4553C60C55D34F742D685CBBA36153BF462DD7E516659F1B9619D9E58EC2982B716 11086A974B054361CC41238DB7B113284C4BE2DB2E08883C364FD821A0870AEED920A5983843DB405350A6E3772E1DE1467D3451, 3C5BF99CBF25A5FBC1ED41341A01727F132CFB9B88F96CB4E205FF7982AE6430EECF9F1CAEB0616377B195F3D6CB32DD2B2521F98A5177D270A586BC03591F4B5, F13C82A9FB0BE0FC3285BBBB387C6EF42ADD9D8B1DAA42FBD9DB171220E7989C13FDCE7F6F049B649BE80E193845DE2B82D34ADB8858B3BDDAB5EB76490076167C 33193FC5E10FCA2564C36AA927133978E4E3A8918A1998B4A2EF8864E19520CC8B61F0C8A8CB91C0F9F1F4AA658A59A3D3779CF3, D974441FF93BD875D32F85621FDA40CC5B8D3E553898195D01951434FF62CEDC9E5EF9F286427798DABCF8D7C86B0177D57414A5BB5BE43E671112602B9CB523AF, 5DDC2DEF5B904E5BAFEC40B0BDB02D4C9FF954EB75454E68A83C0FB2836090AA593ED886780518F113C598BFE901724B64F3219779E9829CD4237173BE3B49A352 994BBF51A32F5E702E4A3FFB7539AC6AAEAAF9B49E4CCA1DE8CE992EA4BF6265A225D259FA62B542EDD5DDFF309F0CEB7A66D6D9, 3B1130BEAB751C179D55ADBB49C6CC941440104AE070F4D960B6994615B661DC31EA425AEDE1DC4086E3671A82836E5AD425F73E76DE95FED7E11E28E7BDDEB27D, 14028F1E42C5B0B76832EAFFD5DABF2206A2DD8FC481827449AEFA922A0A117EE4D85DE95475FC3038B2D6543538FB0BF037DFCEB6A9199597A1BC2987CC67B23B4 1CBE33DF4E98E1B508ADEBFF25FAD05400C00ED1DDAE65E59BA6BCB8BEE3E2730E671770DEF281FC8C98199FD91DD26C26F34848B, 15491048378808C7F9ABF6ECFA499A4BAF3208DED49D6048674EC5A7C5118B47748A66B5DE05E4F8D508CB5A38C02A9AB4EE56E6281738C4B24A59AE432B3820B28, 1F0CD96FB51360B9588233605504816284D6C46397DCAF1456CC40669408EE35B8E6F8C21AAECEFAAF135B9E2C051D657A657246EEFF851F80A1B3FE30900BFCEC3 563A9B9DEBCAA51F1A09C3FD71F070FC02402C75990B31B0D2F4362A3CABA7592B3546529CD785F5A5C84CDF8B59774474D9D8DA1, 744DC5532622CE93265A9BD266A973120840EE42A70231F27735C12F262F486F42B9E34DB4823D824171E3952E39888FEB536BBEF3562F9B7FD08031D32A5AAB9D, 1D36375EDC6231BA3AD055C78BF93CED67B4970235AC69908FFEBCD5201A7D42621CE6742B2A7683BC701286DEBE2F1A576D02A9ED1BDF2CC7EFB8AD92AD9A588F9 102AFD2D9C35FEF5D4E1D4BF855D152F406C08560CB21951278DCA27EB602F60B819FD2F7D68691E0F158E69EA20C65CD5E8D8A8E3, 1DC533F0E41046DE07F15B53528476DB472D8CCAC8028EEA5869BF60102921644F612DE0A96D8E47B2AACC12868CB24F1A6C89C5C91136DB9E68BE0A4EC7191F875, AF5A59CDADCDD5BDFA872792365E735A3507B76A790F8738C88E62DCF758ED22875CE8A27E3E166A5989316331A91F5BB0112590E6B2179903BEAF3179F2D1DD7B 3080F788D4A1FCE17EA57E3E90173F8DC144190226164BF376A95E77C2208E22284DF78E78393B5A2D40AB3DBE62531681BA89FAA9, 192E4960DFF304595C4F784334AA092C2C944CB31328A05C0224B63A8F0D5EA1753F591E02C35064680DBBFD6B8B8BB514E1E0BC4B66C67512D1080EB4ABB010E44, DBC0284A211FE68D52614ABA9B9BA5847BC114DDB1B2805F84F772BE295B0536520404418E2B3186A2DCAB4C4E1CFACA1D096BA3BEC7F32ED20AF10537A6B6DD30 9182E69A7DE5F6A47BF07ABBB045BEA943CC4B067242E3DA63FC1B674661AA6678E9E6AB68ABB20E87C201B93B26F943852F9DEFFB, 1A72286CA4510335269C0A7A8528973C9057B408FA9344D1F4064FFFD3280B6897D1F43B3579777800F5C48D9E8555E5C27DC179BF25825CEF9FBD1B5B63B04928, 192FE4551454D55E266A623155D2473AB4DF1F675A453494D3A7E905B4DCA0959C98E865624BE3B84E6036939041D0A737582CB1F8404DB0C3BDF9990290A32547A 1B488B3CF79B1E3ED73D1703310D13BFBCB64E11356C8AB8F2BF45235D324FF336ABDB4023A03162B9746052BB174EBCA8F8ED9CFF1, 13093DAD0548EF1CD3DD104F6F415B4BDAC830442AE1946CC95D4FE385F7D89282360B7581F7851C0A484879E5B3F2799772E6BE515D10C90567D5B6462FABC8A3B, F0A2E650678B0526931C544D24987581E01C60A22DD2D5E32D908AA27B7C0F29632BDF2F0049F721783C472E5F2FA4F8AEE688FF530098B8CDB67968BB3354C271 51D9A1B6E6D15ABC85B7450993273B3F3622EA33A045A02AD83DCF6A1796EFD9A40391C06AE094282C5D20F83145EC35FAEAC8D6FD3, 16382C2B7F9C282EDF4CC15898744DD404BEFDDD274461CC33BAFB8682B4C02417BB3512B566A0722B40FB7A5B8B3246F46621445FD1ADF186E2B7A9AFF802F4818, 1C7D37BC2A4F2359FD35A2AB14FFEB355C483453FBBCD7A0D0F4AE0B30E1562FA3D315393E5702FC07DEF2356E0DB3BAC1A5F58AF3C5E856E51958A614641CC5402 F58CE524B47410359125CF1CB975B1BDA268BE9AE0D0E08088B96E3E46C4CF8CEC0AB54140A1BC78851762E893D1C4A1F0C05A84F79, 15162C2DB067EF24A26AFBE769EA5FE69155ABF0C39EEB8E3B898070750A0549B318D5B69519795EC7FB0E8F6A7AC1757973EB6040280C3144B57AC950B2A3DF862, EDFE8D5AA5BAE7C42E4A4DDA5EB3512FF854C02078D19F17AE01DFB6651472432F8F69F9C678ABFE4EB28B6E63138813569042DEBCA32E0D7CF3E8F3BD9CF24B6 2E0A6AF6E1D5C30A0B3716D562C611538E73A3BD0A272A1819A2C4ABAD44E6EA6C4201FC3C1E535698F4628B9BB754DE5D2410F8EE6B, 1D30D470B2E079FFFBEC501C304666F49A7246B7B4A3932506E0F7521FB935E8AA9EE82627247FC724A329D7A8AD5BB18B953F3F5A0764C959BB0B42755157A21A3, 1051AB08DF58DEDF5E83101A3A8349C7C0F6929BCE9FCA91167FEBC248D88BC6CE46FEC4521A9624EEA4AF30991AA03BA342C85517C39E04D3839542A67331C4595 8A1F40E4A581491E21A54480285233FAAB5AEB371E757E484CE84E0307CEB4BF44C605F4B45AFA03CADD27A2D325FE9B176C32EACB41, 179648DFC76F49FEA912C21304EEABB3EF2D9D43930DC5213E1F261E31D9A32498B8D97A0FF0E93C08FB7A8B58D0062B3AC983FCBE0D427DDFAA6A5F6270A9F7B61, 54B10D0D94D499FD2E853B61FD6C099E4FBFFA8D42FC273A811031AE8ECA4CF4FAEF3735B11FDA90E571D89EA06B7D75A0B4F85DC5F20A681E03BC4B08A54246F 19E5DC2ADF083DB5A64EFCD8078F69BF00210C1A55B607AD8E6B8EA09176C1E3DCE5211DE1D10EE0B609776E87971FBD1464498C061C3, EAD7064A238176B81C605C4CE0E2EDBB7B5F1246A165A961D5F77CF873041F4A7DE3F37B125C8963F7B8450801F2782FBF133AD4035E6182C9B5F15D1344CA7CFB, 11A8F3CAFFCF2B9E0B4CE967566AAF56687397F9A972612D835299D6952275F6861505D876209DEFC0561414B9527C6A201B3ED62669BF45EB8A707C46C41C34A6D 4DB194809D18B920F2ECF68816AE3D3D0063244F01221708AB42ABE1B46445AB96AF6359A5732CA2221C664B96C55F373D2CDCA412549, 1B8E82141830FE5094583A91383E1C96552C95002A1FF026A60AB5A0A20FFD6A90EB0B1306015EB03946E37ED13CB29CC59D74DB098440F642E963E553C984D26ED, 4CD62F03E4DD7578C64C1046280FCF8C3E54A91E16DCAA6D6B65C59358CC0FCCA9A4B597AE9E13FF58BB5DDA4C7D192507B29AE440526E6395283003127ED3823A E914BD81D74A2B62D8C6E398440AB7B701296CED0366451A01C803A51D2CD102C40E2A0CF05985E6665532E2C4501DA5B78695EC36FDB, F19EF8D87AF85C3B5321BB3C39AD9CBF60F911B4BB6C73F02D2ECDEF4A1367989115192704B9889CF0EB84013B23DCBB0D38F0FDA0296714B50D6F0EF1AAF4791E, 3B90D68A294B4EA3D33613398EB1A8881ED876F47B54DAF92C3C80A80AC555C8BEE98A9D3025DD03FAC042121BCBE797E39B3880309C0E50ACE24F824DA1D0739B 2BB3E388585DE82288A54AAC8CC202725037C46C70A32CF4E05580AEF578673084C2A7E26D10C91B332FF98A84CF058F12693C1C4A4F91, 1F2CE747EB4B22D5014B69BF3CDECB279446105BDEC7AF21B58C93141D32C8D1B031CC78BE26579A0517B8E16335F7087452963CCB010C52A91A2D4BC507DA3BE8, 1F6161A23C26AD6A1DDD965ABA1C3117C77F818CB3083AF6568F1BB8FC2AC7DFCAB7746676E2199433F7E5D4A663F14EA9AFF3413930CE62A4FA4FA1F000448ABB9 831BAA990919B86799EFE005A6460756F0A74D4551E986DEA100820CE06935918E47F7A747325B51998FEC9F8E6D10AD373BB454DEEEB3, 156A69E1756107B3310D77907458EAA27FA69DE7C110428618F7CFECE6BDED7051A0E856FC2EB2E7E93B3FD8C185B020AE7AEB680F9A5EFA72D1CA4D046F7D51735, 1EDC17FF76DA34AEB0CFFBAC598F2C287AC06A8F2101514978ACA8127D374EEFF677FF1BC7228276D272ACCB872909FEA1DE6EEA69C121D51CEF2DA0202916D1506 18952FFCB1B4D2936CDCFA010F2D21604D1F5E7CFF5BC949BE3018626A13BA0B4AAD7E6F5D59711F4CCAFC5DEAB473207A5B31CFE9CCC19, 18E231A2BB0970DC1E6655C8A2B7D8325957D73B7E59A9BB206B638C8CD5439BD295D42BD2C9AACAC391A7513266EDA35379FC12B59D494B4AE60E90BF0818D63FF, 18375B951D26832902650144F76A1CC16E91F6EE5AD76F953E6B61FA754E3CDC764481EC519BC6D4CFE1BF6857258F0AA097B5A724E790A000086E70B24EB73206A 49BF8FF6151E77BA4696EE032D876420E75E1B76FE135BDD3A9049273E3B2E21E0087B4E180C535DE660F519C01D59616F11956FBD6644B, 1975AAA66ADCED2833DE622B01A797EFAE478631A9B455D895F46D40A6901ABF6F6F7C5AF208D2CCB6BE2B81E70BB7FC4C72E88DDF00F1409269A9FE17374B940BB, B605C4E9CDE6E43F254A4FBE3A326F3FF37966BFD5F1FF5BEB0178EEAE932FA78987E6F864443B93BB7B9629E16411B35B680E1B110912A33445E6DFCF4BEBED7 DD3EAFE23F5B672ED3C4CA0988962C62B61A5264FA3A1397AFB0DB75BAB18A65A01971EA4824FA19B322DF4D40580C244D34C04F3832CE1, 1EB1123F455B677723D14412484CFEBB4DA3950F61F19DF5721F58FD3EFA8A75DA98689B5E7A1EE2C070CD3BB069E55DF84D7DC2CC22582F3F7E56D0C439D2E8325, DA618FD3C5505047AAA8CAE07572462797A26A09D089ACECE3C786408BAA657F6422ED5F7417F5367416E9D764D0F22B9F7EB61E7DFAE97D0CE29C56322B9DC091 297BC0FA6BE12358C7B4E5E1C99C28528224EF72EEEAE3AC70F12926130149F30E04C55BED86EEE4D19689DE7C108246CE79E40EDA8986A3, 1CC4EA4FCAF6798C560DFE9FE970AD45D754BB2933147A73A81A2DB9ACEFDA4F606398E1597D2C064242A56345959692841FF26D364A5745C3D6597B964F2D987FC, 1E67EE899571AAC18EF4570DF909882D6FC76B1BDE8254A616CE9705A9B55100C322BE863FC12DBDCBFEB4A9D4734477590A2F53F63EE8A3D4EFFF2198F1232C4A2 7C7342EF43A36A0A571EB1A55CD478F7866ECE58CCC0AB0552D37B723903DDD92A0E5013C894CCAE74C39D9B743186D46B6DAC2C8F9C93E9, 1C5C94EBCF4E441AF961635E852A590638E66AD61ADAFFD38AB95CA9BB0D97ADDA6D45BF2115644D4318D25F357D46CEA9858BE53CD9DE75C6EED05FEE6497A5E8C, 885DAE71332B75E9853931E7A602744D6FB7E30138D8B830955D24A0A83A044979C74D51A59E243F90F480A59BDC38FF79A929562BFC73AD896775CBCDCA12D2C1 17559C8CDCAEA3E1F055C14F0167D6AE6934C6B0A6642010FF87A7256AB0B998B7E2AF03B59BE660B5E4AD8D25C94947D42490485AED5BBBB, 1B1F5EBABC694721BAEE86B8B527C4EA9703C2F49E191F4E6502DA6C447E0A608E87150FE87AAC675580D30D7A74FA52BCDA80AB8804D18EA902BB4520670EBA8B5, 1843B5C24B62CA20F46E7559F3ACFE2DA8C215FFC6B6B9FDC7EB507D8171B7A7E807465B98077EB5CC60A056C1FA738812C6C1BB49AFD117A6AAF3D1F8380F4B300 4600D5A6960BEBA5D10143ED0437840B3B9E5411F32C6032FE96F57040122CCA27A80D0B20D3B32221AE08A7715BDBD77C6DB0D910C813331, F709B54B5114543471870692754A841428EFD0770C82A781AECAE63386C327B3C52E992379AA2FBC8514F0A0C9BA2B068CD1C494DB1DFEF4B7827424109323E2A7, 159926BFE544257AC5EAFDAA49A90D4390E578D9A90C2670626317FCD26F384CD65138EA7CA1265E9382F6705158192785D8FB604EF15C540E461F58B17BF21D484 D20280F3C223C2F17303CBC70CA68C21B2DAFC35D9852098FBC4E050C036865E76F82721627B1966650A19F6541393867549128B325839993, 17C4EF2EDDAC7B6B9C896D936664555798422656BBD4240E7C7F9A447E6EB50B6A1B2A56BDCBB92D4BD10553166815B0127960E767103BDF20CC7E24667AC0ACA57, AD52F42C442B23FCE2650E4B7707D6AA5866F862EBF898F105D6AB42292B3343EA986BFE3BF684F131D0DF349C368860167287B1C2BE5672EC431A7CDA8BA22D3E 2760782DB466B48D4590B635525F3A4651890F4A18C8F61CAF34EA0F240A3931B64E8756427714C332F1E4DE2FC3ABA935FDB37A19708ACCB9, 1329513C937AD4092298CF1593A972B39C33A1A8596632AB6422BE1D1B9DFFD17E272D7C9363210E37E43500C399CF9B14870D231A509FE4386449DC32124F5A6D3, 9B3EB56B122B82035030DF2A6CB05FD0463325B70B5475EC576174FCF58861BC26893555D261A8C7B66B38E2FAF393D1C898FC6F4B339B3FFB48D6208D2C5534E1 762168891D341DA7D0B2229FF71DAED2F49B2DDE4A5AE2560D9EBE2D6C1EAB9522EB9602C7653E4998D5AE9A8F4B02FBA1F91A6E4C51A0662B, 107D8FE9BA7975F4AD4CA1E8446699B2438621B2C0178900F2F8E2CE179048C984AAD88E794F499258EBFF42DF2B9270DE833EC337BB8BFC1033F7976A49BC9B1FA, 51174AC7A12F0A4D508FF09A0EF48CFA212C36F378AC67929607547544A198DEDA80674FBCFDCB81FA90D98F0960FA7CFD17C2C6945B5D7EED22B701F86469C5B6 16264399B579C58F7721667DFE5590C78DDD1899ADF10A70228DC3A88445C02BF68C2C208562FBADCCA810BCFADE108F2E5EB4F4AE4F4E13281, 15F1D0395CFFEFA176770CDB66BDBDA07534A481B1F5A2A31991B140FDA835DBFF58429A4845EB501A733F0234698DA9B3C58E23E9BE24E5810F9061AF7F20DBF95, 5FE3F7A9D8213FE65D219E638873F080FE94EFF192711EC237B1098D1F6F3C6AF1DE7E3C727FCDAA1B33D6EFDEB72FD9901049E26C373A7FA37FD8E3B5C2F23679 4272CACD206D50AE65643379FB00B256A99749CD09D31F5067A94AF98CD14083E3A484619028F30965F83236F09A31AD8B1C1EDE0AEDEA39783, 13BB73C7C0DE9343FD9BF33177CC2C916D2FFA0AABEFFB9F166932845A97212A1259BC6416E1EB584C9ADF7486167CE6E8B642C8AE46FA71434D1B82E514620E4EB, 143266D91BD24A639499B5A0C94641BE2D6434BB8FBAEA6D008F021884E4A5882E50CFCC4A939319AE0AC2733A91B0403BF722EF7382CA0EA696457921845B57597 C75860676147F20B302C9A6DF1021703FCC5DD671D795DF136FBE0ECA673C18BAAED8D24B07AD91C31E896A4D1CE9508A1545C9A20C9BEAC689, 1A2D288FA87769C9695DD78C70D463392AFFA2BB93EF9D5426518F73FB41ABBFBC1CEBF14271400C54782F8CBA28DC665B3A146B383F1D70E391BAA17669E829CC0, 760C7FCB93FD8D145692C3EB4318EE6F03DAD12F014294CAC35A8481C6020EC71DF14764AD139B9406E77F63A41C7E832F4BDA940EF57A957DE9B4A7F17C1FDA69 25609213623D7D6219085CF49D306450BF6519835586C19D3A4F3A2C5F35B44A300C8A76E11708B5495B9C3EE756BBF19E3FD15CE625D3C0539B, 127B866890F34CC775044844BC0864B15175DE7A26E51B4F993D1851F605F6D4944703F7D718ECBAEF5C69B806F7AC29604952AD0A0C77154ECBBD3AFE3A9D3652E, 1C8949428A66A1F2D7E54CC8F8C56A421FC0B8A8E2C6B0637671F2BF31AC064E141FD615FBB996C23A4C499189B07BB9DF72F5CFBEB16C25A71F9D4733E7AB3FB83 7021B63A26B878264B1916DDD7912CF23E2F4C8A009444D7AEEDAE851DA11CDE90259F64A3451A1FDC12D4BCB60433D4DABF7416B2717B40FAD1, 79CD3328A3A58064FB8B90F9FEA4437413F176EE41F6B97E299A538170CB81016CBDDB53C679197505B5723F770D7A4F059ADC86003C634A5630AA114E243E2453, D82A25228F8C3B1407B7EAB67628966010429247A8A4B7B6218D010171EE9C896CC4E817040FAE1FA8A0BCC230399DFD3C961397AF4E8D2FD0BC5E380FCAC4EFE0 1506522AE74296872E14B449986B386D6BA8DE59E01BCCE870CC90B8F58E3569BB070DE2DE9CF4E5F94387E36220C9B7E903E5C44175471C2F073, 67A20B586960E640C96F6C47EAD9D8C0116AEB8C66345879FCE394A5E94F122A628B56B5B555A2B274B28A4CB8213B594BE94DF210358AE760672771435342CDB7, 161A396F9E6651642A631177DF1A79BD53B1047C0A14A8DF913261343FA40E8C73B108CE4D6E4E509EB14ED597F34FAB0B30BF125C627BC778CE764EAB24D0DE295 3F12F680B5C7C3958A3E1CDCC941A94842FA9B0DA05366B95265B22AE0AAA03D311529A89BD6DEB1EBCA97AA26625D27BB0BB14CC45FD5548D159, 10A9131226B61979B6A9798D2E2A8448E379A2E558B4E4D817AAA04B0304B59F864A3E85CA1050CE55AC738D8AE14386BEC6C0C311505D55AD8D7CC931AEEBE692C, B6483343D7004A3AD8D5B99094191C7FBE8B8B52D6F564E0A4D60E3D56F9EED4445B301D8372613428FDEF86824EBAE9E4CC29BFD4CA39D2602C915ACA75A53466 BD38E38221574AC09EBA56965BC4FBD8C8EFD128E0FA342BF7311680A1FFE0B7933F7CF9D3849C15C35FC6FE73271777312313E64D1F7FFDA740B, 9E517DC30559C4CEA55660FE9CC6504D875989DF21629D2C8A83A526A9A186BEED0E8BEFE8999F44086625C32DF45A310E41E18B82210B81A81048D465E762BAD2, 14BAD2DD2D10E324491AE8D29FB0181F16DC0101C47FBDD211897425A410B743028CA405FC074843916801507894C24AC22C2428FDB7053DD07E6D78950F452E0AC 237AAAA866405E041DC2F03C3134EF38A5ACF737AA2EE9C83E5934381E5FFA226B9BE76ED7A8DD4414A1F54FB5975466593693BB2E75E7FF8F5C21, 8C6E1CF957E955181DA548E3DC55EBEC6C3C68BE50F4FBFA0B8AC28F7D4E92FC1F9E5F9D32AC4953F7A6602861575BEE012B9F43771619D1CEF7A8CD492B255268, 14FF248CEADBC92366358C2F3F8046F5DA1A153F8AAB1FF50FD701223209C9B876846D1FAE69EBA7DFE27E6824A101F3E976929EAC9AF070AEA5D53296155AE4868 6A6FFFF932C11A0C5948D0B4939ECDA9F106E5A6FE8CBD58BB0B9CA85B1FEE6742D3B64C86FA97CC3DE5DFEF20C5FD330BA3BB318B61B7FEAE1463, BBEF569E0CC9A96C7A1C0CC4D3D70620BD5E9D53A58ACD7CD25BF21678DC6EFFAA1F89B1F8F39E7631A9A07D25C19E1C6794958AB2A600B278118F0E25C6223487, 148743E3D98925BEEC533C26B0E3AD101CA28BC7701C54F16A92CE70B2F39B67DBC5984D805C418FE5CB09F4134C2FF58B860A64B9CFD866BAA470EA32DF7DDD68B 13F4FFFEB98434E250BDA721DBADC68FDD314B0F4FBA6380A3122D5F9115FCB35C87B22E594EFC764B9B19FCD6251F79922EB3194A22527FC0A3D29, 1C658E918AD481902FFCB697AF52CEDE3F262449436145B74AD147D2D8E4570FF630D547AAAB4F0ADAC32945E559628A5508C60E3775F0F7B3C62223995CEB56ABB, 7BD861163EFBEC24CCC38A42E1EAA9D2B9BA2D2CD8545876004EA665F0ABD374D38E9A476B291E57DB92DD513D17B93C87CEDEB1A187FBF722416B4CE271384BEE 3BDEFFFC2C8C9EA6F238F565930953AF9793E12DEF2F2A81E936881EB341F61A1597168B0BECF562E2D14DF6826F5E6CB68C194BDE66F77F41EB77B, AF1430CCFB6E96905C60132D711CA0183DC456517413D6B4EA79360EE24DF4C61CEE38D67D57D8F6B97B7996FCEFA4935C2EAE90DC1F7EF6CD93B792EA09CB72CA, 15BBEB0B26DF08BA3BA3DF04DA15DEF333445C9D588166E8F5E7C4333EFEDAAE216228A789DB5E9B76A9F9F8C463C7D028EA38995D37D6755E95769D32B68B93736 B39CFFF485A5DBF4D6AAE030B91BFB0EC6BBA389CD8D7F85BBA3985C19C5E24E40C543A123C6E028A873E9E3874E1B4623A44BE39B34E67DC5C2671, 11EB2130BCDCE91DFEBF477898E00F46CB475BF5B27E7C5679BD0B167AEFFCE9DA47D499B4A2F13DC4DE9E7223659A6A64D6DE2B246C475F93A4E0AB69374C77CB9, 1D33D47802BD0525A4294A01AAFA1C5BC445EA609D1C91D0A35AB25145951BC9766149EE2190FBFF57350187675CA4F0A2E2F4CDBE21AA58048E538D3082735AF08 21AD6FFDD90F193DE8400A0922B53F12C5432EA9D68A87E9132EAC9144D51A6EAC24FCAE36B54A079F95BBDAA95EA51D26AECE3AAD19EB3795147353, 1A2F18405BC7A3D509B69C1D05856D4CEF9834E79A256273905DFA6F8B965960B1A7355C8F6365C9D9F4D2540979AE68FE6D4F89F1C462628FDBF2C25F47A9496C5, 14DAA6BB8249897441A6E142244167B9DF06E74D7905910A14AE645A0D23AEC3B4C5A160DE60C9FF1DB0AC4A2AC3D5932D77BBC22D02AC2DC1852F3A9F359D38EEB 65084FF98B2D4BB9B8C01E1B681FBD384FC98BFD839F97BB398C05B3CE7F4F4C046EF60AA41FDE16DEC1338FFC1BEF57740C6AB0074DC1A6BF3D59F9, 1BB9D99F0B34F71683F9629D3ACC1EC0E710861E99FFEC3BFCA03147AFBA4DF250247E2E3AC0C139C54C9DB78F3DE4B6C88D88C435C0253EE30BC55A0F75EC6CFF0, F390B86711EC1DA460FA73AB1C7753428AB592FAA788492718D0ED596A3273914A0BDB4EF43ADD85A9C097F48D7C614E28FCDB14AE62129AA2DD7994C5F51C7D7B 12F18EFECA187E32D2A405A52385F37A8EF5CA3F88ADEC731ACA4111B6B7DEDE40D4CE21FEC5F9A449C439AAFF453CE065C25401015E944F43DB80DEB, AB70771B55DC2406DA2CFDF6AD36BE05F3D6B71391504333C2ADA85367215599B1F75483E32432709AF01E8EF2DC7B393B69D0A66F6BB52749E51A8C855E2B2165, 1C927D230DDEC9908E2202D863E37A9254A9AB0F15B4AD3058D6B508285BF638379DF0513C3DED4C5F003CB486001FB9B5AEA796E8559284FE82113E7BC9EE7184C 38D4ACFC5E497A9877EC10EF6A91DA6FACE15EBE9A09C559505EC33524279C9AC27E6A65FC51ECECDD4CAD00FDCFB6A13146FC03041BBCEDCB92829C1, 1CC9802E3D53A08C1063EF50510241DAAEDF80C1696258F812411A7619D500E3ACAE35D1DC16761E9AB1B667F6A5CFB3DE60C6D0E0626DE429A138FEF3418910622, F45C2CA54B397DB15640C19E2FC5C23A727341A86AA485B95E5E21EF56BDA509239649D4DF7C736DFD5B9423FE2B964941333BA7D63F8AD92E6CFB040992C7F694 AA7E06F51ADC6FC967C432CE3FB58F4F06A41C3BCE1D500BF11C499F6C76D5D0477B3F31F4F5C6C697E60702F96F23E393D4F4090C5336C962B787D43, 15C7C77A85A087586E3543849614AF7CD373C56AD4D04865A72D9DC8572DEB2E811A75A3FC28C8A1D1D7EC61312E1E81CB02EED003FF3693259DFCD877891BE183C, 6F9499F4D91F936C153285A7C383B8C6058E9E676D1E68AA777896030C86F96022A08CDED4527E2B947D4A27E7D11E942F6EBC0E74E84EC2E2F1CD3ECF59DCC8CF 1FF7A14DF50954F5C374C986ABF20ADED13EC54B36A57F023D354DCDE45648170D671BD95DEE15453C7B21508EC4D6BAABB7EDC1B24F9A45C2826977C9, 542B6B74778AC458886E35A9A1410C3DA9F0F0E77930495B62631ACE17B7A0484C9B014CB1536770BB7B6DFC4913B0F34E63FF33C91481C63F7BC031222BCB53AA, 11D96C405781389CF533F8156A70AAE884D261FF36AD792810CA859A2751B6C14CA1C98E12332DAC28A37671D0693C5E81493A483BCE1BD739333035DDAEAEF5AAF 5FE6E3E9DF1BFEE14A5E5C9403D6209C73BC4FE1A3F07D06B79FE969AD02D8452835538C19CA3FCFB57163F1AC4E84300327C94516EECED147873C675B, 183C05B70F209BE717045ABEA0B91E88645D9210307A45F7887CB5B8E05387801E06A17E34545E4D54B50A61A0AD8619B62A9453D499D4CFA64FC591541D360FA55, 185CA9FFA827C9EA38F9EB0BF24CE36701AE794CF05344AAD469C6B13CC40B1426ECF8DFEB69EA8831612E4A042A883279AE8378F3C28CB54A5B367F41A9CEFA885 11FB4ABBD9D53FCA3DF1B15BC0B8261D55B34EFA4EBD1771426DFBC3D070888CF789FFAA44D5EBF6F20542BD504EB8C9009775BCF44CC6C73D695B53611, 17E2D3E8289F1A3822316EC45C80A93F113C2CCF92BBAD0616CE4C31F47A6786DE3104B172733C9C349ECB4724C59F90943CE6A87064F36369B4173D402B33B89D4, 14FC14E5BEB0866623400696A2FF439967C7E33A1528F5790D196FAE0CAA5686D38BD795BBBA74712F406E183A92EB79102086229675A2A8B2EBCA9816608596DA0 35F1E0338D7FBF5EB9D51413422872580119ECEEEC374653C749F34B715199A6E69DFEFECE81C3E4D60FC837F0EC2A5B01C66136DCE65455B83C11FA233, 1673C0F4D6A21EAA5692AC9256C648738BD7252DFD184E9512C3F5F92F8F51E4DCA6FEB75D13FF75EDC8ED728CE24512115B7D66E5A8C7BDD53F148CF7DA70E6CE7, 11AAEC3CE7DF2AD0591949D0BB5F4B5437A7287D3A1CFC06F61FF24D4714631E0471E02782BE823E904AD29FFCE51D17AA838F52E304A157FE0EE06742678A1D22E A1D5A09AA87F3E1C2D7F3C39C6795708034DC6CCC4A5D2FB55DDD9E253F4CCF4B3D9FCFC6B854BAE822F58A7D2C47F11055323A496B2FD0128B435EE699, DE321BBBF4C54AFCE7D32215A2EEFEB2EE09767FFF04FAA6B2341FAF782CF9A9D07EDBE5936F2B36C585E5D99A29B69E8F08F4A2CFE21641DEB6D041C08B974EBD, 18177025D1E0BE77A67CDEB542C098488503F70360EB2F61C823A7B1BDEBB1A8892A3097D85F49AAABCCA29745C5E7CBF103AC62DADCAA995AD95206EF2411C752D 1E580E1CFF97DBA54887DB4AD536C051809E954664DF178F201998DA6FBDE66DE1B8DF6F5428FE30B868E09F7784D7D330FF96AEDC418F7037A1CA1CB3CB, D8DE2E16D35FADD54628BF94D1EC81611E6D703B7D87B3727F96FBF1326D8EFCEE5469442F6229708D2B9F28D0FF2784C78B44877304A890247ACCCBC16872A3B3, 1FE6EA28DD4B30DF390C567AA15EDEB300863F425A5B1B3CC16BCD861924EAE7834D73C0B13FE1A03BB1DD27ED7424BCC01E7C39AB3A211A8EA92445D13444BE9C9 5B082A56FEC792EFD99791E07FA440F481DBBFD32E9D46AD604CCA8F4F39B349A52A9E4DFC7AFA92293AA1DE668E877992FEC40C94C4AE50A6E55E561B61, 184ABE3FB0312D282A4E0DF22DAF6408F35D4F08EA171E96DD753DAFB8E334D9CB1F94FDAAE28A52CADAA6196F8EC9FA8C4A1228E5C0FD1C77B69662CFDB90821DB, 188314CA090595942D25D26EE3A71B97DBFD8F3022A799BD61054D6BCD7DD852759102E0B1FD13A4E496B0D03EB499F44F66D803AE7FDDBAABD6B43AD1961CD392F 111187F04FC56B8CF8CC6B5A17EECC2DD85933F798BD7D40820E65FADEDAD19DCEF7FDAE9F570EFB67BAFE59B33AB966CB8FC4C25BE4E0AF1F4B01B025223, 2DF486A3DC35410AAD27C68671278B1DF07EC59A3555AC1F33AC99327743EEEFA50450981D4A63AE1D4791F8576E745B58E21FFB0132BC9F5471CD596C75C9E2D1, CDDF942FAC9EC5A83D34C1E61BFC6DD0432FCF22A03E617B2A76FB432ACCF076EE5538D91019809C257F329D670DD32BC861236C46F8985263556421734E2DB47E 333497D0EF5042A6EA65420E47CC6489890B9BE6CA3877C1862B31F09C9074D96CE7F90BDE052CF23730FB0D19B02C3462AF4E4713AEA20D5DE105106F669, FC47F39D9A9342D32CCD7ED1550B17FC76DBD98E4EC648491EAA3AD81ECCD498E758EF6E68E2942FB5436EC2F18E6E1A59455534D36645AA6CE2EEF7ABEA6A429F, 77B64D0C8442C16071D06AB2F56DC1E454EB37C0046CF9D9A05AF17100789242D6B426A335007936677AA7C82E365E25E6D335C67E5A4C7F22E80AC4F7A915D218 999DC772CDF0C7F4BF2FC62AD7652D9C9B22D3B45EA96744928195D1D5B15E8C46B7EB239A0F86D6A592F1274D10849D280DEAD53B0BE62819A30F314E33B, 72DF7D29DC382D061D17FA29CDF4F2CA5FE533F44E6C0BB39ACAAA5B535748D155DA215C572A24EFBEB3E08C422CBC7CC389280C764FBB120B37485BE7ED793300, 1379F04E35E19E2823531C0D926889287BC66FEDE617EB1F906294FC5C10D7185AFF09ACAA36484097EEFAD2CB2D9FCD1667FC94A21D7BF27844C157D8EB546769E 1CCD9565869D257DE3D8F5280862F88D5D1687B1D1BFC35CDB784C17581141BA4D427C16ACE2E9483F0B8D375E7318DD77829C07FB123B2784CE92D93EA9B1, 6AF49F5160C72F719C743C516123F45DED177FC979A5257EB459D293CC49C6D6C85FA019A1B25A75D5C5C8EF5AB2D7F471722BAF41D880435CD333F1D35A11A1F9, 17A092F54E224F3F5E370D6188B9735D77BA59A16BF18BDBA27C8622CDB0C4AAADDE676975F36A715B1F5C998E463973C56E5077D81351605DEDCC86E1579E4F45C 5668C03093D77079AB8ADF781928E9A817439715753F4A169268E4460833C52EE7C7744406A8BBD8BD22A7A61B594A986687D417F136B1768E6BB88BBBFD13, 1509FE8354E1C0D49704F7C9E384B44EE122F206A73FD15D5FE5C0893A35BACFC657A2F459B6919C6A59F8B16485DD86901D5FC0334C7F8F56FE2FDD9CD710BAFC3, 1A0FA3E32180226048F38FFE609BC26FD2397A092D6A9CF1EF4F76C682FCA5E0A9BF5B17E87737CC187722AB4DB85E35E6435FBD0B10136F68DABA009D03CD553F1 1033A4091BB86516D02A09E684B7ABCF845CAC5405FBDDE43B73AACD2189B4F8CB7565CCC13FA338A3767F6F2520BDFC933977C47D3A41463AB4329A333F739, 46DBEFDA4678029137F8D2B537F8B3418FCEB35AD4DE9EFD7016EA10AB8CC83F5DE525A4AF44B85D871880490340C24799CFEC7AEB7DCB8A27F328B78033DA3E3A, 17088E0DA70A4E95C5A05C3C9E7FA1E64803497C8ADD85CC6BE00F1F4730ECC3D83320251BEA6F903C26D518C64D70F0391E40F52394D20D464C4CB1ADDFD17765B 309AEC1B53292F44707E1DB38E27036E8D1604FC11F399ACB25B0067649D1EEA6260316643BEE9A9EA637E4D6F6239F5B9AC674D77AEC3D2B01C97CE99BE5AB, BD1D1172FEA3E457BD8AD5444E23C3185D33B63F90381C7F4ED35DD5ABAD4225EB96C94B2ACA6D6445CD805492FAED155383CB2ADCAF8D2109ED57FFD12DBC60D7, 128187DBD872D2FE96112AD4670661DE2B1E1FF315EC45437DD1D17F22855C64181698EFEA87062EA0B21E9920811A09616DD72A9588D4C2B3C05F2D751554A986F 91D0C451F97B8DCD517A591AAA750A4BA7420EF435DACD06171101362DD75CBF27209432CB3CBCFDBF2A7AE84E26ADE12D0535E8670C4B781055C76BCD3B101, AB657A84D03CBE90E321B0C132C593A87E3229AB6F8526BE212718B4938FB431A10D612146F2FEA097A258CBC3C6490D9010D4BC3C8D449512A8644E32B4B2802F, BE610A0EDA21A8284FE7AF01AE163E93C7AA71ECCDDB50B15D2DE9A13FAAB4362C2A29DDB3BB59ACC8DF9002796B193FB9C686C429F5C8961ECCE946F9051849FA 1B5724CF5EC72A967F46F0B4FFF5F1EE2F5C62CDCA1906712453303A28986163D7561BC9861B636F93D7F70B8EA7409A3870FA1B93524E2683101564367B1303, 16FDBCD87907F7640250E562D5D7EA5FF0C1EEE49A0D63FA7A56D6B848793BF1BCD9755011FFEA81132A9364407F299170A095FE89B9A6A3DF9D79AEE77FD341D62, 12548441A0B629009456EAD09DD05F0DE1FE178D71DB7AB140D32B5D0208268C125BD6C60304F450B4CB684CBE67798C91D4CF70E17D2DBFE6E1C4C3E70BAE03796 52056E6E1C557FC37DD4D21EFFE1D5CA8E1528695E4B13536CF990AE79C9242B8602535C92522A4EBB87E522ABF5C1CEA952EE52B9F6EA738930402CA3713909, 10470A88DFED45D0F19595E671D53581F51E4A2D3A0DA6533F89632AAB22FCB4BFBB025554F762A32AEAEE6A1101100F9C006A037BC6DBECD79AA761F0E843F395C, 657458DEC44CCAAE706CB552B34BDC57E34F46E7B24B3DB8D3B346E8D3F066DCBC7AF6FFDC52115D76A5551C996FE46037A45279553A8532D4A6288211F966FA64 F6104B4A55007F4A797E765CFFA5815FAA3F793C1AE139FA46ECB20B6D5B6C829206FA15B6F67EEC3297AF6803E1456BFBF8CAF82DE4BF5A9B90C085EA53AB1B, A9C7B530A8C82ED3DDAC093C679BBA9C10BAE4C6E70A46CE699056782212C251D4659D0174C80EB4A3A9DA5C1309DE8EAB660D182B197CB70984C394B280F2FE51, 1A9AFD356F904DE55B89E664146636D5AA3833C9A8CDC3DB1DE6A40B183F2B658AB79F29024AF382AB6E1E0F5A451C9F54288869F9EB728E3AE80E2F00B786CE883 2E230E1DEFF017DDF6C7B6316FEF0841EFEBE6BB450A3ADEED4C6162248124587B614EE4124E37CC497C70E380BA3D043F3EA60E889AE3E0FD2B24191BEFB0151, 10BFECB2F86933EF2D3D0F4FC1B8BE4C3C2B6AEA1FAFA4BDC00C5E26457551DFE3FDECB8114596EAD3445FB3F7C2D6807AAA4CF476C0F9E2116EE212848E22F7E64, AA03AF238C228537E1528ADB56243799645ECCCA9AB62D78D4354DA6B06EAB59B7B1A61BE103CF52AEF6FD02E39994B0EDF5B55E5E6835E20729BA6CC3BDFD7B81 8A692A59CFD04799E45722944FCD18C5CFC3B431CF1EB09CC7E524266D836D097223ECAC36EAA764DC7552AA822EB70CBDBBF22B99D0ABA2F7816C4B53CF103F3, 89C9C81B7863056A04D35A8DA566FED1A583B11A32C139AF5ED52B6B3C84763CD9D16A03FE9F8F76D66D9043A12CBA99E2160163462553A259E7DBB9E39B36BFCA, 1ACA646516FBCDC7419702A53757BA2EE8EEAC0D228F499870BEDF68661F8D56FF9B44F829B6F0DC32D4C7209F81A8A818C83B8DAE23373C5FB482335007B5287FD 19F3B7F0D6F70D6CDAD0567BCEF674A516F4B1C956D5C11D657AF6C73488A471C566BC604A4BFF62E955FF7FF868C25263933D682CD7202E8E68444E1FB6D30BD9, C838E095D259ADC1081183214930E368BC3C68C226983B0808314A7B5C54400F7EE47C093230C367AD46D06616AB864A293C3509732F99C4E4A3BF76277B58CD20, B5A4ACD32FB314B1A0FEDB687CE97FE16CA00A7004D73036E80C6246420D9EA5211DB0ACAD07813C8E74B0370073906EC7AB3B0962DB31A624AC86A03914E52D05 4DDB27D284E52846907103736CE35DEF44DE155C048143583070E4559D99ED5550343520DEE3FE28BC01FE7FE93A46F72AB9B8388685608BAB38CCEA5F2479238B, 12B7BA8CDCD76630988291EF9B9F414711BECB923207BD1641F63650D2EB79F03D42438B275A2261C69F7DD6FA439794022FFC997C80F12B1255DCAE82A50AEB331, 8B37583CF151BB968D438E17E21480A701261C14963FAE4EF37F9BFA12174D1FB477DAEADAF447DA8188E2D89C052174073ED02CD014CF16A87D2CC77FB0F42F5E E99177778EAF78D3B1530A5A46AA19CDCE9A40140D83CA089152AD00D8CDC7FFF09C9F629CABFA7A3405FB7FBBAED4E5802D28A9939021A301AA66BF1D6D6B6AA1, 1AA4D99854C554B4BC1106C67B4F4C7471C350068949097410ECC934CE1D8A93521FEE72B32980D51B0C4BEB4CCC4F26661ED17AF49D08A6B6850F01C9811960635, 1E2FDA7EBE4C8581C5342540A22C6AE12D991D5D4AB67CACC38078F0DA280902E90E6A14609E9E404711A048A8FEF8A75DA40957494E1577DAAFED199A66EE97C5F libtomcrypt-1.17/notes/hash_tv.txt0000644000175100001440000040030310621351501016050 0ustar tomusersHash Test Vectors: These are the hashes of nn bytes '00 01 02 03 .. (nn-1)' Hash: tiger 0: 3293AC630C13F0245F92BBB1766E16167A4E58492DDE73F3 1: 5D9ED00A030E638BDB753A6A24FB900E5A63B8E73E6C25B6 2: 65B0E1EA36CA17EDE2F055E67EAD67B1C282A11A5BA3A8E0 3: AB7FB8D21CE3D8D9BB5F1AF1F2FA0D3C277906160DB8D226 4: FE2E9D43F74B199D91B9291D73CCFCA0BEA5F068FBA244FF 5: 3DF6D672FE9DAAB21523EB04705D8A8B72B78B00AD465D1C 6: E05724353FE29957C3E8DEBAA21D0C2DD49CCA22191D5AD3 7: 4056DDBF82AE74AB56720DEAF079ACA2F076ED046D044DE5 8: 801FB9BE1A9AC7337A81345B3845E4E7C13AF1FBADB73723 9: 430156547A82492CA859385304748F65F2D4A7E2664AE2B1 10: FC435137CD652D720A11EDF47ABE4680BA4AD5BD810C9835 11: 20A8143DF47F5715FA0905FE6F9D1D2B5B2D4E26FA98930B 12: E4A2063019FBC034DEB01E2A95296042319CBC039DA69A91 13: B5F0FA570C4CD69A3C68448BE42C865BDF77ED68B93875E7 14: 802BE6EA2CE86A0B371F2354944B19CB3231AF7FB4F00FF8 15: D7C08863B5E5E3D69B5404A116315A698E128EBAF8636B70 16: 5C5288CB0E4E533056BA5293440D9BE6F3C461233BF1ED51 17: 88D3A94F3820E4087DA69D8BBE2CF415466063709C450C4D 18: C07B4B155F9F75805D9D087087FCDD28D08A9D022192447E 19: EE473E569FF3E092CF8996B31CE665EA7D61520D42E27395 20: E13DAE8098139CFCEA755D2060F107E3C7581EDF9F4B3B85 21: B48A9C09F26B379AA28FBC750B50CEF69D0D0EE37FF765F7 22: 574A01456373014F4179CDA14541E2E3C5A1CDDA9F9D071C 23: F2E2831E5BB4AF05914C4BA61BB8D600D1EF071C5DF02269 24: B7808A5B6258CBE718EDA938978C69D3FFC45A222E9DBF4C 25: D8E4E076DDE78950D51EAC9F97D2D1916A0910465D45A55C 26: 4EDECFAAE1DE98B7E056E64CA24003422BBE6F048129B24C 27: 0DE283B5A4953EAAEC6F3FDE50D7875C8EE57FA79BDC70FC 28: ECDD4BA1936DB9E6F83E2BD7F39D23927A1A17B2D52A8649 29: BE11893460E49659F7DF3FB3BD5E3E9A319F85FD3496E26C 30: AEC0DA0F2CC0646325CC03319A0E080F68B46B33F81920D6 31: 8824FD39984F6A52FFFF19016E27C594921452086373F2EE 32: 8B6592AFBB02E227AA451B5CFDC821B84245D34B96BF4F13 33: 960DF9C349EC6619FF37E3F0F4832E19CC6A4E4D68962651 34: F4E2B7AA72BC7D6E0CF6DA1094BEEFAA9C55610327C62900 35: 05FD1B80CA4C7C14FE5BF0ACBD0EA3DAE498DC391DCF2277 36: C5E95F953898C68355B591507BB714F0E5DAB9989D083900 37: B2D4E286CF7EA8AB6ECD650C9E48CA23497EADE55485DB1E 38: 9D51657E11C54FFDF205DBB435097A2BC6F93C4BE8D6180B 39: 3C6AE3911356A343AE3113735F07FCFB5E046ACD47B00FBB 40: 664342CDECC825ED340A7FFE2E57107DD0B5F24C24B2C3F0 41: 4EF7FCA13CE684D81DE4F566D2897CEB407FBB3DDE81FD64 42: 54689FECED63F297B13CD494B85E686680F4F78DE7EC81D5 43: AF434BDBDC7EF90BE03E40A033F16E8A57B41840E1E8AB59 44: A32DB678F44905C18968F5D898CA7992EBE2E4CC3318B96C 45: DEE9D519A12ACFB8A0935A368D6E6C75EEEEE6F2B0D5D191 46: CBC74863472D1C9D23C526F4908BD4D4234E00CBCC99A9E9 47: 6C228A1D4871E802E035C9BB16C5187354841FB6BE3C69B6 48: CAA755C55AA869E633CB3C6D93A561944AC7418154E2B0F0 49: A6835F7C0C6CA8F4A45787BAFA77478AE9ADDBEFBC3052D3 50: E406755957EC21BA6A64B5D3AAF31749CF98DF92F1B1FFE0 51: 0C2D4A44A803DBA99B7A467553C9293B46A538558BD77DD4 52: F04F011B09D275A185528CC040EB719649C8471A87B259B3 53: 3DA8B57FF52FCAE7C32636EC6C80708189CED8113C5CDE1E 54: 6C6C88B8E18DF5CB22EDB61A2D3ED74741A708BC46576FB7 55: 2D48EE2BF85DE234754BECF3C6F5B0E62988B5BF24AEA5BB 56: 0D17702DDCA078ED1CC51B95DF29EA1053CE97F69395C613 57: 9D8C2AD327DE43D5782D5F20881F4A8C433BA19AFC8C15AD 58: 227BA419B760D9D10DBB09585EDD475AC2734FD4539F8275 59: 2F5220A828EF94E327BD51D4DF5C58609F8A93B9FE01FFF6 60: 0EED9F91E1A33A50B8E913DBA0B5E248D263E1FC72C6A449 61: 766B707E999FF3C51EE01168513BA0DCEFEAB222DD1F69F6 62: 85E6710694E7C36A2340DA6A371C0560450F3D44D35AD98C 63: D401F9B13D39C24477C0AE6971C705C63C067F29508C29C9 64: 212DF89C57155270344ACCB19027B0B26B104FA0FBBE0FE4 65: 3BEDE767AA4A7507DBEFF83D1BC33F67EBA9C64945066227 66: 79FED1FB9F17C4980108E8605C10D9E176AC8FE4F6A65064 67: 48D9B7622AB7F8968ED926255F78E8CE461E4C9162FFE8B7 68: 6638C83837297B3F53B0F824C087D9A0B8D9FC6265683B8F 69: 174421CF6D331FF51924F8946E8244555C9020D38E31B6DB 70: 03E42AFB5FFF9B9C3794A3DBEC99FA7E3F7305EF07BD29EF 71: CCAFC68D4B3ED889DC9F28CB9225808A40AA8E0D5CA343FF 72: E824F93B4022011886EFC54539D4D5D51863ADA329FB4E22 73: 7CF0DC01B326687530F42040BA0D0CE93174455E8A990D14 74: 7A8E619479F4F5C418EC041806850E6723CA56AFBC3D32CC 75: 083C5CA90F4B296C42040559C8296149D4EEBAB5EF2CB82D 76: 3581B7AC32FA8A0986FD14F277FB106E112B92D18CD689BD 77: 258E822D9CC1ECA8B55D925BA361BA2D9FC27AF181F138B4 78: A86C1E88A64515FA281A462D467458231494F16E835DF873 79: 76E7F06FE9B8B388DB012F8B4BE2FB343F95913EDDE47A27 80: 00278B4E5690E729EC7118B5BF63C9D1EB1268960893CA75 81: 8DE70E64A31BA1AF4F5C23CF774CCA32FE952D76C3FDD1B7 82: BBEA72C840749BABAF1415FEAC343411B89515B87848A09A 83: C6C3CCAC1B338DF117A61ECF9A280E9BA709784C72B76771 84: AE9813EF4429EAE73EA9FDB5E23D263AF1BB87928CF5F048 85: 68647CD7BFFB8E530D28C86685A8D2F657EE4CD64EDD7E66 86: AA8C35B0E746AF56435F6C711AD0423966EA459087409713 87: AAD5C0D5E980B29BC88985C544717B81F58CDB923A3468E0 88: F60929D14781DE44EA607AAFC0D25FA1B6EF3C6AA0F8B3D7 89: C48087DC75EC43A54A593F24E1B359BB75C581A65C3170D0 90: 11D1372FBDFD9FF514611AB20D31BA62F18856C8D6AE3AD7 91: F2A8076B9017EDADEED41F409C9E32EB3BC090EAE89F855D 92: 702FA47E5BD35E344B5B87C0082106337206CADD3D4D5014 93: B9E03FED752A560C3B0365EDF5BFC4DC7EAC5E4BBB93738D 94: 3C84C52BF51077A5819F56E5A5C1C06209181579393220C7 95: F8ECCA28A525594E138B55C06617A063DF74FE3469D98381 96: 1081C3BAEEC0ADF4980C2EA6593B0906DCBEDE4805754774 97: B5152E39DE0BFE8982D783FC4F0CB7160EB2D69F6F3B3E5B 98: 6A6B760BFB1965C72AC793F9C02FA21B0F1C34BD2640BB6B 99: 1E6DCBFA8BA8D96C29101768A6A39433D5AD5A50E0970730 100: 733222D3A033351FAFD68C5CE8A4D833BA7420D44103CB6B 101: E4CD7DA59B215F1DEAA8FBBA850F2C1A7F4C3D495FE6804A 102: 7BE78C790713545754D4C78A9318ACA4AA058C5C23540131 103: B71C3809A504BE2F57AE9E25BDCC3921DC665C65289EA55A 104: 2B8CA39977535EB692EFBF0DECDA8971A8604F7FCBAE75DD 105: 3CC48B51E4C5DE4F0C2ABE0BE6EE4B63CC564A87C01943CD 106: 157ACDF7B59FC25966F9783207554364882840E7251ED6C1 107: DEA1CFAECF18D3611CCD0517131A16DDBC97A12902DD8BAB 108: 2AD2E990BCF6481284DF44B961632687C2E64DFAE2AE16C2 109: 838F3A3B28A50A12B5707490A66080DCFA0230E583B6EB14 110: C8B20315121CDFB3A91BC0EDF11886F283CF6C480F498627 111: 2B0FB04F100BE9AD51B7D64C76651BAB4B7D31D1D9195711 112: B6495B6256FF464EC409A4098B622E8BDBB1003411854FD7 113: 1741A789472E20E1CC89869A2477E4F2807C22182EA5B221 114: 07ADC82CB3F27389A12B6B9C2B268BDDFD1D9478D9EDA0D7 115: D9BD6760FB819A8A3CEE75303F8208FCA3E138B517DAB934 116: 9FCF21A9236C2C12861FD20F1FB15A187CD7EE7821F72BE7 117: 73D165769B34DA6F151464E61115D0E09A66F8D0FA049726 118: 74580BFA88EEA03C0EAE722F81997E400D9CC25FA0311DFA 119: E3C6A369820E267C938D276A858928040C7C25A826501DC7 120: C20AD90DB0B8BEE0335D069259991060969EEC9F939E4CA7 121: F3746F4CD6A19CC137C5FCC8F60A4C0A7F56D97190B7A9C2 122: 63A3B79EAF3DF35180960465059C0ADEE06D45179A56284F 123: 606AFD833D082628D58672403EE6DB348E6F68D8CD1947F8 124: 7567EA8E10CBF312F8478B7C51D87B00B6CF3DE82B03DCE7 125: DBCDC2B9B8589F6C7616B55B059B3B3E38D97A9E6DF1F29A 126: 15D9909F8D69689E7E78A0DB928194A59623E7253AA9D400 127: DE39589DCC0C654867943801946B9888B347526279CA15BD 128: 34FA7C74EE67C1F92C0BE1CFD4B2F46A14FFB999604925F6 Hash: md2 0: 8350E5A3E24C153DF2275C9F80692773 1: EE8DBAE3BC62BDC94EA63F69C1BC26C9 2: 1EAA4F494D81BC570FED4440EF3AC1C3 3: 54CDB6D1BF893171E7814DB84DF63A3A 4: F71A82F8083CD9ABA3D0D651E2577EDA 5: 2F708334DBD1FE8F71CEE77E54B470F9 6: E014DF2DF43498495056E7A437476A34 7: 9C410644446400B0F2C1B4697C443E19 8: 0944DEC40367AC855117012204018C9F 9: CE8A6E797AC79D82D2C6D151F740CB33 10: 06DB4C310570268754114F747E1F0946 11: 9F323D5FC6DA86307BEBC0371A733787 12: 3C1C7E741794D3D4022DE17FCE72B283 13: 035D71AA96F782A9EB8D431E431672EE 14: 7ABE4067ED6CA42C79B542829434559C 15: 5E8D0D6F6F8E07C226AE9DD32609035A 16: 2B1632FF487D6C98AA3773B9D3FCD2AB 17: D3D894482F7541BC0948B19842B479D9 18: CFE6B872AC98304524CC6A88B6C45881 19: 1573DD015C8629DE9664CA0721473888 20: ACFE2D3BB3CCAD8AEF6E37D0D8FBD634 21: F5F83499AA172BE8344F7F39BA708AAA 22: 1D1C71FF6321B685D26F7FA620DA6C22 23: 4D7E74B6C8321775A34F7EFF38AAE5DF 24: 351A988C86AC5A10D0AB8E9071795181 25: 970F511C12E9CCD526EFF8574CF1467F 26: 0A68F53A476F7499EF79278A4EE8DAA3 27: D458CF9C8CD0ABA23BD9A8C5ABE495CE 28: C8002E85C3AD9B8B4AFD23378165C54B 29: 0B4788B157ED150A34D0E6E96BB4789C 30: B14F4E31DE09281E07248A17939BE5B9 31: 803EEB99231526D6A33C8D4FCA537A6F 32: 51FE5D6637D2F0F09E48CE2A7F5030EA Hash: md4 0: 31D6CFE0D16AE931B73C59D7E0C089C0 1: 47C61A0FA8738BA77308A8A600F88E4B 2: 9E7A1DDE4D280E7F389018A5CCC3ABF2 3: E9A4DB2923FAF634CBB12CC1F8AC5C66 4: DF8FA069C6121801FFC539DADD33FCB9 5: 4B3511308F7E71BF6462CF18F1184C61 6: 075582A51F87682919E733C84C9FD998 7: 20DDA7535A464D13E1763BA61BDC12AC 8: 66AE1E305BED186780BB60328D3CCBC5 9: 503E90BF2375627262E58D90177220F8 10: AEC6B48C10659E3D6E18A2CDE8F8D3A0 11: 45EFB3704B6684B0750E3DEDBB2BCDA9 12: 7C9443DBCD858138E32604E0D288F7B8 13: 95E5B93F4EA79C082BA1745D3026D70A 14: C913D5DE0BBD1C2F2838E46363732D97 15: ABE357BDC413C82C8BBAA380C39CB5F9 16: 22F840370EBB1DDBEA4FA3A40243391E 17: 0A289FEC69AF967988FA40C47960060B 18: B63D3ADF13B509C95C088F909A0B356E 19: 36E8E07E3202E6F4F7E885853C9735C7 20: 1D363AFD1208A7B8BD486D51AEBFAEB8 21: 75E36A5445AD72CF5BF47301EBED1FDF 22: DA7979688F48A6606D86C762DF0D8850 23: 6ACB325CE624372873CC01A4AA053F8E 24: 94F9BFD6503DBDC58C163E33504B7EDB 25: 3702CB296784290FC46B82445BF7EB17 26: 903510251E7A00415EA21B6AC268A92D 27: 6DF08DB9C33C86CFE8DAF5E5BB865ECE 28: C29C5223D89A6589DE9253AF050D3449 29: 16B935ACC3EC6C016CA1BBF727C272B9 30: 644C01B157A24584B02A32119A424C01 31: 4A3C6C73634759420C419426F7D43E67 32: 7BD627A6B82FF3D797FFF130D8956391 33: 811A69D6A8AFE3C4FE5B4EFD73804F6E 34: 721BE5F4BDDED885BFF842868F62F4ED 35: 76956871B22D5BECAD3E9A459B4A448B 36: 4F2CF372771A13B4C0C1A589F0EDCF87 37: 084AFBAE8D22DF83CC760A61138E560A 38: E1CA123EBA05CC4899731A593833F372 39: 9D9E277FA61993C018C1C61AE09588BC 40: 85E0D0316F0B76578948810039EDE2BA 41: 27736345D0F2B0A1A9576D17C47D0202 42: DC9F788BE7C97BB5E0D2DD49B9F1D2DC 43: 27F1A9A0D166C495493877DF06E9C104 44: D1ACA7951866F58773CD4AFA3D2F5C2E 45: 5204BE3729BD7D318EA8127BED82D5CC 46: 10258B7939D81F5F8E0EA70EE6500B08 47: 4E699952169098ED3084DC2EEE7BC488 48: DF6ED8D604512088FCEAFB21808BF7D0 49: 904D0667C94C9C981D59BE80DEEEE628 50: D83483A47B64D74F9DED5278EE462404 51: 490EC8799A9DE3BDE8708DAF68E6888E 52: 443E4D2D5F800C22D818927A29A38490 53: 48E82AA772E111FCBE393177F3123963 54: B72685D042162D5F30472281278C42F7 55: CC8A7F2BD608E3EEECB7F121D13BEA55 56: B8E94B6408BBFA6EC9805BF21BC05CBD 57: 6AEC85410412FF54078A9FC72A55ACE5 58: 3E69F792BE88478883E46E867F3C93EB 59: 3B057FC41BA700F0E46740B8FF391F52 60: 3E3C6DF9500BFF8404486A3AEFC6F16D 61: F5AD65BA970ACBBB8335F9C0B9D7139F 62: 75D45F8E48406E32ABF94D07FF9B9C84 63: 54BA4472FCD03E99CF28F90EED9F2AE0 64: 2DE6578F0E7898FA17ACD84B79685D3A 65: 3A4F2CA37EEBDF6DC99A6155517B74FC 66: E19DC463C01E1B712B9415202A2B5505 67: 61D8AA0838DEAEEADE2F26156AF58761 68: BE294AFF81BFEA3159564B8B61844EFE 69: BB943319320EE7B3A029D7BCD101F92F 70: 36239791A7BE33AD46F668B51D724481 71: 21DCC9A32031428B7B02F68E1450A0F3 72: 95C1B0832575E21982B17CCCCAF54556 73: 24939E25985A3B5620B19D7889E5E153 74: 3029C8B005386705FE7E4CBAA060E987 75: E8BD97C5C1A0CC9AD1F1BEB3913B22FF 76: 808EBCA0B0E6FD1B30E4BA499C05EF9B 77: 55BD20AB87DE2E536DDE22286D0922D9 78: 2B2E45FA5628F29DA06462378D17DD12 79: B90F1709241EF59F78666AEBB3D5607C 80: 37854275343F079BCE1639C84D74AE1C 81: 444AB5A4F39B765C5D67BB433D4CF0B1 82: 7E30CFA6363F9AC96607783710E151B9 83: 9D9252DFFB2D5023CFE34873EA6C43AE 84: 49A70634AFCED27DC2DF2EB079F7A1E6 85: 4C976C9EF13716CCB468D82BD8C56FE2 86: 4EB382D16DDC18C31E6DBAC6CA83247D 87: B16112D0FF3C6A8ADB19C13DF742F5D1 88: F703DC6100AE23D194E01EAC433CF28B 89: A6527B1B907218063BF196AA91C73F47 90: 61F1A1E947F3F542FCF85AC758BA5D14 91: 12ADDEDCE418E9444AE34A40353ED0EB 92: D1C35142C475D44A52CEB0A8FAEA7AAB 93: 1F89912C1FC59AAB53C983B035661269 94: 2E7E19A4A6635AB5958DDA70B415EB06 95: B700B6739C0AF162D246AF07284A1AE8 96: E2B95AC9F876A38D33CCBBD7FA92D67E 97: AEB4849953750A10BB236BAC8D5AB487 98: 82D738AF18FD4B26FFF61377EE921E62 99: 0E1451640E59CE0461A46934F174E237 100: AE06EA64074E8C07116563E8E0893BDC 101: 562DCEB678FBFAB24141E591FFD471B1 102: 7DD6C3C2884E483E8CA572C471B2D812 103: 2A4C8E4EC2672C1D54A8DA8F32F04783 104: 2BFED22E8810A4658060B95B0ADB60BC 105: 214D8F2DD099BAB68EC17189BFF8A8EF 106: 98E4EB29797C8E631CD4317AF422FB05 107: 241A0F826F359A21CA0E6D9154D1E291 108: A3398C0118A3605E7A7794B8DF7CA152 109: 5B0A6FC8721F14EB8A03E9A5D87F173B 110: D93ABEC3EBD5672350C3C36F8FB00E53 111: 659905751D1F614A78ECBB56D4398D06 112: 594691B38126E028352DA5B28ADFD416 113: 7533FBD1FD58C85D54A712EF218A9D53 114: 654796E7D2F9F2C2D166F23B5AB18812 115: 5D25B604FB75727AE7EBFF980F54D96A 116: 426A7709CD61EB6ECF4034EC83E073EC 117: 62E21CA2F8E39C03BFF56C8265ACB60A 118: B7C9DAAA89A29F2805DEDE790DCB9575 119: 9C1067170940CE8F8E4745D362675FAB 120: C5BB35660E3D0A286A96EA3AA4922B3C 121: 8F3B6351623A0E482B57525474DC703A 122: CCC34CC280340681CA5117477DD86AE8 123: 2F5FB6B41301F87A0490035DE4C1BB99 124: A16E28DB3F331091E928F9AE3F1ACEB6 125: 7D2259C98085B9BF7F5E36B29DF8384A 126: BDDA1266FF3E8FFBA1DE1B2759B58BCC 127: 2067886DA4BDE10A94B971CD740B0AAB 128: E1275970EB67D2D996E6E658270AA149 Hash: md5 0: D41D8CD98F00B204E9800998ECF8427E 1: 93B885ADFE0DA089CDF634904FD59F71 2: 441077CC9E57554DD476BDFB8B8B8102 3: B95F67F61EBB03619622D798F45FC2D3 4: 37B59AFD592725F9305E484A5D7F5168 5: D05374DC381D9B52806446A71C8E79B1 6: D15AE53931880FD7B724DD7888B4B4ED 7: 9AA461E1ECA4086F9230AA49C90B0C61 8: 3677509751CCF61539174D2B9635A7BF 9: A6E7D3B46FDFAF0BDE2A1F832A00D2DE 10: C56BD5480F6E5413CB62A0AD9666613A 11: 5B86FA8AD8F4357EA417214182177BE8 12: 50A73D7013E9803E3B20888F8FCAFB15 13: B20D4797E23EEA3EA5778970D2E226F3 14: AA541E601B7B9DDD0504D19866350D4E 15: 58B7CE493AC99C66058538DACB1E3C94 16: 1AC1EF01E96CAF1BE0D329331A4FC2A8 17: 1BDD36B0A024C90DB383512607293692 18: 633AB81AEA5942052B794524E1A28477 19: 2D325313EB5DF436C078435FA0F5EFF1 20: 1549D1AAE20214E065AB4B76AAAC89A8 21: 7E437C81824D3982E70C88B5DA8EA94B 22: 2F5F7E7216832AE19C353023618A35A8 23: 6535E52506C27EAA1033891FF4F3A74E 24: 8BD9C8EFBBAC58748951CA5A45CFD386 25: D983C63BF41853056787FE1BB764DBFF 26: B4F24C1219FB00D081C4020C56263451 27: B0AE6708C5E1BE10668F57D3916CF423 28: BA7BB5AD4DBA5BDE028703007969CB25 29: EA880E16EAC1B1488AFF8A25D11D6271 30: C7172F0903C4919EB232F18AB7A30C42 31: E9E77893BA926E732F483282F416FFAC 32: B4FFCB23737CEC315A4A4D1AA2A620CE 33: 5506A276A0A9ACC3093F9169C73CF8C5 34: E5A849897D9CC0B25B286C1F0BFB50E3 35: F54FA30EA7B26D3E11C54D3C8451BCF0 36: 07602FE0229E486957081A49E3F06F83 37: 7C4BBA98253CA834BF9ED43FD8B2F959 38: CF8DF427548BBFDB1E11143FDF008B85 39: 1431A6895A8F435755395F9BA83E76BF 40: 30DD5E4CAE35BA892CC66D7736723980 41: 8EE247A1063931BEDAF4C2FA3E4E261A 42: C32CEEE2D2245DF8589F94FCDA0C9F2C 43: F25FA0E071D1F1CDC6632C6B673BCCD5 44: 370491B643E97577F4F74BD88576D1EC 45: B292BF16E3AAFAF41F19C921068214F8 46: 52921AAE5CCC9B6E8E45853419D0C80F 47: F1375BE31969155EF76F04741CD861D7 48: 04605CA542B2D82B9886A4B4B9ACFB1C 49: FA887BA0FA491FAAACBB82BC5FEFCD5B 50: 06470E932AD7C7CEDF548B5CCB9D4806 51: AD130B245E2DD894267CB0DDC532D169 52: A9EEB95053682248608E97D79E89CA82 53: CC26A3DC608268B98ECD1F3946C4B718 54: 33DD62A2DF6538DAF1CF821D9CDE61F9 55: 6912EE65FFF2D9F9CE2508CDDF8BCDA0 56: 51FDD1ACDA72405DFDFA03FCB85896D7 57: 5320EF4C17EF34A0CF2DB763338D25EB 58: 9F4F41B5CDE885F94CFC0E06E78F929D 59: E39965BC00ECACD90FD875F77EFF499A 60: 63ED72093AE09E2C8553EE069E63D702 61: 0D08FC14AC5BAA37792377355DBAD0AE 62: F3CDFFE2E160A061754A06DAFCFD688B 63: 48A6295221902E8E0938F773A7185E72 64: B2D3F56BC197FD985D5965079B5E7148 65: 8BD7053801C768420FAF816FADBA971C 66: E58B3261A467F02BA51B215C013DF4C3 67: 73062234B55754C3383480D5EF70DCE5 68: F752EBD79A813EF27C35BED69E2EE69F 69: 10907846EB89EF5DC5D4935A09DAD0E7 70: 5F1F5F64B84400FB9AD6D8ECD9C142A0 71: 3157D7BB98A202B50CF0C437AA216C39 72: 70E7ADE70281B0AFCB1D4ED13EFC2E25 73: 0BB96A503B1626C9AB16C1291C663E75 74: 5BED4126B3C973F685FCF92A738D4DAB 75: 7523C240F2A44E86DD22504CA49F098D 76: 6710949ED8AE17C44FB77496BEDCB2AB 77: 4A4C43373B9E40035E6E40CBA227CE0B 78: 91977CBCC32CDEAEC7A0FA24BB948D6A 79: A6A0F1373CF3DBEE116DF2738D6F544D 80: 761F6D007F6E5C64C8D161A5CED4E0AA 81: D44EA4D5A7074B88883A82F2B4CFBE67 82: 3097EDA5666E2B2723E8949FCFF2F244 83: AB247A3D9BC600F594D5A6C50B80583F 84: B229430E3DB2DFDD13AA1DA1BAC14D5C 85: BEFEF62987C6DCDF24FEBD0BB7CD3678 86: BFC3E5C7C461500FF085A66548378E0E 87: A5712194537C75F0DD5A5AB3E9EBAF03 88: 8DAAC097E9044B85B75999D6C3BCCD24 89: B8124DF21129685597C53A3F606FFD28 90: 8FBC4D795C22D958248582A8DF7332ED 91: 36D217135DB136B2BDF1617D7E9C79CE 92: 1B3E6271A3A4B663C509A1255027CA99 93: A25F596574031FF9C34314C1B1F6BF34 94: ACA7017E5BB62BFDD5BBFDED78C8987A 95: 8129E53A694ADD0560B1534B32FE5912 96: DA0E48224106C7535A4CD8DB2AC7B8E3 97: CBD4ACE3D766D8E44F63E0DE8F110F04 98: BDC17A0EF2777512CB402C90E9D13E31 99: 47695AD6AF968D6F1CDD2D8C5C87A466 100: 7ACEDD1A84A4CFCB6E7A16003242945E 101: 225489D3D073AC705F7B3AD358EABAB2 102: 301DA87A7B2EC27514C3A2789D5DBE49 103: 16222C503718F1420958133C330FE3F8 104: D778CE7F642AA23355948477DA4CC11C 105: E873C37F8977E200A594B815E1A87EF3 106: E8F8F41528D4F855D8FDF4055BBABE2F 107: CACF3D3D1E7D21C97D265F64D9864B75 108: 6BF48F161EFF9F7005BD6667F30A5C27 109: 42E7BB8E780B3B26616ECBCACE81FA1A 110: 225AFD8EC21F86F66211ADF54AFC2E86 111: 4FAD3AB7D8546851EC1BB63EA7E6F5A8 112: D1FEC2AC3715E791CA5F489F300381B3 113: F62807C995735B44699BB8179100CE87 114: 54050B090344E3284F390806FF716371 115: 50482241280543B88F7AF3FC13D65C65 116: 4C36F27D4786FE2FB8CAAC690B6D62F7 117: 5A0EDF0B97977EE5AFB3D185B64FB610 118: 4541055C6675B614D27C537C3BB15675 119: 1C772251899A7FF007400B888D6B2042 120: B7BA1EFC6022E9ED272F00B8831E26E6 121: B0B2D719A838DB877B6D6571A39A1CDC 122: 800AA956EC16F603ECDBA66C2DC6E4CF 123: 8827D2778287C58A242ACD4C549BEB31 124: CFBC5AA0B61103C1A982D8927B26F575 125: A1F5B691F74F566A2BE1765731084F8A 126: 80749BE03F5724FA4CA0AEF8909379B7 127: 8402B21E7BC7906493BAE0DAC017F1F9 128: 37EFF01866BA3F538421B30B7CBEFCAC Hash: sha1 0: DA39A3EE5E6B4B0D3255BFEF95601890AFD80709 1: 5BA93C9DB0CFF93F52B521D7420E43F6EDA2784F 2: 3F29546453678B855931C174A97D6C0894B8F546 3: 0C7A623FD2BBC05B06423BE359E4021D36E721AD 4: A02A05B025B928C039CF1AE7E8EE04E7C190C0DB 5: 1CF251472D59F8FADEB3AB258E90999D8491BE19 6: 868460D98D09D8BBB93D7B6CDD15CC7FBEC676B9 7: 6DC86F11B8CDBE879BF8BA3832499C2F93C729BA 8: 67423EBFA8454F19AC6F4686D6C0DC731A3DDD6B 9: 63BF60C7105A07A2B125BBF89E61ABDABC6978C2 10: 494179714A6CD627239DFEDEDF2DE9EF994CAF03 11: 2C7E7C384F7829694282B1E3A6216DEF8082D055 12: CFF9611CB9AA422A16D9BEEE3A75319CE5395912 13: E51F9799C4A21BBA255CF473BAF95A89E1B86180 14: F741644BA6E1BCF5FEE6D3C1B6177B78468ECE99 15: FB1D9241F67827CE6DD7AC55F1E3C4E4F50CAA03 16: 56178B86A57FAC22899A9964185C2CC96E7DA589 17: 0A0315EC7B1E22A79FC862EDF79BDA2FC01669E3 18: 32AF8A619C2566222BB0BA0689DABCC480C381D5 19: D35B5AFBC48A696897C084E6E71AAE67C7CD9417 20: 602C63D2F3D13CA3206CDF204CDE24E7D8F4266C 21: A3C6FBE5C13E8B41FADC204C0CF26F3F214189F4 22: 25E480E9E0CA2B610105CD1424B8A35F63FB3981 23: 45412D51D3CA7BCF452D1612720EE88F9D2427C3 24: ED6A95036E3E046931597A457DB7A78B7309C4C0 25: B4FE0256D346700783420E08A4A6F7992B1E36C9 26: 33E1799E98280E5A9ACE5509477A2048607C5537 27: CF193837F6DE43F8E38000ACFCF764FA8D8FDE22 28: 7C8DE247DDA83599AF2EC2EE2D29E20583DAC34B 29: F38A076F70613FC251C4D21E6435AD08341A8A99 30: DCD68E6174BD74BA180DA047A7345E8D111F85FD 31: 43BBACB5F62A0482CBDB564171B04365CA6E27C0 32: AE5BD8EFEA5322C4D9986D06680A781392F9A642 33: EB90BCE364635C4C23B49F493F0043579BC85C17 34: 2942C7AFA65444C43D0592D0DC73CA71DB729205 35: ABF726F5FDA729FB7F3F0484D7C94B3107AA02AE 36: 75DB4F6BCC05A781DDA9D17C46717286DD53654B 37: A82CB42D89DAF5FBC1D4A48476229C495782F98D 38: FC1A69683744AF823CD69E8A1E3F460591714028 39: DC68DB44B48521B0700A864896A00E17777AEA83 40: CC9AD99E917042381B0F99588896CBF236AA8ED3 41: EC7A68484A749C7065C6B746F9C465DCB414F370 42: C627C449DEFF14AE7ED807293D30846F061DA5B8 43: 4782F2A19B6DBB0882D656DE86C3D21A7317F768 44: 02D4EED99E7307BEA39AF5330BF7FB388D48B496 45: B3D99B9D90A69E50FD4365704F5AB2EAB7BC9763 46: 9B1C07176BB227F73E8A4E173071D39302061DE2 47: D79097DDAC552A6E02A52CE7AAF494D2D73B2557 48: DF7F23B160E75B9BAE5EA1E62B43A5A34A260127 49: F598F3780D8C374D97957B9B62D56106E9E0B2D2 50: 0BD98598F9AB29C1359EF5460A206DD1370515E3 51: E6C320834F69D81689E1ECD5ABC808D49D9C4E07 52: FD5EE7588CD129E12B886974621FD29FACC78E19 53: 2A9C28EF61EB536D3BBDA64AD95A132554BE3D6B 54: CFAE6D86A767B9C700B5081A54265FB2FE0F6FD9 55: 8AE2D46729CFE68FF927AF5EEC9C7D1B66D65AC2 56: 636E2EC698DAC903498E648BD2F3AF641D3C88CB 57: 7CB1330F35244B57437539253304EA78A6B7C443 58: 2E780486F64BC91FBFA2785EC1CA5C9E3CC07939 59: 4A7713D44E97D9F09AE1D786199C58AE2BFAF3EB 60: C98714B16F92C8A770E9FC229DF834D1688E282F 61: AACE3DD6F54A2A255ABA920F5FFC8CF04B85A69A 62: CF8563896A3B0A0775985D8289444C4BBC478DA7 63: 6D942DA0C4392B123528F2905C713A3CE28364BD 64: C6138D514FFA2135BFCE0ED0B8FAC65669917EC7 65: 69BD728AD6E13CD76FF19751FDE427B00E395746 66: CE705B7C60D46E7E36FE073DB8822698579CA410 67: C717EBBF6A2BF1BB33DA6257352D5085BEE218B3 68: 86151D140AAFC9A4B5877D3FBB49014FE5906E57 69: 7446B5A6BBCC58BC9662451A0A747D7D031F9A7D 70: C24887924F92ADAC5AE367995D12691C662B7362 71: 5AF83CFD42D61967778889CA911CFB6C14339BA7 72: 587D4F6E6B4E21343423E434679009CBD3D24DCF 73: AC65DD946C5CC432D4D624CAEB53C7363F96B7AF 74: FA71E70750674C0F6B4AA19D0BE717B2936C83FD 75: C9EFE6DD0A019315F73F3962DE38B6C848A1705B 76: D1D05649B952C8F6EB016BE08FE1544AAC5D5925 77: CC3081AC1D695BAE51CFD5B44B9FB3A230733CC3 78: EB9DE332558953792687D9A7F598B5D84BF0A46B 79: 39DE5EFDC92E3D3678F24D2CF545BA4D172D003D 80: 399DBC9F721E44A992A0DEF42D999B32AF449ADC 81: 996A2817C8ACBC667E1C4C27B8F4E9952736DD7A 82: 3EF8189CE1BCC0D65AA182B1A81534635EDFDF2B 83: D676714C6A6FF4E17A60C0511C25AA8B164FA606 84: 4DB6E3381E1B9290267C1539E1053793C8B81FA1 85: 3A34D35B0296FE4D83EDA39B742A9D8F4B13A958 86: 54F3B45304EF1287F54B877FCCE3285E154F9D6C 87: B1EA96216E025377AB5AA845238FC8BC65DD60E1 88: BC6C7488145485DEDE1AE1D43B594F0046BCDA0F 89: 3D9A0619ECF88C84CE86213E9AA91D9A252CBC32 90: 92CCAA0B4CE89E2BD80A61B9BAFD5AC58AB7B588 91: 3EB326B5BF4440FB3A88E3DCB05C1DB5EA01AC5C 92: 989C63E819B13D4CADFB33F8DEAFBC57C1992A12 93: AE944552C20CF16F07A5C357713832C9D72D0C6B 94: 46723E982569A1E2D9EDCED5498FC1F46F7D63FC 95: 3BC5DAE7907C83A0693F87FD8372EFDD1DF53E09 96: 96D281BA44EB21ECFB1663C8AC5752C48686A927 97: FA0EF18178880A72B51C26555C10F5210DAB4390 98: 0C7ECAC32B8ED6D9835D381BF069568722A276E1 99: 649E44ECBA85C0938EC09229CEE4BB69388EC642 100: 1E6634BFAEBC0348298105923D0F26E47AA33FF5 101: AF2AF2734BB2BAA288940CB62109F4849DAA347F 102: 22D14BC045CC9A3794C99BEEE7ABE278BF24D6D8 103: C3164CCBED75B82ED3F59F4A47FE09B256025549 104: C27B5BC7CD24DE4913614A769A442E9CC9FB0E08 105: F44D48D98CAC77522FF6B9E1B9CBB8489E58E588 106: EA19A71FFBEC9572F6CD65523ACAF865EC05AB52 107: CDA0EB9D310247BD1E8B3EA10D9B9DEFF6FBABA9 108: 449DFCE971B9D65D69FBC72940E9A885E8DDE9CE 109: 96EEBB6B95A9DA99C58190CBD77CD6FBCF638A79 110: 670F7A869E90CE86E0A18232A9D4B1F97C1C77D0 111: BC544E24573D592290FDAFF8ECF3F7F2B00CD483 112: E4CE142D09A84A8645338DD6535CBFAAF800D320 113: 1C26461E26EB697CCC36A98714EE70CAAA87A84E 114: 51C5B1C25A71FF00394A84AB48B5733C8955551E 115: 84803504181C0AE33A511C49AF5015A5B1892BFD 116: 7CC8BCA120C2635ABFEA82DD203112B5C7E165DA 117: 44E2519A529D7261F1BEBEDC8ED95E1182CAE0DC 118: 2A81372DA39C1DF4251539A9922717B7CF5F0334 119: 41C89D06001BAB4AB78736B44EFE7CE18CE6AE08 120: D3DBD653BD8597B7475321B60A36891278E6A04A 121: 3723F8AB857804F89F80970E9FC88CF8F890ADC2 122: D031C9FB7AF0A461241E539E10DB62ED28F7033B 123: E0B550438E794B65D89B9EE5C8F836AE737DECF0 124: FB3998281C31D1A8EEA2EA737AFFD0B4D6AB6AC2 125: 7A914D8B86A534581AA71EC61912BA3F5B478698 126: A271F71547442DEA7B2EDF65CD5FBD5C751710AA 127: 89D7312A903F65CD2B3E34A975E55DBEA9033353 128: E6434BC401F98603D7EDA504790C98C67385D535 Hash: sha224 0: D14A028C2A3A2BC9476102BB288234C415A2B01F828EA62AC5B3E42F 1: FFF9292B4201617BDC4D3053FCE02734166A683D7D858A7F5F59B073 2: 00AC60F30E9BD1956F914C8E5125B69DCC31A179734E6A85B3F702BA 3: E615202185AABE2ACA924BEC29E5A12384F8339EAE4E64C9CBA9F1DA 4: D70DA0705EAE42A5C596D92F331DDA2421B4E14F8B3035FB73B8B700 5: 98029CB458A39A16355963922D32DACD9439F90E9FD106D42A0D123C 6: 7D92E7F1CAD1818ED1D13AB41F04EBABFE1FEF6BB4CBEEBAC34C29BC 7: DDD5BABB1B05D8BCCD644ADC393A9E2303C850DA31922C4DA07574F9 8: 4C07070802E21052FB0295AC0571CAEDF219143ADAE0627E2850EDAA 9: 5D3CA3BFE738D33F841069ADF6DD79B987351CE580ACA23326B3A7E7 10: 6B5373C535A4FA5D56D6C4953575CE64968031BB019B909F8F2DB904 11: 767D0CDC11079BA8DCA276DF5C4B85507DE67DCE47EDA4CD9196D312 12: 02C513977B6242D2FAAC094CAE3C247C6E2745F8A71494A60535A2EA 13: 1F39482310E2209C10A88C7FD7FC1FD567F36789808C37D30045A82B 14: 55BA81EBA644183AB2460C234BB95ABDA898E980BA976584E2977231 15: 2522E2B35A835436C80A122E4676DE64690C81440D42DBDA40EF2151 16: 529D656A8BC413FEF58DA82E1BF0308DCFE0429DCD80687E69C94633 17: A153F81C68D9FFFD4DE0AB9111C2FA86E8EDCA9B294376083077A135 18: 1EC706AEB2227B263A105EDBE2562E0521C96420DA4558012327661B 19: 4904ADADF19D088911EE0EFD20A9AB511F2786C8FD43F1E5E8BE2AC6 20: 6CE245C296289A32F661986FF1C80E893BBD35EB0B182EDC14AB3A7D 21: 33831C459A43CBF8BEB6DD50039750F1EA3688A7EAEF68CB2F095E16 22: EB4BC2EA1F7146E8274A96E874585C401256FB921FFC7E935DDC7FFF 23: 09A266C98019B6B2A4318FBEDBEA5481AF01F0AD2AD16F09991A3C3A 24: 7AF2814CD6105473EE530F2B3DAE992ABB6C801428F33430501F09A6 25: C5BD6127243049C4D5E9E3B391E12BDA86DC7A9856910A757004486F 26: FCA06DDE2DCD212E6C1C11BB22B18B4F5582202655DFB9B6C9960C57 27: 0851998120F8CE47482DA5B2EB21BADF73C9F145921EEFD33459D49F 28: ED36A2092538C5D4769917953E7355A13072DDAD8A6E5E2AF1DE96F6 29: 2C4A89C05BFD09B7068BAFDA37B0314EFCE02AFAE1B2C25DCE337326 30: 1D552A4D06BB8A0827BFE8DA2B6EE56ADBD17CE4810908D572076F6E 31: 997D180912E0655445B07259278AAAD424633F5FF6BD0AFECD4F15DA 32: 71446EA93381BA091F94AFCDC5B938323290A1A027C22A75E88A04D0 33: F77087D6F4AE34E88C62597CEC06220F4C694D2E0EB704820035AE6A 34: 64EE78B0A6C116380A4C16F24489C1E94A578E558453537A9819A2E6 35: F39C1C862FDC9AB4ACFA50FE283CB7595C608F8C521BB7898CF71D34 36: DB482A26C9488A963359D145914612E34B821CC6CDC11113B73BDE2F 37: C7C45F3AA5EEDE664D6CCD510F628D4DC3C67F93973FE05B0163CA13 38: 7F230E3E597845DB9F8D61B44740968FF55F2DF28CA538A68927F130 39: EA52362A9C66B6A5FF3B642FCFEBBF54F793B088D29E6840D7A5CF56 40: 84B064EF9C13F1ED54AD0B8FC0CC28F9BCE5009500E1CD92CA2BAE04 41: A2702281BD63CA745553CB18693DD70AC9A70CD73C01783727707C97 42: 89231FCFFC7022DF20B1846285FAACE44AFCC677685DA55EE02D94EA 43: 4C5B01C50907D097DDBF0923B885A26B58DFF5761C1AEDFB8D5353F5 44: 84E0CF33A7E1C0EAA46F37E99CE5C8B292E81AD61318796D1A9A90C3 45: 27E59A0B6E7B9125D4CAA658810AE5054CE40A9A0A0FFE6E36435EBC 46: C7F21E2B4C89B2A6E64D92F93FC4146EB5886503C1231EE6924B4E13 47: 653CAFF50E077A855992990F0C5F89C75FA18D1CC147F685AF2EA993 48: 6A7BDEA7E456D5339B7D9C244E246AD65B18BA95E0518E201AAA7889 49: 837ADE7F298F8159E6E2408751B0C480648CB6FD6D26C551983F3176 50: BEEF3F6AC40A9DED345BE41242BB2CF924B457A45CACC68379B1DC4A 51: 6D2908EB3B6C8952346E0B65B9406D949B5A340123DB83B151DF5F81 52: 9E75A1D6B4A4D1A9F5AA6F8A48AFD6F3FD360D2D8723B53DBB63208E 53: 436E3BFE94A39359CDF47D35395D34C0435018C88B4E96E68C22645A 54: C209DF2E99E03D679FBA9E14AAF958AC1B0A22076BB3B532A0D7F092 55: 8991DFBA74284E04DC7581C7C3E4068FF6CB7A63733361429834BB56 56: 2B2CD637C16AD7290BB067AD7D8FD04E204FA43A84366AFC7130F4EF 57: E87F5BC938C3B981C197D4B163C635A5049FAC81C4C6467E1251BE48 58: FD9BDAF5CC288A603D1623651D5BA3B8801D1602B0B9221C0B48435D 59: 87F207D9D870EDD7DA61753473A51FC386E2792A3861F949BEA05CFE 60: C9EFF79F4412CE49296C082DC777118F92C9AC4136D4EB32621E942C 61: DDBC76D25D9819693F3597D6F09044F8D6CCBD12F081156F1090AF7D 62: 6411AD13AA3654302BAC8E2BFD1CE76F37E3B3394014BBE260062CFC 63: 049E8DD7EAB3378CE9F823BFB569E5B270235D4B7F9623606971998F 64: C37B88A3522DBF7AC30D1C68EA397AC11D4773571AED01DDAB73531E 65: 114B5FD665736A96585C5D5837D35250AED73C725252CBF7F8B121F6 66: 7D9B844CAAC9EC93AE2159ED3D336C55396216DAC6AC5DC5DECC11C9 67: E1C799109DEEA117F68DD1826B38B514E1D265F11A8B60B24630FF8E 68: 029A0D024B6C0B63E1586F3D34111727E37D49CA12E7F520FA91A926 69: 2EA94F04A72C770A98E2A495D886EE674B7D0FB987B7B5C2217A8773 70: FAF445688FFCA34ED783F948B8F74578503D4845836CAF69DBD5EB51 71: 91EC59AC7C98F9DFB869E11C80027F8A4D311324597E6FC6135224D3 72: 190DFC9C7BDD954E415E543F99B00B5110ED6A12182BFFDCAA77D8B9 73: 8C3AA805FA75625476F3267C211B1DDA52E1810B058EF804E34BEE58 74: BFD0E517E4A340A4E0EF1AC306EE2C6DD1288C77531EF0FD5ACB73FA 75: C621A18D7E09976296CBC39761B020E7E346042FC735FDF106148F3F 76: 27EE5F7E3FE49EAEC0AE0A93FD971EDF0304A4C0513BCF43424C95A2 77: BD9D42F293DA572219F08D4A38081D203E44F612EEDEF93CE0DAF6D4 78: 374CFB6FB12768717EFED2681718C11B22588C429DB9C71AFB5EB562 79: 1CFB1037FC3943559E9F913183DB71392CD4BC68CDFD47D7DEC9C9AD 80: 2537E015D5945E0541BC48320AE4DFF7FEAB911227AE0D579DA1CD05 81: 012B34E1A530B6889E87863A59645EE4FFEB292A33815D2CE11918EA 82: 5242DD4DFEE389E668D8FF78DA9B2D85AAE12D0C220E8D1BADBBA845 83: 4813D70E1D6BB6232CD9257B5132FDBA05E1A4A858E237C303CFA052 84: 0530BBA43AE6393655F21F7EEA67F8E8E819BA225AED78CA8BDE075F 85: 4F7EAF4A9D0000B0E957DFE46DB304EBB2664A32AF4142EC74BE18D8 86: 68CF23B9DC4DC3430835B484648CBF126940AF6BAE51431A66D7F0E6 87: A093D2119C7076259F194F107077061C61C792DC5326C3A4D3A63BA6 88: F4E883F7FD12ACD36E3891986E4D7FF03F3E150F09CD4FB58A023A04 89: 0816862C59CE35E0D78834A221D3BABE21987FDAA81F20ED61D9DA84 90: F415933677BB364C589722E30B958F2BEF8670A10F1F5082F79FDB4F 91: E40C5632490BB8DAD2283B6DBDCA870F4B5AB4271C61127DE999BDF0 92: B2D4E6CD7AFC35A475620EA1446B9024D767890B8593AB50275F370D 93: 948616FD7828F09E8A57F986589948085D18EC3550E0ADA8E0127665 94: 2B115E930333A355A82F074EF261DE6BB2942D9DD64F98BA12D92DDE 95: 6EEAB864B5AD618CDB1AE79C7B1DE31020966A02350AEF71088E6876 96: 676AD81F213E037F3C9BA2310F49DDDA4D6476C28A8EFC0046D3F55C 97: 03A28C9068BC10A6FD87A1E53F00415F8CE994C968DD9CFF60D6B0A2 98: 01D91D084F400C591EDD750B66EC2482C834CE0E140A37E6E142CFEC 99: BCAD899E7C771764CB91FF60AD79BFD629F4803A05FCBCC24E8F3E79 100: 6E08215B5470DDEB67E44A494E52E259A9C2C4FBED4AF5DC6DB3E92A 101: E5C45BED6F8BFC487FF7190B108AF5C5B66F6D55D365B5A1BA156914 102: 0DB55D83B38D42D229CA42D001B09758B5F3F032109F2F999C553655 103: AD4DF1AF973A2747568A1B8DEF15E34A350A93F45BA84596580D11F0 104: D4905849C8C4EA32159A431B52BAAC092F90037093E200A0C46611F9 105: A936D0AA091B827BAD86644C94603068AB34A5B59E29D1E3BAB13039 106: 46D214E9FA8C877C2791CC8E6716868713CB5B677CC4D838242C9B18 107: AE8D3EB227AA3558101D5E5A2BF6C862C9F7297A31A3DF24E4502257 108: 4462C366B10326D4FEF46E71930BCF93713F7D45FAC9963520FF5FE8 109: 05EFC35781E413ECBCC763AE13D5A37C159CE5CCEE6EAA1CFF7CA516 110: CDDBA09D7FE081E7A39C4017B3EDF7A9138D1CB857559BA9AD2C939E 111: 1AEEF583C448A9AE00FBC931B50BC0DA5BB8323E616B11076CEE8B44 112: 01E5ABF50619B5C2078E754EDDEDCF4DE8D31185A2219313CB91A8C9 113: B7FF114CA77757CAD67801E6761AF20F4CBB8328AEF290F77EB612C3 114: 08F43DF4547732424AC7D0390AD8AB3D4978826462446D13B2B468D6 115: AC3799ED09E3BD9E770FD3A0073E371FE9A3D4E3D464C3A7023CC72D 116: 795F160C275FF6B575031D4053BA1D1C32744D09F005B3BF10BDD1F7 117: D2EFD4AC8ABA33151D0399E2893769A6D8BBFBA7B128388BFA65B841 118: F85910F64FEE2B8F91DEC8064F75CB97E1FFC895AEE912DD3945F839 119: 762F18C0DF65C3D0EA64126C8A6E51DB4425E76D4D969ED0F83899BE 120: D022DEB78772A77E8B91D68F90CA1F636E8FE047AE219434CED18EEF 121: A802D8B618A503352CDBCC1FBEF04EA36499EA72D0E32D314CAF83E5 122: 6DE1088DD95C9535849294A8635A44084BA36E4EEF81C6D67B98CE90 123: 6AA11591302A30EFACF874F40AA017F8545D3D9EA68D479965AC0B3E 124: 3288A475A4817D2E42830C709C1DC18A4BBD59DBD903B43CA702F275 125: CCEEE7F6EFA60B2F2CE1090FB929D6068F7EE301E7A84072FD163F7E 126: A45B0FCFAC3F05279B7E8278AED93E37B225E6A997664F92C7555447 127: 554C9C3F7E92B80F4121E00CC147535D377EAEB4FB1FA8E25C7F81C1 128: 67D88DA33FD632D8742424791DFACE672FF59D597FE38B3F2A998386 Hash: sha256 0: E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855 1: 6E340B9CFFB37A989CA544E6BB780A2C78901D3FB33738768511A30617AFA01D 2: B413F47D13EE2FE6C845B2EE141AF81DE858DF4EC549A58B7970BB96645BC8D2 3: AE4B3280E56E2FAF83F414A6E3DABE9D5FBE18976544C05FED121ACCB85B53FC 4: 054EDEC1D0211F624FED0CBCA9D4F9400B0E491C43742AF2C5B0ABEBF0C990D8 5: 08BB5E5D6EAAC1049EDE0893D30ED022B1A4D9B5B48DB414871F51C9CB35283D 6: 17E88DB187AFD62C16E5DEBF3E6527CD006BC012BC90B51A810CD80C2D511F43 7: 57355AC3303C148F11AEF7CB179456B9232CDE33A818DFDA2C2FCB9325749A6B 8: 8A851FF82EE7048AD09EC3847F1DDF44944104D2CBD17EF4E3DB22C6785A0D45 9: F8348E0B1DF00833CBBBD08F07ABDECC10C0EFB78829D7828C62A7F36D0CC549 10: 1F825AA2F0020EF7CF91DFA30DA4668D791C5D4824FC8E41354B89EC05795AB3 11: 78A6273103D17C39A0B6126E226CEC70E33337F4BC6A38067401B54A33E78EAD 12: FFF3A9BCDD37363D703C1C4F9512533686157868F0D4F16A0F02D0F1DA24F9A2 13: 86EBA947D50C2C01570FE1BB5CA552958DABBDBB59B0657F0F26E21FF011E5C7 14: AB107F1BD632D3C3F5C724A99D024F7FAA033F33C07696384B604BFE78AC352D 15: 7071FC3188FDE7E7E500D4768F1784BEDE1A22E991648DCAB9DC3219ACFF1D4C 16: BE45CB2605BF36BEBDE684841A28F0FD43C69850A3DCE5FEDBA69928EE3A8991 17: 3E5718FEA51A8F3F5BACA61C77AFAB473C1810F8B9DB330273B4011CE92C787E 18: 7A096CC12702BCFA647EE070D4F3BA4C2D1D715B484B55B825D0EDBA6545803B 19: 5F9A753613D87B8A17302373C4AEE56FAA310D3B24B6AE1862D673AA22E1790F 20: E7AEBF577F60412F0312D442C70A1FA6148C090BF5BAB404CAEC29482AE779E8 21: 75AEE9DCC9FBE7DDC9394F5BC5D38D9F5AD361F0520F7CEAB59616E38F5950B5 22: 22CB4DF00CDDD6067AD5CFA2BBA9857F21A06843E1A6E39AD1A68CB9A45AB8B7 23: F6A954A68555187D88CD9A026940D15AB2A7E24C7517D21CEEB028E93C96F318 24: 1D64ADD2A6388367C9BC2D1F1B384B069A6EF382CDAAA89771DD103E28613A25 25: B729CE724D9A48D3884DBFCBEE1D3793D922B29FA9D639E7290AF4978263772B 26: B858DA80D8A57DC546905FD147612EBDDD3C9188620405D058F9EE5AB1E6BC52 27: D78750726155A89C9131D0ECF2704B973B8710865BF9E831845DE4F2DCBC19DA 28: DC27F8E8EE2D08A2BCCBB2DBD6C8E07FFBA194101FC3458C34DED55F72C0971A 29: D09BEA65DFF48928A14B79741DE3274B646F55AC898B71A66FA3EAE2D9FACD77 30: F2192584B67DA35DFC26F743E5F53BB0376046F899DC6DABD5E7B541AE86C32F 31: 4F23C2CA8C5C962E50CD31E221BFB6D0ADCA19111DCA8E0C62598FF146DD19C4 32: 630DCD2966C4336691125448BBB25B4FF412A49C732DB2C8ABC1B8581BD710DD 33: 5D8FCFEFA9AEEB711FB8ED1E4B7D5C8A9BAFA46E8E76E68AA18ADCE5A10DF6AB 34: 14CDBF171499F86BD18B262243D669067EFBDBB5431A48289CF02F2B5448B3D4 35: F12DD12340CB84E4D0D9958D62BE7C59BB8F7243A7420FD043177AC542A26AAA 36: 5D7E2D9B1DCBC85E7C890036A2CF2F9FE7B66554F2DF08CEC6AA9C0A25C99C21 37: F4D285F47A1E4959A445EA6528E5DF3EFAB041FA15AAD94DB1E2600B3F395518 38: A2FD0E15D72C9D18F383E40016F9DDC706673C54252084285AAA47A812552577 39: 4ABA23AEA5E2A91B7807CF3026CDD10A1C38533CE55332683D4CCB88456E0703 40: 5FAA4EEC3611556812C2D74B437C8C49ADD3F910F10063D801441F7D75CD5E3B 41: 753629A6117F5A25D338DFF10F4DD3D07E63EECC2EAF8EABE773F6399706FE67 42: 40A1ED73B46030C8D7E88682078C5AB1AE5A2E524E066E8C8743C484DE0E21E5 43: C033843682818C475E187D260D5E2EDF0469862DFA3BB0C116F6816A29EDBF60 44: 17619EC4250EF65F083E2314EF30AF796B6F1198D0FDDFBB0F272930BF9BB991 45: A8E960C769A9508D098451E3D74DD5A2AC6C861EB0341AE94E9FC273597278C9 46: 8EBFEB2E3A159E9F39AD7CC040E6678DADE70D4F59A67D529FA76AF301AB2946 47: EF8A7781A95C32FA02EBF511EDA3DC6E273BE59CB0F9E20A4F84D54F41427791 48: 4DBDC2B2B62CB00749785BC84202236DBC3777D74660611B8E58812F0CFDE6C3 49: 7509FE148E2C426ED16C990F22FE8116905C82C561756E723F63223ACE0E147E 50: A622E13829E488422EE72A5FC92CB11D25C3D0F185A1384B8138DF5074C983BF 51: 3309847CEE454B4F99DCFE8FDC5511A7BA168CE0B6E5684EF73F9030D009B8B5 52: C4C6540A15FC140A784056FE6D9E13566FB614ECB2D9AC0331E264C386442ACD 53: 90962CC12AE9CDAE32D7C33C4B93194B11FAC835942EE41B98770C6141C66795 54: 675F28ACC0B90A72D1C3A570FE83AC565555DB358CF01826DC8EEFB2BF7CA0F3 55: 463EB28E72F82E0A96C0A4CC53690C571281131F672AA229E0D45AE59B598B59 56: DA2AE4D6B36748F2A318F23E7AB1DFDF45ACDC9D049BD80E59DE82A60895F562 57: 2FE741AF801CC238602AC0EC6A7B0C3A8A87C7FC7D7F02A3FE03D1C12EAC4D8F 58: E03B18640C635B338A92B82CCE4FF072F9F1ABA9AC5261EE1340F592F35C0499 59: BD2DE8F5DD15C73F68DFD26A614080C2E323B2B51B1B5ED9D7933E535D223BDA 60: 0DDDE28E40838EF6F9853E887F597D6ADB5F40EB35D5763C52E1E64D8BA3BFFF 61: 4B5C2783C91CECCB7C839213BCBB6A902D7FE8C2EC866877A51F433EA17F3E85 62: C89DA82CBCD76DDF220E4E9091019B9866FFDA72BEE30DE1EFFE6C99701A2221 63: 29AF2686FD53374A36B0846694CC342177E428D1647515F078784D69CDB9E488 64: FDEAB9ACF3710362BD2658CDC9A29E8F9C757FCF9811603A8C447CD1D9151108 65: 4BFD2C8B6F1EEC7A2AFEB48B934EE4B2694182027E6D0FC075074F2FABB31781 66: B6DFD259F6E0D07DEB658A88148F8253F9BBBB74DDD6DB3EDBE159A56BC35073 67: 8FA5913B62847D42BB4B464E00A72C612D2AB0DF2AF0B9A96AF8D323FA509077 68: 7DED979C0153EBB9EF28A15A314D0B27B41C4F8EED700B54974B48EB3ECAF91C 69: 1CF3AA651DCF35DBFE296E770AD7EBC4E00BCCCD0224DB296183DC952D0008C9 70: 5767D69A906D4860DB9079EB7E90AB4A543E5CB032FCE846554AEF6CEB600E1D 71: 8189E3D54767D51E8D1942659A9E2905F9EC3AE72860C16A66E75B8CC9BD2087 72: 107DE2BC788E11029F7851F8E1B0B5AFB4E34379C709FC840689EBD3D1F51B5B 73: 169F6F093A9BE82FEBE1A6A4471425697EC25D5040B472C5B1822AEEA2625988 74: 2087EBD358AE3EA2A092FC19C2DFEE57C5F0860296BC7B057C14E1227C5CB9D1 75: 182AB56F7739E43CEE0B9BA1E92C4B2A81B088705516A5243910159744F21BE9 76: 081F6C68899A48A1BE455A55416104921D2FE4BDAE696F4B72F9D9626A47915E 77: 5CE02376CC256861B78F87E34783814BA1AEC6D09AB500D579ED8EE95C8AFCC8 78: B93E407404E3E95F20FD647365E0E7F46AFABE9AF1FF083AF996135E00D54009 79: E81FA832B37BE8ED8F79DA29987AA4D61310DCB14B2859DEDF8FB1DAA2541FD3 80: C56705FEA5B110B8DC63688533CED21167E628017387C885423B835A55EDD5EF 81: C2226285D08A245A17058ED2D24AD095B714F608AE364FDDF119E0A7DF890540 82: F9C270DA8793221A6809AC685FDD4F5387E0FE1EE6AAF01C74F1E0A719621614 83: E69BEFD6EF7F685C36E343AC1702D87AD6A0E4AC8C0D5C521D04AAD4EF0B7458 84: 4E3033562AD74A7D43EB5FF5FC2382622C6307CB10E245AD62DA77C4C63CB178 85: 2EA17629472564A59E5EB845A2CDD04F442DF2FF26BCC866E400F77158D612A1 86: B90223DF74DD49A8A1461F340F2D7A90F96903CCBB5BC3C74EA3658FC8948B20 87: E0209F42B927EC9C0F6D6A76007ED540E9BDD6E427B3368A1EA6C5E7565972DD 88: 10D9BD424114319C0999ADF6288F74060CD8918EF1228827A6269B2BF0F0880C 89: 7D1978A65AC94DBBCDC62E3D81850299FE157DD9B7BD9E01B170156210D2815A 90: E052DFF9E1C94AAA49556F86FAD55029A4875839FDA57F5005F4C4403876B256 91: 58D29459B2130A2E151252D408B95E6DAC424C564062EB911CC76440CB926CA0 92: 4E4530C392316F598E1BD07F32166380A8F712A33A48E9EB4247131EC5DC05D3 93: A09C9D3E42342C7DEA44EDB4AEB48CF6727CACD8032A12CF77A25829FC249D32 94: EB978D0F1AC03CE5C3510B5F4A16073A7A2BDC15C4AB7777DCF01030CC316667 95: 7D1905A3ACE827EA1AC51C4FA08C281ED3BE87E7F4E928D696BFDE35C8F2DC0F 96: 08359B108FA567F5DCF319FA3434DA6ABBC1D595F426372666447F09CC5A87DC 97: A7B3830FFAB0F2BBABBEF6DF0B169A7917008BF238880BBF8C20B8E000077312 98: B4F5D9B1555994C5EBAEBD82918D560A3BF82962A171A1614E7551939E943366 99: 014ECAEA1B378900F1212898C6DDB01565D81AF1D0EF78DF5E28D46E9CAF7CFC 100: BCE0AFF19CF5AA6A7469A30D61D04E4376E4BBF6381052EE9E7F33925C954D52 101: 4565D7B898CCEA3139AD260F9273115F806B30079D7683218C4E3ECD43AF3B33 102: DDADEB660FE8902C9FB2DB9B6CF237C9CE5B31753398085C4367EB5910B9CC13 103: C15A8928131F6687DD10F3C115DDF8D7C8F2DF7E18D12C08C4FD16F666CE60BA 104: AE8E3D799B1353A39815F90ECEEBEFA265CC448FE39FAF2008CB20784CB2DF9F 105: 98545371A3D9981ABE5AB4A32A1D7B2FADD9801D89DA52A94A4F78A42740D21C 106: 6323DCE2F8B3A04DCEA8D205602348C40403CB200C677EB1A1C0FE37EDB6EB2F 107: 8150F7C5DA910D709FF02DDF85DD293C6A2672633DE8CDA30F2E0AA58B14B0C4 108: 44D21DB70716BD7644CB0D819FA6791805EBC526EA32996A60E41DC753FCFAFC 109: B9B7C375CCA45DB19466EBD0FE7C9E147948CC42C1C90F0579728CFB2651956D 110: A47A551B01E55AAAA015531A4FA26A666F1EBD4BA4573898DE712B8B5E0CA7E9 111: 60780E9451BDC43CF4530FFC95CBB0C4EB24DAE2C39F55F334D679E076C08065 112: 09373F127D34E61DBBAA8BC4499C87074F2DDB10E1B465F506D7D70A15011979 113: 13AAA9B5FB739CDB0E2AF99D9AC0A409390ADC4D1CB9B41F1EF94F8552060E92 114: 5B0A32F1219524F5D72B00BA1A1B1C09A05FF10C83BB7A86042E42988F2AFC06 115: 32796A0A246EA67EB785EDA2E045192B9D6E40B9FE2047B21EF0CEE929039651 116: DA9AB8930992A9F65ECCEC4C310882CAB428A708E6C899181046A8C73AF00855 117: 9C94557382C966753C8CAB0957EAEDBE1D737B5FCB35C56C220DDD36F8A2D351 118: D32AB00929CB935B79D44E74C5A745DB460FF794DEA3B79BE40C1CC5CF5388EF 119: DA18797ED7C3A777F0847F429724A2D8CD5138E6ED2895C3FA1A6D39D18F7EC6 120: F52B23DB1FBB6DED89EF42A23CE0C8922C45F25C50B568A93BF1C075420BBB7C 121: 335A461692B30BBA1D647CC71604E88E676C90E4C22455D0B8C83F4BD7C8AC9B 122: 3D08C4D7BDDA7EC922B0741DF357DE46E7BD102F9AB7A5C67624AB58DA6D9D75 123: CC63BE92E3A900CD067DA89473B61B40579B54EF54F8305C2FFCC893743792E9 124: 865447FC4FAE01471F2FC973BFB448DE00217521EF02E3214D5177EA89C3EF31 125: 3DAA582F9563601E290F3CD6D304BFF7E25A9EE42A34FFBAC5CF2BF40134E0D4 126: 5DDA7CB7C2282A55676F8AD5C448092F4A9EBD65338B07ED224FCD7B6C73F5EF 127: 92CA0FA6651EE2F97B884B7246A562FA71250FEDEFE5EBF270D31C546BFEA976 128: 471FB943AA23C511F6F72F8D1652D9C880CFA392AD80503120547703E56A2BE5 Hash: sha384 0: 38B060A751AC96384CD9327EB1B1E36A21FDB71114BE07434C0CC7BF63F6E1DA274EDEBFE76F65FBD51AD2F14898B95B 1: BEC021B4F368E3069134E012C2B4307083D3A9BDD206E24E5F0D86E13D6636655933EC2B413465966817A9C208A11717 2: 5D13BB39A64C4EE16E0E8D2E1C13EC4731FF1AC69652C072D0CDC355EB9E0EC41B08AEF3DD6FE0541E9FA9E3DCC80F7B 3: 4F895854C1A4FC5AA2E0456EAF8D0ECAA70C196BD901153861D76B8FA3CD95CEEA29EAB6A279F8B08437703CE0B4B91A 4: 80AE432E757826025095CA1FA4F89C06C8BA6754B1D883A8E31A1E65FCFB820BD74ACFACA3D939A574EA408A74162D1D 5: 561C16404A1B592406301780C0C2DF6AA0555F504F35BFBEAC810AE36A343B776858C5E0DE56BB79607A34D2F67108F2 6: 79F4738706FCE9650AC60266675C3CD07298B09923850D525604D040E6E448ADC7DC22780D7E1B95BFEAA86A678E4552 7: E6CE1896C9783A70AC4C90276CC37B37687D7E30C753975762F961AE37118D9A610242716E8359EFC4975AA98C632DCF 8: CFB18F81F4BB672B03214F1FEDE456F882A0DE40120212A1FEBA8FDC48F763C86ACBBFB684D34B70F99F4D8D81FE3A28 9: D075AE1178210804635AC02C656309311527FC8190835C8AD8196577C3332AF4D87F056023F235DB893C69AA87B0CFB9 10: 182E95266ADFF49059E706C61483478FE0688150C8D08B95FAB5CFDE961F12D903AAF44104AF4CE72BA6A4BF20302B2E 11: 89BFCF569AE4AF718510DA78C67414109F5739BB5C40D51C9C8C50E2B2CEE86F2F80C8B9D68F7C01201A0714572FE602 12: B635441A3721CF190B39D23703C5B77018FF1A56C94F8252EE95C217E3477F093E8EC65C6AE767179A7872C8DB9B2141 13: 48DEBF56626CC86DFA47AD6FDEC73FD182434621DA8BC6DB23AFF067BC36DC8244D3071B1F57DE4B716F63D9820DFB23 14: 58475B7CF93FECCB2C02B588F1552A359E7EE9AC45D9AE50B2D7C22021466677D70EF24EFA5C492515164458E9A24744 15: 0AA75534F0F58756A01E3366F78E7611BC7F432364C649C3F50547F7BCA3E5489531B8AB129495FEAC834FF0A0B45DB6 16: C81DF98D9E6DE9B858A1E6EBA0F1A3A399D98C441E67E1062601806485BB89125EFD54CC78DF5FBCEABC93CD7C7BA13B 17: FDD3C4C0F87EEC0CADD73028A06B01E67696C7E04960936B30C73F004CF6B595D644533F8B473C8E63B02D593A64B041 18: 445E4CCA1A03480D149F38014C14D28DF8288F2C6CFF047F45D4F2580AE85EFFB3BE009C9D2ACC54B51467F83A09FBE2 19: 8305DC56172245B82AEDCE7F9C7DC88C0E62CBF835A2AA133EB579F415FFD15BABBC30BB98E55DFDA0F9E80275C92BC4 20: 8A48240E1C85E80651EDDC88599273444839A952CACA2BEF4400576E65B1EB6C19C47A3067B63AF7CDC4238ADB9A8DAD 21: 8F2F7669C27A7CB1CF7A84A2C4F050D7141852D8B429291956B85E2DB5287741A3104E7E99CA5D23A5EEA59A68A4DDB1 22: 32CF04AE2A4A326FDE2FBB887F47FB7A2C486E56088D85B45F0C7587591F44797FE0A67E36F571809695E05F254884B2 23: 713A04A3A6BA8D2FD821F1CDF9FACAF42795E4247C9A26F0ADC5E0E6AACBAFFD8F4E02563733C6BDF1A863A787949B35 24: 35D8A5AA0DC9AB4C9A4C62B36E0E1013977C198B05CF6B92CEA25C08309DAFD282AA9A4862958593C06BA46919EA8019 25: D3FB60C2E981A5C82F1B1BCB3D4D7AF62C9A32A9F0D87E0532C9D3AAC083D70133EFF63A1E2CCB87360BF032C25FE9E1 26: B119F9AC74E58BD081E24C0CC1E090012C192996EED67A8ECA33794FE7E1920E26C0EFAEB866EB5AB82FCA3188A3B05A 27: 5B29543AB0F76F246B7FDE6E8E5D3DF6017A39342BB08351A4EF609AE00A91ACB7C5D0487B3760B34CEF326F63C84572 28: F8E1FAA657BF829C9D2E4811805238CCCD11F0C1AB7619058241BA5606E7BD5E4816163E6E8E82E62A43CB4943A41006 29: 0855B919786B5E5C87B85A6C17A46C550B2BA81B3724389088E2B54BA89D82B8F9841FF442DA5DB8D54C9B2AC108DC3C 30: 7DEF8CAB7C80CEF90FB38989ABEF6F1A5EC18379681E484A1B4DB6624818D2E486FB9C245C1F0DDD85A846D4268344B1 31: 04AAA180C2CD24F0FB150B1AA360F445344150DCA13E1ABB8117D42E25DF7FE29246D9F00C7473D20CEC32A71E64E1F5 32: E7112491FAEEFD57786DA73F367B25A6F5769F5C98FA7B704D8D37747724A647371989E8B0FE8D3CB23F9EEDD528456B 33: EA27126D0B96E00E428943EA94F4B03FD22D56C4FF4636EED139D027E6D45EF57AB86093A7342B3B3851FD3BFD1DDA23 34: B2BD337A4BDD48D25A5E3FCE3E0948EC67829B835A8E3DD0D9F4881D10C766369B079028C6060B7263603288D8FA4BBA 35: A9E940504AE6B137BB1BC88CE3A9AE53DCB63AFDFE5FA0C652003A921F582C08662425C7FBD5B1E1422E39E645D4A757 36: F033150D7464D49A076C7D4BB9E2A5488132786CB4851A4C81DA5B0FCE66D775D3C1766094AD6CA9482DD9539F28ED9A 37: E64D999E7258ABBB4CFF6F74AF7D6A1E9B044C17E1ACE0FC61B29E7732763755A9C1D3A380B080AD968D2228DB731DE7 38: 9030D47B57ABEA93B51162556FF352DA61FDF501132A9FD94E6CB56690E7A805CDB290FB4ADE36BF90A53F20922C9B6E 39: 4473396BB0461EDB4712880810A3F7252725AD4FD6092021A40559F453A1C63ACFFA8A02C85CC8DB86560323DA0A0FD9 40: 095FDD130278B3C8F574D17283611E4D6199EA63A0F1599E01ED070CD0B115296FE353477582BF279D622355C89A23E4 41: 7EE600CEE8437531C6A5BEC313D53371F9B56425D5662C104624D83D51111E5C9F4B83000B8A3EF150E04AEDCF67C237 42: 676D2BD2500BC527DCB51968FE8742E40D2965047478E69155AAB9201E0C9B0F6BA9BE85C4734B0DD556B5FA7608BE83 43: 09F5FE433D1FB8F62A76E5654B54CB6A9EF505D2465A49DCB9669EAC9A30B2532505E4500F842EC9FBE79A382C8C2F4D 44: 075821CA8C547E66AD94F4C4ADF866A2A7554E08D2B0F0B3576801773EDC85DF76107E6912904E9757EBA753A77CD0FF 45: 2172C22E7E48BD0B4A73FF02803D6FCE776CECBD95DFC43CA0763A0B375D57030000B12E59F9CDE81DE58E17489B2C41 46: B9A15689BA4F41BE46855775B46A5DB9D6826E0CBDBC3B292DA6D57B2A179A3D393A8E1B55DE79438E5221580C604EAD 47: EBFA57C946831E2E370A6B1BE46E27C95C512297499B8BD15722622178E00599DEEADD48F1B4B08EB649A137805CB786 48: 25866C8288F9FA319FA9AA2470B4FC2595DFFA9154E607444EA3247E81D74A2AE0957D6B7E050F8C96AA7577BEDCABB5 49: 3D28682B90022C873CEC78C3A47FD45B5124E49ED07E2F0FB41A112A63AACC9E7614ADBB007D129C0673B08C51210839 50: F76D9B7ED868085905AE806CFC5C6DE994999E379922AC003D53F00B65467AACEF3929392F1F2F56C621D2F552544A22 51: 324951FA2432B63D1765C21F98325BC4AE2FFB25F411047C53ED5A3D550B50E2B8F6E79BBE65F2C686A5132E5B982AC7 52: 320CB033AD533AF8EDB3E664E34BB85B2327AFCFC583CE9202C0B11F16425A58FD895D7435E8953F9506A25DE7BE6EF3 53: 6065D55530ED8339B09D7A4D9CB1919004F69ED9D6B119E78E1C39C7AD2AAC029A3F266F7E48350966B845C4D7D92A72 54: EB6E866BDC0B5089301D89B870B75056ABA6D5FA6C7406A8D6D97CE5175102479647D3F93325A2CB648A3F40CCE38542 55: DCEDB6B590EDB4EFA849C801E6B6490657A5C1E64F69269F5F63C9267F6223DE24CEA7AAA6B267D9BCECC15147B6C875 56: 7B9132D597B8873AD55BBC30F18ED3F2C9F340E7DE69FB5774056C71A06D9BC2B14137E9E1C68B6B645FED28B188249D 57: 0901B1E5B13FCE000486BDA64FBE45C79FCE15F38A4DDD9335A521D98829D267ABCCD84284BEF1EA3C2D4E4687C6D3B8 58: 4A9375DBAA878E2C1C7BFB977989E6D39CC00F890ADC425F7084AE3761BAEFCB9384C8B9EB3ADD4C3C838A6D560DF788 59: 908682C3E0D97A4943063EA9DD0A0F55EFCA203ACA3004010D3D7EF94593592729B523EAAE4160C3EA2241EBA236FD65 60: 24586F75A43A08D6CF116B87B86CC43300FC4132523CC4824B7FBB3F54A5B41C7D598B40639B25A99732D575A5CFD355 61: 7B4CFB73E247E941570E70C7308ACC5166F123187F003B1CAA9BCD17DDA8ED5535ACAE443C9ADE93C5567090EACE29AA 62: E97EF4578822DDC79AF60514A188F8C719E4133B58E5EB134261AA7E89C402EA7219129A06B395E5E1D2738AC23FC876 63: DD66B519F51A925814407A449C60B34C553D7652D41783EE903A810A4C9F833B8181C91C7F12283EACD6A5F8A2639DDF 64: 9F2C9EB7116B3D7A4BA84A74A4D4EFF8A5EFCF54B6D7B662693C38577914C73A214766F0A175339BB0895A863824FC0A 65: 14B0A9FFCE149426BF5045FFC24C057451D2473186DEB4F150117B855911A7641651FB1E15DF406EB373D71151C46F25 66: 286505FF7A9EF81224988A8FF1E423A2AD21F6B339E91B89F7F1540F14CC9A603952564539167465CA70FF0B523BECF9 67: 8CAB08A79BA16F3D7CBEB942C7D8676F8D0295B5FAA01F3C850DC4B5FE913AF00F2E938BE0B442187B135BEF1A36C34C 68: 4D12FFBCE2E770ECA1104BD2F29C65FE95534E390A138C30CB0ECB6436A971116D82C6321D2EA2C0A735AF34E5E3E3B2 69: F8617A35FE9116A719441F82F21C79B8868E5FFFC2EA737FDC821246DB7610E9868D870575F19B29F2FD259D9242A497 70: 932FC435B590B1E1D49C34EB3B627DAD5476216518250B1FBFE772476437872B8DA6CAF6D2F33CE7AF8648D956CF717F 71: 3F63DF48C2D87CEB2168BEFBF6B857A415D8BFB7062251E8E1AB0487483EEBDE5E8E8B8B0E3AD81ED4AB15E81FD5E448 72: 4A71E4E737DE74F78E72ECB9DDB580EA5AC96E5BBD5E52E11D4A41AB3B8303E3AF3458A8AD89B39CD9F4A6D5DB3C9E2A 73: CAC3A81A98103BBF08C440F6C8F61AC010DF8AC05FDA77E2ED8660AB73A978B9428BA0458A5C64DFCE35D87F0DAA2A6F 74: 6E5D162C60A451B6257781FA0E36B3BDD9BC42A7BCFEAEB75C18E541A4DE00967E6BF575CB32374C1E9FE7B36D92048B 75: 04DDFD71893D0F4AD2A0B672A057ED2795D6811AEAFDB7136BC8C20A55DABB3AE4B62B8A2C722C1F53E18FFA5771610F 76: 555D5B51C2EA17659516A67D31CE2CB302979F80BD7056908C1A152403FD902EAEBABDD066AB3F7834E7213A6CE99EEB 77: 44797CE4FEC66B26B52A4249C2B267AF891C912E55221EDB6CAFC4E2F022A40E8231931DF0B19321D5CCB2AB8A4F256A 78: 51D7AC85289FE7E4D9431414B2BF3760BE65FEDD1A0B34BED0E1562A73495EE10971B5141835DB454C865039154BEA15 79: 2E31DAE50A484B7E11E2E621D0552803791E07279752E09EDF4C884EF24C79C33D9572AE0DE6E0B6A20271F1F7AB98FF 80: DDC65ED22CAE4D159D35E129A1602D8FA50D7AA53E209B0D5442BB121DB0D5D102441054B2B321675F3722669FECD06E 81: 200E0BC495311E2FE524A1579490D843011A592E4E9B927DEB0727E5481898C557CB2941F18AF0F2725A1B19DE045BA5 82: 561E1875B31DEAEC4DB2FF5BFA7856A6F0ABE1294CDCCA1DA12CCB1786D9556881A768ABAE50F7243921ACF993AAF18C 83: F6B88007732D5B9F75209F9FE107B9917010D5960184FD239854AB4611CC788D1455B113A5565A87326B3CE6CA190DB8 84: B4E703169169B07AC61E76A75ED4AACEE4115F6A43842BF136B514824A05F5C5ADB68F2E525D8C9E8BDB20D3BCA21155 85: F72E2083B296EB7468C97749D3AA1B08F418EBCD9A2E5CB4117C5A034BBEA5E2004EE1E43E26A98E4F25AD4306AF3A57 86: B1DE9ED0D5E5F7FDCDF530041D7320CA7376A64590F6679971F84061C42AA03F0B07C7EBCB806EC8380D9FF0E182293F 87: 30ACC02AECEA9B91F3C6BB0F4CA8EEA1B84A0BA6BBB8F7749FD29C9BE5C5E28AFAE5A33617DFE3FC28CE3A78D1A19CDD 88: 5B2DABAF662B86DC4B1DF6A2EBDEB5CFF1F63C65ACE5E1237DB507DD3FA2C27FF46517B0FCD6F32F25DCD55ACDC07FA0 89: 33BE80B29355AB16AA0F05A45A8DC15A5EF7F9FEE60BCBE05E106BF6FA0F196BFD9CBB8D79298360F760DA7B05135F83 90: 048C648A525FAB61CF81E087047044130E407B71DDD27293119689C8516B19DDC4F276E3B4E93E6AB80A79BB2700DE68 91: BF18EA9E00E6C2262D802FB66E04FFA21DC5C13640BBF27B2C22592DE4AFE31C18147E6EBD2D45669C36F9432494A000 92: 0A1A114981A785C399E2B21871A532B2A747FC67B4DAA287C14F2F449FC6F7C6925DB5E884E6E041D08BF6BC69295124 93: AC6705C373300FCC09A291CFF1834401FC30FAD512569848A05171AA02426B7034EA2E4777AAC2DDFF48089226A4884C 94: B7B08352FF8988C0FFE3FE0E27278F068BDC88AECBA8D7ACD8919850D7400A2C0A0A8519B264F61102290C9AAAD3C2DD 95: 8F78C56A93B3DC69ECC5827F8D591195FB683A9951175754926A8E19F81FF859DC1904DE12BC8482A760E998552D28E6 96: E606004ECDC6878B5EC15F4554017CCF962E92CC6EAEBE4997BA34EC0E53C67D564C8461C013701A401FE347EC0F721E 97: AB7D7116F436ECB13ED2EC42347DDF902E0FD766EA8978CF93625F56B2164E2E630D6383EB03602A8DF27F28F580E3C7 98: D716BE6974E46F19A606486BE576AC6E250AAE6AC2ACE7CA9A924C874790E6B4C94670FD884A6EF770EC5E5F3F264306 99: 746EEE51375E6695BC4B66190172DC6E86C18E144267C7B0133D6C2ECE05F75B862E4C4EA5F813DD927D60C46E2C554F 100: 3D20E33BA4D52A8C374878F1A624A907132264D0C831C64FC51ED8E1CDB75D11C3FC78D4C3CFBF99D7F0BEA9829B725C 101: FE6A6EBBE30EEA13CE04B1C8FA4199331B77566D2AF420D4EACEDCF22C23B3D7AD2313175389A0765AD60A79C0AA85C4 102: 1806469C58C028D7FBE80F219DD45333D440A824032778DEFC0A89CF704D40745F0F449F7DF82D228E1718391C85F318 103: 20CD15E37F6371020B78579210FFD7756B42BD01EB829C1320C59AC382781AC4224439F1F820E215EE907091EE4F028B 104: 7967636E73E440EF1F8751441ADE0F4D169167AC270949A758FE0FFE0B90C2773435623160E4BEA5F23DBE0678E95ED2 105: 754F6D73A11693E07A2E5F05FBE13514C52F04F904131E0544202354D30917C333DC649FF7C33557005BB19B64DB777D 106: 358D83F883166A6D2972C63F2A46EF893D2FF0F577A53830B3B8E2CB28D1EFE8405084C145EE4E0BEE5DFA9AEF739263 107: D74B6FD707BCEC9419F032A9C21A7C79CD38F42D564057CDB956485FC5C2ACAECE9D86BE8E12B9181018EA7871343147 108: A517359A64226F2D08B65203593F3427DD42852476A7609C7F6423C304FBA6EA83981470B8CF171F71BF02F688BB2448 109: 62162975F98C8ED1B74ADE5B2325EC3D185F7BF8D9DE6C08BB3AB052E54C28399AABE2BE4295CBE12003A03924D4EE3F 110: 8F1E4237FBB668D2705FA6964FF50014F54AB6346A7DECC8DBAA282B51803DE20F9090E7AF2E6B40FD8A138AFE25E1BC 111: F5F9FE110D809D34029DE262A01B208356CAEC6E054C7F926B2591F6C9780579D4B59F5578C6F531A84F158A33660CEF 112: 33BA080EC0CCB378E4E95FED3B26C23AA1A280476E007519EE47F60CD9C5C8A65D627259A9AA2FD33CA06D3C14EE5548 113: F14FC73C4192759B70993DC35FBEE193A60A98DBD1F8B2421AFA253DEC63015A0D6B75FB50F9F9A5F7FB8E7241540699 114: 72B9E34E0E655DCD7D9C288D11839A4FD96292F76F69BFB2E7D4F848E498B842CD4ED6486E77E30C603D218144AEEFB7 115: D71CBD531B25BA65E319954E5AA670C8055406A595D006F0DCEE11AFAAF735CB1615EBAB4CC98061645FB70F31CDD9AA 116: 1F4398793AE7B2C4975AB102BC054DCEECB238DE4307B5DC54F6D7C20E066F638A782E33441533276DF9DB1AD0EAA75A 117: CCD908195016DC596A78C6C10C92EF6F272C6251F3C40B2E7DAD3A4538BF3FF585D4E44035B49EC397D1476E9DD28D02 118: A8A26DDB23032BBD4432AC857383A5DE280202B21CE173D864E19C4A52984E159BDD006D95605A4682458137FE6B71BF 119: 0C8D3031D85CEFA23A09E13CE03623F0E648A030E43700C82AA1C8AA7E3EA9CECEF3029A23815AD940CC39ADB7747D2F 120: 0577AD6090B2A39FFA1C4A25436F9E958890C55A5B23CF8CEE8195A5984316D81D6CF0B5916C0AD8B1F512FB39826C6D 121: A5E7C31DCDEC53D8898DCB27D52A5C1774115D8DB163543A330AB502FE31D6017FA4BA4C65ADE0CD911972C5A1B7739D 122: 2785C149B798E41E6ED600DDA5257E2F31484BA4D14D35C8353BA4BB3BFB47F6E2CD9B64C940E3C1F83AA4587DC29CAA 123: 977756EEF1A7C1D4CA31A8E6936E7B8884968A22F2846F20B38F247345B1CCD47405040F727BBE2E0FFCD159206F5E87 124: 9E4811F182E5D6734EA097FCBC77892EC48F09DBA138AD5A5ABFE67F2E88AB61B0A3ECB29028B5528180191754231765 125: E964C5CC45E8356DCE9FFFE715D01AEB3935D644DC9C2603ACD175A04E8924DD84A4D88A1384D6BAA8AB3F7F7D52D122 126: 764EB963850537E57D0969C9914355C5AA67AA9722644569B7F50E20DA8461CC9C6CA5958ABE10F5469E4DC1ED27619F 127: D5FCFE2FCF6B3EF375EDE37C8123D9B78065FECC1D55197E2F7721E6E9A93D0BA4D7FD15F9B96DEA2744DF24141BA2EF 128: CA2385773319124534111A36D0581FC3F00815E907034B90CFF9C3A861E126A741D5DFCFF65A417B6D7296863AC0EC17 129: EF49AE5B9AD51433D00323528D81EA8D2E4D2B507DBD9F1CB84F952B66249A788B1C89FCDB77A0DB9F1FEB901D47FC73 130: D9B681BA08EC0D0598DD3A2A37F909D01A231D22DA52216126534402A58A072DB35FDAE555B99159894BC823F9DACFE7 131: 961E792C94027A091DF880A713ECBCA94E7699FA392CCA3E4B9988CB95DD46C894AB6CFA3DE91236188F7A372B1C60C0 132: 779C845CED9623B6558577C06C6F22768E4A01CED2A9722CB8788FCCA89E0B5CC6A8925533FD097F635997A9C191D59F 133: F8A6FA1C730483AE488191E5863AB3DAB4BBDA1722710E519A2B2455273E78A382C60DB0D21E3B497EF9EEB2780AB384 134: 1DAA34486981474A57029F0B1FF5150A144CEC7939A5D0C3D7DDDC4F471225D98E83E8A0DE880036F1A265E24CA1E674 135: 769694D69D701764BCF81C053E2899B232344506C08A39DEDE3D838F85870818C3A8CD2DBC8695EDAF8FE34B4A5CC35D 136: 97E29E4AE7C7E461196C1D698B5D1186822BB66ACA3B3E062A3AE07DB9DD0FED83A345014D3E5AD89E9046606AD2CEE7 137: 6B57593EE18186573F92273A9B722F9FD77A4A512164FE3756BC2D9F665768016EB2766C46D473A103D7D7090073271F 138: 35235261C522612958048B7FB8E48F96462D2B8B52AB2455C7C142E442E4CF643B367ED466A30BA97D91C1C8C0070E05 139: 67004A5E74598981A79984B2662FFF8C8F49F8FD13C8A841F68DBA18DF68015E9C1EF38D6522D44F89DBFEA8AF48D2D0 140: 8ACD05F9738BBB176E50C7419A05C8200E1BA84B5797032E025ED4B55D7A61CEC4CE3662432A4E0BA938D8C9143D5254 141: 9963300C0CE5F2D39C2B899E47988BFA914D2EA2DBB972C15B3CBC414E41DF3A2FE793597243D46CFF937F41C0D83136 142: FBEE0F5E072237D19170999D02BB95F6F8F48FD0596A982A4FA2D1273872226398DF57A63E1ACCCF6343415DF387D89E 143: 32A65099C47EAE3BCD0F68645845C0171417385B15DB5E5F7BB5AD965F66C98CDC39B7534198AF70AD5739C8A2F2B8DA 144: E936DBA2CED7F65DE3450BA7ADBE1030D7AEFAFCCE0CBA94E671422790B45B49918319A90FAA7692780CAB4301D9833A 145: 1E20D13B4D71ACBDBD5D2AA129E98929510C795119EA8A07EC63917114315E2756B45E7AE42E1A44C5E410ECBEFB3661 146: 02A0571C5C3076CACE7F061BDB108D7CD9C7EA51D0FBF1D00F202A0B5C87F22CE687D1CB15F798ED164CAF1CECF92CF2 147: EA07C4A1DF1E5CB26DC7A7BC76FE518890FB8C424AF3B1C76B37AB21445D9F7FBAB73C7DB35E85337A8F7A0D55121F34 148: 7829712876378DF986A63E4616DCA38DBE8833B14760168897AA808B96D8FFA4460CA3C1A9B674A0FC13E0625537C45A 149: A7CBB3CD50AA663BD2C4520CCEEF123F7D314870806291DA26A59C003D041E46E6B563670F27BECC5F838A273D349AFC 150: C14E7F70D28E17D3546EB40EE96D239CA5EF7EBBBD0DE64B964C145A5F2980D408A6AC248D651E4583E25093042EA286 151: 19F87BFFBFF4B1E195612F41E67E1D4CD0393E73FEDAC1C36550C2B1A7323D3E7D747EAAB9844F45F150F8DF0FB72E80 152: 6BFA3BC29FFF3A92FEC377AF8508D4823F4E87072D6F2F16370B7DD30789A944EE5721EFDA7ABFD47A512EA2D4984BC0 153: EE10FDDE70EB0A11462DC00860AC4756B21C83BFF0066C431B17BA57CCBB9ED018E8058CB9EA44CC11952C3C9BD15F09 154: E6A72B9D2A0FFCA41C3122C767A6FD9CFA04CB5B1D1D94B79A0B2C592A584F731CA0523AEA8F2DBA35FDEF74CAF165EC 155: 59118A53C4479070DC728D94BA36D211F4ED5D35F1B69E4DFC0543F07326F982D2B81DDB020F2CACCAF1E5E9832624E3 156: 63778B7830A3AB7421912A52B3CE9303A53C2A6655291042F428691A633FB9FF173937A8D8F59B21F72D490F39A9AC06 157: A702F15D9483BB767FC6BE9C3BFC64732277CE936AEBADE4022B24B4822BD1B0FA1213AACF7B4506BF8F330FB7643955 158: A3FBEA92041484F7F46B380462C5114B0243A79FEED89ECF8E6D8306D60DBEBDC5FF1578EE7E94B5527EFC5707D2B7D3 159: 1EAEA2602E0B6B328D008A5325C5D4F9DFF7AB9BB5D36816D3EBFEE733BE664E35170506667BF5A24D00222EBC5DCDCD 160: 92E4D41594E15628BEF06CA61E644D2A686C113BF8E3F9A8CD2CD8261B11D01B081EF2941D5182E565B70C566D461B23 161: 2F08DAAA98DE6DB4E85B81E32C651D88075DE18B7F9C3F633BE1F29C89F24968525B1B357DE80C6EA8D9570E003C75DE 162: 5DF64E7960C755D40BE78F0BB7C1A185DF8E505F0B421BE23563472843E3B5CFC7DA0F40908BF56C6F3A6244581C1DE6 163: DABB5DCBC32FE7298C811CE22025E9B1C0B87DA5E7931CC3614E3EE39112206DD8422A5504F11599436B806C9108B01B 164: 31AE27382E330115E009474FB5AC750A278B79EFF63755E323E3478B0761E5E946DA6D2436DC44ADE9F4578A8FBA9896 165: 6804CF0314E455F499E73BBDF4FAA22CA49020330E74C55B1CF4A2D2F4C57D7149B41916002B2852ECFA0713BA91A094 166: 7FAD2AB0972D8059D4306F0B63F25D9ACBBD8FD95EC8199CFA89D4E227EEDE6052AF0C53C703C7E319047DC5734C9F4C 167: 4635E654950B173D3EC81A8212C1E65605C85835CFAD8607C829786855636A660D6C3045FF17663DE465BF2B152879E2 168: B40764D8F066C897C3A8FE54BF21DA294C6B3F1B35255F68C8AB325AB3B94EE8AE2E5173936C17FDC95C9B7C3D3D3A58 169: EE7E424C550F79BA82043245C3B7D0AC32A41B876988C322B9997D87F0A0A1FB8263726B953B43B4616285A239994936 170: 627DCEEACB27F39552AB683330A67A316B2F53842BCE8056FCF3988702955E3BA72FDEEAC2CDB53F13627858C1BBC51F 171: DD13F3B3E9C79958B20D1986650A79CEE1343F9957FBEEDE18B2FB5E543E3B8839EDF7A57EFD818129C4F00F505D2112 172: 0A7061C0FBF1EE8CCB0F4A1D0DCAF2F200291AC06830F0E38D05E1CA2429A2BF57DE5BF8DED5A7CECC3A4748FBCB880E 173: 3635AEA9152337FBFA4C2824C5499B9F3FD32061297C4121FB0A44CDF5D3C8D4C6EFD760A0BF076DBD1801C416949A9C 174: F9C58AF2259C719B0B852FC68299AC9F17A802B49B34CBF5FBEB85DB3C68767CC34DAE2CCB536FF90BAE49FDDEC0CFE4 175: 3541EB8602A4C84545F4476749EAD54E4542C4358CC78CA5B7C8B6BCD9E9A3E649CCB243FE0B3D02930CF1CB7A507FFD 176: 4AA26C2565531A52811D30A1C59152BDE4C61AE2CEAFEF9642E7076EC44C7EBD50F1D1853761B4097D985DFE6878A701 177: 32F1DD0B4AF205B4891E2F43D772EB5E4A5EA3658106FDC8B8CEEBD2D502F8048B583610A419E1A60020C8C2A5A02FC8 178: DA7403FE3C3D3139893522C5DC8E4F615D36A0F7B7B8AAF150D1337C8DFE70311544E54880D1C575D664E9AF979984D9 179: 39F8450D4A946ABC6FCA804AE11935CDE846D999BCFF3091F1E6944EAEAD504F77139A919F915D34DACC13757CCE0157 180: 45CC03085CC3278B8337096BEDFE6F1D645994690660F23A358C4EC728EBAFD6966C487B9492DE217C17823B16589852 181: A2150F3BA3349E3AA0ED97B1A02A58F31EB5731012393EC68846D95465F3B787C272852B6945B1CC0FC2B3BE999E0E46 182: BF9392B085B3C5FFBDE70A3FB64AAB36E39BDE4816F1C9B2A608269336906303F7DFC15F4701D3FAFA5D7A8BFE316A1B 183: 21BDA179D5B80FA6B9444AB1D1F7E06F89F670DA4A038E7E83E8A63CEDD44AB6C1D069D12C6F538B45022EF3160D396D 184: B4216CDE6BC1C27A5C1EA9AC79E85776740F93440AE438D4D9CF51BE8A83AD44565586FBFB58DD743782724A440218E8 185: 5C3D5C00381BCCF77FC2103C262F373592FE34C2B2895F54BCFD1F9B3C87026288130822B2B451D716FA9D4D7FCC93F5 186: B927E3777D4BE05FA85D0CB707FB00F08C576777840634531795CD3D6818F192789977AD6425018025E10F5892FFE708 187: 9C6976E1EDFAEDC32378C8D2758D1B0C5B287C500442EC5D19560BC87C75FD2A7379A3E64ADC1421B7410D1ADD6456BB 188: 9C20482AB71BBD8E985D7891499DB526BCAAE11D2A42DD72FFED664D7BF7F254C2F8DDA2E340690FB83E1F5C58378B72 189: 7899D5AF410188A3D0D0B12D52437313D786CE7959FC4D194D6A3ACA85729B60ABBDC58AC40731B9E833505156BEFE24 190: 4F958FD1841D2B790A199EE3358F4DCEEC64CB34D0886EA91AA5E38F8600FBE13DEE4D6A55AC1273B3730CC62A3611B7 191: 66572F61FE6C34B440AC00C8D3992B9CDE3FC465FCBB193CB7716B53E8032C743718D4F8245D94A22A9AE125795589E0 192: E7AD49861960D1460A77F4F363341ADC2207E205302957250612C7E903802AF5C9423414C52F4C1AD55CC1C8B2922EF8 193: 62BE3AA3A9D08CB41F2CA3ABCCB96E2E91A248E569FF58F58C8BECDDA5B4B25FF46BB30EB37999E6131D944CF3253302 194: 3E082F7DBDF5BBA5F52CC870F2C6E9C63DFCD5D547B183F3FFBE392BF0A1F8F4970CA21E5B9B4306792C138D6B2056C3 195: 5CC36277225DA2EDCC6CB603EDE9C629E5DA823E6D233AB7833F70FEA2878B2F8D08F361BD5B4C7609577329784D87DD 196: 9555EEEE1EE60EE981CED3FB6BF74699E5383436ACC283BDA0F9F6FFE20561ECE75ECE2C5A82C0A158C071A3BA59CF58 197: 0B975D2ABD0551BA987680C4890F80DF93AF2292FDD1E47322560B0AD3BDD38A67D3A78497D78B3C38DA597846C5159D 198: 016CE0B8AD1628C7FBA358EEBB7C3667FA93566086B99F20EA6F87FBACB320E7BCEEBABF0008550A59AC1E6C3B4478DD 199: 3D138114480946A2AA1E2B78948B6BFEA95F53BD8BED81ECCE166062A67FD111933A696E6FFFBFCBDDF71041955C98A0 200: 7EA4BB2534C67036F49DE7BEB5FE8A2478DF04FF3FEF40A9CD4923999A590E9912DF1297217CE1A021AA2FB1013498B8 201: 80C399C975ADDAB12FA20B3C3D04F25218DFEB678B5A87F9963A462F5474732C7C5FAFE0EBBBAA94662789CC10C9AACB 202: C27E28A5B6C7BFBC7ED372B5BD2555EF1370FD96043753015B3FB9AF31D41E7189D4FA8860B183703560A298D90B6E75 203: B792B021B3FA904B5948AFB4E56BD4C40119AC79E57EB24C32A7BF0A1A889313D816997E35F2CA192B34D2FF9B05ED9A 204: 7828C6235E2B8AC46E4BCD7F7C7554EA81B5BFC046133EEFA0C4E64AAAAD7115B04EE09E33CB4EA1FF476960C64D9A36 205: 06678F9A2F238953A8D6646F859FCC3BB0C29BABA669D7F891142C2C3A0BAC1220200B4EFF8C17F5D79E261128C58248 206: 0FD4448A47B6620FE90551A9AA06DD991AB13DBD2AF18A4F17AE4A9A24D9A83E7653D5F5A2C54633C42ACCB0E5915A35 207: AABBB8857DE60BDBB21742DE7ACF7EB8D9180D5D0AED23B7F708F09006C6FC56CE85DB87D9642CB909038E70C15C1574 208: E1BF933A4F32AF56C929911284F9B05B79F0216EF3A150483D74B2D4DCD78885190EB1601A320150C860168221C6BA49 209: 9074B187372B0535738D4606AA0478BECB5251EAEC961699C2795FC028D641D60230532C8F6A096FEF419A46B0DB87FC 210: A63532A684A1851050E2861F7AB94296D131F768A94AB0019A941734E13842EBE8AB1F42DB4D0A84E261CB4707C74290 211: DDFD64103308F0537ABD8D4F2209D8920CB42FA9ECBC93318D438C1493FE11B6134DDFF95DBE3FC6B8AA31F833E305A6 212: 044ED56EF3129D29243665545A59FDC12412E137E1F55A543AACE511F9F86CD3202E3D24807B0FC878BA76223EDC6F42 213: 2E470AB58A76690755AE6643D615039E767B84AE9E68480DD937913C44AC2350A27FDB45D6FADC242BD5F84809D59E2A 214: EC0ABAC477B5AD5F6B11DB4B699283FD4668D84C2BA7F8DF90A5BF83C0E1E224623F0D2BB3F2DC6EAAC5E41436035D58 215: 9FEBB6C1604914837F6D00F9AE23A3459DEDCFD81EF755B96A3CC1F63E4CD2E67F5AC2605E594DCD2610F4962EA6C277 216: 3873BF1A102F1609A624F1A096E420CC459C02590600808F7DA5E3FD49F5B491269C1116A2AC74185A3105B5E9606126 217: CD7E8C16B59BCEE5888DC7FFC28E65B72570B26F3A0C85885BBCE81E5A6B63D781F953E497399DCB506E8C4F5E237169 218: 3D24BC91A4932BF6D631EB7698549B03E7F3930662B8527EC122FC2C7AA41E330862102557F480273864FF9B06628BB2 219: F0B21BC919A3C6089BE3CB7CE10B55D76E31552E759F0465086A89D1FA435E2671928AC329ED7B3D7C1D7121C158BABE 220: B32F9A1FD8A97E6E8E701371BF1A017078B26C3F4C58E342ED455B2557BDA16EAFAC00AEAC1ED7328C65D7C1E227FB83 221: 5468F1B9192244C738EC20FA979F746CF6929FC48F69C79F43E46859AA022CC42E65203CE7CF77A039402093A1552EC0 222: A58151FE3211C27651693B55E67CDE0E886BB0D8F2B6D9066615124CF1DA403DFA014C6F19C1B10DE7D3BBDBD0AB9880 223: FE73FD3276463D27AE6A9F54877CD9BD3410C4A40381D25F5A915194538CA8C4F4B6154ECB9CE8B1B7E23953DC64F664 224: 0D4EA680BA7CCBB9D88C09F6DAA6BC655BDB0B2A1C8C3DE0BE895328027794E223A45969AE594C7A21FABD5C92BA6530 225: E6DC0E64DC804FEF91563B550A83BE7ABD50F51D3BFFA785A428EF9436775DD7E3A589793CB2717DC6BAD8B531CFC922 226: DE168B8F03C0CE8143FD14BD2D294476FBE8DA85B09BF26C5D846E2D19957F87D6FE150B278EA4B3BCD36AE52D251FE5 227: F34472A4DF2D3B529CE56E9D2A721A839DB05DB7B66BE8AB7202B024DEFD46ACF493973DD1FE88D8EF6E70673914DAA9 228: 1F5E8FFB4678B3889E7FEB2288358A5F1377A97F76674A8D3E5EF39D185D02F6A1FB60E43BCC79C31E6974B37E74E50F 229: 190AFF1D363C413BEE16C78C544AFD20678C7B1141D3917B6942E4D1486EDBCEE90EDE8A50E441219ED3B11BEFA09F18 230: 66BB67FC2BDC1D5E8E4366958804F459AA689E04D5FCAFA8CA222656D568B23E976086E2BBAD979EA0973AAA1FADEB8A 231: 0E14C70C02205AA29303D24D6491CC84B648EEB80AE9CC2A0997B7BB646ED32C69D2AE41C0DC007AFCEC514D7B04BCD6 232: E38C413F3FC12764415F39A9F3638AA1204D3E818A43CF2EDD9F2CE01936D36C6720CF5BE8ABA362F92AEC81386A4800 233: C3ED0B3697A84B388AA83DFF8EAA65F5BB12EF00315AD462F1F6D85D410D021BC32E77ADC763A254F7D9F1FB6EEEF1F3 234: 8DC2C3F8C13C43709AAEBD408A679CEC524DA8C8F4157DA4BE551EFD687A395B33577728EB73EB498ECD0AD2487058E8 235: 8AE817F2056903661E4EBF37D7293200D8BEE7AE0CADEA671E4987624A43712FD2C392E37C17D8E81EAEEBEE8E96653F 236: 9A622BC18F3A09C8BC1C8603B55260BADF32AE7ABD8DCB6CDD980C5E7A5B8A38C6D287A63FE88567BB9B0481743C06D9 237: B74C6303DDF9F0AD7CBEE923F7F7F1C7FA52C84EF609F2BBCC07B9911C12F3D1A9BD818A9F36EBB40D4B400AA4D0FDC1 238: 5B1AD3420ED592FA3D593435CA6EBC700583AC5E3CA2876887E5F190EC2109A1E6DD06AFC6C9D7ED0E8B0272B7F9114E 239: 2556CF077A788C49BB6D600F4A3CEE635C4443832D169F761537AFEE2980742B9F34AFBC87F598DD0AEDC4A826ED6A73 240: D64769AD58F5A338669B935F3431E5BEF31667D0A2437BFF78F1E5275075F434FFF675F9833EA04AC4E5C2E2C2C99B8C 241: 3264CAD70D24B53CEC95269B980DAB85A30D24CF8BDBD68F0FF8A45C6208F05723A4B3270CD095FB8B2D9A4167FB3D3B 242: 4D564117E87700C69AFE5A4D90FF50DEF8A54A9BF19382E4290290D2BEE101355EBB2DFB2A9D6D044A6D12D6DDF7BDBE 243: 6AAD71FA5D5D7B63FEA64D94E211155B01F8C9E4B3D86C3B9C014CA4BB6C668037C4739A082F37B2EC5FF6D85F0A58FF 244: B36D529E55B5CF0FD3273F204F798E21DF533BE466AD1AF35EF80082132640493FD89A6CF41CA68AED066E93181A9EEA 245: 78814E883A27D6ED3A5B122260059CC00D31B8A0E933F3C377BB99EF33F47B13B6AD825B740784BEBDD9917879C2DAEF 246: A7978D0C79070B208F070241867476AE622EA887D26B0F6703FA8A455F411649D8919E6E12C540C59DF60CA9C05684CC 247: BDC3E02D31DB1EB7F04CD9FB8876AA9C7CB1852BD3BD62F56E062E216BE648A34FD327B84E3B6339F44697470711F661 248: 9135E6D4B1E2356C3DE16A85E4AF57243CF6861DFB6C53CA13D9481371AEE285B75DCCAFC1A64499F1B2CBE4A3CD82C8 249: D1F9BAA4007BAD437509DB6F6DCA22086CB786026553244A6F480C3A6488F7E26C416C6AE85874477BB5563BA0AECF2E 250: 49E5B7521794B6C73004BADF3D039F4185BE9BF8499FB08B9C8FDA2186B6C4BCD280AE2D2051C6775C19ECF1C776ACF6 251: A7534C1716B59AB1C7AF3DF0AE32F22CD02A1823F61B318F36DFB536B8EF4515116A099F8DED19B00EE7B2D243539960 252: 0F01FB323FADD9380A5E4EE6371E8BDF6FFB1F70C4D4A1B5E8BC9B281582AE0531AB354EA9F58A96568826F6172FC75C 253: 145C9D3926904D8418B75C8D645D43AF651684AE7FAD885AB46141B9EAD2D9727731F44D5AAA0204395E020D1B52DA96 254: F663682EF7FA3F300DFF0B4D9C0D2D126F2BBC164F3B88C8A2207C3799464ED2086CDD324C1E88DAA6EF2D53CF7C190B 255: 98D7AC796C4CFB5D98A1C323656A4BE8AFAAAD168E5EE72B6B7A3FA3260461A043E27243120D41584B58F1AE4463121A 256: FFDAEBFF65ED05CF400F0221C4CCFB4B2104FB6A51F87E40BE6C4309386BFDEC2892E9179B34632331A59592737DB5C5 Hash: sha512 0: CF83E1357EEFB8BDF1542850D66D8007D620E4050B5715DC83F4A921D36CE9CE47D0D13C5D85F2B0FF8318D2877EEC2F63B931BD47417A81A538327AF927DA3E 1: B8244D028981D693AF7B456AF8EFA4CAD63D282E19FF14942C246E50D9351D22704A802A71C3580B6370DE4CEB293C324A8423342557D4E5C38438F0E36910EE 2: 80536C6170DD8626DC081AF148D39EC2FD5D090CC578A76647E7903FD34BD02E4333ECE57B0E24FF116F43429B6FF541834BD40EF0C8D3563ACEF5ED0FD254B8 3: 8081DA5F9C1E3D0E1AA16F604D5E5064543CFF5D7BACE2BB312252461E151B3FE0F034EA8DC1DACFF3361A892D625FBE1B614CDA265F87A473C24B0FA1D91DFD 4: 4EC54B09E2B209DDB9A678522BB451740C513F488CB27A0883630718571745141920036AEBDB78C0B4CD783A4A6EECC937A40C6104E427512D709A634B412F60 5: B7B70A0B14D7FA213C6CCD3CBFFC8BB8F8E11A85F1113B0EB26A00208F2B9B3A1DD4AAF39962861E16AB062274342A1CE1F9DBA3654F36FC338245589F296C28 6: 2F3831BCCC94CF061BCFA5F8C23C1429D26E3BC6B76EDAD93D9025CB91C903AF6CF9C935DC37193C04C2C66E7D9DE17C358284418218AFEA2160147AAA912F4C 7: B7C0B47F42F7202BF7D28D6834BEE365FC01CE3F0C8C8DF24B4D940406C2E9C230BA88854E946EBCD786C18C748969FDF012362B7C96400604B6058950FEAAD4 8: 8A414C5860CF1BE7BC8531442F69A65EF2ECF0B7CAD9994BCB407097EB74CCB92E93AABD24BDE60331123B4D900684CA7BE6027099D4946BF537F4D6C6DF3D82 9: 8B5E5E7FB6530CCE1BFFFD1B1AA338D3282E8483319BF028BB674BB6AEB8200DA389647E3D8631503DC5C487BBFA7D074584493615B036849E0242610EA4758F 10: 0F89EE1FCB7B0A4F7809D1267A029719004C5A5E5EC323A7C3523A20974F9A3F202F56FADBA4CD9E8D654AB9F2E96DC5C795EA176FA20EDE8D854C342F903533 11: 8FFAEE0CCCC162851FAF051AE38667EEFD423C0164C50055F8ADE00AFC3705E3CDEB9900004B0E426CA66AB63AA3B99B075273F44FD37C22A3555C6FD1F37CCB 12: BA51B2A9DA2F26FE81FC3EE11524255937EC6BEC48835EB437C598C55674E15AA50F88922DE7584332A5E4D24787090CB14DFC3ABDB39C55AEDF6EE108F95354 13: B6E30A4016029486F9205C5D141344F885B3DE2468EDFB0B870545F1775CE82597C2A40462F385C957790C20822D9E920EF1AE230878D6B23F221B0182879CCC 14: 79D76024A31CDBE54CA951D264C46E78F6F5AC5DCD018BAF89AA586333BE82B2D5CA2BC64B99CA2A99D95A984F2DC0D6C07E7C96059DD346BB3296ADE3AA33C0 15: 4236736D08F26244E75B51614091CC2C2907D5DD162F8497B14D58D0D954A777C8397549BEE468F30E480252D9B893175DF7D2BF415A128CCC79407D9D5FA536 16: DAA295BEED4E2EE94C24015B56AF626B4F21EF9F44F2B3D40FC41C90900A6BF1B4867C43C57CDA54D1B6FD4869B3F23CED5E0BA3C05D0B1680DF4EC7D0762403 17: 7B9AE840AAB8BEE45B038CE398D15A8679DB92D0BA46FA67D1B8177986E41EACDE915C6552FC2AF8678425B8BE81B57E0F7EEADCC93B56C58DFC38B4D33BF25D 18: 0EF6A8C19E19A466DBA3139E2A401175BEB9EE01FB56A8FC11A3E53B345F2327959F6DAACF0CE6121987D2491251DCF550C95F6026F93A1D96A0F4164CB1C642 19: D6221AACC88CE14EB7DE0F15F2260EBF4294D9AC3D75B87465EF7AF9570C959077860EBBC5C8153000507CE1E39AED5D007F2286210EFFD26A118966ED15C143 20: C9AC4561A7503FAB9C6B71C843AF6911438550BCDF4881EEC18DDA06E4D8B820CCA9521DFA9EF47298CCF6308FE4C4F2F5E34DFEC2ACB78FBDC04D2EF0A5A09E 21: 73C5D58B05E1E6FCE4299F8D9294681416BC3785F51E402DCEDC0E30C0671DD48321A0248CCC13389A012B52513F1B5BBF820E91EB4F616928183485B4F1EB22 22: AB1725C57427DDF93B34AAC62C26F3FF1E49CAD30DD41AE7B5FCE23894245E7E889E0FCA5EC076F247DC7E929D72FB965B45688E57D8CD54212714A17480BE0E 23: 456F6757A82F0589040996BF88F28E61317C358135A9AB6E96E22F5CA68E2A6438D13D176B01157ACA1FEEDCE3C1A6D5C3A9B1D5A471691917392FB94D0834F7 24: 5330241E6F01A49B21AB0D01A9C76AD662E97A325BF8E24C4EB82C6F3B7D2538ADD98F62307F36F900F3934861B80FC9844B761BE15460A1B102C26CF0410E83 25: D8DDA603DC21C20A6DD3C6A4F380C297679F035D27BBA82554D02E1F95ECA2EB20496164F96DC4B84B9BB0942B96A3796AFF6125BB9E8711E2674B440176E91A 26: 81E5A3AF460DD2881353D006AF37478C58AFFF16022441226FB04439783DA920D09FD03E19F45BC82F82735FBF4F2E5F588F11AFDB87B69DB91123CBF05F7F2F 27: 25AECF7D241EE54E668DDD345582DB777F9F631B9D2432CE4D32119BEA3968D9FA3E184B135364DF62247AB74BA7B86AC3542F63D9F18653D86B9B47944AB96A 28: 8A372F722A922E29CF5CB22BDABC6D284364F376DA355CA65BE36DAE2FA6F0335744CEFA9089DE55D331AE64E9B2F1037E73608B03B978758A20A012924AB235 29: D57C54ABB87AD2D518790B81230DA336F551A0D89A57D0A3CFE2F4ACC55B4B210261CD1482BC436F62D3FC96D1536B82A2E93E9A3DB5CD0F1822EEACF307460C 30: 6092F1E76F04A5926F6FCD149B18DC9DBE8581BDE6D2A1468145280463472B636C711FF61F5CCA84FD2F044697BD1DD18340B3ED0A131F4BBA35F839A2DD9E0B 31: 0674A3CDF5F7C18C1B7524C87C36037F3D0267512D11E052F453DBC097CFD52BC331950880CF904656C70758B2E25E21FE2C7E0462E861112A2DC9D0636BBAFC 32: 3D94EEA49C580AEF816935762BE049559D6D1440DEDE12E6A125F1841FFF8E6FA9D71862A3E5746B571BE3D187B0041046F52EBD850C7CBD5FDE8EE38473B649 33: 301F1CD7B25B097AE4C79A97E92BCE359D1289F6754E76B71E7617A06E7783A3CC30F5290209BDA3E6AF239D0DC0F3D1CD4C5E866F4C5C3209EABBD7AAFB8058 34: A8C7114B292CC6F46D73824CB073CAEB23EB1ED5EBB37F064A0A76AD452D936D1DF41433FFA337C3F7CD53F5CC00658ED0633252B69DE192E61D9F002B0F133D 35: D2F92068E07C9AD0572693CF546FE75070E574807C02F5483A31B8CB2105CA55CC6AADAAFE74977F581CE90F43E2AB48260BD7E273D4A83C442EC4871CD88AAC 36: 1A4133CDFA6CC518387D392814029744D6FA71122EBDFB70059512B89469CDB9D9B5E45900E99E67DBA54B4708036298A94835751EF583149F06AB272B2BA355 37: D30DE790B4905717C956A95F60D9ED5948F9E509BA27607E1C5C8FFE35ACD83F719AE04D63364C0BCB72BA529AC79C321ADDFBF7AECF7CA3CAC840A372E6F6CB 38: A25F5D4BFFBC5F0E3D5CACC3A91870866D8C2D22573556C9B9FA0D24E1D68C55EB42726B1895DF8E5E870DA33755DDBBAC130AF2D96D84DD0D57761D25FDB64F 39: F44001A74D0B087AF2A143B778DCDEC1554BCE5992C9672E3D0F6704D022CA1E78F087543569CB99D249B820E683138A2DDC5DC178D585167FDD269D17396A89 40: 692F36EB114060FD04CD38555025251DF985DDF681A0636FBD290EFEA6FCAC5226859373F3E10E8CB07AB5343547EB0A543C18420D70527D2BBD90040F8DAA52 41: 4B1CEF875A025624398CD06DB876EF9AB34FDB1B6A75A07CCB591D9B20EA66E24BAF323911B5CE8B67904945A36C28630B36129939D23D26218610CB049D7AED 42: DB3E80F11517AB797265829371F245A7A0A384E36A8D43E72852C8D47F8CE37A178475EEF44CE8BDEE5AB054F47EED502E76D49B9F4A5AA392077ED1E6F43EC1 43: BD08551AEA7759911B37E9D45748219B47C4EC17A2D2A306D9B8FDF982A9E3106BDC1ACF3F47D383B6D16E85910BBA08128E35EE578E7C55F2E9B9B59F611298 44: 3BD8A709DB9A4E0B874B113564B11EAF8270AD1DA3A9236DBB16F58F43285070344962394C2231B3917401924A3F688150B9A9ED3B410547DE3F56450739592C 45: D0206C8577202C617592B47AE178DA867AC7DAAE4E65B912C771C5FB09585FBD10C36782064E83ACE749BE27045508D544532B628F67DF00A6B7DBA9775D3E06 46: 745083E5994158A0FEE4D849012F43A822D19F068AFB327B372A7A8BFE8347E579DD29424EC95319BF75A24B4DB4280D9C16CEBFF5D930D61D34909061A478AE 47: 3527A5E1E5E5953EC57F309C6513C34405531603372BA0DFD5725E68B9510E5090CC6B317B2E7359D2ABD5ADD353AE1435B85535EB5B0B8F2E09D4DD1BAF3C8B 48: 622BE417916F1B0E9CE8C952171B11B6D2E2932D6197CC17431B9FFDF03FD0ADB69B08DEDAEBDD0F94812BC2C670C894D65165B31D2F2879532F2C14453E6A0E 49: C2EBDADE0368F1DEBE44F8E1B77E66BC1C25E7F0FCED7784D615811E2C01192DBC21253E10709D0BEEE746DE6EF93CF65AA39BA29551E11F602ADDD27B196019 50: 5ACE0640F0DCB25871E1925F96BAB48162D692BA134C9C7052A37FDFA4895B90AC56C7FB0E7FAF155D147A467839500D980E9D4ED1CC96661177ACF0BA8D4167 51: 5D43600C04E52BF6524CDCB9DAD89B1C7563912E7C7E2CA3D34B27B3C1D07D85D35EBB7A65AF0434155AFA3102A580AD557468CC23EEA1E151BFD4EA817FC5B2 52: 38D7538AC3E51DDFB6724F57B29A5E46D15A8C08FB29D15FB0681A4315B03FD6747B85D0EB2B9E5FCEC709F365DE08D61A1EB363094BF292B5154671D15D61DA 53: 2DCE13E5882A31F7396D970AE72E89FB59270D78BF7B4579D0855C4E8BA231D23E5566B77E79CCDC1146762DAAA74F49D82F9EFC0D4FCA891E78F9FF86C61300 54: 6D7644DB575C5C238DA02CC4259996CF163A3A3B5ECCC4FC62442DDF01AA05EF0C4EDBE3E6D220DF189C984AA55726A4922EFE004832F2D8887F0B8A9267DB40 55: 6856647F269C2EE3D8128F0B25427659D880641EF343300DD3CD4679168F58D6527FDA70B4EBC854E2065E172B7D58C1536992C0810599259BA84A2B40C65414 56: 8B12B2F6FE400A51D29656E2B8C42A1BBFE6FCF3E425DA430DB05D1A2DDA14790DEE20FA8B22D8762AFFFE4988A5C98A4430D22A17E41E23D90FA61AB75671A9 57: 92CB9F2E4EEE07C7B32B06CF4917FBE54365F55247CC9B5BC4478D9FADA52B07D1C302B3959D0CA9A75A629653EA7C245A8FBBA2A265CDA4EA70AC5A860A6F3D 58: 23417F93C499DF9EAAF1BFD6A62AADBC711BFE56682943DE5D94E0DAC32F732B763BE28C32AD5F01CB95E5B322AEFF8494B111D7CD8BAB50E7C602695EA6FE42 59: 4ADFA8837BB499605D38716F8305FD50255DEA2EC4BF3EEB07560B3C93B5E3725C5A598277A32502CD5C8AF6C88D55756DEB03B69CFC278FFE2BFB3CA202B0F6 60: 981A245B249111B4CDCD565AE60C9DEB69FDB552B10C932E8D0635685904203C37CC65D674292405DF24A589682B8AA69BD0E16F666652290BD79AC10E3A9B37 61: 15DDF1E434A88F27DEDB8435ED837FE4F1F3BFC5B6FD387A98E93D1C83493D326467C7C53EFEEF158F6B9CC2081267D9761A32A5094399754C0FD62F4C72371A 62: E08026874830E0B911F5CC51B81599A4DC21204F5C9381CB5A0DA8F452EE99D9FF7590B798805C2743822572E6D2E47C2C1F2D428EF3C28D05297BEDC5CAC4EF 63: 9DC9C5598E55DC42955695320839788E353F1D7F6BA74DF74C80A8A52F463C0697F57F68835D1418F4CE9B6530CD79BD0F4C6F7E13C93FEB1218C0B65C2C0561 64: EE4320EBAF3FDB4F2C832B137200C08E235E0FA7BBD0EB1740C7063BA8A0D151DA77E003398E1714A955D475B05E3E950B639503B452EC185DE4229BC4873949 65: 02856CEF735F9ACEC6B9E33F0FBC8F9804D2AA54187F382B8AE842E5D3696C07459AAD2A5AED25EA5E117EB1C7BA35DA6A7A8ADCE9E6AFE3AD79E9FA42D5BBA8 66: 371DDB96ED5BE6521379457AE8ADD707A866732B629EE00074904D73858F3FAE827D84E503F3779073490B274E29D644D76154FAB18945222289BCA798BA6438 67: 96A693A22256D39A0596802319CB7AF997DB4BFE311577E38F8423DE81C567A96775D063471438F0982EFAA6B75B4AB173D9D3B3D4762030B522FA70DCF3B27A 68: 7D8AB6155AB31F29740042D82788A69E880FC642E600BEDFC89098B9D2F4F98BC11141FD420870958810295100DE66F50C96E1E4F6489DE98F9BF2D4A9AA2237 69: CE561F8F679B4EEB1DC97DB0F72632B9DA1C5B5C0292CBF0662CAD981374BF8C9A0BE1355657FB18196F980E6685D52FE601DD45C6B0FBDE7AA5C9D52E7E5973 70: 10164CFD162CABC44C56D76D369096D759954074B0547FA7310C3388F0FB6BB2AA295FAF1E22C44CF59959A37EFE317698BC29AA718D57EBC831A14144F4E48F 71: 658B337A8FA873C73AE4D19992BBAAD10E1325AFB4DC8B5733F870761429B4243A7982AB375E529C1FBE6339A48F9FB9E8FD6A568F9CAFE640E102B9F398A330 72: 4EBDFA0E60E1A3E7FEFB8DB424A5C3A52365F325EC7F51389A4955EE3453BBFC94692DEAC3FF6A4E94105C27D632DF26250FF37314C882FDEB65D53534F8A961 73: DFE9D2A6B0AD5DA802D695B3B91745852C97B0283D9A033F04D79D2CAD4FDE50048AC7D82BCF8C402B109E785D39FC9FA0203F7CFC620EE43577688BCF3E69BF 74: F21869E1EAC3774F3878570AF0DB9A94F464373C1A92E097D180A331C9028A18A68BF4624D8E620B2216B03709F03FB6CD10004F77433ED605B0F771161145C5 75: F1F928D322E6852301AD6FC901E91F2156A3CEEFA204044DDA3B4B76A63692DAAC479FFC6D83EEE3BE028A1F651D3520758DD395A1B251E6C261B7CCE86D0481 76: 37954BB11B0AAA67F803973DDD2709A73B947D0A5FF8DC46C2D3C6918C87069AD0DF907589F3026A94B071E0F00230F00CF74AFE8010C24E489CC8AF9B8BD646 77: 140DB04BF46A194E44F07F6ACEE8326573AA0591F8370A79DF320093C45764A2ABAE531E5A742F496544657FADFEDB7F04D4BD74C347AAE237B5EE59921BA87D 78: 6D0D30BE796B6E1039739BF24CE26D8DB954D25813F8D7F7444617816F93FC7488B71C69D96D77C65007EF6A2BA313AE0739302395F3D9EAB0244E372AB96961 79: 2B92E0D915BC7D56215651BC9F769544C55E2A27080EE726AB14FAC0A43AC51CD378EEA356DFA70EEC3C9146E08E98358C61FFFA3D477CCAC35FD6724A44C23C 80: 2CED9E743D84F8EC5664A99C6DE2238464E61129B3C856A7FD2CE08B185F4D447A829F287870AC5428114A7234E41A78801C19EA5C6246FEFF961DC6A9B55835 81: 4462303D052C70DE76296234B72BFF1AF173E7B63D1CC0E26C518D103BF3BA78D9AF4BA88013192CBADAD83801B8FC29D0838A144AA3CB721AC859EEABF019C0 82: 880FEF79B74C109F030F3FA6FCB82DCA034528CCA68A23ED1EE4133C10B3E443434A37C436F079F3F3A922A8547549A39854120723791519DBC166936C239AA3 83: 12DE996C9DCE152C83BE6C0E69C66633FC4244B412066A5FE7CEAE27BD4A109FEC95332C60E87DF08A1C714D9D2ECF28A8A81F1CDF8BB3CD2CEF71011BF5A5DC 84: 748405D18FC05F0AF7F61E0CCDDEFD8055D86826038C77F2AB230F7D97C89D0EF09CE82C4352A7491729C9FD704B279449D0DD7D86CD2FA52EB3B5A582DC2057 85: 746653CDC44B4C86B29DE5B28254BE9198C0271249F0690615B05F23AC0456DD66CDDD13D2F22924DF530C78FDFD3699E38E29A550E2739A803FD1FFBEB29E59 86: CED0B3E4011A6DA0415C51E37996EBBC5041861FD1584E3D948E1D4DBD7F8673EF93910A10797490DD5C62245EE7EC03D7CE8B8C38FAE21EFAC1AE6056AED143 87: FD4BE7DCAC6984196FABA1D88D0FFA9F33CAA29FBAB3E38CD3DDA7FBD94866C944F91B405B3EC613044E4AF11BE7187B15D5AFB4067C54FA09215C3BAC4FF080 88: 46836D5A579D5158B9F49D6EBE9A43C9F4A55C768869C3D542BB615FDBAEC8DD34FFCC40288567F8C5E9363852EFF44FEF0EFC0904BE178D3F78EA1B61B9E98A 89: C05B8745D68BB9647E411E5AA1F924C2C9B96E7DDE71D190A3B8709ACC2856ABFF3C2DBD7093B25F81C6B9883D377E721968632FA4D566F7F72E1109BDEF2D74 90: 647A0E15CC4BB5EB3333919CC828D68C5352F1FCACE6964F23FCEB46D0D2408AE896D3319B202EC687F3F9E55126C05705FDB909CD8CAC88304A61B69ABCF65C 91: 2DD1C321E3CFB58C2E883F5DC3D87F01936ABAB3F1F27648B6AE563333E3852BCCBBCBF4822230E8F0A0DFE32AB6D8DE92A2B8B2271E17DEBEEBF00D83046B75 92: 38122D8324807E25DC8A74012CA9C0292222604303CE8B66D7329FEA394D85B7BFBE0F656895EBFD26BD60A3B553A6E3E4003276157B31B3A47779E1633D89D9 93: 27FFBA5DD09485E141B659E218D2924AB0392163CDE296D4109F3AEFCDB02241CF0952F0A38E2680D5CFA35363391A324E12519B58C04E8ADF0E9C7A8B6E1712 94: 69DA55F3BDBB1C7397CB382B7E8075F615794F6F8453313C0933D33656A3BAB07C42FF977850625B11CA302494497B0EF3A51F3D2EC2E4AECD24BBBC661C6513 95: EE1270F6FE6223C19AD4814F0549B54C11AE7B43A8F3418B0F7BAC42BB5B093024DD4F3AB0C9AF5FD2025D50D5B8DC3505D8F754F98AC3237344A7C14FA50815 96: AD8ED48E056378B1AFCDC0B3D5D3936AC825F96ABE0953E9BB85B00EC16084A4F0BF12A2B0B73F0A29ECB9841A1DC7F003456016203E891ABA1BEE13FFD19BF0 97: F6EB6972CB5FB156FA20A93D8695AE1D9DA8BBDECCADBA81123E7ECBE917596B51E4A6CF9E1458D882B76B33AEA8F3286CC7CA1085F09EB3DB9B9263095339A5 98: 40C54D468FE760A7094726B9EF12A98A1F0FE5E7112137ECFB3A88DB04B0758EC581603EFDE3610B1D76AA879EC31933CB6AAFA2DFC559C59BA31425B091FFB1 99: DD0324C4DCFF798F024A32A13063A05AF673CB5F8F03E08A0D931406C868A86B5071BA711F6DA80D7FD2F7D3CEE1B7DC12EA456A1EBE4CBCB25ABFB27492390E 100: AF216A7122D29D6A7DC7B89C8B41C111E7C9A00781D4A867A1D75110B48A5A9C92A15D1DC2AEABB53B83BCFFC50F44CFDCAE29DC9984C8C84FEBD0189322BE25 101: 1FD96E1905B024D5FA883B3BF76C00A0235EE6386EABAE4D9602B5C5E5EA81FE3A1DD0D81BFB0F904ABD4DA7FC71EF7A2BBD0DC6A766902021CEB03D2578B204 102: 31B75B047B1214B915EC56983E284D14C214D567F149EB467A1A324080AA0D80264ED771E2F91104B2642E9A8312C0C001652CF4E55308A870A77ACFA088D7C0 103: 59B8D11078C8B65C5DF4F39D1C532BDB9C6E8F2EF121B97DC5BBC29CAF76774A7DDCDCE0F3BCCFFD4779E57D9B23102EF596B8B940480079355CDCF7EC52D47C 104: 3F1702458BA7F28460E84A032BA160430126221AB5320AE028387B60AC53DEBC42FD169A23714AAC3009D52BF9F9485C0878C06A98BB42D1568E7D038234AD23 105: C8DA7ABB93D370CE8BA6F2B58F91ABBF1302F96799544CCABF52D5D1EAC3318AD4EC853EDC99CF86DF9341D6D794B57B68CD1FBC5E37C03AA10297F9828D5D0B 106: E1680FAF315911FB7588AA2F02D5F96A3FB02F60DC3C93117B97E4F00E2CE6862DB06117A6627B14B11B9E4C61BBEEF09134E1684599A370C61721A3B086942B 107: BAEE728FD37CBE1DAB3FD5A922E58111BFBA9BB47E107909FBDEECCB1812DE27D2D87003FC6F9F67977ED592EBFC734470CD1E907858F555F21EAFD6E64F060D 108: 891AFA38F3094E487BADAEBA012F11D3109EF19B858394EECA4C7F0C2E8FFBB3B88A7105C7D73E7252E67BBA518ABB6A312A7B8A11742D31BF53267CF3B09E5B 109: 6E6E3BE3956224A97F813DE55B3594EC5E2F4A43BAB873D902025699AE58FB43DB71DE1DC159E83F7A7EFFC19CA5A03C1EFFD27B026EE9AAAD92D1D58104D3DC 110: 51F2BA331C24541EFEC042CC66398D388348C4FEDC3F77A4DDFDA39752AE2880C68E0465C15B07ABFD93E16BA635AE7CA7D7E144018ADE57607DE8643992F50B 111: A1A111449B198D9B1F538BAD7F3FC1022B3A5B1A5E90A0BC860DE8512746CBC31599E6C834DE3A3235327AF0B51FF57BF7ACF1974A73014D9C3953812EDC7C8D 112: C5FBD731D19D2AE1180F001BE72C2C1AABA1D7B094B3748880E24593B8E117A750E11C1BD867CC2F96DACE8C8B74ABD2D5C4F236BE444E77D30D1916174070B9 113: 61B2E77DB697DFE5571FFF3ED06BD60C41E1E7B7C08A80DE01CB16526D9A9A52D690DFBE792278A60F6E2B4C57A97C729773F26E258D2393890C985D645F6715 114: C02CCA2EE8BED9B4AC74438D4E8B39619347922DDA5CAD2BC3EB9E4CFD4FAF7CC7EB9F6B21ECCA2C55CB60D11EC450390EBCFBA18312E49598D2BC52020DA9F4 115: E528ABD6C315EADE09A981E4861F6148C9DD4F2FCE0EA54CD3E9796F17033A3751FE9A223AA23CDE0E051A10C2BC27C0298BE97CB87C7110667A115B6D30657C 116: 1B0BF23602D272A06BEC3E86FC675E16DFB067B2AB662181315C45733D191137454BA22713B51478B096DC51D3FC7E9730504324655AE8B7BDFC184118933D36 117: 12D5EBC3016C77ADCD01F1DE3F792C4230DE67C0B50102E03FBF3B6B80BF913CB66C3E72530C644719003DB2FCB15196803812D89761E0B781E8AFED7268A35D 118: A3527C4E62349394274FB15B30BD95FAC27472E1E521514775D2E667A5480C5367DA6EE526AAC8D0D1226C33EDA1358091C93EC6B1B8464739D25AC4795EF175 119: 43E497279C2CE805903A33B54B746EA92D607F7C4807986C849823B81097A9099B5896AC7CC66DF3A93EDC8A91B6F3971D6C7F5688DAF635737760BD080E27B3 120: 9636708964C5FF6600510319E07BF3FCFCB1F4058FEC278EFB677964BA1E140C1632505452F802E99BCF09DA3D456DC3868D149A0788A730E49D239CE7415145 121: D5D17F592D401CB111FA7C34CF5035BC08EF6B2E0D3E64DDAB08430DEEFC8B9C09C20EB4E8F98D8EBCAC6F09AA2C1DBB7C1B3B2EFE792377CA6600F703643700 122: 0EA053BBE2E72264AE4F54512C621C733120F777D3CF8FCD8A7CC1ABCAECFB9BE93EE821A15D19467D249A27961E474ABFC433B8C7132321198789D5C2A50896 123: C64291C217E37E754F6F57C1316FCD8A7C2AC2426E86786FFB69797C0645848CAC41DE345FF90B72FCDE918B7CFAEA4D661687E6F737A088E9296EEF4C3B4F31 124: DEF8A3CD4921127815F4D1650FBF8B3EF16EF724A38045133749B7359FA68BDE3EEBC9CB5190FB6720EE3D24473286FC046DE0646C6C0042EA1968B48FB6BFBD 125: 6F3581DF30AF789E44C7459356E1C248749B4A5A389759DFF37826BD278D293BA2264BB808A71C453E22A2962DD33A9C03338AD060B3783713EBA8CC8B43E2C2 126: 2681BF910DDFA680B7204037294D00D0FCAEE84A3747F6E302A16704B3B08EFBDA0E57DBB8E61E92348C8D5FC5A59EAB74C77949A74C7740C30412A9FC65BF34 127: EAB89674FEAA34E27AEBEEFF3C0A4D70070BB872D5E9F186CF1DBBDEE517B6E35724D629FF025A5B07185E911ADA7E3C8ACF830AA0E4F71777BD2D44F504F7F0 128: 1DFFD5E3ADB71D45D2245939665521AE001A317A03720A45732BA1900CA3B8351FC5C9B4CA513EBA6F80BC7B1D1FDAD4ABD13491CB824D61B08D8C0E1561B3F7 129: 1D9DA57FBBDAB09AFB3506AB2D223D06109D65C1C8AD197F50138F714BC4C3F2FE5787922639C680ACAD1C651F955990425954CE2CBA0C5CC83F2667D878EB0F 130: 90272B89212C81B9700897F611F13AC1D291C33A437000C1423336B4D962DD39CE23413160F023963E12F4CCF90D2762B31BFC6818EF865E8A7CBF918A94C1DB 131: 325638D30C9F63D7CDBAA689B7AF8D23826BFE8593B361C7042D3293926146C65C2D6092F20DB5068262359860B3E3D502B6034B9EC8E7253A1FBE4B2007B77C 132: A3FEEC20C69CDAF1936795AEB9052DC525A26F5559045FE458D4B24697E260BDAA45BE8C940A06AE39FDC1F9365F32BAD7DE824FE7722A444E469C7BC198B7C1 133: 3F80B7BFBFC9D45073FDC2ED93F7C19F01E4D49CB912BD2568F248561F9C9ED1B6762270033D9F421C977F8BB8B4A73F9A99D580C0245DD4F64AD35D68C9847E 134: C292EF04844CD7C3E477C2C2FDDEF46FCEF97E5DEA7955FD4F418C7B4114BA0CA2CA230D0F73A585EAAAEA9277D72B83DB74AC5E887439A225C105B0BFB5A38D 135: 9F0DDAB7986DA54E65EF6B536BB4F7BFF468E0F310803DE28D3908492343E4CAA855B8CAC7409E3A8928E63B9C5D1CAEA7A408ED061809DBAE1AB1A67BA1B926 136: C58867D309CA48AF74B4D7E49ECED514C89FD433F9DD842F9B50FFAA6C7810BEF35348D00D26DCBE28122BA1CE33D4CD00D09BA76F982A598B8F65790368AE59 137: C8B1D6B4778932BC21EDDBBE4E48F7711D7E97ED5354DCF11BE98E3110510FB007948C288FD2F7AA71B2E41C86330DBBCA2ED472D15B444828C6DF4282815879 138: F1C0C057C974E4C27E497EEF52A02963D5957EA02C7E1CFE06423048799AAF74475732A7352220A914BF32EBA6A0B6FF28C77D25CC3CA1AFBDA89870F4EB55D7 139: 092E121F2C7A2621AA36AA9B040EFE4435DD649E3F336BA82788D57B9B164184F5B5BA644DB4076B46FF9F3A6B9F58D775CE94FEB648A372D960471A663B74E1 140: 406A5382E9A563E60FDE5CC47F52C6DB86CEE271BD3974AC6E274A1B8C5A7EB369A9B7CD312C301F891D4E3A601A80B9CA06303C53CABD5D3B7834DBC5108470 141: B2D3EFC2390CF7A1093B93C52B76D0DD74BC277F3D67A85F41635F89E923AEBC960B2BDF8A13860CF3083AC3FBA13D4FE5E426F144FC988554E89ED7A0324748 142: F1F7100636AEEEC8AE93A2CAF1F4852F192E1EC1AF13697765CACE58FB40B9D9AFC3BBE7E52EDCE649F53C1BAF653CA20E75D3E4AD549D05EB33A68DD11E1898 143: DB604416DFD0A7DC509DBD2C83D5FEDE5E31D641EE6C14390CF599CDC7D841660AC700D3DE4BE35E07006B724B7DD1BAA21EFC3CA6D346B3B858384FF691F913 144: 87AE00E496649511C3BF947A65805ADB5D237AE8486CBFF01EBE52D5D5062A99DB3434EC22A37DFDB4CBA1A59AF1FA5825EE3DB2A8524BDEAE07F3264989B85A 145: F442BB697D498F2026FA2A5FFFF9AC5ACA0052F6D200E10805104D91BDFC71A3764CE0277009229B9E7C945222BD7C9085163987E4CED02ACC7420A96B0F9587 146: 1061588877909CAABFA37D4915EEBD6E517B8D3EFD5660F872019050B3C1465F11FC9B44E72610219F3F5F21772933F101D9D58B5C5F79FD7457F95749BF11D5 147: FBB4C9BD6821A04CF154DCC7A7507A2C655739F3636B69E8183418E2C33D951DE6BFDF2C3CA603694C44DE44057665EA4835281A2773CB8A84965BE02DF1F3E2 148: 08D54B05F901FE95EA5B56BA19DF9120C66AD004F98BF8FCBDA9DA0874E64978EFC34877B8224A024DE12D7B926B5D83068E8A704EEF0F738A5061E5F8462F54 149: B79F53A5117503B5A0316F801B8D448079F38CB90CC39BAFD4DFE169E3C931D622AF7E26835C9AD4DB25C0D6A684E7DAC4B88B475663E05601A99EE9FC8922EC 150: 2209CF6BA43F61D7E579651EBBA0890686A9CDC1E045255494DB0BC732C9512ACBF72158D5738FF63B500AADCCBA000D25A521D41AB4EE6D92D38E8077B79C07 151: 8236F7CFFA68B49BE5C38A7A1BB67B745430D1511A08EF347383C32AAE1EF4AB2E7F63A20C9D8E5CF2198B32B7BC79B470D36BDF12E7263D669FA4AB8605B75F 152: 228BEFE5788090066D493CF87F75C666BC3C75E0B7BC63E80D38340CF9176251C6E185992B244D4A5B1CECFA42128DAE6EC3ED535AFF039769E364048C442DCF 153: 59171D498BF80731E2E35D0A32DA356419E69B8BAA5B1195D690CD8A5B11542087A007D8DE3FD000BFB03A0408C08E92A0C7712924373FD67A65218E4A4E0F68 154: 4F94A8F6A136E49069C88DFDEA9361B34D68FFC25724F836CCB021BDB74E0AEE9DDFE80B938A5C12B01F0F1CC49C500FE7709C2090F809D9E0256FC93D93122F 155: DE5E17A668F75866262BBB2089C9DD86775100C77974161DF46BE02A9578855E7C81C77263105C473FD1A2D55483063970C0F643CB25AA4B4AB45A40888F61FB 156: 3314001C825DFD2CD1CE08C746F0BE5C451027F0FAA401431AC84FAEA51553EFD9E0646FB7E9B94CBC672DC98FE9870467C176AA648EC72BF61334B13E479E4E 157: 3EE80B1422E3572B46F7CE5841998BD2B6DF3B591FB5E46851B4D54BF572A17DB5963A04EC6AB98BA07C943475AC088B4D201AFD684F30F45C8037400A7C9510 158: 3743FE18BD6AEF36887EAB7BEBCE36D5D3B69DFC306B58B1E8C6241E81A9D38425BA991A29C3B07D4F4B9C5CC762B2563C9E5A05B199CEA5833D9FA0062D161A 159: 7F9F71B086CC6D6B63052767CCD6D0349C076289F63483241CE105076B7549B3187897D45D7B5FB2147E54F056530347A1F9265E6F37953B5941272A29E2FAC6 160: E09CBBFD3DDBB24755CBE8E51C8BFF1BFF36E571EE72E6C99DDA6D507AFE3C562D437E8612B50859AD5CD608424DBE625E0162E6CB7B838F20E7B2F93F40ED91 161: 2E2F91BD5FEB5C79E98ED97C513E17D2D97B02A844780A0190264773C3040A2CF07FCB0E6424B7A0E88C221BA3824C1906FC1647AB40DC13E2D0CC507CBB6BCE 162: 8D4E87F66B3418105CD5583A92A2D2EBE8824E1F9150CB872FD3DA9C93D382C08065C818E1AF9B25875B142E70676D9A525D901EA2142E42D813A221D21EAEF5 163: 0518E420BB5680B74367F8CFCF7DD32F3AAE009A0067FEC22456CEAD0832BDC2A60D8AA7B0A2FDCB9072C0F1171772BB665C0B28CD184609F63AD53F89597F9C 164: 247197FBCBEE77B8EAF6358F71A49D784CB43FB44D99910B0599E69B29E31C4019E830F322D5A7117A996BDB4D91E5CF323DB354E902E4DAEE8057B3F78ED5B7 165: 35A7D806AF0C8167D1505B25EDB565E931864C453BF60AD7B6695035D7584E7714E21F377B35A5F3A69878835617B951977C209F5F3C5967B7DD9BEAA75A7CAB 166: CA9B60EA8DA2D0BBF46742E31AE882F5355688B071883F690AE775C4D949DED8077170F26E89A18CFC251662EA8D1FF43F5A5F28E3FB41ADD741AD2E28341A79 167: A861DC64C745B0F5D3EFB2773C51981A836024BC420B1FCC564E03006163B491126AD8633FADB6DFCB25C2EF92FD82823FE2C7F1161A78C7766B5E21F96BACB8 168: 1EE6CA0866F227B27678326FEDA4CBF59934AB0EA2E874E9EA233AA5C67141A05C1B4C950044BB6C9B9D146520C2E3779AE44187BE0DC1CC41FA7F72500B249E 169: DA1032057A25DA7EF987A2D7CF28B927D3DBD956979679F5A6BF4EA20FE1080BD8AF2DC8B1C7E236E7601BD82CFD64DFCA7D03A03087475ADD57EADFFEC2CA85 170: 22E41325474C7C7EE980314D7738947E9CE3A970B2D28BCD69D545D5E795ED50A5A1839021645D000CD4779E181A65974171C15B9B08B349205B87C150688839 171: 5FC5AD1B8B7622C4D17CCE23679FC7E0CCEBA00C1FD7178245206F866A6BB198F26A05A3D429E2C508DAAC6D0F698FAE6C0DE7FF971EACEEE84813110672F3AB 172: 2264F674AFC9743A46180CE4E4AA6A2BB33D6BF2F62AA14648179400806D718DEE8FE57DA48D88DF5D57B42087BB2FA62F833BFF87B6678606C6336CBCF34B3F 173: 65E9D1187801C74FC23C4F19698F6B93405C681B93A80D23D427D9F2CBFE63F7E2959B2AAD6CD7EF6E987A5FFD585E1BE8E314A1D502FAE80215C5331F8FFC2B 174: E0436B17C2BB096B08698F4CB448287D69322C34814776E0B1B21486A2D5B6906889A5B198FDDF699AB285BDF58783DE7913075F86ADA977DD35FD09AF336E21 175: 857BE6485722B4BE445B72C7A15A1D0BEE6C7FB2AD541C2B4F0035DFA1EEAA10D4F0BA5A124F985DEFA53D0A0554BB258B2832BC2CB5B7787D812E96A55A93DC 176: 7B2298654B95CD00307D8D983A0079CCCFD89E5788180CAF352B6C965B9BB5153C9DE25C4A0CBB5E578859660696C887280EA378A2E02B7C7F9E6CC635509EBD 177: C7ADECC928EF065C263A97A273CE8CB30485BFC035F2FC02C78AE2AC6B7F7ED20E93897C0994CAB8D584EEF9DD475AA1613159A0C862FF179C67120F6B4C72C7 178: 041A03CCE6696653ED5F367749AE1AF3C2654E8A9C0E70E467261E60023876C7271CAE545D114C32D38DA75389525CF0CF1FC0FA9A481ECF43FA0B1F61B868F7 179: E652E4A88EC1A9C4678F8CFDBFB1D758774600255165E2B4DC15F61C18B9ADE14C5ACE7E8AE72D3062B7F1787583C55B14B347F642344E71D6E00FD6F4C56808 180: 903675FD8C70BEBE9FD0DADAB17A638A2DD8089AE63114E36D28F4C75D951D75B0BCAB5247803551862720713AB45A932DBE141E48E9BF3ED9E76201577DDD43 181: 6E61016D474D2AC2984E4EAD44ED82B7129B0B7FF0B9AAF5F45CA68B0529A736B846626CEBCAB9E7CE374D744E7A09C51BBBC746D989806F1A00703A002542FA 182: 20085D4717A204E896F10C5F7E1FD429C9AF848FFF608A2C46D3738EE4FFB944381880A7A455FEC6A1A21754D9ECCF3F1390EA22EC17FCFECE2B86E361784045 183: 37216CA069259BA3244DE3933A3AD5F35712F0AB7B9C81D64000F0B91DD4232B53748B704E7ED0DD682A77D84BAC1B943D2FF7A3DBF5FE33DF455DDB10D11632 184: 1F2467A57006D96FDC75A8BDAF98907AE72AD330C0418B06513C33D86DDB800AB6A51738DBFDF1C44676038C094EB5F309B5B590EAAADA4DB09FE7590FF04888 185: C45893F92AC3E3AA3BC86A9ED659797A7C7DB949A66552ABD046DA2AA7DA9E52FF8BA2673CB44B2CB0481D599EC70020B6D5079296F2C19DB162DC8CCD64BAFD 186: 9919574ADE9B8640BB0EF45F98D1DB6FB7242C433D86CF6D4BD67AD14FF15D74A13F796429E312BAC581552E6597BAD2792F31B2488ED300C6118891ADEE9FB1 187: 034A92D00A172A5F0CE717FC38AB8D68019F500493899401B563845EB604ABE0907749AA830F91B53AA7C89DFFF86664F8B123AFF4721D790A58CC22F36A560C 188: 54714E69859C60B07C7FE34859C855A37A82204D723F1A695F78D7765CE906D109FA6144EBA9E7E7A7D8343A99495E72D160DD468BEFB794D97659B8E2D8F1CE 189: D6CA476F7E68095DFCEF4338BD6466FCA90DF78A17DE9E29111D4645B0DAA0C6E98F156C0EBF9134BC28EF9E0EA67E6D839027DD5CB084E9EBA899DD3413E222 190: 86EB8C026D6BF090636F01F623CD98B960D08E521E44697F364BC1AE1655B9AD6FC3EA38C929AC9A244D18E697342594F3E7DFE605954579AE4042CA69E65AC3 191: 1F63EE615E9B809E3661C77B5029C78A92DC4BE3CC4DFD8BBE78DC7B7D990BC717238004969A8B854CBA04B4D9B30AA1A1964264C47F23D9BCDF45C74FFFD918 192: 0351F475C711D068BE7B0395D65343B5E249FEAA3C3F3B6B87100C50306EF0340F60EF36233F0E6287057EF7BE8634BFC4D46B49E4A8F2CC4839F42F486A16FB 193: 16645F9C0ABBDA602B7436DE3B1C55AAFD1E844057D51EF80A96CBC2FAFF6E3B2706B45069C90A52D779E101793EAF4C9AE85CAD0A5A394164F0BF34C189A2A0 194: 821E46199F4FEBD9C118D49B1CE9FFE953113EB6E4E33DA9E39C676399A0B3F792C2990A9F75D729E58EF750857C07336526631CBAA5EE0643699C8E7B7EEA13 195: 64CB83ABF2BB0A94451F2B9C3EDD76E4A15F9D1F9EE32C0607F5E0951084377E484A8259B3C64428293396F78E6674CC3C027CED1BE12F5671D328D131740770 196: CCC1A68114DF54BF467EC49CB15CE381EBA7E6FF06A93EFC88F442F8A35827D5DC6494A4F39E8423167CC1C3269A3EE6AE68825FE3E2E40EAFB75C8D878FF88B 197: 94D38693F1B1A8F1013544419C5B3BA0CD79B72478A91CF3AD325E4C3CDCE092AB667572233A4F8DFF132401968BC74C553AEEE96D530CA4E5F6D427F9D2C422 198: EB080E256FA9A5D51C3DF577509B877563958704C0F1DB645F75CE24005D3B12503BDC26FD3A66E8F6882D3491428A4932EED6F5F58532FEAF521BA5FE05B70C 199: 9A43D7D0C42D7B5409963339C9D9805BA59ED8A63DB144165A3C759EB9F5D756E6288308DD2FE460CC50DE26E1A1C1747AA165FE6C8A1FD5B0F7CB1373E28CAC 200: 986058E9895E2C2AB8F9E8CBDF801DB12A44842A56A91D5A4E87B1FC98B293722C4664142E42C3C551FF898646268CD92B84ED230B8C94BED7798D4F27CD7465 201: 9FCCC4EEF7571A2BEEE06981856228CEDAF3BD412E777F4AE8524B81C373FDBC210795C1E788EE7081BA42EC3FAFACCF2F386A9096AC719E6565B4E384E390E2 202: E4E8BF0BF40249236FB88C442E6668E3067ED6001189053A3A81EB755798911258E25CACF7282811DD5E5147811844C4B5BF52FC24A6862BCAF9407F2E38EF5D 203: 317ECED703044C1BCE944DDA7114DD1E36244DF6A533790FAADBD0B8DDF1AC0D198B593F0479A038198F4B94AA6ED294168FE0EE800C02E769EE78ED45249945 204: F5FA1EDDE359173067E463107FCDF00EF227CBBA0EC5EA02EBBABE2C79B12E793B98FD3A90A72BC26240D994F53DED65FE22C6FE87EAFD01B8478D1E8569A882 205: 6323E2A8E380CE86433D5B8FCC5E02FABA4ED7F9CE5BD194F7CBFA36F65844B61A7BDF8F131CB4B28C56ACFDB99CD84830557C571FD369650B4608376BBE4FDC 206: DC6BDB69D1C6111E280F993635BB59CD6E7B189166DE593B71E194C5F218D67B00EBE0D028E944976D6538DE410C4D86A2B6F272BB94FFA590208C644F99240F 207: 2428590D2043634FB10268435EA90ABD082D45317D2C54D065529F15E180438AB18FE4CCC9129584804EB04EA1CFF646FA881878520BC01AFF392B6D7D9C0369 208: 1A29341BEF679E5351911809DA190BAB8E665A9375BC2D477742176A70A6BE8ACE4A35645BF8DB97AB9BBAF1F0313004AF8B4CF10ADB26AC0198AB1D45D05C46 209: 0EF4FCF3B2010921C58056B2BA367B4C09F5325E6AE9AD732AB277281D4BA797A847B1C6A74D81523DEA163AB0E556FB5102C14E8CD94AFBAC0AB0A921BF1A25 210: 73C65AF2A53E8860BEE63AF0BD8A457B0AC8D3C5D243FBB1BC3D67624727CC175F3CA133B26342C3401D75DCDDDAD9A692D9A2B1264E90CFFD4BB9E6E775DE15 211: 18D3DE049396E2EA541E15C31C0EF0E0BD90CCC6CA35663856B94F6F18160D616667C55F3ADC1B33E749F60BE50514A4F3BE48ABE2E18FCA10F85ED0266972D5 212: 34DED45ED26FE224E0C5A66A193C11A2CC0786E61D421034B3BB16175019C95453F20BDE865DEEAC5C2BB5C86544641482B51C4E61D9DDACC238D050CFC35776 213: 025D211B55974BAF086B139D8FA1AEA75B627CE1AB894D52F8769874557BE5944D27FD4BA3606266BC7F50D1734436C53D4555A1D2DE0DD2AC51D7F2FA373867 214: 08CD521B1F13440D57001F30BDA0029FD8AA17FF26AFECEFA2CB7EE1812FC79A694ACD0BDA98184154B72FB7CE305FF4897F466CBB3972B4863FC88B3DA52C28 215: BA3BF464071BDF124034CD122451D3374AACFBBC916C858B93E191006235F4D741564BA1DE70372269C122D360121DD3D427853BA76C6B450BB46F4156EA7524 216: CB0B3250639B4ED947BE0C83EEF67D370DE76AB901F607F68FBF1BF8ADA15984DDA7BECAA4D7FDD55FBFE479EEE3F5ECC9CDA7BAEDC9DB7D35DC227411DCF20E 217: 8AFA4024BD96BD50323AFDCF92A7F3E7BFB4C927108CF81C01FD378F61C55D850020DBEB88C6528B8FC141C37EA4852481C14902878AFDE51A7F1EA1612D0324 218: 27057269EEB73333A1A8059D6C9D6FD5AC89EC26500F6F9838CACEC20E93F1713CF5569E820BD80969547D77E56AB0CBF57F03182EF45AC8BDDE114470C6DDEA 219: C79C3D4A4608C7CB4A3D0C14B28CBB96364F44DD8651F36D908AE502E547AD7AD5DFC10DA26CA26C6D9E51CD40F6D7F1BEA0A03358967D867A97333DA8ADF3AF 220: 9DC3B1EF11D85FF8A57330FDF91D5B5AB142FB89A72D880DAE476E020755C2F3B4CA58C9ED36239E8807C059BD66F826EC517B7A44187E7216E48B683B567076 221: D11A97FB7B967E90C2D39EF42EBE49327CD58EA6977C84275B01698E322DD97024A40FC3EEDD96207310708F737E81B79659A6C7202E96BE7AA34D18D4026F63 222: C9BD62C0FCE47736ADCD9275B46845E4ECA23B73678693FEB8E21909EB8405D4B057AF2AFFD7E667E047A07E6ACCADC2A58D7360C17689769DB009F0A7795560 223: 7FAFE6ABE7CB8C109B18A14BC4FC2E4FFEADD55A43AE7DFC58D89B9CCEBB4467FE4CC163FF6EB16C8C71B8EFF12E7891D11D3DA2C6DFA8152DEC52B232267B6B 224: AEC37B2A1157708142BDACFE77E5204174F539D86A12730BBEF6386FCA098AFF2A5C31EA1AB21D3B4537531DDEB27CA9DAEA22F5CC8C9956B2F2595F53BB931C 225: 6B005CC923D9AFF56334CFC7A5E3ECD70E97C4247EB372A3180E7DC5BEBE676E72E2FDFACB74277B70E15D871819626F46661285DB04B3F825C49EEF42391B5E 226: 509B5C993CDF61F8F507A84BBD7D6D7AB090970927400043D39E5F47DC23AC289F5BBF9D3246EDB174D9C5D72BA7A066DC13171EC15FF9508911464F8730D395 227: 00A05302C3A60E58C4C52847F47379212A918060931A72BC660D88E7BF5599DF6C38DE92452B4823B4725BA3EEE866235CCF4D5903E91714CAA230C6D6EEBE45 228: C4FA5EFAA31CA205A732FCD5DEBED53C09A4F30C5BD9ADF27F8C1DCD4B2730925BB6AF176E2E680B2BE325F7DDEFBC9EE6C1CBC4F0426ADCB5CBF18D1437EE6C 229: D125006B8107FA63C375A79AAA0EBE82017372B7CC65C3157CE078DDBDAEE8C569BB84FD8490F2D66D15FE73C6881245761AB2B1D4F056637ECA70641745CDA4 230: 01C7D098DCE4E40A69DE14682587FF2A40BAF9833BDCC6413AB54DB0E64262F290D584CD5B21C6558682C50E1E27BF53A18A16D72ABDE878C3522156C9F04DE3 231: E863DA51CAE09500F589BE05CAAD5788587E2017907444D76F547D6F30632AC658EEB8585733BBB815D2E19EA046369ED3B81AA773FBFFAC316162389E015A71 232: FD8232F7B79BDF9CC52FF0D5DE1C565E9D659BF19769096895D182A88028C1CDB7387DD240128A7ECFD2708EBA7E9E3C676D6E2A036E1B993940F5CCDF1A736A 233: 3BF8572CDC7B825CE7F3222A3DB87F1C52FBD1A8229B957ACFEF2047C560567483C479603A3C0B0F1B2DD265BEC257D1A32C651508D7A4DF501BC015657DCAC0 234: 23FC530B031136A17B8B2FCB55046DE7271312EE3E77851FBDB05F78A294815CB2169079168E07647A2BD5D05C1BC2B1EF1B64B929DAA1F9CE723D448C936FEC 235: 83D10057C7FB494FAAD289B4FE5F093DB2A0C7D79A298173DA735CD5063232BF9E5327A7B4AA795C99F323045790B554476F37EB9D04FE3DF40C047E4113A720 236: 0AA201EDF4124F421D4515554A1A642E3B9D18C70E09E83A886D6F0CAB0750D9BA1FFEB9C587F3ACAB0D8B9C1D83D789102F0E2A6CFF885C50F485929DF4602D 237: B85CC52981751513B917F58305AFFDDC7D901CB3BB1D1BF5DAB058DEC9B8CDCD2DAE543D73EC6AE0889C9D785F9178D207059D994E1C80706EB28AE65AAA100C 238: 068FED72E55444AE108EEFBDD59A96DA4AEA3D81A6642742C38BBD4EAAEDA6EE21FB8702C2F95152F1F997A5F40F06C54619481F2EC343AD33400913D6FDB4FB 239: CB4C7FD522756D5781AD3A4F590A1D862906B960E7720136CB3FB36B563CAA1EA5689134291FA79C80CCC2B4092B41DF32EBDCB36DBE79DB483440228C1622A8 240: 6C48466C9F6C07E4AB762C696B7EEB35CFE236FCA73683E5FAB873AC3489B4D2EB3D7AFCCE7E8165DBBF37ADED3B5B0C889C0B7E0F1790A8330D8677429D91A5 241: 4F663484EFCA758D670147758A5D4D9E5933FE22C0A1DC01F954738FF8310A6515B3EC42094449075ED678C55EE001A4FB91B1081DFAE6AB83860B7B4CC7B4AB 242: 81A70404857420638D72672A2DF5A49D52B9F9F38B385D8C5129D6A2B82A682CFEAFE6509266E4B00F6B6A07341C2F64E4D4F2152583ED143E3DCFB14C1C216F 243: 31F655A1334E1A45584F12A22E03B09E3C69ED0E1D0FD573AD0D56F9C86862299E333ABE78590E97EEAA5C2FB14DC9F34FEF6DDAF6E7A9BFBF68CA6631195CE5 244: B62C5102F97E5C4D7554790A4CF53A58D3EF44C83142D6E009BD1F6FC8F3A19AA1B89DA8DD9BD1310827A5BF662BE7CAC750C48E6ED91313E940D7D9E5EB9C22 245: 380023C0BAC4C9524FF6778BE80CDF195E36FCF460E8CF1BF04E5C2FE08E38C35F183FBCDC3726FF26423F351C507279F6258F2319EA1403B6C8A3DCB384AC7F 246: 473FC167C7C4BC40B17DA039EE09FF3DE884879557E40C52C1981AC419CE021A090BBAE014822D05714077008988D74FF151C927AA43E88CD63FF2CCD2012AF4 247: 006086E61959B1D66C72E754427EAD5E1D6C02D8409F5C32B2F5AE448F54682B504A1ABC0346CCF39BF66A8C7B69081E886B47A7D0B02291462391C95351EE40 248: 3828B2ED548CFD0B74BB34A1FEAE030E267222198D7E387E7FE3ED503905A25D4C3301A9A47E78372F685B05847062476C507708CDD75580ADB579E4CDC79AA0 249: C26A7D5BB103EDFEAE2F1201BE58AAC127F69AE378DB04156074E991745D4AA5AAB3BA064407DFDA8D34E573B7EC1F9F37CEF01ADC17FAF393C262A09F2C4736 250: DCF82307195035A668097514FF1A10E0BF0E802B4945A702D2E17AF6DE1D3D9BA49616DFD16D802054B5219CA37884385E87A713B4EF5C7FCB69661C7F56D5E3 251: 46049EA0DFA5C49429E15626AF4AF2CE0A9DD2F308B99BA6E6E3F3088250A146870FD0B53228D5A1F1BF9859480E1B7A3D3DA180AEF4D5D41BD2951C4E19426C 252: C0A1FB6C0A65A0D1AF46A5FE86C8A88E8A86F83E36317F435542927C98E74833C887CA3AB5E792CE5E3E21CC6C6AF437349F5A66FAFC4DA79742491C643901F9 253: DCDD20CD47B7C7D011E9DF7855B08336BD5007C4435208BD3B914D7E503B8399164A155697E68A1B88A0600BDCF847A114D98FB773C81FEC817B92057A6998A9 254: E2DA07644DAA73B66C1B6FBCDAE7FF28E3B9024F0BC5408FE02C18E3744CF9BD6DD54EA7BFA1F6F3A81C8560FB938FDFF9A38A29853A3A819B58D10213A290EC 255: 15025C9D135861FF5A549DF0BFD6C398FD126613496D4E97627651E68B7B1F80407F187D7978464F0F78BFEEA787600FAAEBBE991EDDB60671CD0CE874F0A744 256: 1E7B80BC8EDC552C8FEEB2780E111477E5BC70465FAC1A77B29B35980C3F0CE4A036A6C9462036824BD56801E62AF7E9FEBA5C22ED8A5AF877BF7DE117DCAC6D Hash: rmd128 0: CDF26213A150DC3ECB610F18F6B38B46 1: F069A435C14A8D4B02A7BBAEE02D0BC3 2: 48456EA1CD4C51DD8E1130F625DA4F8D 3: 6E41F2AE95605779C74CB5ACDFB361CC 4: 0C7A6C73E99A5C65B12D3EF47ECA9D2B 5: 3B80361C079D1B67933455D00AB1428E 6: 0F74C4BFBFC740A027B1D5BB9CAAAFA8 7: AA54ED5DA34CE9205B64D138538C0C1F 8: 08445C3C3E71434DE375CC2071430EBE 9: 1FE0AE641DEC6F8C172F0E27E9E73B9E 10: 4E8152B7EA8F7A31D8649A51389260F9 11: 0F851C98C2B997C2459B34CCB209E481 12: 52D27461FD7E095EE3C6ED43BC24EF23 13: E9F3489135F3D90EBBADF9F916C34920 14: 36D527B693D6531A5E4E15BDE9E4A670 15: 57433A07CC200953B7FD440253D5E476 16: 4A91FFF90756026A90A83927066EC911 17: 5A247C26BB1BABDF1009B6B4951FD76E 18: 002DA29AC9F51F065A1E371660BB67BE 19: CFFED09ACF01DEC9D3891033C0973953 20: B78F28AD3460C99D428AF24E2787EFE7 21: 5E203157AB6BAC57660F3D25FF615C95 22: F128F5DEC3A24AF34AD3E7F3883C8051 23: 2E05AF10A6CE9AD1E0C0FBCBF69B1C9E 24: 67FAFD9A5CEA5D41863D03AF2932C5CF 25: 5ED7E86651AC4BD0EEA718C773812977 26: 6BC74F78256A98761981882C3CF7AAEB 27: 44CC573B964002D877E79B75E4433E41 28: FC02FF53665B52B58DE38784E2C28E92 29: BC4D69312DFD24EEA219F29FF2AB2072 30: 0355E82F130341EFDD997EBDF4469221 31: 453D500D997FC85F6AE16365D83ACC05 32: 42DF4C5A3844F00F77ED84E125237113 33: E782D7162BB54E735F7B9FDD75A3F14E 34: 78993013EEEA7B14999DDD3979191D74 35: 27BFCEF540F0782E9A28328E8DBEE59B 36: DCF00356DCD264B7E359F02D7D2CDBB3 37: 9EE0BD7F55EBD844A8D114F83B3E8FC3 38: 01EF8F3154BA9B9B817AE717FEA00A68 39: 4DCBC2AA56D785CE7249761791442BBB 40: 10282C07B870BCCE0C8DF9E68B4C5DAD 41: 0757B359AB2D1D121BA01BB345A12A87 42: 450AEDEE570A2E9B1A19D5B4747B2AC9 43: 2C45713898BD259B10E2352BECFD6DE8 44: 3E92731175E510FCD07D28AD47DDA0CE 45: 6A8E5690AD4AA2180966AC1503A81A18 46: 820BE195E2AE85C115BFE3C341567030 47: 9C97E1F0E7DA29A0527AC4F59D520100 48: E1257842EA15216543BFE84521B9FDC3 49: 42BA484CB70A58EB3EB5DA43F1D5D5D1 50: 2C674397A81CA35EDF1FE77B442BADD3 51: A3E07C012A7C67D2B6557F4A8B4DD031 52: F01789A2E0379CE16D87EEDE671171CB 53: FFF1657EC846507BDECD2DD829DECDA2 54: 1673DCE23D430948AB818D47E83BB5CD 55: 37CEC696967031AB2122155998A07F51 56: 320B7D4DE17A731B9BA5CBB48956D605 57: 1EB07088E5F563DBC5DD988ACB84B048 58: E4DFE704E4C25D06224D2560B4650467 59: 6C072AD491BEC80667A6D71D9C8F2FF8 60: 53DA8AE3F36FA8F85072A89962F39B76 61: 40210D1C7A728A27E1B5F92057DA4765 62: A4C4E5F271F3BDD74C560787718E8816 63: 4466033447F1E1C9BB107D152BF06051 64: 406C6EC2643CCEF38F964864D12C9191 65: 19F725CB43B171DFE18EDCB90A9DD900 66: EFAC3C9FBF1AB0C0F3601C18FE3F0212 67: 9B9BCD32F735EE353D33A657C2292475 68: 68F4A4294C640BBE4B1E90FF107E05AC 69: 3630FD1C9542A56C851140A7D76C0D00 70: 21AFDFAACDD8FAB91027A61F8DAB6C91 71: 2C7AAC93B6CD1F8E23AAFD49F04C69DF 72: AE4C5124059CFFB3B823E68FAC8CFB33 73: 79E95CB7E752863AA87A7693D0677D89 74: 1B491E33A96D9838398A4F624E773DAF 75: 1F3986FC593D8A8E927C82DFE1F538F8 76: CE64F09024A907E76726E29E1364E606 77: AC98817981B59789E7C7E9CB9F70FDC3 78: 3827B4B077493B289C25EC3E91B36D26 79: 75295EED68F750E506C60A780B7F0285 80: 4FA47F32992EE6C96C3B96B6A69A6656 81: C52E142B7838D731FC036517003FA73E 82: 3451812871ECD1C09E4A95CDC80369B2 83: CB5261A793A55DB33016ED27A35A20F5 84: 2D06368ED98E266E81A3C6491BC24890 85: 677F6509BDB3D44BCFB088A81BFD96D8 86: 6990256193FB0697862AB5A45FFF082E 87: C88D698EAF83E446C025EA915998EA01 88: DB8F672EE8129BF4BCE25704DD57BFA6 89: 807F491456D7E28A36AD6E934B053EA8 90: BBFD55A483CBD0F9DFE18FEC5070A166 91: DF7735106411CC29535664D85ED81603 92: 24FE3535DFCC295C2F34F3F88CACDC88 93: B80CDE220C4199DE303BC97FEE125048 94: 8C252310E9A71C7BC40C3D2011E24EA6 95: BBDB705F5660C50C5B0C87CD812B76FD 96: BD517928591240C7E63C8D9F957F6A4A 97: 78A534AA0F4250EE83D752F3E6940148 98: 3346EDA882F00D6073D133CE609D3B83 99: 51EB1D3235CD35A2386E314F815588C1 100: B4860192E79C1233A08FE595C084315F 101: 79EDBE3E80887B4F741199295347117E 102: A2793EA5F25492D32D315B3923E945D3 103: E398223EBEFC56D3437AA5FBC5345CA5 104: D3E6593D69B24069AF0374671E466930 105: 12D63F5AC48F99BD59EC863B61952C1C 106: CC99A81A22B62A0FCAB4AE889112A8DC 107: CCC82CA5D35A421FFF313F90B9D1A675 108: 5B4A2912071CC36CEA626F9AAD34F257 109: D21FC82D78AC98C5DA436388AC9AC6BE 110: C2F22C7C16DD2E1BBFDD2BE7915B869D 111: 2B5AE5D14DC053558A1702959367760B 112: 7A6A3A6553B2C3387BEBE119E80CFB2B 113: 7E2206BCF666B89341CD7615D0291E3E 114: 93D87A658259C7E9FDD0BCDF93A24356 115: BDBC0B062FA3D743C1B070F2AB43D180 116: EE0A575AFFC966F58B91BB66CC1E6B6A 117: CC24CF8DF0798ED2CCED077B06AF1BAF 118: CBAE264BB4AE635A15D8FDCF7F9A6852 119: B879B9BBF61B6F291A8E4645B70EE06D 120: A6F88AD4A16F789A58F178799279B40E 121: 3DCB6B1674608B11F496F45C9828F90C 122: FF34A1C7748C5B5F2F014ADF57241C43 123: 1A77E2B20ADE5F286705251495AF04BC 124: FD47EE73738626733CC63327D4F5EB7E 125: B9438B50CC80CCE0303244713853A0DA 126: 040BC7876B31E22590F5898068B19859 127: 16ED82C338495D067BBE1D4AE73345FB 128: FBE1AC0EECF0AA2671A6F25733E9711B Hash: rmd160 0: 9C1185A5C5E9FC54612808977EE8F548B2258D31 1: C81B94933420221A7AC004A90242D8B1D3E5070D 2: C0C355CA556CFE356ABC0A5595BAB1364BD86444 3: 6D8D360567AC2CC8C4EC11DEEDE0ADCACDDA388A 4: 04DE53FED2BBFA80FA79698B4C5627536FB620A7 5: 9538F24F7432E952F030BBA82C9F744365035197 6: 817ABE77EBB7EA159AF7BA7DE1EBBF034FE6CAFE 7: 340835AD791316DE50DDB59838F3EB13F5521228 8: 64B7269FA971B162612265C73B9911F53EF43B63 9: AFDD1E7F8E39C63DEE7104014AD9EB32B855E0F0 10: CD2E472470BE8FD70A306DAEC5C59F485EA43929 11: 550844206034AA74E37D813FF29973D3000C1DBF 12: DC24FD5F309A7BEB9A7CFA7A354F2DB2CBC15AFF 13: A814B4CBFAD24B7B92AF0E16794A793DC16D10A2 14: 6C316617808A930BD29972B1142C0AEC89EF00AC 15: 3286BABC7C4635FEC52F67CEFF1471E122D50258 16: 696C7528A3545E25BEC296E0D39B5F898BEC97F7 17: C87DA6F87A65CBCBC4B02BFD6D01E26F8047B5C4 18: F1AC2E0951EA5875B71723BA1A2158DB49EE073D 19: 091A39765126ED406254E7F810F02E0A6124C6A3 20: 4002C0305550C5A726705DCF8D3880C54FED0453 21: 2B59904E1585334B1298AAE6EAB06526CAE5A232 22: 0EF94DF816593728611664F4ED6A0C4DA28C5AA9 23: FE7AB8A5B0CA3C86B6524E3333490D0430E9A4A0 24: E748023DDA7E4B77DE8A4424744331EBC62A6590 25: 96147FE511BC64D9493C795ADE8FC71A78FA8C23 26: D81D7D3B46D5BA875EC2604814616230D7A075A1 27: E8245E6537FEF146A2CF6AF9BC54472BEE6213F5 28: 231CAE27B96A78767A0915A529ADB6B72A8006B6 29: 4D6BE5BB6D29A15A259C8B7BD4827EA82F514425 30: 3B00599329120E535A5D1A46F35AD03CCA27F9D8 31: 2AF4160DADBB84707F7355177A4644E4CF577DFA 32: E6BABB9619D7A81272711FC546A16B211DD93957 33: 1E374AB924A652FA36B395D654D226BF901B6A04 34: 67281E2EFADF2EA6211B549426D3A598B5E1F291 35: 993464E56DC035716064577245BCE99ED175356B 36: 298D2CEC0A3887C93501307B51F75BFD5CF0AFEE 37: 2A0A02BF4D63CC09978EAF3B3B85A4DE8470B025 38: 6236F6FE25D5157BA95BF49EEBA8987A6A301D2C 39: B4DD7121567E8A428F16BBD5A8832FB2EE68BC0A 40: 5FBE6037F8D8EFAA9A315C070CE3373080244496 41: 04D5E112C47EA03BB60CBCEB9FC8ED7D92A68C0A 42: 658797C7756256C98E04E6718D9F8952F90DA672 43: 6A27ECD40BDA4CC81C599DE94D0D2904716FD457 44: EF5AC5B8E7A00560E79DB54AAD4B97E996D2745E 45: E67EE5275910B48F7D248A8B844DBC041257D695 46: FFD256BCBBF0F3BB4DF615B4236C147FD09F4F1B 47: E83A4B18C347F188301DD3AA78265AD3AB3C0311 48: 13968583BC017CF0C5043364A42EC0D97E923711 49: 39C33EA7C4F393C4DD4B882F73FDDAC2D7FE1EDA 50: 50B0068D46AA025615053132BB53F88DC062DB2D 51: 434198200766DB6CF48C993906FEAC2B47224A3F 52: 004FBC3820002357434D6B8ADCF79BFA6F9E3DD7 53: 13F7A8CDDDE021BCA6227EFF1A71DE19AF399B66 54: ECAB85CA0C2AABF18F5359F94AAD7578A08AB5EF 55: 3C86963B3FF646A65AE42996E9664C747CC7E5E6 56: EBDD79CFD4FD9949EF8089673D2620427F487CFB 57: 635B0D05BE254D82503A9E1DB7647DD1B5D5D6BF 58: BE314B818A657DDEF92DF123FCC17C1DAA851C04 59: DCFBF0575A2B3F64B24DC203BDCB46290B21791E 60: ADA425E87A8DACF9C28B67E8BE4B204A31960004 61: 35691DD184E08A80230467ADC6E68599B7295A51 62: AD1CAEFC7ABDC90E7877D376957532B7D91D7434 63: 6D31D3D634B4A7AA15914C239576EB1956F2D9A4 64: 2581F5E9F957B44B0FA24D31996DE47409DD1E0F 65: 109949B95341EEEA7365E8AC4D0D3883D98F709A 66: AC745186C82DF8697458326051A6CE7E4E9C1C1A 67: 5DE50BBB11C62ABE22E7EDC288B7D1B6A1CFCC60 68: 7DD54CC4E8C70A4AC55F4C0485A4DFE139253757 69: A5E0EFB95E6162F9637D58D3E4836F9661D6A34A 70: 6C77DE7607A361D22852385E663171148C0499BD 71: 3467662275B136AF096D84258B17CA5F23BD6397 72: 1C56A69A826F95B8971635AA709978A441E75836 73: 9094727596F086BA28956A6BB69CCBF3B2B29FA6 74: 8C0B6183C33E902C22F17D81D18144ACB7B66FB2 75: 24ECF7598894FFBBC7D30FB1EA47092F03C398CA 76: 6A02FE0041D98AB7AA6916A5245BFBBCF6635C2D 77: F3021EDB24459533488660512660DDFF7F451C3C 78: FBB7561C0065C90D7B8182018EAE73A18288E968 79: 32784F0E354A20688359B6EE7FD3874714C48677 80: 8BFBA0972D36739EA808C37C07F2E320ACB4114D 81: 74EADA88C8ED0B649FCCC36DE338CB538242FE10 82: ED812B77C12856DB371E6F7DDF15A59FEBDD6962 83: 27021F491E923CF0B191E13ABCADDAA72586B769 84: 47664874218C135C09ED40DFAC26E06733AD02CE 85: B39E492616FDAF2480F13D6E46CEBECC1FF5CBA5 86: DE967F65BF6DF26150AF866FADCA58C45DDC337B 87: 8F2E2D23CC6A2B52B904032119CE68649406033A 88: 247FB8B2BD1BDC35D0C07EA10FD9686A19E4723B 89: 9D1E80D5695569D0DE28587D37103BBB0701E462 90: FA5C338E7506AC5418C4FC2C04AA933588892D4A 91: D6BC93880FEC0163E3F223C8A64BA0879BBB0AED 92: 8F27EE9C8A923C9698584786B5227CF17F0F557E 93: 4C10ACF2F404236E2DABED0BB48DDC6D00AC4B16 94: D5166CC6B779EB2D45AB3222181064D05FFB5E23 95: 13042EB8245A8C5DED69CFCC1F1DB264889CF5CF 96: 07136FE8CC1A03673891BC614E29BE79EA02D627 97: 73C50B2751C502572492C801C28B02C7E9F61B76 98: 8BE4B71D50C2D2895B9CA359ECB69F90CDCB1DD5 99: 36A669D7C1DA8E23D07B29BD6769DC324EB6D6B3 100: 8AE5D2E6B1F3A514257F2469B637454931844AEB 101: F16396E005FE5ACC34EB53E6086F477415794BF2 102: 907CD2922CA5F62F79E17B28AF389A38066E2C9C 103: 62C9351A21A50F2150367F25D4C166C63E771C32 104: 8809CB529232A0CB22D384B70462B64D93B0EC1A 105: A85E4B4260A836BF0DA50B83BE1080D98CEF8A17 106: 21D2A0D78435B2590B2C6366439939B9B15246E7 107: 204FFDFDFCA5D46CCEC5FA96A778BFCBEA70BCE9 108: 01DC05D6006E12D2F63A8F061B00D18CCA135D41 109: 30E67D3FC0A0A6D2F257AE24EA8C168A4B0E0F5B 110: 9B9454E2B42908E57403871A64EA5E930F35B70A 111: 9F72DB053BC5370C786E34013FB8DA5958000D5A 112: C1BFA4009BFEAA30ADA4D940FC40F97FFEA3FC39 113: 26FC30BF64087DC3FA4CA394637D15F73B7687FD 114: 36106E0DF24B7DEF46E9AEAB7CE0D784FE619D9D 115: 0D82262E443C3C56565EE35776F95978E16F1757 116: B19E6C73E94401020B14ABBF19A15A6F0C9061AF 117: 68ECB5552C7B7B26940A82B6A67B0F4C62EEB871 118: A834797B79DBB564AE587003EC4B74914A1580C5 119: AD430B4283203A7B7F338B9D252DFDBF807402BF 120: B89CDC109009F1982C8B34FCA446953584D3F6C4 121: 8030CC5A4F55566958A5BFCA97CB6F40B9C19279 122: D0CBD1EA711E2D405DA5ECC2905DD8A3A3E83C37 123: ACCDC924549D314019C4FD1AAC6AE3CDFB81BC84 124: 312933643FCAAEBA4DB9BDE6EF7D6EFA70E37399 125: 47F11AE47E2E693EDC0B06351E935C9B5DA42A35 126: E4C6AA211767C15E90935DF552E4EEB89F23AD50 127: 2BE8E565E24A87171F0700ECAFA3C2942C97023E 128: 7C4D36070C1E1176B2960A1B0DD2319D547CF8EB Hash: whirlpool 0: 19FA61D75522A4669B44E39C1D2E1726C530232130D407F89AFEE0964997F7A73E83BE698B288FEBCF88E3E03C4F0757EA8964E59B63D93708B138CC42A66EB3 1: 4D9444C212955963D425A410176FCCFB74161E6839692B4C11FDE2ED6EB559EFE0560C39A7B61D5A8BCABD6817A3135AF80F342A4942CCAAE745ABDDFB6AFED0 2: 2661D03372ED5C961EE23F42ED9498B451030EED2FD01F29178955529B2F8A758F0444087C82AED85540C8217E959EB8CB43EBBBB77A7E0D2980D6406AA2190B 3: 7314E8035788304E57E68AC9EA89544ACE6D2379035697D91B98B64B105130DC814B67A4B46B4DF6C103016B8F7C7403E0B943F0291ED6909E2219B6E18E89D8 4: A6C01D8CB93A5CEC17A9BDD270B24C8EE78686CAFFC454F253D9B8DAD5398E52304CD57F30F2111BE78FD98338DD3A41FD8A45124C940C4A59F270100DD6CB6F 5: DB22986F9FECA154CCF0E7DAD914AE8C0851E170D116E9B550C39B373F109FD073395C0711745E40233226F96B5FBF6C8EF1D7F8E2E4AF5375821C897EB18514 6: 793498B98970BB3CF187B0A28D353AB2EEC8F6CDA12E6D484CBCCDB96B2BFE6B5278CDB38C9BEDAEB59A8404645DBEDFBE1FE54227947E226EDFD36114067F34 7: 052A7C4EC5AD200B6B8131F30E97A9A5DA44899E1C6C31BBE078058630D5E208FD6F2F51A796F814F8AD048D759F8DCE442C405D96D6E1B1A197AD908B366E98 8: 219B01987262C597603DBC495792F2423E24A4BCD38825A74CEE8ED91D55935296D80E73DB43A78FDD6119233A31DA5940C6E335EB22600729478A20F61A56DD 9: 4BBB8746D1D754CE91C27F3A6262ACBBFD4A38D100A65ADADD3174ED6EF8F6AD343F0ED2DF28309A6E979E02B12E732A3E70371EF1E0935E8A30B7C55146D9AC 10: 81BE2AD26A90BF502C9514F46681276F927E916A630FAC442D823FE4D8EDE0FAE2E8384F3C267B56126F0C009BF8689D475C53425322BF8CD7F6C80CD2C725C6 11: FCDEAB03C0FAC7939E8478FD152EEC2408D4A6C0D829B55AFCC5184C50706C253676CF68DA3ABC1C1AEEB5822898C5194AC801881B8CBCC8DB15930EAAEE9373 12: F943E5CD2DF74699913B25EEF0B08FCA6BAE9E66BC073DF0BD950CA02FF17276F4A28393BCCCF6E567024CBC6C05C94EA912F1B07034AA375009F594B25D9542 13: 1260728E085D172EE82065B3F878FE21F550748598E72A40F4FAC3F54B72A99E6B3CFDA7141C7E5BE123757AE4332C8320786408523DFC8655D7E1F7010792B2 14: 67EB4E93961EF18A82152DE2882CC5AF4DD1254732A8FC1959147268441A80EAF0E0B68041F7CF013313ACAD044BD440F1E06D3E449D206433F3B52BE2C9E7B9 15: 9AB90A3384DA32A03B31DDA21732B398358DD40D7586E836CFA047961360CEA2F1E3DD0CF2D90CBB57F68C4334110694A6C1BA17B1E9E533E6CF3A3ACCEFF84E 16: 112C2ED4CE732E21334D7248A30E683246BA602AD3681BAE365E857AA840F1F80FCEF1B9ADA33AC1F9BF6FB75045F9E61449B26F9201E482E7F2ADC8ED9A1D80 17: EF574EE7B498AA64F3ACBE1972E42B873C6FADE053A1459AB52D5E5B49C0AFA0C62FE901ADC3FF07A7D0ACC459C3DDB3F6D499C70B63F68B60B02E2784BB9AC4 18: C6185B5836DD3B160695E5E27058AB266EDE91A5417DC086988EA5181DF5BA0C51DEB11F6BA14AF2847540BE368B6C561CD976809E2D9982F4D49F96E0AF4F7C 19: 8510D305A5E1AB3A0832B242ED402BEC2D70C24B41BD840B8D2DE436A6B4DBB7CB5F7F9F1432E694F0CB1239EAB0DDD92E6D0C7E96FDAD5F8E465E286D7588EC 20: 926800FF566CAFAEABACA9990772EFEC8AC956C3C572A360194F95AAAAE477F98AB7750B2710E262D039D8584BE79D93E9E6405BA25DFF6DCF29C54D748DD655 21: 0F0B98CE94E2CC67D36086D153A2DF48F20283413407C3CD0570B619871DAC188AA37BA30BD706AFEF475BDA7AEFAB63055ADE8B792F025D088B51A08E941B01 22: E6538F3479D33979F046FBC88D4BA785B072EF58877BFC9D1214FA8374B78DA6895D5A4F4E50E6AC6A237E48A73EB18E4452E7C8AD50C82238FA9B323C96935C 23: 378E83B88847F234A6A2FF7304ABA759A422E6823334ECF71E9C3C1F8B21B016D9A8A100B6B160772FFF12482A50613BD832EF534DBD1D4D055F3227C7513F11 24: ECFC0F6C168962197E181C27FC9AA1975FED01E655B3D4A7857872451D6AF810783184534C401709A63BF6BE6CDB1D1455C382CBAA6F68E8180CBA9E0CDDB9EE 25: 8523B737250579A3787BD83E5DCC57F7038B393F003223A7BAB98EE4D040441190622290B164F32FB96682730DF62CC366FC33126DE2F7DDE3A38C818C48F680 26: C6BE341A28878B733C30F50D67F6933D3A15A0950CAAB96B9F3D7D78C95C61874A400CAB65A100302D9E2DCEADC4A0C043834EB0433D5D684C187AED93B5EC6A 27: 4AE827A36DA140D2271F74DF1AF4303DF4B1C319428F8BA94EA28BD3765BE4535275053DA49B630E6B754097ADCD7F17DC7C16158F43E2C1851951EC3016CD8B 28: 6D3F01856A8A28E28EADF60401E84253C3F7CD13F3A9FB8F94D8B07B74F7416817F274903C135BA0DA4509A78D004388CBCCA75B06132C7CFC0156C03803E85B 29: 07CDC2BDD9CDC49853384FB647736B50D788AB80A0A54A0969B86603B683C22A1C5FD32D3AC92E73D378F379C4BA30A48E7D38FBB867E981271FB3962C745659 30: 9DC875BF987C55CE646A709E89CA89E226B0F15666D5174771368FAD768BF3318B8BC7D8CA80AFB5E6BB7FC0090B5559F11DA165DE51B940C9DFE911D4790477 31: 58BEE92BE003CCC34F9CE8C0B323C6BAF1297460BAAB4998CB3B52D2BBAA24D1B06CB597EB2E609A008572FF93710E3A7F42AC53E3FF09D4733757EACA41E20C 32: 888AEB1BE2BECB28598556A128AFEA037D0689C8D13D9894F1416B2C48B2551CB2FDA321A26CC4D7E1C87332D7A3C18FFB455C92C0E7AAF829FA40B8A28BB656 33: 19099B4E8ABF225DC7BD1C1DC6D52F54E8FB7E4EAE0AB19293C686E6FD2828221A1153BBA4C143795D1A718585D9255B6DC911C0EDA5E0042A10565AA5D6D8E7 34: 22B3ED65F64C8E51257A922FF90DC09447224B9A8C7B5A6A94D68601F3D4C7C1557BB90B91DF318EF9F8BB367E838D36A3CA82FDCB85721AEA20A8A2268D90AF 35: 0D2B24C6FD5D772704BC17D2FC8C011F1511F92491104F3C22470864882656AA40DD07C0C329C8BAFD90ADEA7F473349038CE475D352DA41E24FF64723070566 36: FEB43F7DCDE56A2EE963236C234E5800C011FC54D14396288DE5A7AC7DB2A72D1E8F63F04D1DDB3C55CF3BF19F4E0FBA4B79405A6B45ECB31254C9F1951C632B 37: B8AE2C8427A750F34647C3529A05D44691B8DE0C79525D9145665BDA5C0C396C00E936BF2493F12945899B6FDAA9F61E6E7B22846023D140F873EE7D48D76BC8 38: E80C49D1E29F6FAF0BB5C7B47F5A85B3A0EDDED84418890748724792CC83B53AB044B051722F1ADAAB713E5069E883C1D172CE0EFF6EE6AEBE05B1FD77DB652B 39: 1FED03FA70436EF45286648ABF39057C33815E6A80A19E22009B89C809DD6F0099C944B882FF9DF3DF08DD51295F3F02FBAB40F606C045BD4395969E27647D24 40: 2E3630EB519F6DD115B3E4818DB4429CDDF1C6CC2C8548F8CCA226A24F87A949A27DCBF141803B87B2A2C0F8AF830031DB1FE084E3996D8834F8E7D29EEA4AFB 41: D54509526805DFC0871CBD6E41ACE395C64373E8F57146A657C28BB3ADBF7E57A152D27BE24B8F30F08329C2E040359B119690D9A1118BC14A3B1883D093466E 42: 0AB062968EE4D71DCE807EFAF835EE11588854ACA0959B5341DDFD10E70BA9AD427D92168B31B8E6EF81F58615AF9215A8708CE1F144EE29901D1FC282C3F78F 43: 45862B0D0F0AC5CC1C5769C29D786FD3AC788CFBCDD6CAECFB120D05D71F2575F4174CAD5E5A00D2D740D0714E92822427085F044A72D66631755BC55E5BCC8E 44: D3A9EFFA759181346D8FE53130F05B2C65F96E1D5908A61DA8FA3A9BC551A7781ED7B1A6CFFCB2F742DDAE8D22B0EC99D82B14EB85719253693FF920FD5071D8 45: DB53395A78DDE62A406211955EC56C6F7BEB9EC2275501C35CA955268C3E2D71BA246B4286C76FAFDE012F9E2CAAC8601A74699B466023FE9F8B1BA26F65042B 46: 9426FFB7B70DEDF1CFBCE6610583CDCD91AB421FE39DDC31F4215CF7604B9050C84A3BA29C4B236F1CC3B09F53D29229132FDDDD9B468CBB6338BBBA6193F84B 47: 3D74F17DC6FE057703C72452BC7A078EC019424A89783F1FA40003657C323997DF30BBA38CB4B16BAD8FDC43260956090F765C26AB1FC88BF7F87EACA1821B52 48: C6EF119085EB17EC1B9F74791D95E366FE916F5397C20857A8966C52512F4EE16E63B53A28F7632A867EFC7FFD8080B173D5E2E33A2063FEC7D1181ACF8C7824 49: D878B30402FECA5EC93362105D5E183D658DD2FD38B8173FF609740CC84239C4F8F533AC3451D369001CCD4AC78814058DE0F7E1F93D167A46E85E3002F4F386 50: 948C4254AD2C5658A28D42DDC3CB4FE4CF731B4180B8A4A183C23C54CCEA045307422547600598CCFFD3C6229DAA6CDD006D3C782ED91AC61172059D016970DE 51: B74FDFED0388D5164BEE25E37C6687FA8D5C069D4FB0D42A7F1A270A676F83F24FD1C9048EC0D49F7BE913D893E0015E0A3F724653B3F0AB0017683948712E46 52: 497EB803D053D5DF498369BADBF8AAD57ED1B072CF361D3DB2A528D3DB16DD962887916E9D21FFB439DC2C025CDD8C21ADCC98A23C8C5B0245F2D71CF728F10F 53: 63F4098F650820EDCEA3E7C10B65D3B0F1949A28FEA323702F27C7D311C7E6BFC82D4C01F4FAD06FE0288E410EF325DE192F78B88E04075FA9581AE2B031A68B 54: 337914B013B8056D7849E42ADB47FA761B5AB05696CB8FDA6B87FFF88B0477902991AD81664727164053E4E47ACDF880DCAD0E0E67F7141123DB494450CF0B61 55: A385FE66F8C852638F5BE44503B680298EBBF27DBD9F20B1A0447215C0E2C1078926002113A71C78148D5019FB22C8132DD05356C78A1A8D8E4EEC5A6442DBA9 56: 218336585A419E9877CB63387C5E759FC93F0FE1A7BA717B8BE9B2302393E0D14DEF2F749D138692D0A0296F1C792B567F40037DD2B8787F1F47FF363CF34F37 57: 7EB842771A61A9AF779C8794CA055518E7F38CD13F61638900EAAEA000B12816D52C593B62B9DAD79DB7397A463AB99A9D0035E7A1369B0556D593DB41EEEB6B 58: E41D1492D3472FBD42F2460650F9DAF2ECCDEAEF5F4516B452D940DAD516F5168439154B4BA76610461B343BCF1E7DD7DD8C285EC0CC46C17CE3C7E14103042A 59: 88057C0B8442BC5763283EA17FD1FE1AE011A988E1D7E0F914004CD3AD2E06FEEECDF59E309B9EBDABF19559954C37F71FA98C14BB19F7B91CE5F827C1DDE1B5 60: C5DE99AA273D1971272263C740E689739B39725A0B7C48B41577F05738A24F5EE2C0B673F93BD52A083798DDDC6E70A209213B58C95D49ABC5BCBABDD6AE7D22 61: 68296AC346BA3B14C038CDC629C5F5700CEB9F5DAFD94F948C6B991C0F91813BFD02660A2A05A02A61D8EB03BC93601F9F6A38196650047E1D7DD1071CC6974D 62: 1CE0E6793B0ED59C4DB7D5F24FEF75A4ED2F28CE4AA7E5EB25919219C2C04935E4B15841821FA92FC7537DE2A538871E5A043A773CB1ED061333113223248C18 63: 37BF321F66ACE827B66ECAA651CCFCAD30AB627E717AA4FE441279C4FA48555CB7784B0AF25A73B86375BE71A1E3FDDEC661E0EB8115E0BB2B9A7FF81DC75DF9 64: 5C3C6F524C8AE1E7A4F76B84977B1560E78EB568E2FD8D72699AD79186481BD42B53AB39A0B741D9C098A4ECB01F3ECCF3844CF1B73A9355EE5D496A2A1FB5B3 65: 85A19923268414DE6A10A2CDEF7917D7AA01E68DF9D028CBAB5C5236FAEFCED836BDE9CF90D8A214013056202A1BAE5CB73606078C5572D8FE85C36002C92D70 66: C2FB9763A6F86225F6C66F55ACC8E7E17C1A2664416B2704D64AAC2CC5B04A626030B5243CA61D62076DDBDF3C6B3765C38D0CFA01D4D45C124EA28DA593F84F 67: 5083280300FA5A1B172D7B5CCADA5CECE1EE5B7B5D382EB4A430179EB133970B0B89F6BB6DCBB1F38EC9F13F5B7D1559F114DE0EE26178EBC56CBE31BB26A91D 68: B3571E8C1CBC0C58E23094B39352D554B43F9E7DD0FF981C12A01E0D8BBFF06A39875D90BEDA7F345550E6F67935A49E0183456B9967BB319D74AAD87CCA3695 69: D11537B780D458D37279D00621F646EBAD3244A22E4D45DF11AC5D084FDF70E7A32F897DF727E65EDD1019DABCC05DF0B5E015FC5CC1184129C5DDFB14F62154 70: C146458EF40E6F1944BFD863B2862A97145BA580D47C7ACA67E797EAC6790841C57D68A74930AEFCD49031819FBED806A0C033DD529A203B4E460F357BA1BBFB 71: 660F3E1D5CD3B2AFD95DB0D8C258F6AD74DD40DB688A37AB4A24D720766541B1CB928001EF6D67CE5429039C9C1490613DDF90A27E6152BE7D42E1614C590056 72: DEC468EF73E98F44B60EB994935921F920DC0CEEB7498655F0FAB7607A77A7A3D9462DD8BAD46CB408EFA81FF08D7E9508BC565C1578C37C2B87D41A0A32A549 73: 070D4C36A0934C5C12E6B65FFF385404E49C3871DA8674D93D26E3166A7EF9693D946B419F0E10C9624964B37493DC8A46D26D8AB8942E60143036659CA4C91D 74: BB8935CC84E08E6B4E7C6233E41D880D70CC018D1668EE64F19906A83730495D01AFCE1A4EA8129A98B7F9E074FD35C0BA6D5667625DB63A867BAA67BDEFC190 75: A0A7A0B619643115C582BB6953D2A3EAA942451F631FC56C0933B535313D668FA4CA7D6BEC4DC9FE2AD7528DD6F8DBE68478A040FBFDD2F3DC3AD7035DB67371 76: D6C57C3FB08D07A30A622B25985A52A6E552499345244725B1084E41691B11EB31D3B9776940A9A7E6115D2D1A93372D3A7388D87B01D13BCA726E8823E89729 77: 413CB26BE2B1BA8ABE930ED1B9978BA4874CF32B38C825CB6DFE9C21A87C0BD115D3357198FDA0A5B7CDEB4235A354E9C2F37D11B33AC6A257DEC67326830E23 78: 748E4648FBD009E4848E44A284D0CB2088300F50CD5215A285826E968B9DA59B6322E1987F78447150AF72CE37E516BE9E83B05A9817AB7A924ED8B09557CB5F 79: 0A8111FEA824D43E0991C22FC3B1368A191D0C73308283494309D0762AB1EE5AF0CE2DB8F0562DECAC636128688540E845D72BEA3852A19CA2ED22D6C1E82CF1 80: DB1067879F014EF676471D950A81DA073D676DE52E85F67890C8471FE6144078DAF940CB6F9F097BEDB8FAC94C737C5B8A3B4217CFF4A56DC349B2AE845AB25B 81: 6165F19F569BAAA3A3ABE6D6108D07E1ECB22092F66227DC27173DAC097118C2D927F2E5F7D20C8CEF0F99C6FE6C7AA46BF18FBC452F6FDD733728030CD0A4A6 82: 1D4AA14617A4BB9E48DCC1A7EE5DF65298AE45FB193F077FDB6D1C2B3252E1633AF86A527C29861661CE155A47E5BAC91D9B07715E0FF7E08B39A3128891EC42 83: C2C22B53D6BA460954C2D826FD3DEEE60E33AF2EFC87A61CBF2AA021166AFB90967ADE2C564D037518E4141BE9C0D0BC0B4F95498D5AD920BF28CAD4F5FE700C 84: BB5E9CFE19C6A2D14EA4C1F6BDE51855DF61D650B23330BAC30A5072EAACF86CA02AD31FE4C146176DEC75C56A56C2B868177E0E365414508D2E7606AB9E8921 85: 6B40A13C5486396864608BE7285BD4D1205180BC41E10E537042A1CC6CD12FA7737B5E73D768BBC5D687FCCE41880A8D9773C26316ACEA2D78DA26FECCC11E90 86: DAD0DC8A7D78E29B12182D36F47B93CAB562C44FD6C5B1718651022CDEEC30133437431D13C43EC1C02DCE776F459A57C29355B3FA0D67C6BF84AD26194A8854 87: 8118AEE5DFBD7FD9F94403FFD3C6BEA08706D4C4DC78CDE72F751A6C4027ABEC7786A62732819ADC036B787E25E151AC51B60BD2381A64F05A326800D7514B15 88: C64737334A61872EC00C8A3F1B1EA931FEE8D80203CE6DB9F1ABEFEE2CD3E652971615AE4F9A23400B9E31D861BE6B7E0F6DED28ED74B45D6AE90E70AD49508B 89: F927B571B03B892B46C0A16148F13A2E6B80630CE41BA7DBE311F9ADBB5E8F23923CF0CA527DDD20BB3FE42BBE805066BEAD569F6FED12A2722A8629427ED841 90: 2576A445CCD8977F24F50EE30EA7A51F0F3F49D41BAA663BD1C1734E02367A382E3D0E8C07EAED0C6A47CF662FE573BAE5593D9C4BA8FFDB4AF024F6064F7A89 91: E85C73AEB638F35565BDD2523AE2A86B573C339B4D5FF8498ADF71BA587CBF146AE63B8C920B2F0A166F802167A04CD0D7F7A842D7D058165894CF9188289032 92: E74E2ABDD6AFFF851EF78F8A866DDE9B9F86D906B298DD1E3630E1D4A30B6FCD7FF91943A57367A00E2658A84346F53ABC896EDAA395167E5EBD12C954E0B820 93: 6827226985276BA731A9AE2E4DBF2D0187C05D566F06D098E05E3F425DC058958B50F09B4CE0741F1375E9B522F94A61F1ED8A43A8D03A036D2ABFCEDD4F0C1F 94: 19A71A12DCABA1BA185BA38BCC0D915584A801EA49F975393B25AFBC456571CBF1A6F9121CBAE89A9B438092C65532489A95A0864320102EAD9A2EBD30D41F6F 95: C70F19BAEA7420A7482C9C54CBB689A9AB93E4F8538EDC2371A1EDB3A103DFB7176E04DF170FF71EF46DFDAC1E8F9CD6FF96115BE1EFC271A56BDCFB67D29E67 96: 8BBCCFC8815786ADD9F108F4381A2B084179002AE940ADD4C42AA2550C353CD0351C2F7F1BD544D8F268FA332B0E803838318A39079E9D93269A01EAF9CAC967 97: 5266FA966A04B8A2450ECF3826C9E1516FEDC33EE81D4911A601351564D27C8BD4A11BF00E0DE237E50D75421CBE475E38967F28E6A1C5D311A2C95B84898D1E 98: DF87823E1E02AF34532C5F3A08CF03CB9B2017B835525B3E3C448B1ED15569935D9A1DA19A6B1E8D056FBC868447ABE6226B97F256F6B638B052B4BAB3BD4808 99: A1317CAC2364B10EABBD3540B6139D337C0EB3F7A740C050988FF9B3584213DF5833AAD81D36C30CE6CE76962A9E1D45F08667A314036A299454F25F73EB067F 100: B752B6EEB497A8BEBFC1BE1649CA41D57FD1973BFFC2261CA196B5474E0F353762F354C1D743581F61C51F4D86921360BC2E8AD35E830578B68B12E884A50894 101: B0BB23AED2CFC9C58C8BAB019CD10DBE75717EE8F04AA45FD8D84748E3F05C523FD2F70DCC460F7A18DF7D28A224BCB86CFA4C8164D081D51F3487A7BD0C8109 102: 0FA46C6A759DA9A3649679780A28FDD51EDFD3F99A4B801C5824247B270A137CF40006609E149C919CDA0A6C856A9A8E855A670A2BB2CD5211FAD42E84F6E365 103: C4E350267BD335848D00151AF2C380E49A323E63AA264D534EA1BF7A860B764A78993F7FFF34ED93ACB1F5A5AB66758C462B4D2F2F4E14225D29FEC0C102E772 104: AFA0F1DB8A321FC6C4EF7C65ED2ADC4B094E928E230D27295699DE68FB5C1657FE0E5C4E66C5852ACFC45DA94BEFDAC89CF0D4174B262E6FD51CDC3E7FFFA5CE 105: 9A86A440FF8A33DCD38C69D7564EF827F614629CB699B7F45E7FFF1CFF4AD5E27EFFDD32EF1D0845987A6A273EA34C19374E9FB606BB2E3B909157CC6666D29A 106: 1FAF8C564575D654133B0A452EC43959C9F9E20C044724B74EFC90D2CECE4C49A0512C9F4DA2E999552E3ACC04CE0F0E2FDA9826C2A1FBBACEC4330081D5CA43 107: 8B35FFFCD91E617C8A49B13CD0FFA2199FA1F20E5633AE6E95881BBCA02B1E047392DC9A4C0F0A4C39D3984E78ECC4DCC1B5C94A26ACDC1F69C7ABABFFB45175 108: 6C8AB69E946FE86DEF6F14B955B8F1977686EAFF8E384CA45F245CCC0EB1C80AF8E62B0E7387C0DA52BBA31B1A01EBB00CA26CBFDA9D8069A773C3B62F989A2C 109: C3A243B45B7C3C2002CB197BADBD84C4900D504FCD277D2DC6C06D34B1317B41EF098BB980800FA9D011C0363D074308835AEBCF3393B1C925045E97E14831C0 110: 803E065AFEFC6C48EF9F701233AF512465729E81B0DBFF99A2E7FEFFB542831E1D3B30230BFA2F30343695C060AC8140C37CC8D1E25E95E6A1139C5522F4ED28 111: 86618429B8720ADCBC8B9FEAED8BD44E0848572CB6137213273563EBFDA859240E17DFDAFF68B09953F1853C9E7EF217875E7BD6959E76DC3A1CE5F548B76CEB 112: 96439A93295B5C479F0310B28377FC10DF81B593AC233556B15897F1FA3886C940639AFF2ECEB29894DA884626B4811254FE2622EC7B4577087D9046C96AA556 113: 9F7BAE13DB80C72A434BC4704998A73D7E546CC2590E0D0EE511CAFC63C622A8B2A296426E42754606D02B6EA060892E325EA1AC13EF0B523A3551F4D25BE241 114: E999A862E5C479B7BB21EB52E4BD301571A8A39B712EBFEFAC720F28C515025E98CCC74B950D57CF3C3B34D788D62CDA0339AE0DA02C8A107BCDD797C4751FF1 115: CD00EC5142CBBCA87BC15D69EBE96B5222F25BE1576B318208178679B13A9A8BA4BBABE9A488BB38C4EEF327C9A4DEA4225DD30C0F70B97C18C5C2FB19FC2134 116: 1289951D2B62112BA590D8C0CF9EFA38AB77737F994060596738612E6BDC41EC8672F50A027A2C049299FD39E1776BC3EEBFE3E66CCF4009615D63F0A4C43ABE 117: 451A46FBDC954FB76E744AF3DA8429C881197F6BC12D22412438729288AA4540843B9FD4CD1BDBA5E864FEAEF0CD6CFF045A37510B3759FADFEF4697E9BF9240 118: A267FCDF72D9160DA2A01E781E07701478F95A38C262ADEBFA194EA6D5A50A9CF3E04D32AA4B492580C6E8D8FAE1F813F3C17F82B7F47D8CE0C900F0F3052F98 119: 3D910AB6579455653EFC939BE1B22D993537408086361008EBB166724FAFE3C8578EF4BE0378BC28ED883FC0FF3DE5A9310CEDE65FAF3AD9590A13B3CA4F81C5 120: 47386DF4D41775737BC4E52D7CB2EFC11BA335A5D59597B5DEB3DD0A35032461F5DB4779D48BD6F3A10C5503AC563C790235E6F54EA79CEADB6A56AFCCE890DF 121: BA59044EF3A242974F074337CBB6840FA0506C2227A429498F546B2CEBE0644DFF1D442190C48CB54BEE72F960670F71AF1F8402AD5ABE8C1482DEFA881FA903 122: 89B4F35E5C8C19AD61CF1600BA80C1A1BBCFDC86AD9F8066C967BA10F62827FCEFA1EBD07C90C82B48082A5B7D6A72E0AAFD230DE05955C7E8C081286B0CA96D 123: 0C7F94250F4EA7647F91E7EA8B8612AE8E7BFE4F5BCDD90CDCE564BC9842F6987AFB4C3661D8431440FEE18EB2EC70BCCD34A6B61D209CB72BE782A0808C08E2 124: 2C8B8B17820085795BC6A2720B5D0BDF5407D9DEE1CAA4270FFAD010AE9555DFD2B74A742512BAFFAA1D5B4F14ECDB2BD4BF37838D5981A317C7287805974019 125: B464C5A9D040F11DA45D98C4BCA9295D0F589DB11EE5603410C62BDACCC329B9AC14567C3A6F3BBA4B92CD3B95BE58AD4DA435199CE62D8BD61269F8BEA38FE4 126: 2F64554FD54AA4A04ADE3793AFCC5C968B1C3603F4F71E1BB5342BA4E951D79A4580BF57736E7FC13A43604A057E9C360C099AC5B3403DA8AAFDBBF417FF6ADC 127: 3C9A7F387B7104DF19CF264B0B5821B2E46E44ADC79262546E98FFA113EB3D45799EAC78CCA4643C937FCC3C1D249A212FACB34C63D45EEC81069095D7CDCE7B 128: 803A3B37C89E84FBBEC75BEE3D00DD728FFC4246B5A5E989DC8DC2CD0F7937966AB78C79E1D4648EE6EB40F3D70491CB46B8AB42E155672E2AB8374FCF70DD79 Hash: chc_hash 0: 4047929F1F572643B55F829EB3291D11 1: 8898FD04F810507740E7A8DBF44C18E8 2: 1445928BB912A6D3C5111923B6C5D48D 3: D85B2E8854D16A440CF32DDDA741DA52 4: 5F3082124472598098B03649EA409CDC 5: 604A19622A06D0486D559A07C95B297A 6: A16F89E4DACA6C8174C9D66AA23B15AF 7: FC6893F79A2D28315FBBEFCAF0280793 8: 6A80F04CB93B1CFB947DED28141E877A 9: D036D0B4DEF1FA138C3181367143D1A9 10: F031A2DC2A196B268046F73728EE7831 11: 2E05C9B5A43CFB01AD026ABA8AE8201F 12: 8B49EF0BC936792F905E61AE621E63C3 13: 485CF5E83BC66843D446D9922547E43B 14: 704767A75D1FD6639CE72291AE1F6CD8 15: 19F6228C2531747CB20F644F9EC65691 16: B78FEC0628D7F47B042A3C15C57750FB 17: 3EF9AFAAFAE9C80D09CD078E1CC0BD8A 18: 5E4501C8DD0D49589F4FFA20F278D316 19: 00D2D0FDD0E0476C9D40DE5A04508849 20: CC7382E78D8DF07F0BAB66203F191745 21: 85B841BCCCB4AD2420BCABCFD06A0757 22: 7159E38F4D7E4CEBEBF86A65A984BA2A 23: C8949A9D92601726F77E1AEF0E5F1E0F 24: 8CE35EF6EC7DDA294134077420159F68 25: A0F4E4522832676B49E7CD393E6D9761 26: F55C27D180948585819833322D7BC4CA 27: 0A3975A0113E1FE6A66F8C7D529715B5 28: F77135C5D04096181305C0906BAEE789 29: 31FF81B49B9003D73F878F810D49C851 30: BE1E12BF021D0DB2FC5CE7D5348A1DE7 31: CB4AF60D7340EC6849574DF1E5BAA24E 32: 7C5ABDBA19396D7BE48C2A84F8CC747B libtomcrypt-1.17/notes/base64_tv.txt0000644000175100001440000000174110621351501016214 0ustar tomusersBase64 vectors. These are the base64 encodings of the strings 00,01,02...NN-1 0: 1: AA== 2: AAE= 3: AAEC 4: AAECAw== 5: AAECAwQ= 6: AAECAwQF 7: AAECAwQFBg== 8: AAECAwQFBgc= 9: AAECAwQFBgcI 10: AAECAwQFBgcICQ== 11: AAECAwQFBgcICQo= 12: AAECAwQFBgcICQoL 13: AAECAwQFBgcICQoLDA== 14: AAECAwQFBgcICQoLDA0= 15: AAECAwQFBgcICQoLDA0O 16: AAECAwQFBgcICQoLDA0ODw== 17: AAECAwQFBgcICQoLDA0ODxA= 18: AAECAwQFBgcICQoLDA0ODxAR 19: AAECAwQFBgcICQoLDA0ODxAREg== 20: AAECAwQFBgcICQoLDA0ODxAREhM= 21: AAECAwQFBgcICQoLDA0ODxAREhMU 22: AAECAwQFBgcICQoLDA0ODxAREhMUFQ== 23: AAECAwQFBgcICQoLDA0ODxAREhMUFRY= 24: AAECAwQFBgcICQoLDA0ODxAREhMUFRYX 25: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGA== 26: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBk= 27: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBka 28: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGw== 29: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxw= 30: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwd 31: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHg== 32: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8= libtomcrypt-1.17/notes/cipher_tv.txt0000644000175100001440000014731010621351501016405 0ustar tomusersCipher Test Vectors These are test encryptions with key of nn bytes '00 01 02 03 .. (nn-1)' and original PT of the same style. The output of step N is used as the key and plaintext for step N+1 (key bytes repeated as required to fill the key) Cipher: aes Key Size: 16 bytes 0: 0A940BB5416EF045F1C39458C653EA5A 1: 2B20AF92A928562CF645B1B824F2E6D9 2: FC29C3356937ECC3159D8D6EF5E883A1 3: 4C07B5A2EF31A3229C87AB2E4DE88602 4: 93AFA1147E793FFCC3D852695A62D008 5: D4BCC317DC9AFE0E6C7AD1E76F79DBE9 6: FEDB3371F3C65162AFCCDC6D18C79A65 7: 4AF2A76F93F07C14161C16B5C176E439 8: 00A1A596AF7CF44FD12981FA12CB1515 9: 8013D7006AB38AEBD40D0DC10328751C 10: 81A077F3A262FA4D00D98EE4D1BEC390 11: 0CCBC99A3135F26D2BE824D633C0366F 12: CDBB5568610AD428706408B64DB66E50 13: CE94461EB0D57C8DB6AEB2BC8E8CE1D2 14: 06F14868F4298979462595C0FBF33F5A 15: FE22A7097513246074B7C8DFD57D32B2 16: 0F2D936610F6D9E32C0E624568BB8E6F 17: F32BCD92B563D475E98322E5850AC277 18: 6E6FCB72930D81469F9E05B20FD406C0 19: 42FF674CBA6C19C4AD84D42816173099 20: 41C12474A49B6B2B5E7D38E03A4DD4E0 21: F9E234E3CE3FCED184C775B6140AD733 22: 7EB5CC6B183D8B3EB4FBA4717CD8838A 23: CB6C5D78F9721E5BF8E980F0EDCAD4AF 24: B3F20EF6C26FD9301576D82DA6D50809 25: F9375037377D86599FB4F241166C43E9 26: 98BAF9AB7402479C2DA356F5DAE35D5F 27: 58D1A8E0DC3BC53FD995BB0F60F25FE7 28: 0A75C0D22D2627C97BA2A7344B9B8C74 29: 88C299B2F8C9EDAF86A301BBF534BDA7 30: 755E3A17420281F2C619588A6B521FF9 31: 0E540DD25C0C147461146E11F832A63D 32: DC5B58691C6BA5B243036A41301BD7D1 33: E9299A7336C2D8A51D6C7E2BD1B8F054 34: 78CA6F682FC649DB289DD62D28D3A22D 35: 98D96EDA081DE416083650B22BD3869D 36: E747DE96D122CE1EF6F89BDE0FAE75FF 37: E48DDF2EDDEB54C861A1E42F5B649EEE 38: C650C2CF1E903B7F9C8536A2446CA762 39: CF0BCDCE0F1FE7EB40016C1231FB2962 40: 37B1C8BE3812147E0D5D115A797663EF 41: 45DD8184581049C4B28FBC0809690C5D 42: 11B0D889F96E677EEC2E934E9F7F5398 43: CEC30BC1128A96CD506E406B5ADFAE19 44: DE67D5439BF83D5338D53F362FCF79B6 45: 724FBB2D95CBEABC568AA44941D9B6E5 46: C63F480DA3C73B2A661F1FBC3E4D1F89 47: 225CD18789D18FF09C982EF38AEF0AAF 48: B493DEC7E3D11911DEF8788102453670 49: 23E0B12A67DF025CB77CBDF9E295FCAF Key Size: 24 bytes 0: 0060BFFE46834BB8DA5CF9A61FF220AE 1: 597FA00D03EDDC81C2575B4DD6B6AEFD 2: 4881E4EF69005DCB9110BA327CAC8460 3: FC4A968AF65FCFF45E4698455918673D 4: 3079D7B27A3DA5C0805A61CC37109EE0 5: 9B3F2C7C35806276E2C53826EC1B3C84 6: FCDFCB1FD9FCF1B63E1AB6737FC154E8 7: 4A8012AFD410D29CE2CEE0FD195EF9DA 8: 9F4201C4174C71A3AEF8FD6822197D67 9: DE3E5E98DA60E895389A1C17E3D50DA1 10: 20C9064A076C01D1BC121A5A2A1F913C 11: BA41A36CD24B515545B8B464B244E5BE 12: 2CC1DE9DBCAC45269C6DBBC9203095F4 13: 2ED2499CFEB30203E6305B3E1C329C4D 14: FD709FC0AB48B204C95B74AD189C8832 15: 7ED298B472C53A4CB7A3BAE588805E86 16: CB0C6FE2BA76901F9EDE752634DCC31D 17: 6C5CA6EFCF7101881507AB8770ACF1DE 18: DEC3C5209E98BBFAA469C5FE6C02A674 19: CFAC040C1198C8264679CACEAA7E9DE7 20: EF990992EBA8ECA7E5F95E3B9D69D3A4 21: 8FC1B640EB55A96D08D83D1184B77769 22: E1F3DFB9D055BCB2D6CED6DCB8361BFB 23: 6621F47057706F2A079819DBC0197B9C 24: 882611AC68778CBD6A46FB5DD4611A37 25: F35E1367A283CC641FBCE26512A8F2F1 26: 5A4A71F69056CFBAB67DDA777F5CD945 27: C446F2BFAD060A9E9E17F71B05ADABD0 28: 1F0E50F71A67FAA7D169A7A1017FFD65 29: A6A38588848915509451A2354D2AAC8E 30: 4C887574F2C5DB00ED4FBAF814A70302 31: 1B642944162A049CCA9FD0284D7AB4C3 32: 431BD9293C5BFD12F948C255C838880B 33: 32CD23A30039AE2FB80B804B905362B1 34: EBB30E07E7517580A645CD1B5F664182 35: 292F2BB28BB172620B05C7621BA347D6 36: 46C06E1223F392D57B98EFCF4C832C18 37: 451DFBAD2AA92080204F85432236A42C 38: 768D6206D2B3DD1B9C26FAA5977A6477 39: 3705F9CEBFE8F91ECE07F84578C05494 40: 085EB0DCF360F5403FF1E7402A0F7A03 41: 2A0D56F2E7C7FCE3095F511BDE4AD9A2 42: A8AB2F3643A61AF164F99FEFAE2CE1B4 43: E73FD4B1FAE0E5E6A6A31CCC2AF96386 44: 578E84FD1AA16FF350374E4FD5FDD529 45: EEAE301DD57084801DB01F8B9C4036CE 46: 1C44A93B404298327857F71962E0604C 47: B5F64CD5835C85A68DC23E26D4B8FF80 48: 6C6F97850A87088AF195D0500B3F5D78 49: 0BAB3A60A25CD1A750C2C443AA01C57A Key Size: 32 bytes 0: 5A6E045708FB7196F02E553D02C3A692 1: 5F7229D6AACF0DAFE3B518C0D4ADBAB4 2: 96477F47C0A6F482AC4036D2C60FAAD8 3: 7F791D54914F12E9F0D92F4416EFBEC0 4: 87DDB19415BEDC42BD361FE380553C5A 5: 8EDB2A09DC8731DB76D9F67A03AC4D9E 6: 269A7C08C28D5E4D9355DDBA161F862E 7: 042A3397BA5029C443DD76755008DB2A 8: 469C82A94BC5F7B2DF57F0CE1716EE74 9: 5A84A93077FA19146078310035F4B7E4 10: 28CAF1C0D811F86CFD3C5EFC30DF79F9 11: 05B575D06C2D593B708F7C695CE97571 12: B7E8CACF0A0BD7F2F5DA0B09CC8B8AEC 13: 0ADDE90F66F1BCF38CEC63EFBF9DBD46 14: 9BF99E7F5B8F176DD686AF017D5196E2 15: ABC189EE80D4A4588B3D54DDACCD9778 16: A57405378580B1E8A8D877791300374C 17: D1EF03F72FAB3DB68022FC60A2CEC13D 18: 3D2406231BA17FF7CC973C5E203872DF 19: C3E07233BD101502953D6186001838E4 20: DC281C0CE02A83098C80D6C9463F3449 21: A923023D2390B2230FCE9217776AAAFC 22: 92E28E69009959FB84046C5ED1B64D1A 23: CEF8F684EC64A31C651280CDC942DFC2 24: 5A954684B22691F9CFC60442A654EF61 25: 56A38A0D93188BAA50DFAF2CB799A76C 26: 54503340C5DE26679AA5F35215DE85EA 27: E74BFAF64946DFD699583FF9C47A1EAF 28: 01F234F9868B085E9B1A2EC84738E2DB 29: BBCA3DAEAB24EF25BC7B623F4D9FD680 30: 3956C880F7F7D94ABC259D3D86157F27 31: 4672C2149054C839C537BDA1F5BBF8F4 32: CF1E9ACBEB391062593BD88C7948F64D 33: CA5B4E867AE9D8BA2D4416C908EB99F1 34: 36666180C768636CF1708CC5C85A6875 35: 53E396D2755218675494C7AA515A2310 36: C2B7D31A59A602A65E155F80353DB83D 37: 0EBCE19FF6FC03E327A2602F858D835E 38: E47CC2A5E6C7FEF185806E2CFB304D91 39: D61F15FF75E0F523FA3872132A09AF42 40: DCC25495052980986AE30756BA0417DA 41: 451BF5B7C1F1AED9F3D5E18A391EA4DA 42: 1B6B105C580083D23F3A8EACE41B7984 43: 8C2F86CD6C86B67C9EBDCAFC5720E4F8 44: 41360BDB3E4C6836BE0D15B659CEC5AA 45: F972104AD851BAE0AD963817A3F03F58 46: 396095F7C102B5A238110DD3D6D4ADFF 47: F58391AEB9A5D8BB32A3055B37556E81 48: A23789B146CE89C876F3C331901261D8 49: 2684AF345C4B13FA154E93A3E2CD2A90 Cipher: blowfish Key Size: 8 bytes 0: 84BF44A1442B8217 1: 3981205BDD22C01E 2: 0ACC5CCBA118CD07 3: DF76980D5E089145 4: A8503E8D849C599D 5: 5E56574687038F5F 6: D63296B036996F50 7: FD2FD7A0669A9E7A 8: BC6583720A962585 9: 4B38C2856256103E 10: 48A4FA354DB3A8A6 11: EF97C32734BE2A10 12: A7467E9C729F8123 13: 04D2507F9C4B5854 14: 57F76A4D406B22D1 15: ED0A3B26D842C8F2 16: 047CB457E9730CD1 17: 9F13BB1A97BF5E2F 18: 628CA4F77161C95A 19: 37C7D8EF718DFD50 20: 2C9A9C655B839B1E 21: AB222D66579DBE0D 22: 57950CDEAD6FAE88 23: 67AAB3669431E403 24: 6B35C87144F6B748 25: 94C2E8A1DBC963C2 26: ECD68F56EED1F78E 27: 2E7BE0B866B1D3C7 28: 6671DCDCB3D8EED4 29: 8ACBE7A2F77FBB35 30: 0BF0AC4EAE284F93 31: 29928AE5DC8A57C6 32: 84E48C27E21264DF 33: 4EF0E943E4F48ED3 34: DA155BEFBFFD2638 35: 611EC83E0931FFBE 36: 3BDDEC15BC543A92 37: D7B9564BBAEE19FC 38: DE44907E9F0A1F11 39: C8638C0594D13614 40: 9E67F1B15418BF14 41: EDF531A083F72852 42: 7E5F8F9A72890BB3 43: 2A0B060E3EDDE9C3 44: 9B4B0F6FE6511106 45: 328658F222C7FCE4 46: F6F1B50B4F9F9C93 47: A620519E69952F5E 48: 24DA24DFE96AD818 49: 226C43435FBDA34A Key Size: 32 bytes 0: 46CDCC4D4D14BA2E 1: C079641BD6584E5A 2: 38828DF8B4C4920C 3: B4ABCF6B78A721F3 4: 8E7E2914CBBA708C 5: C0EBE7002C888495 6: C60F404DE7CF9B78 7: B29E843E1771EF26 8: 983033386CA6A09B 9: 76F1F89AFDCF7130 10: BED4E2114F4376FA 11: 879A2B9D19AFAB87 12: 366201BC87532AE5 13: 6F409580FA907A64 14: F7A202F00A38863E 15: 98B0A9C79FFC27B1 16: 1CB68D9BBF8A1A8A 17: C21A2C54E5471D23 18: 76A81C3DFC149934 19: C7A0627412FC323A 20: A034684D7058E7A6 21: AC87722F27029BC2 22: 36A6C2AF10245E3E 23: 1F85B90D11217EBE 24: 9C2A0C383A4AB7D5 25: 11D5C689039CA179 26: B0B38C7077E1450B 27: C59C7DCCC3B8A1BB 28: 9BC539F29208AC24 29: 8546F17C77C60C05 30: B189C3E92AF53844 31: 3C7689163B8D2776 32: 6AFEB9A0671156A8 33: 05514E39F2990008 34: C941E31A2A1F42BF 35: 87C3777C74A730A0 36: 2861667755C8B727 37: AF75A0312433B151 38: F76939331E9C9792 39: 819FF8C81FC7C8DC 40: 31E7B07EB03D170D 41: 696E5EC1A741170E 42: 6C5BF0E0BA48FEC3 43: 6D751BCCDC475797 44: BB5A91D0CA7E60F4 45: 7F7EC0531C88B14C 46: 9F302392529B70E8 47: CAC9A1A88F09AC1D 48: 39D56A652E02D5B0 49: 13641D42BC126517 Key Size: 56 bytes 0: 373C66BBA50EB9CC 1: A4E8C602AE3A2CEB 2: A59F08BA78502F32 3: D0D4968015F4E4FF 4: 0D3C2F291E6C2EE0 5: 3F99F5DADAD5FD2C 6: 5BA41EC1A506396D 7: 0BDE3B5B50591D35 8: 5C4A6AEFA69A115D 9: ADABFE96D6D159E8 10: F97F0B9C88ACD5C0 11: 8882A163F0F02BB2 12: F00556C9F5A56A32 13: 257615BEC96CC228 14: D58DAEC547DD8B89 15: E677F4953EC44097 16: 20156D066DC37000 17: 6F18E01C6FDF947E 18: C8DFF24F12621237 19: 032F91C5119AE308 20: 394194AD8BC1E5CF 21: 6F24E937F3925581 22: 086A4510D95759F3 23: 073204BADF0EE942 24: 5BC8B8E402D90F43 25: A10B7E9D01DD3809 26: 22C0B183AFFDA506 27: 216306AE6DDBAF3F 28: E275E1F52430A1FD 29: C3BDB49D588D31BB 30: B860818C5923B688 31: BE1BC7A444B0E141 32: E4C4B67900DBC8DB 33: 36D7B7ECB6679A9C 34: C1EAD201EE34BEF7 35: 9ABBC877CE825B14 36: 3B211121C0C3C09A 37: BE3B34FF2E83F5A7 38: 46C2B3E628A53EAD 39: B7E7DDE16C7DFF62 40: 3C9A14C4226EBCC5 41: C5FD46242DB29704 42: D45A96723FF62201 43: BB015D10878CF70D 44: 71DB021BE398D41A 45: 06F52D237F06C260 46: 3552F47E8CCFC73F 47: 769E33828AD5D88E 48: 659861DDF080AA67 49: CF7A13782F317342 Cipher: xtea Key Size: 16 bytes 0: 256004E1F55BC0C7 1: 2D385C151A691C42 2: F93BFEA758A7DDB4 3: 2A905D97C0CA3E48 4: 12C7C2787B913AE6 5: FB24B1F32549EF59 6: 2A8BFF867FB4FF73 7: 5692243526C6BA77 8: 4CD423ADFCDD1B6C 9: 9B99AFC35EB2FED0 10: 416B4AA4E07DA7F4 11: 4DBC9052ABFF9510 12: 8AF9457F8E599216 13: BC3CA2B1C7267395 14: E4BE31DF42282F7A 15: B344CA8AA57E9E40 16: 57A1F94CD2F4576D 17: 96177FCD28BFF1BB 18: 78A1F63A0EBAAC33 19: 5F3FCBCD7442B617 20: D6F7CD5ECA688967 21: D92EDF70CBDE703F 22: E2E2C2EE5D18E58E 23: 4BF00478CB7833C3 24: F9936D550815FE8F 25: 19A3B07B3E47D7D8 26: ACA441F099A7E30C 27: F70183F199988E3F 28: 0A41FC22F369310A 29: ABFAF40853A4A38C 30: 6B5D29DB1155D96B 31: 0DD0C08A27561D66 32: 4C56E22292F17AA3 33: 3F925ED65613DF4A 34: 521B4C97081DC901 35: 2B1EC3E1C8CF84EC 36: 2A412556F42A48F6 37: 0A57B8A527DFE507 38: EB55C9C157E3C922 39: 6E6D6E9AB925ED92 40: A4C5C90A0D4A8F16 41: 7F9F9F658C427D55 42: 9A5139994FF04C3F 43: 9054771F027E29BC 44: 90543E7BAED313BD 45: 5DEC1EBE6A617D36 46: 19AB6A708CDB9B2D 47: BABB97BB5CF9D4E4 48: 2C2ADC05AF255861 49: 52266710153E3F7E Cipher: rc5 Key Size: 8 bytes 0: 04F6B9B18E6828C1 1: BEA50D165E50EA04 2: 6F3728FE19F09B03 3: C682C26278B372FE 4: 78BCC81E144E1B0F 5: B62775716366450F 6: 5BC49690F97CBCFC 7: 359414E9EACDE379 8: D3331D8ECBF684FF 9: 13129FB10EAFC82E 10: 7F29218421CC4B5A 11: FC225A4F31A75162 12: 29BF8BFDA8A15D37 13: 6854AC5BD98EEE95 14: DEF05AB6D102E992 15: 317C3EA6F0600016 16: D6F3658B2E80B77F 17: 7C1DF7ED6C92C23D 18: F8665145BAFE28C5 19: 9D8059C34B79F0EF 20: DC8D1617D3EBC7DB 21: 2D8FF59FCA19BE6C 22: 5C6956743715EA13 23: 91160BE1F4F3D4A0 24: 1D482C2359EC93F5 25: 9C21D1A3755A7251 26: E48D1BB926D51E63 27: 08A054946263F617 28: 9C900BA37199B7C7 29: 0C6C58743EC83082 30: B24197EEB5603D3D 31: CF5B735F8A492E49 32: 337C504698BBE553 33: 3A2BCCC88BE9ED51 34: F3E9241743203ABF 35: B67BCC625815C585 36: F8E96E4EEBC2566C 37: E27D162006C67C8D 38: 08CE8C1A5E3C169A 39: 0CF8AD04125EFCD8 40: 6712F9F044864FAA 41: 0FD465AFFD64085E 42: 6BA8C82B3974391F 43: A5FFF24CE9659357 44: 0947F81E1EB4970E 45: DEA966CA50243067 46: 1F1BE4866F48E39F 47: 03A7D7CE793F52C7 48: A1FADE3F801B414A 49: DE7DA6D14A50E305 Key Size: 68 bytes 0: C8704ABBDA9624EE 1: C719C645E301FC16 2: 32D82553B0E35EF8 3: C63C77EE6C2A6E36 4: F84EDA1E77ECB5F0 5: 382C1E72AA1FD1BC 6: 6B00939F535F9C83 7: 3CE0825AE10C2B0E 8: 1F9E7738602BDD0A 9: 9273E7933CED0B0A 10: 4CAB45EEA45C32DC 11: FD0208C6A89FB519 12: 520D8E6912E9551D 13: 5B88684544868BD5 14: 32AA2A8EE58135D4 15: 281045702DD38766 16: 26D68E073C996747 17: 23DFB9E174D86192 18: E32FD5AF5101E45C 19: 3DEFB679670A143C 20: E616394D859BFE94 21: 217B9BE0ED47DDAD 22: 4F7901A5620EA484 23: 6654C042783F5737 24: 752AA74BACF9BE65 25: 2FAEBEB8B325F89B 26: 6FEA020B058F32CB 27: 2A32682A36691665 28: 338C8AB628A30105 29: DFAE9DD082DFE38C 30: 51B451C29DBA19C4 31: A2993DA9B8C1D5FD 32: 24D92FA331E2F93A 33: 821A961C0524C89D 34: A07BF305EE8964D9 35: 981652361262C5CE 36: 3DD770C3761B695B 37: F36359AFE1C8A07C 38: BEBC629B8938F4A3 39: 2E31DC53F77898B3 40: 52E4104C4E8E6901 41: 75C912DA610525EA 42: 2F280F70963F82DE 43: D7E3FCCA75AEE5DF 44: 8EBC7E825A14A2BB 45: C1138701F64187DB 46: 1294E21ED2550DFA 47: 577820D772BE2C8E 48: 48CE93C46BFD33CD 49: 3B50D264382E03BC Key Size: 128 bytes 0: 236CF0A207576E8E 1: AC12D8F1AE55F057 2: CEC4230F747B547A 3: 61EA1B510D033B26 4: E064F51998E20804 5: 6247797DF02BAEF7 6: D25A766244063A7F 7: 2C2B3FDDA0E07067 8: 04EED646C3F6FF90 9: 05487E7702865E4A 10: 6C0A92AC23ED07C5 11: 6E54E768C797F797 12: A7C53BF7B252A884 13: 731052795E12C80B 14: 3E4DAD15A826C43D 15: 10B1191B4012C2A0 16: ADD244B33AEAEF7E 17: F6CC7B5F0885E056 18: E23489F3B7BE438E 19: B0C27661692FDE4C 20: E81CE014DA769F07 21: 7A8BE0D2D52623A8 22: 082F444E00D5E127 23: AE42F684ADD1DAC7 24: 9061BA686F76A450 25: 9BEB7141B8F6F5F0 26: 38CBA9933AEF85E7 27: C66F4245901CB341 28: 8659AA47E6B06BC3 29: 357AB20DCE2DDA3E 30: 236689C2F36976D9 31: 331EFD7D5CF7AD50 32: C373526C2D44DB80 33: 79F7ACBA770F5C92 34: 64325C5A67F364F6 35: DF2F720829FF1694 36: 9EE17F47ED487BC6 37: C41067896AF4CFC5 38: 5776E1E5FBE59933 39: 07A05B1508B739E0 40: B19EF72A65B3C035 41: F8BF5FF4095C0173 42: 7F1226C6CA7B4072 43: 8A6C8F26A97DD33B 44: 62948A9A627E98AD 45: 9EC58E3F8A477D21 46: A656F285AE0684B4 47: 8489690681A53EE5 48: 940915E733721837 49: 1221956BCEE0143B Cipher: rc6 Key Size: 8 bytes 0: 6533F7041D69B9B883A5305180A85520 1: 496683D6356950E8F4AF4582630BE46C 2: CA421828FCFCEF2F042F6D81F14CBE76 3: 92DB67F2F057858FC806E071D239F245 4: 203CDFE0C36434AEDDBE2DA68ADC5EF0 5: 8EB23BDBD58A279C1F3BF75199FC9E34 6: 8FA8BB4E772E09DD1EFBE03090E77FF8 7: 2018803BFD91D157AE20C6E8FF1894B0 8: 267319634294F0684AFA7B26EB612B3C 9: 108745E1F2E80864D9043582CD5550EE 10: E4F9EFE5A6C426BB719EA17174890D0A 11: EFFD4CAE649740B3309692AA19ACA227 12: EB909E6D0789F649538E7EA1686FC0F9 13: 0216851E23EDAE52D9964939DA0A7493 14: D6A9CD3429D1679D26A9599EBDE5409A 15: 5DCDECA6E89A7F0EB40649EFDE6420AF 16: B74FD556B06C07BA8D9E517348CC66CC 17: 9A22CB5B73EF1DDE68A5AEF1B1510ECC 18: 77F78557143E08A7449A75A13098FEF8 19: 548FE6700BD17D0AE247B07C2F1AB0E7 20: B7DFD8CB428A36733BBE9A51CF45C072 21: E7E8B7AA2D93E3DE99C543A473CC6760 22: 3FA5821248B0F0AEB5CF00EEF7958F5E 23: 0A655AC6C51DB33849BCDA72DAE106F1 24: 9EE93EAB01E1A1DC57B698C266469481 25: A7D398720E0ABA2D0D143D8306FD5AC8 26: 98A46C94125BD2E5600BD26EEA420F2A 27: F4789EDC3C50BC4186816F14A86403D1 28: F8AFBA8EC652EFDC3AF5EA5CFE143E16 29: CEEEBD4B6724A30E1859A5B4EF9B2B3D 30: 766715B4C4FA7CD4B365A2A67C79E48A 31: 92C5EB7BE61155D79DE0A6F55715DA22 32: 42CF0C9B2BAACB085CB1603688037D0F 33: 6C4BE816F7B573CCFA8BB6E399EEB17F 34: B6D7E606CC99D267ECCFDBC006878691 35: 2048B58B74F9A721B2E33D2EB86F5991 36: 3E458C1015ECB08CC7B8980135E71893 37: E4E28A032CF2F3C8262CD4BBE7A4CDF8 38: 701EAA449AD9E5AF81DF3F436AB25620 39: D1C3FB7C16F5249503EB389A692B112F 40: 7012790DB65526DC87F9A2BF0FBB5664 41: B782A3104FFE65DDB340F713ACFFE25B 42: A155F033E4536FB1176EBDF9EB5FEC4C 43: 8898BCC7A008127014850D5529327352 44: 8F4B3BE150FAA0371CDE69891E52A3C9 45: D371C8283F68DE983C98D98A7563B934 46: DEB679915E8F0D0B65B37918BE4596F7 47: 84D74F7FA199304A47BB37B8AF893CF0 48: 5367B0187496539F6DF6CCE0965B376D 49: 4B9C6011D43CF2D8FAFA2E7105D85024 Key Size: 68 bytes 0: 6BBF763FF30876A4BBB68A7E7E290770 1: 59852279E82E98B8B680E5CEE12BB99A 2: F96989565E5B163EA483FF74ACA22DC9 3: 221F7A410F5AD73C1C67DEBA99683E0A 4: 55F058D1D9B8C372E2A28AB6E953A851 5: 24A8F7E07620A55D69CC3981B92E5CCE 6: F4D9DA95BF66FE28BA3A84E77E62822D 7: EE7EAC2BD34DDE6F83E6D4F23C0A49D3 8: 4218AA697FB7C5D897E66EB00A9FB489 9: 55A8CDF8608A3B1A6B14275E2258A096 10: 18D50743982F5C8A5C528BDB5896CDFC 11: 391403B889F0CEE865893EBE9F1BF90A 12: F3CA9C30C163C510432D3207DB6967EA 13: B14B6574DF53257BE4508DBE78843B47 14: F52F1E5FD6FB19C1F5466276F9C33A97 15: 9D5AABA86E8B65E4F633B6EDE17516E8 16: 9038CF746F722DA1A0C34461359FD378 17: 398E317E9CC074C2293B59598F72EA64 18: 9D75D897D487DD2B5BC534B4B223ADD1 19: 6C6DFF734BFB9700EDD6B3CFC6E311F7 20: E27591407CA9771F227A5B6B3A77C928 21: 1618F15FFA8E2692A3B3EF8EB6151427 22: FA426AC6161F31F0D63FC9DA97A6A393 23: 1281869E9959DED2CF75F50DA7FAB66A 24: E8BF17E4B76D6DC5C1D07DC80970665A 25: 9A869B6C5EEF391C7E7C4585FFD9FF3A 26: 59564F799AFC984D39A8168D1A30C8C8 27: 1D3927AA2E2C48E6CFEF88D04ADD30DE 28: 39BF89DE1365DF15A8ABA86856ED074B 29: 0CCC4A4DEB36A000E7EB271F5EE54543 30: 26476623D35A514B8833D868426A2BE9 31: C3C85993EA15AB2D056D670707851802 32: BF5F7ED18E1320BAD536DCEDEE1A9AF7 33: 337BDC5FF0F7AD44E6A3F5D6712BD5DF 34: 7DBA76B3D9C818D0CE1A530BC79E77D2 35: 20DF55E617CD2598F18534DA7A22B555 36: B0A0C1BDF9E81B4F07F47D31A9CC8408 37: CB9586F4B27F759B9B9C6C7DB01D26A8 38: 1E79A2894906A64098AC43799CEFED38 39: 82FA120F237EB0B3A1F8B52379B8346F 40: 3DB9848603E3B1134585E5C9001D119B 41: A750875900E244996887EC995131D151 42: 12133748D3745F77C161470A921F73BD 43: A265C351694574B44517FDAD8816133F 44: 5E50CC8281C2A69FD376250D99620DD3 45: 443ABBC1AD5605A0BA05B8E6ABA5D2A1 46: 73546A87B39C54F0639EBEC118ADA007 47: 380244C822817453C75405B727D67C4B 48: 73F1E23DFF05EFAB5D39E503031C4165 49: 8030071491490590A8913AE4B5D082CC Key Size: 128 bytes 0: 24B06811BD97AE9512B3799E3189DCD3 1: 92DBA6269E880F8D8A09143D792A46DE 2: F956F459C333DFBA4C6A309C613DD661 3: C31488EA551CC0FC8885F6817CA696FF 4: F59634FE907F9DF9467BD1059F82DAAC 5: 051AF11DD2FCF742169B58A786128CE7 6: 87326A3A4A98CC15B23DFBFFC5AE16D3 7: 58FCDE2E88A79D5682729ADB4D971142 8: EAA787D68EB68CA79CCC6BFAC3BE9247 9: 8BCF6980AEED36AF38B68A50DD454AF0 10: 4B0E31AE48E903DFF52939800BB16DC0 11: 19766AA929B40840715D53D9170C986F 12: F9CAEB36F03CE7B3BB363AC7EB3ACF99 13: C8E34A6BDEDA4DB836DF3D863D02A6EB 14: 370547CEA441FDCBAFD281A8653BE2D4 15: 77E0F33343158A8C3AC3C6D14FD69431 16: 7A985B1368F842C644538C654D081FD3 17: 60E0C8933F43D40003030196E8E881AC 18: 3473474B58AE6BC7582ADD7AE24711B7 19: 75936C8D46F6D5AF5C7EE0E8DCEB5AB2 20: 4A04F619FB0E05F7B07C43F4B9F2E134 21: FD53A5A7F4F0B9D933E38D9F07AC88CD 22: F62EE43B20F582AC77879AD7E66FCCAC 23: 4436AD771624896683D7D29E8879F89F 24: F88F3C0EF2B9FD0CA997BEF17787DA2F 25: FF5576F42CE9A0665A1D6A2420A691D0 26: C077D6AEBA65B61CD1A9AAE17FCFC04D 27: 84D0D7C52D6DB3979BC3F6F34456CB91 28: F163121D9EB7569CA7DE3B7619E0BE51 29: 727D23FB43215467B57DC67A8890CF26 30: 60BA577F3C6627267D7B33E693FB7BCB 31: 82C66B23586CCEA2AE1480B469B3F3C3 32: A65092726D6CF2F77CE00648E2D117B0 33: EC30662CBA891A3380B846DA6C64024E 34: CE1B253FBCE36B217ED1EFBAAAD2E783 35: 9D963CD5E65A9ECD2DAEE93B6C6C1178 36: 1B8E3D07E7BD4BB4248B6A7DF8935980 37: DBC3FD5888B80C4CEFC6C5E170E271CE 38: 307CA8CDDFE5DA152B66E10346BB2E1C 39: 8858250F933650D978B403A4504EA581 40: F06005FA6E56E0C0D96988A3FAD359FC 41: 816CBE37FDE3719804DBFD093E3FD87D 42: 4878C07B127D696214393DDC66F5EB36 43: EFBA6045243050C0D8D82046B17008E8 44: 3D30C3E5892D32BA3C685DC5B186E959 45: D4A4C41F0E6687E4021FB90D7A8A9F81 46: FE1057B2013308C4CE839B4186F43B4C 47: D7333AC65F66ED6D4BB8D069E265020F 48: 33C262F58BF0D91DF2047E799BAA5F37 49: B960A18764D7A6E17FA1F88487EFF192 Cipher: safer+ Key Size: 16 bytes 0: 7D42607880B424C27E5A73A34FECE686 1: 1A99D469F1946EA46523083FBAA79CBB 2: 831385E400FD681C8A30AAD9477F1ABB 3: 5C1BB8F259CDEC2C1BE0B803C7D9447F 4: C57C1CBB18D87FCF72A87B247392752D 5: 1625183B0C595A33FE0E8AE0DCE40ADE 6: 4AF3A9D6733DC4FFF3422AA5BE5ADC94 7: 853133894C87A23318DFAD2B247FBFF3 8: 8C7F68E01A8413D19B9A479246E54722 9: 8620898ECD3BF91A47CC54E6D9987FA7 10: 33F12ABB7CC6A9041543A2073AEDFFA7 11: A096E46F2834F79C096D0B655EDC9A63 12: 3DD0D7824A87C9F5D8D25F5AF57E70B7 13: 6B7C99E5CD29AC1C5A8D66AB460E5AD5 14: 95A9F6009AB4DD2AC7E8E45F36D91E9C 15: 60CCEFC6630329C341782B17365995A2 16: 0276C96A7B1191BC16C8A9C98468DB05 17: 1F352CB77C21139C058837B8194E3E64 18: 2DB8E340F58844705F217551782F6B4D 19: 34E99832E0722C5AE8F0CA1A50E9E7E2 20: 7E1538DC10C1F56C3723A87BFD127743 21: 36B9714A8ACDC8B8A17E85E2803A8C88 22: 11848329B0DB9DC7768C07D95F0CF662 23: 93ECEDEB4C6369AC56AF1F49345720A6 24: A3ED7F9D17067C2650728E266B623124 25: F33574590B435D1DDBBA925F0D0EA8AD 26: 87E542DBD40DCBD80C4AB52555C264C1 27: 6D806991AB8E3604C8267AC1EBEC2E21 28: 4B7333F87EBB46BB2A8ECD392C85A12B 29: 4FF49ACA62898F558AC065B66CAD0234 30: 62DE7B2133B09544EDD0DF66DC4F5E2A 31: 82195B39FF7B8A85D7F0EE52D19E510F 32: 24FA56176A4F0B37F851CBAB176C9702 33: 85FA9230D9B93CDCC0752FC738211703 34: D441132032BDAC6715F4453CBC2434D8 35: 438AB9BEA8A900368D84EF870EAF7E84 36: 433BE5BFE1529BFA7C5688CFE3BD4DE5 37: 2A79FB6F37AA08533445B8BEA5098EA2 38: B9C986EE45D204B6A1CA152944912C9F 39: 8289C9F78760D02AA71873FD97E2ECB8 40: 48B0D1244523165055BE9A5E95CF852E 41: 471E211E5E784C2AF476DB3CB555CF35 42: F290CBEB1F1009D250F7B12E044B80C3 43: 1B9796D80C3976FE3071B1C01154D42E 44: A80E21A1A1007B69E8BCAE728BBE6A92 45: 652058EF0FAF8549424F998669660931 46: 89418FB4740E9801F6DFFEDC593FA32E 47: 907561A69CFA117F167A52B88777D89C 48: EA2EB4B1EE739320F99894B476A8A51E 49: E627E64AAB6E2FF6B99643A7FBB84BFC Key Size: 24 bytes 0: E8975F94A8B1392FBA78CBDDCC8E8F08 1: 708CEFB68A0281AEA424B3D4698D2F2B 2: 21A0DE56545BC950FCE4DF209C96CE6F 3: F2CA4103B703264D46CBC09E13D5B8EE 4: 2892101077FEE427C434CCFBBAB598B5 5: C2F191CC5C681CBFC098B264C479B2AD 6: 308C3B794C8A7971BBA96FE4C727F48E 7: 8A4F9D4463B5DC4DD461ED0763CDAEA2 8: B7E1BBBE455AEDF18329A6EECD6E222C 9: C80DAAE7FBDF56DE05A897FBDBB53DEC 10: 6A3D38758BF0390156F22F83C20F0262 11: CA493DF771E37A93822D6117ED14B60C 12: 623012748826A08F3C59B71FF3D66327 13: A283BCB126B9795D306B129035BCC2DC 14: 3790A6704BB0F119139A0264F7E8B2C8 15: 9B369BBC095428EBD712517B2C4D06F0 16: 0F488018162193ADB11E4C39CFDEE0DC 17: 8AFB7C6FD7D6DD64C2C77DA3A0D91EE2 18: B8BEFA241BA339BF6F059464C533F9F0 19: E76141C8CD54200FAB2F8C2B76AF5FEE 20: 80B4FE57851C0240D81E78DA8200F195 21: 8BF1C690EF5FCE7ADC74E31C24F83F5E 22: D30C4F78703BDE91750E0E49FA0E8982 23: 86C5D1E0B88EF0AF9B899850510000EB 24: FDE727442BCC0305A7B06E6EE179D836 25: 0B4A719342F9226FA680796887A98FA5 26: 980D4BE9AF3E3CF9D4558478D1DD03AB 27: 03ECD11992D3D5864B8D1987966BA544 28: 8DBC2931D7D17657BF38E3931F486850 29: 76AE069E39FA7308BBF507ABE35BC1E8 30: 9541B59CE18EA255CDC06DFD3FFCD1C1 31: 5A382748AE3641ABF6D9CA24A35B2002 32: 9B7A49DCC2CFC5A6078AB41E6F62B4CD 33: 91B2EAC878E5628DBCC7C876B91B73D1 34: 31125CFFC41A0D3528FB16BAE761C47A 35: 916D2A769DA002ADCA8C87F8241BB50D 36: 681C3F601EE5D82F9B040932F2FB4AEF 37: 6B6F32E5EAC2F424074C33F7C988D5FE 38: D15A5FDC2A4956DE61BA6E1C98867242 39: 0747BCFE1B979E947EED5225FAFCA44F 40: 133B43C85CCBC360DF8649BBBD2EB45B 41: 052D943062A6D475D30100EA412C30EE 42: BD6401C591D585F4A82CDCF678679D5B 43: F95D1A5E338F56760C425D972D67B57B 44: 9B1569308608CA00BB1E2BC9E20289A7 45: B6454C52C64F64D69F1D36D2D224A222 46: 529B5B013AE3F37E38BE340D1D200A64 47: 1B65904F177212AC8E9ED4D8DB287810 48: CD5CAC56236E0B9A25A5D306F12D8C4B 49: 01DF7E1D0F5F7A5DAA0B379388425126 Key Size: 32 bytes 0: 7FBC212996ECE9CA2C4D5BD88FA0B3D9 1: EA3D788C25CF3BE7F4101EDECF23455B 2: BD0B98481366AE0869ABA11DB18D1E95 3: 53393E2B757C90489EB6B47F67837337 4: E1D350640CCA6C13648C3B57BE00B950 5: 951E1EF99E6DE72744A9D8D9EBFBA94E 6: 433E4D4E64B41818097BD5E2EBA01D8E 7: 8FCBD07E303B381B2935FB82CA0CBF13 8: CF46569005BD968B9310149E892B4D69 9: F1B672657C2657AD53BFFE2BA5DDE1D2 10: 0035337210703240F9CF2F5A9184FDB7 11: 773951841F77DCF8A6730109DEDF3E9A 12: E47DC0FB381DB86EBD208A0D649E7B03 13: 0D9E34ADB257146EAB95AF14636301D2 14: AB5D5C106E52AC7662C26F9F27F2CD55 15: 6938F205DC23C3500B7723281E9F626F 16: 3CABD52558D7F418CAF6B41CEC334DAD 17: D2192F1E5AFC3B989C42C396B3764862 18: 59D32E3A41141C6CAA2A8F44FD587D94 19: 483CFECF65D71CB2994E1C12A1A7F907 20: 8F086AD81B1FD5B13195EDB4DAB7DC73 21: EFEB1328CE7AE6A63E7D8B3ECA9E12B9 22: 362AAE308B3BBA588DBCFBB7197E693C 23: B817A136EB30CD127B5015A85A7B6E95 24: 03796E7F244CC916BE02AF61E5FEC42F 25: 5854F2889CFF44B0688718C23B0A822D 26: 0F772AC6E37364AA7B844AEACB33F4A2 27: B3E95F5195BA646DAF333AA89130451F 28: 911A32AF7CC44309B37D75E158A4AB18 29: 232CFE228EB72A949616B307C2BEED15 30: 7C8989F135B8DE6FD26C7792B8354F35 31: E79231779BFB9F792BD179C0625280A8 32: 015F6CCAE8A1275A2E836A207D8254EA 33: 4EB94709245CE1FBF7C6D9587FA92D40 34: 63D82005320F974EFDC4C021FB73ABB5 35: 0F15B2E8E389C2D59289D7DA41ABD07D 36: CEE7FBBF766540D4E39903D0494DB797 37: FB564C18A15D53108C1954FCD3518FC1 38: A67C5F4A4A95AF2BD8E4FC1182B2EEBB 39: 0D354E664C35B9364E4EE9DB8DE0CA76 40: 3295826D52F3B980B50EFF3E9317F1CB 41: BC65592A9C0BADD84F363A175EE6BC54 42: 58DE762ADA621FE2A7A6A83F68E93213 43: AD774FC8402F7DDBB881B703EC836057 44: F1C95AD5E004AF35AE315AE88A2577FA 45: 968775A2C3485875B024B008D96182EC 46: 623E736238B5800ACD9B67D76C84D236 47: 1C5E9F65D43343D743E50C80D0E0F648 48: A62E4A197E15CF90C2569DC38D9FC915 49: 165B139BE483A71381B9A8E93D9473DA Cipher: twofish Key Size: 16 bytes 0: 9FB63337151BE9C71306D159EA7AFAA4 1: 8CC5A931DEC29B4C7D85595D24FF8405 2: E867FC0E144FDEA24FEA88D22D8776EA 3: B450A2969C67D93E1AE3A4093BA4C48F 4: 7AEA41F9956149F336612E868E42B3C4 5: F201FBB730E6E58CF9E5AD1DC4844C4C 6: 13D8869E66412C6C288B5D7F37F2D94A 7: CD57DDDDB782C0A04C40E47D920799DC 8: 65371C8ABC919EC09004A7D63D9302BF 9: CC31DFD3B7DCCC86866CC79D45A89C3F 10: 541D548D311714EF8661BFA721568D16 11: 269F3AA2D2D10DBD3DD3992BFEE23C05 12: F86DA5D73AFBA94A9D592D02B5855D25 13: EAD8D785B50E036437E39F3B27DB4657 14: 2AD0A13C493B9F3EDD259E11A495B205 15: C05F9D72AA384F05B28A3519AF218CA9 16: D442072F588D38AC8B9D447762E9FCF3 17: FDD3BFB91EFD127196FF9F19ADADBF28 18: F56717661B424E41D7DE1CD13E21DF89 19: 0F6C952D9BE6CA49B5147EFD44455A92 20: 6C214935726364F2766BE7B4C2B64362 21: 5D5316D7E057FF481CCC10C7452D1A17 22: 56C78DBD802CC9B040446A3EFF3F12AC 23: A38CEADA8448DBE29C2D11DF2A487715 24: CB2F786AB8063350F3FAE11EC8C65A5B 25: F5B7298B6F558E2C4FCC11744AD22653 26: 01BF89C1B48C5F6918FC6BDC10B12A21 27: A031F25AAFF294EE79220BC76E73E52E 28: 42C94B50E12499DA35F14BB6BB6E684D 29: FD68B6840DC9A271CDE2032EF0200295 30: A9863C1B04B3FE3945D29966F67B87E2 31: 6226D4CEEC1E8AEC1B7B3E13D80A83FF 32: 6100A71B1E3ABBBA48A9ED280DD1617E 33: 5CE93A26D4EFF0CC7DFA2DD43A511871 34: 282D165BFBA0F7F229161BE533BFC4D9 35: E6AC479970891392972B2845C949A068 36: 4E4A887368F8443BE51FA7CD16CF0B87 37: 121AFC81AA2750572B35D100BDC34DB5 38: 7C41FA7E0A18A87E44BE488F331B35E0 39: C8847D295E1F505C04E2F5CE2CBF5E00 40: 4686EE8628BC1BBB92CE825F04B1D5E8 41: 397DFACD19C283B3FC27D3FCBE952254 42: 815B6C69608B5A379E3C9E67FB1BA15A 43: A73E72B912EB3AA4929E9EAF73A448BB 44: 5BC4E2C88512BCD55408CC5AEAD15A91 45: EF20B2BF297456DED1F4AB7BE0747902 46: 3D876135E19BB56B98050450C6B0FD06 47: D68100E1BAD07B438786337C0957471D 48: CE85A91938049B5E21C983F7C45ECA3E 49: 9FACEFFB9D08BB65DDC34E3C575B8442 Key Size: 24 bytes 0: 95ACCC625366547617F8BE4373D10CD7 1: 99AEB25CCE73B3796C351A19791ACD52 2: 56B9D6689830275C1A3E4266B3D56D53 3: 2F5F822E11F087BCB8A0F428414855A0 4: 65400F729990FE175AAA894BCFBB1A59 5: 947BA33D20194BBB0D4904023FB32FFB 6: 116B0C6744D215AE98DEB1F9FF1D36C0 7: BA6964C101FA044ED06877E46D540850 8: A36B18526FA0004CF557C99A3AC1423A 9: 573099674B8AFC2DD6424A2E4C581B89 10: F46169CFE9496A2696A93EEB7EC561FB 11: 2C64BC052898F3F3A2B78F2591F2BF1E 12: E8A0D40B08585459199DD6ECC108A490 13: 47927989BE5EB55B9A0F294C04FF035F 14: 54A3024E3AD86005A2C44E4B8BDBBEFB 15: D0AD51D1DADFAD7ED0EBCC756DBCDCC9 16: 5DE698B7014C34AA6F0099CBB5937A20 17: 9BA30F49470C6DB9632C5EDE34F8EE73 18: 0BDF558A2AE9298288E60616442D3408 19: 25F6DD23BA4E090E1CFFA6EE3487AFA7 20: DAC5FB99E299D2672F79F0C38E177D83 21: 58CB113430895C9890D96EA60E3DDC23 22: 48A0771F0049B776A44AE8877B57EFFB 23: 2F12B26A4BF7065076417530CDEE14CC 24: AA6ADCB0176D5324C4C1FFD640D502EE 25: 384B52A66F4C7A70ED36091BC3FEA09C 26: 2AFE7ACF071C6B0FD69930A09D6DD5E5 27: 9A2DB9A5E7712A5BFB095D2C09453CA3 28: 716C0EF522A13EA05A48F16BAD3FD10A 29: 44AB46F3CCFD02BDD2C77A332293A4D9 30: CE6AB27A0F60F410B1B3CACD9AB923A8 31: 69EAFAFC171C55D1D90ED1C6E1F3A48F 32: 5EEEB0B7833121AD7D27BCFAF2D4F8ED 33: 47133445A4EBCC60E27B29FCC160FA75 34: 9F1BFEB9715A20D5FA7BA3BFF1A27BBC 35: 516D4615F07756B4DBE7D37EBBF4684E 36: B88744E53073BDA0F1B115E3DB224E83 37: 1B77C3D067BBE00420450BA5CD9A83CA 38: 94B87AC96F8CBFF36B01A68E0651E591 39: 52ACE87A1A8E46655935536FB3701290 40: B406BB632D5B7985400EC78D621C8801 41: 20F9ABCBF97A9917EC6C5DE3CB2C925B 42: 539A8AF920833F9E81A20A6D10543176 43: B79AFB8BB39B0351094F37C6EC93F8A9 44: 5830BD21289FED3F95C3E3740AC6C5BF 45: 86C4AF5839ECB9860B175642ADA32895 46: A6427E5E08CEA2A50B8426B063AEE189 47: 2E872129B5BC5F535BCE2B81F013A103 48: 2203EB9B2BF51FC2025549D0BF1924A7 49: 6A5E383A4FC78F6E03B9B276F81195BE Key Size: 32 bytes 0: 8EF0272C42DB838BCF7B07AF0EC30F38 1: 9F8801E94E41A7DC875665663BFA7912 2: EBE2CA6B45A0BEE83B54402E1A843A3B 3: F6C5A1187AEF4B5A88E97E866CD757A1 4: B3E62CD473E53812EDF9ECE875F39F5B 5: D8C38B1EC23264BB7C42B5589C1300B2 6: BE315EB75B944EC9E51F5EAE65F70BD2 7: D4275409941A44993037364886B60598 8: FC34F1D4E9C4A634C1349F6D4E9AB94E 9: BE712387C59A40A8A35F854333A0302E 10: 1F1FE164834BABC71DBFDFCCA7D2B4B6 11: BB2413CCB5347B5157651819E698D988 12: 6EB5523A968ECE965D9AA4B975D7C2EF 13: B5DD49AB7E269F9D8516FB57EB47D57D 14: 74F5D81856F192D49A70B3743945BFC0 15: 95437BB00D57CD88BD52DE0A66D934C6 16: AE4804A975D67C6B6F99176F407AAA3C 17: 5E5B2FB9B2A028A5467B56F8BDBA6980 18: 8C617FF1F9C50A36BE2EC19A629BA96B 19: E3401F7CBE177A1D224117894E7EA08A 20: F8451D9DD31A08BE828FA9AF39708921 21: 5BE66DD577826804817B85A07BCEDE28 22: E426227780943AA1A830B7E7D7F7CA0A 23: B39C7277C3A5CA21897563DBD8DD6D94 24: FA9992385396F959841D1E0E68CCE00D 25: E1DE89B1DD5CC31685558A51CC731E6C 26: 64618455C46C6FF117F19FF300B3B557 27: 882758C02B3C11D406A21012977D4BF8 28: F948B62F8038D3A3AFB73041B2F263AE 29: AE3BF626020D2877052B90B31E70B8A4 30: F1C6DBBC166985C9EC2E1A3A61BD8E75 31: 82C343FA36B6D4E9E7AF6D0B7741FB09 32: 0BFB756EC55AC63BEA71E4A8187C2B10 33: F1941AD10BE60DAD3FBA33CB899B63A3 34: 18236A39CD34743DE7B60B2575A9B204 35: AA37FBC2525F74710D7561D316E8D90B 36: 413E0F72C2B349FE2691554F77162B5C 37: 5B9E6F98B2CA0F637E463BE4A6EFD39E 38: 1B4A4CA36DC60D51BA981392D6070379 39: B1E26163A90F339E33F86D252EFBAB99 40: BB98F9F844FA81B25ECC89A8482404BE 41: CE142F512A42A28F4788847B971AA7E9 42: C5CE782936F3D28C69C2BD45FD7BC117 43: 9B6E142582E0A309EDB550DED51238B0 44: 0D9D80C01612977FF3A2C7A982D0894A 45: A7630C752B1F787B07C382693334C6AF 46: 9F24990F270D575881C746481A59C245 47: C38B5E11479C200B5ACE1D6522FC6B1F 48: 99118D8114D24B6559CC5D9456F1BEDB 49: F8B974A4BC134F39BE9B27BD8B2F1129 Cipher: safer-k64 Key Size: 8 bytes 0: 533F0CD7CCC6DDF6 1: C3CD66BB1E5E5C17 2: 079DFD68F6AF9A79 3: 84EB4922264A1204 4: 31F3A7D739C7E42C 5: 381F88FB46E1DCA2 6: CAF4AC443E50EF47 7: 2914E255DA9BDDBB 8: A160A24120E4FECC 9: F748C6009FFBC465 10: 8B3CB5784846D2B0 11: 4F98C1621473399B 12: B486B0BC365ABEE9 13: 314EAB2B4E9F7840 14: 613FE3637968A8FE 15: 28935352361E1239 16: 0DCB090233B8EB3C 17: CF0BC7F307586C8B 18: 64DF354F96CB0781 19: D2B73C6BAACA7FB1 20: 638FCEEF49A29743 21: 204C4E0E0C0A8B63 22: F041EF6BE046D8AA 23: 76954D822F5E2C32 24: 6700C60971A73C9E 25: 80019293AA929DF2 26: 8EF4DE13F054ED98 27: 41DDF9845ABA2B7A 28: B91834079643850C 29: 8F44EC823D5D70DC 30: EC2FF8DE726C84CE 31: 25DF59DC2EA22CB5 32: FC1130B511794ABB 33: ED3259359D2E68D4 34: D7773C04804033F6 35: C1A32C114589251C 36: 51647E61EE32542E 37: B95A8037457C8425 38: 4F84B3D483F239EE 39: 458401C3787BCA5E 40: F59B5A93FD066F8A 41: 1450E10189CC4000 42: 0F758B71804B3AB3 43: 51B744B271554626 44: B55ADA1ED1B29F0D 45: 585DF794461FEBDA 46: 3790CC4DCA437505 47: 7F7D46616FF05DFA 48: 6AE981921DFCFB13 49: FE89299D55465BC6 Cipher: safer-sk64 Key Size: 8 bytes 0: 14A391FCE1DECD95 1: 16A5418C990D77F4 2: EE33161465F7E2DD 3: AB85A34464D58EC4 4: 3D247C84C1B98737 5: D88D275545132F17 6: 00B45A81780E3441 7: 6830FAE6C4A6D0D3 8: 93DF6918E1975723 9: 15AB9036D02AA290 10: 0933666F0BA4486E 11: 93F42DEE726D949C 12: 756E7BA3A6D4DE2E 13: 4922DCE8EED38CFD 14: 8EC07AFBD42DF21C 15: E82BEBCFB1D7C6B4 16: B3EDB4CB62B8A9BA 17: 5521307CA52DD2F3 18: 54B5D75512E1F8F3 19: 1A736293F2D460A8 20: 778C71384545F710 21: CBC041D3BF742253 22: 9C47FC0FDA1FE8D9 23: B84E290D4BF6EE66 24: FC3E514CE66BB9E3 25: E8742C92E3640AA8 26: 4DA275A571BDE1F0 27: C5698E3F6AC5ED9D 28: AC3E758DBC7425EA 29: B1D316FC0C5A59FD 30: 2861C78CA59069B9 31: E742B9B6525201CF 32: 2072746EDF9B32A6 33: 41EF55A26D66FEBC 34: EC57905E4EED5AC9 35: 5854E6D1C2FB2B88 36: 492D7E4A699EA6D6 37: D3E6B9298813982C 38: 65071A860261288B 39: 401EEF4839AC3C2E 40: 1025CA9BD9109F1D 41: 0C28B570A1AE84EA 42: BFBE239720E4B3C5 43: 09FB0339ACCEC228 44: DFF2E0E2631B556D 45: ECE375020575B084 46: 1C4C14890D44EB42 47: EA9062A14D4E1F7F 48: 82773D9EEFCAB1AB 49: 516C78FF770B6A2F Cipher: safer-k128 Key Size: 16 bytes 0: 4D791DB28D724E55 1: 53788205114E1200 2: 4472BCCAF3DDEF59 3: FE9B3640ED11589C 4: 4DDD7859819857D7 5: 6BF901C4B46CC9DB 6: 930DBFC0DE0F5007 7: E89F702158A00D82 8: BEB661953BF46D50 9: 6F0DA64C0FD101F9 10: 4EBBCE4E5A37BED8 11: 996EAA0AF92A09AC 12: AED6BB9522E0B00F 13: DF9C643624A271B4 14: 2E5C789DD44EF0CF 15: 86A5BA1060177330 16: 2385DBA4DEBEB4A3 17: 82E2FC765722094D 18: B3CA2161757695EF 19: F8A4C6081F3ABC06 20: 6422316E1BEFFAC8 21: C178511BFBFF380E 22: 049B8CBEDE5942A9 23: 0E181292C1B1DEFC 24: C347BA0632A49E55 25: 32FDA46669714F99 26: 0523743E30C16788 27: 782BE96A93769ED0 28: 9F99C9E8BD4A69D8 29: 104C094F120C926D 30: 1F7EA3C4654D59E6 31: 90C263629BC81D53 32: 1803469BE59FED9E 33: 1478C7C176B86336 34: 362FE111601411FF 35: 6428417432ECC3C8 36: D74C42FCC6946FC5 37: 1A8F3A82C78C2BE6 38: EE22C641DC096375 39: 59D34A0187C5C021 40: F68CC96F09686A30 41: CF8C608BDCC4A7FC 42: D2896AB16C284A85 43: 8375C5B139D93189 44: 0F0462F9D8EBAED0 45: C3359B7CF78B3963 46: E4F7233D6F05DCC9 47: 8533D1062397119B 48: 4B300915F320DFCE 49: A050956A4F705DB9 Cipher: safer-sk128 Key Size: 16 bytes 0: 511E4D5D8D70B37E 1: 3C688F629490B796 2: 41CB15571FE700C6 3: F1CBFE79F0AD23C8 4: 0A0DC4AA14C2E8AA 5: 05740CF7CD1CA039 6: 24E886AD6E0C0A67 7: EEF14D7B967066BC 8: 6ABDF6D8AF85EAA0 9: 0EB947521357ED27 10: BDD2C15957F9EC95 11: 0989B87A74A2D454 12: 04C793BA2FAB7462 13: 3DAD2FACDDFA3C45 14: D1194935CC4E1BD7 15: BAC0A2C8248FF782 16: 7DD5894A82298C64 17: A59F552A4377C08B 18: 8DDDE41AB4586151 19: 7CC4261B38FFA833 20: E99204D6584158EC 21: AACC8ED0803CB5C4 22: C105CA72A7688E79 23: 3D662FDC35B88C09 24: A4BCEDC0AE99E30E 25: EAECF9B6024D353C 26: 214651A3D34AFF40 27: 807099325F9D73C2 28: 45EC21AEB6B90A24 29: DCED39526687F219 30: 2CC248E301D3101D 31: C7F37AB8570BA13C 32: BB9B31A34A39641B 33: 5314570844948CAC 34: 4581F837C02CD4F4 35: 4E036B1B62303BF3 36: 7B3B88DE1F5492A4 37: CEF2865C14875035 38: 14DE8BEE09A155DE 39: 3AA284C74867161B 40: 3616B4607369D597 41: 07512F57E75EDEF7 42: 710D1641FCE64DC2 43: DB2A089E87C867A2 44: A192D7B392AA2E2F 45: 8D797A62FBFE6C81 46: E52CE898E19BF110 47: 72695C25158CB870 48: 29F945B733FB498F 49: 27057037E976F3FB Cipher: rc2 Key Size: 8 bytes 0: 83B189DE87161805 1: 7DCB9C9E50D15508 2: C724D535853CDE79 3: 113AFD4BA7D3D7E3 4: CFA06CFB93C2280C 5: B3F291C1AAD9CB07 6: 606F74D9AAD4FA71 7: 1CC3F7AD551C5F89 8: 43F8772BA6C6B60D 9: 2F933E12F57689DD 10: 2BC1AF0D5571D17E 11: 4123AAFABDB254E5 12: 413E0AD5C709DCE0 13: 6B3CF01A7542BD2F 14: 1E5E2CA0CD605999 15: D0F7C9DC472A0709 16: 00482798857A2BB9 17: EED583440CFA8B48 18: DFB377FE1EE5E055 19: 30511C4C565E8F75 20: F74A72482B43B99E 21: 1EE4EA7849B0B070 22: DB7A4ACF022706FD 23: 2D7EBABC8C8E4DD4 24: 6F0369BF66A8B637 25: 59E5D13B247EE0F6 26: C7BAB430AA89A5FE 27: AE0F03746D38138B 28: 942DF0B523D02482 29: 929CE0963CFA46B1 30: F8C68A91DC53B7CC 31: 5735395C63E15094 32: 7821605C18D83D42 33: DEC892FD743BA6DC 34: 77AC80C1177963D3 35: 3E223EB4EA297456 36: AF63B231D671D9DC 37: 665CA287AF32E92C 38: E451EAB337DC1EB6 39: 95B179EC950992CA 40: B8937115492802AE 41: 355A6E5EDF40A939 42: 353E77D4A5A28D79 43: C958FA5903F921B8 44: C334E296BCB24ABE 45: 4F37F7F652FE31ED 46: 77304A655B03ED67 47: 3548A4209ACB6EE2 48: 696E712B1911B695 49: E4B63641D22A3DDD Key Size: 68 bytes 0: 7ED68E8B30A7D5DA 1: 867E18AE64B783EE 2: 032E554D6AAD7055 3: 26BD785D0DDAD48B 4: FFBD4009ABF53D03 5: A71006E1E30C3855 6: 92638EE741BE65B5 7: FC8C5F28CB38C83D 8: F03F145CBCC4CF80 9: A28A7C63F67DDE7B 10: 3089486A2247B72A 11: CDD6E6BA5ED53A8D 12: B75A2DE8CB96A267 13: F74D72A2CD68CEF5 14: 3865AC8D170EEDBA 15: B1B520CE5FC2BA39 16: 658DACFDD701B4EA 17: 6B5C1DA9484FCEDF 18: E3CDFB5755BDFFC1 19: 56DAFF7E9A908880 20: B6F8B970F68BC2BD 21: 7A00DEE6977A91F2 22: 6C0CE4FD2D02B36C 23: 8EDA10D868504648 24: 76FB106689E66EA7 25: 67F45BB28A20E110 26: 5F3207099AF93B07 27: F5E382F7266AB342 28: 0E31AC2E4CEFFBDC 29: 8DBA1B2FC6980FF0 30: 311368E62EC2A9E2 31: 50DD1F7A319727EB 32: F0DE146C9ECF5662 33: 81CE0842CE223F15 34: 4C442535A8BC9AD2 35: 06EE8869DB91EBDA 36: 4078E7CAC29DCEE7 37: 115D619FB705F289 38: 3D3F8A380DCB8FB1 39: 9044E5AB8049D21A 40: 66327F00B07CFC76 41: 811AB23A4AD3F132 42: D4A507E96BB39BC2 43: 51C9E4C9318F87D9 44: D2255C13DBD09E88 45: ECB76BCB961F812D 46: 83D7E39727BBBEC5 47: 415540F0AE34DD65 48: 232D20F9E188E2C7 49: EE37261ABA270B22 Key Size: 128 bytes 0: 8A8F8E5C5A04C73B 1: B197CF922883CE71 2: 8AF3F896460CC597 3: 755F313AEB18D3B8 4: F1DB52688BB879A8 5: 29D68EA6456B1CF9 6: BE7C444267A7925D 7: 46A7BF7DED575933 8: E2C7AD7C902E5E15 9: 90A38AE1DD69C2EA 10: AA95FA050CD3388C 11: 23822B6AD5B83018 12: 8FD42F0DBFF3FEE1 13: 645098BC94FDE21B 14: 7E43D43EAC50E992 15: 2F540FC66A9E0F43 16: 453E52EA7B2D1F92 17: F6F731E8C5A32C54 18: B1E89646504E4D7C 19: AB8168452A7984E1 20: 044BB0758DB5435B 21: E9BAE7C99A152BFF 22: B758F70708B6597E 23: 23A1EFD0AA925D7E 24: CA60DD174CBA23DC 25: 5E916F2DF7B6B3CF 26: F2723A9BFD82BB62 27: 2BC381F6C048687E 28: 573BFD71896A4133 29: 03DF7250C3D69801 30: 8639060454669BCB 31: E31945F0A87221AB 32: AA39447BBF0A77EA 33: 174F1B65BF6A34A3 34: 2712F966022A9589 35: B6358876D6D56D16 36: 2A92C131E68B77BE 37: 040C6935F4CFC43B 38: F23503C74121C660 39: EDD120883F1F813D 40: AFC6500D34BD9D33 41: 963117444417BDD3 42: 2FC3A58861B4A58E 43: CFDB70ED8BCD1173 44: 91B75760CF38B8D5 45: 93A59048B78B3415 46: 7E60C5E75225D45F 47: D4212C6422878FFA 48: DDD1B241E0E0EF6E 49: 20337DB931078078 Cipher: des Key Size: 8 bytes 0: E1B246E5A7C74CBC 1: 9262AFD8AD571E2E 2: 36D2067D960EB870 3: 319834DC66705192 4: B4508A7C5F012C93 5: CAD1DECDDEE81342 6: AE9E1CBB71C719E6 7: D7FBB1CDAFD5B2C1 8: BE1A70564E3BFB5A 9: 96D9EC1407A1BD34 10: 05E4B9AF3A4DABB3 11: 0DC77419E1F12C02 12: F73E62369190A5E3 13: 830C1CA7820ABA2D 14: D2574B6AEED0A4F4 15: BC08782E293546A1 16: A35DCC9AAD1EBFB3 17: 79B2224667B33706 18: F9462FFD2808233A 19: D6421CD0D9697DC5 20: 57CB2173D67E7001 21: DBE2DB0BDC07644F 22: 014E72E7E99C969F 23: 37901B1963D0B29B 24: 8E12C23929125686 25: 73AA9E2A60C327A1 26: 54A19D07D941EAC2 27: ADB8CBBAEE1848D6 28: 3997E866119856B5 29: 4D647526FE7E1E27 30: D574FE7342104F93 31: B84383E34A790E11 32: 322214BE9B93BB6F 33: D4C8E0B7AA139D68 34: 2B9747CD280E48C8 35: F92EB2E3711FEE2C 36: 5CEE84E124B7882B 37: 82427488597FF618 38: B1E8B313D2DC76CF 39: 03E237CD40D7F214 40: 8C8DC1299293E15D 41: D6C7463FE86D4EF8 42: CF1550CACE647779 43: B998B3D32B69F00B 44: 1B94C342C3D91107 45: ABD4551B27F58BE8 46: 2B24D978D1BFB3DA 47: 85361D36950635CB 48: 448009F38F1DBB4A 49: 6B901B2B79B6950C Cipher: 3des Key Size: 24 bytes 0: 58ED248F77F6B19E 1: DA5C39983FD34F30 2: 0BD322177B935920 3: 9D093F3174EDBAE3 4: 756B1F2CDF02B791 5: 57C31C2A913C1126 6: CF936257517C53FA 7: 5F06305849E5E158 8: 9A85DFD788C59D19 9: 6392279BBE29DC1F 10: 76B0AF835D79C4E8 11: 7073F36DB1E31464 12: 276258605F2CAB3B 13: 3B69E97811FDA996 14: 3E6E491D2862A1F3 15: F8F3F68BDB006520 16: FD376E66D401A097 17: CA2FE47825804996 18: 6F5C256F84FD14AF 19: D7B07F5C40FF0CDE 20: 73F2E074F1324496 21: 0B2A35016F24BD21 22: B040D2E3B311C193 23: 3938DEA347112E2E 24: 9D7C1703CEC0BFAA 25: A07949F76BDFAF68 26: 43087EEF52564C4C 27: 11132B599734AF0E 28: 62A04C819FDD9A8C 29: B74F0E5649D33690 30: 8E77E5009B0AA322 31: 5174134B9A1889B9 32: 053E33441D11AE63 33: 01EF381013F86E4C 34: BCA358DEF35DFD60 35: 5908A88513E2E5A0 36: A3214C8367E04B05 37: B2CBBE851A54BE9C 38: B271817F63B3B76A 39: 08AFBF82ABB97D8A 40: 2CE02ED014186B86 41: 63F3011C97F6E990 42: C392351F432738D9 43: 0534DDA50E685725 44: 1509456871F5CC20 45: 2383029935901342 46: 8714F1A53CCB213A 47: 2491B2FD3CE6A7CB 48: 4BB02399D85BB66E 49: B8AC2CDFF7AC22C1 Cipher: cast5 Key Size: 5 bytes 0: 9B32EF7653DAB4E6 1: 48AEB06B1BDB2397 2: B530927183622D58 3: 0ECC8F24BA742216 4: F6352F9B6461D82C 5: AF6315AE98E12A71 6: C364D4B506EF28B9 7: 817061BEDF5E0A5D 8: C19DE7B1F2066C04 9: A6E1345E3AA1B79D 10: 06B036B04785428F 11: 244DAB3F7223F567 12: B9CF3791F6C79F4A 13: 86C5A02AF0517C5E 14: A16E3198F1317E04 15: CF72A44C01E36DDD 16: 199C72ECD5E632ED 17: 0BC66BF05EB7887A 18: AE1F696F3D6B7952 19: 685C92084F600885 20: DBC1353A95AD2097 21: F481E98CB36CAB3B 22: 8F1C06A482C70BB6 23: EA087739954A9CE5 24: 6D0AD727D8E4EF9D 25: 61CA0F7965FEE246 26: 0D664CA16BA785DA 27: 2359D363755605B9 28: 6B6E3A216ABFB55A 29: 6FBCCF7B0342D3C9 30: 3431F4572E2CBE57 31: 36D84FCE6D5D8FE4 32: C234F6AD41E34E76 33: 522F12E8D0617263 34: AD8199B6E94D4E74 35: 56DEC7C21C83B2AD 36: 22CDBFBC5B476E69 37: 70BAD497381F378D 38: 4584F15DBC0EB7F3 39: DE0603CEE19BCFCD 40: EA8D582C1CE62FC9 41: 4299C28A912CE568 42: 7208AB000E3FA9D4 43: 7AAE6CB398D01665 44: 33A6AA42B6D7949C 45: 2AEC5640AD535D69 46: 74D37D9DD7B67248 47: A5300FFF5CF85833 48: 834F83398D591C38 49: 85C787A8B7E519DB Key Size: 10 bytes 0: 95827CB504BD43C7 1: 8FBF4EBCB8413ABF 2: 5CFF411BECED9971 3: CEE2AEB4415E0A5D 4: BB3A8DF7C54FA88F 5: D508B933EF335111 6: 993745722EF0D8D3 7: 04EFB233AA88E796 8: 478A7DCEAF243F90 9: 269CC3D138ED48E7 10: 88EBD14D2F999C89 11: B7441626D4487A20 12: 46A6E2CE6C66058E 13: 60687D2D5381757F 14: 885D05ABBF187B89 15: 5032A7ECD3D51521 16: 50BAF36BC5C14A8B 17: 8E805499569FBB0E 18: F8359B18AF3E69C5 19: F24E415CB4D2AA95 20: 361805D4E45B56B4 21: 3172336F01E3530C 22: 333A551E0A03C4A3 23: E2B991995A2D2962 24: 067CEEDD8F213B67 25: FEC3F306851F8616 26: 4B80DAE6AB11894F 27: 250C26E21A8273A2 28: 313F2A505915C909 29: 42E0DC3D4816B38D 30: 9FAEEF0510DEE721 31: 3BB5F5EF74B4CD7E 32: 0FBC9007F462BEAC 33: B9D1467B0D7A1043 34: D9B991C9348DF321 35: 061D577806C50742 36: 48AEA67AAAB6FA23 37: 22F7910383BDA87C 38: 9987087EDBA56FD8 39: 2FCC8341B69BAA14 40: 29DEDB6C2A433F50 41: E067D2746B99A9CB 42: A5C9CB975A856D57 43: AAFEFD3A82D6185B 44: BBE8952CC93CCCC8 45: FC08CE0934EF2E25 46: E44E642DBA7CF3F0 47: CC26F0E8E85AB372 48: D95D63B8389082E0 49: BCA941C921B91E16 Key Size: 16 bytes 0: 20B42D77A79EBAE5 1: 96CF6C91E5183CA2 2: BD87E77A38DDB4E2 3: E7454CA30B69DE2D 4: 888F278D219384EE 5: 972CB887CDE920F8 6: 49BEC1E7913F3CAE 7: 96A81B37FEF63CA5 8: 408DD23A6DA940FC 9: DA86E92BB735755F 10: 2032F2D972F228BD 11: 8F9EF7DEEF74EFEA 12: 547C92025DCAF9F4 13: 80CD440DFF2EA62A 14: 7D6141D102E1B941 15: 307596ABF5C9A6B2 16: 82E3F1B17EBD52FE 17: 5917DDD11EDB55A3 18: 2909F77166F24F9F 19: 88BDE9D686328942 20: 8F987B737F6A011A 21: A74B3D1D6433B9F4 22: DA8F95DE949482EC 23: 953BA9B26B9AC476 24: 76A52FE193CBFAF9 25: 4BB7D2597A78F2D8 26: 5C8BE951251F4B1D 27: 6E8AB32A4A279D84 28: BB94BC9937B42848 29: FF0EE686F97BF8DB 30: 4146656AB1477E13 31: 1BFCA7053E6DB8AC 32: 4B9A6A349BFA926E 33: 3B5F6FDD127B0A87 34: 53C996E956598599 35: 62C142E63C28B5EE 36: BBB71D6548F32693 37: 107576AA26352455 38: DE32E31FFE02B6F9 39: 4C5DB81D1715FF5C 40: 8E5C706206F493A6 41: 4BBC51E184A67C92 42: AAE216B413DE2A06 43: 77AE26F467233B06 44: E8680D0E71F6AAD6 45: 7061DCED4BC94F78 46: 06772D63818C7E86 47: EE5B9CFC06CBD639 48: 5784B3EFCDC28DD4 49: 4F962107A2EF843C Cipher: noekeon Key Size: 16 bytes 0: 18A6ECE528AA797328B2C091A02F54C5 1: 2A570E89CD8B7EEEE2C0249C8B68682E 2: 828F4F6E3F3CB82EEEF26F37B26AEA78 3: A3CA71833499F244BF26F487620266A4 4: 333ACCE84B0A9DE91A22D1407F9DA83C 5: 224285F3DB3D0D184D53F8FFDC8008D0 6: DE39E2973025FE9EC1ACDE8F06985F91 7: 2F00F45A01B1B0AA979E164DC5CCFE10 8: 43775F3CBEE629EF6A9BA77CA36171D9 9: 1E6A67ABF1B6ACF59FB484866AC15A86 10: 70490989E2CD2145730921CCC37F0A17 11: 67B0DD0EA903486B1CB56591FCF42678 12: 774AAB71FF28E49A30E1E718D98114E8 13: DF4797990E1C65C9F6735BD967164D45 14: DE2779DF26FC1B99F576ED4CFBAE76CB 15: A13AD17440641B3460A01175E3274AB9 16: 1166499165F2A1196CA2DB831F264E77 17: 35D24A385416CF2A44AB97A4AEC45E14 18: D3D0E0DC962B1AD1AED92F57129088B2 19: 00EF3E246B32634ABAF8BEE31D5C592A 20: 79BBF3F807675B9F264BABC67DF4C2AB 21: F391F2D58F0998F24BC9E5FA75DB9E99 22: 066EF13C2617E97E6015B86BA1E059B2 23: 5B0E2D7AE1E2734B9D5734C87F7BE272 24: CDF7020212B7CF21F4817829386A6F8E 25: 24873E1A0EF4908DF85114ED9BDB0168 26: 99904360C843472F71AB86B26DC78A00 27: BEE70B3735A67268578FF107C328940B 28: 97DBB283536BC8AE8DBF56F3474C7740 29: 2F4C903975EF709E004D24DC132A8A51 30: 3EF0859A281782F905198C607FBE5C43 31: 2D9CD48BC6A99E86468CBDD2A55C7D5F 32: 5518D3ED18D5E5A62752CDF0846D0C77 33: F751E9CAF107BAD8A1F1F9C374277A6A 34: C5BA4DE907C41221FBABC5EC43710D0C 35: 5CA48836330870365A10E7B676695C9D 36: 937A964E0EA4D246E97293375B167EFD 37: C0A876CB6957717541A90CCCB034BFB8 38: A57C93A09F9160A28D3D4DEDC987746C 39: 1FFA1E0B5EE0F0A18425F62717254419 40: 8411C87262AE482CFC43C3092BEAFD90 41: 0B9BB379FB3587A9ACEEED4771D8DC20 42: 3B32EDBF9557E1DFBCEEC269B51FA494 43: D1104E2888679A9EF6A13AE00ED7E1FB 44: 0EC9849BAD58A279B42B5BA629B0045B 45: CF206E8D3399918E75DE4765DD743060 46: 55CCEB28E27D4DC7CE2546454FFD2C33 47: 6E2339281583420B76E1750D35296C12 48: 7800EC3D8C344BE7F2D2812F5AFF3DA4 49: B80F4B0BDAA54A04D5A26BCA185F4EA2 Cipher: skipjack Key Size: 10 bytes 0: F62E83484FE30190 1: 03B4DFE5423A117B 2: 8CE4DAA2307CF018 3: 77D8C958DAE4336D 4: 00D367D5C1FC95D8 5: C1F1305A5B01A474 6: C3956225C846F695 7: 2A8977DC186749A3 8: 433AC6B56AE5C200 9: 10489A7E87F803CE 10: F176DF022D02D136 11: 1395AE1C0C00AA1B 12: 0C1C3FF32E93F789 13: 901EAAD562EE92DF 14: 59D55D9EE3EA0154 15: D9135CE0BBF68AC7 16: 90A8E4A8E76349A3 17: C04ED52AA69D1ED0 18: 19E842698B5008A4 19: 26FCA0FA3AA7718D 20: 62635FD1A542C7C0 21: 5A3695398C979E40 22: 34998BB72108D89F 23: F889CF892998D689 24: 2C6A4D61F468F19C 25: EC70D59FC906349B 26: B95F11FD098B34A6 27: 32F86206BB4E525B 28: E6BE51063B60CB9A 29: 8964E47BAC22F995 30: B1C297883819747B 31: F2AE1F39F55FB6C2 32: E633EA2DE342767E 33: AF1F0ECBCA788A28 34: 6A898F4407696B27 35: CD9CB5374EA080BD 36: 15881B0200AE6A42 37: 579D05E5F5DE7840 38: 86F8C683D23EB976 39: FDAC7DC6C8F7777D 40: 10D6F7641409F027 41: FCDAA0872D1EC61A 42: 7A353991A81344DC 43: 43661187956D3F8D 44: 5190FDFB904A78F0 45: EF651E67F65CCD57 46: 5E539C61748BDE3D 47: E11E23BA8BEBA42E 48: BAEF0956173B32AD 49: 0AAB29DF65861F4C Cipher: anubis Key Size: 16 bytes 0: 30FF064629BF7EF5B010830BF3D4E1E9 1: DD7A8E87CFD352AF9F63EA24ADA7E353 2: 0D0BE8F05510EBD6A3EC842E5BD9FC2A 3: 330F09581FDC897B3FE6EC1A5056A410 4: 30349D965F43C295B9484C389C4D942C 5: 9225343F0056BC355060C0282C638D02 6: E3A85D41B5337533C4D87730948A9D4E 7: 09DA0DDB65FF431081CAB08A28010B76 8: 6C0D0BD6CEAFB9783B31023FD455DAC6 9: FBE6F26B7CA322A45312856D586DE2EE 10: 1F269EC072D0FBA72E87CA77F8B983FB 11: CFFAE9ADE3006BD511ED172D42F16D05 12: 73F0E9DE89F4C7541506F052D181BAC2 13: FCFA3E2E89FF769834295C77431EF7CE 14: 0452360383D56F827C81263F6B0855BC 15: 40744E07299D6A2A210BE5598835221B 16: 2F0FC61148C36F4C7B42DF274AD0DDE0 17: 2EA0E9BE9E4E4DF85488FE6E7CFCD6E3 18: 0AD1254FA64C3996BBD485D41A3687A0 19: 5B55988652DF200348A114F802FD3C03 20: C32906AF76934C1436CA60BAD58A0C66 21: 59D87987DE9DD485C4537F3A95A164A0 22: 0A706ADF488D84632C96F4BEC43D9FA8 23: 0B74E0CDD14D984B37491E2D9FA63CAE 24: 47CB1827D151A60473E67BD5D233102F 25: F455B4B665D3D0AFB25FDE4A3312AFF6 26: F9A0649421D45DF604206854F681DBDB 27: 21477F5546339E4B6D8215368EE9F884 28: 577640F23CA73345701B0906DFABA4B7 29: 89F8D08A6E173759020DD7301E0FE361 30: 44EF7AF7043FD4B8112345CEE42BC969 31: D7CF0CE04A57253F4C63CABC4A5CB034 32: AF73D3F4CED32593B315E27079131D22 33: F6E603E3455359FE43A3B83AAF3AF0C5 34: DCC3FB557F2C301B631DEF499097E4FD 35: 8285A25CF6F7E701644708E12081C62C 36: EC702DD0293F4C646B1C9C2606762816 37: 289491E5A65DCA605B78E88DA8A9F8AB 38: D82FBC14452BE34C5840DAD81FC2A65E 39: B88A340EB1BF8D5ADE6A4E6C16104FC8 40: C9FC3D70D2BA26C4059BD3D34134264C 41: 18CE3D2920E3BDEFA91C369E9DE57BF4 42: 50917AE58278E15A18A47B284D8027A3 43: BDA6F9DE33704302CE056412143B4F82 44: C287898C1451774675EB7A964C004E0D 45: 3BDE73E0D357319AB06D3675F1D3E28D 46: 30FF4326C89C0FFE4D31D2E92CC0BF9B 47: F69816F304ED892232F220F290320A8D 48: 1368153F1A54EFF8D61F93A2D6AF21E3 49: 06DD274894B6EDF3159A1403F47F09C7 Key Size: 28 bytes 0: 7828B1997D3D050201DC6EE45C8521B5 1: 0D77F896F9CEF16DAAFCF962C2257AAE 2: 89C27B0623F5EECCA38BAE1AD86AE156 3: 44EC09834052009CC3CD66E1BA11AF01 4: F922BFDB03FB186A069C1E7B48222E3D 5: 277F7971955D8984AAECF287C32B8211 6: E77ED0144A3ED827B71453B91562FE25 7: 1760EFD04477AE527BC37F72C8BBBCAE 8: 26259425ACD58207AE328B3F1A217AC1 9: 0876C4DC51D22657C4121E9067C2C3BA 10: 0214981592C9CEDD4D654F84AF1793A5 11: 3E11FA027BC4F15048D27B187062259A 12: 24E7D61BB21EA90B5282B43AAFB0DBDC 13: 688F56ECB45B7C242000653460F04A23 14: DFA587501A875ACDE8687A04AE404861 15: 4C21CC3FBB768CC9AF2242FA206FE406 16: 5CA0B03FA7751DEBBE70CB21AA61765A 17: 4879B3AC26270C422645B9CA29CAD8BB 18: 24F941E1B9AF84C18D03885EAACE16E3 19: 05E163A0150123C2664131A81B20AFC1 20: D606CAA85362E23598E5B8BD60C60506 21: 33BD0AE751019BB751C151AE47BD5811 22: 75DA523F5F793F90034144A3599DC5E6 23: CD4709B56521EA306F5AD95CCA878183 24: 6A4EC2EDDEBBBFEB62C1F13F7A59BF20 25: 2A36272DC4EFDFC03F4DCF049ED2ADFF 26: FD4F3904E8E37E7C31508E5829482965 27: BA64BAE1C2ABB8599A31B245DBAD1153 28: 757E0151783A50FC92AE55861DCD797D 29: 5E63BDA3217ECB544972CA14A9074DA5 30: E52F1195921767FA2410BA095EA5C328 31: 6D7E42D67E329D669299B5A590017E8D 32: 0516F6F7D99ADE5DC42E635BB5832E80 33: 57FB4E6B82ED2A3091248DCEF9C27F14 34: 25231D0E9B96534977D2F2AF93DD10AB 35: 847C4C524A586568D19EFA3ECA343F1C 36: 52448814064E0F33A4EA89368C2E1ACC 37: 461275466FAA7BC16ABAD9EC459BD67A 38: 16C8324A383A00DA06DBEC419B69C551 39: 5F26F7CF715FF2649DCC3C71EB6B92DF 40: 575363411FB07C067CD4357A1CD1D695 41: AB70F08BAB51C5F57139A107EE858A12 42: 887F62AE3D700EC5323EDA231C6B4C48 43: 7B9851B01DC9083293F3B226690A54F4 44: 36E03DF51C574E35EF2077DB7A49548E 45: E238A564246B163F97EDD733A235EDEB 46: 30679CE080915DC3BFA91D0DAFF5E82E 47: 7C2E8145D803D4FE18EE32995AAC16B0 48: 24D6F61ECC87206804885D33BFA7B2CA 49: 1F4F81751CB3FAFDC9F9C27E639F370B Key Size: 40 bytes 0: 31C3221C218E4CA1762B0DE77B964528 1: 0B6E4BD937773597647FFE0A3859BB12 2: 67A116E5F762619DE72F99AD1562A943 3: B6A841663FB466ACAF89C8DA5BA080F0 4: 0442708BF804642B9B1C69F5D905817E 5: BC77391EAB530B96CA35319E510DB306 6: AED37991A50AECB70C1B99137D5B38F2 7: 8735F7AF0BF6C5C7E3C98021E83A31EE 8: A614243B1B871D80BDCE4A23AD00F9FA 9: 16AC67B139A92AD777871C990D3DA571 10: B1774A2A12A8CAB25D28A575B67CEF5D 11: 4C9B1A120BC6A33C62AF903FEEC3AF5F 12: 7B128F00480E497C5754EE333457EE5E 13: AB56D578229492B95ED309C0EC566658 14: 42FAF577855FEDB3446D40B4B6677445 15: 84E0C19B4A4512001F663E22D3184F0A 16: 8B01680D049F5A9421BA9BED100CC272 17: 2B1D70B92A5DF12CE0FA6A7AA43E4CEE 18: C7F61340D1B2321A1884E54D74576657 19: 153C07C56B32530866722C4DEAC86A50 20: 2EACBEFC4A29D1250EEAFD12A1D4AE77 21: FCCB40B0997E47512295066F1A0344DD 22: C149A543345E2A1B8249F71CB9F903A4 23: 3FD0688A8D0BE5F06F157C234C29BF9A 24: 6A3F813F396D77C7F4641ECC3E0BF3AA 25: E2888B9D2A6D819367F61C5792866A8F 26: 1A8A000F91AF4E600DDD88E098BD938B 27: 2283E758C04548EF8C37FA9F5700A7AD 28: 4FD6D8E1678D2B85520B96C038C582BF 29: D13C0B228F792EF88F09ED192C571029 30: 1A2A06B1987BE0DADA4B558AE5E6A128 31: 097B0460C47F1801986F5706A69EB01C 32: DD17BAC0737515C6386ECA6A6D6C02B6 33: 5989BD1D46FD6EC14D4C55D5D6D17F99 34: 431002E0224BD34B0B93988356C19E7C 35: 37DB7570296DCCE45ABDDE36EBE4731D 36: 4731DE78EEBAA1D02568EEEA2E04A2F5 37: 1F879753A7964AF44C84FD5765D8E080 38: 54F120726F68EA4B0501365CD2A84759 39: 366E43BB744C615999E896D01A0D1D0E 40: 18747BD79F1D0529D09CAC70F4D08948 41: 4F9854BAE0834A0C5FD12381225958F2 42: 7C14ADF94A0B61828996D902E4CCFF3E 43: 242F0E9CE96E4E208A9E0C5D76F8E698 44: 27EE179E2A9301B521B2C94ED3D36A77 45: 892C84A5E77E88A67F5F00F3597F4C04 46: FC7880D7860E90DE17E935700FC8C030 47: BC49373F775BF9CD6BDC22C87F71E192 48: 365646D0DE092AF42EC8F12A19840342 49: 62D0E9C210A20ECD2FF191AD3495DE6F Cipher: khazad Key Size: 16 bytes 0: 9C4C292A989175FC 1: F49E366AF89BD6B7 2: 9E859C8F323666F9 3: 349EC57A02451059 4: 59E34CF03134A662 5: 436C16BAB80E3E2D 6: 81C35012B08A194C 7: 056CCC9991C1F087 8: 0A59F24C4715B303 9: 3C2CFF98AE8500FD 10: 9136C3FCC332D974 11: FA3FA726E6BEBA65 12: DD84E4F9F39FB7EE 13: A3F397CC9FB771F5 14: E2D6ECC1F40A51C7 15: 6704A1A705163A02 16: BD820F5AF7DEEB04 17: E21E37CC122027FF 18: E319085D8E2C1F4F 19: 0DDFE55B199A49A9 20: B70F39CCCB2BA9A6 21: 3F2F25723AED2E29 22: 751FACD5F517AB2F 23: D32CE55FBF217CE9 24: 91393018EA847012 25: D50F1C54BABE7081 26: C73350FBC5B3A82B 27: E9A054F709FD5C57 28: 94BD5121B25746D4 29: EE19F88B28BEB4B7 30: CE6845FD13A3B78A 31: 566729D0183496BC 32: DC0E1D38CB5E03A8 33: 251AD2B2842C75E3 34: D344AC41190F3594 35: 579B956A36ADA3A8 36: 5F83D3AFEE9A6F25 37: 2D3FF8708A03C600 38: 32A732C7BEEBB693 39: F437276FAA05BB39 40: 58DDD4CD0281C5FD 41: ECC2C84BD8C0A4DC 42: BAB24C2CEFE23531 43: 5244BFA3E2821E7D 44: A4B273E960946B2C 45: 039376D02A8D6788 46: D3EB7074E3B05206 47: 89C18FFA26ED0836 48: 1F05A2D2D78927D9 49: 0133E1745856C44C libtomcrypt-1.17/makefile.icc0000644000175100001440000003464210621351501014771 0ustar tomusers# MAKEFILE for linux ICC (Intel C compiler) # # Tested with ICC v8.... # # Be aware that ICC isn't quite as stable as GCC and several optimization switches # seem to break the code (that GCC and MSVC compile just fine). In particular # "-ip" and "-x*" seem to break the code (ROL/ROR macro problems). As the makefile # is shipped the code will build and execute properly. # # Also note that ICC often makes code that is slower than GCC. This is probably due to # a mix of not being able to use "-ip" and just having fewer optimization algos than GCC. # # Tom St Denis # Compiler and Linker Names CC=icc #LD=ld # Archiver [makes .a files] #AR=ar #ARFLAGS=r # Compilation flags. Note the += does not write over the user's CFLAGS! CFLAGS += -c -Isrc/headers/ -Itestprof/ -DINTEL_CC -DLTC_SOURCE #ICC v9 doesn't support LTC_FAST for things like Pelican MAC #Despite the fact I can't see what's wrong with my code #Oh well CFLAGS += -DLTC_NO_FAST #The default rule for make builds the libtomcrypt library. default:library # optimize for SPEED # # -mcpu= can be pentium, pentiumpro (covers PII through PIII) or pentium4 # -ax? specifies make code specifically for ? but compatible with IA-32 # -x? specifies compile solely for ? [not specifically IA-32 compatible] # # where ? is # K - PIII # W - first P4 [Williamette] # N - P4 Northwood # P - P4 Prescott # B - Blend of P4 and PM [mobile] # # Default to just generic max opts ifdef LTC_SMALL CFLAGS += -O2 -xP -ip endif ifndef IGNORE_SPEED CFLAGS += -O3 -xP -ip endif # want to see stuff? #CFLAGS += -opt_report #These flags control how the library gets built. #Output filenames for various targets. ifndef LIBNAME LIBNAME=libtomcrypt.a endif ifndef LIBTEST LIBTEST=libtomcrypt_prof.a LIBTEST_S=$(LIBTEST) endif HASH=hashsum CRYPT=encrypt SMALL=small PROF=x86_prof TV=tv_gen MULTI=multi TIMING=timing TEST=test #LIBPATH-The directory for libtomcrypt to be installed to. #INCPATH-The directory to install the header files for libtomcrypt. #DATAPATH-The directory to install the pdf docs. ifndef DESTDIR DESTDIR= endif ifndef LIBPATH LIBPATH=/usr/lib endif ifndef INCPATH INCPATH=/usr/include endif ifndef DATAPATH DATAPATH=/usr/share/doc/libtomcrypt/pdf endif #List of objects to compile. #START_INS OBJECTS=src/ciphers/aes/aes_enc.o src/ciphers/aes/aes.o src/ciphers/anubis.o src/ciphers/blowfish.o \ src/ciphers/cast5.o src/ciphers/des.o src/ciphers/kasumi.o src/ciphers/khazad.o src/ciphers/kseed.o \ src/ciphers/multi2.o src/ciphers/noekeon.o src/ciphers/rc2.o src/ciphers/rc5.o src/ciphers/rc6.o \ src/ciphers/safer/safer.o src/ciphers/safer/saferp.o src/ciphers/safer/safer_tab.o \ src/ciphers/skipjack.o src/ciphers/twofish/twofish.o src/ciphers/xtea.o src/encauth/ccm/ccm_memory.o \ src/encauth/ccm/ccm_test.o src/encauth/eax/eax_addheader.o src/encauth/eax/eax_decrypt.o \ src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o \ src/encauth/eax/eax_encrypt_authenticate_memory.o src/encauth/eax/eax_encrypt.o \ src/encauth/eax/eax_init.o src/encauth/eax/eax_test.o src/encauth/gcm/gcm_add_aad.o \ src/encauth/gcm/gcm_add_iv.o src/encauth/gcm/gcm_done.o src/encauth/gcm/gcm_gf_mult.o \ src/encauth/gcm/gcm_init.o src/encauth/gcm/gcm_memory.o src/encauth/gcm/gcm_mult_h.o \ src/encauth/gcm/gcm_process.o src/encauth/gcm/gcm_reset.o src/encauth/gcm/gcm_test.o \ src/encauth/ocb/ocb_decrypt.o src/encauth/ocb/ocb_decrypt_verify_memory.o \ src/encauth/ocb/ocb_done_decrypt.o src/encauth/ocb/ocb_done_encrypt.o \ src/encauth/ocb/ocb_encrypt_authenticate_memory.o src/encauth/ocb/ocb_encrypt.o \ src/encauth/ocb/ocb_init.o src/encauth/ocb/ocb_ntz.o src/encauth/ocb/ocb_shift_xor.o \ src/encauth/ocb/ocb_test.o src/encauth/ocb/s_ocb_done.o src/hashes/chc/chc.o \ src/hashes/helper/hash_file.o src/hashes/helper/hash_filehandle.o src/hashes/helper/hash_memory.o \ src/hashes/helper/hash_memory_multi.o src/hashes/md2.o src/hashes/md4.o src/hashes/md5.o \ src/hashes/rmd128.o src/hashes/rmd160.o src/hashes/rmd256.o src/hashes/rmd320.o src/hashes/sha1.o \ src/hashes/sha2/sha256.o src/hashes/sha2/sha512.o src/hashes/tiger.o src/hashes/whirl/whirl.o \ src/mac/f9/f9_done.o src/mac/f9/f9_file.o src/mac/f9/f9_init.o src/mac/f9/f9_memory.o \ src/mac/f9/f9_memory_multi.o src/mac/f9/f9_process.o src/mac/f9/f9_test.o src/mac/hmac/hmac_done.o \ src/mac/hmac/hmac_file.o src/mac/hmac/hmac_init.o src/mac/hmac/hmac_memory.o \ src/mac/hmac/hmac_memory_multi.o src/mac/hmac/hmac_process.o src/mac/hmac/hmac_test.o \ src/mac/omac/omac_done.o src/mac/omac/omac_file.o src/mac/omac/omac_init.o src/mac/omac/omac_memory.o \ src/mac/omac/omac_memory_multi.o src/mac/omac/omac_process.o src/mac/omac/omac_test.o \ src/mac/pelican/pelican.o src/mac/pelican/pelican_memory.o src/mac/pelican/pelican_test.o \ src/mac/pmac/pmac_done.o src/mac/pmac/pmac_file.o src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \ src/mac/pmac/pmac_memory_multi.o src/mac/pmac/pmac_ntz.o src/mac/pmac/pmac_process.o \ src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/mac/xcbc/xcbc_done.o \ src/mac/xcbc/xcbc_file.o src/mac/xcbc/xcbc_init.o src/mac/xcbc/xcbc_memory.o \ src/mac/xcbc/xcbc_memory_multi.o src/mac/xcbc/xcbc_process.o src/mac/xcbc/xcbc_test.o \ src/math/fp/ltc_ecc_fp_mulmod.o src/math/gmp_desc.o src/math/ltm_desc.o src/math/multi.o \ src/math/rand_prime.o src/math/tfm_desc.o src/misc/base64/base64_decode.o \ src/misc/base64/base64_encode.o src/misc/burn_stack.o src/misc/crypt/crypt_argchk.o \ src/misc/crypt/crypt.o src/misc/crypt/crypt_cipher_descriptor.o src/misc/crypt/crypt_cipher_is_valid.o \ src/misc/crypt/crypt_find_cipher_any.o src/misc/crypt/crypt_find_cipher.o \ src/misc/crypt/crypt_find_cipher_id.o src/misc/crypt/crypt_find_hash_any.o \ src/misc/crypt/crypt_find_hash.o src/misc/crypt/crypt_find_hash_id.o \ src/misc/crypt/crypt_find_hash_oid.o src/misc/crypt/crypt_find_prng.o src/misc/crypt/crypt_fsa.o \ src/misc/crypt/crypt_hash_descriptor.o src/misc/crypt/crypt_hash_is_valid.o \ src/misc/crypt/crypt_ltc_mp_descriptor.o src/misc/crypt/crypt_prng_descriptor.o \ src/misc/crypt/crypt_prng_is_valid.o src/misc/crypt/crypt_register_cipher.o \ src/misc/crypt/crypt_register_hash.o src/misc/crypt/crypt_register_prng.o \ src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o \ src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/pkcs5/pkcs_5_1.o \ src/misc/pkcs5/pkcs_5_2.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o \ src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o src/modes/cbc/cbc_setiv.o \ src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o src/modes/cfb/cfb_done.o \ src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o \ src/modes/cfb/cfb_start.o src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_done.o \ src/modes/ctr/ctr_encrypt.o src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o \ src/modes/ctr/ctr_start.o src/modes/ctr/ctr_test.o src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o \ src/modes/ecb/ecb_encrypt.o src/modes/ecb/ecb_start.o src/modes/f8/f8_decrypt.o src/modes/f8/f8_done.o \ src/modes/f8/f8_encrypt.o src/modes/f8/f8_getiv.o src/modes/f8/f8_setiv.o src/modes/f8/f8_start.o \ src/modes/f8/f8_test_mode.o src/modes/lrw/lrw_decrypt.o src/modes/lrw/lrw_done.o \ src/modes/lrw/lrw_encrypt.o src/modes/lrw/lrw_getiv.o src/modes/lrw/lrw_process.o \ src/modes/lrw/lrw_setiv.o src/modes/lrw/lrw_start.o src/modes/lrw/lrw_test.o \ src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o src/modes/ofb/ofb_encrypt.o \ src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o src/modes/ofb/ofb_start.o \ src/modes/xts/xts_decrypt.o src/modes/xts/xts_done.o src/modes/xts/xts_encrypt.o \ src/modes/xts/xts_init.o src/modes/xts/xts_mult_x.o src/modes/xts/xts_test.o \ src/pk/asn1/der/bit/der_decode_bit_string.o src/pk/asn1/der/bit/der_encode_bit_string.o \ src/pk/asn1/der/bit/der_length_bit_string.o src/pk/asn1/der/boolean/der_decode_boolean.o \ src/pk/asn1/der/boolean/der_encode_boolean.o src/pk/asn1/der/boolean/der_length_boolean.o \ src/pk/asn1/der/choice/der_decode_choice.o src/pk/asn1/der/ia5/der_decode_ia5_string.o \ src/pk/asn1/der/ia5/der_encode_ia5_string.o src/pk/asn1/der/ia5/der_length_ia5_string.o \ src/pk/asn1/der/integer/der_decode_integer.o src/pk/asn1/der/integer/der_encode_integer.o \ src/pk/asn1/der/integer/der_length_integer.o \ src/pk/asn1/der/object_identifier/der_decode_object_identifier.o \ src/pk/asn1/der/object_identifier/der_encode_object_identifier.o \ src/pk/asn1/der/object_identifier/der_length_object_identifier.o \ src/pk/asn1/der/octet/der_decode_octet_string.o src/pk/asn1/der/octet/der_encode_octet_string.o \ src/pk/asn1/der/octet/der_length_octet_string.o \ src/pk/asn1/der/printable_string/der_decode_printable_string.o \ src/pk/asn1/der/printable_string/der_encode_printable_string.o \ src/pk/asn1/der/printable_string/der_length_printable_string.o \ src/pk/asn1/der/sequence/der_decode_sequence_ex.o \ src/pk/asn1/der/sequence/der_decode_sequence_flexi.o \ src/pk/asn1/der/sequence/der_decode_sequence_multi.o \ src/pk/asn1/der/sequence/der_encode_sequence_ex.o \ src/pk/asn1/der/sequence/der_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \ src/pk/asn1/der/sequence/der_sequence_free.o src/pk/asn1/der/set/der_encode_set.o \ src/pk/asn1/der/set/der_encode_setof.o src/pk/asn1/der/short_integer/der_decode_short_integer.o \ src/pk/asn1/der/short_integer/der_encode_short_integer.o \ src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \ src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \ src/pk/asn1/der/utf8/der_decode_utf8_string.o src/pk/asn1/der/utf8/der_encode_utf8_string.o \ src/pk/asn1/der/utf8/der_length_utf8_string.o src/pk/dsa/dsa_decrypt_key.o \ src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o \ src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_shared_secret.o src/pk/dsa/dsa_sign_hash.o \ src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc_ansi_x963_export.o \ src/pk/ecc/ecc_ansi_x963_import.o src/pk/ecc/ecc.o src/pk/ecc/ecc_decrypt_key.o \ src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_free.o src/pk/ecc/ecc_get_size.o \ src/pk/ecc/ecc_import.o src/pk/ecc/ecc_make_key.o src/pk/ecc/ecc_shared_secret.o \ src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_test.o src/pk/ecc/ecc_verify_hash.o \ src/pk/ecc/ltc_ecc_is_valid_idx.o src/pk/ecc/ltc_ecc_map.o src/pk/ecc/ltc_ecc_mul2add.o \ src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \ src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \ src/pk/katja/katja_decrypt_key.o src/pk/katja/katja_encrypt_key.o src/pk/katja/katja_export.o \ src/pk/katja/katja_exptmod.o src/pk/katja/katja_free.o src/pk/katja/katja_import.o \ src/pk/katja/katja_make_key.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \ src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \ src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v1_5_decode.o \ src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \ src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \ src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o \ src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \ src/prngs/sprng.o src/prngs/yarrow.o HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \ src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \ src/headers/tomcrypt_pk.h src/headers/tomcrypt_hash.h src/headers/tomcrypt_math.h \ src/headers/tomcrypt_misc.h src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h \ src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h #END_INS #Who do we install as? ifdef INSTALL_USER USER=$(INSTALL_USER) else USER=root endif ifdef INSTALL_GROUP GROUP=$(INSTALL_GROUP) else GROUP=wheel endif #ciphers come in two flavours... enc+dec and enc aes_enc.o: aes.c aes_tab.c $(CC) $(CFLAGS) -DENCRYPT_ONLY -c aes.c -o aes_enc.o HASHOBJECTS=demos/hashsum.o CRYPTOBJECTS=demos/encrypt.o SMALLOBJECTS=demos/small.o TVS=demos/tv_gen.o TIMINGS=demos/timing.o TESTS=demos/test.o #ciphers come in two flavours... enc+dec and enc src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c $(CC) $(CFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes.c -o src/ciphers/aes/aes_enc.o #These are the rules to make certain object files. src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c #This rule makes the libtomcrypt library. library: $(LIBNAME) testprof/$(LIBTEST): cd testprof ; LIBTEST_S=$(LIBTEST) CFLAGS="$(CFLAGS)" make -f makefile.icc $(LIBNAME): $(OBJECTS) $(AR) $(ARFLAGS) $@ $(OBJECTS) ranlib $@ #This rule makes the hash program included with libtomcrypt hashsum: library $(HASHOBJECTS) $(CC) $(HASHOBJECTS) $(LIBNAME) $(EXTRALIBS) -o $(HASH) $(WARN) #makes the crypt program crypt: library $(CRYPTOBJECTS) $(CC) $(CRYPTOBJECTS) $(LIBNAME) $(EXTRALIBS) -o $(CRYPT) $(WARN) #makes the small program small: library $(SMALLOBJECTS) $(CC) $(SMALLOBJECTS) $(LIBNAME) $(EXTRALIBS) -o $(SMALL) $(WARN) tv_gen: library $(TVS) $(CC) $(TVS) $(LIBNAME) $(EXTRALIBS) -o $(TV) timing: library $(TIMINGS) testprof/$(LIBTEST) $(CC) $(TIMINGS) testprof/$(LIBTEST) $(LIBNAME) $(EXTRALIBS) -o $(TIMING) test: library $(TESTS) testprof/$(LIBTEST) $(CC) $(TESTS) testprof/$(LIBTEST) $(LIBNAME) $(EXTRALIBS) -o $(TEST) #This rule installs the library and the header files. This must be run #as root in order to have a high enough permission to write to the correct #directories and to set the owner and group to root. install: library install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH) install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) install -g $(GROUP) -o $(USER) $(LIBNAME) $(DESTDIR)$(LIBPATH) install -g $(GROUP) -o $(USER) $(LIBTEST) $(DESTDIR)$(LIBPATH) install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH) # $Source: /cvs/libtom/libtomcrypt/makefile.icc,v $ # $Revision: 1.76 $ # $Date: 2007/02/16 16:36:25 $ libtomcrypt-1.17/README0000644000175100001440000000002410621351501013377 0ustar tomusersSee doc/crypt.pdf libtomcrypt-1.17/filter.pl0000644000175100001440000000100510621351501014341 0ustar tomusers#!/usr/bin/perl # we want to filter every between START_INS and END_INS out and then insert crap from another file (this is fun) $dst = shift; $ins = shift; open(SRC,"<$dst"); open(INS,"<$ins"); open(TMP,">tmp.delme"); $l = 0; while () { if ($_ =~ /START_INS/) { print TMP $_; $l = 1; while () { print TMP $_; } close INS; } elsif ($_ =~ /END_INS/) { print TMP $_; $l = 0; } elsif ($l == 0) { print TMP $_; } } close TMP; close SRC; libtomcrypt-1.17/fixupind.pl0000644000175100001440000000033210621351501014704 0ustar tomusersopen(IN,"crypt.ind.tmp"); $a = ; print OUT "$a\n\\addcontentsline{toc}{chapter}{Index}\n"; while () { print OUT $_; } close OUT; close IN; system("mv -f crypt.ind.tmp crypt.ind"); libtomcrypt-1.17/testprof/0000755000175100001440000000000010621351501014371 5ustar tomuserslibtomcrypt-1.17/testprof/makefile.shared0000644000175100001440000000127310621351501017341 0ustar tomusersCC=libtool --mode=compile gcc CFLAGS += -I../src/headers -I./ -Wall -W # ranlib tools ifndef RANLIB RANLIB=ranlib endif OBJECTS = base64_test.o cipher_hash_test.o der_tests.o \ dsa_test.o ecc_test.o mac_test.o modes_test.o pkcs_1_test.o rsa_test.o \ store_test.o test_driver.o x86_prof.o katja_test.o ifndef LIBTEST LIBTEST=libtomcrypt_prof.la endif default: $(LIBTEST) $(LIBTEST): $(OBJECTS) libtool --silent --mode=link gcc $(CFLAGS) `find . -type f | grep "[.]lo" | xargs` -o $@ -rpath $(LIBPATH) -version-info $(VERSION) install: $(LIBTEST) libtool --silent --mode=install install -c $(LIBTEST) $(DESTDIR)$(LIBPATH)/$(LIBTEST) libtomcrypt-1.17/testprof/makefile.icc0000644000175100001440000000070010621351501016623 0ustar tomusersCFLAGS += -I../src/headers -I./ CC=icc OBJECTS = base64_test.o cipher_hash_test.o der_tests.o \ dsa_test.o ecc_test.o mac_test.o modes_test.o pkcs_1_test.o rsa_test.o \ store_test.o test_driver.o x86_prof.o katja_test.o ifndef LIBTEST_S LIBTEST_S = libtomcrypt_prof.a endif default: $(LIBTEST_S) $(LIBTEST_S): $(OBJECTS) $(AR) $(ARFLAGS) $@ $(OBJECTS) ranlib $@ clean: rm -f *.o *.a libtomcrypt-1.17/testprof/modes_test.c0000644000175100001440000000524410621351501016710 0ustar tomusers/* test CFB/OFB/CBC modes */ #include int modes_test(void) { unsigned char pt[64], ct[64], tmp[64], key[16], iv[16], iv2[16]; int cipher_idx; #ifdef LTC_CBC_MODE symmetric_CBC cbc; #endif #ifdef LTC_CFB_MODE symmetric_CFB cfb; #endif #ifdef LTC_OFB_MODE symmetric_OFB ofb; #endif unsigned long l; /* make a random pt, key and iv */ yarrow_read(pt, 64, &yarrow_prng); yarrow_read(key, 16, &yarrow_prng); yarrow_read(iv, 16, &yarrow_prng); /* get idx of AES handy */ cipher_idx = find_cipher("aes"); if (cipher_idx == -1) { fprintf(stderr, "test requires AES"); return 1; } #ifdef LTC_F8_MODE DO(f8_test_mode()); #endif #ifdef LTC_LRW_MODE DO(lrw_test()); #endif #ifdef LTC_CBC_MODE /* test CBC mode */ /* encode the block */ DO(cbc_start(cipher_idx, iv, key, 16, 0, &cbc)); l = sizeof(iv2); DO(cbc_getiv(iv2, &l, &cbc)); if (l != 16 || memcmp(iv2, iv, 16)) { fprintf(stderr, "cbc_getiv failed"); return 1; } DO(cbc_encrypt(pt, ct, 64, &cbc)); /* decode the block */ DO(cbc_setiv(iv2, l, &cbc)); zeromem(tmp, sizeof(tmp)); DO(cbc_decrypt(ct, tmp, 64, &cbc)); if (memcmp(tmp, pt, 64) != 0) { fprintf(stderr, "CBC failed"); return 1; } #endif #ifdef LTC_CFB_MODE /* test CFB mode */ /* encode the block */ DO(cfb_start(cipher_idx, iv, key, 16, 0, &cfb)); l = sizeof(iv2); DO(cfb_getiv(iv2, &l, &cfb)); /* note we don't memcmp iv2/iv since cfb_start processes the IV for the first block */ if (l != 16) { fprintf(stderr, "cfb_getiv failed"); return 1; } DO(cfb_encrypt(pt, ct, 64, &cfb)); /* decode the block */ DO(cfb_setiv(iv, l, &cfb)); zeromem(tmp, sizeof(tmp)); DO(cfb_decrypt(ct, tmp, 64, &cfb)); if (memcmp(tmp, pt, 64) != 0) { fprintf(stderr, "CFB failed"); return 1; } #endif #ifdef LTC_OFB_MODE /* test OFB mode */ /* encode the block */ DO(ofb_start(cipher_idx, iv, key, 16, 0, &ofb)); l = sizeof(iv2); DO(ofb_getiv(iv2, &l, &ofb)); if (l != 16 || memcmp(iv2, iv, 16)) { fprintf(stderr, "ofb_getiv failed"); return 1; } DO(ofb_encrypt(pt, ct, 64, &ofb)); /* decode the block */ DO(ofb_setiv(iv2, l, &ofb)); zeromem(tmp, sizeof(tmp)); DO(ofb_decrypt(ct, tmp, 64, &ofb)); if (memcmp(tmp, pt, 64) != 0) { fprintf(stderr, "OFB failed"); return 1; } #endif #ifdef LTC_CTR_MODE DO(ctr_test()); #endif #ifdef LTC_XTS_MODE DO(xts_test()); #endif return 0; } /* $Source: /cvs/libtom/libtomcrypt/testprof/modes_test.c,v $ */ /* $Revision: 1.15 $ */ /* $Date: 2007/02/16 16:36:25 $ */ libtomcrypt-1.17/testprof/test.der0000644000175100001440000000024210621351501016042 0ustar tomusers00  *H 0Ϛd3 ׃1Tu3$}-e?r$(hOD>`& ^Ԉ8I*n[7GkAh|aBȀ6Ov clIX̪%; `?T:M1甤Dlibtomcrypt-1.17/testprof/test.key0000644000175100001440000000157310621351501016070 0ustar tomusers-----BEGIN RSA PRIVATE KEY----- MIICXgIBAAKBgQDPmt5kitrIMyCp14MxGVSymoWnobd1M7aprIQks97bfYUtlmXl P3KVJJ8oaMpP20QcPmASit0mpev/C17UiDhJKm5bvxI3R70Fa7zb8+7kEY5BaHxh E9dCyIC+No/cCItPrKTidgzJY2xJWJPtzKrcJTsKYD+LVDrDTTHnlKRE/QIDAQAB AoGBAMhiuereRFMdVpfZl54azzAeCohFhikwo02fYWVz4NaHj7bzBqOC3Hys/pso mq79+/4vDtiXBOO7H9HsDbqjSX9HrIpEBH6GtzlCP60etw6lUfRAYx79veqfQZ+o kB1vClqVExENgK9fZJiKLHhoZbAri6JTh8rxZASr8nvbg8iBAkEA975eI8MyP7+L jjru/PzL5ffxC7xCgq7Vej7K99VpP2Qloh+3dXUFkkLruPHzCgXjlNFVeDWgNqCb fJKEbN3cTQJBANaGDoVCCwQIhCFg8A4NiP0eNhBlTx5TtAhygFw/WWYX5pjy6Wx6 Bkysdj3tjKHOrRu9tH0ovOMOOI2Z2AW1o3ECQG3rwy0u8F6kiDEFKQCK0ZUpm4PP ddsx43on3jp0MAx2TNRQKkAtOdmZY6ldgK5TypQ/BSMe+AUE4bg18hezoIkCQQCr kIj6YAgpUJpDi6BQzNha/pdkY3F0IqMgAlrP68YWlVTRy6uNGsYA+giSnHHVUlI1 lnFLi5IM0Om/rWMLpemxAkEA3MwnyOTcYkjVm6/1q2D2If1T4rddCckaoQSp/GEs XQRYOlo58UohVmf9zCCjj3gYWnk9Lo5+hgrmqDPBBBdKnw== -----END RSA PRIVATE KEY----- libtomcrypt-1.17/testprof/makefile0000644000175100001440000000076710621351501016103 0ustar tomusersCFLAGS += -I../src/headers -I./ -Wall -W # ranlib tools ifndef RANLIB RANLIB=ranlib endif OBJECTS = base64_test.o cipher_hash_test.o der_tests.o \ dsa_test.o ecc_test.o mac_test.o modes_test.o pkcs_1_test.o rsa_test.o \ store_test.o test_driver.o x86_prof.o katja_test.o ifndef LIBTEST_S LIBTEST_S=libtomcrypt_prof.a endif default: $(LIBTEST_S) $(LIBTEST_S): $(OBJECTS) $(AR) $(ARFLAGS) $@ $(OBJECTS) $(RANLIB) $@ clean: rm -f *.o *.a libtomcrypt-1.17/testprof/dsa_test.c0000644000175100001440000000423410621351501016346 0ustar tomusers#include #ifdef LTC_MDSA int dsa_test(void) { unsigned char msg[16], out[1024], out2[1024]; unsigned long x, y; int stat1, stat2; dsa_key key, key2; /* make a random key */ DO(dsa_make_key(&yarrow_prng, find_prng("yarrow"), 20, 128, &key)); /* verify it */ DO(dsa_verify_key(&key, &stat1)); if (stat1 == 0) { fprintf(stderr, "dsa_verify_key "); return 1; } /* encrypt a message */ for (x = 0; x < 16; x++) { msg[x] = x; } x = sizeof(out); DO(dsa_encrypt_key(msg, 16, out, &x, &yarrow_prng, find_prng("yarrow"), find_hash("sha1"), &key)); /* decrypt */ y = sizeof(out2); DO(dsa_decrypt_key(out, x, out2, &y, &key)); if (y != 16 || memcmp(out2, msg, 16)) { fprintf(stderr, "dsa_decrypt failed, y == %lu\n", y); return 1; } /* sign the message */ x = sizeof(out); DO(dsa_sign_hash(msg, sizeof(msg), out, &x, &yarrow_prng, find_prng("yarrow"), &key)); /* verify it once */ DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key)); /* Modify and verify again */ msg[0] ^= 1; DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat2, &key)); msg[0] ^= 1; if (!(stat1 == 1 && stat2 == 0)) { fprintf(stderr, "dsa_verify %d %d", stat1, stat2); return 1; } /* test exporting it */ x = sizeof(out2); DO(dsa_export(out2, &x, PK_PRIVATE, &key)); DO(dsa_import(out2, x, &key2)); /* verify a signature with it */ DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key2)); if (stat1 == 0) { fprintf(stderr, "dsa_verify (import private) %d ", stat1); return 1; } dsa_free(&key2); /* export as public now */ x = sizeof(out2); DO(dsa_export(out2, &x, PK_PUBLIC, &key)); DO(dsa_import(out2, x, &key2)); /* verify a signature with it */ DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key2)); if (stat1 == 0) { fprintf(stderr, "dsa_verify (import public) %d ", stat1); return 1; } dsa_free(&key2); dsa_free(&key); return 0; } #else int dsa_test(void) { fprintf(stderr, "NOP"); return 0; } #endif /* $Source: /cvs/libtom/libtomcrypt/testprof/dsa_test.c,v $ */ /* $Revision: 1.10 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/testprof/test_driver.c0000644000175100001440000000062010621351501017065 0ustar tomusers#include void run_cmd(int res, int line, char *file, char *cmd) { if (res != CRYPT_OK) { fprintf(stderr, "%s (%d)\n%s:%d:%s\n", error_to_string(res), res, file, line, cmd); if (res != CRYPT_NOP) { exit(EXIT_FAILURE); } } } /* $Source: /cvs/libtom/libtomcrypt/testprof/test_driver.c,v $ */ /* $Revision: 1.2 $ */ /* $Date: 2006/11/13 23:14:33 $ */ libtomcrypt-1.17/testprof/mac_test.c0000644000175100001440000000123410621351501016334 0ustar tomusers/* test pmac/omac/hmac */ #include int mac_test(void) { #ifdef LTC_HMAC DO(hmac_test()); #endif #ifdef LTC_PMAC DO(pmac_test()); #endif #ifdef LTC_OMAC DO(omac_test()); #endif #ifdef LTC_XCBC DO(xcbc_test()); #endif #ifdef LTC_F9_MODE DO(f9_test()); #endif #ifdef LTC_EAX_MODE DO(eax_test()); #endif #ifdef LTC_OCB_MODE DO(ocb_test()); #endif #ifdef LTC_CCM_MODE DO(ccm_test()); #endif #ifdef LTC_GCM_MODE DO(gcm_test()); #endif #ifdef LTC_PELICAN DO(pelican_test()); #endif return 0; } /* $Source: /cvs/libtom/libtomcrypt/testprof/mac_test.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/testprof/x86_prof.c0000644000175100001440000011447110621351501016220 0ustar tomusers#include prng_state yarrow_prng; struct list results[100]; int no_results; int sorter(const void *a, const void *b) { const struct list *A, *B; A = a; B = b; if (A->avg < B->avg) return -1; if (A->avg > B->avg) return 1; return 0; } void tally_results(int type) { int x; /* qsort the results */ qsort(results, no_results, sizeof(struct list), &sorter); fprintf(stderr, "\n"); if (type == 0) { for (x = 0; x < no_results; x++) { fprintf(stderr, "%-20s: Schedule at %6lu\n", cipher_descriptor[results[x].id].name, (unsigned long)results[x].spd1); } } else if (type == 1) { for (x = 0; x < no_results; x++) { printf ("%-20s[%3d]: Encrypt at %5lu, Decrypt at %5lu\n", cipher_descriptor[results[x].id].name, cipher_descriptor[results[x].id].ID, results[x].spd1, results[x].spd2); } } else { for (x = 0; x < no_results; x++) { printf ("%-20s: Process at %5lu\n", hash_descriptor[results[x].id].name, results[x].spd1 / 1000); } } } /* RDTSC from Scott Duplichan */ ulong64 rdtsc (void) { #if defined __GNUC__ && !defined(LTC_NO_ASM) #ifdef INTEL_CC ulong64 a; asm ( " rdtsc ":"=A"(a)); return a; #elif defined(__i386__) || defined(__x86_64__) ulong64 a; asm __volatile__ ("rdtsc\nmovl %%eax,(%0)\nmovl %%edx,4(%0)\n"::"r"(&a):"%eax","%edx"); return a; #elif defined(LTC_PPC32) || defined(TFM_PPC32) unsigned long a, b; __asm__ __volatile__ ("mftbu %1 \nmftb %0\n":"=r"(a), "=r"(b)); return (((ulong64)b) << 32ULL) | ((ulong64)a); #elif defined(__ia64__) /* gcc-IA64 version */ unsigned long result; __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory"); while (__builtin_expect ((int) result == -1, 0)) __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory"); return result; #elif defined(__sparc__) #if defined(__arch64__) ulong64 a; asm volatile("rd %%tick,%0" : "=r" (a)); return a; #else register unsigned long x, y; __asm__ __volatile__ ("rd %%tick, %0; clruw %0, %1; srlx %0, 32, %0" : "=r" (x), "=r" (y) : "0" (x), "1" (y)); return ((unsigned long long) x << 32) | y; #endif #else return XCLOCK(); #endif /* Microsoft and Intel Windows compilers */ #elif defined _M_IX86 && !defined(LTC_NO_ASM) __asm rdtsc #elif defined _M_AMD64 && !defined(LTC_NO_ASM) return __rdtsc (); #elif defined _M_IA64 && !defined(LTC_NO_ASM) #if defined __INTEL_COMPILER #include #endif return __getReg (3116); #else return XCLOCK(); #endif } static ulong64 timer, skew = 0; void t_start(void) { timer = rdtsc(); } ulong64 t_read(void) { return rdtsc() - timer; } void init_timer(void) { ulong64 c1, c2, t1, t2, t3; unsigned long y1; c1 = c2 = (ulong64)-1; for (y1 = 0; y1 < TIMES*100; y1++) { t_start(); t1 = t_read(); t3 = t_read(); t2 = (t_read() - t1)>>1; c1 = (t1 > c1) ? t1 : c1; c2 = (t2 > c2) ? t2 : c2; } skew = c2 - c1; fprintf(stderr, "Clock Skew: %lu\n", (unsigned long)skew); } void reg_algs(void) { int err; #ifdef LTC_RIJNDAEL register_cipher (&aes_desc); #endif #ifdef LTC_BLOWFISH register_cipher (&blowfish_desc); #endif #ifdef LTC_XTEA register_cipher (&xtea_desc); #endif #ifdef LTC_RC5 register_cipher (&rc5_desc); #endif #ifdef LTC_RC6 register_cipher (&rc6_desc); #endif #ifdef LTC_SAFERP register_cipher (&saferp_desc); #endif #ifdef LTC_TWOFISH register_cipher (&twofish_desc); #endif #ifdef LTC_SAFER register_cipher (&safer_k64_desc); register_cipher (&safer_sk64_desc); register_cipher (&safer_k128_desc); register_cipher (&safer_sk128_desc); #endif #ifdef LTC_RC2 register_cipher (&rc2_desc); #endif #ifdef LTC_DES register_cipher (&des_desc); register_cipher (&des3_desc); #endif #ifdef LTC_CAST5 register_cipher (&cast5_desc); #endif #ifdef LTC_NOEKEON register_cipher (&noekeon_desc); #endif #ifdef LTC_SKIPJACK register_cipher (&skipjack_desc); #endif #ifdef LTC_KHAZAD register_cipher (&khazad_desc); #endif #ifdef LTC_ANUBIS register_cipher (&anubis_desc); #endif #ifdef LTC_KSEED register_cipher (&kseed_desc); #endif #ifdef LTC_KASUMI register_cipher (&kasumi_desc); #endif #ifdef LTC_MULTI2 register_cipher (&multi2_desc); #endif #ifdef LTC_TIGER register_hash (&tiger_desc); #endif #ifdef LTC_MD2 register_hash (&md2_desc); #endif #ifdef LTC_MD4 register_hash (&md4_desc); #endif #ifdef LTC_MD5 register_hash (&md5_desc); #endif #ifdef LTC_SHA1 register_hash (&sha1_desc); #endif #ifdef LTC_SHA224 register_hash (&sha224_desc); #endif #ifdef LTC_SHA256 register_hash (&sha256_desc); #endif #ifdef LTC_SHA384 register_hash (&sha384_desc); #endif #ifdef LTC_SHA512 register_hash (&sha512_desc); #endif #ifdef LTC_RIPEMD128 register_hash (&rmd128_desc); #endif #ifdef LTC_RIPEMD160 register_hash (&rmd160_desc); #endif #ifdef LTC_RIPEMD256 register_hash (&rmd256_desc); #endif #ifdef LTC_RIPEMD320 register_hash (&rmd320_desc); #endif #ifdef LTC_WHIRLPOOL register_hash (&whirlpool_desc); #endif #ifdef LTC_CHC_HASH register_hash(&chc_desc); if ((err = chc_register(register_cipher(&aes_desc))) != CRYPT_OK) { fprintf(stderr, "chc_register error: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } #endif #ifndef LTC_YARROW #error This demo requires Yarrow. #endif register_prng(&yarrow_desc); #ifdef LTC_FORTUNA register_prng(&fortuna_desc); #endif #ifdef LTC_RC4 register_prng(&rc4_desc); #endif #ifdef LTC_SOBER128 register_prng(&sober128_desc); #endif if ((err = rng_make_prng(128, find_prng("yarrow"), &yarrow_prng, NULL)) != CRYPT_OK) { fprintf(stderr, "rng_make_prng failed: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } } int time_keysched(void) { unsigned long x, y1; ulong64 t1, c1; symmetric_key skey; int kl; int (*func) (const unsigned char *, int , int , symmetric_key *); unsigned char key[MAXBLOCKSIZE]; fprintf(stderr, "\n\nKey Schedule Time Trials for the Symmetric Ciphers:\n(Times are cycles per key)\n"); no_results = 0; for (x = 0; cipher_descriptor[x].name != NULL; x++) { #define DO1(k) func(k, kl, 0, &skey); func = cipher_descriptor[x].setup; kl = cipher_descriptor[x].min_key_length; c1 = (ulong64)-1; for (y1 = 0; y1 < KTIMES; y1++) { yarrow_read(key, kl, &yarrow_prng); t_start(); DO1(key); t1 = t_read(); c1 = (t1 > c1) ? c1 : t1; } t1 = c1 - skew; results[no_results].spd1 = results[no_results].avg = t1; results[no_results++].id = x; fprintf(stderr, "."); fflush(stdout); #undef DO1 } tally_results(0); return 0; } int time_cipher(void) { unsigned long x, y1; ulong64 t1, t2, c1, c2, a1, a2; symmetric_ECB ecb; unsigned char key[MAXBLOCKSIZE], pt[4096]; int err; fprintf(stderr, "\n\nECB Time Trials for the Symmetric Ciphers:\n"); no_results = 0; for (x = 0; cipher_descriptor[x].name != NULL; x++) { ecb_start(x, key, cipher_descriptor[x].min_key_length, 0, &ecb); /* sanity check on cipher */ if ((err = cipher_descriptor[x].test()) != CRYPT_OK) { fprintf(stderr, "\n\nERROR: Cipher %s failed self-test %s\n", cipher_descriptor[x].name, error_to_string(err)); exit(EXIT_FAILURE); } #define DO1 ecb_encrypt(pt, pt, sizeof(pt), &ecb); #define DO2 DO1 DO1 c1 = c2 = (ulong64)-1; for (y1 = 0; y1 < 100; y1++) { t_start(); DO1; t1 = t_read(); DO2; t2 = t_read(); t2 -= t1; c1 = (t1 > c1 ? c1 : t1); c2 = (t2 > c2 ? c2 : t2); } a1 = c2 - c1 - skew; #undef DO1 #undef DO2 #define DO1 ecb_decrypt(pt, pt, sizeof(pt), &ecb); #define DO2 DO1 DO1 c1 = c2 = (ulong64)-1; for (y1 = 0; y1 < 100; y1++) { t_start(); DO1; t1 = t_read(); DO2; t2 = t_read(); t2 -= t1; c1 = (t1 > c1 ? c1 : t1); c2 = (t2 > c2 ? c2 : t2); } a2 = c2 - c1 - skew; ecb_done(&ecb); results[no_results].id = x; results[no_results].spd1 = a1/(sizeof(pt)/cipher_descriptor[x].block_length); results[no_results].spd2 = a2/(sizeof(pt)/cipher_descriptor[x].block_length); results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2; ++no_results; fprintf(stderr, "."); fflush(stdout); #undef DO2 #undef DO1 } tally_results(1); return 0; } #ifdef LTC_CBC_MODE int time_cipher2(void) { unsigned long x, y1; ulong64 t1, t2, c1, c2, a1, a2; symmetric_CBC cbc; unsigned char key[MAXBLOCKSIZE], pt[4096]; int err; fprintf(stderr, "\n\nCBC Time Trials for the Symmetric Ciphers:\n"); no_results = 0; for (x = 0; cipher_descriptor[x].name != NULL; x++) { cbc_start(x, pt, key, cipher_descriptor[x].min_key_length, 0, &cbc); /* sanity check on cipher */ if ((err = cipher_descriptor[x].test()) != CRYPT_OK) { fprintf(stderr, "\n\nERROR: Cipher %s failed self-test %s\n", cipher_descriptor[x].name, error_to_string(err)); exit(EXIT_FAILURE); } #define DO1 cbc_encrypt(pt, pt, sizeof(pt), &cbc); #define DO2 DO1 DO1 c1 = c2 = (ulong64)-1; for (y1 = 0; y1 < 100; y1++) { t_start(); DO1; t1 = t_read(); DO2; t2 = t_read(); t2 -= t1; c1 = (t1 > c1 ? c1 : t1); c2 = (t2 > c2 ? c2 : t2); } a1 = c2 - c1 - skew; #undef DO1 #undef DO2 #define DO1 cbc_decrypt(pt, pt, sizeof(pt), &cbc); #define DO2 DO1 DO1 c1 = c2 = (ulong64)-1; for (y1 = 0; y1 < 100; y1++) { t_start(); DO1; t1 = t_read(); DO2; t2 = t_read(); t2 -= t1; c1 = (t1 > c1 ? c1 : t1); c2 = (t2 > c2 ? c2 : t2); } a2 = c2 - c1 - skew; cbc_done(&cbc); results[no_results].id = x; results[no_results].spd1 = a1/(sizeof(pt)/cipher_descriptor[x].block_length); results[no_results].spd2 = a2/(sizeof(pt)/cipher_descriptor[x].block_length); results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2; ++no_results; fprintf(stderr, "."); fflush(stdout); #undef DO2 #undef DO1 } tally_results(1); return 0; } #else int time_cipher2(void) { fprintf(stderr, "NO CBC\n"); return 0; } #endif #ifdef LTC_CTR_MODE int time_cipher3(void) { unsigned long x, y1; ulong64 t1, t2, c1, c2, a1, a2; symmetric_CTR ctr; unsigned char key[MAXBLOCKSIZE], pt[4096]; int err; fprintf(stderr, "\n\nCTR Time Trials for the Symmetric Ciphers:\n"); no_results = 0; for (x = 0; cipher_descriptor[x].name != NULL; x++) { ctr_start(x, pt, key, cipher_descriptor[x].min_key_length, 0, CTR_COUNTER_LITTLE_ENDIAN, &ctr); /* sanity check on cipher */ if ((err = cipher_descriptor[x].test()) != CRYPT_OK) { fprintf(stderr, "\n\nERROR: Cipher %s failed self-test %s\n", cipher_descriptor[x].name, error_to_string(err)); exit(EXIT_FAILURE); } #define DO1 ctr_encrypt(pt, pt, sizeof(pt), &ctr); #define DO2 DO1 DO1 c1 = c2 = (ulong64)-1; for (y1 = 0; y1 < 100; y1++) { t_start(); DO1; t1 = t_read(); DO2; t2 = t_read(); t2 -= t1; c1 = (t1 > c1 ? c1 : t1); c2 = (t2 > c2 ? c2 : t2); } a1 = c2 - c1 - skew; #undef DO1 #undef DO2 #define DO1 ctr_decrypt(pt, pt, sizeof(pt), &ctr); #define DO2 DO1 DO1 c1 = c2 = (ulong64)-1; for (y1 = 0; y1 < 100; y1++) { t_start(); DO1; t1 = t_read(); DO2; t2 = t_read(); t2 -= t1; c1 = (t1 > c1 ? c1 : t1); c2 = (t2 > c2 ? c2 : t2); } a2 = c2 - c1 - skew; ctr_done(&ctr); results[no_results].id = x; results[no_results].spd1 = a1/(sizeof(pt)/cipher_descriptor[x].block_length); results[no_results].spd2 = a2/(sizeof(pt)/cipher_descriptor[x].block_length); results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2; ++no_results; fprintf(stderr, "."); fflush(stdout); #undef DO2 #undef DO1 } tally_results(1); return 0; } #else int time_cipher3(void) { fprintf(stderr, "NO CTR\n"); return 0; } #endif #ifdef LTC_LRW_MODE int time_cipher4(void) { unsigned long x, y1; ulong64 t1, t2, c1, c2, a1, a2; symmetric_LRW lrw; unsigned char key[MAXBLOCKSIZE], pt[4096]; int err; fprintf(stderr, "\n\nLRW Time Trials for the Symmetric Ciphers:\n"); no_results = 0; for (x = 0; cipher_descriptor[x].name != NULL; x++) { if (cipher_descriptor[x].block_length != 16) continue; lrw_start(x, pt, key, cipher_descriptor[x].min_key_length, key, 0, &lrw); /* sanity check on cipher */ if ((err = cipher_descriptor[x].test()) != CRYPT_OK) { fprintf(stderr, "\n\nERROR: Cipher %s failed self-test %s\n", cipher_descriptor[x].name, error_to_string(err)); exit(EXIT_FAILURE); } #define DO1 lrw_encrypt(pt, pt, sizeof(pt), &lrw); #define DO2 DO1 DO1 c1 = c2 = (ulong64)-1; for (y1 = 0; y1 < 100; y1++) { t_start(); DO1; t1 = t_read(); DO2; t2 = t_read(); t2 -= t1; c1 = (t1 > c1 ? c1 : t1); c2 = (t2 > c2 ? c2 : t2); } a1 = c2 - c1 - skew; #undef DO1 #undef DO2 #define DO1 lrw_decrypt(pt, pt, sizeof(pt), &lrw); #define DO2 DO1 DO1 c1 = c2 = (ulong64)-1; for (y1 = 0; y1 < 100; y1++) { t_start(); DO1; t1 = t_read(); DO2; t2 = t_read(); t2 -= t1; c1 = (t1 > c1 ? c1 : t1); c2 = (t2 > c2 ? c2 : t2); } a2 = c2 - c1 - skew; lrw_done(&lrw); results[no_results].id = x; results[no_results].spd1 = a1/(sizeof(pt)/cipher_descriptor[x].block_length); results[no_results].spd2 = a2/(sizeof(pt)/cipher_descriptor[x].block_length); results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2; ++no_results; fprintf(stderr, "."); fflush(stdout); #undef DO2 #undef DO1 } tally_results(1); return 0; } #else int time_cipher4(void) { fprintf(stderr, "NO LRW\n"); return 0; } #endif int time_hash(void) { unsigned long x, y1, len; ulong64 t1, t2, c1, c2; hash_state md; int (*func)(hash_state *, const unsigned char *, unsigned long), err; unsigned char pt[MAXBLOCKSIZE]; fprintf(stderr, "\n\nHASH Time Trials for:\n"); no_results = 0; for (x = 0; hash_descriptor[x].name != NULL; x++) { /* sanity check on hash */ if ((err = hash_descriptor[x].test()) != CRYPT_OK) { fprintf(stderr, "\n\nERROR: Hash %s failed self-test %s\n", hash_descriptor[x].name, error_to_string(err)); exit(EXIT_FAILURE); } hash_descriptor[x].init(&md); #define DO1 func(&md,pt,len); #define DO2 DO1 DO1 func = hash_descriptor[x].process; len = hash_descriptor[x].blocksize; c1 = c2 = (ulong64)-1; for (y1 = 0; y1 < TIMES; y1++) { t_start(); DO1; t1 = t_read(); DO2; t2 = t_read() - t1; c1 = (t1 > c1) ? c1 : t1; c2 = (t2 > c2) ? c2 : t2; } t1 = c2 - c1 - skew; t1 = ((t1 * CONST64(1000))) / ((ulong64)hash_descriptor[x].blocksize); results[no_results].id = x; results[no_results].spd1 = results[no_results].avg = t1; ++no_results; fprintf(stderr, "."); fflush(stdout); #undef DO2 #undef DO1 } tally_results(2); return 0; } #undef MPI /*#warning you need an mp_rand!!!*/ #ifdef MPI void time_mult(void) { ulong64 t1, t2; unsigned long x, y; void *a, *b, *c; fprintf(stderr, "Timing Multiplying:\n"); mp_init_multi(&a,&b,&c,NULL); for (x = 128/DIGIT_BIT; x <= 1536/DIGIT_BIT; x += 128/DIGIT_BIT) { mp_rand(&a, x); mp_rand(&b, x); #define DO1 mp_mul(&a, &b, &c); #define DO2 DO1; DO1; t2 = -1; for (y = 0; y < TIMES; y++) { t_start(); t1 = t_read(); DO2; t1 = (t_read() - t1)>>1; if (t1 < t2) t2 = t1; } fprintf(stderr, "%4lu bits: %9llu cycles\n", x*DIGIT_BIT, t2); } mp_clear_multi(&a,&b,&c,NULL); #undef DO1 #undef DO2 } void time_sqr(void) { ulong64 t1, t2; unsigned long x, y; mp_int a, b; fprintf(stderr, "Timing Squaring:\n"); mp_init_multi(&a,&b,NULL); for (x = 128/DIGIT_BIT; x <= 1536/DIGIT_BIT; x += 128/DIGIT_BIT) { mp_rand(&a, x); #define DO1 mp_sqr(&a, &b); #define DO2 DO1; DO1; t2 = -1; for (y = 0; y < TIMES; y++) { t_start(); t1 = t_read(); DO2; t1 = (t_read() - t1)>>1; if (t1 < t2) t2 = t1; } fprintf(stderr, "%4lu bits: %9llu cycles\n", x*DIGIT_BIT, t2); } mp_clear_multi(&a,&b,NULL); #undef DO1 #undef DO2 } #else void time_mult(void) { fprintf(stderr, "NO MULT\n"); } void time_sqr(void) { fprintf(stderr, "NO SQR\n"); } #endif void time_prng(void) { ulong64 t1, t2; unsigned char buf[4096]; prng_state tprng; unsigned long x, y; int err; fprintf(stderr, "Timing PRNGs (cycles/byte output, cycles add_entropy (32 bytes) :\n"); for (x = 0; prng_descriptor[x].name != NULL; x++) { /* sanity check on prng */ if ((err = prng_descriptor[x].test()) != CRYPT_OK) { fprintf(stderr, "\n\nERROR: PRNG %s failed self-test %s\n", prng_descriptor[x].name, error_to_string(err)); exit(EXIT_FAILURE); } prng_descriptor[x].start(&tprng); zeromem(buf, 256); prng_descriptor[x].add_entropy(buf, 256, &tprng); prng_descriptor[x].ready(&tprng); t2 = -1; #define DO1 if (prng_descriptor[x].read(buf, 4096, &tprng) != 4096) { fprintf(stderr, "\n\nERROR READ != 4096\n\n"); exit(EXIT_FAILURE); } #define DO2 DO1 DO1 for (y = 0; y < 10000; y++) { t_start(); t1 = t_read(); DO2; t1 = (t_read() - t1)>>1; if (t1 < t2) t2 = t1; } fprintf(stderr, "%20s: %5llu ", prng_descriptor[x].name, t2>>12); #undef DO2 #undef DO1 #define DO1 prng_descriptor[x].start(&tprng); prng_descriptor[x].add_entropy(buf, 32, &tprng); prng_descriptor[x].ready(&tprng); prng_descriptor[x].done(&tprng); #define DO2 DO1 DO1 for (y = 0; y < 10000; y++) { t_start(); t1 = t_read(); DO2; t1 = (t_read() - t1)>>1; if (t1 < t2) t2 = t1; } fprintf(stderr, "%5llu\n", t2); #undef DO2 #undef DO1 } } #ifdef LTC_MDSA /* time various DSA operations */ void time_dsa(void) { dsa_key key; ulong64 t1, t2; unsigned long x, y; int err; static const struct { int group, modulus; } groups[] = { { 20, 96 }, { 20, 128 }, { 24, 192 }, { 28, 256 }, { 32, 512 } }; for (x = 0; x < (sizeof(groups)/sizeof(groups[0])); x++) { t2 = 0; for (y = 0; y < 4; y++) { t_start(); t1 = t_read(); if ((err = dsa_make_key(&yarrow_prng, find_prng("yarrow"), groups[x].group, groups[x].modulus, &key)) != CRYPT_OK) { fprintf(stderr, "\n\ndsa_make_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); } t1 = t_read() - t1; t2 += t1; #ifdef LTC_PROFILE t2 <<= 2; break; #endif if (y < 3) { dsa_free(&key); } } t2 >>= 2; fprintf(stderr, "DSA-(%lu, %lu) make_key took %15llu cycles\n", (unsigned long)groups[x].group*8, (unsigned long)groups[x].modulus*8, t2); } } #endif #ifdef LTC_MRSA /* time various RSA operations */ void time_rsa(void) { rsa_key key; ulong64 t1, t2; unsigned char buf[2][2048]; unsigned long x, y, z, zzz; int err, zz, stat; for (x = 1024; x <= 2048; x += 256) { t2 = 0; for (y = 0; y < 4; y++) { t_start(); t1 = t_read(); if ((err = rsa_make_key(&yarrow_prng, find_prng("yarrow"), x/8, 65537, &key)) != CRYPT_OK) { fprintf(stderr, "\n\nrsa_make_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); } t1 = t_read() - t1; t2 += t1; #ifdef LTC_PROFILE t2 <<= 2; break; #endif if (y < 3) { rsa_free(&key); } } t2 >>= 2; fprintf(stderr, "RSA-%lu make_key took %15llu cycles\n", x, t2); t2 = 0; for (y = 0; y < 16; y++) { t_start(); t1 = t_read(); z = sizeof(buf[1]); if ((err = rsa_encrypt_key(buf[0], 32, buf[1], &z, (const unsigned char *)"testprog", 8, &yarrow_prng, find_prng("yarrow"), find_hash("sha1"), &key)) != CRYPT_OK) { fprintf(stderr, "\n\nrsa_encrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); } t1 = t_read() - t1; t2 += t1; #ifdef LTC_PROFILE t2 <<= 4; break; #endif } t2 >>= 4; fprintf(stderr, "RSA-%lu encrypt_key took %15llu cycles\n", x, t2); t2 = 0; for (y = 0; y < 2048; y++) { t_start(); t1 = t_read(); zzz = sizeof(buf[0]); if ((err = rsa_decrypt_key(buf[1], z, buf[0], &zzz, (const unsigned char *)"testprog", 8, find_hash("sha1"), &zz, &key)) != CRYPT_OK) { fprintf(stderr, "\n\nrsa_decrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); } t1 = t_read() - t1; t2 += t1; #ifdef LTC_PROFILE t2 <<= 11; break; #endif } t2 >>= 11; fprintf(stderr, "RSA-%lu decrypt_key took %15llu cycles\n", x, t2); t2 = 0; for (y = 0; y < 256; y++) { t_start(); t1 = t_read(); z = sizeof(buf[1]); if ((err = rsa_sign_hash(buf[0], 20, buf[1], &z, &yarrow_prng, find_prng("yarrow"), find_hash("sha1"), 8, &key)) != CRYPT_OK) { fprintf(stderr, "\n\nrsa_sign_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); } t1 = t_read() - t1; t2 += t1; #ifdef LTC_PROFILE t2 <<= 8; break; #endif } t2 >>= 8; fprintf(stderr, "RSA-%lu sign_hash took %15llu cycles\n", x, t2); t2 = 0; for (y = 0; y < 2048; y++) { t_start(); t1 = t_read(); if ((err = rsa_verify_hash(buf[1], z, buf[0], 20, find_hash("sha1"), 8, &stat, &key)) != CRYPT_OK) { fprintf(stderr, "\n\nrsa_verify_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); } if (stat == 0) { fprintf(stderr, "\n\nrsa_verify_hash for RSA-%lu failed to verify signature(%lu)\n", x, y); exit(EXIT_FAILURE); } t1 = t_read() - t1; t2 += t1; #ifdef LTC_PROFILE t2 <<= 11; break; #endif } t2 >>= 11; fprintf(stderr, "RSA-%lu verify_hash took %15llu cycles\n", x, t2); fprintf(stderr, "\n\n"); rsa_free(&key); } } #else void time_rsa(void) { fprintf(stderr, "NO RSA\n"); } #endif #ifdef MKAT /* time various KAT operations */ void time_katja(void) { katja_key key; ulong64 t1, t2; unsigned char buf[2][4096]; unsigned long x, y, z, zzz; int err, zz; for (x = 1024; x <= 2048; x += 256) { t2 = 0; for (y = 0; y < 4; y++) { t_start(); t1 = t_read(); if ((err = katja_make_key(&yarrow_prng, find_prng("yarrow"), x/8, &key)) != CRYPT_OK) { fprintf(stderr, "\n\nkatja_make_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); } t1 = t_read() - t1; t2 += t1; if (y < 3) { katja_free(&key); } } t2 >>= 2; fprintf(stderr, "Katja-%lu make_key took %15llu cycles\n", x, t2); t2 = 0; for (y = 0; y < 16; y++) { t_start(); t1 = t_read(); z = sizeof(buf[1]); if ((err = katja_encrypt_key(buf[0], 32, buf[1], &z, "testprog", 8, &yarrow_prng, find_prng("yarrow"), find_hash("sha1"), &key)) != CRYPT_OK) { fprintf(stderr, "\n\nkatja_encrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); } t1 = t_read() - t1; t2 += t1; } t2 >>= 4; fprintf(stderr, "Katja-%lu encrypt_key took %15llu cycles\n", x, t2); t2 = 0; for (y = 0; y < 2048; y++) { t_start(); t1 = t_read(); zzz = sizeof(buf[0]); if ((err = katja_decrypt_key(buf[1], z, buf[0], &zzz, "testprog", 8, find_hash("sha1"), &zz, &key)) != CRYPT_OK) { fprintf(stderr, "\n\nkatja_decrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); } t1 = t_read() - t1; t2 += t1; } t2 >>= 11; fprintf(stderr, "Katja-%lu decrypt_key took %15llu cycles\n", x, t2); katja_free(&key); } } #else void time_katja(void) { fprintf(stderr, "NO Katja\n"); } #endif #ifdef LTC_MECC /* time various ECC operations */ void time_ecc(void) { ecc_key key; ulong64 t1, t2; unsigned char buf[2][256]; unsigned long i, w, x, y, z; int err, stat; static unsigned long sizes[] = { #ifdef ECC112 112/8, #endif #ifdef ECC128 128/8, #endif #ifdef ECC160 160/8, #endif #ifdef ECC192 192/8, #endif #ifdef ECC224 224/8, #endif #ifdef ECC256 256/8, #endif #ifdef ECC384 384/8, #endif #ifdef ECC521 521/8, #endif 100000}; for (x = sizes[i=0]; x < 100000; x = sizes[++i]) { t2 = 0; for (y = 0; y < 256; y++) { t_start(); t1 = t_read(); if ((err = ecc_make_key(&yarrow_prng, find_prng("yarrow"), x, &key)) != CRYPT_OK) { fprintf(stderr, "\n\necc_make_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); } t1 = t_read() - t1; t2 += t1; #ifdef LTC_PROFILE t2 <<= 8; break; #endif if (y < 255) { ecc_free(&key); } } t2 >>= 8; fprintf(stderr, "ECC-%lu make_key took %15llu cycles\n", x*8, t2); t2 = 0; for (y = 0; y < 256; y++) { t_start(); t1 = t_read(); z = sizeof(buf[1]); if ((err = ecc_encrypt_key(buf[0], 20, buf[1], &z, &yarrow_prng, find_prng("yarrow"), find_hash("sha1"), &key)) != CRYPT_OK) { fprintf(stderr, "\n\necc_encrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); } t1 = t_read() - t1; t2 += t1; #ifdef LTC_PROFILE t2 <<= 8; break; #endif } t2 >>= 8; fprintf(stderr, "ECC-%lu encrypt_key took %15llu cycles\n", x*8, t2); t2 = 0; for (y = 0; y < 256; y++) { t_start(); t1 = t_read(); w = 20; if ((err = ecc_decrypt_key(buf[1], z, buf[0], &w, &key)) != CRYPT_OK) { fprintf(stderr, "\n\necc_decrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); } t1 = t_read() - t1; t2 += t1; #ifdef LTC_PROFILE t2 <<= 8; break; #endif } t2 >>= 8; fprintf(stderr, "ECC-%lu decrypt_key took %15llu cycles\n", x*8, t2); t2 = 0; for (y = 0; y < 256; y++) { t_start(); t1 = t_read(); z = sizeof(buf[1]); if ((err = ecc_sign_hash(buf[0], 20, buf[1], &z, &yarrow_prng, find_prng("yarrow"), &key)) != CRYPT_OK) { fprintf(stderr, "\n\necc_sign_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); } t1 = t_read() - t1; t2 += t1; #ifdef LTC_PROFILE t2 <<= 8; break; #endif } t2 >>= 8; fprintf(stderr, "ECC-%lu sign_hash took %15llu cycles\n", x*8, t2); t2 = 0; for (y = 0; y < 256; y++) { t_start(); t1 = t_read(); if ((err = ecc_verify_hash(buf[1], z, buf[0], 20, &stat, &key)) != CRYPT_OK) { fprintf(stderr, "\n\necc_verify_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK)); exit(EXIT_FAILURE); } if (stat == 0) { fprintf(stderr, "\n\necc_verify_hash for ECC-%lu failed to verify signature(%lu)\n", x*8, y); exit(EXIT_FAILURE); } t1 = t_read() - t1; t2 += t1; #ifdef LTC_PROFILE t2 <<= 8; break; #endif } t2 >>= 8; fprintf(stderr, "ECC-%lu verify_hash took %15llu cycles\n", x*8, t2); fprintf(stderr, "\n\n"); ecc_free(&key); } } #else void time_ecc(void) { fprintf(stderr, "NO ECC\n"); } #endif void time_macs_(unsigned long MAC_SIZE) { unsigned char *buf, key[16], tag[16]; ulong64 t1, t2; unsigned long x, z; int err, cipher_idx, hash_idx; fprintf(stderr, "\nMAC Timings (cycles/byte on %luKB blocks):\n", MAC_SIZE); buf = XMALLOC(MAC_SIZE*1024); if (buf == NULL) { fprintf(stderr, "\n\nout of heap yo\n\n"); exit(EXIT_FAILURE); } cipher_idx = find_cipher("aes"); hash_idx = find_hash("sha1"); if (cipher_idx == -1 || hash_idx == -1) { fprintf(stderr, "Warning the MAC tests requires AES and LTC_SHA1 to operate... so sorry\n"); return; } yarrow_read(buf, MAC_SIZE*1024, &yarrow_prng); yarrow_read(key, 16, &yarrow_prng); #ifdef LTC_OMAC t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; if ((err = omac_memory(cipher_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) { fprintf(stderr, "\n\nomac error... %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } fprintf(stderr, "LTC_OMAC-%s\t\t%9llu\n", cipher_descriptor[cipher_idx].name, t2/(ulong64)(MAC_SIZE*1024)); #endif #ifdef LTC_XCBC t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; if ((err = xcbc_memory(cipher_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) { fprintf(stderr, "\n\nxcbc error... %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } fprintf(stderr, "XCBC-%s\t\t%9llu\n", cipher_descriptor[cipher_idx].name, t2/(ulong64)(MAC_SIZE*1024)); #endif #ifdef LTC_F9_MODE t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; if ((err = f9_memory(cipher_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) { fprintf(stderr, "\n\nF9 error... %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } fprintf(stderr, "F9-%s\t\t\t%9llu\n", cipher_descriptor[cipher_idx].name, t2/(ulong64)(MAC_SIZE*1024)); #endif #ifdef LTC_PMAC t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; if ((err = pmac_memory(cipher_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) { fprintf(stderr, "\n\npmac error... %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } fprintf(stderr, "PMAC-AES\t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024)); #endif #ifdef LTC_PELICAN t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; if ((err = pelican_memory(key, 16, buf, MAC_SIZE*1024, tag)) != CRYPT_OK) { fprintf(stderr, "\n\npelican error... %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } fprintf(stderr, "LTC_PELICAN \t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024)); #endif #ifdef LTC_HMAC t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; if ((err = hmac_memory(hash_idx, key, 16, buf, MAC_SIZE*1024, tag, &z)) != CRYPT_OK) { fprintf(stderr, "\n\nhmac error... %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } fprintf(stderr, "LTC_HMAC-%s\t\t%9llu\n", hash_descriptor[hash_idx].name, t2/(ulong64)(MAC_SIZE*1024)); #endif XFREE(buf); } void time_macs(void) { time_macs_(1); time_macs_(4); time_macs_(32); } void time_encmacs_(unsigned long MAC_SIZE) { unsigned char *buf, IV[16], key[16], tag[16]; ulong64 t1, t2; unsigned long x, z; int err, cipher_idx; symmetric_key skey; fprintf(stderr, "\nENC+MAC Timings (zero byte AAD, 16 byte IV, cycles/byte on %luKB blocks):\n", MAC_SIZE); buf = XMALLOC(MAC_SIZE*1024); if (buf == NULL) { fprintf(stderr, "\n\nout of heap yo\n\n"); exit(EXIT_FAILURE); } cipher_idx = find_cipher("aes"); yarrow_read(buf, MAC_SIZE*1024, &yarrow_prng); yarrow_read(key, 16, &yarrow_prng); yarrow_read(IV, 16, &yarrow_prng); #ifdef LTC_EAX_MODE t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; if ((err = eax_encrypt_authenticate_memory(cipher_idx, key, 16, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z)) != CRYPT_OK) { fprintf(stderr, "\nEAX error... %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } fprintf(stderr, "EAX \t\t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024)); #endif #ifdef LTC_OCB_MODE t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; if ((err = ocb_encrypt_authenticate_memory(cipher_idx, key, 16, IV, buf, MAC_SIZE*1024, buf, tag, &z)) != CRYPT_OK) { fprintf(stderr, "\nOCB error... %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } fprintf(stderr, "OCB \t\t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024)); #endif #ifdef LTC_CCM_MODE t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; if ((err = ccm_memory(cipher_idx, key, 16, NULL, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z, CCM_ENCRYPT)) != CRYPT_OK) { fprintf(stderr, "\nCCM error... %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } fprintf(stderr, "CCM (no-precomp) \t%9llu\n", t2/(ulong64)(MAC_SIZE*1024)); cipher_descriptor[cipher_idx].setup(key, 16, 0, &skey); t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; if ((err = ccm_memory(cipher_idx, key, 16, &skey, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z, CCM_ENCRYPT)) != CRYPT_OK) { fprintf(stderr, "\nCCM error... %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } fprintf(stderr, "CCM (precomp) \t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024)); cipher_descriptor[cipher_idx].done(&skey); #endif #ifdef LTC_GCM_MODE t2 = -1; for (x = 0; x < 100; x++) { t_start(); t1 = t_read(); z = 16; if ((err = gcm_memory(cipher_idx, key, 16, IV, 16, NULL, 0, buf, MAC_SIZE*1024, buf, tag, &z, GCM_ENCRYPT)) != CRYPT_OK) { fprintf(stderr, "\nGCM error... %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } fprintf(stderr, "GCM (no-precomp)\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024)); { gcm_state gcm #ifdef LTC_GCM_TABLES_SSE2 __attribute__ ((aligned (16))) #endif ; if ((err = gcm_init(&gcm, cipher_idx, key, 16)) != CRYPT_OK) { fprintf(stderr, "gcm_init: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } t2 = -1; for (x = 0; x < 10000; x++) { t_start(); t1 = t_read(); z = 16; if ((err = gcm_reset(&gcm)) != CRYPT_OK) { fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err)); exit(EXIT_FAILURE); } if ((err = gcm_add_iv(&gcm, IV, 16)) != CRYPT_OK) { fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err)); exit(EXIT_FAILURE); } if ((err = gcm_add_aad(&gcm, NULL, 0)) != CRYPT_OK) { fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err)); exit(EXIT_FAILURE); } if ((err = gcm_process(&gcm, buf, MAC_SIZE*1024, buf, GCM_ENCRYPT)) != CRYPT_OK) { fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err)); exit(EXIT_FAILURE); } if ((err = gcm_done(&gcm, tag, &z)) != CRYPT_OK) { fprintf(stderr, "\nGCM error[%d]... %s\n", __LINE__, error_to_string(err)); exit(EXIT_FAILURE); } t1 = t_read() - t1; if (t1 < t2) t2 = t1; } fprintf(stderr, "GCM (precomp)\t\t%9llu\n", t2/(ulong64)(MAC_SIZE*1024)); } #endif } void time_encmacs(void) { time_encmacs_(1); time_encmacs_(4); time_encmacs_(32); } /* $Source: /cvs/libtom/libtomcrypt/testprof/x86_prof.c,v $ */ /* $Revision: 1.58 $ */ /* $Date: 2007/05/12 14:37:41 $ */ libtomcrypt-1.17/testprof/der_tests.c0000644000175100001440000010001710621351501016530 0ustar tomusers#include #if defined(GMP_LTC_DESC) || defined(USE_GMP) #include #endif #ifndef LTC_DER int der_tests(void) { fprintf(stderr, "NOP"); return 0; } #else static void der_set_test(void) { ltc_asn1_list list[10]; static const unsigned char oct_str[] = { 1, 2, 3, 4 }; static const unsigned char bin_str[] = { 1, 0, 0, 1 }; static const unsigned long int_val = 12345678UL; unsigned char strs[10][10], outbuf[128]; unsigned long x, val, outlen; int err; /* make structure and encode it */ LTC_SET_ASN1(list, 0, LTC_ASN1_OCTET_STRING, oct_str, sizeof(oct_str)); LTC_SET_ASN1(list, 1, LTC_ASN1_BIT_STRING, bin_str, sizeof(bin_str)); LTC_SET_ASN1(list, 2, LTC_ASN1_SHORT_INTEGER, &int_val, 1); /* encode it */ outlen = sizeof(outbuf); if ((err = der_encode_set(list, 3, outbuf, &outlen)) != CRYPT_OK) { fprintf(stderr, "error encoding set: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } /* first let's test the set_decoder out of order to see what happens, we should get all the fields we expect even though they're in a diff order */ LTC_SET_ASN1(list, 0, LTC_ASN1_BIT_STRING, strs[1], sizeof(strs[1])); LTC_SET_ASN1(list, 1, LTC_ASN1_SHORT_INTEGER, &val, 1); LTC_SET_ASN1(list, 2, LTC_ASN1_OCTET_STRING, strs[0], sizeof(strs[0])); if ((err = der_decode_set(outbuf, outlen, list, 3)) != CRYPT_OK) { fprintf(stderr, "error decoding set using der_decode_set: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } /* now compare the items */ if (memcmp(strs[0], oct_str, sizeof(oct_str))) { fprintf(stderr, "error decoding set using der_decode_set (oct_str is wrong):\n"); exit(EXIT_FAILURE); } if (memcmp(strs[1], bin_str, sizeof(bin_str))) { fprintf(stderr, "error decoding set using der_decode_set (bin_str is wrong):\n"); exit(EXIT_FAILURE); } if (val != int_val) { fprintf(stderr, "error decoding set using der_decode_set (int_val is wrong):\n"); exit(EXIT_FAILURE); } strcpy((char*)strs[0], "one"); strcpy((char*)strs[1], "one2"); strcpy((char*)strs[2], "two"); strcpy((char*)strs[3], "aaa"); strcpy((char*)strs[4], "aaaa"); strcpy((char*)strs[5], "aab"); strcpy((char*)strs[6], "aaab"); strcpy((char*)strs[7], "bbb"); strcpy((char*)strs[8], "bbba"); strcpy((char*)strs[9], "bbbb"); for (x = 0; x < 10; x++) { LTC_SET_ASN1(list, x, LTC_ASN1_PRINTABLE_STRING, strs[x], strlen((char*)strs[x])); } outlen = sizeof(outbuf); if ((err = der_encode_setof(list, 10, outbuf, &outlen)) != CRYPT_OK) { fprintf(stderr, "error encoding SET OF: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } for (x = 0; x < 10; x++) { LTC_SET_ASN1(list, x, LTC_ASN1_PRINTABLE_STRING, strs[x], sizeof(strs[x]) - 1); } XMEMSET(strs, 0, sizeof(strs)); if ((err = der_decode_set(outbuf, outlen, list, 10)) != CRYPT_OK) { fprintf(stderr, "error decoding SET OF: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } /* now compare */ for (x = 1; x < 10; x++) { if (!(strlen((char*)strs[x-1]) <= strlen((char*)strs[x])) && strcmp((char*)strs[x-1], (char*)strs[x]) >= 0) { fprintf(stderr, "error SET OF order at %lu is wrong\n", x); exit(EXIT_FAILURE); } } } /* we are encoding SEQUENCE { PRINTABLE "printable" IA5 "ia5" SEQUENCE { INTEGER 12345678 UTCTIME { 91, 5, 6, 16, 45, 40, 1, 7, 0 } SEQUENCE { OCTET STRING { 1, 2, 3, 4 } BIT STRING { 1, 0, 0, 1 } SEQUENCE { OID { 1, 2, 840, 113549 } NULL SET OF { PRINTABLE "333" // WILL GET SORTED PRINTABLE "222" } } } } */ static void der_flexi_test(void) { static const char printable_str[] = "printable"; static const char set1_str[] = "333"; static const char set2_str[] = "222"; static const char ia5_str[] = "ia5"; static const unsigned long int_val = 12345678UL; static const ltc_utctime utctime = { 91, 5, 6, 16, 45, 40, 1, 7, 0 }; static const unsigned char oct_str[] = { 1, 2, 3, 4 }; static const unsigned char bit_str[] = { 1, 0, 0, 1 }; static const unsigned long oid_str[] = { 1, 2, 840, 113549 }; unsigned char encode_buf[192]; unsigned long encode_buf_len, decode_len; int err; ltc_asn1_list static_list[5][3], *decoded_list, *l; /* build list */ LTC_SET_ASN1(static_list[0], 0, LTC_ASN1_PRINTABLE_STRING, (void *)printable_str, strlen(printable_str)); LTC_SET_ASN1(static_list[0], 1, LTC_ASN1_IA5_STRING, (void *)ia5_str, strlen(ia5_str)); LTC_SET_ASN1(static_list[0], 2, LTC_ASN1_SEQUENCE, static_list[1], 3); LTC_SET_ASN1(static_list[1], 0, LTC_ASN1_SHORT_INTEGER, (void *)&int_val, 1); LTC_SET_ASN1(static_list[1], 1, LTC_ASN1_UTCTIME, (void *)&utctime, 1); LTC_SET_ASN1(static_list[1], 2, LTC_ASN1_SEQUENCE, static_list[2], 3); LTC_SET_ASN1(static_list[2], 0, LTC_ASN1_OCTET_STRING, (void *)oct_str, 4); LTC_SET_ASN1(static_list[2], 1, LTC_ASN1_BIT_STRING, (void *)bit_str, 4); LTC_SET_ASN1(static_list[2], 2, LTC_ASN1_SEQUENCE, static_list[3], 3); LTC_SET_ASN1(static_list[3], 0, LTC_ASN1_OBJECT_IDENTIFIER,(void *)oid_str, 4); LTC_SET_ASN1(static_list[3], 1, LTC_ASN1_NULL, NULL, 0); LTC_SET_ASN1(static_list[3], 2, LTC_ASN1_SETOF, static_list[4], 2); LTC_SET_ASN1(static_list[4], 0, LTC_ASN1_PRINTABLE_STRING, set1_str, strlen(set1_str)); LTC_SET_ASN1(static_list[4], 1, LTC_ASN1_PRINTABLE_STRING, set2_str, strlen(set2_str)); /* encode it */ encode_buf_len = sizeof(encode_buf); if ((err = der_encode_sequence(&static_list[0][0], 3, encode_buf, &encode_buf_len)) != CRYPT_OK) { fprintf(stderr, "Encoding static_list: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } #if 0 { FILE *f; f = fopen("t.bin", "wb"); fwrite(encode_buf, 1, encode_buf_len, f); fclose(f); } #endif /* decode with flexi */ decode_len = encode_buf_len; if ((err = der_decode_sequence_flexi(encode_buf, &decode_len, &decoded_list)) != CRYPT_OK) { fprintf(stderr, "decoding static_list: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } if (decode_len != encode_buf_len) { fprintf(stderr, "Decode len of %lu does not match encode len of %lu \n", decode_len, encode_buf_len); exit(EXIT_FAILURE); } /* we expect l->next to be NULL and l->child to not be */ l = decoded_list; if (l->next != NULL || l->child == NULL) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } /* we expect a SEQUENCE */ if (l->type != LTC_ASN1_SEQUENCE) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } l = l->child; /* PRINTABLE STRING */ /* we expect printable_str */ if (l->next == NULL || l->child != NULL) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } if (l->type != LTC_ASN1_PRINTABLE_STRING) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } if (l->size != strlen(printable_str) || memcmp(printable_str, l->data, l->size)) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } /* move to next */ l = l->next; /* IA5 STRING */ /* we expect ia5_str */ if (l->next == NULL || l->child != NULL) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } if (l->type != LTC_ASN1_IA5_STRING) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } if (l->size != strlen(ia5_str) || memcmp(ia5_str, l->data, l->size)) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } /* move to next */ l = l->next; /* expect child anve move down */ if (l->next != NULL || l->child == NULL) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } if (l->type != LTC_ASN1_SEQUENCE) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } l = l->child; /* INTEGER */ if (l->next == NULL || l->child != NULL) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } if (l->type != LTC_ASN1_INTEGER) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } if (mp_cmp_d(l->data, 12345678UL) != LTC_MP_EQ) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } /* move to next */ l = l->next; /* UTCTIME */ if (l->next == NULL || l->child != NULL) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } if (l->type != LTC_ASN1_UTCTIME) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } if (memcmp(l->data, &utctime, sizeof(utctime))) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } /* move to next */ l = l->next; /* expect child anve move down */ if (l->next != NULL || l->child == NULL) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } if (l->type != LTC_ASN1_SEQUENCE) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } l = l->child; /* OCTET STRING */ /* we expect oct_str */ if (l->next == NULL || l->child != NULL) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } if (l->type != LTC_ASN1_OCTET_STRING) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } if (l->size != sizeof(oct_str) || memcmp(oct_str, l->data, l->size)) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } /* move to next */ l = l->next; /* BIT STRING */ /* we expect oct_str */ if (l->next == NULL || l->child != NULL) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } if (l->type != LTC_ASN1_BIT_STRING) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } if (l->size != sizeof(bit_str) || memcmp(bit_str, l->data, l->size)) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } /* move to next */ l = l->next; /* expect child anve move down */ if (l->next != NULL || l->child == NULL) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } if (l->type != LTC_ASN1_SEQUENCE) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } l = l->child; /* OID STRING */ /* we expect oid_str */ if (l->next == NULL || l->child != NULL) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } if (l->type != LTC_ASN1_OBJECT_IDENTIFIER) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } if (l->size != sizeof(oid_str)/sizeof(oid_str[0]) || memcmp(oid_str, l->data, l->size*sizeof(oid_str[0]))) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } /* move to next */ l = l->next; /* NULL */ if (l->type != LTC_ASN1_NULL) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } /* move to next */ l = l->next; /* expect child anve move down */ if (l->next != NULL || l->child == NULL) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } if (l->type != LTC_ASN1_SET) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } l = l->child; /* PRINTABLE STRING */ /* we expect printable_str */ if (l->next == NULL || l->child != NULL) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } if (l->type != LTC_ASN1_PRINTABLE_STRING) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } /* note we compare set2_str FIRST because the SET OF is sorted and "222" comes before "333" */ if (l->size != strlen(set2_str) || memcmp(set2_str, l->data, l->size)) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } /* move to next */ l = l->next; /* PRINTABLE STRING */ /* we expect printable_str */ if (l->type != LTC_ASN1_PRINTABLE_STRING) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } if (l->size != strlen(set1_str) || memcmp(set1_str, l->data, l->size)) { fprintf(stderr, "(%d), %d, %lu, next=%p, prev=%p, parent=%p, child=%p\n", __LINE__, l->type, l->size, l->next, l->prev, l->parent, l->child); exit(EXIT_FAILURE); } der_sequence_free(l); } static int der_choice_test(void) { ltc_asn1_list types[7], host[1]; unsigned char bitbuf[10], octetbuf[10], ia5buf[10], printbuf[10], outbuf[256]; unsigned long integer, oidbuf[10], outlen, inlen, x, y; void *mpinteger; ltc_utctime utctime = { 91, 5, 6, 16, 45, 40, 1, 7, 0 }; /* setup variables */ for (x = 0; x < sizeof(bitbuf); x++) { bitbuf[x] = x & 1; } for (x = 0; x < sizeof(octetbuf); x++) { octetbuf[x] = x; } for (x = 0; x < sizeof(ia5buf); x++) { ia5buf[x] = 'a'; } for (x = 0; x < sizeof(printbuf); x++) { printbuf[x] = 'a'; } integer = 1; for (x = 0; x < sizeof(oidbuf)/sizeof(oidbuf[0]); x++) { oidbuf[x] = x + 1; } DO(mp_init(&mpinteger)); for (x = 0; x < 14; x++) { /* setup list */ LTC_SET_ASN1(types, 0, LTC_ASN1_PRINTABLE_STRING, printbuf, sizeof(printbuf)); LTC_SET_ASN1(types, 1, LTC_ASN1_BIT_STRING, bitbuf, sizeof(bitbuf)); LTC_SET_ASN1(types, 2, LTC_ASN1_OCTET_STRING, octetbuf, sizeof(octetbuf)); LTC_SET_ASN1(types, 3, LTC_ASN1_IA5_STRING, ia5buf, sizeof(ia5buf)); if (x > 7) { LTC_SET_ASN1(types, 4, LTC_ASN1_SHORT_INTEGER, &integer, 1); } else { LTC_SET_ASN1(types, 4, LTC_ASN1_INTEGER, mpinteger, 1); } LTC_SET_ASN1(types, 5, LTC_ASN1_OBJECT_IDENTIFIER, oidbuf, sizeof(oidbuf)/sizeof(oidbuf[0])); LTC_SET_ASN1(types, 6, LTC_ASN1_UTCTIME, &utctime, 1); LTC_SET_ASN1(host, 0, LTC_ASN1_CHOICE, types, 7); /* encode */ outlen = sizeof(outbuf); DO(der_encode_sequence(&types[x>6?x-7:x], 1, outbuf, &outlen)); /* decode it */ inlen = outlen; DO(der_decode_sequence(outbuf, inlen, &host[0], 1)); for (y = 0; y < 7; y++) { if (types[y].used && y != (x>6?x-7:x)) { fprintf(stderr, "CHOICE, flag %lu in trial %lu was incorrectly set to one\n", y, x); return 1; } if (!types[y].used && y == (x>6?x-7:x)) { fprintf(stderr, "CHOICE, flag %lu in trial %lu was incorrectly set to zero\n", y, x); return 1; } } } mp_clear(mpinteger); return 0; } int der_tests(void) { unsigned long x, y, z, zz, oid[2][32]; unsigned char buf[3][2048]; void *a, *b, *c, *d, *e, *f, *g; static const unsigned char rsa_oid_der[] = { 0x06, 0x06, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d }; static const unsigned long rsa_oid[] = { 1, 2, 840, 113549 }; static const unsigned char rsa_ia5[] = "test1@rsa.com"; static const unsigned char rsa_ia5_der[] = { 0x16, 0x0d, 0x74, 0x65, 0x73, 0x74, 0x31, 0x40, 0x72, 0x73, 0x61, 0x2e, 0x63, 0x6f, 0x6d }; static const unsigned char rsa_printable[] = "Test User 1"; static const unsigned char rsa_printable_der[] = { 0x13, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x65, 0x72, 0x20, 0x31 }; static const ltc_utctime rsa_time1 = { 91, 5, 6, 16, 45, 40, 1, 7, 0 }; static const ltc_utctime rsa_time2 = { 91, 5, 6, 23, 45, 40, 0, 0, 0 }; ltc_utctime tmp_time; static const unsigned char rsa_time1_der[] = { 0x17, 0x11, 0x39, 0x31, 0x30, 0x35, 0x30, 0x36, 0x31, 0x36, 0x34, 0x35, 0x34, 0x30, 0x2D, 0x30, 0x37, 0x30, 0x30 }; static const unsigned char rsa_time2_der[] = { 0x17, 0x0d, 0x39, 0x31, 0x30, 0x35, 0x30, 0x36, 0x32, 0x33, 0x34, 0x35, 0x34, 0x30, 0x5a }; static const wchar_t utf8_1[] = { 0x0041, 0x2262, 0x0391, 0x002E }; static const unsigned char utf8_1_der[] = { 0x0C, 0x07, 0x41, 0xE2, 0x89, 0xA2, 0xCE, 0x91, 0x2E }; static const wchar_t utf8_2[] = { 0xD55C, 0xAD6D, 0xC5B4 }; static const unsigned char utf8_2_der[] = { 0x0C, 0x09, 0xED, 0x95, 0x9C, 0xEA, 0xB5, 0xAD, 0xEC, 0x96, 0xB4 }; unsigned char utf8_buf[32]; wchar_t utf8_out[32]; DO(mp_init_multi(&a, &b, &c, &d, &e, &f, &g, NULL)); for (zz = 0; zz < 16; zz++) { #ifdef USE_TFM for (z = 0; z < 256; z++) { #else for (z = 0; z < 1024; z++) { #endif if (yarrow_read(buf[0], z, &yarrow_prng) != z) { fprintf(stderr, "Failed to read %lu bytes from yarrow\n", z); return 1; } DO(mp_read_unsigned_bin(a, buf[0], z)); /* if (mp_iszero(a) == LTC_MP_NO) { a.sign = buf[0][0] & 1 ? LTC_MP_ZPOS : LTC_MP_NEG; } */ x = sizeof(buf[0]); DO(der_encode_integer(a, buf[0], &x)); DO(der_length_integer(a, &y)); if (y != x) { fprintf(stderr, "DER INTEGER size mismatch\n"); return 1; } mp_set_int(b, 0); DO(der_decode_integer(buf[0], y, b)); if (y != x || mp_cmp(a, b) != LTC_MP_EQ) { fprintf(stderr, "%lu: %lu vs %lu\n", z, x, y); mp_clear_multi(a, b, c, d, e, f, g, NULL); return 1; } } } /* test short integer */ for (zz = 0; zz < 256; zz++) { for (z = 1; z < 4; z++) { if (yarrow_read(buf[0], z, &yarrow_prng) != z) { fprintf(stderr, "Failed to read %lu bytes from yarrow\n", z); return 1; } /* encode with normal */ DO(mp_read_unsigned_bin(a, buf[0], z)); x = sizeof(buf[0]); DO(der_encode_integer(a, buf[0], &x)); /* encode with short */ y = sizeof(buf[1]); DO(der_encode_short_integer(mp_get_int(a), buf[1], &y)); if (x != y || memcmp(buf[0], buf[1], x)) { fprintf(stderr, "DER INTEGER short encoding failed, %lu, %lu\n", x, y); for (z = 0; z < x; z++) fprintf(stderr, "%02x ", buf[0][z]); fprintf(stderr, "\n"); for (z = 0; z < y; z++) fprintf(stderr, "%02x ", buf[1][z]); fprintf(stderr, "\n"); mp_clear_multi(a, b, c, d, e, f, g, NULL); return 1; } /* decode it */ x = 0; DO(der_decode_short_integer(buf[1], y, &x)); if (x != mp_get_int(a)) { fprintf(stderr, "DER INTEGER short decoding failed, %lu, %lu\n", x, mp_get_int(a)); mp_clear_multi(a, b, c, d, e, f, g, NULL); return 1; } } } mp_clear_multi(a, b, c, d, e, f, g, NULL); /* Test bit string */ for (zz = 1; zz < 1536; zz++) { yarrow_read(buf[0], zz, &yarrow_prng); for (z = 0; z < zz; z++) { buf[0][z] &= 0x01; } x = sizeof(buf[1]); DO(der_encode_bit_string(buf[0], zz, buf[1], &x)); DO(der_length_bit_string(zz, &y)); if (y != x) { fprintf(stderr, "\nDER BIT STRING length of encoded not match expected : %lu, %lu, %lu\n", z, x, y); return 1; } y = sizeof(buf[2]); DO(der_decode_bit_string(buf[1], x, buf[2], &y)); if (y != zz || memcmp(buf[0], buf[2], zz)) { fprintf(stderr, "%lu, %lu, %d\n", y, zz, memcmp(buf[0], buf[2], zz)); return 1; } } /* Test octet string */ for (zz = 1; zz < 1536; zz++) { yarrow_read(buf[0], zz, &yarrow_prng); x = sizeof(buf[1]); DO(der_encode_octet_string(buf[0], zz, buf[1], &x)); DO(der_length_octet_string(zz, &y)); if (y != x) { fprintf(stderr, "\nDER OCTET STRING length of encoded not match expected : %lu, %lu, %lu\n", z, x, y); return 1; } y = sizeof(buf[2]); DO(der_decode_octet_string(buf[1], x, buf[2], &y)); if (y != zz || memcmp(buf[0], buf[2], zz)) { fprintf(stderr, "%lu, %lu, %d\n", y, zz, memcmp(buf[0], buf[2], zz)); return 1; } } /* test OID */ x = sizeof(buf[0]); DO(der_encode_object_identifier((unsigned long*)rsa_oid, sizeof(rsa_oid)/sizeof(rsa_oid[0]), buf[0], &x)); if (x != sizeof(rsa_oid_der) || memcmp(rsa_oid_der, buf[0], x)) { fprintf(stderr, "rsa_oid_der encode failed to match, %lu, ", x); for (y = 0; y < x; y++) fprintf(stderr, "%02x ", buf[0][y]); fprintf(stderr, "\n"); return 1; } y = sizeof(oid[0])/sizeof(oid[0][0]); DO(der_decode_object_identifier(buf[0], x, oid[0], &y)); if (y != sizeof(rsa_oid)/sizeof(rsa_oid[0]) || memcmp(rsa_oid, oid[0], sizeof(rsa_oid))) { fprintf(stderr, "rsa_oid_der decode failed to match, %lu, ", y); for (z = 0; z < y; z++) fprintf(stderr, "%lu ", oid[0][z]); fprintf(stderr, "\n"); return 1; } /* do random strings */ for (zz = 0; zz < 5000; zz++) { /* pick a random number of words */ yarrow_read(buf[0], 4, &yarrow_prng); LOAD32L(z, buf[0]); z = 2 + (z % ((sizeof(oid[0])/sizeof(oid[0][0])) - 2)); /* fill them in */ oid[0][0] = buf[0][0] % 3; oid[0][1] = buf[0][1] % 40; for (y = 2; y < z; y++) { yarrow_read(buf[0], 4, &yarrow_prng); LOAD32L(oid[0][y], buf[0]); } /* encode it */ x = sizeof(buf[0]); DO(der_encode_object_identifier(oid[0], z, buf[0], &x)); DO(der_length_object_identifier(oid[0], z, &y)); if (x != y) { fprintf(stderr, "Random OID %lu test failed, length mismatch: %lu, %lu\n", z, x, y); for (x = 0; x < z; x++) fprintf(stderr, "%lu\n", oid[0][x]); return 1; } /* decode it */ y = sizeof(oid[0])/sizeof(oid[0][0]); DO(der_decode_object_identifier(buf[0], x, oid[1], &y)); if (y != z) { fprintf(stderr, "Random OID %lu test failed, decode length mismatch: %lu, %lu\n", z, x, y); return 1; } if (memcmp(oid[0], oid[1], sizeof(oid[0][0]) * z)) { fprintf(stderr, "Random OID %lu test failed, decoded values wrong\n", z); for (x = 0; x < z; x++) fprintf(stderr, "%lu\n", oid[0][x]); fprintf(stderr, "\n\n Got \n\n"); for (x = 0; x < z; x++) fprintf(stderr, "%lu\n", oid[1][x]); return 1; } } /* IA5 string */ x = sizeof(buf[0]); DO(der_encode_ia5_string(rsa_ia5, strlen((char*)rsa_ia5), buf[0], &x)); if (x != sizeof(rsa_ia5_der) || memcmp(buf[0], rsa_ia5_der, x)) { fprintf(stderr, "IA5 encode failed: %lu, %lu\n", x, (unsigned long)sizeof(rsa_ia5_der)); return 1; } DO(der_length_ia5_string(rsa_ia5, strlen((char*)rsa_ia5), &y)); if (y != x) { fprintf(stderr, "IA5 length failed to match: %lu, %lu\n", x, y); return 1; } y = sizeof(buf[1]); DO(der_decode_ia5_string(buf[0], x, buf[1], &y)); if (y != strlen((char*)rsa_ia5) || memcmp(buf[1], rsa_ia5, strlen((char*)rsa_ia5))) { fprintf(stderr, "DER IA5 failed test vector\n"); return 1; } /* Printable string */ x = sizeof(buf[0]); DO(der_encode_printable_string(rsa_printable, strlen((char*)rsa_printable), buf[0], &x)); if (x != sizeof(rsa_printable_der) || memcmp(buf[0], rsa_printable_der, x)) { fprintf(stderr, "PRINTABLE encode failed: %lu, %lu\n", x, (unsigned long)sizeof(rsa_printable_der)); return 1; } DO(der_length_printable_string(rsa_printable, strlen((char*)rsa_printable), &y)); if (y != x) { fprintf(stderr, "printable length failed to match: %lu, %lu\n", x, y); return 1; } y = sizeof(buf[1]); DO(der_decode_printable_string(buf[0], x, buf[1], &y)); if (y != strlen((char*)rsa_printable) || memcmp(buf[1], rsa_printable, strlen((char*)rsa_printable))) { fprintf(stderr, "DER printable failed test vector\n"); return 1; } /* Test UTC time */ x = sizeof(buf[0]); DO(der_encode_utctime((ltc_utctime*)&rsa_time1, buf[0], &x)); if (x != sizeof(rsa_time1_der) || memcmp(buf[0], rsa_time1_der, x)) { fprintf(stderr, "UTCTIME encode of rsa_time1 failed: %lu, %lu\n", x, (unsigned long)sizeof(rsa_time1_der)); fprintf(stderr, "\n\n"); for (y = 0; y < x; y++) fprintf(stderr, "%02x ", buf[0][y]); printf("\n"); return 1; } DO(der_length_utctime((ltc_utctime*)&rsa_time1, &y)); if (y != x) { fprintf(stderr, "UTCTIME length failed to match for rsa_time1: %lu, %lu\n", x, y); return 1; } DO(der_decode_utctime(buf[0], &y, &tmp_time)); if (y != x || memcmp(&rsa_time1, &tmp_time, sizeof(ltc_utctime))) { fprintf(stderr, "UTCTIME decode failed for rsa_time1: %lu %lu\n", x, y); fprintf(stderr, "\n\n%u %u %u %u %u %u %u %u %u\n\n", tmp_time.YY, tmp_time.MM, tmp_time.DD, tmp_time.hh, tmp_time.mm, tmp_time.ss, tmp_time.off_dir, tmp_time.off_mm, tmp_time.off_hh); return 1; } x = sizeof(buf[0]); DO(der_encode_utctime((ltc_utctime*)&rsa_time2, buf[0], &x)); if (x != sizeof(rsa_time2_der) || memcmp(buf[0], rsa_time2_der, x)) { fprintf(stderr, "UTCTIME encode of rsa_time2 failed: %lu, %lu\n", x, (unsigned long)sizeof(rsa_time1_der)); fprintf(stderr, "\n\n"); for (y = 0; y < x; y++) fprintf(stderr, "%02x ", buf[0][y]); printf("\n"); return 1; } DO(der_length_utctime((ltc_utctime*)&rsa_time2, &y)); if (y != x) { fprintf(stderr, "UTCTIME length failed to match for rsa_time2: %lu, %lu\n", x, y); return 1; } DO(der_decode_utctime(buf[0], &y, &tmp_time)); if (y != x || memcmp(&rsa_time2, &tmp_time, sizeof(ltc_utctime))) { fprintf(stderr, "UTCTIME decode failed for rsa_time2: %lu %lu\n", x, y); fprintf(stderr, "\n\n%u %u %u %u %u %u %u %u %u\n\n", tmp_time.YY, tmp_time.MM, tmp_time.DD, tmp_time.hh, tmp_time.mm, tmp_time.ss, tmp_time.off_dir, tmp_time.off_mm, tmp_time.off_hh); return 1; } /* UTF 8 */ /* encode it */ x = sizeof(utf8_buf); DO(der_encode_utf8_string(utf8_1, sizeof(utf8_1) / sizeof(utf8_1[0]), utf8_buf, &x)); if (x != sizeof(utf8_1_der) || memcmp(utf8_buf, utf8_1_der, x)) { fprintf(stderr, "DER UTF8_1 encoded to %lu bytes\n", x); for (y = 0; y < x; y++) fprintf(stderr, "%02x ", (unsigned)utf8_buf[y]); fprintf(stderr, "\n"); return 1; } /* decode it */ y = sizeof(utf8_out) / sizeof(utf8_out[0]); DO(der_decode_utf8_string(utf8_buf, x, utf8_out, &y)); if (y != (sizeof(utf8_1) / sizeof(utf8_1[0])) || memcmp(utf8_1, utf8_out, y * sizeof(wchar_t))) { fprintf(stderr, "DER UTF8_1 decoded to %lu wchar_t\n", y); for (x = 0; x < y; x++) fprintf(stderr, "%04lx ", (unsigned long)utf8_out[x]); fprintf(stderr, "\n"); return 1; } /* encode it */ x = sizeof(utf8_buf); DO(der_encode_utf8_string(utf8_2, sizeof(utf8_2) / sizeof(utf8_2[0]), utf8_buf, &x)); if (x != sizeof(utf8_2_der) || memcmp(utf8_buf, utf8_2_der, x)) { fprintf(stderr, "DER UTF8_2 encoded to %lu bytes\n", x); for (y = 0; y < x; y++) fprintf(stderr, "%02x ", (unsigned)utf8_buf[y]); fprintf(stderr, "\n"); return 1; } /* decode it */ y = sizeof(utf8_out) / sizeof(utf8_out[0]); DO(der_decode_utf8_string(utf8_buf, x, utf8_out, &y)); if (y != (sizeof(utf8_2) / sizeof(utf8_2[0])) || memcmp(utf8_2, utf8_out, y * sizeof(wchar_t))) { fprintf(stderr, "DER UTF8_2 decoded to %lu wchar_t\n", y); for (x = 0; x < y; x++) fprintf(stderr, "%04lx ", (unsigned long)utf8_out[x]); fprintf(stderr, "\n"); return 1; } der_set_test(); der_flexi_test(); return der_choice_test(); } #endif /* $Source: /cvs/libtom/libtomcrypt/testprof/der_tests.c,v $ */ /* $Revision: 1.50 $ */ /* $Date: 2007/05/12 14:20:27 $ */ libtomcrypt-1.17/testprof/ecc_test.c0000644000175100001440000001540210621351501016330 0ustar tomusers#include #ifdef LTC_MECC static int sizes[] = { #ifdef ECC112 14, #endif #ifdef ECC128 16, #endif #ifdef ECC160 20, #endif #ifdef ECC192 24, #endif #ifdef ECC224 28, #endif #ifdef ECC256 32, #endif #ifdef ECC384 48, #endif #ifdef ECC521 65 #endif }; #ifdef LTC_ECC_SHAMIR int ecc_test_shamir(void) { void *modulus, *mp, *kA, *kB, *rA, *rB; ecc_point *G, *A, *B, *C1, *C2; int x, y, z; unsigned char buf[ECC_BUF_SIZE]; DO(mp_init_multi(&kA, &kB, &rA, &rB, &modulus, NULL)); LTC_ARGCHK((G = ltc_ecc_new_point()) != NULL); LTC_ARGCHK((A = ltc_ecc_new_point()) != NULL); LTC_ARGCHK((B = ltc_ecc_new_point()) != NULL); LTC_ARGCHK((C1 = ltc_ecc_new_point()) != NULL); LTC_ARGCHK((C2 = ltc_ecc_new_point()) != NULL); for (x = 0; x < (int)(sizeof(sizes)/sizeof(sizes[0])); x++) { /* get the base point */ for (z = 0; ltc_ecc_sets[z].name; z++) { if (sizes[z] < ltc_ecc_sets[z].size) break; } LTC_ARGCHK(ltc_ecc_sets[z].name != NULL); /* load it */ DO(mp_read_radix(G->x, ltc_ecc_sets[z].Gx, 16)); DO(mp_read_radix(G->y, ltc_ecc_sets[z].Gy, 16)); DO(mp_set(G->z, 1)); DO(mp_read_radix(modulus, ltc_ecc_sets[z].prime, 16)); DO(mp_montgomery_setup(modulus, &mp)); /* do 100 random tests */ for (y = 0; y < 100; y++) { /* pick a random r1, r2 */ LTC_ARGCHK(yarrow_read(buf, sizes[x], &yarrow_prng) == sizes[x]); DO(mp_read_unsigned_bin(rA, buf, sizes[x])); LTC_ARGCHK(yarrow_read(buf, sizes[x], &yarrow_prng) == sizes[x]); DO(mp_read_unsigned_bin(rB, buf, sizes[x])); /* compute rA * G = A */ DO(ltc_mp.ecc_ptmul(rA, G, A, modulus, 1)); /* compute rB * G = B */ DO(ltc_mp.ecc_ptmul(rB, G, B, modulus, 1)); /* pick a random kA, kB */ LTC_ARGCHK(yarrow_read(buf, sizes[x], &yarrow_prng) == sizes[x]); DO(mp_read_unsigned_bin(kA, buf, sizes[x])); LTC_ARGCHK(yarrow_read(buf, sizes[x], &yarrow_prng) == sizes[x]); DO(mp_read_unsigned_bin(kB, buf, sizes[x])); /* now, compute kA*A + kB*B = C1 using the older method */ DO(ltc_mp.ecc_ptmul(kA, A, C1, modulus, 0)); DO(ltc_mp.ecc_ptmul(kB, B, C2, modulus, 0)); DO(ltc_mp.ecc_ptadd(C1, C2, C1, modulus, mp)); DO(ltc_mp.ecc_map(C1, modulus, mp)); /* now compute using mul2add */ DO(ltc_mp.ecc_mul2add(A, kA, B, kB, C2, modulus)); /* is they the sames? */ if ((mp_cmp(C1->x, C2->x) != LTC_MP_EQ) || (mp_cmp(C1->y, C2->y) != LTC_MP_EQ) || (mp_cmp(C1->z, C2->z) != LTC_MP_EQ)) { fprintf(stderr, "ECC failed shamir test: size=%d, testno=%d\n", sizes[x], y); return 1; } } mp_montgomery_free(mp); } ltc_ecc_del_point(C2); ltc_ecc_del_point(C1); ltc_ecc_del_point(B); ltc_ecc_del_point(A); ltc_ecc_del_point(G); mp_clear_multi(kA, kB, rA, rB, modulus, NULL); return 0; } #endif int ecc_tests (void) { unsigned char buf[4][4096]; unsigned long x, y, z, s; int stat, stat2; ecc_key usera, userb, pubKey, privKey; DO(ecc_test ()); DO(ecc_test ()); DO(ecc_test ()); DO(ecc_test ()); DO(ecc_test ()); for (s = 0; s < (sizeof(sizes)/sizeof(sizes[0])); s++) { /* make up two keys */ DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), sizes[s], &usera)); DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), sizes[s], &userb)); /* make the shared secret */ x = sizeof(buf[0]); DO(ecc_shared_secret (&usera, &userb, buf[0], &x)); y = sizeof(buf[1]); DO(ecc_shared_secret (&userb, &usera, buf[1], &y)); if (y != x) { fprintf(stderr, "ecc Shared keys are not same size."); return 1; } if (memcmp (buf[0], buf[1], x)) { fprintf(stderr, "ecc Shared keys not same contents."); return 1; } /* now export userb */ y = sizeof(buf[0]); DO(ecc_export (buf[1], &y, PK_PUBLIC, &userb)); ecc_free (&userb); /* import and make the shared secret again */ DO(ecc_import (buf[1], y, &userb)); z = sizeof(buf[0]); DO(ecc_shared_secret (&usera, &userb, buf[2], &z)); if (z != x) { fprintf(stderr, "failed. Size don't match?"); return 1; } if (memcmp (buf[0], buf[2], x)) { fprintf(stderr, "Failed. Contents didn't match."); return 1; } /* export with ANSI X9.63 */ y = sizeof(buf[1]); DO(ecc_ansi_x963_export(&userb, buf[1], &y)); ecc_free (&userb); /* now import the ANSI key */ DO(ecc_ansi_x963_import(buf[1], y, &userb)); /* shared secret */ z = sizeof(buf[0]); DO(ecc_shared_secret (&usera, &userb, buf[2], &z)); if (z != x) { fprintf(stderr, "failed. Size don't match?"); return 1; } if (memcmp (buf[0], buf[2], x)) { fprintf(stderr, "Failed. Contents didn't match."); return 1; } ecc_free (&usera); ecc_free (&userb); /* test encrypt_key */ DO(ecc_make_key (&yarrow_prng, find_prng ("yarrow"), sizes[s], &usera)); /* export key */ x = sizeof(buf[0]); DO(ecc_export(buf[0], &x, PK_PUBLIC, &usera)); DO(ecc_import(buf[0], x, &pubKey)); x = sizeof(buf[0]); DO(ecc_export(buf[0], &x, PK_PRIVATE, &usera)); DO(ecc_import(buf[0], x, &privKey)); for (x = 0; x < 32; x++) { buf[0][x] = x; } y = sizeof (buf[1]); DO(ecc_encrypt_key (buf[0], 32, buf[1], &y, &yarrow_prng, find_prng ("yarrow"), find_hash ("sha256"), &pubKey)); zeromem (buf[0], sizeof (buf[0])); x = sizeof (buf[0]); DO(ecc_decrypt_key (buf[1], y, buf[0], &x, &privKey)); if (x != 32) { fprintf(stderr, "Failed (length)"); return 1; } for (x = 0; x < 32; x++) { if (buf[0][x] != x) { fprintf(stderr, "Failed (contents)"); return 1; } } /* test sign_hash */ for (x = 0; x < 16; x++) { buf[0][x] = x; } x = sizeof (buf[1]); DO(ecc_sign_hash (buf[0], 16, buf[1], &x, &yarrow_prng, find_prng ("yarrow"), &privKey)); DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat, &pubKey)); buf[0][0] ^= 1; DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat2, &privKey)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "ecc_verify_hash failed %d, %d, ", stat, stat2); return 1; } ecc_free (&usera); ecc_free (&pubKey); ecc_free (&privKey); } #ifdef LTC_ECC_SHAMIR return ecc_test_shamir(); #else return 0; #endif } #else int ecc_tests(void) { fprintf(stderr, "NOP"); return 0; } #endif /* $Source: /cvs/libtom/libtomcrypt/testprof/ecc_test.c,v $ */ /* $Revision: 1.22 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/testprof/store_test.c0000644000175100001440000000346110621351501016734 0ustar tomusers#include /* Test store/load macros with offsets */ int store_test(void) { unsigned char buf[256]; int y; ulong32 L, L1; ulong64 LL, LL1; #ifdef LTC_FAST int x, z; #endif for (y = 0; y < 4; y++) { L = 0x12345678UL; L1 = 0; STORE32L(L, buf + y); LOAD32L(L1, buf + y); if (L1 != L) { fprintf(stderr, "\n32L failed at offset %d\n", y); return 1; } STORE32H(L, buf + y); LOAD32H(L1, buf + y); if (L1 != L) { fprintf(stderr, "\n32H failed at offset %d\n", y); return 1; } } for (y = 0; y < 8; y++) { LL = CONST64 (0x01020304050607); LL1 = 0; STORE64L(LL, buf + y); LOAD64L(LL1, buf + y); if (LL1 != LL) { fprintf(stderr, "\n64L failed at offset %d\n", y); return 1; } STORE64H(LL, buf + y); LOAD64H(LL1, buf + y); if (LL1 != LL) { fprintf(stderr, "\n64H failed at offset %d\n", y); return 1; } } /* test LTC_FAST */ #ifdef LTC_FAST y = 16; for (z = 0; z < y; z++) { /* fill y bytes with random */ yarrow_read(buf+z, y, &yarrow_prng); yarrow_read(buf+z+y, y, &yarrow_prng); /* now XOR it byte for byte */ for (x = 0; x < y; x++) { buf[2*y+z+x] = buf[z+x] ^ buf[z+y+x]; } /* now XOR it word for word */ for (x = 0; x < y; x += sizeof(LTC_FAST_TYPE)) { *((LTC_FAST_TYPE*)(&buf[3*y+z+x])) = *((LTC_FAST_TYPE*)(&buf[z+x])) ^ *((LTC_FAST_TYPE*)(&buf[z+y+x])); } if (memcmp(&buf[2*y+z], &buf[3*y+z], y)) { fprintf(stderr, "\nLTC_FAST failed at offset %d\n", z); return 1; } } #endif return 0; } /* $Source: /cvs/libtom/libtomcrypt/testprof/store_test.c,v $ */ /* $Revision: 1.6 $ */ /* $Date: 2005/05/05 14:35:59 $ */ libtomcrypt-1.17/testprof/base64_test.c0000644000175100001440000000116310621351501016661 0ustar tomusers#include int base64_test(void) { unsigned char in[64], out[256], tmp[64]; unsigned long x, l1, l2; for (x = 0; x < 64; x++) { yarrow_read(in, x, &yarrow_prng); l1 = sizeof(out); DO(base64_encode(in, x, out, &l1)); l2 = sizeof(tmp); DO(base64_decode(out, l1, tmp, &l2)); if (l2 != x || memcmp(tmp, in, x)) { fprintf(stderr, "base64 failed %lu %lu %lu", x, l1, l2); return 1; } } return 0; } /* $Source: /cvs/libtom/libtomcrypt/testprof/base64_test.c,v $ */ /* $Revision: 1.5 $ */ /* $Date: 2005/05/21 12:51:25 $ */ libtomcrypt-1.17/testprof/katja_test.c0000644000175100001440000001556210621351501016677 0ustar tomusers#include #ifdef MKAT int katja_test(void) { unsigned char in[1024], out[1024], tmp[1024]; katja_key key, privKey, pubKey; int hash_idx, prng_idx, stat, stat2, size; unsigned long kat_msgsize, len, len2, cnt; static unsigned char lparam[] = { 0x01, 0x02, 0x03, 0x04 }; hash_idx = find_hash("sha1"); prng_idx = find_prng("yarrow"); if (hash_idx == -1 || prng_idx == -1) { fprintf(stderr, "katja_test requires LTC_SHA1 and yarrow"); return 1; } for (size = 1024; size <= 2048; size += 256) { /* make 10 random key */ for (cnt = 0; cnt < 10; cnt++) { DO(katja_make_key(&yarrow_prng, prng_idx, size/8, &key)); if (mp_count_bits(key.N) < size - 7) { fprintf(stderr, "katja_%d key modulus has %d bits\n", size, mp_count_bits(key.N)); len = mp_unsigned_bin_size(key.N); mp_to_unsigned_bin(key.N, tmp); fprintf(stderr, "N == \n"); for (cnt = 0; cnt < len; ) { fprintf(stderr, "%02x ", tmp[cnt]); if (!(++cnt & 15)) fprintf(stderr, "\n"); } len = mp_unsigned_bin_size(key.p); mp_to_unsigned_bin(key.p, tmp); fprintf(stderr, "p == \n"); for (cnt = 0; cnt < len; ) { fprintf(stderr, "%02x ", tmp[cnt]); if (!(++cnt & 15)) fprintf(stderr, "\n"); } len = mp_unsigned_bin_size(key.q); mp_to_unsigned_bin(key.q, tmp); fprintf(stderr, "\nq == \n"); for (cnt = 0; cnt < len; ) { fprintf(stderr, "%02x ", tmp[cnt]); if (!(++cnt & 15)) fprintf(stderr, "\n"); } fprintf(stderr, "\n"); return 1; } if (cnt != 9) { katja_free(&key); } } /* encrypt the key (without lparam) */ for (cnt = 0; cnt < 4; cnt++) { for (kat_msgsize = 1; kat_msgsize <= 42; kat_msgsize++) { /* make a random key/msg */ yarrow_read(in, kat_msgsize, &yarrow_prng); len = sizeof(out); len2 = kat_msgsize; DO(katja_encrypt_key(in, kat_msgsize, out, &len, NULL, 0, &yarrow_prng, prng_idx, hash_idx, &key)); /* change a byte */ out[8] ^= 1; DO(katja_decrypt_key(out, len, tmp, &len2, NULL, 0, hash_idx, &stat2, &key)); /* change a byte back */ out[8] ^= 1; if (len2 != kat_msgsize) { fprintf(stderr, "\nkatja_decrypt_key mismatch len %lu (first decrypt)", len2); return 1; } len2 = kat_msgsize; DO(katja_decrypt_key(out, len, tmp, &len2, NULL, 0, hash_idx, &stat, &key)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "katja_decrypt_key failed"); return 1; } if (len2 != kat_msgsize || memcmp(tmp, in, kat_msgsize)) { unsigned long x; fprintf(stderr, "\nkatja_decrypt_key mismatch, len %lu (second decrypt)\n", len2); fprintf(stderr, "Original contents: \n"); for (x = 0; x < kat_msgsize; ) { fprintf(stderr, "%02x ", in[x]); if (!(++x % 16)) { fprintf(stderr, "\n"); } } fprintf(stderr, "\n"); fprintf(stderr, "Output contents: \n"); for (x = 0; x < kat_msgsize; ) { fprintf(stderr, "%02x ", out[x]); if (!(++x % 16)) { fprintf(stderr, "\n"); } } fprintf(stderr, "\n"); return 1; } } } /* encrypt the key (with lparam) */ for (kat_msgsize = 1; kat_msgsize <= 42; kat_msgsize++) { len = sizeof(out); len2 = kat_msgsize; DO(katja_encrypt_key(in, kat_msgsize, out, &len, lparam, sizeof(lparam), &yarrow_prng, prng_idx, hash_idx, &key)); /* change a byte */ out[8] ^= 1; DO(katja_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), hash_idx, &stat2, &key)); if (len2 != kat_msgsize) { fprintf(stderr, "\nkatja_decrypt_key mismatch len %lu (first decrypt)", len2); return 1; } /* change a byte back */ out[8] ^= 1; len2 = kat_msgsize; DO(katja_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), hash_idx, &stat, &key)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "katja_decrypt_key failed"); return 1; } if (len2 != kat_msgsize || memcmp(tmp, in, kat_msgsize)) { fprintf(stderr, "katja_decrypt_key mismatch len %lu", len2); return 1; } } #if 0 /* sign a message (unsalted, lower cholestorol and Atkins approved) now */ len = sizeof(out); DO(katja_sign_hash(in, 20, out, &len, &yarrow_prng, prng_idx, hash_idx, 0, &key)); /* export key and import as both private and public */ len2 = sizeof(tmp); DO(katja_export(tmp, &len2, PK_PRIVATE, &key)); DO(katja_import(tmp, len2, &privKey)); len2 = sizeof(tmp); DO(katja_export(tmp, &len2, PK_PUBLIC, &key)); DO(katja_import(tmp, len2, &pubKey)); /* verify with original */ DO(katja_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &key)); /* change a byte */ in[0] ^= 1; DO(katja_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &key)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "katja_verify_hash (unsalted, origKey) failed, %d, %d", stat, stat2); katja_free(&key); katja_free(&pubKey); katja_free(&privKey); return 1; } /* verify with privKey */ /* change a byte */ in[0] ^= 1; DO(katja_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &privKey)); /* change a byte */ in[0] ^= 1; DO(katja_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &privKey)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "katja_verify_hash (unsalted, privKey) failed, %d, %d", stat, stat2); katja_free(&key); katja_free(&pubKey); katja_free(&privKey); return 1; } /* verify with pubKey */ /* change a byte */ in[0] ^= 1; DO(katja_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &pubKey)); /* change a byte */ in[0] ^= 1; DO(katja_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &pubKey)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "katja_verify_hash (unsalted, pubkey) failed, %d, %d", stat, stat2); katja_free(&key); katja_free(&pubKey); katja_free(&privKey); return 1; } /* sign a message (salted) now (use privKey to make, pubKey to verify) */ len = sizeof(out); DO(katja_sign_hash(in, 20, out, &len, &yarrow_prng, prng_idx, hash_idx, 8, &privKey)); DO(katja_verify_hash(out, len, in, 20, hash_idx, 8, &stat, &pubKey)); /* change a byte */ in[0] ^= 1; DO(katja_verify_hash(out, len, in, 20, hash_idx, 8, &stat2, &pubKey)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "katja_verify_hash (salted) failed, %d, %d", stat, stat2); katja_free(&key); katja_free(&pubKey); katja_free(&privKey); return 1; } #endif katja_free(&key); katja_free(&pubKey); katja_free(&privKey); } /* free the key and return */ return 0; } #else int katja_test(void) { fprintf(stderr, "NOP"); return 0; } #endif libtomcrypt-1.17/testprof/pkcs_1_test.c0000644000175100001440000000543610621351501016764 0ustar tomusers#include #ifdef LTC_PKCS_1 int pkcs_1_test(void) { unsigned char buf[3][128]; int res1, res2, res3, prng_idx, hash_idx, err; unsigned long x, y, l1, l2, l3, i1, i2, lparamlen, saltlen, modlen; static const unsigned char lparam[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 }; /* get hash/prng */ hash_idx = find_hash("sha1"); prng_idx = find_prng("yarrow"); if (hash_idx == -1 || prng_idx == -1) { fprintf(stderr, "pkcs_1 tests require sha1/yarrow"); return 1; } srand(time(NULL)); /* do many tests */ for (x = 0; x < 100; x++) { zeromem(buf, sizeof(buf)); /* make a dummy message (of random length) */ l3 = (rand() & 31) + 8; for (y = 0; y < l3; y++) buf[0][y] = rand() & 255; /* pick a random lparam len [0..16] */ lparamlen = abs(rand()) % 17; /* pick a random saltlen 0..16 */ saltlen = abs(rand()) % 17; /* LTC_PKCS #1 v2.0 supports modlens not multiple of 8 */ modlen = 800 + (abs(rand()) % 224); /* encode it */ l1 = sizeof(buf[1]); DO(pkcs_1_oaep_encode(buf[0], l3, lparam, lparamlen, modlen, &yarrow_prng, prng_idx, hash_idx, buf[1], &l1)); /* decode it */ l2 = sizeof(buf[2]); DO(pkcs_1_oaep_decode(buf[1], l1, lparam, lparamlen, modlen, hash_idx, buf[2], &l2, &res1)); if (res1 != 1 || l2 != l3 || memcmp(buf[2], buf[0], l3) != 0) { fprintf(stderr, "Outsize == %lu, should have been %lu, res1 = %d, lparamlen = %lu, msg contents follow.\n", l2, l3, res1, lparamlen); fprintf(stderr, "ORIGINAL:\n"); for (x = 0; x < l3; x++) { fprintf(stderr, "%02x ", buf[0][x]); } fprintf(stderr, "\nRESULT:\n"); for (x = 0; x < l2; x++) { fprintf(stderr, "%02x ", buf[2][x]); } fprintf(stderr, "\n\n"); return 1; } /* test PSS */ l1 = sizeof(buf[1]); DO(pkcs_1_pss_encode(buf[0], l3, saltlen, &yarrow_prng, prng_idx, hash_idx, modlen, buf[1], &l1)); DO(pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res1)); buf[0][i1 = abs(rand()) % l3] ^= 1; DO(pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res2)); buf[0][i1] ^= 1; buf[1][i2 = abs(rand()) % (l1 - 1)] ^= 1; pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res3); if (!(res1 == 1 && res2 == 0 && res3 == 0)) { fprintf(stderr, "PSS failed: %d, %d, %d, %lu, %lu\n", res1, res2, res3, l3, saltlen); return 1; } } return 0; } #else int pkcs_1_test(void) { fprintf(stderr, "NOP"); return 0; } #endif /* $Source: /cvs/libtom/libtomcrypt/testprof/pkcs_1_test.c,v $ */ /* $Revision: 1.8 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/testprof/makefile.msvc0000644000175100001440000000054410621351501017043 0ustar tomusersCFLAGS = /I../src/headers/ /I./ /Ox /DWIN32 /DLTC_SOURCE /W3 /Fo$@ OBJECTS=base64_test.obj cipher_hash_test.obj der_tests.obj \ dsa_test.obj ecc_test.obj mac_test.obj modes_test.obj pkcs_1_test.obj \ rsa_test.obj store_test.obj test_driver.obj x86_prof.obj katja_test.obj tomcrypt_prof.lib: $(OBJECTS) lib /out:tomcrypt_prof.lib $(OBJECTS) libtomcrypt-1.17/testprof/tomcrypt_test.h0000644000175100001440000000322410621351501017463 0ustar tomusers #ifndef __TEST_H_ #define __TEST_H_ #include /* enable stack testing */ /* #define STACK_TEST */ /* stack testing, define this if stack usage goes downwards [e.g. x86] */ #define STACK_DOWN typedef struct { char *name, *prov, *req; int (*entry)(void); } test_entry; extern prng_state yarrow_prng; void run_cmd(int res, int line, char *file, char *cmd); #ifdef LTC_VERBOSE #define DO(x) do { fprintf(stderr, "%s:\n", #x); run_cmd((x), __LINE__, __FILE__, #x); } while (0); #else #define DO(x) do { run_cmd((x), __LINE__, __FILE__, #x); } while (0); #endif /* TESTS */ int cipher_hash_test(void); int modes_test(void); int mac_test(void); int pkcs_1_test(void); int store_test(void); int rsa_test(void); int katja_test(void); int ecc_tests(void); int dsa_test(void); int der_tests(void); /* timing */ #define KTIMES 25 #define TIMES 100000 extern struct list { int id; unsigned long spd1, spd2, avg; } results[]; extern int no_results; int sorter(const void *a, const void *b); void tally_results(int type); ulong64 rdtsc (void); void t_start(void); ulong64 t_read(void); void init_timer(void); /* register default algs */ void reg_algs(void); int time_keysched(void); int time_cipher(void); int time_cipher2(void); int time_cipher3(void); int time_hash(void); void time_mult(void); void time_sqr(void); void time_prng(void); void time_rsa(void); void time_dsa(void); void time_katja(void); void time_ecc(void); void time_macs_(unsigned long MAC_SIZE); void time_macs(void); void time_encmacs(void); #endif /* $Source: /cvs/libtom/libtomcrypt/testprof/tomcrypt_test.h,v $ */ /* $Revision: 1.14 $ */ /* $Date: 2006/10/18 03:36:34 $ */ libtomcrypt-1.17/testprof/cipher_hash_test.c0000644000175100001440000000250310621351501020051 0ustar tomusers/* test the ciphers and hashes using their built-in self-tests */ #include int cipher_hash_test(void) { int x; unsigned char buf[4096]; unsigned long n; prng_state nprng; /* test ciphers */ for (x = 0; cipher_descriptor[x].name != NULL; x++) { DO(cipher_descriptor[x].test()); } /* test hashes */ for (x = 0; hash_descriptor[x].name != NULL; x++) { DO(hash_descriptor[x].test()); } /* test prngs (test, import/export */ for (x = 0; prng_descriptor[x].name != NULL; x++) { DO(prng_descriptor[x].test()); DO(prng_descriptor[x].start(&nprng)); DO(prng_descriptor[x].add_entropy((unsigned char *)"helloworld12", 12, &nprng)); DO(prng_descriptor[x].ready(&nprng)); n = sizeof(buf); DO(prng_descriptor[x].pexport(buf, &n, &nprng)); prng_descriptor[x].done(&nprng); DO(prng_descriptor[x].pimport(buf, n, &nprng)); DO(prng_descriptor[x].ready(&nprng)); if (prng_descriptor[x].read(buf, 100, &nprng) != 100) { fprintf(stderr, "Error reading from imported PRNG!\n"); exit(EXIT_FAILURE); } prng_descriptor[x].done(&nprng); } return 0; } /* $Source: /cvs/libtom/libtomcrypt/testprof/cipher_hash_test.c,v $ */ /* $Revision: 1.3 $ */ /* $Date: 2005/05/05 14:35:59 $ */ libtomcrypt-1.17/testprof/rsa_test.c0000644000175100001440000003755110621351501016374 0ustar tomusers#include #ifdef LTC_MRSA #define RSA_MSGSIZE 78 /* These are test keys [see file test.key] that I use to test my import/export against */ static const unsigned char openssl_private_rsa[] = { 0x30, 0x82, 0x02, 0x5e, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xcf, 0x9a, 0xde, 0x64, 0x8a, 0xda, 0xc8, 0x33, 0x20, 0xa9, 0xd7, 0x83, 0x31, 0x19, 0x54, 0xb2, 0x9a, 0x85, 0xa7, 0xa1, 0xb7, 0x75, 0x33, 0xb6, 0xa9, 0xac, 0x84, 0x24, 0xb3, 0xde, 0xdb, 0x7d, 0x85, 0x2d, 0x96, 0x65, 0xe5, 0x3f, 0x72, 0x95, 0x24, 0x9f, 0x28, 0x68, 0xca, 0x4f, 0xdb, 0x44, 0x1c, 0x3e, 0x60, 0x12, 0x8a, 0xdd, 0x26, 0xa5, 0xeb, 0xff, 0x0b, 0x5e, 0xd4, 0x88, 0x38, 0x49, 0x2a, 0x6e, 0x5b, 0xbf, 0x12, 0x37, 0x47, 0xbd, 0x05, 0x6b, 0xbc, 0xdb, 0xf3, 0xee, 0xe4, 0x11, 0x8e, 0x41, 0x68, 0x7c, 0x61, 0x13, 0xd7, 0x42, 0xc8, 0x80, 0xbe, 0x36, 0x8f, 0xdc, 0x08, 0x8b, 0x4f, 0xac, 0xa4, 0xe2, 0x76, 0x0c, 0xc9, 0x63, 0x6c, 0x49, 0x58, 0x93, 0xed, 0xcc, 0xaa, 0xdc, 0x25, 0x3b, 0x0a, 0x60, 0x3f, 0x8b, 0x54, 0x3a, 0xc3, 0x4d, 0x31, 0xe7, 0x94, 0xa4, 0x44, 0xfd, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x81, 0x00, 0xc8, 0x62, 0xb9, 0xea, 0xde, 0x44, 0x53, 0x1d, 0x56, 0x97, 0xd9, 0x97, 0x9e, 0x1a, 0xcf, 0x30, 0x1e, 0x0a, 0x88, 0x45, 0x86, 0x29, 0x30, 0xa3, 0x4d, 0x9f, 0x61, 0x65, 0x73, 0xe0, 0xd6, 0x87, 0x8f, 0xb6, 0xf3, 0x06, 0xa3, 0x82, 0xdc, 0x7c, 0xac, 0xfe, 0x9b, 0x28, 0x9a, 0xae, 0xfd, 0xfb, 0xfe, 0x2f, 0x0e, 0xd8, 0x97, 0x04, 0xe3, 0xbb, 0x1f, 0xd1, 0xec, 0x0d, 0xba, 0xa3, 0x49, 0x7f, 0x47, 0xac, 0x8a, 0x44, 0x04, 0x7e, 0x86, 0xb7, 0x39, 0x42, 0x3f, 0xad, 0x1e, 0xb7, 0x0e, 0xa5, 0x51, 0xf4, 0x40, 0x63, 0x1e, 0xfd, 0xbd, 0xea, 0x9f, 0x41, 0x9f, 0xa8, 0x90, 0x1d, 0x6f, 0x0a, 0x5a, 0x95, 0x13, 0x11, 0x0d, 0x80, 0xaf, 0x5f, 0x64, 0x98, 0x8a, 0x2c, 0x78, 0x68, 0x65, 0xb0, 0x2b, 0x8b, 0xa2, 0x53, 0x87, 0xca, 0xf1, 0x64, 0x04, 0xab, 0xf2, 0x7b, 0xdb, 0x83, 0xc8, 0x81, 0x02, 0x41, 0x00, 0xf7, 0xbe, 0x5e, 0x23, 0xc3, 0x32, 0x3f, 0xbf, 0x8b, 0x8e, 0x3a, 0xee, 0xfc, 0xfc, 0xcb, 0xe5, 0xf7, 0xf1, 0x0b, 0xbc, 0x42, 0x82, 0xae, 0xd5, 0x7a, 0x3e, 0xca, 0xf7, 0xd5, 0x69, 0x3f, 0x64, 0x25, 0xa2, 0x1f, 0xb7, 0x75, 0x75, 0x05, 0x92, 0x42, 0xeb, 0xb8, 0xf1, 0xf3, 0x0a, 0x05, 0xe3, 0x94, 0xd1, 0x55, 0x78, 0x35, 0xa0, 0x36, 0xa0, 0x9b, 0x7c, 0x92, 0x84, 0x6c, 0xdd, 0xdc, 0x4d, 0x02, 0x41, 0x00, 0xd6, 0x86, 0x0e, 0x85, 0x42, 0x0b, 0x04, 0x08, 0x84, 0x21, 0x60, 0xf0, 0x0e, 0x0d, 0x88, 0xfd, 0x1e, 0x36, 0x10, 0x65, 0x4f, 0x1e, 0x53, 0xb4, 0x08, 0x72, 0x80, 0x5c, 0x3f, 0x59, 0x66, 0x17, 0xe6, 0x98, 0xf2, 0xe9, 0x6c, 0x7a, 0x06, 0x4c, 0xac, 0x76, 0x3d, 0xed, 0x8c, 0xa1, 0xce, 0xad, 0x1b, 0xbd, 0xb4, 0x7d, 0x28, 0xbc, 0xe3, 0x0e, 0x38, 0x8d, 0x99, 0xd8, 0x05, 0xb5, 0xa3, 0x71, 0x02, 0x40, 0x6d, 0xeb, 0xc3, 0x2d, 0x2e, 0xf0, 0x5e, 0xa4, 0x88, 0x31, 0x05, 0x29, 0x00, 0x8a, 0xd1, 0x95, 0x29, 0x9b, 0x83, 0xcf, 0x75, 0xdb, 0x31, 0xe3, 0x7a, 0x27, 0xde, 0x3a, 0x74, 0x30, 0x0c, 0x76, 0x4c, 0xd4, 0x50, 0x2a, 0x40, 0x2d, 0x39, 0xd9, 0x99, 0x63, 0xa9, 0x5d, 0x80, 0xae, 0x53, 0xca, 0x94, 0x3f, 0x05, 0x23, 0x1e, 0xf8, 0x05, 0x04, 0xe1, 0xb8, 0x35, 0xf2, 0x17, 0xb3, 0xa0, 0x89, 0x02, 0x41, 0x00, 0xab, 0x90, 0x88, 0xfa, 0x60, 0x08, 0x29, 0x50, 0x9a, 0x43, 0x8b, 0xa0, 0x50, 0xcc, 0xd8, 0x5a, 0xfe, 0x97, 0x64, 0x63, 0x71, 0x74, 0x22, 0xa3, 0x20, 0x02, 0x5a, 0xcf, 0xeb, 0xc6, 0x16, 0x95, 0x54, 0xd1, 0xcb, 0xab, 0x8d, 0x1a, 0xc6, 0x00, 0xfa, 0x08, 0x92, 0x9c, 0x71, 0xd5, 0x52, 0x52, 0x35, 0x96, 0x71, 0x4b, 0x8b, 0x92, 0x0c, 0xd0, 0xe9, 0xbf, 0xad, 0x63, 0x0b, 0xa5, 0xe9, 0xb1, 0x02, 0x41, 0x00, 0xdc, 0xcc, 0x27, 0xc8, 0xe4, 0xdc, 0x62, 0x48, 0xd5, 0x9b, 0xaf, 0xf5, 0xab, 0x60, 0xf6, 0x21, 0xfd, 0x53, 0xe2, 0xb7, 0x5d, 0x09, 0xc9, 0x1a, 0xa1, 0x04, 0xa9, 0xfc, 0x61, 0x2c, 0x5d, 0x04, 0x58, 0x3a, 0x5a, 0x39, 0xf1, 0x4a, 0x21, 0x56, 0x67, 0xfd, 0xcc, 0x20, 0xa3, 0x8f, 0x78, 0x18, 0x5a, 0x79, 0x3d, 0x2e, 0x8e, 0x7e, 0x86, 0x0a, 0xe6, 0xa8, 0x33, 0xc1, 0x04, 0x17, 0x4a, 0x9f, }; /*** openssl public RSA key in DER format */ static const unsigned char openssl_public_rsa[] = { 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xcf, 0x9a, 0xde, 0x64, 0x8a, 0xda, 0xc8, 0x33, 0x20, 0xa9, 0xd7, 0x83, 0x31, 0x19, 0x54, 0xb2, 0x9a, 0x85, 0xa7, 0xa1, 0xb7, 0x75, 0x33, 0xb6, 0xa9, 0xac, 0x84, 0x24, 0xb3, 0xde, 0xdb, 0x7d, 0x85, 0x2d, 0x96, 0x65, 0xe5, 0x3f, 0x72, 0x95, 0x24, 0x9f, 0x28, 0x68, 0xca, 0x4f, 0xdb, 0x44, 0x1c, 0x3e, 0x60, 0x12, 0x8a, 0xdd, 0x26, 0xa5, 0xeb, 0xff, 0x0b, 0x5e, 0xd4, 0x88, 0x38, 0x49, 0x2a, 0x6e, 0x5b, 0xbf, 0x12, 0x37, 0x47, 0xbd, 0x05, 0x6b, 0xbc, 0xdb, 0xf3, 0xee, 0xe4, 0x11, 0x8e, 0x41, 0x68, 0x7c, 0x61, 0x13, 0xd7, 0x42, 0xc8, 0x80, 0xbe, 0x36, 0x8f, 0xdc, 0x08, 0x8b, 0x4f, 0xac, 0xa4, 0xe2, 0x76, 0x0c, 0xc9, 0x63, 0x6c, 0x49, 0x58, 0x93, 0xed, 0xcc, 0xaa, 0xdc, 0x25, 0x3b, 0x0a, 0x60, 0x3f, 0x8b, 0x54, 0x3a, 0xc3, 0x4d, 0x31, 0xe7, 0x94, 0xa4, 0x44, 0xfd, 0x02, 0x03, 0x01, 0x00, 0x01, }; /* same key but with extra headers stripped */ static const unsigned char openssl_public_rsa_stripped[] = { 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xcf, 0x9a, 0xde, 0x64, 0x8a, 0xda, 0xc8, 0x33, 0x20, 0xa9, 0xd7, 0x83, 0x31, 0x19, 0x54, 0xb2, 0x9a, 0x85, 0xa7, 0xa1, 0xb7, 0x75, 0x33, 0xb6, 0xa9, 0xac, 0x84, 0x24, 0xb3, 0xde, 0xdb, 0x7d, 0x85, 0x2d, 0x96, 0x65, 0xe5, 0x3f, 0x72, 0x95, 0x24, 0x9f, 0x28, 0x68, 0xca, 0x4f, 0xdb, 0x44, 0x1c, 0x3e, 0x60, 0x12, 0x8a, 0xdd, 0x26, 0xa5, 0xeb, 0xff, 0x0b, 0x5e, 0xd4, 0x88, 0x38, 0x49, 0x2a, 0x6e, 0x5b, 0xbf, 0x12, 0x37, 0x47, 0xbd, 0x05, 0x6b, 0xbc, 0xdb, 0xf3, 0xee, 0xe4, 0x11, 0x8e, 0x41, 0x68, 0x7c, 0x61, 0x13, 0xd7, 0x42, 0xc8, 0x80, 0xbe, 0x36, 0x8f, 0xdc, 0x08, 0x8b, 0x4f, 0xac, 0xa4, 0xe2, 0x76, 0x0c, 0xc9, 0x63, 0x6c, 0x49, 0x58, 0x93, 0xed, 0xcc, 0xaa, 0xdc, 0x25, 0x3b, 0x0a, 0x60, 0x3f, 0x8b, 0x54, 0x3a, 0xc3, 0x4d, 0x31, 0xe7, 0x94, 0xa4, 0x44, 0xfd, 0x02, 0x03, 0x01, 0x00, 0x01, }; static int rsa_compat_test(void) { rsa_key key; unsigned char buf[1024]; unsigned long len; /* try reading the key */ DO(rsa_import(openssl_private_rsa, sizeof(openssl_private_rsa), &key)); /* now try to export private/public and compare */ len = sizeof(buf); DO(rsa_export(buf, &len, PK_PRIVATE, &key)); if (len != sizeof(openssl_private_rsa) || memcmp(buf, openssl_private_rsa, len)) { fprintf(stderr, "RSA private export failed to match OpenSSL output, %lu, %lu\n", len, (unsigned long)sizeof(openssl_private_rsa)); return 1; } len = sizeof(buf); DO(rsa_export(buf, &len, PK_PUBLIC, &key)); if (len != sizeof(openssl_public_rsa_stripped) || memcmp(buf, openssl_public_rsa_stripped, len)) { fprintf(stderr, "RSA(private) public export failed to match OpenSSL output\n"); return 1; } rsa_free(&key); /* try reading the public key */ DO(rsa_import(openssl_public_rsa_stripped, sizeof(openssl_public_rsa_stripped), &key)); len = sizeof(buf); DO(rsa_export(buf, &len, PK_PUBLIC, &key)); if (len != sizeof(openssl_public_rsa_stripped) || memcmp(buf, openssl_public_rsa_stripped, len)) { fprintf(stderr, "RSA(public) stripped public import failed to match OpenSSL output\n"); return 1; } rsa_free(&key); /* try reading the public key */ DO(rsa_import(openssl_public_rsa, sizeof(openssl_public_rsa), &key)); len = sizeof(buf); DO(rsa_export(buf, &len, PK_PUBLIC, &key)); if (len != sizeof(openssl_public_rsa_stripped) || memcmp(buf, openssl_public_rsa_stripped, len)) { fprintf(stderr, "RSA(public) SSL public import failed to match OpenSSL output\n"); return 1; } rsa_free(&key); return 0; } int rsa_test(void) { unsigned char in[1024], out[1024], tmp[1024]; rsa_key key, privKey, pubKey; int hash_idx, prng_idx, stat, stat2; unsigned long rsa_msgsize, len, len2, cnt; static unsigned char lparam[] = { 0x01, 0x02, 0x03, 0x04 }; if (rsa_compat_test() != 0) { return 1; } hash_idx = find_hash("sha1"); prng_idx = find_prng("yarrow"); if (hash_idx == -1 || prng_idx == -1) { fprintf(stderr, "rsa_test requires LTC_SHA1 and yarrow"); return 1; } /* make 10 random key */ for (cnt = 0; cnt < 10; cnt++) { DO(rsa_make_key(&yarrow_prng, prng_idx, 1024/8, 65537, &key)); if (mp_count_bits(key.N) != 1024) { fprintf(stderr, "rsa_1024 key modulus has %d bits\n", mp_count_bits(key.N)); len = mp_unsigned_bin_size(key.N); mp_to_unsigned_bin(key.N, tmp); fprintf(stderr, "N == \n"); for (cnt = 0; cnt < len; ) { fprintf(stderr, "%02x ", tmp[cnt]); if (!(++cnt & 15)) fprintf(stderr, "\n"); } len = mp_unsigned_bin_size(key.p); mp_to_unsigned_bin(key.p, tmp); fprintf(stderr, "p == \n"); for (cnt = 0; cnt < len; ) { fprintf(stderr, "%02x ", tmp[cnt]); if (!(++cnt & 15)) fprintf(stderr, "\n"); } len = mp_unsigned_bin_size(key.q); mp_to_unsigned_bin(key.q, tmp); fprintf(stderr, "\nq == \n"); for (cnt = 0; cnt < len; ) { fprintf(stderr, "%02x ", tmp[cnt]); if (!(++cnt & 15)) fprintf(stderr, "\n"); } fprintf(stderr, "\n"); return 1; } if (cnt != 9) { rsa_free(&key); } } /* encrypt the key (without lparam) */ for (cnt = 0; cnt < 4; cnt++) { for (rsa_msgsize = 1; rsa_msgsize <= 86; rsa_msgsize++) { /* make a random key/msg */ yarrow_read(in, rsa_msgsize, &yarrow_prng); len = sizeof(out); len2 = rsa_msgsize; DO(rsa_encrypt_key(in, rsa_msgsize, out, &len, NULL, 0, &yarrow_prng, prng_idx, hash_idx, &key)); /* change a byte */ out[8] ^= 1; DO(rsa_decrypt_key(out, len, tmp, &len2, NULL, 0, hash_idx, &stat2, &key)); /* change a byte back */ out[8] ^= 1; if (len2 != rsa_msgsize) { fprintf(stderr, "\nrsa_decrypt_key mismatch len %lu (first decrypt)", len2); return 1; } len2 = rsa_msgsize; DO(rsa_decrypt_key(out, len, tmp, &len2, NULL, 0, hash_idx, &stat, &key)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "rsa_decrypt_key failed"); return 1; } if (len2 != rsa_msgsize || memcmp(tmp, in, rsa_msgsize)) { unsigned long x; fprintf(stderr, "\nrsa_decrypt_key mismatch, len %lu (second decrypt)\n", len2); fprintf(stderr, "Original contents: \n"); for (x = 0; x < rsa_msgsize; ) { fprintf(stderr, "%02x ", in[x]); if (!(++x % 16)) { fprintf(stderr, "\n"); } } fprintf(stderr, "\n"); fprintf(stderr, "Output contents: \n"); for (x = 0; x < rsa_msgsize; ) { fprintf(stderr, "%02x ", out[x]); if (!(++x % 16)) { fprintf(stderr, "\n"); } } fprintf(stderr, "\n"); return 1; } } } /* encrypt the key (with lparam) */ for (rsa_msgsize = 1; rsa_msgsize <= 86; rsa_msgsize++) { len = sizeof(out); len2 = rsa_msgsize; DO(rsa_encrypt_key(in, rsa_msgsize, out, &len, lparam, sizeof(lparam), &yarrow_prng, prng_idx, hash_idx, &key)); /* change a byte */ out[8] ^= 1; DO(rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), hash_idx, &stat2, &key)); if (len2 != rsa_msgsize) { fprintf(stderr, "\nrsa_decrypt_key mismatch len %lu (first decrypt)", len2); return 1; } /* change a byte back */ out[8] ^= 1; len2 = rsa_msgsize; DO(rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), hash_idx, &stat, &key)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "rsa_decrypt_key failed"); return 1; } if (len2 != rsa_msgsize || memcmp(tmp, in, rsa_msgsize)) { fprintf(stderr, "rsa_decrypt_key mismatch len %lu", len2); return 1; } } /* encrypt the key LTC_PKCS #1 v1.5 (payload from 1 to 117 bytes) */ for (rsa_msgsize = 1; rsa_msgsize <= 117; rsa_msgsize++) { len = sizeof(out); len2 = rsa_msgsize; DO(rsa_encrypt_key_ex(in, rsa_msgsize, out, &len, NULL, 0, &yarrow_prng, prng_idx, 0, LTC_LTC_PKCS_1_V1_5, &key)); len2 = rsa_msgsize; DO(rsa_decrypt_key_ex(out, len, tmp, &len2, NULL, 0, 0, LTC_LTC_PKCS_1_V1_5, &stat, &key)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "rsa_decrypt_key_ex failed, %d, %d", stat, stat2); return 1; } if (len2 != rsa_msgsize || memcmp(tmp, in, rsa_msgsize)) { fprintf(stderr, "rsa_decrypt_key_ex mismatch len %lu", len2); return 1; } } /* sign a message (unsalted, lower cholestorol and Atkins approved) now */ len = sizeof(out); DO(rsa_sign_hash(in, 20, out, &len, &yarrow_prng, prng_idx, hash_idx, 0, &key)); /* export key and import as both private and public */ len2 = sizeof(tmp); DO(rsa_export(tmp, &len2, PK_PRIVATE, &key)); DO(rsa_import(tmp, len2, &privKey)); len2 = sizeof(tmp); DO(rsa_export(tmp, &len2, PK_PUBLIC, &key)); DO(rsa_import(tmp, len2, &pubKey)); /* verify with original */ DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &key)); /* change a byte */ in[0] ^= 1; DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &key)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "rsa_verify_hash (unsalted, origKey) failed, %d, %d", stat, stat2); rsa_free(&key); rsa_free(&pubKey); rsa_free(&privKey); return 1; } /* verify with privKey */ /* change a byte */ in[0] ^= 1; DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &privKey)); /* change a byte */ in[0] ^= 1; DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &privKey)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "rsa_verify_hash (unsalted, privKey) failed, %d, %d", stat, stat2); rsa_free(&key); rsa_free(&pubKey); rsa_free(&privKey); return 1; } /* verify with pubKey */ /* change a byte */ in[0] ^= 1; DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat, &pubKey)); /* change a byte */ in[0] ^= 1; DO(rsa_verify_hash(out, len, in, 20, hash_idx, 0, &stat2, &pubKey)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "rsa_verify_hash (unsalted, pubkey) failed, %d, %d", stat, stat2); rsa_free(&key); rsa_free(&pubKey); rsa_free(&privKey); return 1; } /* sign a message (salted) now (use privKey to make, pubKey to verify) */ len = sizeof(out); DO(rsa_sign_hash(in, 20, out, &len, &yarrow_prng, prng_idx, hash_idx, 8, &privKey)); DO(rsa_verify_hash(out, len, in, 20, hash_idx, 8, &stat, &pubKey)); /* change a byte */ in[0] ^= 1; DO(rsa_verify_hash(out, len, in, 20, hash_idx, 8, &stat2, &pubKey)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "rsa_verify_hash (salted) failed, %d, %d", stat, stat2); rsa_free(&key); rsa_free(&pubKey); rsa_free(&privKey); return 1; } /* sign a message with LTC_PKCS #1 v1.5 */ len = sizeof(out); DO(rsa_sign_hash_ex(in, 20, out, &len, LTC_LTC_PKCS_1_V1_5, &yarrow_prng, prng_idx, hash_idx, 8, &privKey)); DO(rsa_verify_hash_ex(out, len, in, 20, LTC_LTC_PKCS_1_V1_5, hash_idx, 8, &stat, &pubKey)); /* change a byte */ in[0] ^= 1; DO(rsa_verify_hash_ex(out, len, in, 20, LTC_LTC_PKCS_1_V1_5, hash_idx, 8, &stat2, &pubKey)); if (!(stat == 1 && stat2 == 0)) { fprintf(stderr, "rsa_verify_hash_ex failed, %d, %d", stat, stat2); rsa_free(&key); rsa_free(&pubKey); rsa_free(&privKey); return 1; } /* free the key and return */ rsa_free(&key); rsa_free(&pubKey); rsa_free(&privKey); return 0; } #else int rsa_test(void) { fprintf(stderr, "NOP"); return 0; } #endif /* $Source: /cvs/libtom/libtomcrypt/testprof/rsa_test.c,v $ */ /* $Revision: 1.20 $ */ /* $Date: 2007/05/12 14:32:35 $ */ libtomcrypt-1.17/mess.sh0000644000175100001440000000017210621351501014026 0ustar tomusers#!/bin/bash if cvs log $1 >/dev/null 2>/dev/null; then exit 0; else echo "$1 shouldn't be here, removed"; rm -f $1 ; fi libtomcrypt-1.17/makefile0000644000175100001440000004250010621351501014224 0ustar tomusers# MAKEFILE for linux GCC # # Tom St Denis # Modified by Clay Culver # The version VERSION=1.17 PLATFORM := $(shell uname | sed -e 's/_.*//') # Compiler and Linker Names #CC=gcc #LD=ld # Archiver [makes .a files] #AR=ar #ARFLAGS=r ifndef MAKE MAKE=make endif # ranlib tools ifndef RANLIB ifeq ($(PLATFORM), Darwin) RANLIB=ranlib -c else RANLIB=ranlib endif endif # Compilation flags. Note the += does not write over the user's CFLAGS! CFLAGS += -c -I./testprof/ -I./src/headers/ -Wall -Wsign-compare -W -Wshadow -Wno-unused-parameter -DLTC_SOURCE # additional warnings (newer GCC 3.4 and higher) ifdef GCC_34 CFLAGS += -Wsystem-headers -Wdeclaration-after-statement -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wmissing-prototypes \ -Wmissing-declarations -Wpointer-arith endif ifndef IGNORE_SPEED # optimize for SPEED CFLAGS += -O3 -funroll-loops # add -fomit-frame-pointer. hinders debugging! CFLAGS += -fomit-frame-pointer # optimize for SIZE #CFLAGS += -Os -DLTC_SMALL_CODE endif # older GCCs can't handle the "rotate with immediate" ROLc/RORc/etc macros # define this to help #CFLAGS += -DLTC_NO_ROLC # compile for DEBUGING (required for ccmalloc checking!!!) #CFLAGS += -g3 -DLTC_NO_ASM #Output filenames for various targets. ifndef LIBNAME LIBNAME=libtomcrypt.a endif ifndef LIBTEST LIBTEST=libtomcrypt_prof.a endif LIBTEST_S=$(LIBTEST) HASH=hashsum CRYPT=encrypt SMALL=small PROF=x86_prof TV=tv_gen MULTI=multi TIMING=timing TEST=test #LIBPATH-The directory for libtomcrypt to be installed to. #INCPATH-The directory to install the header files for libtomcrypt. #DATAPATH-The directory to install the pdf docs. ifndef DESTDIR DESTDIR= endif ifndef LIBPATH LIBPATH=/usr/lib endif ifndef INCPATH INCPATH=/usr/include endif ifndef DATAPATH DATAPATH=/usr/share/doc/libtomcrypt/pdf endif #Who do we install as? ifdef INSTALL_USER USER=$(INSTALL_USER) else USER=root endif ifdef INSTALL_GROUP GROUP=$(INSTALL_GROUP) else GROUP=wheel endif #List of objects to compile. #START_INS OBJECTS=src/ciphers/aes/aes_enc.o src/ciphers/aes/aes.o src/ciphers/anubis.o src/ciphers/blowfish.o \ src/ciphers/cast5.o src/ciphers/des.o src/ciphers/kasumi.o src/ciphers/khazad.o src/ciphers/kseed.o \ src/ciphers/multi2.o src/ciphers/noekeon.o src/ciphers/rc2.o src/ciphers/rc5.o src/ciphers/rc6.o \ src/ciphers/safer/safer.o src/ciphers/safer/saferp.o src/ciphers/safer/safer_tab.o \ src/ciphers/skipjack.o src/ciphers/twofish/twofish.o src/ciphers/xtea.o src/encauth/ccm/ccm_memory.o \ src/encauth/ccm/ccm_test.o src/encauth/eax/eax_addheader.o src/encauth/eax/eax_decrypt.o \ src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o \ src/encauth/eax/eax_encrypt_authenticate_memory.o src/encauth/eax/eax_encrypt.o \ src/encauth/eax/eax_init.o src/encauth/eax/eax_test.o src/encauth/gcm/gcm_add_aad.o \ src/encauth/gcm/gcm_add_iv.o src/encauth/gcm/gcm_done.o src/encauth/gcm/gcm_gf_mult.o \ src/encauth/gcm/gcm_init.o src/encauth/gcm/gcm_memory.o src/encauth/gcm/gcm_mult_h.o \ src/encauth/gcm/gcm_process.o src/encauth/gcm/gcm_reset.o src/encauth/gcm/gcm_test.o \ src/encauth/ocb/ocb_decrypt.o src/encauth/ocb/ocb_decrypt_verify_memory.o \ src/encauth/ocb/ocb_done_decrypt.o src/encauth/ocb/ocb_done_encrypt.o \ src/encauth/ocb/ocb_encrypt_authenticate_memory.o src/encauth/ocb/ocb_encrypt.o \ src/encauth/ocb/ocb_init.o src/encauth/ocb/ocb_ntz.o src/encauth/ocb/ocb_shift_xor.o \ src/encauth/ocb/ocb_test.o src/encauth/ocb/s_ocb_done.o src/hashes/chc/chc.o \ src/hashes/helper/hash_file.o src/hashes/helper/hash_filehandle.o src/hashes/helper/hash_memory.o \ src/hashes/helper/hash_memory_multi.o src/hashes/md2.o src/hashes/md4.o src/hashes/md5.o \ src/hashes/rmd128.o src/hashes/rmd160.o src/hashes/rmd256.o src/hashes/rmd320.o src/hashes/sha1.o \ src/hashes/sha2/sha256.o src/hashes/sha2/sha512.o src/hashes/tiger.o src/hashes/whirl/whirl.o \ src/mac/f9/f9_done.o src/mac/f9/f9_file.o src/mac/f9/f9_init.o src/mac/f9/f9_memory.o \ src/mac/f9/f9_memory_multi.o src/mac/f9/f9_process.o src/mac/f9/f9_test.o src/mac/hmac/hmac_done.o \ src/mac/hmac/hmac_file.o src/mac/hmac/hmac_init.o src/mac/hmac/hmac_memory.o \ src/mac/hmac/hmac_memory_multi.o src/mac/hmac/hmac_process.o src/mac/hmac/hmac_test.o \ src/mac/omac/omac_done.o src/mac/omac/omac_file.o src/mac/omac/omac_init.o src/mac/omac/omac_memory.o \ src/mac/omac/omac_memory_multi.o src/mac/omac/omac_process.o src/mac/omac/omac_test.o \ src/mac/pelican/pelican.o src/mac/pelican/pelican_memory.o src/mac/pelican/pelican_test.o \ src/mac/pmac/pmac_done.o src/mac/pmac/pmac_file.o src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \ src/mac/pmac/pmac_memory_multi.o src/mac/pmac/pmac_ntz.o src/mac/pmac/pmac_process.o \ src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/mac/xcbc/xcbc_done.o \ src/mac/xcbc/xcbc_file.o src/mac/xcbc/xcbc_init.o src/mac/xcbc/xcbc_memory.o \ src/mac/xcbc/xcbc_memory_multi.o src/mac/xcbc/xcbc_process.o src/mac/xcbc/xcbc_test.o \ src/math/fp/ltc_ecc_fp_mulmod.o src/math/gmp_desc.o src/math/ltm_desc.o src/math/multi.o \ src/math/rand_prime.o src/math/tfm_desc.o src/misc/base64/base64_decode.o \ src/misc/base64/base64_encode.o src/misc/burn_stack.o src/misc/crypt/crypt_argchk.o \ src/misc/crypt/crypt.o src/misc/crypt/crypt_cipher_descriptor.o src/misc/crypt/crypt_cipher_is_valid.o \ src/misc/crypt/crypt_find_cipher_any.o src/misc/crypt/crypt_find_cipher.o \ src/misc/crypt/crypt_find_cipher_id.o src/misc/crypt/crypt_find_hash_any.o \ src/misc/crypt/crypt_find_hash.o src/misc/crypt/crypt_find_hash_id.o \ src/misc/crypt/crypt_find_hash_oid.o src/misc/crypt/crypt_find_prng.o src/misc/crypt/crypt_fsa.o \ src/misc/crypt/crypt_hash_descriptor.o src/misc/crypt/crypt_hash_is_valid.o \ src/misc/crypt/crypt_ltc_mp_descriptor.o src/misc/crypt/crypt_prng_descriptor.o \ src/misc/crypt/crypt_prng_is_valid.o src/misc/crypt/crypt_register_cipher.o \ src/misc/crypt/crypt_register_hash.o src/misc/crypt/crypt_register_prng.o \ src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o \ src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/pkcs5/pkcs_5_1.o \ src/misc/pkcs5/pkcs_5_2.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o \ src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o src/modes/cbc/cbc_setiv.o \ src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o src/modes/cfb/cfb_done.o \ src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o \ src/modes/cfb/cfb_start.o src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_done.o \ src/modes/ctr/ctr_encrypt.o src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o \ src/modes/ctr/ctr_start.o src/modes/ctr/ctr_test.o src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o \ src/modes/ecb/ecb_encrypt.o src/modes/ecb/ecb_start.o src/modes/f8/f8_decrypt.o src/modes/f8/f8_done.o \ src/modes/f8/f8_encrypt.o src/modes/f8/f8_getiv.o src/modes/f8/f8_setiv.o src/modes/f8/f8_start.o \ src/modes/f8/f8_test_mode.o src/modes/lrw/lrw_decrypt.o src/modes/lrw/lrw_done.o \ src/modes/lrw/lrw_encrypt.o src/modes/lrw/lrw_getiv.o src/modes/lrw/lrw_process.o \ src/modes/lrw/lrw_setiv.o src/modes/lrw/lrw_start.o src/modes/lrw/lrw_test.o \ src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o src/modes/ofb/ofb_encrypt.o \ src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o src/modes/ofb/ofb_start.o \ src/modes/xts/xts_decrypt.o src/modes/xts/xts_done.o src/modes/xts/xts_encrypt.o \ src/modes/xts/xts_init.o src/modes/xts/xts_mult_x.o src/modes/xts/xts_test.o \ src/pk/asn1/der/bit/der_decode_bit_string.o src/pk/asn1/der/bit/der_encode_bit_string.o \ src/pk/asn1/der/bit/der_length_bit_string.o src/pk/asn1/der/boolean/der_decode_boolean.o \ src/pk/asn1/der/boolean/der_encode_boolean.o src/pk/asn1/der/boolean/der_length_boolean.o \ src/pk/asn1/der/choice/der_decode_choice.o src/pk/asn1/der/ia5/der_decode_ia5_string.o \ src/pk/asn1/der/ia5/der_encode_ia5_string.o src/pk/asn1/der/ia5/der_length_ia5_string.o \ src/pk/asn1/der/integer/der_decode_integer.o src/pk/asn1/der/integer/der_encode_integer.o \ src/pk/asn1/der/integer/der_length_integer.o \ src/pk/asn1/der/object_identifier/der_decode_object_identifier.o \ src/pk/asn1/der/object_identifier/der_encode_object_identifier.o \ src/pk/asn1/der/object_identifier/der_length_object_identifier.o \ src/pk/asn1/der/octet/der_decode_octet_string.o src/pk/asn1/der/octet/der_encode_octet_string.o \ src/pk/asn1/der/octet/der_length_octet_string.o \ src/pk/asn1/der/printable_string/der_decode_printable_string.o \ src/pk/asn1/der/printable_string/der_encode_printable_string.o \ src/pk/asn1/der/printable_string/der_length_printable_string.o \ src/pk/asn1/der/sequence/der_decode_sequence_ex.o \ src/pk/asn1/der/sequence/der_decode_sequence_flexi.o \ src/pk/asn1/der/sequence/der_decode_sequence_multi.o \ src/pk/asn1/der/sequence/der_encode_sequence_ex.o \ src/pk/asn1/der/sequence/der_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \ src/pk/asn1/der/sequence/der_sequence_free.o src/pk/asn1/der/set/der_encode_set.o \ src/pk/asn1/der/set/der_encode_setof.o src/pk/asn1/der/short_integer/der_decode_short_integer.o \ src/pk/asn1/der/short_integer/der_encode_short_integer.o \ src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \ src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \ src/pk/asn1/der/utf8/der_decode_utf8_string.o src/pk/asn1/der/utf8/der_encode_utf8_string.o \ src/pk/asn1/der/utf8/der_length_utf8_string.o src/pk/dsa/dsa_decrypt_key.o \ src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o \ src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_shared_secret.o src/pk/dsa/dsa_sign_hash.o \ src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc_ansi_x963_export.o \ src/pk/ecc/ecc_ansi_x963_import.o src/pk/ecc/ecc.o src/pk/ecc/ecc_decrypt_key.o \ src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_free.o src/pk/ecc/ecc_get_size.o \ src/pk/ecc/ecc_import.o src/pk/ecc/ecc_make_key.o src/pk/ecc/ecc_shared_secret.o \ src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_test.o src/pk/ecc/ecc_verify_hash.o \ src/pk/ecc/ltc_ecc_is_valid_idx.o src/pk/ecc/ltc_ecc_map.o src/pk/ecc/ltc_ecc_mul2add.o \ src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \ src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \ src/pk/katja/katja_decrypt_key.o src/pk/katja/katja_encrypt_key.o src/pk/katja/katja_export.o \ src/pk/katja/katja_exptmod.o src/pk/katja/katja_free.o src/pk/katja/katja_import.o \ src/pk/katja/katja_make_key.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \ src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \ src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v1_5_decode.o \ src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \ src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \ src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o \ src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \ src/prngs/sprng.o src/prngs/yarrow.o HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \ src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \ src/headers/tomcrypt_pk.h src/headers/tomcrypt_hash.h src/headers/tomcrypt_math.h \ src/headers/tomcrypt_misc.h src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h \ src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h #END_INS TESTOBJECTS=demos/test.o HASHOBJECTS=demos/hashsum.o CRYPTOBJECTS=demos/encrypt.o SMALLOBJECTS=demos/small.o TVS=demos/tv_gen.o MULTIS=demos/multi.o TIMINGS=demos/timing.o TESTS=demos/test.o #Files left over from making the crypt.pdf. LEFTOVERS=*.dvi *.log *.aux *.toc *.idx *.ilg *.ind *.out #Compressed filenames COMPRESSED=crypt-$(VERSION).tar.bz2 crypt-$(VERSION).zip #The default rule for make builds the libtomcrypt library. default:library #ciphers come in two flavours... enc+dec and enc src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c $(CC) $(CFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes.c -o src/ciphers/aes/aes_enc.o #These are the rules to make certain object files. src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c #This rule makes the libtomcrypt library. library: $(LIBNAME) $(OBJECTS): $(HEADERS) testprof/$(LIBTEST): cd testprof ; CFLAGS="$(CFLAGS)" LIBTEST_S=$(LIBTEST_S) $(MAKE) $(LIBNAME): $(OBJECTS) $(AR) $(ARFLAGS) $@ $(OBJECTS) $(RANLIB) $@ #This rule makes the hash program included with libtomcrypt hashsum: library $(HASHOBJECTS) $(CC) $(HASHOBJECTS) $(LIBNAME) $(EXTRALIBS) -o $(HASH) $(WARN) #makes the crypt program crypt: library $(CRYPTOBJECTS) $(CC) $(CRYPTOBJECTS) $(LIBNAME) $(EXTRALIBS) -o $(CRYPT) $(WARN) #makes the small program small: library $(SMALLOBJECTS) $(CC) $(SMALLOBJECTS) $(LIBNAME) $(EXTRALIBS) -o $(SMALL) $(WARN) tv_gen: library $(TVS) $(CC) $(LDFLAGS) $(TVS) $(LIBNAME) $(EXTRALIBS) -o $(TV) multi: library $(MULTIS) $(CC) $(MULTIS) $(LIBNAME) $(EXTRALIBS) -o $(MULTI) timing: library testprof/$(LIBTEST) $(TIMINGS) $(CC) $(LDFLAGS) $(TIMINGS) testprof/$(LIBTEST) $(LIBNAME) $(EXTRALIBS) -o $(TIMING) test: library testprof/$(LIBTEST) $(TESTS) $(CC) $(LDFLAGS) $(TESTS) testprof/$(LIBTEST) $(LIBNAME) $(EXTRALIBS) -o $(TEST) #This rule installs the library and the header files. This must be run #as root in order to have a high enough permission to write to the correct #directories and to set the owner and group to root. ifndef NODOCS install: library docs else install: library endif install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH) install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(DATAPATH) install -g $(GROUP) -o $(USER) $(LIBNAME) $(DESTDIR)$(LIBPATH) install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH) ifndef NODOCS install -g $(GROUP) -o $(USER) doc/crypt.pdf $(DESTDIR)$(DATAPATH) endif install_test: testprof/$(LIBTEST) install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH) install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) install -g $(GROUP) -o $(USER) testprof/$(LIBTEST) $(DESTDIR)$(LIBPATH) profile: CFLAGS="$(CFLAGS) -fprofile-generate" $(MAKE) timing EXTRALIBS="$(EXTRALIBS) -lgcov" ./timing rm -f timing `find . -type f | grep [.][ao] | xargs` CFLAGS="$(CFLAGS) -fprofile-use" $(MAKE) timing EXTRALIBS="$(EXTRALIBS) -lgcov" #This rule cleans the source tree of all compiled code, not including the pdf #documentation. clean: rm -f `find . -type f | grep "[.]o" | xargs` rm -f `find . -type f | grep "[.]lo" | xargs` rm -f `find . -type f | grep "[.]a" | xargs` rm -f `find . -type f | grep "[.]la" | xargs` rm -f `find . -type f | grep "[.]obj" | xargs` rm -f `find . -type f | grep "[.]lib" | xargs` rm -f `find . -type f | grep "[.]exe" | xargs` rm -f `find . -type f | grep "[.]gcda" | xargs` rm -f `find . -type f | grep "[.]gcno" | xargs` rm -f `find . -type f | grep "[.]il" | xargs` rm -f `find . -type f | grep "[.]dyn" | xargs` rm -f `find . -type f | grep "[.]dpi" | xargs` rm -rf `find . -type d | grep "[.]libs" | xargs` rm -f crypt.aux crypt.dvi crypt.idx crypt.ilg crypt.ind crypt.log crypt.toc rm -f $(TV) $(PROF) $(SMALL) $(CRYPT) $(HASHSUM) $(MULTI) $(TIMING) $(TEST) rm -rf doc/doxygen rm -f doc/*.pdf rm -f *.txt #build the doxy files (requires Doxygen, tetex and patience) doxy: doxygen cd doc/doxygen/latex ; ${MAKE} ; mv -f refman.pdf ../../. echo The huge doxygen PDF should be available as doc/refman.pdf #This builds the crypt.pdf file. Note that the rm -f *.pdf has been removed #from the clean command! This is because most people would like to keep the #nice pre-compiled crypt.pdf that comes with libtomcrypt! We only need to #delete it if we are rebuilding it. docs: crypt.tex rm -f doc/crypt.pdf $(LEFTOVERS) echo "hello" > crypt.ind latex crypt > /dev/null latex crypt > /dev/null makeindex crypt.idx > /dev/null perl fixupind.pl latex crypt > /dev/null dvipdf crypt mv -ivf crypt.pdf doc/crypt.pdf rm -f $(LEFTOVERS) docdvi: crypt.tex echo hello > crypt.ind latex crypt > /dev/null latex crypt > /dev/null makeindex crypt.idx perl fixupind.pl latex crypt > /dev/null latex crypt > /dev/null #zipup the project (take that!) no_oops: clean cd .. ; cvs commit echo Scanning for scratch/dirty files find . -type f | grep -v CVS | xargs -n 1 bash mess.sh zipup: no_oops docs cd .. ; rm -rf crypt* libtomcrypt-$(VERSION) ; mkdir libtomcrypt-$(VERSION) ; \ cp -R ./libtomcrypt/* ./libtomcrypt-$(VERSION)/ ; \ cd libtomcrypt-$(VERSION) ; rm -rf `find . -type d | grep CVS | xargs` ; cd .. ; \ tar -cjvf crypt-$(VERSION).tar.bz2 libtomcrypt-$(VERSION) ; \ zip -9r crypt-$(VERSION).zip libtomcrypt-$(VERSION) ; \ gpg -b -a crypt-$(VERSION).tar.bz2 ; gpg -b -a crypt-$(VERSION).zip ; \ mv -fv crypt* ~ ; rm -rf libtomcrypt-$(VERSION) # $Source: /cvs/libtom/libtomcrypt/makefile,v $ # $Revision: 1.150 $ # $Date: 2007/02/16 16:36:25 $ libtomcrypt-1.17/testbuild.sh0000644000175100001440000000063610621351501015063 0ustar tomusers#!/bin/bash echo "$1 (Build Only, $2, $3)..." make clean 1>/dev/null 2>/dev/null echo -n "building..." touch testok.txt CFLAGS="$2 $CFLAGS $4" EXTRALIBS="$5" make -f $3 test tv_gen 1>gcc_1.txt 2>gcc_2.txt || (echo "build $1 failed see gcc_2.txt for more information" && cat gcc_2.txt && rm -f testok.txt && exit 1) if find testok.txt -type f 1>/dev/null 2>/dev/null ; then echo "successful" exit 0 fi exit 1 libtomcrypt-1.17/genlist.sh0000644000175100001440000000125110621351501014523 0ustar tomusers#!/bin/bash # aes_tab.o is a pseudo object as it's made from aes.o and MPI is optional export a=`echo -n "src/ciphers/aes/aes_enc.o " ; find . -type f | sort | grep "[.]/src" | grep "[.]c" | grep -v "sha224" | grep -v "sha384" | grep -v "aes_tab" | grep -v "twofish_tab" | grep -v "whirltab" | grep -v "dh_sys" | grep -v "ecc_sys" | grep -v "mpi[.]c" | grep -v "sober128tab" | sed -e 'sE\./EE' | sed -e 's/\.c/\.o/' | xargs` perl ./parsenames.pl OBJECTS "$a" export a=`find . -type f | grep [.]/src | grep [.]h | sed -e 'se\./ee' | xargs` perl ./parsenames.pl HEADERS "$a" # $Source: /cvs/libtom/libtomcrypt/genlist.sh,v $ # $Revision: 1.4 $ # $Date: 2005/07/17 23:15:12 $ libtomcrypt-1.17/run.sh0000644000175100001440000000116510621351501013666 0ustar tomusers#!/bin/bash bash build.sh " $1" "$2 -O2" "$3 IGNORE_SPEED=1" "$4" "$5" if [ -a testok.txt ] && [ -f testok.txt ]; then echo else echo echo "Test failed" exit 1 fi rm -f testok.txt bash build.sh " $1" "$2 -Os" " $3 IGNORE_SPEED=1 LTC_SMALL=1" "$4" "$5" if [ -a testok.txt ] && [ -f testok.txt ]; then echo else echo echo "Test failed" exit 1 fi rm -f testok.txt bash build.sh " $1" " $2" " $3 " "$4" "$5" if [ -a testok.txt ] && [ -f testok.txt ]; then echo else echo echo "Test failed" exit 1 fi exit 0 # $Source: /cvs/libtom/libtomcrypt/run.sh,v $ # $Revision: 1.15 $ # $Date: 2005/07/23 14:18:31 $ libtomcrypt-1.17/build.sh0000644000175100001440000000160610621351501014161 0ustar tomusers#!/bin/bash echo "$1 ($2, $3)..." make clean 1>/dev/null 2>/dev/null echo -n "building..." CFLAGS="$2 $CFLAGS $4" EXTRALIBS="$5" make -j4 -f $3 test tv_gen 1>gcc_1.txt 2>gcc_2.txt || (echo "build $1 failed see gcc_2.txt for more information" && cat gcc_2.txt && exit 1) echo -n "testing..." if [ -a test ] && [ -f test ] && [ -x test ]; then ((./test >test_std.txt 2>test_err.txt && ./tv_gen > tv.txt) && echo "$1 test passed." && echo "y" > testok.txt) || (echo "$1 test failed" && cat test_err.txt && exit 1) if find *_tv.txt -type f 1>/dev/null 2>/dev/null ; then for f in *_tv.txt; do if (diff --ignore-case $f notes/$f) then true; else (echo "tv_gen $f failed" && rm -f testok.txt && exit 1); fi; done fi fi if [ -a testok.txt ] && [ -f testok.txt ]; then exit 0 fi exit 1 # $Source: /cvs/libtom/libtomcrypt/build.sh,v $ # $Revision: 1.9 $ # $Date: 2006/03/18 14:10:55 $ libtomcrypt-1.17/makefile.msvc0000644000175100001440000002626510621351501015205 0ustar tomusers#MSVC Makefile [tested with MSVC 6.00 with SP5] # #Tom St Denis CFLAGS = /Isrc/headers/ /Itestprof/ /Ox /DWIN32 /DLTC_SOURCE /W3 /Fo$@ $(CF) #START_INS OBJECTS=src/ciphers/aes/aes_enc.obj src/ciphers/aes/aes.obj src/ciphers/anubis.obj src/ciphers/blowfish.obj \ src/ciphers/cast5.obj src/ciphers/des.obj src/ciphers/kasumi.obj src/ciphers/khazad.obj src/ciphers/kseed.obj \ src/ciphers/multi2.obj src/ciphers/noekeon.obj src/ciphers/rc2.obj src/ciphers/rc5.obj src/ciphers/rc6.obj \ src/ciphers/safer/safer.obj src/ciphers/safer/saferp.obj src/ciphers/safer/safer_tab.obj \ src/ciphers/skipjack.obj src/ciphers/twofish/twofish.obj src/ciphers/xtea.obj src/encauth/ccm/ccm_memory.obj \ src/encauth/ccm/ccm_test.obj src/encauth/eax/eax_addheader.obj src/encauth/eax/eax_decrypt.obj \ src/encauth/eax/eax_decrypt_verify_memory.obj src/encauth/eax/eax_done.obj \ src/encauth/eax/eax_encrypt_authenticate_memory.obj src/encauth/eax/eax_encrypt.obj \ src/encauth/eax/eax_init.obj src/encauth/eax/eax_test.obj src/encauth/gcm/gcm_add_aad.obj \ src/encauth/gcm/gcm_add_iv.obj src/encauth/gcm/gcm_done.obj src/encauth/gcm/gcm_gf_mult.obj \ src/encauth/gcm/gcm_init.obj src/encauth/gcm/gcm_memory.obj src/encauth/gcm/gcm_mult_h.obj \ src/encauth/gcm/gcm_process.obj src/encauth/gcm/gcm_reset.obj src/encauth/gcm/gcm_test.obj \ src/encauth/ocb/ocb_decrypt.obj src/encauth/ocb/ocb_decrypt_verify_memory.obj \ src/encauth/ocb/ocb_done_decrypt.obj src/encauth/ocb/ocb_done_encrypt.obj \ src/encauth/ocb/ocb_encrypt_authenticate_memory.obj src/encauth/ocb/ocb_encrypt.obj \ src/encauth/ocb/ocb_init.obj src/encauth/ocb/ocb_ntz.obj src/encauth/ocb/ocb_shift_xor.obj \ src/encauth/ocb/ocb_test.obj src/encauth/ocb/s_ocb_done.obj src/hashes/chc/chc.obj \ src/hashes/helper/hash_file.obj src/hashes/helper/hash_filehandle.obj src/hashes/helper/hash_memory.obj \ src/hashes/helper/hash_memory_multi.obj src/hashes/md2.obj src/hashes/md4.obj src/hashes/md5.obj \ src/hashes/rmd128.obj src/hashes/rmd160.obj src/hashes/rmd256.obj src/hashes/rmd320.obj src/hashes/sha1.obj \ src/hashes/sha2/sha256.obj src/hashes/sha2/sha512.obj src/hashes/tiger.obj src/hashes/whirl/whirl.obj \ src/mac/f9/f9_done.obj src/mac/f9/f9_file.obj src/mac/f9/f9_init.obj src/mac/f9/f9_memory.obj \ src/mac/f9/f9_memory_multi.obj src/mac/f9/f9_process.obj src/mac/f9/f9_test.obj src/mac/hmac/hmac_done.obj \ src/mac/hmac/hmac_file.obj src/mac/hmac/hmac_init.obj src/mac/hmac/hmac_memory.obj \ src/mac/hmac/hmac_memory_multi.obj src/mac/hmac/hmac_process.obj src/mac/hmac/hmac_test.obj \ src/mac/omac/omac_done.obj src/mac/omac/omac_file.obj src/mac/omac/omac_init.obj src/mac/omac/omac_memory.obj \ src/mac/omac/omac_memory_multi.obj src/mac/omac/omac_process.obj src/mac/omac/omac_test.obj \ src/mac/pelican/pelican.obj src/mac/pelican/pelican_memory.obj src/mac/pelican/pelican_test.obj \ src/mac/pmac/pmac_done.obj src/mac/pmac/pmac_file.obj src/mac/pmac/pmac_init.obj src/mac/pmac/pmac_memory.obj \ src/mac/pmac/pmac_memory_multi.obj src/mac/pmac/pmac_ntz.obj src/mac/pmac/pmac_process.obj \ src/mac/pmac/pmac_shift_xor.obj src/mac/pmac/pmac_test.obj src/mac/xcbc/xcbc_done.obj \ src/mac/xcbc/xcbc_file.obj src/mac/xcbc/xcbc_init.obj src/mac/xcbc/xcbc_memory.obj \ src/mac/xcbc/xcbc_memory_multi.obj src/mac/xcbc/xcbc_process.obj src/mac/xcbc/xcbc_test.obj \ src/math/fp/ltc_ecc_fp_mulmod.obj src/math/gmp_desc.obj src/math/ltm_desc.obj src/math/multi.obj \ src/math/rand_prime.obj src/math/tfm_desc.obj src/misc/base64/base64_decode.obj \ src/misc/base64/base64_encode.obj src/misc/burn_stack.obj src/misc/crypt/crypt_argchk.obj \ src/misc/crypt/crypt.obj src/misc/crypt/crypt_cipher_descriptor.obj src/misc/crypt/crypt_cipher_is_valid.obj \ src/misc/crypt/crypt_find_cipher_any.obj src/misc/crypt/crypt_find_cipher.obj \ src/misc/crypt/crypt_find_cipher_id.obj src/misc/crypt/crypt_find_hash_any.obj \ src/misc/crypt/crypt_find_hash.obj src/misc/crypt/crypt_find_hash_id.obj \ src/misc/crypt/crypt_find_hash_oid.obj src/misc/crypt/crypt_find_prng.obj src/misc/crypt/crypt_fsa.obj \ src/misc/crypt/crypt_hash_descriptor.obj src/misc/crypt/crypt_hash_is_valid.obj \ src/misc/crypt/crypt_ltc_mp_descriptor.obj src/misc/crypt/crypt_prng_descriptor.obj \ src/misc/crypt/crypt_prng_is_valid.obj src/misc/crypt/crypt_register_cipher.obj \ src/misc/crypt/crypt_register_hash.obj src/misc/crypt/crypt_register_prng.obj \ src/misc/crypt/crypt_unregister_cipher.obj src/misc/crypt/crypt_unregister_hash.obj \ src/misc/crypt/crypt_unregister_prng.obj src/misc/error_to_string.obj src/misc/pkcs5/pkcs_5_1.obj \ src/misc/pkcs5/pkcs_5_2.obj src/misc/zeromem.obj src/modes/cbc/cbc_decrypt.obj src/modes/cbc/cbc_done.obj \ src/modes/cbc/cbc_encrypt.obj src/modes/cbc/cbc_getiv.obj src/modes/cbc/cbc_setiv.obj \ src/modes/cbc/cbc_start.obj src/modes/cfb/cfb_decrypt.obj src/modes/cfb/cfb_done.obj \ src/modes/cfb/cfb_encrypt.obj src/modes/cfb/cfb_getiv.obj src/modes/cfb/cfb_setiv.obj \ src/modes/cfb/cfb_start.obj src/modes/ctr/ctr_decrypt.obj src/modes/ctr/ctr_done.obj \ src/modes/ctr/ctr_encrypt.obj src/modes/ctr/ctr_getiv.obj src/modes/ctr/ctr_setiv.obj \ src/modes/ctr/ctr_start.obj src/modes/ctr/ctr_test.obj src/modes/ecb/ecb_decrypt.obj src/modes/ecb/ecb_done.obj \ src/modes/ecb/ecb_encrypt.obj src/modes/ecb/ecb_start.obj src/modes/f8/f8_decrypt.obj src/modes/f8/f8_done.obj \ src/modes/f8/f8_encrypt.obj src/modes/f8/f8_getiv.obj src/modes/f8/f8_setiv.obj src/modes/f8/f8_start.obj \ src/modes/f8/f8_test_mode.obj src/modes/lrw/lrw_decrypt.obj src/modes/lrw/lrw_done.obj \ src/modes/lrw/lrw_encrypt.obj src/modes/lrw/lrw_getiv.obj src/modes/lrw/lrw_process.obj \ src/modes/lrw/lrw_setiv.obj src/modes/lrw/lrw_start.obj src/modes/lrw/lrw_test.obj \ src/modes/ofb/ofb_decrypt.obj src/modes/ofb/ofb_done.obj src/modes/ofb/ofb_encrypt.obj \ src/modes/ofb/ofb_getiv.obj src/modes/ofb/ofb_setiv.obj src/modes/ofb/ofb_start.obj \ src/modes/xts/xts_decrypt.obj src/modes/xts/xts_done.obj src/modes/xts/xts_encrypt.obj \ src/modes/xts/xts_init.obj src/modes/xts/xts_mult_x.obj src/modes/xts/xts_test.obj \ src/pk/asn1/der/bit/der_decode_bit_string.obj src/pk/asn1/der/bit/der_encode_bit_string.obj \ src/pk/asn1/der/bit/der_length_bit_string.obj src/pk/asn1/der/boolean/der_decode_boolean.obj \ src/pk/asn1/der/boolean/der_encode_boolean.obj src/pk/asn1/der/boolean/der_length_boolean.obj \ src/pk/asn1/der/choice/der_decode_choice.obj src/pk/asn1/der/ia5/der_decode_ia5_string.obj \ src/pk/asn1/der/ia5/der_encode_ia5_string.obj src/pk/asn1/der/ia5/der_length_ia5_string.obj \ src/pk/asn1/der/integer/der_decode_integer.obj src/pk/asn1/der/integer/der_encode_integer.obj \ src/pk/asn1/der/integer/der_length_integer.obj \ src/pk/asn1/der/object_identifier/der_decode_object_identifier.obj \ src/pk/asn1/der/object_identifier/der_encode_object_identifier.obj \ src/pk/asn1/der/object_identifier/der_length_object_identifier.obj \ src/pk/asn1/der/octet/der_decode_octet_string.obj src/pk/asn1/der/octet/der_encode_octet_string.obj \ src/pk/asn1/der/octet/der_length_octet_string.obj \ src/pk/asn1/der/printable_string/der_decode_printable_string.obj \ src/pk/asn1/der/printable_string/der_encode_printable_string.obj \ src/pk/asn1/der/printable_string/der_length_printable_string.obj \ src/pk/asn1/der/sequence/der_decode_sequence_ex.obj \ src/pk/asn1/der/sequence/der_decode_sequence_flexi.obj \ src/pk/asn1/der/sequence/der_decode_sequence_multi.obj \ src/pk/asn1/der/sequence/der_encode_sequence_ex.obj \ src/pk/asn1/der/sequence/der_encode_sequence_multi.obj src/pk/asn1/der/sequence/der_length_sequence.obj \ src/pk/asn1/der/sequence/der_sequence_free.obj src/pk/asn1/der/set/der_encode_set.obj \ src/pk/asn1/der/set/der_encode_setof.obj src/pk/asn1/der/short_integer/der_decode_short_integer.obj \ src/pk/asn1/der/short_integer/der_encode_short_integer.obj \ src/pk/asn1/der/short_integer/der_length_short_integer.obj src/pk/asn1/der/utctime/der_decode_utctime.obj \ src/pk/asn1/der/utctime/der_encode_utctime.obj src/pk/asn1/der/utctime/der_length_utctime.obj \ src/pk/asn1/der/utf8/der_decode_utf8_string.obj src/pk/asn1/der/utf8/der_encode_utf8_string.obj \ src/pk/asn1/der/utf8/der_length_utf8_string.obj src/pk/dsa/dsa_decrypt_key.obj \ src/pk/dsa/dsa_encrypt_key.obj src/pk/dsa/dsa_export.obj src/pk/dsa/dsa_free.obj src/pk/dsa/dsa_import.obj \ src/pk/dsa/dsa_make_key.obj src/pk/dsa/dsa_shared_secret.obj src/pk/dsa/dsa_sign_hash.obj \ src/pk/dsa/dsa_verify_hash.obj src/pk/dsa/dsa_verify_key.obj src/pk/ecc/ecc_ansi_x963_export.obj \ src/pk/ecc/ecc_ansi_x963_import.obj src/pk/ecc/ecc.obj src/pk/ecc/ecc_decrypt_key.obj \ src/pk/ecc/ecc_encrypt_key.obj src/pk/ecc/ecc_export.obj src/pk/ecc/ecc_free.obj src/pk/ecc/ecc_get_size.obj \ src/pk/ecc/ecc_import.obj src/pk/ecc/ecc_make_key.obj src/pk/ecc/ecc_shared_secret.obj \ src/pk/ecc/ecc_sign_hash.obj src/pk/ecc/ecc_sizes.obj src/pk/ecc/ecc_test.obj src/pk/ecc/ecc_verify_hash.obj \ src/pk/ecc/ltc_ecc_is_valid_idx.obj src/pk/ecc/ltc_ecc_map.obj src/pk/ecc/ltc_ecc_mul2add.obj \ src/pk/ecc/ltc_ecc_mulmod.obj src/pk/ecc/ltc_ecc_mulmod_timing.obj src/pk/ecc/ltc_ecc_points.obj \ src/pk/ecc/ltc_ecc_projective_add_point.obj src/pk/ecc/ltc_ecc_projective_dbl_point.obj \ src/pk/katja/katja_decrypt_key.obj src/pk/katja/katja_encrypt_key.obj src/pk/katja/katja_export.obj \ src/pk/katja/katja_exptmod.obj src/pk/katja/katja_free.obj src/pk/katja/katja_import.obj \ src/pk/katja/katja_make_key.obj src/pk/pkcs1/pkcs_1_i2osp.obj src/pk/pkcs1/pkcs_1_mgf1.obj \ src/pk/pkcs1/pkcs_1_oaep_decode.obj src/pk/pkcs1/pkcs_1_oaep_encode.obj src/pk/pkcs1/pkcs_1_os2ip.obj \ src/pk/pkcs1/pkcs_1_pss_decode.obj src/pk/pkcs1/pkcs_1_pss_encode.obj src/pk/pkcs1/pkcs_1_v1_5_decode.obj \ src/pk/pkcs1/pkcs_1_v1_5_encode.obj src/pk/rsa/rsa_decrypt_key.obj src/pk/rsa/rsa_encrypt_key.obj \ src/pk/rsa/rsa_export.obj src/pk/rsa/rsa_exptmod.obj src/pk/rsa/rsa_free.obj src/pk/rsa/rsa_import.obj \ src/pk/rsa/rsa_make_key.obj src/pk/rsa/rsa_sign_hash.obj src/pk/rsa/rsa_verify_hash.obj src/prngs/fortuna.obj \ src/prngs/rc4.obj src/prngs/rng_get_bytes.obj src/prngs/rng_make_prng.obj src/prngs/sober128.obj \ src/prngs/sprng.obj src/prngs/yarrow.obj HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \ src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \ src/headers/tomcrypt_pk.h src/headers/tomcrypt_hash.h src/headers/tomcrypt_math.h \ src/headers/tomcrypt_misc.h src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h \ src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h #END_INS default: library #ciphers come in two flavours... enc+dec and enc src/ciphers/aes/aes_enc.obj: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c $(CC) $(CFLAGS) /DENCRYPT_ONLY /c src/ciphers/aes/aes.c /Fosrc/ciphers/aes/aes_enc.obj library: $(OBJECTS) lib /out:tomcrypt.lib $(OBJECTS) cd testprof nmake -f makefile.msvc cd .. tv_gen: demos/tv_gen.c library cl $(CFLAGS) demos/tv_gen.c tomcrypt.lib advapi32.lib $(EXTRALIBS) hashsum: demos/hashsum.c library cl $(CFLAGS) demos/hashsum.c tomcrypt.lib advapi32.lib $(EXTRALIBS) test: demos/test.c library cl $(CFLAGS) demos/test.c testprof/tomcrypt_prof.lib tomcrypt.lib advapi32.lib $(EXTRALIBS) timing: demos/timing.c library cl $(CFLAGS) demos/timing.c testprof/tomcrypt_prof.lib tomcrypt.lib advapi32.lib $(EXTRALIBS) # $Source: /cvs/libtom/libtomcrypt/makefile.msvc,v $ # $Revision: 1.54 $ # $Date: 2007/02/16 16:36:25 $ libtomcrypt-1.17/makefile.unix0000644000175100001440000003245310621351501015214 0ustar tomusers# MAKEFILE for bsd make # # Tom St Denis # Compiler and Linker Names CC=cc LD=ld # Archiver [makes .a files] AR=ar ARFLAGS=r # Compilation flags. Note the += does not write over the user's CFLAGS! CFLAGS = -c -I./testprof/ -I./src/headers/ -DLTC_SOURCE -O2 ${CFLAGS_OPTS} -o $@ LIBNAME=libtomcrypt.a LIBTEST=libtomcrypt_prof.a LIBTEST_S=$(LIBTEST) HASH=hashsum CRYPT=encrypt SMALL=small PROF=x86_prof TV=tv_gen MULTI=multi TIMING=timing TEST=test #LIBPATH-The directory for libtomcrypt to be installed to. #INCPATH-The directory to install the header files for libtomcrypt. #DATAPATH-The directory to install the pdf docs. LIBPATH=/usr/local/lib INCPATH=/usr/local/include DATAPATH=/usr/local/share/doc/libtomcrypt/pdf #Who do we install as? USER=root GROUP=wheel #List of objects to compile. #START_INS OBJECTS=src/ciphers/aes/aes_enc.o src/ciphers/aes/aes.o src/ciphers/anubis.o src/ciphers/blowfish.o \ src/ciphers/cast5.o src/ciphers/des.o src/ciphers/kasumi.o src/ciphers/khazad.o src/ciphers/kseed.o \ src/ciphers/multi2.o src/ciphers/noekeon.o src/ciphers/rc2.o src/ciphers/rc5.o src/ciphers/rc6.o \ src/ciphers/safer/safer.o src/ciphers/safer/saferp.o src/ciphers/safer/safer_tab.o \ src/ciphers/skipjack.o src/ciphers/twofish/twofish.o src/ciphers/xtea.o src/encauth/ccm/ccm_memory.o \ src/encauth/ccm/ccm_test.o src/encauth/eax/eax_addheader.o src/encauth/eax/eax_decrypt.o \ src/encauth/eax/eax_decrypt_verify_memory.o src/encauth/eax/eax_done.o \ src/encauth/eax/eax_encrypt_authenticate_memory.o src/encauth/eax/eax_encrypt.o \ src/encauth/eax/eax_init.o src/encauth/eax/eax_test.o src/encauth/gcm/gcm_add_aad.o \ src/encauth/gcm/gcm_add_iv.o src/encauth/gcm/gcm_done.o src/encauth/gcm/gcm_gf_mult.o \ src/encauth/gcm/gcm_init.o src/encauth/gcm/gcm_memory.o src/encauth/gcm/gcm_mult_h.o \ src/encauth/gcm/gcm_process.o src/encauth/gcm/gcm_reset.o src/encauth/gcm/gcm_test.o \ src/encauth/ocb/ocb_decrypt.o src/encauth/ocb/ocb_decrypt_verify_memory.o \ src/encauth/ocb/ocb_done_decrypt.o src/encauth/ocb/ocb_done_encrypt.o \ src/encauth/ocb/ocb_encrypt_authenticate_memory.o src/encauth/ocb/ocb_encrypt.o \ src/encauth/ocb/ocb_init.o src/encauth/ocb/ocb_ntz.o src/encauth/ocb/ocb_shift_xor.o \ src/encauth/ocb/ocb_test.o src/encauth/ocb/s_ocb_done.o src/hashes/chc/chc.o \ src/hashes/helper/hash_file.o src/hashes/helper/hash_filehandle.o src/hashes/helper/hash_memory.o \ src/hashes/helper/hash_memory_multi.o src/hashes/md2.o src/hashes/md4.o src/hashes/md5.o \ src/hashes/rmd128.o src/hashes/rmd160.o src/hashes/rmd256.o src/hashes/rmd320.o src/hashes/sha1.o \ src/hashes/sha2/sha256.o src/hashes/sha2/sha512.o src/hashes/tiger.o src/hashes/whirl/whirl.o \ src/mac/f9/f9_done.o src/mac/f9/f9_file.o src/mac/f9/f9_init.o src/mac/f9/f9_memory.o \ src/mac/f9/f9_memory_multi.o src/mac/f9/f9_process.o src/mac/f9/f9_test.o src/mac/hmac/hmac_done.o \ src/mac/hmac/hmac_file.o src/mac/hmac/hmac_init.o src/mac/hmac/hmac_memory.o \ src/mac/hmac/hmac_memory_multi.o src/mac/hmac/hmac_process.o src/mac/hmac/hmac_test.o \ src/mac/omac/omac_done.o src/mac/omac/omac_file.o src/mac/omac/omac_init.o src/mac/omac/omac_memory.o \ src/mac/omac/omac_memory_multi.o src/mac/omac/omac_process.o src/mac/omac/omac_test.o \ src/mac/pelican/pelican.o src/mac/pelican/pelican_memory.o src/mac/pelican/pelican_test.o \ src/mac/pmac/pmac_done.o src/mac/pmac/pmac_file.o src/mac/pmac/pmac_init.o src/mac/pmac/pmac_memory.o \ src/mac/pmac/pmac_memory_multi.o src/mac/pmac/pmac_ntz.o src/mac/pmac/pmac_process.o \ src/mac/pmac/pmac_shift_xor.o src/mac/pmac/pmac_test.o src/mac/xcbc/xcbc_done.o \ src/mac/xcbc/xcbc_file.o src/mac/xcbc/xcbc_init.o src/mac/xcbc/xcbc_memory.o \ src/mac/xcbc/xcbc_memory_multi.o src/mac/xcbc/xcbc_process.o src/mac/xcbc/xcbc_test.o \ src/math/fp/ltc_ecc_fp_mulmod.o src/math/gmp_desc.o src/math/ltm_desc.o src/math/multi.o \ src/math/rand_prime.o src/math/tfm_desc.o src/misc/base64/base64_decode.o \ src/misc/base64/base64_encode.o src/misc/burn_stack.o src/misc/crypt/crypt_argchk.o \ src/misc/crypt/crypt.o src/misc/crypt/crypt_cipher_descriptor.o src/misc/crypt/crypt_cipher_is_valid.o \ src/misc/crypt/crypt_find_cipher_any.o src/misc/crypt/crypt_find_cipher.o \ src/misc/crypt/crypt_find_cipher_id.o src/misc/crypt/crypt_find_hash_any.o \ src/misc/crypt/crypt_find_hash.o src/misc/crypt/crypt_find_hash_id.o \ src/misc/crypt/crypt_find_hash_oid.o src/misc/crypt/crypt_find_prng.o src/misc/crypt/crypt_fsa.o \ src/misc/crypt/crypt_hash_descriptor.o src/misc/crypt/crypt_hash_is_valid.o \ src/misc/crypt/crypt_ltc_mp_descriptor.o src/misc/crypt/crypt_prng_descriptor.o \ src/misc/crypt/crypt_prng_is_valid.o src/misc/crypt/crypt_register_cipher.o \ src/misc/crypt/crypt_register_hash.o src/misc/crypt/crypt_register_prng.o \ src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o \ src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/pkcs5/pkcs_5_1.o \ src/misc/pkcs5/pkcs_5_2.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o \ src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o src/modes/cbc/cbc_setiv.o \ src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o src/modes/cfb/cfb_done.o \ src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o \ src/modes/cfb/cfb_start.o src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_done.o \ src/modes/ctr/ctr_encrypt.o src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o \ src/modes/ctr/ctr_start.o src/modes/ctr/ctr_test.o src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o \ src/modes/ecb/ecb_encrypt.o src/modes/ecb/ecb_start.o src/modes/f8/f8_decrypt.o src/modes/f8/f8_done.o \ src/modes/f8/f8_encrypt.o src/modes/f8/f8_getiv.o src/modes/f8/f8_setiv.o src/modes/f8/f8_start.o \ src/modes/f8/f8_test_mode.o src/modes/lrw/lrw_decrypt.o src/modes/lrw/lrw_done.o \ src/modes/lrw/lrw_encrypt.o src/modes/lrw/lrw_getiv.o src/modes/lrw/lrw_process.o \ src/modes/lrw/lrw_setiv.o src/modes/lrw/lrw_start.o src/modes/lrw/lrw_test.o \ src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o src/modes/ofb/ofb_encrypt.o \ src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o src/modes/ofb/ofb_start.o \ src/modes/xts/xts_decrypt.o src/modes/xts/xts_done.o src/modes/xts/xts_encrypt.o \ src/modes/xts/xts_init.o src/modes/xts/xts_mult_x.o src/modes/xts/xts_test.o \ src/pk/asn1/der/bit/der_decode_bit_string.o src/pk/asn1/der/bit/der_encode_bit_string.o \ src/pk/asn1/der/bit/der_length_bit_string.o src/pk/asn1/der/boolean/der_decode_boolean.o \ src/pk/asn1/der/boolean/der_encode_boolean.o src/pk/asn1/der/boolean/der_length_boolean.o \ src/pk/asn1/der/choice/der_decode_choice.o src/pk/asn1/der/ia5/der_decode_ia5_string.o \ src/pk/asn1/der/ia5/der_encode_ia5_string.o src/pk/asn1/der/ia5/der_length_ia5_string.o \ src/pk/asn1/der/integer/der_decode_integer.o src/pk/asn1/der/integer/der_encode_integer.o \ src/pk/asn1/der/integer/der_length_integer.o \ src/pk/asn1/der/object_identifier/der_decode_object_identifier.o \ src/pk/asn1/der/object_identifier/der_encode_object_identifier.o \ src/pk/asn1/der/object_identifier/der_length_object_identifier.o \ src/pk/asn1/der/octet/der_decode_octet_string.o src/pk/asn1/der/octet/der_encode_octet_string.o \ src/pk/asn1/der/octet/der_length_octet_string.o \ src/pk/asn1/der/printable_string/der_decode_printable_string.o \ src/pk/asn1/der/printable_string/der_encode_printable_string.o \ src/pk/asn1/der/printable_string/der_length_printable_string.o \ src/pk/asn1/der/sequence/der_decode_sequence_ex.o \ src/pk/asn1/der/sequence/der_decode_sequence_flexi.o \ src/pk/asn1/der/sequence/der_decode_sequence_multi.o \ src/pk/asn1/der/sequence/der_encode_sequence_ex.o \ src/pk/asn1/der/sequence/der_encode_sequence_multi.o src/pk/asn1/der/sequence/der_length_sequence.o \ src/pk/asn1/der/sequence/der_sequence_free.o src/pk/asn1/der/set/der_encode_set.o \ src/pk/asn1/der/set/der_encode_setof.o src/pk/asn1/der/short_integer/der_decode_short_integer.o \ src/pk/asn1/der/short_integer/der_encode_short_integer.o \ src/pk/asn1/der/short_integer/der_length_short_integer.o src/pk/asn1/der/utctime/der_decode_utctime.o \ src/pk/asn1/der/utctime/der_encode_utctime.o src/pk/asn1/der/utctime/der_length_utctime.o \ src/pk/asn1/der/utf8/der_decode_utf8_string.o src/pk/asn1/der/utf8/der_encode_utf8_string.o \ src/pk/asn1/der/utf8/der_length_utf8_string.o src/pk/dsa/dsa_decrypt_key.o \ src/pk/dsa/dsa_encrypt_key.o src/pk/dsa/dsa_export.o src/pk/dsa/dsa_free.o src/pk/dsa/dsa_import.o \ src/pk/dsa/dsa_make_key.o src/pk/dsa/dsa_shared_secret.o src/pk/dsa/dsa_sign_hash.o \ src/pk/dsa/dsa_verify_hash.o src/pk/dsa/dsa_verify_key.o src/pk/ecc/ecc_ansi_x963_export.o \ src/pk/ecc/ecc_ansi_x963_import.o src/pk/ecc/ecc.o src/pk/ecc/ecc_decrypt_key.o \ src/pk/ecc/ecc_encrypt_key.o src/pk/ecc/ecc_export.o src/pk/ecc/ecc_free.o src/pk/ecc/ecc_get_size.o \ src/pk/ecc/ecc_import.o src/pk/ecc/ecc_make_key.o src/pk/ecc/ecc_shared_secret.o \ src/pk/ecc/ecc_sign_hash.o src/pk/ecc/ecc_sizes.o src/pk/ecc/ecc_test.o src/pk/ecc/ecc_verify_hash.o \ src/pk/ecc/ltc_ecc_is_valid_idx.o src/pk/ecc/ltc_ecc_map.o src/pk/ecc/ltc_ecc_mul2add.o \ src/pk/ecc/ltc_ecc_mulmod.o src/pk/ecc/ltc_ecc_mulmod_timing.o src/pk/ecc/ltc_ecc_points.o \ src/pk/ecc/ltc_ecc_projective_add_point.o src/pk/ecc/ltc_ecc_projective_dbl_point.o \ src/pk/katja/katja_decrypt_key.o src/pk/katja/katja_encrypt_key.o src/pk/katja/katja_export.o \ src/pk/katja/katja_exptmod.o src/pk/katja/katja_free.o src/pk/katja/katja_import.o \ src/pk/katja/katja_make_key.o src/pk/pkcs1/pkcs_1_i2osp.o src/pk/pkcs1/pkcs_1_mgf1.o \ src/pk/pkcs1/pkcs_1_oaep_decode.o src/pk/pkcs1/pkcs_1_oaep_encode.o src/pk/pkcs1/pkcs_1_os2ip.o \ src/pk/pkcs1/pkcs_1_pss_decode.o src/pk/pkcs1/pkcs_1_pss_encode.o src/pk/pkcs1/pkcs_1_v1_5_decode.o \ src/pk/pkcs1/pkcs_1_v1_5_encode.o src/pk/rsa/rsa_decrypt_key.o src/pk/rsa/rsa_encrypt_key.o \ src/pk/rsa/rsa_export.o src/pk/rsa/rsa_exptmod.o src/pk/rsa/rsa_free.o src/pk/rsa/rsa_import.o \ src/pk/rsa/rsa_make_key.o src/pk/rsa/rsa_sign_hash.o src/pk/rsa/rsa_verify_hash.o src/prngs/fortuna.o \ src/prngs/rc4.o src/prngs/rng_get_bytes.o src/prngs/rng_make_prng.o src/prngs/sober128.o \ src/prngs/sprng.o src/prngs/yarrow.o HEADERS=src/headers/tomcrypt_cfg.h src/headers/tomcrypt_mac.h src/headers/tomcrypt_macros.h \ src/headers/tomcrypt_custom.h src/headers/tomcrypt_argchk.h src/headers/tomcrypt_cipher.h \ src/headers/tomcrypt_pk.h src/headers/tomcrypt_hash.h src/headers/tomcrypt_math.h \ src/headers/tomcrypt_misc.h src/headers/tomcrypt.h src/headers/tomcrypt_pkcs.h \ src/headers/tomcrypt_prng.h testprof/tomcrypt_test.h #END_INS TESTOBJECTS=demos/test.o HASHOBJECTS=demos/hashsum.o CRYPTOBJECTS=demos/encrypt.o SMALLOBJECTS=demos/small.o TVS=demos/tv_gen.o MULTIS=demos/multi.o TIMINGS=demos/timing.o TESTS=demos/test.o #Files left over from making the crypt.pdf. LEFTOVERS=*.dvi *.log *.aux *.toc *.idx *.ilg *.ind *.out #Compressed filenames COMPRESSED=crypt-$(VERSION).tar.bz2 crypt-$(VERSION).zip #The default rule for make builds the libtomcrypt library. default:library #ciphers come in two flavours... enc+dec and enc src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c $(CC) $(CFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes.c -o src/ciphers/aes/aes_enc.o #These are the rules to make certain object files. src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c src/ciphers/twofish/twofish.o: src/ciphers/twofish/twofish.c src/ciphers/twofish/twofish_tab.c src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c src/hashes/sha2/sha512.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha384.c src/hashes/sha2/sha256.o: src/hashes/sha2/sha256.c src/hashes/sha2/sha224.c #This rule makes the libtomcrypt library. library: $(LIBNAME) testprof/$(LIBTEST): cd testprof ; CFLAGS="$(CFLAGS)" LIBTEST_S=$(LIBTEST_S) $(MAKE) $(LIBNAME): $(OBJECTS) $(AR) $(ARFLAGS) $@ $(OBJECTS) $(RANLIB) $@ #This rule makes the hash program included with libtomcrypt hashsum: library $(HASHOBJECTS) $(CC) $(HASHOBJECTS) $(LIBNAME) $(EXTRALIBS) -o $(HASH) $(WARN) #makes the crypt program crypt: library $(CRYPTOBJECTS) $(CC) $(CRYPTOBJECTS) $(LIBNAME) $(EXTRALIBS) -o $(CRYPT) $(WARN) #makes the small program small: library $(SMALLOBJECTS) $(CC) $(SMALLOBJECTS) $(LIBNAME) $(EXTRALIBS) -o $(SMALL) $(WARN) tv_gen: library $(TVS) $(CC) $(LDFLAGS) $(TVS) $(LIBNAME) $(EXTRALIBS) -o $(TV) multi: library $(MULTIS) $(CC) $(MULTIS) $(LIBNAME) $(EXTRALIBS) -o $(MULTI) timing: library testprof/$(LIBTEST) $(TIMINGS) $(CC) $(LDFLAGS) $(TIMINGS) testprof/$(LIBTEST) $(LIBNAME) $(EXTRALIBS) -o $(TIMING) test: library testprof/$(LIBTEST) $(TESTS) $(CC) $(LDFLAGS) $(TESTS) testprof/$(LIBTEST) $(LIBNAME) $(EXTRALIBS) -o $(TEST) #This rule installs the library and the header files. This must be run #as root in order to have a high enough permission to write to the correct #directories and to set the owner and group to root. install: library install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH) install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(DATAPATH) install -g $(GROUP) -o $(USER) $(LIBNAME) $(DESTDIR)$(LIBPATH) install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH) install_test: testprof/$(LIBTEST) install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH) install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH) install -g $(GROUP) -o $(USER) testprof/$(LIBTEST) $(DESTDIR)$(LIBPATH) # $Source: /cvs/libtom/libtomcrypt/makefile.unix,v $ # $Revision: 1.7 $ # $Date: 2007/02/16 16:36:25 $ libtomcrypt-1.17/crypt.lof0000644000175100001440000000232110621351501014364 0ustar tomusers\addvspace {10\p@ } \addvspace {10\p@ } \contentsline {figure}{\numberline {2.1}{\ignorespaces Load And Store Macros}}{9}{figure.2.1} \contentsline {figure}{\numberline {2.2}{\ignorespaces Rotate Macros}}{9}{figure.2.2} \addvspace {10\p@ } \contentsline {figure}{\numberline {3.1}{\ignorespaces Built--In Software Ciphers}}{19}{figure.3.1} \contentsline {figure}{\numberline {3.2}{\ignorespaces Twofish Build Options}}{21}{figure.3.2} \addvspace {10\p@ } \contentsline {figure}{\numberline {4.1}{\ignorespaces Built--In Software Hashes}}{59}{figure.4.1} \addvspace {10\p@ } \addvspace {10\p@ } \contentsline {figure}{\numberline {6.1}{\ignorespaces List of Provided PRNGs}}{84}{figure.6.1} \addvspace {10\p@ } \addvspace {10\p@ } \addvspace {10\p@ } \contentsline {figure}{\numberline {9.1}{\ignorespaces DSA Key Sizes}}{121}{figure.9.1} \addvspace {10\p@ } \contentsline {figure}{\numberline {10.1}{\ignorespaces List of ASN.1 Supported Types}}{129}{figure.10.1} \addvspace {10\p@ } \addvspace {10\p@ } \contentsline {figure}{\numberline {12.1}{\ignorespaces RSA/DH Key Strength}}{151}{figure.12.1} \contentsline {figure}{\numberline {12.2}{\ignorespaces ECC Key Strength}}{151}{figure.12.2} \addvspace {10\p@ } \addvspace {10\p@ } libtomcrypt-1.17/crypt.tex0000644000175100001440000110515010621351501014411 0ustar tomusers\documentclass[synpaper]{book} \usepackage[dvips]{geometry} \usepackage{hyperref} \usepackage{makeidx} \usepackage{amssymb} \usepackage{color} \usepackage{alltt} \usepackage{graphicx} \usepackage{layout} \usepackage{fancyhdr} \def\union{\cup} \def\intersect{\cap} \def\getsrandom{\stackrel{\rm R}{\gets}} \def\cross{\times} \def\cat{\hspace{0.5em} \| \hspace{0.5em}} \def\catn{$\|$} \def\divides{\hspace{0.3em} | \hspace{0.3em}} \def\nequiv{\not\equiv} \def\approx{\raisebox{0.2ex}{\mbox{\small $\sim$}}} \def\lcm{{\rm lcm}} \def\gcd{{\rm gcd}} \def\log{{\rm log}} \def\ord{{\rm ord}} \def\abs{{\mathit abs}} \def\rep{{\mathit rep}} \def\mod{{\mathit\ mod\ }} \renewcommand{\pmod}[1]{\ ({\rm mod\ }{#1})} \newcommand{\floor}[1]{\left\lfloor{#1}\right\rfloor} \newcommand{\ceil}[1]{\left\lceil{#1}\right\rceil} \def\Or{{\rm\ or\ }} \def\And{{\rm\ and\ }} \def\iff{\hspace{1em}\Longleftrightarrow\hspace{1em}} \def\implies{\Rightarrow} \def\undefined{{\rm \textit{undefined}}} \def\Proof{\vspace{1ex}\noindent {\bf Proof:}\hspace{1em}} \let\oldphi\phi \def\phi{\varphi} \def\Pr{{\rm Pr}} \newcommand{\str}[1]{{\mathbf{#1}}} \def\F{{\mathbb F}} \def\N{{\mathbb N}} \def\Z{{\mathbb Z}} \def\R{{\mathbb R}} \def\C{{\mathbb C}} \def\Q{{\mathbb Q}} \definecolor{DGray}{gray}{0.5} \newcommand{\emailaddr}[1]{\mbox{$<${#1}$>$}} \def\twiddle{\raisebox{0.3ex}{\mbox{\tiny $\sim$}}} \def\gap{\vspace{0.5ex}} \makeindex \newcommand{\mysection}[1] % Re-define the chaptering command to use { % THESE headers. \section{#1} \markboth{\textsf{www.libtom.org}}{\thesection ~ {#1}} } \newcommand{\mystarsection}[1] % Re-define the chaptering command to use { % THESE headers. \section*{#1} \markboth{\textsf{www.libtom.org}}{{#1}} } \pagestyle{empty} \begin{document} \frontmatter \pagestyle{empty} ~ \vspace{2in} ~ \begin{center} \begin{Huge}LibTomCrypt\end{Huge} ~ \begin{large}Developer Manual\end{large} ~ \vspace{15mm} \begin{tabular}{c} Tom St Denis \\ LibTom Projects \end{tabular} \end{center} \vfil \newpage This document is part of the LibTomCrypt package and is hereby released into the public domain. ~ Open Source. Open Academia. Open Minds. ~ \begin{flushright} Tom St Denis ~ Ottawa, Ontario ~ Canada ~ \vfil \end{flushright} \newpage \tableofcontents \listoffigures \pagestyle{myheadings} \mainmatter \chapter{Introduction} \mysection{What is the LibTomCrypt?} LibTomCrypt is a portable ISO C cryptographic library meant to be a tool set for cryptographers who are designing cryptosystems. It supports symmetric ciphers, one-way hashes, pseudo-random number generators, public key cryptography (via PKCS \#1 RSA, DH or ECCDH), and a plethora of support routines. The library was designed such that new ciphers/hashes/PRNGs can be added at run-time and the existing API (and helper API functions) are able to use the new designs automatically. There exists self-check functions for each block cipher and hash function to ensure that they compile and execute to the published design specifications. The library also performs extensive parameter error checking to prevent any number of run-time exploits or errors. \subsection{What the library IS for?} The library serves as a toolkit for developers who have to solve cryptographic problems. Out of the box LibTomCrypt does not process SSL or OpenPGP messages, it doesn't read X.509 certificates, or write PEM encoded data. It does, however, provide all of the tools required to build such functionality. LibTomCrypt was designed to be a flexible library that was not tied to any particular cryptographic problem. \mysection{Why did I write it?} You may be wondering, \textit{Tom, why did you write a crypto library. I already have one.} Well the reason falls into two categories: \begin{enumerate} \item I am too lazy to figure out someone else's API. I'd rather invent my own simpler API and use that. \item It was (still is) good coding practice. \end{enumerate} The idea is that I am not striving to replace OpenSSL or Crypto++ or Cryptlib or etc. I'm trying to write my {\bf own} crypto library and hopefully along the way others will appreciate the work. With this library all core functions (ciphers, hashes, prngs, and bignum) have the same prototype definition. They all load and store data in a format independent of the platform. This means if you encrypt with Blowfish on a PPC it should decrypt on an x86 with zero problems. The consistent API also means that if you learn how to use Blowfish with the library you know how to use Safer+, RC6, or Serpent as well. With all of the core functions there are central descriptor tables that can be used to make a program automatically pick between ciphers, hashes and PRNGs at run-time. That means your application can support all ciphers/hashes/prngs/bignum without changing the source code. Not only did I strive to make a consistent and simple API to work with but I also attempted to make the library configurable in terms of its build options. Out of the box the library will build with any modern version of GCC without having to use configure scripts. This means that the library will work with platforms where development tools may be limited (e.g. no autoconf). On top of making the build simple and the API approachable I've also attempted for a reasonably high level of robustness and efficiency. LibTomCrypt traps and returns a series of errors ranging from invalid arguments to buffer overflows/overruns. It is mostly thread safe and has been clocked on various platforms with \textit{cycles per byte} timings that are comparable (and often favourable) to other libraries such as OpenSSL and Crypto++. \subsection{Modular} The LibTomCrypt package has also been written to be very modular. The block ciphers, one--way hashes, pseudo--random number generators (PRNG), and bignum math routines are all used within the API through \textit{descriptor} tables which are essentially structures with pointers to functions. While you can still call particular functions directly (\textit{e.g. sha256\_process()}) this descriptor interface allows the developer to customize their usage of the library. For example, consider a hardware platform with a specialized RNG device. Obviously one would like to tap that for the PRNG needs within the library (\textit{e.g. making a RSA key}). All the developer has to do is write a descriptor and the few support routines required for the device. After that the rest of the API can make use of it without change. Similarly imagine a few years down the road when AES2 (\textit{or whatever they call it}) has been invented. It can be added to the library and used within applications with zero modifications to the end applications provided they are written properly. This flexibility within the library means it can be used with any combination of primitive algorithms and unlike libraries like OpenSSL is not tied to direct routines. For instance, in OpenSSL there are CBC block mode routines for every single cipher. That means every time you add or remove a cipher from the library you have to update the associated support code as well. In LibTomCrypt the associated code (\textit{chaining modes in this case}) are not directly tied to the ciphers. That is a new cipher can be added to the library by simply providing the key setup, ECB decrypt and encrypt and test vector routines. After that all five chaining mode routines can make use of the cipher right away. \mysection{License} The project is hereby released as public domain. \mysection{Patent Disclosure} The author (Tom St Denis) is not a patent lawyer so this section is not to be treated as legal advice. To the best of the author's knowledge the only patent related issues within the library are the RC5 and RC6 symmetric block ciphers. They can be removed from a build by simply commenting out the two appropriate lines in \textit{tomcrypt\_custom.h}. The rest of the ciphers and hashes are patent free or under patents that have since expired. The RC2 and RC4 symmetric ciphers are not under patents but are under trademark regulations. This means you can use the ciphers you just can't advertise that you are doing so. \mysection{Thanks} I would like to give thanks to the following people (in no particular order) for helping me develop this project from early on: \begin{enumerate} \item Richard van de Laarschot \item Richard Heathfield \item Ajay K. Agrawal \item Brian Gladman \item Svante Seleborg \item Clay Culver \item Jason Klapste \item Dobes Vandermeer \item Daniel Richards \item Wayne Scott \item Andrew Tyler \item Sky Schulz \item Christopher Imes \end{enumerate} There have been quite a few other people as well. Please check the change log to see who else has contributed from time to time. \chapter{The Application Programming Interface (API)} \mysection{Introduction} \index{CRYPT\_ERROR} \index{CRYPT\_OK} In general the API is very simple to memorize and use. Most of the functions return either {\bf void} or {\bf int}. Functions that return {\bf int} will return {\bf CRYPT\_OK} if the function was successful, or one of the many error codes if it failed. Certain functions that return int will return $-1$ to indicate an error. These functions will be explicitly commented upon. When a function does return a CRYPT error code it can be translated into a string with \index{error\_to\_string()} \begin{verbatim} const char *error_to_string(int err); \end{verbatim} An example of handling an error is: \begin{small} \begin{verbatim} void somefunc(void) { int err; /* call a cryptographic function */ if ((err = some_crypto_function(...)) != CRYPT_OK) { printf("A crypto error occurred, %s\n", error_to_string(err)); /* perform error handling */ } /* continue on if no error occurred */ } \end{verbatim} \end{small} There is no initialization routine for the library and for the most part the code is thread safe. The only thread related issue is if you use the same symmetric cipher, hash or public key state data in multiple threads. Normally that is not an issue. To include the prototypes for \textit{LibTomCrypt.a} into your own program simply include \textit{tomcrypt.h} like so: \begin{small} \begin{verbatim} #include int main(void) { return 0; } \end{verbatim} \end{small} The header file \textit{tomcrypt.h} also includes \textit{stdio.h}, \textit{string.h}, \textit{stdlib.h}, \textit{time.h} and \textit{ctype.h}. \mysection{Macros} There are a few helper macros to make the coding process a bit easier. The first set are related to loading and storing 32/64-bit words in little/big endian format. The macros are: \index{STORE32L} \index{STORE64L} \index{LOAD32L} \index{LOAD64L} \index{STORE32H} \index{STORE64H} \index{LOAD32H} \index{LOAD64H} \index{BSWAP} \newpage \begin{figure}[hpbt] \begin{small} \begin{center} \begin{tabular}{|c|c|c|} \hline STORE32L(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $x \to y[0 \ldots 3]$ \\ \hline STORE64L(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $x \to y[0 \ldots 7]$ \\ \hline LOAD32L(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $y[0 \ldots 3] \to x$ \\ \hline LOAD64L(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $y[0 \ldots 7] \to x$ \\ \hline STORE32H(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $x \to y[3 \ldots 0]$ \\ \hline STORE64H(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $x \to y[7 \ldots 0]$ \\ \hline LOAD32H(x, y) & {\bf unsigned long} x, {\bf unsigned char} *y & $y[3 \ldots 0] \to x$ \\ \hline LOAD64H(x, y) & {\bf unsigned long long} x, {\bf unsigned char} *y & $y[7 \ldots 0] \to x$ \\ \hline BSWAP(x) & {\bf unsigned long} x & Swap bytes \\ \hline \end{tabular} \caption{Load And Store Macros} \end{center} \end{small} \end{figure} There are 32 and 64-bit cyclic rotations as well: \index{ROL} \index{ROR} \index{ROL64} \index{ROR64} \index{ROLc} \index{RORc} \index{ROL64c} \index{ROR64c} \begin{figure}[hpbt] \begin{small} \begin{center} \begin{tabular}{|c|c|c|} \hline ROL(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x << y, 0 \le y \le 31$ \\ \hline ROLc(x, y) & {\bf unsigned long} x, {\bf const unsigned long} y & $x << y, 0 \le y \le 31$ \\ \hline ROR(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x >> y, 0 \le y \le 31$ \\ \hline RORc(x, y) & {\bf unsigned long} x, {\bf const unsigned long} y & $x >> y, 0 \le y \le 31$ \\ \hline && \\ \hline ROL64(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x << y, 0 \le y \le 63$ \\ \hline ROL64c(x, y) & {\bf unsigned long} x, {\bf const unsigned long} y & $x << y, 0 \le y \le 63$ \\ \hline ROR64(x, y) & {\bf unsigned long} x, {\bf unsigned long} y & $x >> y, 0 \le y \le 63$ \\ \hline ROR64c(x, y) & {\bf unsigned long} x, {\bf const unsigned long} y & $x >> y, 0 \le y \le 63$ \\ \hline \end{tabular} \caption{Rotate Macros} \end{center} \end{small} \end{figure} \mysection{Functions with Variable Length Output} Certain functions such as (for example) \textit{rsa\_export()} give an output that is variable length. To prevent buffer overflows you must pass it the length of the buffer where the output will be stored. For example: \index{rsa\_export()} \index{error\_to\_string()} \index{variable length output} \begin{small} \begin{verbatim} #include int main(void) { rsa_key key; unsigned char buffer[1024]; unsigned long x; int err; /* ... Make up the RSA key somehow ... */ /* lets export the key, set x to the size of the * output buffer */ x = sizeof(buffer); if ((err = rsa_export(buffer, &x, PK_PUBLIC, &key)) != CRYPT_OK) { printf("Export error: %s\n", error_to_string(err)); return -1; } /* if rsa_export() was successful then x will have * the size of the output */ printf("RSA exported key takes %d bytes\n", x); /* ... do something with the buffer */ return 0; } \end{verbatim} \end{small} In the above example if the size of the RSA public key was more than 1024 bytes this function would return an error code indicating a buffer overflow would have occurred. If the function succeeds, it stores the length of the output back into \textit{x} so that the calling application will know how many bytes were used. As of v1.13, most functions will update your length on failure to indicate the size required by the function. Not all functions support this so please check the source before you rely on it doing that. \mysection{Functions that need a PRNG} \index{Pseudo Random Number Generator} \index{PRNG} Certain functions such as \textit{rsa\_make\_key()} require a Pseudo Random Number Generator (PRNG). These functions do not setup the PRNG themselves so it is the responsibility of the calling function to initialize the PRNG before calling them. Certain PRNG algorithms do not require a \textit{prng\_state} argument (sprng for example). The \textit{prng\_state} argument may be passed as \textbf{NULL} in such situations. \index{register\_prng()} \index{rsa\_make\_key()} \begin{small} \begin{verbatim} #include int main(void) { rsa_key key; int err; /* register the system RNG */ register_prng(&sprng_desc) /* make a 1024-bit RSA key with the system RNG */ if ((err = rsa_make_key(NULL, find_prng("sprng"), 1024/8, 65537, &key)) != CRYPT_OK) { printf("make_key error: %s\n", error_to_string(err)); return -1; } /* use the key ... */ return 0; } \end{verbatim} \end{small} \mysection{Functions that use Arrays of Octets} Most functions require inputs that are arrays of the data type \textit{unsigned char}. Whether it is a symmetric key, IV for a chaining mode or public key packet it is assumed that regardless of the actual size of \textit{unsigned char} only the lower eight bits contain data. For example, if you want to pass a 256 bit key to a symmetric ciphers setup routine, you must pass in (a pointer to) an array of 32 \textit{unsigned char} variables. Certain routines (such as SAFER+) take special care to work properly on platforms where an \textit{unsigned char} is not eight bits. For the purposes of this library, the term \textit{byte} will refer to an octet or eight bit word. Typically an array of type \textit{byte} will be synonymous with an array of type \textit{unsigned char.} \chapter{Symmetric Block Ciphers} \mysection{Core Functions} LibTomCrypt provides several block ciphers with an ECB block mode interface. It is important to first note that you should never use the ECB modes directly to encrypt data. Instead you should use the ECB functions to make a chaining mode, or use one of the provided chaining modes. All of the ciphers are written as ECB interfaces since it allows the rest of the API to grow in a modular fashion. \subsection{Key Scheduling} All ciphers store their scheduled keys in a single data type called \textit{symmetric\_key}. This allows all ciphers to have the same prototype and store their keys as naturally as possible. This also removes the need for dynamic memory allocation, and allows you to allocate a fixed sized buffer for storing scheduled keys. All ciphers must provide six visible functions which are (given that XXX is the name of the cipher) the following: \index{Cipher Setup} \begin{verbatim} int XXX_setup(const unsigned char *key, int keylen, int rounds, symmetric_key *skey); \end{verbatim} The XXX\_setup() routine will setup the cipher to be used with a given number of rounds and a given key length (in bytes). The number of rounds can be set to zero to use the default, which is generally a good idea. If the function returns successfully the variable \textit{skey} will have a scheduled key stored in it. It's important to note that you should only used this scheduled key with the intended cipher. For example, if you call \textit{blowfish\_setup()} do not pass the scheduled key onto \textit{rc5\_ecb\_encrypt()}. All built--in setup functions do not allocate memory off the heap so when you are done with a key you can simply discard it (e.g. they can be on the stack). However, to maintain proper coding practices you should always call the respective XXX\_done() function. This allows for quicker porting to applications with externally supplied plugins. \subsection{ECB Encryption and Decryption} To encrypt or decrypt a block in ECB mode there are these two functions per cipher: \index{Cipher Encrypt} \index{Cipher Decrypt} \begin{verbatim} int XXX_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int XXX_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); \end{verbatim} These two functions will encrypt or decrypt (respectively) a single block of text\footnote{The size of which depends on which cipher you are using.}, storing the result in the \textit{ct} buffer (\textit{pt} resp.). It is possible that the input and output buffer are the same buffer. For the encrypt function \textit{pt}\footnote{pt stands for plaintext.} is the input and \textit{ct}\footnote{ct stands for ciphertext.} is the output. For the decryption function it's the opposite. They both return \textbf{CRYPT\_OK} on success. To test a particular cipher against test vectors\footnote{As published in their design papers.} call the following self-test function. \subsection{Self--Testing} \index{Cipher Testing} \begin{verbatim} int XXX_test(void); \end{verbatim} This function will return {\bf CRYPT\_OK} if the cipher matches the test vectors from the design publication it is based upon. \subsection{Key Sizing} For each cipher there is a function which will help find a desired key size. It is specified as follows: \index{Key Sizing} \begin{verbatim} int XXX_keysize(int *keysize); \end{verbatim} Essentially, it will round the input keysize in \textit{keysize} down to the next appropriate key size. This function will return {\bf CRYPT\_OK} if the key size specified is acceptable. For example: \begin{small} \begin{verbatim} #include int main(void) { int keysize, err; /* now given a 20 byte key what keysize does Twofish want to use? */ keysize = 20; if ((err = twofish_keysize(&keysize)) != CRYPT_OK) { printf("Error getting key size: %s\n", error_to_string(err)); return -1; } printf("Twofish suggested a key size of %d\n", keysize); return 0; } \end{verbatim} \end{small} This should indicate a keysize of sixteen bytes is suggested by storing 16 in \textit{keysize.} \subsection{Cipher Termination} When you are finished with a cipher you can de--initialize it with the done function. \begin{verbatim} void XXX_done(symmetric_key *skey); \end{verbatim} For the software based ciphers within LibTomCrypt, these functions will not do anything. However, user supplied cipher descriptors may require to be called for resource management purposes. To be compliant, all functions which call a cipher setup function must also call the respective cipher done function when finished. \subsection{Simple Encryption Demonstration} An example snippet that encodes a block with Blowfish in ECB mode. \index{blowfish\_setup()} \index{blowfish\_ecb\_encrypt()} \index{blowfish\_ecb\_decrypt()} \index{blowfish\_done()} \begin{small} \begin{verbatim} #include int main(void) { unsigned char pt[8], ct[8], key[8]; symmetric_key skey; int err; /* ... key is loaded appropriately in key ... */ /* ... load a block of plaintext in pt ... */ /* schedule the key */ if ((err = blowfish_setup(key, /* the key we will use */ 8, /* key is 8 bytes (64-bits) long */ 0, /* 0 == use default # of rounds */ &skey) /* where to put the scheduled key */ ) != CRYPT_OK) { printf("Setup error: %s\n", error_to_string(err)); return -1; } /* encrypt the block */ blowfish_ecb_encrypt(pt, /* encrypt this 8-byte array */ ct, /* store encrypted data here */ &skey); /* our previously scheduled key */ /* now ct holds the encrypted version of pt */ /* decrypt the block */ blowfish_ecb_decrypt(ct, /* decrypt this 8-byte array */ pt, /* store decrypted data here */ &skey); /* our previously scheduled key */ /* now we have decrypted ct to the original plaintext in pt */ /* Terminate the cipher context */ blowfish_done(&skey); return 0; } \end{verbatim} \end{small} \mysection{Key Sizes and Number of Rounds} \index{Symmetric Keys} As a general rule of thumb, do not use symmetric keys under 80 bits if you can help it. Only a few of the ciphers support smaller keys (mainly for test vectors anyways). Ideally, your application should be making at least 256 bit keys. This is not because you are to be paranoid. It is because if your PRNG has a bias of any sort the more bits the better. For example, if you have $\mbox{Pr}\left[X = 1\right] = {1 \over 2} \pm \gamma$ where $\vert \gamma \vert > 0$ then the total amount of entropy in N bits is $N \cdot -log_2\left ({1 \over 2} + \vert \gamma \vert \right)$. So if $\gamma$ were $0.25$ (a severe bias) a 256-bit string would have about 106 bits of entropy whereas a 128-bit string would have only 53 bits of entropy. The number of rounds of most ciphers is not an option you can change. Only RC5 allows you to change the number of rounds. By passing zero as the number of rounds all ciphers will use their default number of rounds. Generally the ciphers are configured such that the default number of rounds provide adequate security for the given block and key size. \mysection{The Cipher Descriptors} \index{Cipher Descriptor} To facilitate automatic routines an array of cipher descriptors is provided in the array \textit{cipher\_descriptor}. An element of this array has the following (partial) format (See Section \ref{sec:cipherdesc}): \begin{small} \begin{verbatim} struct _cipher_descriptor { /** name of cipher */ char *name; /** internal ID */ unsigned char ID; /** min keysize (octets) */ int min_key_length, /** max keysize (octets) */ max_key_length, /** block size (octets) */ block_length, /** default number of rounds */ default_rounds; ...... }; \end{verbatim} \end{small} Where \textit{name} is the lower case ASCII version of the name. The fields \textit{min\_key\_length} and \textit{max\_key\_length} are the minimum and maximum key sizes in bytes. The \textit{block\_length} member is the block size of the cipher in bytes. As a good rule of thumb it is assumed that the cipher supports the min and max key lengths but not always everything in between. The \textit{default\_rounds} field is the default number of rounds that will be used. For a plugin to be compliant it must provide at least each function listed before the accelerators begin. Accelerators are optional, and if missing will be emulated in software. The remaining fields are all pointers to the core functions for each cipher. The end of the cipher\_descriptor array is marked when \textit{name} equals {\bf NULL}. As of this release the current cipher\_descriptors elements are the following: \vfil \index{Cipher descriptor table} \index{blowfish\_desc} \index{xtea\_desc} \index{rc2\_desc} \index{rc5\_desc} \index{rc6\_desc} \index{saferp\_desc} \index{aes\_desc} \index{twofish\_desc} \index{des\_desc} \index{des3\_desc} \index{noekeon\_desc} \index{skipjack\_desc} \index{anubis\_desc} \index{khazad\_desc} \index{kseed\_desc} \index{kasumi\_desc} \begin{figure}[hpbt] \begin{small} \begin{center} \begin{tabular}{|c|c|c|c|c|c|} \hline \textbf{Name} & \textbf{Descriptor Name} & \textbf{Block Size} & \textbf{Key Range} & \textbf{Rounds} \\ \hline Blowfish & blowfish\_desc & 8 & 8 $\ldots$ 56 & 16 \\ \hline X-Tea & xtea\_desc & 8 & 16 & 32 \\ \hline RC2 & rc2\_desc & 8 & 8 $\ldots$ 128 & 16 \\ \hline RC5-32/12/b & rc5\_desc & 8 & 8 $\ldots$ 128 & 12 $\ldots$ 24 \\ \hline RC6-32/20/b & rc6\_desc & 16 & 8 $\ldots$ 128 & 20 \\ \hline SAFER+ & saferp\_desc &16 & 16, 24, 32 & 8, 12, 16 \\ \hline AES & aes\_desc & 16 & 16, 24, 32 & 10, 12, 14 \\ & aes\_enc\_desc & 16 & 16, 24, 32 & 10, 12, 14 \\ \hline Twofish & twofish\_desc & 16 & 16, 24, 32 & 16 \\ \hline DES & des\_desc & 8 & 8 & 16 \\ \hline 3DES (EDE mode) & des3\_desc & 8 & 24 & 16 \\ \hline CAST5 (CAST-128) & cast5\_desc & 8 & 5 $\ldots$ 16 & 12, 16 \\ \hline Noekeon & noekeon\_desc & 16 & 16 & 16 \\ \hline Skipjack & skipjack\_desc & 8 & 10 & 32 \\ \hline Anubis & anubis\_desc & 16 & 16 $\ldots$ 40 & 12 $\ldots$ 18 \\ \hline Khazad & khazad\_desc & 8 & 16 & 8 \\ \hline SEED & kseed\_desc & 16 & 16 & 16 \\ \hline KASUMI & kasumi\_desc & 8 & 16 & 8 \\ \hline \end{tabular} \end{center} \end{small} \caption{Built--In Software Ciphers} \end{figure} \subsection{Notes} \begin{small} \begin{enumerate} \item For AES, (also known as Rijndael) there are four descriptors which complicate issues a little. The descriptors rijndael\_desc and rijndael\_enc\_desc provide the cipher named \textit{rijndael}. The descriptors aes\_desc and aes\_enc\_desc provide the cipher name \textit{aes}. Functionally both \textit{rijndael} and \textit{aes} are the same cipher. The only difference is when you call find\_cipher() you have to pass the correct name. The cipher descriptors with \textit{enc} in the middle (e.g. rijndael\_enc\_desc) are related to an implementation of Rijndael with only the encryption routine and tables. The decryption and self--test function pointers of both \textit{encrypt only} descriptors are set to \textbf{NULL} and should not be called. The \textit{encrypt only} descriptors are useful for applications that only use the encryption function of the cipher. Algorithms such as EAX, PMAC and OMAC only require the encryption function. So far this \textit{encrypt only} functionality has only been implemented for Rijndael as it makes the most sense for this cipher. \item Note that for \textit{DES} and \textit{3DES} they use 8 and 24 byte keys but only 7 and 21 [respectively] bytes of the keys are in fact used for the purposes of encryption. My suggestion is just to use random 8/24 byte keys instead of trying to make a 8/24 byte string from the real 7/21 byte key. \item Note that \textit{Twofish} has additional configuration options (Figure \ref{fig:twofishopts}) that take place at build time. These options are found in the file \textit{tomcrypt\_cfg.h}. The first option is \textit{TWOFISH\_SMALL} which when defined will force the Twofish code to not pre-compute the Twofish \textit{$g(X)$} function as a set of four $8 \times 32$ s-boxes. This means that a scheduled key will require less ram but the resulting cipher will be slower. The second option is \textit{TWOFISH\_TABLES} which when defined will force the Twofish code to use pre-computed tables for the two s-boxes $q_0, q_1$ as well as the multiplication by the polynomials 5B and EF used in the MDS multiplication. As a result the code is faster and slightly larger. The speed increase is useful when \textit{TWOFISH\_SMALL} is defined since the s-boxes and MDS multiply form the heart of the Twofish round function. \begin{figure}[hpbt] \index{Twofish build options} \index{TWOFISH\_SMALL} \index{TWOFISH\_TABLES} \begin{small} \begin{center} \begin{tabular}{|l|l|l|} \hline \textbf{TWOFISH\_SMALL} & \textbf{TWOFISH\_TABLES} & \textbf{Speed and Memory (per key)} \\ \hline undefined & undefined & Very fast, 4.2KB of ram. \\ \hline undefined & defined & Faster key setup, larger code. \\ \hline defined & undefined & Very slow, 0.2KB of ram. \\ \hline defined & defined & Faster, 0.2KB of ram, larger code. \\ \hline \end{tabular} \end{center} \end{small} \caption{Twofish Build Options} \label{fig:twofishopts} \end{figure} \end{enumerate} \end{small} To work with the cipher\_descriptor array there is a function: \index{find\_cipher()} \begin{verbatim} int find_cipher(char *name) \end{verbatim} Which will search for a given name in the array. It returns $-1$ if the cipher is not found, otherwise it returns the location in the array where the cipher was found. For example, to indirectly setup Blowfish you can also use: \begin{small} \index{register\_cipher()} \index{find\_cipher()} \index{error\_to\_string()} \begin{verbatim} #include int main(void) { unsigned char key[8]; symmetric_key skey; int err; /* you must register a cipher before you use it */ if (register_cipher(&blowfish_desc)) == -1) { printf("Unable to register Blowfish cipher."); return -1; } /* generic call to function (assuming the key * in key[] was already setup) */ if ((err = cipher_descriptor[find_cipher("blowfish")]. setup(key, 8, 0, &skey)) != CRYPT_OK) { printf("Error setting up Blowfish: %s\n", error_to_string(err)); return -1; } /* ... use cipher ... */ } \end{verbatim} \end{small} A good safety would be to check the return value of \textit{find\_cipher()} before accessing the desired function. In order to use a cipher with the descriptor table you must register it first using: \index{register\_cipher()} \begin{verbatim} int register_cipher(const struct _cipher_descriptor *cipher); \end{verbatim} Which accepts a pointer to a descriptor and returns the index into the global descriptor table. If an error occurs such as there is no more room (it can have 32 ciphers at most) it will return {\bf{-1}}. If you try to add the same cipher more than once it will just return the index of the first copy. To remove a cipher call: \index{unregister\_cipher()} \begin{verbatim} int unregister_cipher(const struct _cipher_descriptor *cipher); \end{verbatim} Which returns {\bf CRYPT\_OK} if it removes the cipher, otherwise it returns {\bf CRYPT\_ERROR}. \begin{small} \begin{verbatim} #include int main(void) { int err; /* register the cipher */ if (register_cipher(&rijndael_desc) == -1) { printf("Error registering Rijndael\n"); return -1; } /* use Rijndael */ /* remove it */ if ((err = unregister_cipher(&rijndael_desc)) != CRYPT_OK) { printf("Error removing Rijndael: %s\n", error_to_string(err)); return -1; } return 0; } \end{verbatim} \end{small} This snippet is a small program that registers Rijndael. \mysection{Symmetric Modes of Operations} \subsection{Background} A typical symmetric block cipher can be used in chaining modes to effectively encrypt messages larger than the block size of the cipher. Given a key $k$, a plaintext $P$ and a cipher $E$ we shall denote the encryption of the block $P$ under the key $k$ as $E_k(P)$. In some modes there exists an initial vector denoted as $C_{-1}$. \subsubsection{ECB Mode} \index{ECB mode} ECB or Electronic Codebook Mode is the simplest method to use. It is given as: \begin{equation} C_i = E_k(P_i) \end{equation} This mode is very weak since it allows people to swap blocks and perform replay attacks if the same key is used more than once. \subsubsection{CBC Mode} \index{CBC mode} CBC or Cipher Block Chaining mode is a simple mode designed to prevent trivial forms of replay and swap attacks on ciphers. It is given as: \begin{equation} C_i = E_k(P_i \oplus C_{i - 1}) \end{equation} It is important that the initial vector be unique and preferably random for each message encrypted under the same key. \subsubsection{CTR Mode} \index{CTR mode} CTR or Counter Mode is a mode which only uses the encryption function of the cipher. Given a initial vector which is treated as a large binary counter the CTR mode is given as: \begin{eqnarray} C_{-1} = C_{-1} + 1\mbox{ }(\mbox{mod }2^W) \nonumber \\ C_i = P_i \oplus E_k(C_{-1}) \end{eqnarray} Where $W$ is the size of a block in bits (e.g. 64 for Blowfish). As long as the initial vector is random for each message encrypted under the same key replay and swap attacks are infeasible. CTR mode may look simple but it is as secure as the block cipher is under a chosen plaintext attack (provided the initial vector is unique). \subsubsection{CFB Mode} \index{CFB mode} CFB or Ciphertext Feedback Mode is a mode akin to CBC. It is given as: \begin{eqnarray} C_i = P_i \oplus C_{-1} \nonumber \\ C_{-1} = E_k(C_i) \end{eqnarray} Note that in this library the output feedback width is equal to the size of the block cipher. That is this mode is used to encrypt whole blocks at a time. However, the library will buffer data allowing the user to encrypt or decrypt partial blocks without a delay. When this mode is first setup it will initially encrypt the initial vector as required. \subsubsection{OFB Mode} \index{OFB mode} OFB or Output Feedback Mode is a mode akin to CBC as well. It is given as: \begin{eqnarray} C_{-1} = E_k(C_{-1}) \nonumber \\ C_i = P_i \oplus C_{-1} \end{eqnarray} Like the CFB mode the output width in CFB mode is the same as the width of the block cipher. OFB mode will also buffer the output which will allow you to encrypt or decrypt partial blocks without delay. \subsection{Choice of Mode} My personal preference is for the CTR mode since it has several key benefits: \begin{enumerate} \item No short cycles which is possible in the OFB and CFB modes. \item Provably as secure as the block cipher being used under a chosen plaintext attack. \item Technically does not require the decryption routine of the cipher. \item Allows random access to the plaintext. \item Allows the encryption of block sizes that are not equal to the size of the block cipher. \end{enumerate} The CTR, CFB and OFB routines provided allow you to encrypt block sizes that differ from the ciphers block size. They accomplish this by buffering the data required to complete a block. This allows you to encrypt or decrypt any size block of memory with either of the three modes. The ECB and CBC modes process blocks of the same size as the cipher at a time. Therefore, they are less flexible than the other modes. \subsection{Ciphertext Stealing} \index{Ciphertext stealing} Ciphertext stealing is a method of dealing with messages in CBC mode which are not a multiple of the block length. This is accomplished by encrypting the last ciphertext block in ECB mode, and XOR'ing the output against the last partial block of plaintext. LibTomCrypt does not support this mode directly but it is fairly easy to emulate with a call to the cipher's ecb\_encrypt() callback function. The more sane way to deal with partial blocks is to pad them with zeroes, and then use CBC normally. \subsection{Initialization} \index{CBC Mode} \index{CTR Mode} \index{OFB Mode} \index{CFB Mode} The library provides simple support routines for handling CBC, CTR, CFB, OFB and ECB encoded messages. Assuming the mode you want is XXX there is a structure called \textit{symmetric\_XXX} that will contain the information required to use that mode. They have identical setup routines (except CTR and ECB mode): \index{ecb\_start()} \index{cfb\_start()} \index{cbc\_start()} \index{ofb\_start()} \index{ctr\_start()} \begin{verbatim} int XXX_start( int cipher, const unsigned char *IV, const unsigned char *key, int keylen, int num_rounds, symmetric_XXX *XXX); int ctr_start( int cipher, const unsigned char *IV, const unsigned char *key, int keylen, int num_rounds, int ctr_mode, symmetric_CTR *ctr); int ecb_start( int cipher, const unsigned char *key, int keylen, int num_rounds, symmetric_ECB *ecb); \end{verbatim} In each case, \textit{cipher} is the index into the cipher\_descriptor array of the cipher you want to use. The \textit{IV} value is the initialization vector to be used with the cipher. You must fill the IV yourself and it is assumed they are the same length as the block size\footnote{In other words the size of a block of plaintext for the cipher, e.g. 8 for DES, 16 for AES, etc.} of the cipher you choose. It is important that the IV be random for each unique message you want to encrypt. The parameters \textit{key}, \textit{keylen} and \textit{num\_rounds} are the same as in the XXX\_setup() function call. The final parameter is a pointer to the structure you want to hold the information for the mode of operation. The routines return {\bf CRYPT\_OK} if the cipher initialized correctly, otherwise, they return an error code. \subsubsection{CTR Mode} In the case of CTR mode there is an additional parameter \textit{ctr\_mode} which specifies the mode that the counter is to be used in. If \textbf{CTR\_COUNTER\_ LITTLE\_ENDIAN} was specified then the counter will be treated as a little endian value. Otherwise, if \textbf{CTR\_COUNTER\_BIG\_ENDIAN} was specified the counter will be treated as a big endian value. As of v1.15 the RFC 3686 style of increment then encrypt is also supported. By OR'ing \textbf{LTC\_CTR\_RFC3686} with the CTR \textit{mode} value, ctr\_start() will increment the counter before encrypting it for the first time. As of V1.17, the library supports variable length counters for CTR mode. The (optional) counter length is specified by OR'ing the octet length of the counter against the \textit{ctr\_mode} parameter. The default, zero, indicates that a full block length counter will be used. This also ensures backwards compatibility with software that uses older versions of the library. \begin{small} \begin{verbatim} symmetric_CTR ctr; int err; unsigned char IV[16], key[16]; /* use a 32-bit little endian counter */ if ((err = ctr_start(find_cipher("aes"), IV, key, 16, 0, CTR_COUNTER_LITTLE_ENDIAN | 4, &ctr)) != CRYPT_OK) { handle_error(err); } \end{verbatim} \end{small} Changing the counter size has little (really no) effect on the performance of the CTR chaining mode. It is provided for compatibility with other software (and hardware) which have smaller fixed sized counters. \subsection{Encryption and Decryption} To actually encrypt or decrypt the following routines are provided: \index{ecb\_encrypt()} \index{ecb\_decrypt()} \index{cfb\_encrypt()} \index{cfb\_decrypt()} \index{cbc\_encrypt()} \index{cbc\_decrypt()} \index{ofb\_encrypt()} \index{ofb\_decrypt()} \index{ctr\_encrypt()} \index{ctr\_decrypt()} \begin{verbatim} int XXX_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_YYY *YYY); int XXX_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_YYY *YYY); \end{verbatim} Where \textit{XXX} is one of $\lbrace ecb, cbc, ctr, cfb, ofb \rbrace$. In all cases, \textit{len} is the size of the buffer (as number of octets) to encrypt or decrypt. The CTR, OFB and CFB modes are order sensitive but not chunk sensitive. That is you can encrypt \textit{ABCDEF} in three calls like \textit{AB}, \textit{CD}, \textit{EF} or two like \textit{ABCDE} and \textit{F} and end up with the same ciphertext. However, encrypting \textit{ABC} and \textit{DABC} will result in different ciphertexts. All five of the modes will return {\bf CRYPT\_OK} on success from the encrypt or decrypt functions. In the ECB and CBC cases, \textit{len} must be a multiple of the ciphers block size. In the CBC case, you must manually pad the end of your message (either with zeroes or with whatever your protocol requires). To decrypt in either mode, perform the setup like before (recall you have to fetch the IV value you used), and use the decrypt routine on all of the blocks. \subsection{IV Manipulation} To change or read the IV of a previously initialized chaining mode use the following two functions. \index{cbc\_setiv()} \index{cbc\_getiv()} \index{ofb\_setiv()} \index{ofb\_getiv()} \index{cfb\_setiv()} \index{cfb\_getiv()} \index{ctr\_setiv()} \index{ctr\_getiv()} \begin{verbatim} int XXX_getiv(unsigned char *IV, unsigned long *len, symmetric_XXX *XXX); int XXX_setiv(const unsigned char *IV, unsigned long len, symmetric_XXX *XXX); \end{verbatim} The XXX\_getiv() functions will read the IV out of the chaining mode and store it into \textit{IV} along with the length of the IV stored in \textit{len}. The XXX\_setiv will initialize the chaining mode state as if the original IV were the new IV specified. The length of the IV passed in must be the size of the ciphers block size. The XXX\_setiv() functions are handy if you wish to change the IV without re--keying the cipher. What the \textit{setiv} function will do depends on the mode being changed. In CBC mode, the new IV replaces the existing IV as if it were the last ciphertext block. In CFB mode, the IV is encrypted as if it were the prior encrypted pad. In CTR mode, the IV is encrypted without first incrementing it (regardless of the LTC\_RFC\_3686 flag presence). In F8 mode, the IV is encrypted and becomes the new pad. It does not change the salted IV, and is only meant to allow seeking within a session. In LRW, it changes the tweak, forcing a computation of the tweak pad, allowing for seeking within the session. In OFB mode, the IV is encrypted and becomes the new pad. \subsection{Stream Termination} To terminate an open stream call the done function. \index{ecb\_done()} \index{cbc\_done()}\index{cfb\_done()}\index{ofb\_done()} \index{ctr\_done()} \begin{verbatim} int XXX_done(symmetric_XXX *XXX); \end{verbatim} This will terminate the stream (by terminating the cipher) and return \textbf{CRYPT\_OK} if successful. \newpage \subsection{Examples} \begin{small} \begin{verbatim} #include int main(void) { unsigned char key[16], IV[16], buffer[512]; symmetric_CTR ctr; int x, err; /* register twofish first */ if (register_cipher(&twofish_desc) == -1) { printf("Error registering cipher.\n"); return -1; } /* somehow fill out key and IV */ /* start up CTR mode */ if ((err = ctr_start( find_cipher("twofish"), /* index of desired cipher */ IV, /* the initial vector */ key, /* the secret key */ 16, /* length of secret key (16 bytes) */ 0, /* 0 == default # of rounds */ CTR_COUNTER_LITTLE_ENDIAN, /* Little endian counter */ &ctr) /* where to store the CTR state */ ) != CRYPT_OK) { printf("ctr_start error: %s\n", error_to_string(err)); return -1; } /* somehow fill buffer than encrypt it */ if ((err = ctr_encrypt( buffer, /* plaintext */ buffer, /* ciphertext */ sizeof(buffer), /* length of plaintext pt */ &ctr) /* CTR state */ ) != CRYPT_OK) { printf("ctr_encrypt error: %s\n", error_to_string(err)); return -1; } /* make use of ciphertext... */ /* now we want to decrypt so let's use ctr_setiv */ if ((err = ctr_setiv( IV, /* the initial IV we gave to ctr_start */ 16, /* the IV is 16 bytes long */ &ctr) /* the ctr state we wish to modify */ ) != CRYPT_OK) { printf("ctr_setiv error: %s\n", error_to_string(err)); return -1; } if ((err = ctr_decrypt( buffer, /* ciphertext */ buffer, /* plaintext */ sizeof(buffer), /* length of plaintext */ &ctr) /* CTR state */ ) != CRYPT_OK) { printf("ctr_decrypt error: %s\n", error_to_string(err)); return -1; } /* terminate the stream */ if ((err = ctr_done(&ctr)) != CRYPT_OK) { printf("ctr_done error: %s\n", error_to_string(err)); return -1; } /* clear up and return */ zeromem(key, sizeof(key)); zeromem(&ctr, sizeof(ctr)); return 0; } \end{verbatim} \end{small} \subsection{LRW Mode} LRW mode is a cipher mode which is meant for indexed encryption like used to handle storage media. It is meant to have efficient seeking and overcome the security problems of ECB mode while not increasing the storage requirements. It is used much like any other chaining mode except with two key differences. The key is specified as two strings the first key $K_1$ is the (normally AES) key and can be any length (typically 16, 24 or 32 octets long). The second key $K_2$ is the \textit{tweak} key and is always 16 octets long. The tweak value is \textbf{NOT} a nonce or IV value it must be random and secret. To initialize LRW mode use: \index{lrw\_start()} \begin{verbatim} int lrw_start( int cipher, const unsigned char *IV, const unsigned char *key, int keylen, const unsigned char *tweak, int num_rounds, symmetric_LRW *lrw); \end{verbatim} This will initialize the LRW context with the given (16 octet) \textit{IV}, cipher $K_1$ \textit{key} of length \textit{keylen} octets and the (16 octet) $K_2$ \textit{tweak}. While LRW was specified to be used only with AES, LibTomCrypt will allow any 128--bit block cipher to be specified as indexed by \textit{cipher}. The number of rounds for the block cipher \textit{num\_rounds} can be 0 to use the default number of rounds for the given cipher. To process data use the following functions: \index{lrw\_encrypt()} \index{lrw\_decrypt()} \begin{verbatim} int lrw_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_LRW *lrw); int lrw_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_LRW *lrw); \end{verbatim} These will encrypt (or decrypt) the plaintext to the ciphertext buffer (or vice versa). The length is specified by \textit{len} in octets but must be a multiple of 16. The LRW code uses a fast tweak update such that consecutive blocks are encrypted faster than if random seeking where used. To manipulate the IV use the following functions: \index{lrw\_getiv()} \index{lrw\_setiv()} \begin{verbatim} int lrw_getiv(unsigned char *IV, unsigned long *len, symmetric_LRW *lrw); int lrw_setiv(const unsigned char *IV, unsigned long len, symmetric_LRW *lrw); \end{verbatim} These will get or set the 16--octet IV. Note that setting the IV is the same as \textit{seeking} and unlike other modes is not a free operation. It requires updating the entire tweak which is slower than sequential use. Avoid seeking excessively in performance constrained code. To terminate the LRW state use the following: \index{lrw\_done()} \begin{verbatim} int lrw_done(symmetric_LRW *lrw); \end{verbatim} \subsection{XTS Mode} As of v1.17, LibTomCrypt supports XTS mode with code donated by Elliptic Semiconductor Inc.\footnote{www.ellipticsemi.com}. XTS is a chaining mode for 128--bit block ciphers, recommended by IEEE (P1619) for disk encryption. It is meant to be an encryption mode with random access to the message data without compromising privacy. It requires two private keys (of equal length) to perform the encryption process. Each encryption invocation includes a sector number or unique identifier specified as a 128--bit string. To initialize XTS mode use the following function call: \index{xts\_start()} \begin{verbatim} int xts_start( int cipher, const unsigned char *key1, const unsigned char *key2, unsigned long keylen, int num_rounds, symmetric_xts *xts) \end{verbatim} This will start the XTS mode with the two keys pointed to by \textit{key1} and \textit{key2} of length \textit{keylen} octets each. To encrypt or decrypt a sector use the following calls: \index{xts\_encrypt()} \index{xts\_decrypt()} \begin{verbatim} int xts_encrypt( const unsigned char *pt, unsigned long ptlen, unsigned char *ct, const unsigned char *tweak, symmetric_xts *xts); int xts_decrypt( const unsigned char *ct, unsigned long ptlen, unsigned char *pt, const unsigned char *tweak, symmetric_xts *xts); \end{verbatim} The first will encrypt the plaintext pointed to by \textit{pt} of length \textit{ptlen} octets, and store the ciphertext in the array pointed to by \textit{ct}. It uses the 128--bit tweak pointed to by \textit{tweak} to encrypt the block. The decrypt function performs the opposite operation. Both functions support ciphertext stealing (blocks that are not multiples of 16 bytes). The P1619 specification states the tweak for sector number shall be represented as a 128--bit little endian string. To terminate the XTS state call the following function: \index{xts\_done()} \begin{verbatim} void xts_done(symmetric_xts *xts); \end{verbatim} \subsection{F8 Mode} \index{F8 Mode} The F8 Chaining mode (see RFC 3711 for instance) is yet another chaining mode for block ciphers. It behaves much like CTR mode in that it XORs a keystream against the plaintext to encrypt. F8 mode comes with the additional twist that the counter value is secret, encrypted by a \textit{salt key}. We initialize F8 mode with the following function call: \index{f8\_start()} \begin{verbatim} int f8_start( int cipher, const unsigned char *IV, const unsigned char *key, int keylen, const unsigned char *salt_key, int skeylen, int num_rounds, symmetric_F8 *f8); \end{verbatim} This will start the F8 mode state using \textit{key} as the secret key, \textit{IV} as the counter. It uses the \textit{salt\_key} as IV encryption key (\textit{m} in the RFC 3711). The salt\_key can be shorter than the secret key but it should not be longer. To encrypt or decrypt data we use the following two functions: \index{f8\_encrypt()} \index{f8\_decrypt()} \begin{verbatim} int f8_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_F8 *f8); int f8_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_F8 *f8); \end{verbatim} These will encrypt or decrypt a variable length array of bytes using the F8 mode state specified. The length is specified in bytes and does not have to be a multiple of the ciphers block size. To change or retrieve the current counter IV value use the following functions: \index{f8\_getiv()} \index{f8\_setiv()} \begin{verbatim} int f8_getiv(unsigned char *IV, unsigned long *len, symmetric_F8 *f8); int f8_setiv(const unsigned char *IV, unsigned long len, symmetric_F8 *f8); \end{verbatim} These work with the current IV value only and not the encrypted IV value specified during the call to f8\_start(). The purpose of these two functions is to be able to seek within a current session only. If you want to change the session IV you will have to call f8\_done() and then start a new state with f8\_start(). To terminate an F8 state call the following function: \index{f8\_done()} \begin{verbatim} int f8_done(symmetric_F8 *f8); \end{verbatim} \vfil \mysection{Encrypt and Authenticate Modes} \subsection{EAX Mode} LibTomCrypt provides support for a mode called EAX\footnote{See M. Bellare, P. Rogaway, D. Wagner, A Conventional Authenticated-Encryption Mode.} in a manner similar to the way it was intended to be used by the designers. First, a short description of what EAX mode is before we explain how to use it. EAX is a mode that requires a cipher, CTR and OMAC support and provides encryption and authentication\footnote{Note that since EAX only requires OMAC and CTR you may use \textit{encrypt only} cipher descriptors with this mode.}. It is initialized with a random \textit{nonce} that can be shared publicly, a \textit{header} which can be fixed and public, and a random secret symmetric key. The \textit{header} data is meant to be meta--data associated with a stream that isn't private (e.g., protocol messages). It can be added at anytime during an EAX stream, and is part of the authentication tag. That is, changes in the meta-data can be detected by changes in the output tag. The mode can then process plaintext producing ciphertext as well as compute a partial checksum. The actual checksum called a \textit{tag} is only emitted when the message is finished. In the interim, the user can process any arbitrary sized message block to send to the recipient as ciphertext. This makes the EAX mode especially suited for streaming modes of operation. The mode is initialized with the following function. \index{eax\_init()} \begin{verbatim} int eax_init( eax_state *eax, int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *nonce, unsigned long noncelen, const unsigned char *header, unsigned long headerlen); \end{verbatim} Where \textit{eax} is the EAX state. The \textit{cipher} parameter is the index of the desired cipher in the descriptor table. The \textit{key} parameter is the shared secret symmetric key of length \textit{keylen} octets. The \textit{nonce} parameter is the random public string of length \textit{noncelen} octets. The \textit{header} parameter is the random (or fixed or \textbf{NULL}) header for the message of length \textit{headerlen} octets. When this function completes, the \textit{eax} state will be initialized such that you can now either have data decrypted or encrypted in EAX mode. Note: if \textit{headerlen} is zero you may pass \textit{header} as \textbf{NULL} to indicate there is no initial header data. To encrypt or decrypt data in a streaming mode use the following. \index{eax\_encrypt()} \index{eax\_decrypt()} \begin{verbatim} int eax_encrypt( eax_state *eax, const unsigned char *pt, unsigned char *ct, unsigned long length); int eax_decrypt( eax_state *eax, const unsigned char *ct, unsigned char *pt, unsigned long length); \end{verbatim} The function \textit{eax\_encrypt} will encrypt the bytes in \textit{pt} of \textit{length} octets, and store the ciphertext in \textit{ct}. Note: \textit{ct} and \textit{pt} may be the same region in memory. This function will also send the ciphertext through the OMAC function. The function \textit{eax\_decrypt} decrypts \textit{ct}, and stores it in \textit{pt}. This also allows \textit{pt} and \textit{ct} to be the same region in memory. You cannot both encrypt or decrypt with the same \textit{eax} context. For bi--directional communication you will need to initialize two EAX contexts (preferably with different headers and nonces). Note: both of these functions allow you to send the data in any granularity but the order is important. While the eax\_init() function allows you to add initial header data to the stream you can also add header data during the EAX stream with the following. \index{eax\_addheader()} \begin{verbatim} int eax_addheader( eax_state *eax, const unsigned char *header, unsigned long length); \end{verbatim} This will add the \textit{length} octet from \textit{header} to the given \textit{eax} header. Once the message is finished, the \textit{tag} (checksum) may be computed with the following function: \index{eax\_done()} \begin{verbatim} int eax_done( eax_state *eax, unsigned char *tag, unsigned long *taglen); \end{verbatim} This will terminate the EAX state \textit{eax}, and store up to \textit{taglen} bytes of the message tag in \textit{tag}. The function then stores how many bytes of the tag were written out back in to \textit{taglen}. The EAX mode code can be tested to ensure it matches the test vectors by calling the following function: \index{eax\_test()} \begin{verbatim} int eax_test(void); \end{verbatim} This requires that the AES (or Rijndael) block cipher be registered with the cipher\_descriptor table first. \begin{verbatim} #include int main(void) { int err; eax_state eax; unsigned char pt[64], ct[64], nonce[16], key[16], tag[16]; unsigned long taglen; if (register_cipher(&rijndael_desc) == -1) { printf("Error registering Rijndael"); return EXIT_FAILURE; } /* ... make up random nonce and key ... */ /* initialize context */ if ((err = eax_init( &eax, /* context */ find_cipher("rijndael"), /* cipher id */ nonce, /* the nonce */ 16, /* nonce is 16 bytes */ "TestApp", /* example header */ 7) /* header length */ ) != CRYPT_OK) { printf("Error eax_init: %s", error_to_string(err)); return EXIT_FAILURE; } /* now encrypt data, say in a loop or whatever */ if ((err = eax_encrypt( &eax, /* eax context */ pt, /* plaintext (source) */ ct, /* ciphertext (destination) */ sizeof(pt) /* size of plaintext */ ) != CRYPT_OK) { printf("Error eax_encrypt: %s", error_to_string(err)); return EXIT_FAILURE; } /* finish message and get authentication tag */ taglen = sizeof(tag); if ((err = eax_done( &eax, /* eax context */ tag, /* where to put tag */ &taglen /* length of tag space */ ) != CRYPT_OK) { printf("Error eax_done: %s", error_to_string(err)); return EXIT_FAILURE; } /* now we have the authentication tag in "tag" and * it's taglen bytes long */ } \end{verbatim} You can also perform an entire EAX state on a block of memory in a single function call with the following functions. \index{eax\_encrypt\_authenticate\_memory} \index{eax\_decrypt\_verify\_memory} \begin{verbatim} int eax_encrypt_authenticate_memory( int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *nonce, unsigned long noncelen, const unsigned char *header, unsigned long headerlen, const unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tag, unsigned long *taglen); int eax_decrypt_verify_memory( int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *nonce, unsigned long noncelen, const unsigned char *header, unsigned long headerlen, const unsigned char *ct, unsigned long ctlen, unsigned char *pt, unsigned char *tag, unsigned long taglen, int *res); \end{verbatim} Both essentially just call eax\_init() followed by eax\_encrypt() (or eax\_decrypt() respectively) and eax\_done(). The parameters have the same meaning as with those respective functions. The only difference is eax\_decrypt\_verify\_memory() does not emit a tag. Instead you pass it a tag as input and it compares it against the tag it computed while decrypting the message. If the tags match then it stores a $1$ in \textit{res}, otherwise it stores a $0$. \subsection{OCB Mode} LibTomCrypt provides support for a mode called OCB\footnote{See P. Rogaway, M. Bellare, J. Black, T. Krovetz, \textit{OCB: A Block Cipher Mode of Operation for Efficient Authenticated Encryption}.} . OCB is an encryption protocol that simultaneously provides authentication. It is slightly faster to use than EAX mode but is less flexible. Let's review how to initialize an OCB context. \index{ocb\_init()} \begin{verbatim} int ocb_init( ocb_state *ocb, int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *nonce); \end{verbatim} This will initialize the \textit{ocb} context using cipher descriptor \textit{cipher}. It will use a \textit{key} of length \textit{keylen} and the random \textit{nonce}. Note that \textit{nonce} must be a random (public) string the same length as the block ciphers block size (e.g. 16 bytes for AES). This mode has no \textit{Associated Data} like EAX mode does which means you cannot authenticate metadata along with the stream. To encrypt or decrypt data use the following. \index{ocb\_encrypt()} \index{ocb\_decrypt()} \begin{verbatim} int ocb_encrypt( ocb_state *ocb, const unsigned char *pt, unsigned char *ct); int ocb_decrypt( ocb_state *ocb, const unsigned char *ct, unsigned char *pt); \end{verbatim} This will encrypt (or decrypt for the latter) a fixed length of data from \textit{pt} to \textit{ct} (vice versa for the latter). They assume that \textit{pt} and \textit{ct} are the same size as the block cipher's block size. Note that you cannot call both functions given a single \textit{ocb} state. For bi-directional communication you will have to initialize two \textit{ocb} states (with different nonces). Also \textit{pt} and \textit{ct} may point to the same location in memory. \subsubsection{State Termination} When you are finished encrypting the message you call the following function to compute the tag. \index{ocb\_done\_encrypt()} \begin{verbatim} int ocb_done_encrypt( ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tag, unsigned long *taglen); \end{verbatim} This will terminate an encrypt stream \textit{ocb}. If you have trailing bytes of plaintext that will not complete a block you can pass them here. This will also encrypt the \textit{ptlen} bytes in \textit{pt} and store them in \textit{ct}. It will also store up to \textit{taglen} bytes of the tag into \textit{tag}. Note that \textit{ptlen} must be less than or equal to the block size of block cipher chosen. Also note that if you have an input message equal to the length of the block size then you pass the data here (not to ocb\_encrypt()) only. To terminate a decrypt stream and compared the tag you call the following. \index{ocb\_done\_decrypt()} \begin{verbatim} int ocb_done_decrypt( ocb_state *ocb, const unsigned char *ct, unsigned long ctlen, unsigned char *pt, const unsigned char *tag, unsigned long taglen, int *res); \end{verbatim} Similarly to the previous function you can pass trailing message bytes into this function. This will compute the tag of the message (internally) and then compare it against the \textit{taglen} bytes of \textit{tag} provided. By default \textit{res} is set to zero. If all \textit{taglen} bytes of \textit{tag} can be verified then \textit{res} is set to one (authenticated message). \subsubsection{Packet Functions} To make life simpler the following two functions are provided for memory bound OCB. %\index{ocb\_encrypt\_authenticate\_memory()} \begin{verbatim} int ocb_encrypt_authenticate_memory( int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *nonce, const unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tag, unsigned long *taglen); \end{verbatim} This will OCB encrypt the message \textit{pt} of length \textit{ptlen}, and store the ciphertext in \textit{ct}. The length \textit{ptlen} can be any arbitrary length. \index{ocb\_decrypt\_verify\_memory()} \begin{verbatim} int ocb_decrypt_verify_memory( int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *nonce, const unsigned char *ct, unsigned long ctlen, unsigned char *pt, const unsigned char *tag, unsigned long taglen, int *res); \end{verbatim} Similarly, this will OCB decrypt, and compare the internally computed tag against the tag provided. \textit{res} is set appropriately. \subsection{CCM Mode} CCM is a NIST proposal for encrypt + authenticate that is centered around using AES (or any 16--byte cipher) as a primitive. Unlike EAX and OCB mode, it is only meant for \textit{packet} mode where the length of the input is known in advance. Since it is a packet mode function, CCM only has one function that performs the protocol. \index{ccm\_memory()} \begin{verbatim} int ccm_memory( int cipher, const unsigned char *key, unsigned long keylen, symmetric_key *uskey, const unsigned char *nonce, unsigned long noncelen, const unsigned char *header, unsigned long headerlen, unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tag, unsigned long *taglen, int direction); \end{verbatim} This performs the \textit{CCM} operation on the data. The \textit{cipher} variable indicates which cipher in the descriptor table to use. It must have a 16--byte block size for CCM. The key can be specified in one of two fashions. First, it can be passed as an array of octets in \textit{key} of length \textit{keylen}. Alternatively, it can be passed in as a previously scheduled key in \textit{uskey}. The latter fashion saves time when the same key is used for multiple packets. If \textit{uskey} is not \textbf{NULL}, then \textit{key} may be \textbf{NULL} (and vice-versa). The nonce or salt is \textit{nonce} of length \textit{noncelen} octets. The header is meta--data you want to send with the message but not have encrypted, it is stored in \textit{header} of length \textit{headerlen} octets. The header can be zero octets long (if $headerlen = 0$ then you can pass \textit{header} as \textbf{NULL}). The plaintext is stored in \textit{pt}, and the ciphertext in \textit{ct}. The length of both are expected to be equal and is passed in as \textit{ptlen}. It is allowable that $pt = ct$. The \textit{direction} variable indicates whether encryption (direction $=$ \textbf{CCM\_ENCRYPT}) or decryption (direction $=$ \textbf{CCM\_DECRYPT}) is to be performed. As implemented, this version of CCM cannot handle header or plaintext data longer than $2^{32} - 1$ octets long. You can test the implementation of CCM with the following function. \index{ccm\_test()} \begin{verbatim} int ccm_test(void); \end{verbatim} This will return \textbf{CRYPT\_OK} if the CCM routine passes known test vectors. It requires AES or Rijndael to be registered previously, otherwise it will return \textbf{CRYPT\_NOP}. \subsubsection{CCM Example} The following is a sample of how to call CCM. \begin{small} \begin{verbatim} #include int main(void) { unsigned char key[16], nonce[12], pt[32], ct[32], tag[16], tagcp[16]; unsigned long taglen; int err; /* register cipher */ register_cipher(&aes_desc); /* somehow fill key, nonce, pt */ /* encrypt it */ taglen = sizeof(tag); if ((err = ccm_memory(find_cipher("aes"), key, 16, /* 128-bit key */ NULL, /* not prescheduled */ nonce, 12, /* 96-bit nonce */ NULL, 0, /* no header */ pt, 32, /* 32-byte plaintext */ ct, /* ciphertext */ tag, &taglen, CCM_ENCRYPT)) != CRYPT_OK) { printf("ccm_memory error %s\n", error_to_string(err)); return -1; } /* ct[0..31] and tag[0..15] now hold the output */ /* decrypt it */ taglen = sizeof(tagcp); if ((err = ccm_memory(find_cipher("aes"), key, 16, /* 128-bit key */ NULL, /* not prescheduled */ nonce, 12, /* 96-bit nonce */ NULL, 0, /* no header */ ct, 32, /* 32-byte ciphertext */ pt, /* plaintext */ tagcp, &taglen, CCM_DECRYPT)) != CRYPT_OK) { printf("ccm_memory error %s\n", error_to_string(err)); return -1; } /* now pt[0..31] should hold the original plaintext, tagcp[0..15] and tag[0..15] should have the same contents */ } \end{verbatim} \end{small} \subsection{GCM Mode} Galois counter mode is an IEEE proposal for authenticated encryption (also it is a planned NIST standard). Like EAX and OCB mode, it can be used in a streaming capacity however, unlike EAX it cannot accept \textit{additional authentication data} (meta--data) after plaintext has been processed. This mode also only works with block ciphers with a 16--byte block. A GCM stream is meant to be processed in three modes, one after another. First, the initial vector (per session) data is processed. This should be unique to every session. Next, the the optional additional authentication data is processed, and finally the plaintext (or ciphertext depending on the direction). \subsubsection{Initialization} To initialize the GCM context with a secret key call the following function. \index{gcm\_init()} \begin{verbatim} int gcm_init( gcm_state *gcm, int cipher, const unsigned char *key, int keylen); \end{verbatim} This initializes the GCM state \textit{gcm} for the given cipher indexed by \textit{cipher}, with a secret key \textit{key} of length \textit{keylen} octets. The cipher chosen must have a 16--byte block size (e.g., AES). \subsubsection{Initial Vector} After the state has been initialized (or reset) the next step is to add the session (or packet) initial vector. It should be unique per packet encrypted. \index{gcm\_add\_iv()} \begin{verbatim} int gcm_add_iv( gcm_state *gcm, const unsigned char *IV, unsigned long IVlen); \end{verbatim} This adds the initial vector octets from \textit{IV} of length \textit{IVlen} to the GCM state \textit{gcm}. You can call this function as many times as required to process the entire IV. Note: the GCM protocols provides a \textit{shortcut} for 12--byte IVs where no pre-processing is to be done. If you want to minimize per packet latency it is ideal to only use 12--byte IVs. You can just increment it like a counter for each packet. \subsubsection{Additional Authentication Data} After the entire IV has been processed, the additional authentication data can be processed. Unlike the IV, a packet/session does not require additional authentication data (AAD) for security. The AAD is meant to be used as side--channel data you want to be authenticated with the packet. Note: once you begin adding AAD to the GCM state you cannot return to adding IV data until the state has been reset. \index{gcm\_add\_aad()} \begin{verbatim} int gcm_add_aad( gcm_state *gcm, const unsigned char *adata, unsigned long adatalen); \end{verbatim} This adds the additional authentication data \textit{adata} of length \textit{adatalen} to the GCM state \textit{gcm}. \subsubsection{Plaintext Processing} After the AAD has been processed, the plaintext (or ciphertext depending on the direction) can be processed. \index{gcm\_process()} \begin{verbatim} int gcm_process( gcm_state *gcm, unsigned char *pt, unsigned long ptlen, unsigned char *ct, int direction); \end{verbatim} This processes message data where \textit{pt} is the plaintext and \textit{ct} is the ciphertext. The length of both are equal and stored in \textit{ptlen}. Depending on the mode \textit{pt} is the input and \textit{ct} is the output (or vice versa). When \textit{direction} equals \textbf{GCM\_ENCRYPT} the plaintext is read, encrypted and stored in the ciphertext buffer. When \textit{direction} equals \textbf{GCM\_DECRYPT} the opposite occurs. \subsubsection{State Termination} To terminate a GCM state and retrieve the message authentication tag call the following function. \index{gcm\_done()} \begin{verbatim} int gcm_done( gcm_state *gcm, unsigned char *tag, unsigned long *taglen); \end{verbatim} This terminates the GCM state \textit{gcm} and stores the tag in \textit{tag} of length \textit{taglen} octets. \subsubsection{State Reset} The call to gcm\_init() will perform considerable pre--computation (when \textbf{GCM\_TABLES} is defined) and if you're going to be dealing with a lot of packets it is very costly to have to call it repeatedly. To aid in this endeavour, the reset function has been provided. \index{gcm\_reset()} \begin{verbatim} int gcm_reset(gcm_state *gcm); \end{verbatim} This will reset the GCM state \textit{gcm} to the state that gcm\_init() left it. The user would then call gcm\_add\_iv(), gcm\_add\_aad(), etc. \subsubsection{One--Shot Packet} To process a single packet under any given key the following helper function can be used. \index{gcm\_memory()} \begin{verbatim} int gcm_memory( int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *IV, unsigned long IVlen, const unsigned char *adata, unsigned long adatalen, unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tag, unsigned long *taglen, int direction); \end{verbatim} This will initialize the GCM state with the given key, IV and AAD value then proceed to encrypt or decrypt the message text and store the final message tag. The definition of the variables is the same as it is for all the manual functions. If you are processing many packets under the same key you shouldn't use this function as it invokes the pre--computation with each call. \subsubsection{Example Usage} The following is an example usage of how to use GCM over multiple packets with a shared secret key. \begin{small} \begin{verbatim} #include int send_packet(const unsigned char *pt, unsigned long ptlen, const unsigned char *iv, unsigned long ivlen, const unsigned char *aad, unsigned long aadlen, gcm_state *gcm) { int err; unsigned long taglen; unsigned char tag[16]; /* reset the state */ if ((err = gcm_reset(gcm)) != CRYPT_OK) { return err; } /* Add the IV */ if ((err = gcm_add_iv(gcm, iv, ivlen)) != CRYPT_OK) { return err; } /* Add the AAD (note: aad can be NULL if aadlen == 0) */ if ((err = gcm_add_aad(gcm, aad, aadlen)) != CRYPT_OK) { return err; } /* process the plaintext */ if ((err = gcm_process(gcm, pt, ptlen, pt, GCM_ENCRYPT)) != CRYPT_OK) { return err; } /* Finish up and get the MAC tag */ taglen = sizeof(tag); if ((err = gcm_done(gcm, tag, &taglen)) != CRYPT_OK) { return err; } /* ... send a header describing the lengths ... */ /* depending on the protocol and how IV is * generated you may have to send it too... */ send(socket, iv, ivlen, 0); /* send the aad */ send(socket, aad, aadlen, 0); /* send the ciphertext */ send(socket, pt, ptlen, 0); /* send the tag */ send(socket, tag, taglen, 0); return CRYPT_OK; } int main(void) { gcm_state gcm; unsigned char key[16], IV[12], pt[PACKET_SIZE]; int err, x; unsigned long ptlen; /* somehow fill key/IV with random values */ /* register AES */ register_cipher(&aes_desc); /* init the GCM state */ if ((err = gcm_init(&gcm, find_cipher("aes"), key, 16)) != CRYPT_OK) { whine_and_pout(err); } /* handle us some packets */ for (;;) { ptlen = make_packet_we_want_to_send(pt); /* use IV as counter (12 byte counter) */ for (x = 11; x >= 0; x--) { if (++IV[x]) { break; } } if ((err = send_packet(pt, ptlen, iv, 12, NULL, 0, &gcm)) != CRYPT_OK) { whine_and_pout(err); } } return EXIT_SUCCESS; } \end{verbatim} \end{small} \chapter{One-Way Cryptographic Hash Functions} \mysection{Core Functions} Like the ciphers, there are hash core functions and a universal data type to hold the hash state called \textit{hash\_state}. To initialize hash XXX (where XXX is the name) call: \index{Hash Functions} \begin{verbatim} void XXX_init(hash_state *md); \end{verbatim} This simply sets up the hash to the default state governed by the specifications of the hash. To add data to the message being hashed call: \begin{verbatim} int XXX_process( hash_state *md, const unsigned char *in, unsigned long inlen); \end{verbatim} Essentially all hash messages are virtually infinitely\footnote{Most hashes are limited to $2^{64}$ bits or 2,305,843,009,213,693,952 bytes.} long message which are buffered. The data can be passed in any sized chunks as long as the order of the bytes are the same the message digest (hash output) will be the same. For example, this means that: \begin{verbatim} md5_process(&md, "hello ", 6); md5_process(&md, "world", 5); \end{verbatim} Will produce the same message digest as the single call: \index{Message Digest} \begin{verbatim} md5_process(&md, "hello world", 11); \end{verbatim} To finally get the message digest (the hash) call: \begin{verbatim} int XXX_done( hash_state *md, unsigned char *out); \end{verbatim} This function will finish up the hash and store the result in the \textit{out} array. You must ensure that \textit{out} is long enough for the hash in question. Often hashes are used to get keys for symmetric ciphers so the \textit{XXX\_done()} functions will wipe the \textit{md} variable before returning automatically. To test a hash function call: \begin{verbatim} int XXX_test(void); \end{verbatim} This will return {\bf CRYPT\_OK} if the hash matches the test vectors, otherwise it returns an error code. An example snippet that hashes a message with md5 is given below. \begin{small} \begin{verbatim} #include int main(void) { hash_state md; unsigned char *in = "hello world", out[16]; /* setup the hash */ md5_init(&md); /* add the message */ md5_process(&md, in, strlen(in)); /* get the hash in out[0..15] */ md5_done(&md, out); return 0; } \end{verbatim} \end{small} \mysection{Hash Descriptors} Like the set of ciphers, the set of hashes have descriptors as well. They are stored in an array called \textit{hash\_descriptor} and are defined by: \begin{verbatim} struct _hash_descriptor { char *name; unsigned long hashsize; /* digest output size in bytes */ unsigned long blocksize; /* the block size the hash uses */ void (*init) (hash_state *hash); int (*process)( hash_state *hash, const unsigned char *in, unsigned long inlen); int (*done) (hash_state *hash, unsigned char *out); int (*test) (void); }; \end{verbatim} \index{find\_hash()} The \textit{name} member is the name of the hash function (all lowercase). The \textit{hashsize} member is the size of the digest output in bytes, while \textit{blocksize} is the size of blocks the hash expects to the compression function. Technically, this detail is not important for high level developers but is useful to know for performance reasons. The \textit{init} member initializes the hash, \textit{process} passes data through the hash, \textit{done} terminates the hash and retrieves the digest. The \textit{test} member tests the hash against the specified test vectors. There is a function to search the array as well called \textit{int find\_hash(char *name)}. It returns -1 if the hash is not found, otherwise, the position in the descriptor table of the hash. In addition, there is also find\_hash\_oid() which finds a hash by the ASN.1 OBJECT IDENTIFIER string. \index{find\_hash\_oid()} \begin{verbatim} int find_hash_oid(const unsigned long *ID, unsigned long IDlen); \end{verbatim} You can use the table to indirectly call a hash function that is chosen at run-time. For example: \begin{small} \begin{verbatim} #include int main(void) { unsigned char buffer[100], hash[MAXBLOCKSIZE]; int idx, x; hash_state md; /* register hashes .... */ if (register_hash(&md5_desc) == -1) { printf("Error registering MD5.\n"); return -1; } /* register other hashes ... */ /* prompt for name and strip newline */ printf("Enter hash name: \n"); fgets(buffer, sizeof(buffer), stdin); buffer[strlen(buffer) - 1] = 0; /* get hash index */ idx = find_hash(buffer); if (idx == -1) { printf("Invalid hash name!\n"); return -1; } /* hash input until blank line */ hash_descriptor[idx].init(&md); while (fgets(buffer, sizeof(buffer), stdin) != NULL) hash_descriptor[idx].process(&md, buffer, strlen(buffer)); hash_descriptor[idx].done(&md, hash); /* dump to screen */ for (x = 0; x < hash_descriptor[idx].hashsize; x++) printf("%02x ", hash[x]); printf("\n"); return 0; } \end{verbatim} \end{small} Note the usage of \textbf{MAXBLOCKSIZE}. In LibTomCrypt, no symmetric block, key or hash digest is larger than \textbf{MAXBLOCKSIZE} in length. This provides a simple size you can set your automatic arrays to that will not get overrun. There are three helper functions to make working with hashes easier. The first is a function to hash a buffer, and produce the digest in a single function call. \index{hash\_memory()} \begin{verbatim} int hash_memory( int hash, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); \end{verbatim} This will hash the data pointed to by \textit{in} of length \textit{inlen}. The hash used is indexed by the \textit{hash} parameter. The message digest is stored in \textit{out}, and the \textit{outlen} parameter is updated to hold the message digest size. The next helper function allows for the hashing of a file based on a file name. \index{hash\_file()} \begin{verbatim} int hash_file( int hash, const char *fname, unsigned char *out, unsigned long *outlen); \end{verbatim} This will hash the file named by \textit{fname} using the hash indexed by \textit{hash}. The file named in this function call must be readable by the user owning the process performing the request. This function can be omitted by the \textbf{LTC\_NO\_FILE} define, which forces it to return \textbf{CRYPT\_NOP} when it is called. The message digest is stored in \textit{out}, and the \textit{outlen} parameter is updated to hold the message digest size. \index{hash\_filehandle()} \begin{verbatim} int hash_filehandle( int hash, FILE *in, unsigned char *out, unsigned long *outlen); \end{verbatim} This will hash the file identified by the handle \textit{in} using the hash indexed by \textit{hash}. This will begin hashing from the current file pointer position, and will not rewind the file pointer when finished. This function can be omitted by the \textbf{LTC\_NO\_FILE} define, which forces it to return \textbf{CRYPT\_NOP} when it is called. The message digest is stored in \textit{out}, and the \textit{outlen} parameter is updated to hold the message digest size. To perform the above hash with md5 the following code could be used: \begin{small} \begin{verbatim} #include int main(void) { int idx, err; unsigned long len; unsigned char out[MAXBLOCKSIZE]; /* register the hash */ if (register_hash(&md5_desc) == -1) { printf("Error registering MD5.\n"); return -1; } /* get the index of the hash */ idx = find_hash("md5"); /* call the hash */ len = sizeof(out); if ((err = hash_memory(idx, "hello world", 11, out, &len)) != CRYPT_OK) { printf("Error hashing data: %s\n", error_to_string(err)); return -1; } return 0; } \end{verbatim} \end{small} \subsection{Hash Registration} Similar to the cipher descriptor table you must register your hash algorithms before you can use them. These functions work exactly like those of the cipher registration code. The functions are: \index{register\_hash()} \index{unregister\_hash()} \begin{verbatim} int register_hash(const struct _hash_descriptor *hash); int unregister_hash(const struct _hash_descriptor *hash); \end{verbatim} The following hashes are provided as of this release within the LibTomCrypt library: \index{Hash descriptor table} \begin{figure}[here] \begin{center} \begin{tabular}{|c|c|c|} \hline \textbf{Name} & \textbf{Descriptor Name} & \textbf{Size of Message Digest (bytes)} \\ \hline WHIRLPOOL & whirlpool\_desc & 64 \\ \hline SHA-512 & sha512\_desc & 64 \\ \hline SHA-384 & sha384\_desc & 48 \\ \hline RIPEMD-320 & rmd160\_desc & 40 \\ \hline SHA-256 & sha256\_desc & 32 \\ \hline RIPEMD-256 & rmd160\_desc & 32 \\ \hline SHA-224 & sha224\_desc & 28 \\ \hline TIGER-192 & tiger\_desc & 24 \\ \hline SHA-1 & sha1\_desc & 20 \\ \hline RIPEMD-160 & rmd160\_desc & 20 \\ \hline RIPEMD-128 & rmd128\_desc & 16 \\ \hline MD5 & md5\_desc & 16 \\ \hline MD4 & md4\_desc & 16 \\ \hline MD2 & md2\_desc & 16 \\ \hline \end{tabular} \end{center} \caption{Built--In Software Hashes} \end{figure} \vfil \mysection{Cipher Hash Construction} \index{Cipher Hash Construction} An addition to the suite of hash functions is the \textit{Cipher Hash Construction} or \textit{CHC} mode. In this mode applicable block ciphers (such as AES) can be turned into hash functions that other LTC functions can use. In particular this allows a cryptosystem to be designed using very few moving parts. In order to use the CHC system the developer will have to take a few extra steps. First the \textit{chc\_desc} hash descriptor must be registered with register\_hash(). At this point the CHC hash cannot be used to hash data. While it is in the hash system you still have to tell the CHC code which cipher to use. This is accomplished via the chc\_register() function. \index{chc\_register()} \begin{verbatim} int chc_register(int cipher); \end{verbatim} A cipher has to be registered with CHC (and also in the cipher descriptor tables with register\_cipher()). The chc\_register() function will bind a cipher to the CHC system. Only one cipher can be bound to the CHC hash at a time. There are additional requirements for the system to work. \begin{enumerate} \item The cipher must have a block size greater than 64--bits. \item The cipher must allow an input key the size of the block size. \end{enumerate} Example of using CHC with the AES block cipher. \begin{verbatim} #include int main(void) { int err; /* register cipher and hash */ if (register_cipher(&aes_enc_desc) == -1) { printf("Could not register cipher\n"); return EXIT_FAILURE; } if (register_hash(&chc_desc) == -1) { printf("Could not register hash\n"); return EXIT_FAILURE; } /* start chc with AES */ if ((err = chc_register(find_cipher("aes"))) != CRYPT_OK) { printf("Error binding AES to CHC: %s\n", error_to_string(err)); } /* now you can use chc_hash in any LTC function * [aside from pkcs...] */ } \end{verbatim} \mysection{Notice} It is highly recommended that you \textbf{not} use the MD4 or MD5 hashes for the purposes of digital signatures or authentication codes. These hashes are provided for completeness and they still can be used for the purposes of password hashing or one-way accumulators (e.g. Yarrow). The other hashes such as the SHA-1, SHA-2 (that includes SHA-512, SHA-384 and SHA-256) and TIGER-192 are still considered secure for all purposes you would normally use a hash for. \chapter{Message Authentication Codes} \mysection{HMAC Protocol} Thanks to Dobes Vandermeer, the library now includes support for hash based message authentication codes, or HMAC for short. An HMAC of a message is a keyed authentication code that only the owner of a private symmetric key will be able to verify. The purpose is to allow an owner of a private symmetric key to produce an HMAC on a message then later verify if it is correct. Any impostor or eavesdropper will not be able to verify the authenticity of a message. The HMAC support works much like the normal hash functions except that the initialization routine requires you to pass a key and its length. The key is much like a key you would pass to a cipher. That is, it is simply an array of octets stored in unsigned characters. The initialization routine is: \index{hmac\_init()} \begin{verbatim} int hmac_init( hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen); \end{verbatim} The \textit{hmac} parameter is the state for the HMAC code. The \textit{hash} parameter is the index into the descriptor table of the hash you want to use to authenticate the message. The \textit{key} parameter is the pointer to the array of chars that make up the key. The \textit{keylen} parameter is the length (in octets) of the key you want to use to authenticate the message. To send octets of a message through the HMAC system you must use the following function: \index{hmac\_process()} \begin{verbatim} int hmac_process( hmac_state *hmac, const unsigned char *in, unsigned long inlen); \end{verbatim} \textit{hmac} is the HMAC state you are working with. \textit{in} is the array of octets to send into the HMAC process. \textit{inlen} is the number of octets to process. Like the hash process routines, you can send the data in arbitrarily sized chunks. When you are finished with the HMAC process you must call the following function to get the HMAC code: \index{hmac\_done()} \begin{verbatim} int hmac_done( hmac_state *hmac, unsigned char *out, unsigned long *outlen); \end{verbatim} The \textit{hmac} parameter is the HMAC state you are working with. The \textit{out} parameter is the array of octets where the HMAC code should be stored. You must set \textit{outlen} to the size of the destination buffer before calling this function. It is updated with the length of the HMAC code produced (depending on which hash was picked). If \textit{outlen} is less than the size of the message digest (and ultimately the HMAC code) then the HMAC code is truncated as per FIPS-198 specifications (e.g. take the first \textit{outlen} bytes). There are two utility functions provided to make using HMACs easier to do. They accept the key and information about the message (file pointer, address in memory), and produce the HMAC result in one shot. These are useful if you want to avoid calling the three step process yourself. \index{hmac\_memory()} \begin{verbatim} int hmac_memory( int hash, const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); \end{verbatim} This will produce an HMAC code for the array of octets in \textit{in} of length \textit{inlen}. The index into the hash descriptor table must be provided in \textit{hash}. It uses the key from \textit{key} with a key length of \textit{keylen}. The result is stored in the array of octets \textit{out} and the length in \textit{outlen}. The value of \textit{outlen} must be set to the size of the destination buffer before calling this function. Similarly for files there is the following function: \index{hmac\_file()} \begin{verbatim} int hmac_file( int hash, const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *out, unsigned long *outlen); \end{verbatim} \textit{hash} is the index into the hash descriptor table of the hash you want to use. \textit{fname} is the filename to process. \textit{key} is the array of octets to use as the key of length \textit{keylen}. \textit{out} is the array of octets where the result should be stored. To test if the HMAC code is working there is the following function: \index{hmac\_test()} \begin{verbatim} int hmac_test(void); \end{verbatim} Which returns {\bf CRYPT\_OK} if the code passes otherwise it returns an error code. Some example code for using the HMAC system is given below. \begin{small} \begin{verbatim} #include int main(void) { int idx, err; hmac_state hmac; unsigned char key[16], dst[MAXBLOCKSIZE]; unsigned long dstlen; /* register SHA-1 */ if (register_hash(&sha1_desc) == -1) { printf("Error registering SHA1\n"); return -1; } /* get index of SHA1 in hash descriptor table */ idx = find_hash("sha1"); /* we would make up our symmetric key in "key[]" here */ /* start the HMAC */ if ((err = hmac_init(&hmac, idx, key, 16)) != CRYPT_OK) { printf("Error setting up hmac: %s\n", error_to_string(err)); return -1; } /* process a few octets */ if((err = hmac_process(&hmac, "hello", 5) != CRYPT_OK) { printf("Error processing hmac: %s\n", error_to_string(err)); return -1; } /* get result (presumably to use it somehow...) */ dstlen = sizeof(dst); if ((err = hmac_done(&hmac, dst, &dstlen)) != CRYPT_OK) { printf("Error finishing hmac: %s\n", error_to_string(err)); return -1; } printf("The hmac is %lu bytes long\n", dstlen); /* return */ return 0; } \end{verbatim} \end{small} \mysection{OMAC Support} \index{OMAC} \index{CMAC} OMAC\footnote{\url{http://crypt.cis.ibaraki.ac.jp/omac/omac.html}}, which stands for \textit{One-Key CBC MAC} is an algorithm which produces a Message Authentication Code (MAC) using only a block cipher such as AES. Note: OMAC has been standardized as CMAC within NIST, for the purposes of this library OMAC and CMAC are synonymous. From an API standpoint, the OMAC routines work much like the HMAC routines. Instead, in this case a cipher is used instead of a hash. To start an OMAC state you call \index{omac\_init()} \begin{verbatim} int omac_init( omac_state *omac, int cipher, const unsigned char *key, unsigned long keylen); \end{verbatim} The \textit{omac} parameter is the state for the OMAC algorithm. The \textit{cipher} parameter is the index into the cipher\_descriptor table of the cipher\footnote{The cipher must have a 64 or 128 bit block size. Such as CAST5, Blowfish, DES, AES, Twofish, etc.} you wish to use. The \textit{key} and \textit{keylen} parameters are the keys used to authenticate the data. To send data through the algorithm call \index{omac\_process()} \begin{verbatim} int omac_process( omac_state *state, const unsigned char *in, unsigned long inlen); \end{verbatim} This will send \textit{inlen} bytes from \textit{in} through the active OMAC state \textit{state}. Returns \textbf{CRYPT\_OK} if the function succeeds. The function is not sensitive to the granularity of the data. For example, \begin{verbatim} omac_process(&mystate, "hello", 5); omac_process(&mystate, " world", 6); \end{verbatim} Would produce the same result as, \begin{verbatim} omac_process(&mystate, "hello world", 11); \end{verbatim} When you are done processing the message you can call the following to compute the message tag. \index{omac\_done()} \begin{verbatim} int omac_done( omac_state *state, unsigned char *out, unsigned long *outlen); \end{verbatim} Which will terminate the OMAC and output the \textit{tag} (MAC) to \textit{out}. Note that unlike the HMAC and other code \textit{outlen} can be smaller than the default MAC size (for instance AES would make a 16-byte tag). Part of the OMAC specification states that the output may be truncated. So if you pass in $outlen = 5$ and use AES as your cipher than the output MAC code will only be five bytes long. If \textit{outlen} is larger than the default size it is set to the default size to show how many bytes were actually used. Similar to the HMAC code the file and memory functions are also provided. To OMAC a buffer of memory in one shot use the following function. \index{omac\_memory()} \begin{verbatim} int omac_memory( int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); \end{verbatim} This will compute the OMAC of \textit{inlen} bytes of \textit{in} using the key \textit{key} of length \textit{keylen} bytes and the cipher specified by the \textit{cipher}'th entry in the cipher\_descriptor table. It will store the MAC in \textit{out} with the same rules as omac\_done. To OMAC a file use \index{omac\_file()} \begin{verbatim} int omac_file( int cipher, const unsigned char *key, unsigned long keylen, const char *filename, unsigned char *out, unsigned long *outlen); \end{verbatim} Which will OMAC the entire contents of the file specified by \textit{filename} using the key \textit{key} of length \textit{keylen} bytes and the cipher specified by the \textit{cipher}'th entry in the cipher\_descriptor table. It will store the MAC in \textit{out} with the same rules as omac\_done. To test if the OMAC code is working there is the following function: \index{omac\_test()} \begin{verbatim} int omac_test(void); \end{verbatim} Which returns {\bf CRYPT\_OK} if the code passes otherwise it returns an error code. Some example code for using the OMAC system is given below. \begin{small} \begin{verbatim} #include int main(void) { int idx, err; omac_state omac; unsigned char key[16], dst[MAXBLOCKSIZE]; unsigned long dstlen; /* register Rijndael */ if (register_cipher(&rijndael_desc) == -1) { printf("Error registering Rijndael\n"); return -1; } /* get index of Rijndael in cipher descriptor table */ idx = find_cipher("rijndael"); /* we would make up our symmetric key in "key[]" here */ /* start the OMAC */ if ((err = omac_init(&omac, idx, key, 16)) != CRYPT_OK) { printf("Error setting up omac: %s\n", error_to_string(err)); return -1; } /* process a few octets */ if((err = omac_process(&omac, "hello", 5) != CRYPT_OK) { printf("Error processing omac: %s\n", error_to_string(err)); return -1; } /* get result (presumably to use it somehow...) */ dstlen = sizeof(dst); if ((err = omac_done(&omac, dst, &dstlen)) != CRYPT_OK) { printf("Error finishing omac: %s\n", error_to_string(err)); return -1; } printf("The omac is %lu bytes long\n", dstlen); /* return */ return 0; } \end{verbatim} \end{small} \mysection{PMAC Support} The PMAC\footnote{J.Black, P.Rogaway, \textit{A Block--Cipher Mode of Operation for Parallelizable Message Authentication}} protocol is another MAC algorithm that relies solely on a symmetric-key block cipher. It uses essentially the same API as the provided OMAC code. A PMAC state is initialized with the following. \index{pmac\_init()} \begin{verbatim} int pmac_init( pmac_state *pmac, int cipher, const unsigned char *key, unsigned long keylen); \end{verbatim} Which initializes the \textit{pmac} state with the given \textit{cipher} and \textit{key} of length \textit{keylen} bytes. The chosen cipher must have a 64 or 128 bit block size (e.x. AES). To MAC data simply send it through the process function. \index{pmac\_process()} \begin{verbatim} int pmac_process( pmac_state *state, const unsigned char *in, unsigned long inlen); \end{verbatim} This will process \textit{inlen} bytes of \textit{in} in the given \textit{state}. The function is not sensitive to the granularity of the data. For example, \begin{verbatim} pmac_process(&mystate, "hello", 5); pmac_process(&mystate, " world", 6); \end{verbatim} Would produce the same result as, \begin{verbatim} pmac_process(&mystate, "hello world", 11); \end{verbatim} When a complete message has been processed the following function can be called to compute the message tag. \index{pmac\_done()} \begin{verbatim} int pmac_done( pmac_state *state, unsigned char *out, unsigned long *outlen); \end{verbatim} This will store up to \textit{outlen} bytes of the tag for the given \textit{state} into \textit{out}. Note that if \textit{outlen} is larger than the size of the tag it is set to the amount of bytes stored in \textit{out}. Similar to the OMAC code the file and memory functions are also provided. To PMAC a buffer of memory in one shot use the following function. \index{pmac\_memory()} \begin{verbatim} int pmac_memory( int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); \end{verbatim} This will compute the PMAC of \textit{msglen} bytes of \textit{msg} using the key \textit{key} of length \textit{keylen} bytes, and the cipher specified by the \textit{cipher}'th entry in the cipher\_descriptor table. It will store the MAC in \textit{out} with the same rules as pmac\_done(). To PMAC a file use \index{pmac\_file()} \begin{verbatim} int pmac_file( int cipher, const unsigned char *key, unsigned long keylen, const char *filename, unsigned char *out, unsigned long *outlen); \end{verbatim} Which will PMAC the entire contents of the file specified by \textit{filename} using the key \textit{key} of length \textit{keylen} bytes, and the cipher specified by the \textit{cipher}'th entry in the cipher\_descriptor table. It will store the MAC in \textit{out} with the same rules as pmac\_done(). To test if the PMAC code is working there is the following function: \index{pmac\_test()} \begin{verbatim} int pmac_test(void); \end{verbatim} Which returns {\bf CRYPT\_OK} if the code passes otherwise it returns an error code. \mysection{Pelican MAC} Pelican MAC is a new (experimental) MAC by the AES team that uses four rounds of AES as a \textit{mixing function}. It achieves a very high rate of processing and is potentially very secure. It requires AES to be enabled to function. You do not have to register\_cipher() AES first though as it calls AES directly. \index{pelican\_init()} \begin{verbatim} int pelican_init( pelican_state *pelmac, const unsigned char *key, unsigned long keylen); \end{verbatim} This will initialize the Pelican state with the given AES key. Once this has been done you can begin processing data. \index{pelican\_process()} \begin{verbatim} int pelican_process( pelican_state *pelmac, const unsigned char *in, unsigned long inlen); \end{verbatim} This will process \textit{inlen} bytes of \textit{in} through the Pelican MAC. It's best that you pass in multiples of 16 bytes as it makes the routine more efficient but you may pass in any length of text. You can call this function as many times as required to process an entire message. \index{pelican\_done()} \begin{verbatim} int pelican_done(pelican_state *pelmac, unsigned char *out); \end{verbatim} This terminates a Pelican MAC and writes the 16--octet tag to \textit{out}. \subsection{Example} \begin{verbatim} #include int main(void) { pelican_state pelstate; unsigned char key[32], tag[16]; int err; /* somehow initialize a key */ /* initialize pelican mac */ if ((err = pelican_init(&pelstate, /* the state */ key, /* user key */ 32 /* key length in octets */ )) != CRYPT_OK) { printf("Error initializing Pelican: %s", error_to_string(err)); return EXIT_FAILURE; } /* MAC some data */ if ((err = pelican_process(&pelstate, /* the state */ "hello world", /* data to mac */ 11 /* length of data */ )) != CRYPT_OK) { printf("Error processing Pelican: %s", error_to_string(err)); return EXIT_FAILURE; } /* Terminate the MAC */ if ((err = pelican_done(&pelstate,/* the state */ tag /* where to store the tag */ )) != CRYPT_OK) { printf("Error terminating Pelican: %s", error_to_string(err)); return EXIT_FAILURE; } /* tag[0..15] has the MAC output now */ return EXIT_SUCCESS; } \end{verbatim} \mysection{XCBC-MAC} As of LibTomCrypt v1.15, XCBC-MAC (RFC 3566) has been provided to support TLS encryption suites. Like OMAC, it computes a message authentication code by using a cipher in CBC mode. It also uses a single key which it expands into the requisite three keys for the MAC function. A XCBC--MAC state is initialized with the following function: \index{xcbc\_init()} \begin{verbatim} int xcbc_init( xcbc_state *xcbc, int cipher, const unsigned char *key, unsigned long keylen); \end{verbatim} This will initialize the XCBC--MAC state \textit{xcbc}, with the key specified in \textit{key} of length \textit{keylen} octets. The cipher indicated by the \textit{cipher} index can be either a 64 or 128--bit block cipher. This will return \textbf{CRYPT\_OK} on success. \index{LTC\_XCBC\_PURE} It is possible to use XCBC in a three key mode by OR'ing the value \textbf{LTC\_XCBC\_PURE} against the \textit{keylen} parameter. In this mode, the key is interpretted as three keys. If the cipher has a block size of $n$ octets, the first key is then $keylen - 2n$ octets and is the encryption key. The next $2n$ octets are the $K_1$ and $K_2$ padding keys (used on the last block). For example, to use AES--192 \textit{keylen} should be $24 + 2 \cdot 16 = 56$ octets. The three keys are interpretted as if they were concatenated in the \textit{key} buffer. To process data through XCBC--MAC use the following function: \index{xcbc\_process()} \begin{verbatim} int xcbc_process( xcbc_state *state, const unsigned char *in, unsigned long inlen); \end{verbatim} This will add the message octets pointed to by \textit{in} of length \textit{inlen} to the XCBC--MAC state pointed to by \textit{state}. Like the other MAC functions, the granularity of the input is not important but the order is. This will return \textbf{CRYPT\_OK} on success. To compute the MAC tag value use the following function: \index{xcbc\_done()} \begin{verbatim} int xcbc_done( xcbc_state *state, unsigned char *out, unsigned long *outlen); \end{verbatim} This will retrieve the XCBC--MAC tag from the state pointed to by \textit{state}, and store it in the array pointed to by \textit{out}. The \textit{outlen} parameter specifies the maximum size of the destination buffer, and is updated to hold the final size of the tag when the function returns. This will return \textbf{CRYPT\_OK} on success. Helper functions are provided to make parsing memory buffers and files easier. The following functions are provided: \index{xcbc\_memory()} \begin{verbatim} int xcbc_memory( int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); \end{verbatim} This will compute the XCBC--MAC of \textit{msglen} bytes of \textit{msg}, using the key \textit{key} of length \textit{keylen} bytes, and the cipher specified by the \textit{cipher}'th entry in the cipher\_descriptor table. It will store the MAC in \textit{out} with the same rules as xcbc\_done(). To xcbc a file use \index{xcbc\_file()} \begin{verbatim} int xcbc_file( int cipher, const unsigned char *key, unsigned long keylen, const char *filename, unsigned char *out, unsigned long *outlen); \end{verbatim} Which will XCBC--MAC the entire contents of the file specified by \textit{filename} using the key \textit{key} of length \textit{keylen} bytes, and the cipher specified by the \textit{cipher}'th entry in the cipher\_descriptor table. It will store the MAC in \textit{out} with the same rules as xcbc\_done(). To test XCBC--MAC for RFC 3566 compliance use the following function: \index{xcbc\_test()} \begin{verbatim} int xcbc_test(void); \end{verbatim} This will return \textbf{CRYPT\_OK} on success. This requires the AES or Rijndael descriptor be previously registered, otherwise, it will return \textbf{CRYPT\_NOP}. \mysection{F9--MAC} The F9--MAC is yet another CBC--MAC variant proposed for the 3GPP standard. Originally specified to be used with the KASUMI block cipher, it can also be used with other ciphers. For LibTomCrypt, the F9--MAC code can use any cipher. \subsection{Usage Notice} F9--MAC differs slightly from the other MAC functions in that it requires the caller to perform the final message padding. The padding quite simply is a direction bit followed by a 1 bit and enough zeros to make the message a multiple of the cipher block size. If the message is byte aligned, the padding takes on the form of a single 0x40 or 0xC0 byte followed by enough 0x00 bytes to make the message proper multiple. If the user simply wants a MAC function (hint: use OMAC) padding with a single 0x40 byte should be sufficient for security purposes and still be reasonably compatible with F9--MAC. \subsection{F9--MAC Functions} A F9--MAC state is initialized with the following function: \index{f9\_init()} \begin{verbatim} int f9_init( f9_state *f9, int cipher, const unsigned char *key, unsigned long keylen); \end{verbatim} This will initialize the F9--MAC state \textit{f9}, with the key specified in \textit{key} of length \textit{keylen} octets. The cipher indicated by the \textit{cipher} index can be either a 64 or 128--bit block cipher. This will return \textbf{CRYPT\_OK} on success. To process data through F9--MAC use the following function: \index{f9\_process()} \begin{verbatim} int f9_process( f9_state *state, const unsigned char *in, unsigned long inlen); \end{verbatim} This will add the message octets pointed to by \textit{in} of length \textit{inlen} to the F9--MAC state pointed to by \textit{state}. Like the other MAC functions, the granularity of the input is not important but the order is. This will return \textbf{CRYPT\_OK} on success. To compute the MAC tag value use the following function: \index{f9\_done()} \begin{verbatim} int f9_done( f9_state *state, unsigned char *out, unsigned long *outlen); \end{verbatim} This will retrieve the F9--MAC tag from the state pointed to by \textit{state}, and store it in the array pointed to by \textit{out}. The \textit{outlen} parameter specifies the maximum size of the destination buffer, and is updated to hold the final size of the tag when the function returns. This will return \textbf{CRYPT\_OK} on success. Helper functions are provided to make parsing memory buffers and files easier. The following functions are provided: \index{f9\_memory()} \begin{verbatim} int f9_memory( int cipher, const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); \end{verbatim} This will compute the F9--MAC of \textit{msglen} bytes of \textit{msg}, using the key \textit{key} of length \textit{keylen} bytes, and the cipher specified by the \textit{cipher}'th entry in the cipher\_descriptor table. It will store the MAC in \textit{out} with the same rules as f9\_done(). To F9--MAC a file use \index{f9\_file()} \begin{verbatim} int f9_file( int cipher, const unsigned char *key, unsigned long keylen, const char *filename, unsigned char *out, unsigned long *outlen); \end{verbatim} Which will F9--MAC the entire contents of the file specified by \textit{filename} using the key \textit{key} of length \textit{keylen} bytes, and the cipher specified by the \textit{cipher}'th entry in the cipher\_descriptor table. It will store the MAC in \textit{out} with the same rules as f9\_done(). To test f9--MAC for RFC 3566 compliance use the following function: \index{f9\_test()} \begin{verbatim} int f9_test(void); \end{verbatim} This will return \textbf{CRYPT\_OK} on success. This requires the AES or Rijndael descriptor be previously registered, otherwise, it will return \textbf{CRYPT\_NOP}. \chapter{Pseudo-Random Number Generators} \mysection{Core Functions} The library provides an array of core functions for Pseudo-Random Number Generators (PRNGs) as well. A cryptographic PRNG is used to expand a shorter bit string into a longer bit string. PRNGs are used wherever random data is required such as Public Key (PK) key generation. There is a universal structure called \textit{prng\_state}. To initialize a PRNG call: \index{PRNG start} \begin{verbatim} int XXX_start(prng_state *prng); \end{verbatim} This will setup the PRNG for future use and not seed it. In order for the PRNG to be cryptographically useful you must give it entropy. Ideally you'd have some OS level source to tap like in UNIX. To add entropy to the PRNG call: \index{PRNG add\_entropy} \begin{verbatim} int XXX_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); \end{verbatim} Which returns {\bf CRYPT\_OK} if the entropy was accepted. Once you think you have enough entropy you call another function to put the entropy into action. \index{PRNG ready} \begin{verbatim} int XXX_ready(prng_state *prng); \end{verbatim} Which returns {\bf CRYPT\_OK} if it is ready. Finally to actually read bytes call: \index{PRNG read} \begin{verbatim} unsigned long XXX_read(unsigned char *out, unsigned long outlen, prng_state *prng); \end{verbatim} Which returns the number of bytes read from the PRNG. When you are finished with a PRNG state you call the following. \index{PRNG done} \begin{verbatim} void XXX_done(prng_state *prng); \end{verbatim} This will terminate a PRNG state and free any memory (if any) allocated. To export a PRNG state so that you can later resume the PRNG call the following. \index{PRNG export} \begin{verbatim} int XXX_export(unsigned char *out, unsigned long *outlen, prng_state *prng); \end{verbatim} This will write a \textit{PRNG state} to the buffer \textit{out} of length \textit{outlen} bytes. The idea of the export is meant to be used as a \textit{seed file}. That is, when the program starts up there will not likely be that much entropy available. To import a state to seed a PRNG call the following function. \index{PRNG import} \begin{verbatim} int XXX_import(const unsigned char *in, unsigned long inlen, prng_state *prng); \end{verbatim} This will call the start and add\_entropy functions of the given PRNG. It will use the state in \textit{in} of length \textit{inlen} as the initial seed. You must pass the same seed length as was exported by the corresponding export function. Note that importing a state will not \textit{resume} the PRNG from where it left off. That is, if you export a state, emit (say) 8 bytes and then import the previously exported state the next 8 bytes will not specifically equal the 8 bytes you generated previously. When a program is first executed the normal course of operation is: \begin{enumerate} \item Gather entropy from your sources for a given period of time or number of events. \item Start, use your entropy via add\_entropy and ready the PRNG yourself. \end{enumerate} When your program is finished you simply call the export function and save the state to a medium (disk, flash memory, etc). The next time your application starts up you can detect the state, feed it to the import function and go on your way. It is ideal that (as soon as possible) after start up you export a fresh state. This helps in the case that the program aborts or the machine is powered down without being given a chance to exit properly. Note that even if you have a state to import it is important to add new entropy to the state. However, there is less pressure to do so. To test a PRNG for operational conformity call the following functions. \index{PRNG test} \begin{verbatim} int XXX_test(void); \end{verbatim} This will return \textbf{CRYPT\_OK} if PRNG is operating properly. \subsection{Remarks} It is possible to be adding entropy and reading from a PRNG at the same time. For example, if you first seed the PRNG and call ready() you can now read from it. You can also keep adding new entropy to it. The new entropy will not be used in the PRNG until ready() is called again. This allows the PRNG to be used and re-seeded at the same time. No real error checking is guaranteed to see if the entropy is sufficient, or if the PRNG is even in a ready state before reading. \subsection{Example} Below is a simple snippet to read 10 bytes from Yarrow. It is important to note that this snippet is {\bf NOT} secure since the entropy added is not random. \begin{verbatim} #include int main(void) { prng_state prng; unsigned char buf[10]; int err; /* start it */ if ((err = yarrow_start(&prng)) != CRYPT_OK) { printf("Start error: %s\n", error_to_string(err)); } /* add entropy */ if ((err = yarrow_add_entropy("hello world", 11, &prng)) != CRYPT_OK) { printf("Add_entropy error: %s\n", error_to_string(err)); } /* ready and read */ if ((err = yarrow_ready(&prng)) != CRYPT_OK) { printf("Ready error: %s\n", error_to_string(err)); } printf("Read %lu bytes from yarrow\n", yarrow_read(buf, sizeof(buf), &prng)); return 0; } \end{verbatim} \mysection{PRNG Descriptors} \index{PRNG Descriptor} PRNGs have descriptors that allow plugin driven functions to be created using PRNGs. The plugin descriptors are stored in the structure \textit{prng\_descriptor}. The format of an element is: \begin{verbatim} struct _prng_descriptor { char *name; int export_size; /* size in bytes of exported state */ int (*start) (prng_state *); int (*add_entropy)(const unsigned char *, unsigned long, prng_state *); int (*ready) (prng_state *); unsigned long (*read)(unsigned char *, unsigned long len, prng_state *); void (*done)(prng_state *); int (*export)(unsigned char *, unsigned long *, prng_state *); int (*import)(const unsigned char *, unsigned long, prng_state *); int (*test)(void); }; \end{verbatim} To find a PRNG in the descriptor table the following function can be used: \index{find\_prng()} \begin{verbatim} int find_prng(const char *name); \end{verbatim} This will search the PRNG descriptor table for the PRNG named \textit{name}. It will return -1 if the PRNG is not found, otherwise, it returns the index into the descriptor table. Just like the ciphers and hashes, you must register your prng before you can use it. The two functions provided work exactly as those for the cipher registry functions. They are the following: \index{register\_prng()} \index{unregister\_prng()} \begin{verbatim} int register_prng(const struct _prng_descriptor *prng); int unregister_prng(const struct _prng_descriptor *prng); \end{verbatim} The register function will register the PRNG, and return the index into the table where it was placed (or -1 for error). It will avoid registering the same descriptor twice, and will return the index of the current placement in the table if the caller attempts to register it more than once. The unregister function will return \textbf{CRYPT\_OK} if the PRNG was found and removed. Otherwise, it returns \textbf{CRYPT\_ERROR}. \subsection{PRNGs Provided} \begin{figure}[here] \begin{center} \begin{small} \begin{tabular}{|c|c|l|} \hline \textbf{Name} & \textbf{Descriptor} & \textbf{Usage} \\ \hline Yarrow & yarrow\_desc & Fast short-term PRNG \\ \hline Fortuna & fortuna\_desc & Fast long-term PRNG (recommended) \\ \hline RC4 & rc4\_desc & Stream Cipher \\ \hline SOBER-128 & sober128\_desc & Stream Cipher (also very fast PRNG) \\ \hline \end{tabular} \end{small} \end{center} \caption{List of Provided PRNGs} \end{figure} \subsubsection{Yarrow} Yarrow is fast PRNG meant to collect an unspecified amount of entropy from sources (keyboard, mouse, interrupts, etc), and produce an unbounded string of random bytes. \textit{Note:} This PRNG is still secure for most tasks but is no longer recommended. Users should use Fortuna instead. \subsubsection{Fortuna} Fortuna is a fast attack tolerant and more thoroughly designed PRNG suitable for long term usage. It is faster than the default implementation of Yarrow\footnote{Yarrow has been implemented to work with most cipher and hash combos based on which you have chosen to build into the library.} while providing more security. Fortuna is slightly less flexible than Yarrow in the sense that it only works with the AES block cipher and SHA--256 hash function. Technically, Fortuna will work with any block cipher that accepts a 256--bit key, and any hash that produces at least a 256--bit output. However, to make the implementation simpler it has been fixed to those choices. Fortuna is more secure than Yarrow in the sense that attackers who learn parts of the entropy being added to the PRNG learn far less about the state than that of Yarrow. Without getting into to many details Fortuna has the ability to recover from state determination attacks where the attacker starts to learn information from the PRNGs output about the internal state. Yarrow on the other hand, cannot recover from that problem until new entropy is added to the pool and put to use through the ready() function. \subsubsection{RC4} RC4 is an old stream cipher that can also double duty as a PRNG in a pinch. You key RC4 by calling add\_entropy(), and setup the key by calling ready(). You can only add up to 256 bytes via add\_entropy(). When you read from RC4, the output is XOR'ed against your buffer you provide. In this manner, you can use rc4\_read() as an encrypt (and decrypt) function. You really should not use RC4. This is not because RC4 is weak, (though biases are known to exist) but simply due to the fact that faster alternatives exist. \subsubsection{SOBER-128} SOBER--128 is a stream cipher designed by the QUALCOMM Australia team. Like RC4, you key it by calling add\_entropy(). There is no need to call ready() for this PRNG as it does not do anything. Note: this cipher has several oddities about how it operates. The first call to add\_entropy() sets the cipher's key. Every other time call to the add\_entropy() function sets the cipher's IV variable. The IV mechanism allows you to encrypt several messages with the same key, and not re--use the same key material. Unlike Yarrow and Fortuna, all of the entropy (and hence security) of this algorithm rests in the data you pass it on the \textbf{first} call to add\_entropy(). All buffers sent to add\_entropy() must have a length that is a multiple of four bytes. Like RC4, the output of SOBER--128 is XOR'ed against the buffer you provide it. In this manner, you can use sober128\_read() as an encrypt (and decrypt) function. Since SOBER-128 has a fixed keying scheme, and is very fast (faster than RC4) the ideal usage of SOBER-128 is to key it from the output of Fortuna (or Yarrow), and use it to encrypt messages. It is also ideal for simulations which need a high quality (and fast) stream of bytes. \subsubsection{Example Usage} \begin{small} \begin{verbatim} #include int main(void) { prng_state prng; unsigned char buf[32]; int err; if ((err = rc4_start(&prng)) != CRYPT_OK) { printf("RC4 init error: %s\n", error_to_string(err)); exit(-1); } /* use "key" as the key */ if ((err = rc4_add_entropy("key", 3, &prng)) != CRYPT_OK) { printf("RC4 add entropy error: %s\n", error_to_string(err)); exit(-1); } /* setup RC4 for use */ if ((err = rc4_ready(&prng)) != CRYPT_OK) { printf("RC4 ready error: %s\n", error_to_string(err)); exit(-1); } /* encrypt buffer */ strcpy(buf,"hello world"); if (rc4_read(buf, 11, &prng) != 11) { printf("RC4 read error\n"); exit(-1); } return 0; } \end{verbatim} \end{small} To decrypt you have to do the exact same steps. \mysection{The Secure RNG} \index{Secure RNG} An RNG is related to a PRNG in many ways, except that it does not expand a smaller seed to get the data. They generate their random bits by performing some computation on fresh input bits. Possibly the hardest thing to get correctly in a cryptosystem is the PRNG. Computers are deterministic that try hard not to stray from pre--determined paths. This makes gathering entropy needed to seed a PRNG a hard task. There is one small function that may help on certain platforms: \index{rng\_get\_bytes()} \begin{verbatim} unsigned long rng_get_bytes( unsigned char *buf, unsigned long len, void (*callback)(void)); \end{verbatim} Which will try one of three methods of getting random data. The first is to open the popular \textit{/dev/random} device which on most *NIX platforms provides cryptographic random bits\footnote{This device is available in Windows through the Cygwin compiler suite. It emulates \textit{/dev/random} via the Microsoft CSP.}. The second method is to try the Microsoft Cryptographic Service Provider, and read the RNG. The third method is an ANSI C clock drift method that is also somewhat popular but gives bits of lower entropy. The \textit{callback} parameter is a pointer to a function that returns void. It is used when the slower ANSI C RNG must be used so the calling application can still work. This is useful since the ANSI C RNG has a throughput of roughly three bytes a second. The callback pointer may be set to {\bf NULL} to avoid using it if you do not want to. The function returns the number of bytes actually read from any RNG source. There is a function to help setup a PRNG as well: \index{rng\_make\_prng()} \begin{verbatim} int rng_make_prng( int bits, int wprng, prng_state *prng, void (*callback)(void)); \end{verbatim} This will try to initialize the prng with a state of at least \textit{bits} of entropy. The \textit{callback} parameter works much like the callback in \textit{rng\_get\_bytes()}. It is highly recommended that you use this function to setup your PRNGs unless you have a platform where the RNG does not work well. Example usage of this function is given below: \begin{small} \begin{verbatim} #include int main(void) { ecc_key mykey; prng_state prng; int err; /* register yarrow */ if (register_prng(&yarrow_desc) == -1) { printf("Error registering Yarrow\n"); return -1; } /* setup the PRNG */ if ((err = rng_make_prng(128, find_prng("yarrow"), &prng, NULL)) != CRYPT_OK) { printf("Error setting up PRNG, %s\n", error_to_string(err)); return -1; } /* make a 192-bit ECC key */ if ((err = ecc_make_key(&prng, find_prng("yarrow"), 24, &mykey)) != CRYPT_OK) { printf("Error making key: %s\n", error_to_string(err)); return -1; } return 0; } \end{verbatim} \end{small} \subsection{The Secure PRNG Interface} It is possible to access the secure RNG through the PRNG interface, and in turn use it within dependent functions such as the PK API. This simplifies the cryptosystem on platforms where the secure RNG is fast. The secure PRNG never requires to be started, that is you need not call the start, add\_entropy, or ready functions. For example, consider the previous example using this PRNG. \begin{small} \begin{verbatim} #include int main(void) { ecc_key mykey; int err; /* register SPRNG */ if (register_prng(&sprng_desc) == -1) { printf("Error registering SPRNG\n"); return -1; } /* make a 192-bit ECC key */ if ((err = ecc_make_key(NULL, find_prng("sprng"), 24, &mykey)) != CRYPT_OK) { printf("Error making key: %s\n", error_to_string(err)); return -1; } return 0; } \end{verbatim} \end{small} \chapter{RSA Public Key Cryptography} \mysection{Introduction} RSA wrote the PKCS \#1 specifications which detail RSA Public Key Cryptography. In the specifications are padding algorithms for encryption and signatures. The standard includes the \textit{v1.5} and \textit{v2.1} algorithms. To simplify matters a little the v2.1 encryption and signature padding algorithms are called OAEP and PSS respectively. \mysection{PKCS \#1 Padding} PKCS \#1 v1.5 padding is so simple that both signature and encryption padding are performed by the same function. Note: the signature padding does \textbf{not} include the ASN.1 padding required. That is performed by the rsa\_sign\_hash\_ex() function documented later on in this chapter. \subsection{PKCS \#1 v1.5 Encoding} The following function performs PKCS \#1 v1.5 padding: \index{pkcs\_1\_v1\_5\_encode()} \begin{verbatim} int pkcs_1_v1_5_encode( const unsigned char *msg, unsigned long msglen, int block_type, unsigned long modulus_bitlen, prng_state *prng, int prng_idx, unsigned char *out, unsigned long *outlen); \end{verbatim} This will encode the message pointed to by \textit{msg} of length \textit{msglen} octets. The \textit{block\_type} parameter must be set to \textbf{LTC\_PKCS\_1\_EME} to perform encryption padding. It must be set to \textbf{LTC\_PKCS\_1\_EMSA} to perform signature padding. The \textit{modulus\_bitlen} parameter indicates the length of the modulus in bits. The padded data is stored in \textit{out} with a length of \textit{outlen} octets. The output will not be longer than the modulus which helps allocate the correct output buffer size. Only encryption padding requires a PRNG. When performing signature padding the \textit{prng\_idx} parameter may be left to zero as it is not checked for validity. \subsection{PKCS \#1 v1.5 Decoding} The following function performs PKCS \#1 v1.5 de--padding: \index{pkcs\_1\_v1\_5\_decode()} \begin{verbatim} int pkcs_1_v1_5_decode( const unsigned char *msg, unsigned long msglen, int block_type, unsigned long modulus_bitlen, unsigned char *out, unsigned long *outlen, int *is_valid); \end{verbatim} \index{LTC\_PKCS\_1\_EME} \index{LTC\_PKCS\_1\_EMSA} This will remove the PKCS padding data pointed to by \textit{msg} of length \textit{msglen}. The decoded data is stored in \textit{out} of length \textit{outlen}. If the padding is valid, a 1 is stored in \textit{is\_valid}, otherwise, a 0 is stored. The \textit{block\_type} parameter must be set to either \textbf{LTC\_PKCS\_1\_EME} or \textbf{LTC\_PKCS\_1\_EMSA} depending on whether encryption or signature padding is being removed. \mysection{PKCS \#1 v2.1 Encryption} PKCS \#1 RSA Encryption amounts to OAEP padding of the input message followed by the modular exponentiation. As far as this portion of the library is concerned we are only dealing with th OAEP padding of the message. \subsection{OAEP Encoding} The following function performs PKCS \#1 v2.1 encryption padding: \index{pkcs\_1\_oaep\_encode()} \begin{alltt} int pkcs_1_oaep_encode( const unsigned char *msg, unsigned long msglen, const unsigned char *lparam, unsigned long lparamlen, unsigned long modulus_bitlen, prng_state *prng, int prng_idx, int hash_idx, unsigned char *out, unsigned long *outlen); \end{alltt} This accepts \textit{msg} as input of length \textit{msglen} which will be OAEP padded. The \textit{lparam} variable is an additional system specific tag that can be applied to the encoding. This is useful to identify which system encoded the message. If no variance is desired then \textit{lparam} can be set to \textbf{NULL}. OAEP encoding requires the length of the modulus in bits in order to calculate the size of the output. This is passed as the parameter \textit{modulus\_bitlen}. \textit{hash\_idx} is the index into the hash descriptor table of the hash desired. PKCS \#1 allows any hash to be used but both the encoder and decoder must use the same hash in order for this to succeed. The size of hash output affects the maximum sized input message. \textit{prng\_idx} and \textit{prng} are the random number generator arguments required to randomize the padding process. The padded message is stored in \textit{out} along with the length in \textit{outlen}. If $h$ is the length of the hash and $m$ the length of the modulus (both in octets) then the maximum payload for \textit{msg} is $m - 2h - 2$. For example, with a $1024$--bit RSA key and SHA--1 as the hash the maximum payload is $86$ bytes. Note that when the message is padded it still has not been RSA encrypted. You must pass the output of this function to rsa\_exptmod() to encrypt it. \subsection{OAEP Decoding} \index{pkcs\_1\_oaep\_decode()} \begin{alltt} int pkcs_1_oaep_decode( const unsigned char *msg, unsigned long msglen, const unsigned char *lparam, unsigned long lparamlen, unsigned long modulus_bitlen, int hash_idx, unsigned char *out, unsigned long *outlen, int *res); \end{alltt} This function decodes an OAEP encoded message and outputs the original message that was passed to the OAEP encoder. \textit{msg} is the output of pkcs\_1\_oaep\_encode() of length \textit{msglen}. \textit{lparam} is the same system variable passed to the OAEP encoder. If it does not match what was used during encoding this function will not decode the packet. \textit{modulus\_bitlen} is the size of the RSA modulus in bits and must match what was used during encoding. Similarly the \textit{hash\_idx} index into the hash descriptor table must match what was used during encoding. If the function succeeds it decodes the OAEP encoded message into \textit{out} of length \textit{outlen} and stores a $1$ in \textit{res}. If the packet is invalid it stores $0$ in \textit{res} and if the function fails for another reason it returns an error code. \mysection{PKCS \#1 Digital Signatures} \subsection{PSS Encoding} PSS encoding is the second half of the PKCS \#1 standard which is padding to be applied to messages that are signed. \index{pkcs\_1\_pss\_encode()} \begin{alltt} int pkcs_1_pss_encode( const unsigned char *msghash, unsigned long msghashlen, unsigned long saltlen, prng_state *prng, int prng_idx, int hash_idx, unsigned long modulus_bitlen, unsigned char *out, unsigned long *outlen); \end{alltt} This function assumes the message to be PSS encoded has previously been hashed. The input hash \textit{msghash} is of length \textit{msghashlen}. PSS allows a variable length random salt (it can be zero length) to be introduced in the signature process. \textit{hash\_idx} is the index into the hash descriptor table of the hash to use. \textit{prng\_idx} and \textit{prng} are the random number generator information required for the salt. Similar to OAEP encoding \textit{modulus\_bitlen} is the size of the RSA modulus (in bits). It limits the size of the salt. If $m$ is the length of the modulus $h$ the length of the hash output (in octets) then there can be $m - h - 2$ bytes of salt. This function does not actually sign the data it merely pads the hash of a message so that it can be processed by rsa\_exptmod(). \subsection{PSS Decoding} To decode a PSS encoded signature block you have to use the following. \index{pkcs\_1\_pss\_decode()} \begin{alltt} int pkcs_1_pss_decode( const unsigned char *msghash, unsigned long msghashlen, const unsigned char *sig, unsigned long siglen, unsigned long saltlen, int hash_idx, unsigned long modulus_bitlen, int *res); \end{alltt} This will decode the PSS encoded message in \textit{sig} of length \textit{siglen} and compare it to values in \textit{msghash} of length \textit{msghashlen}. If the block is a valid PSS block and the decoded hash equals the hash supplied \textit{res} is set to non--zero. Otherwise, it is set to zero. The rest of the parameters are as in the PSS encode call. It's important to use the same \textit{saltlen} and hash for both encoding and decoding as otherwise the procedure will not work. \mysection{RSA Key Operations} \subsection{Background} RSA is a public key algorithm that is based on the inability to find the \textit{e-th} root modulo a composite of unknown factorization. Normally the difficulty of breaking RSA is associated with the integer factoring problem but they are not strictly equivalent. The system begins with with two primes $p$ and $q$ and their product $N = pq$. The order or \textit{Euler totient} of the multiplicative sub-group formed modulo $N$ is given as $\phi(N) = (p - 1)(q - 1)$ which can be reduced to $\mbox{lcm}(p - 1, q - 1)$. The public key consists of the composite $N$ and some integer $e$ such that $\mbox{gcd}(e, \phi(N)) = 1$. The private key consists of the composite $N$ and the inverse of $e$ modulo $\phi(N)$ often simply denoted as $de \equiv 1\mbox{ }(\mbox{mod }\phi(N))$. A person who wants to encrypt with your public key simply forms an integer (the plaintext) $M$ such that $1 < M < N-2$ and computes the ciphertext $C = M^e\mbox{ }(\mbox{mod }N)$. Since finding the inverse exponent $d$ given only $N$ and $e$ appears to be intractable only the owner of the private key can decrypt the ciphertext and compute $C^d \equiv \left (M^e \right)^d \equiv M^1 \equiv M\mbox{ }(\mbox{mod }N)$. Similarly the owner of the private key can sign a message by \textit{decrypting} it. Others can verify it by \textit{encrypting} it. Currently RSA is a difficult system to cryptanalyze provided that both primes are large and not close to each other. Ideally $e$ should be larger than $100$ to prevent direct analysis. For example, if $e$ is three and you do not pad the plaintext to be encrypted than it is possible that $M^3 < N$ in which case finding the cube-root would be trivial. The most often suggested value for $e$ is $65537$ since it is large enough to make such attacks impossible and also well designed for fast exponentiation (requires 16 squarings and one multiplication). It is important to pad the input to RSA since it has particular mathematical structure. For instance $M_1^dM_2^d = (M_1M_2)^d$ which can be used to forge a signature. Suppose $M_3 = M_1M_2$ is a message you want to have a forged signature for. Simply get the signatures for $M_1$ and $M_2$ on their own and multiply the result together. Similar tricks can be used to deduce plaintexts from ciphertexts. It is important not only to sign the hash of documents only but also to pad the inputs with data to remove such structure. \subsection{RSA Key Generation} For RSA routines a single \textit{rsa\_key} structure is used. To make a new RSA key call: \index{rsa\_make\_key()} \begin{verbatim} int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key); \end{verbatim} Where \textit{wprng} is the index into the PRNG descriptor array. The \textit{size} parameter is the size in bytes of the RSA modulus desired. The \textit{e} parameter is the encryption exponent desired, typical values are 3, 17, 257 and 65537. Stick with 65537 since it is big enough to prevent trivial math attacks, and not super slow. The \textit{key} parameter is where the constructed key is placed. All keys must be at least 128 bytes, and no more than 512 bytes in size (\textit{that is from 1024 to 4096 bits}). \index{rsa\_free()} Note: the \textit{rsa\_make\_key()} function allocates memory at run--time when you make the key. Make sure to call \textit{rsa\_free()} (see below) when you are finished with the key. If \textit{rsa\_make\_key()} fails it will automatically free the memory allocated. \index{PK\_PRIVATE} \index{PK\_PUBLIC} There are two types of RSA keys. The types are {\bf PK\_PRIVATE} and {\bf PK\_PUBLIC}. The first type is a private RSA key which includes the CRT parameters\footnote{As of v0.99 the PK\_PRIVATE\_OPTIMIZED type has been deprecated, and has been replaced by the PK\_PRIVATE type.} in the form of a RSAPrivateKey (PKCS \#1 compliant). The second type, is a public RSA key which only includes the modulus and public exponent. It takes the form of a RSAPublicKey (PKCS \#1 compliant). \subsection{RSA Exponentiation} To do raw work with the RSA function, that is without padding, use the following function: \index{rsa\_exptmod()} \begin{verbatim} int rsa_exptmod(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, int which, rsa_key *key); \end{verbatim} This will load the bignum from \textit{in} as a big endian integer in the format PKCS \#1 specifies, raises it to either \textit{e} or \textit{d} and stores the result in \textit{out} and the size of the result in \textit{outlen}. \textit{which} is set to {\bf PK\_PUBLIC} to use \textit{e} (i.e. for encryption/verifying) and set to {\bf PK\_PRIVATE} to use \textit{d} as the exponent (i.e. for decrypting/signing). Note: the output of this function is zero--padded as per PKCS \#1 specification. This allows this routine to work with PKCS \#1 padding functions properly. \mysection{RSA Key Encryption} Normally RSA is used to encrypt short symmetric keys which are then used in block ciphers to encrypt a message. To facilitate encrypting short keys the following functions have been provided. \index{rsa\_encrypt\_key()} \begin{verbatim} int rsa_encrypt_key( const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, const unsigned char *lparam, unsigned long lparamlen, prng_state *prng, int prng_idx, int hash_idx, rsa_key *key); \end{verbatim} This function will OAEP pad \textit{in} of length \textit{inlen} bytes, RSA encrypt it, and store the ciphertext in \textit{out} of length \textit{outlen} octets. The \textit{lparam} and \textit{lparamlen} are the same parameters you would pass to \index{pkcs\_1\_oaep\_encode()} pkcs\_1\_oaep\_encode(). \subsection{Extended Encryption} As of v1.15, the library supports both v1.5 and v2.1 PKCS \#1 style paddings in these higher level functions. The following is the extended encryption function: \index{rsa\_encrypt\_key\_ex()} \begin{verbatim} int rsa_encrypt_key_ex( const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, const unsigned char *lparam, unsigned long lparamlen, prng_state *prng, int prng_idx, int hash_idx, int padding, rsa_key *key); \end{verbatim} \index{LTC\_PKCS\_1\_OAEP} \index{LTC\_PKCS\_1\_V1\_5} The parameters are all the same as for rsa\_encrypt\_key() except for the addition of the \textit{padding} parameter. It must be set to \textbf{LTC\_PKCS\_1\_V1\_5} to perform v1.5 encryption, or set to \textbf{LTC\_PKCS\_1\_OAEP} to perform v2.1 encryption. When performing v1.5 encryption, the hash and lparam parameters are totally ignored and can be set to \textbf{NULL} or zero (respectively). \mysection{RSA Key Decryption} \index{rsa\_decrypt\_key()} \begin{verbatim} int rsa_decrypt_key( const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, const unsigned char *lparam, unsigned long lparamlen, int hash_idx, int *stat, rsa_key *key); \end{verbatim} This function will RSA decrypt \textit{in} of length \textit{inlen} then OAEP de-pad the resulting data and store it in \textit{out} of length \textit{outlen}. The \textit{lparam} and \textit{lparamlen} are the same parameters you would pass to pkcs\_1\_oaep\_decode(). If the RSA decrypted data is not a valid OAEP packet then \textit{stat} is set to $0$. Otherwise, it is set to $1$. \subsection{Extended Decryption} As of v1.15, the library supports both v1.5 and v2.1 PKCS \#1 style paddings in these higher level functions. The following is the extended decryption function: \index{rsa\_decrypt\_key\_ex()} \begin{verbatim} int rsa_decrypt_key_ex( const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, const unsigned char *lparam, unsigned long lparamlen, int hash_idx, int padding, int *stat, rsa_key *key); \end{verbatim} Similar to the extended encryption, the new parameter \textit{padding} indicates which version of the PKCS \#1 standard to use. It must be set to \textbf{LTC\_PKCS\_1\_V1\_5} to perform v1.5 decryption, or set to \textbf{LTC\_PKCS\_1\_OAEP} to perform v2.1 decryption. When performing v1.5 decryption, the hash and lparam parameters are totally ignored and can be set to \textbf{NULL} or zero (respectively). \mysection{RSA Signature Generation} Similar to RSA key encryption RSA is also used to \textit{digitally sign} message digests (hashes). To facilitate this process the following functions have been provided. \index{rsa\_sign\_hash()} \begin{verbatim} int rsa_sign_hash(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, prng_state *prng, int prng_idx, int hash_idx, unsigned long saltlen, rsa_key *key); \end{verbatim} This will PSS encode the message digest pointed to by \textit{in} of length \textit{inlen} octets. Next, the PSS encoded hash will be RSA \textit{signed} and the output stored in the buffer pointed to by \textit{out} of length \textit{outlen} octets. The \textit{hash\_idx} parameter indicates which hash will be used to create the PSS encoding. It should be the same as the hash used to hash the message being signed. The \textit{saltlen} parameter indicates the length of the desired salt, and should typically be small. A good default value is between 8 and 16 octets. Strictly, it must be small than $modulus\_len - hLen - 2$ where \textit{modulus\_len} is the size of the RSA modulus (in octets), and \textit{hLen} is the length of the message digest produced by the chosen hash. \subsection{Extended Signatures} As of v1.15, the library supports both v1.5 and v2.1 signatures. The extended signature generation function has the following prototype: \index{rsa\_sign\_hash\_ex()} \begin{verbatim} int rsa_sign_hash_ex( const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, int padding, prng_state *prng, int prng_idx, int hash_idx, unsigned long saltlen, rsa_key *key); \end{verbatim} This will PKCS encode the message digest pointed to by \textit{in} of length \textit{inlen} octets. Next, the PKCS encoded hash will be RSA \textit{signed} and the output stored in the buffer pointed to by \textit{out} of length \textit{outlen} octets. The \textit{padding} parameter must be set to \textbf{LTC\_PKCS\_1\_V1\_5} to produce a v1.5 signature, otherwise, it must be set to \textbf{LTC\_PKCS\_1\_PSS} to produce a v2.1 signature. When performing a v1.5 signature the \textit{prng}, \textit{prng\_idx}, and \textit{hash\_idx} parameters are not checked and can be left to any values such as $\lbrace$\textbf{NULL}, 0, 0$\rbrace$. \mysection{RSA Signature Verification} \index{rsa\_verify\_hash()} \begin{verbatim} int rsa_verify_hash(const unsigned char *sig, unsigned long siglen, const unsigned char *msghash, unsigned long msghashlen, int hash_idx, unsigned long saltlen, int *stat, rsa_key *key); \end{verbatim} This will RSA \textit{verify} the signature pointed to by \textit{sig} of length \textit{siglen} octets. Next, the RSA decoded data is PSS decoded and the extracted hash is compared against the message digest pointed to by \textit{msghash} of length \textit{msghashlen} octets. If the RSA decoded data is not a valid PSS message, or if the PSS decoded hash does not match the \textit{msghash} value, \textit{res} is set to $0$. Otherwise, if the function succeeds, and signature is valid \textit{res} is set to $1$. \subsection{Extended Verification} As of v1.15, the library supports both v1.5 and v2.1 signature verification. The extended signature verification function has the following prototype: \index{rsa\_verify\_hash\_ex()} \begin{verbatim} int rsa_verify_hash_ex( const unsigned char *sig, unsigned long siglen, const unsigned char *hash, unsigned long hashlen, int padding, int hash_idx, unsigned long saltlen, int *stat, rsa_key *key); \end{verbatim} This will RSA \textit{verify} the signature pointed to by \textit{sig} of length \textit{siglen} octets. Next, the RSA decoded data is PKCS decoded and the extracted hash is compared against the message digest pointed to by \textit{msghash} of length \textit{msghashlen} octets. If the RSA decoded data is not a valid PSS message, or if the PKCS decoded hash does not match the \textit{msghash} value, \textit{res} is set to $0$. Otherwise, if the function succeeds, and signature is valid \textit{res} is set to $1$. The \textit{padding} parameter must be set to \textbf{LTC\_PKCS\_1\_V1\_5} to perform a v1.5 verification. Otherwise, it must be set to \textbf{LTC\_PKCS\_1\_PSS} to perform a v2.1 verification. When performing a v1.5 verification the \textit{hash\_idx} parameter is ignored. \mysection{RSA Encryption Example} \begin{small} \begin{verbatim} #include int main(void) { int err, hash_idx, prng_idx, res; unsigned long l1, l2; unsigned char pt[16], pt2[16], out[1024]; rsa_key key; /* register prng/hash */ if (register_prng(&sprng_desc) == -1) { printf("Error registering sprng"); return EXIT_FAILURE; } /* register a math library (in this case TomsFastMath) ltc_mp = tfm_desc; if (register_hash(&sha1_desc) == -1) { printf("Error registering sha1"); return EXIT_FAILURE; } hash_idx = find_hash("sha1"); prng_idx = find_prng("sprng"); /* make an RSA-1024 key */ if ((err = rsa_make_key(NULL, /* PRNG state */ prng_idx, /* PRNG idx */ 1024/8, /* 1024-bit key */ 65537, /* we like e=65537 */ &key) /* where to store the key */ ) != CRYPT_OK) { printf("rsa_make_key %s", error_to_string(err)); return EXIT_FAILURE; } /* fill in pt[] with a key we want to send ... */ l1 = sizeof(out); if ((err = rsa_encrypt_key(pt, /* data we wish to encrypt */ 16, /* data is 16 bytes long */ out, /* where to store ciphertext */ &l1, /* length of ciphertext */ "TestApp", /* our lparam for this program */ 7, /* lparam is 7 bytes long */ NULL, /* PRNG state */ prng_idx, /* prng idx */ hash_idx, /* hash idx */ &key) /* our RSA key */ ) != CRYPT_OK) { printf("rsa_encrypt_key %s", error_to_string(err)); return EXIT_FAILURE; } /* now let's decrypt the encrypted key */ l2 = sizeof(pt2); if ((err = rsa_decrypt_key(out, /* encrypted data */ l1, /* length of ciphertext */ pt2, /* where to put plaintext */ &l2, /* plaintext length */ "TestApp", /* lparam for this program */ 7, /* lparam is 7 bytes long */ hash_idx, /* hash idx */ &res, /* validity of data */ &key) /* our RSA key */ ) != CRYPT_OK) { printf("rsa_decrypt_key %s", error_to_string(err)); return EXIT_FAILURE; } /* if all went well pt == pt2, l2 == 16, res == 1 */ } \end{verbatim} \end{small} \mysection{RSA Key Format} The RSA key format adopted for exporting and importing keys is the PKCS \#1 format defined by the ASN.1 constructs known as RSAPublicKey and RSAPrivateKey. Additionally, the OpenSSL key format is supported by the import function only. \subsection{RSA Key Export} To export a RSA key use the following function. \index{rsa\_export()} \begin{verbatim} int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key); \end{verbatim} This will export the RSA key in either a RSAPublicKey or RSAPrivateKey (PKCS \#1 types) depending on the value of \textit{type}. When it is set to \textbf{PK\_PRIVATE} the export format will be RSAPrivateKey and otherwise it will be RSAPublicKey. \subsection{RSA Key Import} To import a RSA key use the following function. \index{rsa\_import()} \begin{verbatim} int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key); \end{verbatim} This will import the key stored in \textit{inlen} and import it to \textit{key}. If the function fails it will automatically free any allocated memory. This function can import both RSAPublicKey and RSAPrivateKey formats. As of v1.06 this function can also import OpenSSL DER formatted public RSA keys. They are essentially encapsulated RSAPublicKeys. LibTomCrypt will import the key, strip off the additional data (it's the preferred hash) and fill in the rsa\_key structure as if it were a native RSAPublicKey. Note that there is no function provided to export in this format. \chapter{Elliptic Curve Cryptography} \mysection{Background} The library provides a set of core ECC functions as well that are designed to be the Elliptic Curve analogy of all of the Diffie-Hellman routines in the previous chapter. Elliptic curves (of certain forms) have the benefit that they are harder to attack (no sub-exponential attacks exist unlike normal DH crypto) in fact the fastest attack requires the square root of the order of the base point in time. That means if you use a base point of order $2^{192}$ (which would represent a 192-bit key) then the work factor is $2^{96}$ in order to find the secret key. The curves in this library are taken from the following website: \begin{verbatim} http://csrc.nist.gov/cryptval/dss.htm \end{verbatim} As of v1.15 three new curves from the SECG standards are also included they are the secp112r1, secp128r1, and secp160r1 curves. These curves were added to support smaller devices which do not need as large keys for security. They are all curves over the integers modulo a prime. The curves have the basic equation that is: \begin{equation} y^2 = x^3 - 3x + b\mbox{ }(\mbox{mod }p) \end{equation} The variable $b$ is chosen such that the number of points is nearly maximal. In fact the order of the base points $\beta$ provided are very close to $p$ that is $\vert \vert \phi(\beta) \vert \vert \approx \vert \vert p \vert \vert$. The curves range in order from $\approx 2^{112}$ points to $\approx 2^{521}$. According to the source document any key size greater than or equal to 256-bits is sufficient for long term security. \mysection{Fixed Point Optimizations} \index{Fixed Point ECC} \index{MECC\_FP} As of v1.12 of LibTomCrypt, support for Fixed Point ECC point multiplication has been added. It is a generic optimization that is supported by any conforming math plugin. It is enabled by defining \textbf{MECC\_FP} during the build, such as \begin{verbatim} CFLAGS="-DTFM_DESC -DMECC_FP" make \end{verbatim} which will build LTC using the TFM math library and enabling this new feature. The feature is not enabled by default as it is \textbf{NOT} thread safe (by default). It supports the LTC locking macros (such as by enabling LTC\_PTHREAD), but by default is not locked. \index{FP\_ENTRIES} The optimization works by using a Fixed Point multiplier on any base point you use twice or more in a short period of time. It has a limited size cache (of FP\_ENTRIES entries) which it uses to hold recent bases passed to ltc\_ecc\_mulmod(). Any base detected to be used twice is sent through the pre--computation phase, and then the fixed point algorithm can be used. For example, if you use a NIST base point twice in a row, the 2$^{nd}$ and all subsequent point multiplications with that point will use the faster algorithm. \index{FP\_LUT} The optimization uses a window on the multiplicand of FP\_LUT bits (default: 8, min: 2, max: 12), and this controls the memory/time trade-off. The larger the value the faster the algorithm will be but the more memory it will take. The memory usage is $3 \cdot 2^{FP\_LUT}$ integers which by default with TFM amounts to about 400kB of memory. Tuning TFM (by changing FP\_SIZE) can decrease the usage by a fair amount. Memory is only used by a cache entry if it is active. Both FP\_ENTRIES and FP\_LUT are definable on the command line if you wish to override them. For instance, \begin{verbatim} CFLAGS="-DTFM_DESC -DMECC_FP -DFP_ENTRIES=8 -DFP_LUT=6" make \end{verbatim} \begin{flushleft} \index{FP\_SIZE} \index{TFM} \index{tfm.h} would define a window of 6 bits and limit the cache to 8 entries. Generally, it is better to first tune TFM by adjusting FP\_SIZE (from tfm.h). It defaults to 4096 bits (512 bytes) which is way more than what is required by ECC. At most, you need 1152 bits to accommodate ECC--521. If you're only using (say) ECC--256 you will only need 576 bits, which would reduce the memory usage by 700\%. \end{flushleft} \mysection{Key Format} LibTomCrypt uses a unique format for ECC public and private keys. While ANSI X9.63 partially specifies key formats, it does it in a less than ideally simple manner. \ In the case of LibTomCrypt, it is meant \textbf{solely} for NIST and SECG $GF(p)$ curves. The format of the keys is as follows: \index{ECC Key Format} \begin{small} \begin{verbatim} ECCPublicKey ::= SEQUENCE { flags BIT STRING(0), -- public/private flag (always zero), keySize INTEGER, -- Curve size (in bits) divided by eight -- and rounded down, e.g. 521 => 65 pubkey.x INTEGER, -- The X co-ordinate of the public key point pubkey.y INTEGER, -- The Y co-ordinate of the public key point } ECCPrivateKey ::= SEQUENCE { flags BIT STRING(1), -- public/private flag (always one), keySize INTEGER, -- Curve size (in bits) divided by eight -- and rounded down, e.g. 521 => 65 pubkey.x INTEGER, -- The X co-ordinate of the public key point pubkey.y INTEGER, -- The Y co-ordinate of the public key point secret.k INTEGER, -- The secret key scalar } \end{verbatim} \end{small} The first flags bit denotes whether the key is public (zero) or private (one). \vfil \mysection{ECC Curve Parameters} The library uses the following structure to describe an elliptic curve. This is used internally, as well as by the new extended ECC functions which allow the user to specify their own curves. \index{ltc\_ecc\_set\_type} \begin{verbatim} /** Structure defines a NIST GF(p) curve */ typedef struct { /** The size of the curve in octets */ int size; /** name of curve */ char *name; /** The prime that defines the field (encoded in hex) */ char *prime; /** The fields B param (hex) */ char *B; /** The order of the curve (hex) */ char *order; /** The x co-ordinate of the base point on the curve (hex) */ char *Gx; /** The y co-ordinate of the base point on the curve (hex) */ char *Gy; } ltc_ecc_set_type; \end{verbatim} The curve must be of the form $y^2 = x^3 - 3x + b$, and all of the integer parameters are encoded in hexadecimal format. \mysection{Core Functions} \subsection{ECC Key Generation} There is a key structure called \textit{ecc\_key} used by the ECC functions. There is a function to make a key: \index{ecc\_make\_key()} \begin{verbatim} int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key); \end{verbatim} The \textit{keysize} is the size of the modulus in bytes desired. Currently directly supported values are 12, 16, 20, 24, 28, 32, 48, and 65 bytes which correspond to key sizes of 112, 128, 160, 192, 224, 256, 384, and 521 bits respectively. If you pass a key size that is between any key size it will round the keysize up to the next available one. The function will free any internally allocated resources if there is an error. \subsection{Extended Key Generation} As of v1.16, the library supports an extended key generation routine which allows the user to specify their own curve. It is specified as follows: \index{ecc\_make\_key\_ex()} \begin{verbatim} int ecc_make_key_ex( prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp); \end{verbatim} This function generates a random ECC key over the curve specified by the parameters by \textit{dp}. The rest of the parameters are equivalent to those from the original key generation function. \subsection{ECC Key Free} To free the memory allocated by a ecc\_make\_key(), ecc\_make\_key\_ex(), ecc\_import(), or ecc\_import\_ex() call use the following function: \index{ecc\_free()} \begin{verbatim} void ecc_free(ecc_key *key); \end{verbatim} \subsection{ECC Key Export} To export an ECC key using the LibTomCrypt format call the following function: \index{ecc\_export()} \begin{verbatim} int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); \end{verbatim} This will export the key with the given \textit{type} (\textbf{PK\_PUBLIC} or \textbf{PK\_PRIVATE}), and store it to \textit{out}. \subsection{ECC Key Import} The following function imports a LibTomCrypt format ECC key: \index{ecc\_import()} \begin{verbatim} int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key); \end{verbatim} This will import the ECC key from \textit{in}, and store it in the ecc\_key structure pointed to by \textit{key}. If the operation fails it will free any allocated memory automatically. \subsection{Extended Key Import} The following function imports a LibTomCrypt format ECC key using a specified set of curve parameters: \index{ecc\_import\_ex()} \begin{verbatim} int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp); \end{verbatim} This will import the key from the array pointed to by \textit{in} of length \textit{inlen} octets. The key is stored in the ECC structure pointed to by \textit{key}. The curve is specified by the parameters pointed to by \textit{dp}. The function will free all internally allocated memory upon error. \subsection{ANSI X9.63 Export} The following function exports an ECC public key in the ANSI X9.63 format: \index{ecc\_ansi\_x963\_export()} \begin{verbatim} int ecc_ansi_x963_export( ecc_key *key, unsigned char *out, unsigned long *outlen); \end{verbatim} The ECC key pointed to by \textit{key} is exported in public fashion to the array pointed to by \textit{out}. The ANSI X9.63 format used is from section 4.3.6 of the standard. It does not allow for the export of private keys. \subsection{ANSI X9.63 Import} The following function imports an ANSI X9.63 section 4.3.6 format public ECC key: \index{ecc\_ansi\_x963\_import()} \begin{verbatim} int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key); \end{verbatim} This will import the key stored in the array pointed to by \textit{in} of length \textit{inlen} octets. The imported key is stored in the ECC key pointed to by \textit{key}. The function will free any allocated memory upon error. \subsection{Extended ANSI X9.63 Import} The following function allows the importing of an ANSI x9.63 section 4.3.6 format public ECC key using user specified domain parameters: \index{ecc\_ansi\_x963\_import\_ex()} \begin{verbatim} int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp); \end{verbatim} This will import the key stored in the array pointed to by \textit{in} of length \textit{inlen} octets using the domain parameters pointed to by \textit{dp}. The imported key is stored in the ECC key pointed to by \textit{key}. The function will free any allocated memory upon error. \subsection{ECC Shared Secret} To construct a Diffie-Hellman shared secret with a private and public ECC key, use the following function: \index{ecc\_shared\_secret()} \begin{verbatim} int ecc_shared_secret( ecc_key *private_key, ecc_key *public_key, unsigned char *out, unsigned long *outlen); \end{verbatim} The \textit{private\_key} is typically the local private key, and \textit{public\_key} is the key the remote party has shared. Note: this function stores only the $x$ co-ordinate of the shared elliptic point as described in ANSI X9.63 ECC--DH. \mysection{ECC Diffie-Hellman Encryption} ECC--DH Encryption is performed by producing a random key, hashing it, and XOR'ing the digest against the plaintext. It is not strictly ANSI X9.63 compliant but it is very similar. It has been extended by using an ASN.1 sequence and hash object identifiers to allow portable usage. The following function encrypts a short string (no longer than the message digest) using this technique: \subsection{ECC-DH Encryption} \index{ecc\_encrypt\_key()} \begin{verbatim} int ecc_encrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, prng_state *prng, int wprng, int hash, ecc_key *key); \end{verbatim} As the name implies this function encrypts a (symmetric) key, and is not intended for encrypting long messages directly. It will encrypt the plaintext in the array pointed to by \textit{in} of length \textit{inlen} octets. It uses the public ECC key pointed to by \textit{key}, and hash algorithm indexed by \textit{hash} to construct a shared secret which may be XOR'ed against the plaintext. The ciphertext is stored in the output buffer pointed to by \textit{out} of length \textit{outlen} octets. The data is encrypted to the public ECC \textit{key} such that only the holder of the private key can decrypt the payload. To have multiple recipients multiple call to this function for each public ECC key is required. \subsection{ECC-DH Decryption} \index{ecc\_decrypt\_key()} \begin{verbatim} int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, ecc_key *key); \end{verbatim} This function will decrypt an encrypted payload. The \textit{key} provided must be the private key corresponding to the public key used during encryption. If the wrong key is provided the function will not specifically return an error code. It is important to use some form of challenge response in that case (e.g. compute a MAC of a known string). \subsection{ECC Encryption Format} The packet format for the encrypted keys is the following ASN.1 SEQUENCE: \begin{verbatim} ECCEncrypt ::= SEQUENCE { hashID OBJECT IDENTIFIER, -- OID of hash used pubkey OCTET STRING , -- Encapsulated ECCPublicKey skey OCTET STRING -- xor of plaintext and --"hash of shared secret" } \end{verbatim} \mysection{EC DSA Signatures} There are also functions to sign and verify messages. They use the ANSI X9.62 EC-DSA algorithm to generate and verify signatures in the ANSI X9.62 format. \subsection{EC-DSA Signature Generation} To sign a message digest (hash) use the following function: \index{ecc\_sign\_hash()} \begin{verbatim} int ecc_sign_hash(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, prng_state *prng, int wprng, ecc_key *key); \end{verbatim} This function will EC--DSA sign the message digest stored in the array pointed to by \textit{in} of length \textit{inlen} octets. The signature will be stored in the array pointed to by \textit{out} of length \textit{outlen} octets. The function requires a properly seeded PRNG, and the ECC \textit{key} provided must be a private key. \subsection{EC-DSA Signature Verification} \index{ecc\_verify\_hash()} \begin{verbatim} int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, const unsigned char *hash, unsigned long hashlen, int *stat, ecc_key *key); \end{verbatim} This function will verify the EC-DSA signature in the array pointed to by \textit{sig} of length \textit{siglen} octets, against the message digest pointed to by the array \textit{hash} of length \textit{hashlen}. It will store a non--zero value in \textit{stat} if the signature is valid. Note: the function will not return an error if the signature is invalid. It will return an error, if the actual signature payload is an invalid format. The ECC \textit{key} must be the public (or private) ECC key corresponding to the key that performed the signature. \subsection{Signature Format} The signature code is an implementation of X9.62 EC--DSA, and the output is compliant for GF(p) curves. \mysection{ECC Keysizes} With ECC if you try to sign a hash that is bigger than your ECC key you can run into problems. The math will still work, and in effect the signature will still work. With ECC keys the strength of the signature is limited by the size of the hash, or the size of they key, whichever is smaller. For example, if you sign with SHA256 and an ECC-192 key, you in effect have 96--bits of security. The library will not warn you if you make this mistake, so it is important to check yourself before using the signatures. \chapter{Digital Signature Algorithm} \mysection{Introduction} The Digital Signature Algorithm (or DSA) is a variant of the ElGamal Signature scheme which has been modified to reduce the bandwidth of the signatures. For example, to have \textit{80-bits of security} with ElGamal, you need a group with an order of at least 1024--bits. With DSA, you need a group of order at least 160--bits. By comparison, the ElGamal signature would require at least 256 bytes of storage, whereas the DSA signature would require only at least 40 bytes. \mysection{Key Format} Since no useful public standard for DSA key storage was presented to me during the course of this development I made my own ASN.1 SEQUENCE which I document now so that others can interoperate with this library. \begin{verbatim} DSAPublicKey ::= SEQUENCE { publicFlags BIT STRING(0), -- must be 0 g INTEGER , -- base generator -- check that g^q mod p == 1 -- and that 1 < g < p - 1 p INTEGER , -- prime modulus q INTEGER , -- order of sub-group -- (must be prime) y INTEGER , -- public key, specifically, -- g^x mod p, -- check that y^q mod p == 1 -- and that 1 < y < p - 1 } DSAPrivateKey ::= SEQUENCE { publicFlags BIT STRING(1), -- must be 1 g INTEGER , -- base generator -- check that g^q mod p == 1 -- and that 1 < g < p - 1 p INTEGER , -- prime modulus q INTEGER , -- order of sub-group -- (must be prime) y INTEGER , -- public key, specifically, -- g^x mod p, -- check that y^q mod p == 1 -- and that 1 < y < p - 1 x INTEGER -- private key } \end{verbatim} The leading BIT STRING has a single bit in it which is zero for public keys and one for private keys. This makes the structure uniquely decodable, and easy to work with. \mysection{Key Generation} To make a DSA key you must call the following function \begin{verbatim} int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key); \end{verbatim} The variable \textit{prng} is an active PRNG state and \textit{wprng} the index to the descriptor. \textit{group\_size} and \textit{modulus\_size} control the difficulty of forging a signature. Both parameters are in bytes. The larger the \textit{group\_size} the more difficult a forgery becomes upto a limit. The value of $group\_size$ is limited by $15 < group\_size < 1024$ and $modulus\_size - group\_size < 512$. Suggested values for the pairs are as follows. \begin{figure}[here] \begin{center} \begin{tabular}{|c|c|c|} \hline \textbf{Bits of Security} & \textbf{group\_size} & \textbf{modulus\_size} \\ \hline 80 & 20 & 128 \\ \hline 120 & 30 & 256 \\ \hline 140 & 35 & 384 \\ \hline 160 & 40 & 512 \\ \hline \end{tabular} \end{center} \caption{DSA Key Sizes} \end{figure} When you are finished with a DSA key you can call the following function to free the memory used. \index{dsa\_free()} \begin{verbatim} void dsa_free(dsa_key *key); \end{verbatim} \mysection{Key Verification} Each DSA key is composed of the following variables. \begin{enumerate} \item $q$ a small prime of magnitude $256^{group\_size}$. \item $p = qr + 1$ a large prime of magnitude $256^{modulus\_size}$ where $r$ is a random even integer. \item $g = h^r \mbox{ (mod }p\mbox{)}$ a generator of order $q$ modulo $p$. $h$ can be any non-trivial random value. For this library they start at $h = 2$ and step until $g$ is not $1$. \item $x$ a random secret (the secret key) in the range $1 < x < q$ \item $y = g^x \mbox{ (mod }p\mbox{)}$ the public key. \end{enumerate} A DSA key is considered valid if it passes all of the following tests. \begin{enumerate} \item $q$ must be prime. \item $p$ must be prime. \item $g$ cannot be one of $\lbrace -1, 0, 1 \rbrace$ (modulo $p$). \item $g$ must be less than $p$. \item $(p-1) \equiv 0 \mbox{ (mod }q\mbox{)}$. \item $g^q \equiv 1 \mbox{ (mod }p\mbox{)}$. \item $1 < y < p - 1$ \item $y^q \equiv 1 \mbox{ (mod }p\mbox{)}$. \end{enumerate} Tests one and two ensure that the values will at least form a field which is required for the signatures to function. Tests three and four ensure that the generator $g$ is not set to a trivial value which would make signature forgery easier. Test five ensures that $q$ divides the order of multiplicative sub-group of $\Z/p\Z$. Test six ensures that the generator actually generates a prime order group. Tests seven and eight ensure that the public key is within range and belongs to a group of prime order. Note that test eight does not prove that $g$ generated $y$ only that $y$ belongs to a multiplicative sub-group of order $q$. The following function will perform these tests. \index{dsa\_verify\_key()} \begin{verbatim} int dsa_verify_key(dsa_key *key, int *stat); \end{verbatim} This will test \textit{key} and store the result in \textit{stat}. If the result is $stat = 0$ the DSA key failed one of the tests and should not be used at all. If the result is $stat = 1$ the DSA key is valid (as far as valid mathematics are concerned). \mysection{Signatures} \subsection{Signature Generation} To generate a DSA signature call the following function: \index{dsa\_sign\_hash()} \begin{verbatim} int dsa_sign_hash(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, prng_state *prng, int wprng, dsa_key *key); \end{verbatim} Which will sign the data in \textit{in} of length \textit{inlen} bytes. The signature is stored in \textit{out} and the size of the signature in \textit{outlen}. If the signature is longer than the size you initially specify in \textit{outlen} nothing is stored and the function returns an error code. The DSA \textit{key} must be of the \textbf{PK\_PRIVATE} persuasion. \subsection{Signature Verification} To verify a hash created with that function use the following function: \index{dsa\_verify\_hash()} \begin{verbatim} int dsa_verify_hash(const unsigned char *sig, unsigned long siglen, const unsigned char *hash, unsigned long inlen, int *stat, dsa_key *key); \end{verbatim} Which will verify the data in \textit{hash} of length \textit{inlen} against the signature stored in \textit{sig} of length \textit{siglen}. It will set \textit{stat} to $1$ if the signature is valid, otherwise it sets \textit{stat} to $0$. \mysection{DSA Encrypt and Decrypt} As of version 1.07, the DSA keys can be used to encrypt and decrypt small payloads. It works similar to the ECC encryption where a shared key is computed, and the hash of the shared key XOR'ed against the plaintext forms the ciphertext. The format used is functional port of the ECC encryption format to the DSA algorithm. \subsection{DSA Encryption} This function will encrypt a small payload with a recipients public DSA key. \index{dsa\_encrypt\_key()} \begin{verbatim} int dsa_encrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, prng_state *prng, int wprng, int hash, dsa_key *key); \end{verbatim} This will encrypt the payload in \textit{in} of length \textit{inlen} and store the ciphertext in the output buffer \textit{out}. The length of the ciphertext \textit{outlen} must be originally set to the length of the output buffer. The DSA \textit{key} can be a public key. \subsection{DSA Decryption} \index{dsa\_decrypt\_key()} \begin{verbatim} int dsa_decrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, dsa_key *key); \end{verbatim} This will decrypt the ciphertext \textit{in} of length \textit{inlen}, and store the original payload in \textit{out} of length \textit{outlen}. The DSA \textit{key} must be a private key. \mysection{DSA Key Import and Export} \subsection{DSA Key Export} To export a DSA key so that it can be transported use the following function: \index{dsa\_export()} \begin{verbatim} int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key); \end{verbatim} This will export the DSA \textit{key} to the buffer \textit{out} and set the length in \textit{outlen} (which must have been previously initialized to the maximum buffer size). The \textit{type} variable may be either \textbf{PK\_PRIVATE} or \textbf{PK\_PUBLIC} depending on whether you want to export a private or public copy of the DSA key. \subsection{DSA Key Import} To import an exported DSA key use the following function : \index{dsa\_import()} \begin{verbatim} int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key); \end{verbatim} This will import the DSA key from the buffer \textit{in} of length \textit{inlen} to the \textit{key}. If the process fails the function will automatically free all of the heap allocated in the process (you don't have to call dsa\_free()). \chapter{Standards Support} \mysection{ASN.1 Formats} LibTomCrypt supports a variety of ASN.1 data types encoded with the Distinguished Encoding Rules (DER) suitable for various cryptographic protocols. The data types are all provided with three basic functions with \textit{similar} prototypes. One function has been dedicated to calculate the length in octets of a given format, and two functions have been dedicated to encoding and decoding the format. On top of the basic data types are the SEQUENCE and SET data types which are collections of other ASN.1 types. They are provided in the same manner as the other data types except they use list of objects known as the \textbf{ltc\_asn1\_list} structure. It is defined as the following: \index{ltc\_asn1\_list structure} \begin{verbatim} typedef struct { int type; void *data; unsigned long size; int used; struct ltc_asn1_list_ *prev, *next, *child, *parent; } ltc_asn1_list; \end{verbatim} \index{LTC\_SET\_ASN1 macro} The \textit{type} field is one of the following ASN.1 field definitions. The \textit{data} pointer is a void pointer to the data to be encoded (or the destination) and the \textit{size} field is specific to what you are encoding (e.g. number of bits in the BIT STRING data type). The \textit{used} field is primarily for the CHOICE decoder and reflects if the particular member of a list was the decoded data type. To help build the lists in an orderly fashion the macro \textit{LTC\_SET\_ASN1(list, index, Type, Data, Size)} has been provided. It will assign to the \textit{index}th position in the \textit{list} the triplet (Type, Data, Size). An example usage would be: \begin{small} \begin{verbatim} ... ltc_asn1_list sequence[3]; unsigned long three=3; LTC_SET_ASN1(sequence, 0, LTC_ASN1_IA5_STRING, "hello", 5); LTC_SET_ASN1(sequence, 1, LTC_ASN1_SHORT_INTEGER, &three, 1); LTC_SET_ASN1(sequence, 2, LTC_ASN1_NULL, NULL, 0); \end{verbatim} \end{small} The macro is relatively safe with respect to modifying variables, for instance the following code is equivalent. \begin{small} \begin{verbatim} ... ltc_asn1_list sequence[3]; unsigned long three=3; int x=0; LTC_SET_ASN1(sequence, x++, LTC_ASN1_IA5_STRING, "hello", 5); LTC_SET_ASN1(sequence, x++, LTC_ASN1_SHORT_INTEGER, &three, 1); LTC_SET_ASN1(sequence, x++, LTC_ASN1_NULL, NULL, 0); \end{verbatim} \end{small} \begin{figure}[here] \begin{center} \begin{small} \begin{tabular}{|l|l|} \hline \textbf{Definition} & \textbf{ASN.1 Type} \\ \hline LTC\_ASN1\_EOL & End of a ASN.1 list structure. \\ \hline LTC\_ASN1\_BOOLEAN & BOOLEAN type \\ \hline LTC\_ASN1\_INTEGER & INTEGER (uses mp\_int) \\ \hline LTC\_ASN1\_SHORT\_INTEGER & INTEGER (32--bit using unsigned long) \\ \hline LTC\_ASN1\_BIT\_STRING & BIT STRING (one bit per char) \\ \hline LTC\_ASN1\_OCTET\_STRING & OCTET STRING (one octet per char) \\ \hline LTC\_ASN1\_NULL & NULL \\ \hline LTC\_ASN1\_OBJECT\_IDENTIFIER & OBJECT IDENTIFIER \\ \hline LTC\_ASN1\_IA5\_STRING & IA5 STRING (one octet per char) \\ \hline LTC\_ASN1\_UTF8\_STRING & UTF8 STRING (one wchar\_t per char) \\ \hline LTC\_ASN1\_PRINTABLE\_STRING & PRINTABLE STRING (one octet per char) \\ \hline LTC\_ASN1\_UTCTIME & UTCTIME (see ltc\_utctime structure) \\ \hline LTC\_ASN1\_SEQUENCE & SEQUENCE (and SEQUENCE OF) \\ \hline LTC\_ASN1\_SET & SET \\ \hline LTC\_ASN1\_SETOF & SET OF \\ \hline LTC\_ASN1\_CHOICE & CHOICE \\ \hline \end{tabular} \caption{List of ASN.1 Supported Types} \end{small} \end{center} \end{figure} \subsection{SEQUENCE Type} The SEQUENCE data type is a collection of other ASN.1 data types encapsulated with a small header which is a useful way of sending multiple data types in one packet. \subsubsection{SEQUENCE Encoding} To encode a sequence a \textbf{ltc\_asn1\_list} array must be initialized with the members of the sequence and their respective pointers. The encoding is performed with the following function. \index{der\_encode\_sequence()} \begin{verbatim} int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen, unsigned char *out, unsigned long *outlen); \end{verbatim} This encodes a sequence of items pointed to by \textit{list} where the list has \textit{inlen} items in it. The SEQUENCE will be encoded to \textit{out} and of length \textit{outlen}. The function will terminate when it reads all the items out of the list (upto \textit{inlen}) or it encounters an item in the list with a type of \textbf{LTC\_ASN1\_EOL}. The \textit{data} pointer in the list would be the same pointer you would pass to the respective ASN.1 encoder (e.g. der\_encode\_bit\_string()) and it is simply passed on verbatim to the dependent encoder. The list can contain other SEQUENCE or SET types which enables you to have nested SEQUENCE and SET definitions. In these cases the \textit{data} pointer is simply a pointer to another \textbf{ltc\_asn1\_list}. \subsubsection{SEQUENCE Decoding} \index{der\_decode\_sequence()} Decoding a SEQUENCE is similar to encoding. You set up an array of \textbf{ltc\_asn1\_list} where in this case the \textit{size} member is the maximum size (in certain cases). For types such as IA5 STRING, BIT STRING, OCTET STRING (etc) the \textit{size} field is updated after successful decoding to reflect how many units of the respective type has been loaded. \begin{verbatim} int der_decode_sequence(const unsigned char *in, unsigned long inlen, ltc_asn1_list *list, unsigned long outlen); \end{verbatim} This will decode upto \textit{outlen} items from the input buffer \textit{in} of length \textit{inlen} octets. The function will stop (gracefully) when it runs out of items to decode. It will fail (for among other reasons) when it runs out of input bytes to read, a data type is invalid or a heap failure occurred. For the following types the \textit{size} field will be updated to reflect the number of units read of the given type. \begin{enumerate} \item BIT STRING \item OCTET STRING \item OBJECT IDENTIFIER \item IA5 STRING \item PRINTABLE STRING \end{enumerate} \subsubsection{SEQUENCE Length} The length of a SEQUENCE can be determined with the following function. \index{der\_length\_sequence()} \begin{verbatim} int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, unsigned long *outlen); \end{verbatim} This will get the encoding size for the given \textit{list} of length \textit{inlen} and store it in \textit{outlen}. \subsubsection{SEQUENCE Multiple Argument Lists} For small or simple sequences an encoding or decoding can be performed with one of the following two functions. \index{der\_encode\_sequence\_multi()} \index{der\_decode\_sequence\_multi()} \begin{verbatim} int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...); int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...); \end{verbatim} These either encode or decode (respectively) a SEQUENCE data type where the items in the sequence are specified after the length parameter. The list of items are specified as a triple of the form \textit{(type, size, data)} where \textit{type} is an \textbf{int}, \textit{size} is a \textbf{unsigned long} and \textit{data} is \textbf{void} pointer. The list of items must be terminated with an item with the type \textbf{LTC\_ASN1\_EOL}. It is ideal that you cast the \textit{size} values to unsigned long to ensure that the proper data type is passed to the function. Constants such as \textit{1} without a cast or prototype are of type \textbf{int} by default. Appending \textit{UL} or pre-pending \textit{(unsigned long)} is enough to cast it to the correct type. \begin{small} \begin{verbatim} unsigned char buf[MAXBUFSIZE]; unsigned long buflen; int err; buflen = sizeof(buf); if ((err = der_encode_sequence_multi(buf, &buflen, LTC_ASN1_IA5_STRING, 5UL, "Hello", LTC_ASN1_IA5_STRING, 7UL, " World!", LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { // error handling } \end{verbatim} \end{small} This example encodes a SEQUENCE with two IA5 STRING types containing ``Hello'' and `` World!'' respectively. Note the usage of the \textbf{UL} modifier on the size parameters. This forces the compiler to pass the numbers as the required \textbf{unsigned long} type that the function expects. \subsection{SET and SET OF} \index{SET} \index{SET OF} SET and SET OF are related to the SEQUENCE type in that they can be pretty much be decoded with the same code. However, they are different, and they should be carefully noted. The SET type is an unordered array of ASN.1 types sorted by the TAG (type identifier), whereas the SET OF type is an ordered array of a \textbf{single} ASN.1 object sorted in ascending order by the DER their respective encodings. \subsubsection{SET Encoding} SETs use the same array structure of ltc\_asn1\_list that the SEQUENCE functions use. They are encoded with the following function: \index{der\_encode\_set()} \begin{verbatim} int der_encode_set(ltc_asn1_list *list, unsigned long inlen, unsigned char *out, unsigned long *outlen); \end{verbatim} This will encode the list of ASN.1 objects in \textit{list} of length \textit{inlen} objects, and store the output in \textit{out} of length \textit{outlen} bytes. The function will make a copy of the list provided, and sort it by the TAG. Objects with identical TAGs are additionally sorted on their original placement in the array (to make the process deterministic). This function will \textbf{NOT} recognize \textit{DEFAULT} objects, and it is the responsibility of the caller to remove them as required. \subsubsection{SET Decoding} The SET type can be decoded with the following function. \index{der\_decode\_set()} \begin{verbatim} int der_decode_set(const unsigned char *in, unsigned long inlen, ltc_asn1_list *list, unsigned long outlen); \end{verbatim} This will decode the SET specified by \textit{list} of length \textit{outlen} objects from the input buffer \textit{in} of length \textit{inlen} octets. It handles the fact that SETs are not strictly ordered and will make multiple passes (as required) through the list to decode all the objects. \subsubsection{SET Length} The length of a SET can be determined by calling der\_length\_sequence() since they have the same encoding length. \subsubsection{SET OF Encoding} A \textit{SET OF} object is an array of identical objects (e.g. OCTET STRING) sorted in ascending order by the DER encoding of the object. They are used to store objects deterministically based solely on their encoding. It uses the same array structure of ltc\_asn1\_list that the SEQUENCE functions use. They are encoded with the following function. \index{der\_encode\_setof()} \begin{verbatim} int der_encode_setof(ltc_asn1_list *list, unsigned long inlen, unsigned char *out, unsigned long *outlen); \end{verbatim} This will encode a \textit{SET OF} containing the \textit{list} of \textit{inlen} ASN.1 objects and store the encoding in the output buffer \textit{out} of length \textit{outlen}. The routine will first encode the SET OF in an unordered fashion (in a temporary buffer) then sort using the XQSORT macro and copy back to the output buffer. This means you need at least enough memory to keep an additional copy of the output on the heap. \subsubsection{SET OF Decoding} Since the decoding of a \textit{SET OF} object is unambiguous it can be decoded with der\_decode\_sequence(). \subsubsection{SET OF Length} Like the SET type the der\_length\_sequence() function can be used to determine the length of a \textit{SET OF} object. \subsection{ASN.1 INTEGER} To encode or decode INTEGER data types use the following functions. \index{der\_encode\_integer()}\index{der\_decode\_integer()}\index{der\_length\_integer()} \begin{verbatim} int der_encode_integer( void *num, unsigned char *out, unsigned long *outlen); int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num); int der_length_integer( void *num, unsigned long *len); \end{verbatim} These will encode or decode a signed INTEGER data type using the bignum data type to store the large INTEGER. To encode smaller values without allocating a bignum to store the value, the \textit{short} INTEGER functions were made available. \index{der\_encode\_short\_integer()}\index{der\_decode\_short\_integer()}\index{der\_length\_short\_integer()} \begin{verbatim} int der_encode_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen); int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num); int der_length_short_integer(unsigned long num, unsigned long *outlen); \end{verbatim} These will encode or decode an unsigned \textbf{unsigned long} type (only reads upto 32--bits). For values in the range $0 \dots 2^{32} - 1$ the integer and short integer functions can encode and decode each others outputs. \subsection{ASN.1 BIT STRING} \index{der\_encode\_bit\_string()}\index{der\_decode\_bit\_string()}\index{der\_length\_bit\_string()} \begin{verbatim} int der_encode_bit_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); int der_decode_bit_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); int der_length_bit_string(unsigned long nbits, unsigned long *outlen); \end{verbatim} These will encode or decode a BIT STRING data type. The bits are passed in (or read out) using one \textbf{char} per bit. A non--zero value will be interpreted as a one bit, and a zero value a zero bit. \subsection{ASN.1 OCTET STRING} \index{der\_encode\_octet\_string()}\index{der\_decode\_octet\_string()}\index{der\_length\_octet\_string()} \begin{verbatim} int der_encode_octet_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); int der_decode_octet_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); int der_length_octet_string(unsigned long noctets, unsigned long *outlen); \end{verbatim} These will encode or decode an OCTET STRING data type. The octets are stored using one \textbf{unsigned char} each. \subsection{ASN.1 OBJECT IDENTIFIER} \index{der\_encode\_object\_identifier()}\index{der\_decode\_object\_identifier()}\index{der\_length\_object\_identifier()} \begin{verbatim} int der_encode_object_identifier(unsigned long *words, unsigned long nwords, unsigned char *out, unsigned long *outlen); int der_decode_object_identifier(const unsigned char *in, unsigned long inlen, unsigned long *words, unsigned long *outlen); int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen); \end{verbatim} These will encode or decode an OBJECT IDENTIFIER object. The words of the OID are stored in individual \textbf{unsigned long} elements, and must be in the range $0 \ldots 2^{32} - 1$. \subsection{ASN.1 IA5 STRING} \index{der\_encode\_ia5\_string()}\index{der\_decode\_ia5\_string()}\index{der\_length\_ia5\_string()} \begin{verbatim} int der_encode_ia5_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); int der_decode_ia5_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen); \end{verbatim} These will encode or decode an IA5 STRING. The characters are read or stored in individual \textbf{char} elements. These functions performs internal character to numerical conversions based on the conventions of the compiler being used. For instance, on an x86\_32 machine 'A' == 65 but the same may not be true on say a SPARC machine. Internally, these functions have a table of literal characters and their numerical ASCII values. This provides a stable conversion provided that the build platform honours the run--time platforms character conventions. \subsection{ASN.1 PRINTABLE STRING} \index{der\_encode\_printable\_string()}\index{der\_decode\_printable\_string()}\index{der\_length\_printable\_string()} \begin{verbatim} int der_encode_printable_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); int der_decode_printable_string(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen); \end{verbatim} These will encode or decode an PRINTABLE STRING. The characters are read or stored in individual \textbf{char} elements. These functions performs internal character to numerical conversions based on the conventions of the compiler being used. For instance, on an x86\_32 machine 'A' == 65 but the same may not be true on say a SPARC machine. Internally, these functions have a table of literal characters and their numerical ASCII values. This provides a stable conversion provided that the build platform honours the run-time platforms character conventions. \subsection{ASN.1 UTF8 STRING} \index{der\_encode\_utf8\_string()}\index{der\_decode\_utf8\_string()}\index{der\_length\_utf8\_string()} \begin{verbatim} int der_encode_utf8_string(const wchar_t *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); int der_decode_utf8_string(const unsigned char *in, unsigned long inlen, wchar_t *out, unsigned long *outlen); int der_length_utf8_string(const wchar_t *octets, unsigned long noctets, unsigned long *outlen); \end{verbatim} These will encode or decode an UTF8 STRING. The characters are read or stored in individual \textbf{wchar\_t} elements. These function performs no internal mapping and treat the characters as literals. These functions use the \textbf{wchar\_t} type which is not universally available. In those cases, the library will typedef it to \textbf{unsigned long}. If you intend to use the ISO C functions for working with wide--char arrays, you should make sure that wchar\_t has been defined previously. \subsection{ASN.1 UTCTIME} The UTCTIME type is to store a date and time in ASN.1 format. It uses the following structure to organize the time. \index{ltc\_utctime structure} \begin{verbatim} typedef struct { unsigned YY, /* year 00--99 */ MM, /* month 01--12 */ DD, /* day 01--31 */ hh, /* hour 00--23 */ mm, /* minute 00--59 */ ss, /* second 00--59 */ off_dir, /* timezone offset direction 0 == +, 1 == - */ off_hh, /* timezone offset hours */ off_mm; /* timezone offset minutes */ } ltc_utctime; \end{verbatim} The time can be offset plus or minus a set amount of hours (off\_hh) and minutes (off\_mm). When \textit{off\_dir} is zero, the time will be added otherwise it will be subtracted. For instance, the array $\lbrace 5, 6, 20, 22, 4, 00, 0, 5, 0 \rbrace$ represents the current time of \textit{2005, June 20th, 22:04:00} with a time offset of +05h00. \index{der\_encode\_utctime()}\index{der\_decode\_utctime()}\index{der\_length\_utctime()} \begin{verbatim} int der_encode_utctime( ltc_utctime *utctime, unsigned char *out, unsigned long *outlen); int der_decode_utctime(const unsigned char *in, unsigned long *inlen, ltc_utctime *out); int der_length_utctime( ltc_utctime *utctime, unsigned long *outlen); \end{verbatim} The encoder will store time in one of the two ASN.1 formats, either \textit{YYMMDDhhmmssZ} or \textit{YYMMDDhhmmss$\pm$hhmm}, and perform minimal error checking on the input. The decoder will read all valid ASN.1 formats and perform range checking on the values (not complete but rational) useful for catching packet errors. It is suggested that decoded data be further scrutinized (e.g. days of month in particular). \subsection{ASN.1 CHOICE} The CHOICE ASN.1 type represents a union of ASN.1 types all of which are stored in a \textit{ltc\_asn1\_list}. There is no encoder for the CHOICE type, only a decoder. The decoder will scan through the provided list attempting to use the appropriate decoder on the input packet. The list can contain any ASN.1 data type\footnote{Except it cannot have LTC\_ASN1\_INTEGER and LTC\_ASN1\_SHORT\_INTEGER simultaneously.} except for other CHOICE types. There is no encoder for the CHOICE type as the actual DER encoding is the encoding of the chosen type. \index{der\_decode\_choice()} \begin{verbatim} int der_decode_choice(const unsigned char *in, unsigned long *inlen, ltc_asn1_list *list, unsigned long outlen); \end{verbatim} This will decode the input in the \textit{in} field of length \textit{inlen}. It uses the provided ASN.1 list specified in the \textit{list} field which has \textit{outlen} elements. The \textit{inlen} field will be updated with the length of the decoded data type, as well as the respective entry in the \textit{list} field will have the \textit{used} flag set to non--zero to reflect it was the data type decoded. \subsection{ASN.1 Flexi Decoder} The ASN.1 \textit{flexi} decoder allows the developer to decode arbitrary ASN.1 DER packets (provided they use data types LibTomCrypt supports) without first knowing the structure of the data. Where der\_decode \_sequence() requires the developer to specify the data types to decode in advance the flexi decoder is entirely free form. The flexi decoder uses the same \textit{ltc\_asn1\_list} but instead of being stored in an array it uses the linked list pointers \textit{prev}, \textit{next}, \textit{parent} and \textit{child}. The list works as a \textit{doubly-linked list} structure where decoded items at the same level are siblings (using next and prev) and items encoded in a SEQUENCE are stored as a child element. When a SEQUENCE or SET has been encountered a SEQUENCE (or SET resp.) item will be added as a sibling (e.g. list.type == LTC\_ASN1\_SEQUENCE) and the child pointer points to a new list of items contained within the object. \index{der\_decode\_sequence\_flexi()} \begin{verbatim} int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out); \end{verbatim} This will decode items in the \textit{in} buffer of max input length \textit{inlen} and store the newly created pointer to the list in \textit{out}. This function allocates all required memory for the decoding. It stores the number of octets read back into \textit{inlen}. The function will terminate when either it hits an invalid ASN.1 tag, or it reads \textit{inlen} octets. An early termination is a soft error, and returns normally. The decoded list \textit{out} will point to the very first element of the list (e.g. both parent and prev pointers will be \textbf{NULL}). An invalid decoding will terminate the process, and free the allocated memory automatically. \textbf{Note:} the list decoded by this function is \textbf{NOT} in the correct form for der\_encode\_sequence() to use directly. You will have to first have to convert the list by first storing all of the siblings in an array then storing all the children as sub-lists of a sequence using the \textit{.data} pointer. Currently no function in LibTomCrypt provides this ability. \subsubsection{Sample Decoding} Suppose we decode the following structure: \begin{small} \begin{verbatim} User ::= SEQUENCE { Name IA5 STRING LoginToken SEQUENCE { passwdHash OCTET STRING pubkey ECCPublicKey } LastOn UTCTIME } \end{verbatim} \end{small} \begin{flushleft}and we decoded it with the following code:\end{flushleft} \begin{small} \begin{verbatim} unsigned char inbuf[MAXSIZE]; unsigned long inbuflen; ltc_asn1_list *list; int err; /* somehow fill inbuf/inbuflen */ if ((err = der_decode_sequence_flexi(inbuf, inbuflen, &list)) != CRYPT_OK) { printf("Error decoding: %s\n", error_to_string(err)); exit(EXIT_FAILURE); } \end{verbatim} \end{small} At this point \textit{list} would point to the SEQUENCE identified by \textit{User}. It would have no sibblings (prev or next), and only a child node. Walking to the child node with the following code will bring us to the \textit{Name} portion of the SEQUENCE: \begin{small} \begin{verbatim} list = list->child; \end{verbatim} \end{small} Now \textit{list} points to the \textit{Name} member (with the tag IA5 STRING). The \textit{data}, \textit{size}, and \textit{type} members of \textit{list} should reflect that of an IA5 STRING. The sibbling will now be the \textit{LoginToken} SEQUENCE. The sibbling has a child node which points to the \textit{passwdHash} OCTET STRING. We can walk to this node with the following code: \begin{small} \begin{verbatim} /* list already pointing to 'Name' */ list = list->next->child; \end{verbatim} \end{small} At this point, \textit{list} will point to the \textit{passwdHash} member of the innermost SEQUENCE. This node has a sibbling, the \textit{pubkey} member of the SEQUENCE. The \textit{LastOn} member of the SEQUENCE is a sibbling of the LoginToken node, if we wanted to walk there we would have to go up and over via: \begin{small} \begin{verbatim} list = list->parent->next; \end{verbatim} \end{small} At this point, we are pointing to the last node of the list. Lists are terminated in all directions by a \textbf{NULL} pointer. All nodes are doubly linked so that you can walk up and down the nodes without keeping pointers lying around. \subsubsection{Free'ing a Flexi List} To free the list use the following function. \index{der\_sequence\_free()} \begin{verbatim} void der_sequence_free(ltc_asn1_list *in); \end{verbatim} This will free all of the memory allocated by der\_decode\_sequence\_flexi(). \mysection{Password Based Cryptography} \subsection{PKCS \#5} \index{PKCS \#5} In order to securely handle user passwords for the purposes of creating session keys and chaining IVs the PKCS \#5 was drafted. PKCS \#5 is made up of two algorithms, Algorithm One and Algorithm Two. Algorithm One is the older fairly limited algorithm which has been implemented for completeness. Algorithm Two is a bit more modern and more flexible to work with. \subsection{Algorithm One} Algorithm One accepts as input a password, an 8--byte salt, and an iteration counter. The iteration counter is meant to act as delay for people trying to brute force guess the password. The higher the iteration counter the longer the delay. This algorithm also requires a hash algorithm and produces an output no longer than the output of the hash. \index{pkcs\_5\_alg1()} \begin{alltt} int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, const unsigned char *salt, int iteration_count, int hash_idx, unsigned char *out, unsigned long *outlen) \end{alltt} Where \textit{password} is the user's password. Since the algorithm allows binary passwords you must also specify the length in \textit{password\_len}. The \textit{salt} is a fixed size 8--byte array which should be random for each user and session. The \textit{iteration\_count} is the delay desired on the password. The \textit{hash\_idx} is the index of the hash you wish to use in the descriptor table. The output of length up to \textit{outlen} is stored in \textit{out}. If \textit{outlen} is initially larger than the size of the hash functions output it is set to the number of bytes stored. If it is smaller than not all of the hash output is stored in \textit{out}. \subsection{Algorithm Two} Algorithm Two is the recommended algorithm for this task. It allows variable length salts, and can produce outputs larger than the hash functions output. As such, it can easily be used to derive session keys for ciphers and MACs as well initial vectors as required from a single password and invocation of this algorithm. \index{pkcs\_5\_alg2()} \begin{alltt} int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, const unsigned char *salt, unsigned long salt_len, int iteration_count, int hash_idx, unsigned char *out, unsigned long *outlen) \end{alltt} Where \textit{password} is the users password. Since the algorithm allows binary passwords you must also specify the length in \textit{password\_len}. The \textit{salt} is an array of size \textit{salt\_len}. It should be random for each user and session. The \textit{iteration\_count} is the delay desired on the password. The \textit{hash\_idx} is the index of the hash you wish to use in the descriptor table. The output of length up to \textit{outlen} is stored in \textit{out}. \begin{verbatim} /* demo to show how to make session state material * from a password */ #include int main(void) { unsigned char password[100], salt[100], cipher_key[16], cipher_iv[16], mac_key[16], outbuf[48]; int err, hash_idx; unsigned long outlen, password_len, salt_len; /* register hash and get it's idx .... */ /* get users password and make up a salt ... */ /* create the material (100 iterations in algorithm) */ outlen = sizeof(outbuf); if ((err = pkcs_5_alg2(password, password_len, salt, salt_len, 100, hash_idx, outbuf, &outlen)) != CRYPT_OK) { /* error handle */ } /* now extract it */ memcpy(cipher_key, outbuf, 16); memcpy(cipher_iv, outbuf+16, 16); memcpy(mac_key, outbuf+32, 16); /* use material (recall to store the salt in the output) */ } \end{verbatim} \chapter{Miscellaneous} \mysection{Base64 Encoding and Decoding} The library provides functions to encode and decode a RFC 1521 base--64 coding scheme. The characters used in the mappings are: \begin{verbatim} ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ \end{verbatim} Those characters are supported in the 7-bit ASCII map, which means they can be used for transport over common e-mail, usenet and HTTP mediums. The format of an encoded stream is just a literal sequence of ASCII characters where a group of four represent 24-bits of input. The first four chars of the encoders output is the length of the original input. After the first four characters is the rest of the message. Often, it is desirable to line wrap the output to fit nicely in an e-mail or usenet posting. The decoder allows you to put any character (that is not in the above sequence) in between any character of the encoders output. You may not however, break up the first four characters. To encode a binary string in base64 call: \index{base64\_encode()} \index{base64\_decode()} \begin{verbatim} int base64_encode(const unsigned char *in, unsigned long len, unsigned char *out, unsigned long *outlen); \end{verbatim} Where \textit{in} is the binary string and \textit{out} is where the ASCII output is placed. You must set the value of \textit{outlen} prior to calling this function and it sets the length of the base64 output in \textit{outlen} when it is done. To decode a base64 string call: \begin{verbatim} int base64_decode(const unsigned char *in, unsigned long len, unsigned char *out, unsigned long *outlen); \end{verbatim} \mysection{Primality Testing} \index{Primality Testing} The library includes primality testing and random prime functions as well. The primality tester will perform the test in two phases. First it will perform trial division by the first few primes. Second it will perform eight rounds of the Rabin-Miller primality testing algorithm. If the candidate passes both phases it is declared prime otherwise it is declared composite. No prime number will fail the two phases but composites can. Each round of the Rabin-Miller algorithm reduces the probability of a pseudo-prime by $1 \over 4$ therefore after sixteen rounds the probability is no more than $\left ( { 1 \over 4 } \right )^{8} = 2^{-16}$. In practice the probability of error is in fact much lower than that. When making random primes the trial division step is in fact an optimized implementation of \textit{Implementation of Fast RSA Key Generation on Smart Cards}\footnote{Chenghuai Lu, Andre L. M. dos Santos and Francisco R. Pimentel}. In essence a table of machine-word sized residues are kept of a candidate modulo a set of primes. When the candidate is rejected and ultimately incremented to test the next number the residues are updated without using multi-word precision math operations. As a result the routine can scan ahead to the next number required for testing with very little work involved. In the event that a composite did make it through it would most likely cause the the algorithm trying to use it to fail. For instance, in RSA two primes $p$ and $q$ are required. The order of the multiplicative sub-group (modulo $pq$) is given as $\phi(pq)$ or $(p - 1)(q - 1)$. The decryption exponent $d$ is found as $de \equiv 1\mbox{ }(\mbox{mod } \phi(pq))$. If either $p$ or $q$ is composite the value of $d$ will be incorrect and the user will not be able to sign or decrypt messages at all. Suppose $p$ was prime and $q$ was composite this is just a variation of the multi-prime RSA. Suppose $q = rs$ for two primes $r$ and $s$ then $\phi(pq) = (p - 1)(r - 1)(s - 1)$ which clearly is not equal to $(p - 1)(rs - 1)$. These are not technically part of the LibTomMath library but this is the best place to document them. To test if a \textit{mp\_int} is prime call: \begin{verbatim} int is_prime(mp_int *N, int *result); \end{verbatim} This puts a one in \textit{result} if the number is probably prime, otherwise it places a zero in it. It is assumed that if it returns an error that the value in \textit{result} is undefined. To make a random prime call: \begin{verbatim} int rand_prime( mp_int *N, unsigned long len, prng_state *prng, int wprng); \end{verbatim} Where \textit{len} is the size of the prime in bytes ($2 \le len \le 256$). You can set \textit{len} to the negative size you want to get a prime of the form $p \equiv 3\mbox{ }(\mbox{mod } 4)$. So if you want a 1024-bit prime of this sort pass \textit{len = -128} to the function. Upon success it will return {\bf CRYPT\_OK} and \textit{N} will contain an integer which is very likely prime. \chapter{Programming Guidelines} \mysection{Secure Pseudo Random Number Generators} Probably the single most vulnerable point of any cryptosystem is the PRNG. Without one, generating and protecting secrets would be impossible. The requirement that one be setup correctly is vitally important, and to address this point the library does provide two RNG sources that will address the largest amount of end users as possible. The \textit{sprng} PRNG provides an easy to access source of entropy for any application on a UNIX (and the like) or Windows computer. However, when the end user is not on one of these platforms, the application developer must address the issue of finding entropy. This manual is not designed to be a text on cryptography. I would just like to highlight that when you design a cryptosystem make sure the first problem you solve is getting a fresh source of entropy. \mysection{Preventing Trivial Errors} Two simple ways to prevent trivial errors is to prevent overflows, and to check the return values. All of the functions which output variable length strings will require you to pass the length of the destination. If the size of your output buffer is smaller than the output it will report an error. Therefore, make sure the size you pass is correct! Also, virtually all of the functions return an error code or {\bf CRYPT\_OK}. You should detect all errors, as simple typos can cause algorithms to fail to work as desired. \mysection{Registering Your Algorithms} To avoid linking and other run--time errors it is important to register the ciphers, hashes and PRNGs you intend to use before you try to use them. This includes any function which would use an algorithm indirectly through a descriptor table. A neat bonus to the registry system is that you can add external algorithms that are not part of the library without having to hack the library. For example, suppose you have a hardware specific PRNG on your system. You could easily write the few functions required plus a descriptor. After registering your PRNG, all of the library functions that need a PRNG can instantly take advantage of it. The same applies for ciphers, hashes, and bignum math routines. \mysection{Key Sizes} \subsection{Symmetric Ciphers} For symmetric ciphers, use as large as of a key as possible. For the most part \textit{bits are cheap} so using a 256--bit key is not a hard thing to do. As a good rule of thumb do not use a key smaller than 128 bits. \subsection{Asymmetric Ciphers} The following chart gives the work factor for solving a DH/RSA public key using the NFS. The work factor for a key of order $n$ is estimated to be \begin{equation} e^{1.923 \cdot ln(n)^{1 \over 3} \cdot ln(ln(n))^{2 \over 3}} \end{equation} Note that $n$ is not the bit-length but the magnitude. For example, for a 1024-bit key $n = 2^{1024}$. The work required is: \begin{figure}[here] \begin{center} \begin{tabular}{|c|c|} \hline RSA/DH Key Size (bits) & Work Factor ($log_2$) \\ \hline 512 & 63.92 \\ \hline 768 & 76.50 \\ \hline 1024 & 86.76 \\ \hline 1536 & 103.37 \\ \hline 2048 & 116.88 \\ \hline 2560 & 128.47 \\ \hline 3072 & 138.73 \\ \hline 4096 & 156.49 \\ \hline \end{tabular} \end{center} \caption{RSA/DH Key Strength} \end{figure} The work factor for ECC keys is much higher since the best attack is still fully exponential. Given a key of magnitude $n$ it requires $\sqrt n$ work. The following table summarizes the work required: \begin{figure}[here] \begin{center} \begin{tabular}{|c|c|} \hline ECC Key Size (bits) & Work Factor ($log_2$) \\ \hline 112 & 56 \\ \hline 128 & 64 \\ \hline 160 & 80 \\ \hline 192 & 96 \\ \hline 224 & 112 \\ \hline 256 & 128 \\ \hline 384 & 192 \\ \hline 521 & 260.5 \\ \hline \end{tabular} \end{center} \caption{ECC Key Strength} \end{figure} Using the above tables the following suggestions for key sizes seems appropriate: \begin{center} \begin{tabular}{|c|c|c|} \hline Security Goal & RSA/DH Key Size (bits) & ECC Key Size (bits) \\ \hline Near term & 1024 & 160 \\ \hline Short term & 1536 & 192 \\ \hline Long Term & 2560 & 384 \\ \hline \end{tabular} \end{center} \mysection{Thread Safety} The library is not fully thread safe but several simple precautions can be taken to avoid any problems. The registry functions such as register\_cipher() are not thread safe no matter what you do. It is best to call them from your programs initialization code before threads are initiated. The rest of the code uses state variables you must pass it such as hash\_state, hmac\_state, etc. This means that if each thread has its own state variables then they will not affect each other, and are fully thread safe. This is fairly simple with symmetric ciphers and hashes. \index{LTC\_PTHREAD} The only sticky issue is a shared PRNG which can be alleviated with the careful use of mutex devices. Defining LTC\_PTHREAD for instance, enables pthreads based mutex locking in various routines such as the Yarrow and Fortuna PRNGs, the fixed point ECC multiplier, and other routines. \chapter{Configuring and Building the Library} \mysection{Introduction} The library is fairly flexible about how it can be built, used, and generally distributed. Additions are being made with each new release that will make the library even more flexible. Each of the classes of functions can be disabled during the build process to make a smaller library. This is particularly useful for shared libraries. As of v1.06 of the library, the build process has been moved to two steps for the typical LibTomCrypt application. This is because LibTomCrypt no longer provides a math API on its own and relies on third party libraries (such as LibTomMath, GnuMP, or TomsFastMath). The build process now consists of installing a math library first, and then building and installing LibTomCrypt with a math library configured. Note that LibTomCrypt can be built with no internal math descriptors. This means that one must be provided at either build, or run time for the application. LibTomCrypt comes with three math descriptors that provide a standard interface to math libraries. \mysection{Makefile variables} All GNU driven makefiles (including the makefile for ICC) use a set of common variables to control the build and install process. Most of the settings can be overwritten from the command line which makes custom installation a breeze. \index{MAKE}\index{CC}\index{AR} \subsection{MAKE, CC and AR} The MAKE, CC and AR flags can all be overwritten. They default to \textit{make}, \textit{\$CC} and \textit{\$AR} respectively. Changing MAKE allows you to change what program will be invoked to handle sub--directories. For example, this \begin{verbatim} MAKE=gmake gmake install \end{verbatim} \begin{flushleft} will build and install the libraries with the \textit{gmake} tool. Similarly, \end{flushleft} \begin{verbatim} CC=arm-gcc AR=arm-ar make \end{verbatim} \begin{flushleft} will build the library using \textit{arm--gcc} as the compiler and \textit{arm--ar} as the archiver. \end{flushleft} \subsection{IGNORE\_SPEED} \index{IGNORE\_SPEED} When \textbf{IGNORE\_SPEED} has been defined the default optimization flags for CFLAGS will be disabled which allows the developer to specify new CFLAGS on the command line. E.g. to add debugging \begin{verbatim} CFLAGS="-g3" make IGNORE_SPEED=1 \end{verbatim} This will turn off optimizations and add \textit{-g3} to the CFLAGS which enables debugging. \subsection{LIBNAME and LIBNAME\_S} \index{LIBNAME} \index{LIBNAME\_S} \textbf{LIBNAME} is the name of the output library (archive) to create. It defaults to \textit{libtomcrypt.a} for static builds and \textit{libtomcrypt.la} for shared. The \textbf{LIBNAME\_S} variable is the static name while doing shared builds. Ideally they should have the same prefix but don't have to. \index{LIBTEST} \index{LIBTEST\_S} Similarly \textbf{LIBTEST} and \textbf{LIBTEST\_S} are the names for the profiling and testing library. The default is \textit{libtomcrypt\_prof.a} for static and \textit{libtomcrypt\_prof.la} for shared. \subsection{Installation Directories} \index{DESTDIR} \index{LIBPATH} \index{INCPATH} \index{DATADIR} \textbf{DESTDIR} is the prefix for the installation directories. It defaults to an empty string. \textbf{LIBPATH} is the prefix for the library directory which defaults to \textit{/usr/lib}. \textbf{INCPATH} is the prefix for the header file directory which defaults to \textit{/usr/include}. \textbf{DATADIR} is the prefix for the data (documentation) directory which defaults to \textit{/usr/share/doc/libtomcrypt/pdf}. All four can be used to create custom install locations depending on the nature of the OS and file system in use. \begin{verbatim} make LIBPATH=/home/tom/project/lib INCPATH=/home/tom/project/include \ DATAPATH=/home/tom/project/docs install \end{verbatim} This will build the library and install it to the directories under \textit{/home/tom/project/}. e.g. \begin{small} \begin{verbatim} /home/tom/project/: total 1 drwxr-xr-x 2 tom users 80 Jul 30 16:02 docs drwxr-xr-x 2 tom users 528 Jul 30 16:02 include drwxr-xr-x 2 tom users 80 Jul 30 16:02 lib /home/tom/project/docs: total 452 -rwxr-xr-x 1 tom users 459009 Jul 30 16:02 crypt.pdf /home/tom/project/include: total 132 -rwxr-xr-x 1 tom users 2482 Jul 30 16:02 tomcrypt.h -rwxr-xr-x 1 tom users 702 Jul 30 16:02 tomcrypt_argchk.h -rwxr-xr-x 1 tom users 2945 Jul 30 16:02 tomcrypt_cfg.h -rwxr-xr-x 1 tom users 22763 Jul 30 16:02 tomcrypt_cipher.h -rwxr-xr-x 1 tom users 5174 Jul 30 16:02 tomcrypt_custom.h -rwxr-xr-x 1 tom users 11314 Jul 30 16:02 tomcrypt_hash.h -rwxr-xr-x 1 tom users 11571 Jul 30 16:02 tomcrypt_mac.h -rwxr-xr-x 1 tom users 13614 Jul 30 16:02 tomcrypt_macros.h -rwxr-xr-x 1 tom users 14714 Jul 30 16:02 tomcrypt_math.h -rwxr-xr-x 1 tom users 632 Jul 30 16:02 tomcrypt_misc.h -rwxr-xr-x 1 tom users 10934 Jul 30 16:02 tomcrypt_pk.h -rwxr-xr-x 1 tom users 2634 Jul 30 16:02 tomcrypt_pkcs.h -rwxr-xr-x 1 tom users 7067 Jul 30 16:02 tomcrypt_prng.h -rwxr-xr-x 1 tom users 1467 Jul 30 16:02 tomcrypt_test.h /home/tom/project/lib: total 1073 -rwxr-xr-x 1 tom users 1096284 Jul 30 16:02 libtomcrypt.a \end{verbatim} \end{small} \mysection{Extra libraries} \index{EXTRALIBS} \textbf{EXTRALIBS} specifies any extra libraries required to link the test programs and shared libraries. They are specified in the notation that GCC expects for global archives. \begin{verbatim} CFLAGS="-DTFM_DESC -DUSE_TFM" EXTRALIBS=-ltfm make install \ test timing \end{verbatim} This will install the library using the TomsFastMath library and link the \textit{libtfm.a} library out of the default library search path. The two defines are explained below. You can specify multiple archives (say if you want to support two math libraries, or add on additional code) to the \textbf{EXTRALIBS} variable by separating them by a space. Note that \textbf{EXTRALIBS} is not required if you are only making and installing the static library but none of the test programs. \mysection{Building a Static Library} Building a static library is fairly trivial as it only requires one invocation of the GNU make command. \begin{verbatim} CFLAGS="-DTFM_DESC" make install \end{verbatim} That will build LibTomCrypt (including the TomsFastMath descriptor), and install it in the default locations indicated previously. You can enable the built--in LibTomMath descriptor as well (or in place of the TomsFastMath descriptor). Similarly, you can build the library with no built--in math descriptors. \begin{verbatim} make install \end{verbatim} In this case, no math descriptors are present in the library and they will have to be made available at build or run time before you can use any of the public key functions. Note that even if you include the built--in descriptors you must link against the source library as well. \begin{verbatim} gcc -DTFM_DESC myprogram.c -ltomcrypt -ltfm -o myprogram \end{verbatim} This will compile \textit{myprogram} and link it against the LibTomCrypt library as well as TomsFastMath (which must have been previously installed). Note that we define \textbf{TFM\_DESC} for compilation. This is so that the TFM descriptor symbol will be defined for the client application to make use of without giving warnings. \mysection{Building a Shared Library} LibTomCrypt can also be built as a shared library through the \textit{makefile.shared} make script. It is similar to use as the static script except that you \textbf{must} specify the \textbf{EXTRALIBS} variable at install time. \begin{verbatim} CFLAGS="-DTFM_DESC" EXTRALIBS=-ltfm make -f makefile.shared install \end{verbatim} This will build and install the library and link the shared object against the TomsFastMath library (which must be installed as a shared object as well). The shared build process requires libtool to be installed. \mysection{Header Configuration} The file \textit{tomcrypt\_cfg.h} is what lets you control various high level macros which control the behaviour of the library. Build options are also stored in \textit{tomcrypt\_custom.h} which allow the enabling and disabling of various algorithms. \subsubsection{ARGTYPE} This lets you control how the LTC\_ARGCHK macro will behave. The macro is used to check pointers inside the functions against NULL. There are four settings for ARGTYPE. When set to 0, it will have the default behaviour of printing a message to stderr and raising a SIGABRT signal. This is provided so all platforms that use LibTomCrypt can have an error that functions similarly. When set to 1, it will simply pass on to the assert() macro. When set to 2, the macro will display the error to stderr then return execution to the caller. This could lead to a segmentation fault (e.g. when a pointer is \textbf{NULL}) but is useful if you handle signals on your own. When set to 3, it will resolve to a empty macro and no error checking will be performed. Finally, when set to 4, it will return CRYPT\_INVALID\_ARG to the caller. \subsubsection{Endianess} There are five macros related to endianess issues. For little endian platforms define, \textbf{ENDIAN\_LITTLE}. For big endian platforms define \textbf{ENDIAN\_BIG}. Similarly when the default word size of an \textit{unsigned long} is 32-bits define \textbf{ENDIAN\_32BITWORD} or define \textbf{ENDIAN\_64BITWORD} when its 64-bits. If you do not define any of them the library will automatically use \textbf{ENDIAN\_NEUTRAL} which will work on all platforms. Currently LibTomCrypt will detect x86-32, x86-64, MIPS R5900, SPARC and SPARC64 running GCC as well as x86-32 running MSVC. \mysection{The Configure Script} There are also options you can specify from the \textit{tomcrypt\_custom.h} header file. \subsection{X memory routines} \index{XMALLOC}\index{XCALLOC}\index{XREALLOC}\index{XFREE} At the top of tomcrypt\_custom.h are a series of macros denoted as XMALLOC, XCALLOC, XREALLOC, XFREE, and so on. They resolve to the name of the respective functions from the standard C library by default. This lets you substitute in your own memory routines. If you substitute in your own functions they must behave like the standard C library functions in terms of what they expect as input and output. These macros are handy for working with platforms which do not have a standard C library. For instance, the OLPC\footnote{See http://dev.laptop.org/git?p=bios-crypto;a=summary} bios code uses these macros to redirect to very compact heap and string operations. \subsection{X clock routines} The rng\_get\_bytes() function can call a function that requires the clock() function. These macros let you override the default clock() used with a replacement. By default the standard C library clock() function is used. \subsection{LTC\_NO\_FILE} During the build if LTC\_NO\_FILE is defined then any function in the library that uses file I/O will not call the file I/O functions and instead simply return CRYPT\_NOP. This should help resolve any linker errors stemming from a lack of file I/O on embedded platforms. \subsection{LTC\_CLEAN\_STACK} When this functions is defined the functions that store key material on the stack will clean up afterwards. Assumes that you have no memory paging with the stack. \subsection{LTC\_TEST} When this has been defined the various self--test functions (for ciphers, hashes, prngs, etc) are included in the build. This is the default configuration. If LTC\_NO\_TEST has been defined, the testing routines will be compacted and only return CRYPT\_NOP. \subsection{LTC\_NO\_FAST} When this has been defined the library will not use faster word oriented operations. By default, they are only enabled for platforms which can be auto-detected. This macro ensures that they are never enabled. \subsection{LTC\_FAST} This mode (auto-detected with x86\_32,x86\_64 platforms with GCC or MSVC) configures various routines such as ctr\_encrypt() or cbc\_encrypt() that it can safely XOR multiple octets in one step by using a larger data type. This has the benefit of cutting down the overhead of the respective functions. This mode does have one downside. It can cause unaligned reads from memory if you are not careful with the functions. This is why it has been enabled by default only for the x86 class of processors where unaligned accesses are allowed. Technically LTC\_FAST is not \textit{portable} since unaligned accesses are not covered by the ISO C specifications. In practice however, you can use it on pretty much any platform (even MIPS) with care. By design the \textit{fast} mode functions won't get unaligned on their own. For instance, if you call ctr\_encrypt() right after calling ctr\_start() and all the inputs you gave are aligned than ctr\_encrypt() will perform aligned memory operations only. However, if you call ctr\_encrypt() with an odd amount of plaintext then call it again the CTR pad (the IV) will be partially used. This will cause the ctr routine to first use up the remaining pad bytes. Then if there are enough plaintext bytes left it will use whole word XOR operations. These operations will be unaligned. The simplest precaution is to make sure you process all data in power of two blocks and handle \textit{remainder} at the end. e.g. If you are CTR'ing a long stream process it in blocks of (say) four kilobytes and handle any remaining incomplete blocks at the end of the stream. \index{LTC\_FAST\_TYPE} If you do plan on using the \textit{LTC\_FAST} mode you have to also define a \textit{LTC\_FAST\_TYPE} macro which resolves to an optimal sized data type you can perform integer operations with. Ideally it should be four or eight bytes since it must properly divide the size of your block cipher (e.g. 16 bytes for AES). This means sadly if you're on a platform with 57--bit words (or something) you can't use this mode. So sad. \subsection{LTC\_NO\_ASM} When this has been defined the library will not use any inline assembler. Only a few platforms support assembler inlines but various versions of ICC and GCC cannot handle all of the assembler functions. \subsection{Symmetric Ciphers, One-way Hashes, PRNGS and Public Key Functions} There are a plethora of macros for the ciphers, hashes, PRNGs and public key functions which are fairly self-explanatory. When they are defined the functionality is included otherwise it is not. There are some dependency issues which are noted in the file. For instance, Yarrow requires CTR chaining mode, a block cipher and a hash function. Also see technical note number five for more details. \subsection{LTC\_EASY} When defined the library is configured to build fewer algorithms and modes. Mostly it sticks to NIST and ANSI approved algorithms. See the header file \textit{tomcrypt\_custom.h} for more details. It is meant to provide literally an easy method of trimming the library build to the most minimum of useful functionality. \subsection{TWOFISH\_SMALL and TWOFISH\_TABLES} Twofish is a 128-bit symmetric block cipher that is provided within the library. The cipher itself is flexible enough to allow some trade-offs in the implementation. When TWOFISH\_SMALL is defined the scheduled symmetric key for Twofish requires only 200 bytes of memory. This is achieved by not pre-computing the substitution boxes. Having this defined will also greatly slow down the cipher. When this macro is not defined Twofish will pre-compute the tables at a cost of 4KB of memory. The cipher will be much faster as a result. When TWOFISH\_TABLES is defined the cipher will use pre-computed (and fixed in code) tables required to work. This is useful when TWOFISH\_SMALL is defined as the table values are computed on the fly. When this is defined the code size will increase by approximately 500 bytes. If this is defined but TWOFISH\_SMALL is not the cipher will still work but it will not speed up the encryption or decryption functions. \subsection{GCM\_TABLES} When defined GCM will use a 64KB table (per GCM state) which will greatly speed up the per--packet latency. It also increases the initialization time and is not suitable when you are going to use a key a few times only. \subsection{GCM\_TABLES\_SSE2} \index{SSE2} When defined GCM will use the SSE2 instructions to perform the $GF(2^x)$ multiply using 16 128--bit XOR operations. It shaves a few cycles per byte of GCM output on both the AMD64 and Intel Pentium 4 platforms. Requires GCC and an SSE2 equipped platform. \subsection{LTC\_SMALL\_CODE} When this is defined some of the code such as the Rijndael and SAFER+ ciphers are replaced with smaller code variants. These variants are slower but can save quite a bit of code space. \subsection{LTC\_PTHREAD} When this is activated all of the descriptor table functions will use pthread locking to ensure thread safe updates to the tables. Note that it doesn't prevent a thread that is passively using a table from being messed up by another thread that updates the table. Generally the rule of thumb is to setup the tables once at startup and then leave them be. This added build flag simply makes updating the tables safer. \subsection{LTC\_ECC\_TIMING\_RESISTANT} When this has been defined the ECC point multiplier (built--in to the library) will use a timing resistant point multiplication algorithm which prevents leaking key bits of the private key (scalar). It is a slower algorithm but useful for situations where timing side channels pose a significant threat. \subsection{Math Descriptors} The library comes with three math descriptors that allow you to interface the public key cryptography API to freely available math libraries. When \textbf{GMP\_DESC}, \textbf{LTM\_DESC}, or \textbf{TFM\_DESC} are defined descriptors for the respective library are built and included in the library as \textit{gmp\_desc}, \textit{ltm\_desc}, or \textit{tfm\_desc} respectively. In the test demos that use the libraries the additional flags \textbf{USE\_GMP}, \textbf{USE\_LTM}, and \textbf{USE\_TFM} can be defined to tell the program which library to use. Only one of the USE flags can be defined at once. \index{GMP\_DESC} \index{USE\_GMP} \index{LTM\_DESC} \index{TFM\_DESC} \index{USE\_LTM} \index{USE\_TFM} \begin{small} \begin{verbatim} CFLAGS="-DGMP_DESC -DLTM_DESC -DTFM_DESC -DUSE_TFM" \ EXTRALIBS="-lgmp -ltommath -ltfm" make -f makefile.shared install timing \end{verbatim} \end{small} That will build and install the library with all descriptors (and link against all), but only use TomsFastMath in the timing demo. \chapter{Optimizations} \mysection{Introduction} The entire API was designed with plug and play in mind at the low level. That is you can swap out any cipher, hash, PRNG or bignum library and the dependent API will not require updating. This has the nice benefit that one can add ciphers (etc.) not have to re--write portions of the API. For the most part, LibTomCrypt has also been written to be highly portable and easy to build out of the box on pretty much any platform. As such there are no assembler inlines throughout the code, I make no assumptions about the platform, etc... That works well for most cases but there are times where performance is of the essence. This API allows optimized routines to be dropped in--place of the existing portable routines. For instance, hand optimized assembler versions of AES could be provided. Any existing function that uses the cipher could automatically use the optimized code without re--writing. This also paves the way for hardware drivers that can access hardware accelerated cryptographic devices. At the heart of this flexibility is the \textit{descriptor} system. A descriptor is essentially just a C \textit{struct} which describes the algorithm and provides pointers to functions that do the required work. For a given class of operation (e.g. cipher, hash, prng, bignum) the functions of a descriptor have identical prototypes which makes development simple. In most dependent routines all an end developer has to do is register\_XXX() the descriptor and they are set. \mysection{Ciphers} The ciphers in LibTomCrypt are accessed through the ltc\_cipher\_descriptor structure. \label{sec:cipherdesc} \begin{small} \begin{verbatim} struct ltc_cipher_descriptor { /** name of cipher */ char *name; /** internal ID */ unsigned char ID; /** min keysize (octets) */ int min_key_length, /** max keysize (octets) */ max_key_length, /** block size (octets) */ block_length, /** default number of rounds */ default_rounds; /** Setup the cipher @param key The input symmetric key @param keylen The length of the input key (octets) @param num_rounds The requested number of rounds (0==default) @param skey [out] The destination of the scheduled key @return CRYPT_OK if successful */ int (*setup)(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); /** Encrypt a block @param pt The plaintext @param ct [out] The ciphertext @param skey The scheduled key @return CRYPT_OK if successful */ int (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); /** Decrypt a block @param ct The ciphertext @param pt [out] The plaintext @param skey The scheduled key @return CRYPT_OK if successful */ int (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); /** Test the block cipher @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled */ int (*test)(void); /** Terminate the context @param skey The scheduled key */ void (*done)(symmetric_key *skey); /** Determine a key size @param keysize [in/out] The size of the key desired The suggested size @return CRYPT_OK if successful */ int (*keysize)(int *keysize); /** Accelerators **/ /** Accelerated ECB encryption @param pt Plaintext @param ct Ciphertext @param blocks The number of complete blocks to process @param skey The scheduled key context @return CRYPT_OK if successful */ int (*accel_ecb_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, symmetric_key *skey); /** Accelerated ECB decryption @param pt Plaintext @param ct Ciphertext @param blocks The number of complete blocks to process @param skey The scheduled key context @return CRYPT_OK if successful */ int (*accel_ecb_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, symmetric_key *skey); /** Accelerated CBC encryption @param pt Plaintext @param ct Ciphertext @param blocks The number of complete blocks to process @param IV The initial value (input/output) @param skey The scheduled key context @return CRYPT_OK if successful */ int (*accel_cbc_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, symmetric_key *skey); /** Accelerated CBC decryption @param pt Plaintext @param ct Ciphertext @param blocks The number of complete blocks to process @param IV The initial value (input/output) @param skey The scheduled key context @return CRYPT_OK if successful */ int (*accel_cbc_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, symmetric_key *skey); /** Accelerated CTR encryption @param pt Plaintext @param ct Ciphertext @param blocks The number of complete blocks to process @param IV The initial value (input/output) @param mode little or big endian counter (mode=0 or mode=1) @param skey The scheduled key context @return CRYPT_OK if successful */ int (*accel_ctr_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, int mode, symmetric_key *skey); /** Accelerated LRW @param pt Plaintext @param ct Ciphertext @param blocks The number of complete blocks to process @param IV The initial value (input/output) @param tweak The LRW tweak @param skey The scheduled key context @return CRYPT_OK if successful */ int (*accel_lrw_encrypt)(const unsigned char *pt, unsigned char *ct, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, symmetric_key *skey); /** Accelerated LRW @param ct Ciphertext @param pt Plaintext @param blocks The number of complete blocks to process @param IV The initial value (input/output) @param tweak The LRW tweak @param skey The scheduled key context @return CRYPT_OK if successful */ int (*accel_lrw_decrypt)(const unsigned char *ct, unsigned char *pt, unsigned long blocks, unsigned char *IV, const unsigned char *tweak, symmetric_key *skey); /** Accelerated CCM packet (one-shot) @param key The secret key to use @param keylen The length of the secret key (octets) @param uskey A previously scheduled key [can be NULL] @param nonce The session nonce [use once] @param noncelen The length of the nonce @param header The header for the session @param headerlen The length of the header (octets) @param pt [out] The plaintext @param ptlen The length of the plaintext (octets) @param ct [out] The ciphertext @param tag [out] The destination tag @param taglen [in/out] The max size and resulting size of the authentication tag @param direction Encrypt or Decrypt direction (0 or 1) @return CRYPT_OK if successful */ int (*accel_ccm_memory)( const unsigned char *key, unsigned long keylen, symmetric_key *uskey, const unsigned char *nonce, unsigned long noncelen, const unsigned char *header, unsigned long headerlen, unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tag, unsigned long *taglen, int direction); /** Accelerated GCM packet (one shot) @param key The secret key @param keylen The length of the secret key @param IV The initial vector @param IVlen The length of the initial vector @param adata The additional authentication data (header) @param adatalen The length of the adata @param pt The plaintext @param ptlen The length of the plaintext/ciphertext @param ct The ciphertext @param tag [out] The MAC tag @param taglen [in/out] The MAC tag length @param direction Encrypt or Decrypt mode (GCM_ENCRYPT or GCM_DECRYPT) @return CRYPT_OK on success */ int (*accel_gcm_memory)( const unsigned char *key, unsigned long keylen, const unsigned char *IV, unsigned long IVlen, const unsigned char *adata, unsigned long adatalen, unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tag, unsigned long *taglen, int direction); /** Accelerated one shot OMAC @param key The secret key @param keylen The key length (octets) @param in The message @param inlen Length of message (octets) @param out [out] Destination for tag @param outlen [in/out] Initial and final size of out @return CRYPT_OK on success */ int (*omac_memory)( const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); /** Accelerated one shot XCBC @param key The secret key @param keylen The key length (octets) @param in The message @param inlen Length of message (octets) @param out [out] Destination for tag @param outlen [in/out] Initial and final size of out @return CRYPT_OK on success */ int (*xcbc_memory)( const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); /** Accelerated one shot F9 @param key The secret key @param keylen The key length (octets) @param in The message @param inlen Length of message (octets) @param out [out] Destination for tag @param outlen [in/out] Initial and final size of out @return CRYPT_OK on success @remark Requires manual padding */ int (*f9_memory)( const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); }; \end{verbatim} \end{small} \subsection{Name} \index{find\_cipher()} The \textit{name} parameter specifies the name of the cipher. This is what a developer would pass to find\_cipher() to find the cipher in the descriptor tables. \subsection{Internal ID} This is a single byte Internal ID you can use to distinguish ciphers from each other. \subsection{Key Lengths} The minimum key length is \textit{min\_key\_length} and is measured in octets. Similarly the maximum key length is \textit{max\_key\_length}. They can be equal and both must valid key sizes for the cipher. Values in between are not assumed to be valid though they may be. \subsection{Block Length} The size of the ciphers plaintext or ciphertext is \textit{block\_length} and is measured in octets. \subsection{Rounds} Some ciphers allow different number of rounds to be used. Usually you just use the default. The default round count is \textit{default\_rounds}. \subsection{Setup} To initialize a cipher (for ECB mode) the function setup() was provided. It accepts an array of key octets \textit{key} of length \textit{keylen} octets. The user can specify the number of rounds they want through \textit{num\_rounds} where $num\_rounds = 0$ means use the default. The destination of a scheduled key is stored in \textit{skey}. Inside the \textit{symmetric\_key} union there is a \textit{void *data} which you can use to allocate data if you need a data structure that does not fit with the existing ones provided. Just make sure in your \textit{done()} function that you free the allocated memory. \subsection{Single block ECB} To process a single block in ECB mode the ecb\_encrypt() and ecb\_decrypt() functions were provided. The plaintext and ciphertext buffers are allowed to overlap so you must make sure you do not overwrite the output before you are finished with the input. \subsection{Testing} The test() function is used to self--test the \textit{device}. It takes no arguments and returns \textbf{CRYPT\_OK} if all is working properly. You may return \textbf{CRYPT\_NOP} to indicate that no testing was performed. \subsection{Key Sizing} Occasionally, a function will want to find a suitable key size to use since the input is oddly sized. The keysize() function is for this case. It accepts a pointer to an integer which represents the desired size. The function then has to match it to the exact or a lower key size that is valid for the cipher. For example, if the input is $25$ and $24$ is valid then it stores $24$ back in the pointed to integer. It must not round up and must return an error if the keysize cannot be mapped to a valid key size for the cipher. \subsection{Acceleration} The next set of functions cover the accelerated functionality of the cipher descriptor. Any combination of these functions may be set to \textbf{NULL} to indicate it is not supported. In those cases the software defaults are used (using the single ECB block routines). \subsubsection{Accelerated ECB} These two functions are meant for cases where a user wants to encrypt (in ECB mode no less) an array of blocks. These functions are accessed through the accel\_ecb\_encrypt and accel\_ecb\_decrypt pointers. The \textit{blocks} count is the number of complete blocks to process. \subsubsection{Accelerated CBC} These two functions are meant for accelerated CBC encryption. These functions are accessed through the accel\_cbc\_encrypt and accel\_cbc\_decrypt pointers. The \textit{blocks} value is the number of complete blocks to process. The \textit{IV} is the CBC initial vector. It is an input upon calling this function and must be updated by the function before returning. \subsubsection{Accelerated CTR} This function is meant for accelerated CTR encryption. It is accessible through the accel\_ctr\_encrypt pointer. The \textit{blocks} value is the number of complete blocks to process. The \textit{IV} is the CTR counter vector. It is an input upon calling this function and must be updated by the function before returning. The \textit{mode} value indicates whether the counter is big (mode = CTR\_COUNTER\_BIG\_ENDIAN) or little (mode = CTR\_COUNTER\_LITTLE\_ENDIAN) endian. This function (and the way it's called) differs from the other two since ctr\_encrypt() allows any size input plaintext. The accelerator will only be called if the following conditions are met. \begin{enumerate} \item The accelerator is present \item The CTR pad is empty \item The remaining length of the input to process is greater than or equal to the block size. \end{enumerate} The \textit{CTR pad} is empty when a multiple (including zero) blocks of text have been processed. That is, if you pass in seven bytes to AES--CTR mode you would have to pass in a minimum of nine extra bytes before the accelerator could be called. The CTR accelerator must increment the counter (and store it back into the buffer provided) before encrypting it to create the pad. The accelerator will only be used to encrypt whole blocks. Partial blocks are always handled in software. \subsubsection{Accelerated LRW} These functions are meant for accelerated LRW. They process blocks of input in lengths of multiples of 16 octets. They must accept the \textit{IV} and \textit{tweak} state variables and updated them prior to returning. Note that you may want to disable \textbf{LRW\_TABLES} in \textit{tomcrypt\_custom.h} if you intend to use accelerators for LRW. While both encrypt and decrypt accelerators are not required it is suggested as it makes lrw\_setiv() more efficient. Note that calling lrw\_done() will only invoke the cipher\_descriptor[].done() function on the \textit{symmetric\_key} parameter of the LRW state. That means if your device requires any (LRW specific) resources you should free them in your ciphers() done function. The simplest way to think of it is to write the plugin solely to do LRW with the cipher. That way cipher\_descriptor[].setup() means to init LRW resources and cipher\_descriptor[].done() means to free them. \subsubsection{Accelerated CCM} This function is meant for accelerated CCM encryption or decryption. It processes the entire packet in one call. You can optimize the work flow somewhat by allowing the caller to call the setup() function first to schedule the key if your accelerator cannot do the key schedule on the fly (for instance). This function MUST support both key passing methods. \begin{center} \begin{small} \begin{tabular}{|r|r|l|} \hline \textbf{key} & \textbf{uskey} & \textbf{Source of key} \\ \hline NULL & NULL & Error, not supported \\ \hline non-NULL & NULL & Use key, do a key schedule \\ \hline NULL & non-NULL & Use uskey, key schedule not required \\ \hline non-NULL & non-NULL & Use uskey, key schedule not required \\ \hline \end{tabular} \end{small} \end{center} \index{ccm\_memory()} This function is called when the user calls ccm\_memory(). \subsubsection{Accelerated GCM} \index{gcm\_memory()} This function is meant for accelerated GCM encryption or decryption. It processes the entire packet in one call. Note that the setup() function will not be called prior to this. This function must handle scheduling the key provided on its own. It is called when the user calls gcm\_memory(). \subsubsection{Accelerated OMAC} \index{omac\_memory()} This function is meant to perform an optimized OMAC1 (CMAC) message authentication code computation when the user calls omac\_memory(). \subsubsection{Accelerated XCBC-MAC} \index{xcbc\_memory()} This function is meant to perform an optimized XCBC-MAC message authentication code computation when the user calls xcbc\_memory(). \subsubsection{Accelerated F9} \index{f9\_memory()} This function is meant to perform an optimized F9 message authentication code computation when the user calls f9\_memory(). Like f9\_memory(), it requires the caller to perform any 3GPP related padding before calling in order to ensure proper compliance with F9. \mysection{One--Way Hashes} The hash functions are accessed through the ltc\_hash\_descriptor structure. \begin{small} \begin{verbatim} struct ltc_hash_descriptor { /** name of hash */ char *name; /** internal ID */ unsigned char ID; /** Size of digest in octets */ unsigned long hashsize; /** Input block size in octets */ unsigned long blocksize; /** ASN.1 OID */ unsigned long OID[16]; /** Length of DER encoding */ unsigned long OIDlen; /** Init a hash state @param hash The hash to initialize @return CRYPT_OK if successful */ int (*init)(hash_state *hash); /** Process a block of data @param hash The hash state @param in The data to hash @param inlen The length of the data (octets) @return CRYPT_OK if successful */ int (*process)( hash_state *hash, const unsigned char *in, unsigned long inlen); /** Produce the digest and store it @param hash The hash state @param out [out] The destination of the digest @return CRYPT_OK if successful */ int (*done)( hash_state *hash, unsigned char *out); /** Self-test @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled */ int (*test)(void); /* accelerated hmac callback: if you need to-do multiple packets just use the generic hmac_memory and provide a hash callback */ int (*hmac_block)(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); }; \end{verbatim} \end{small} \subsection{Name} This is the name the hash is known by and what find\_hash() will look for. \subsection{Internal ID} This is the internal ID byte used to distinguish the hash from other hashes. \subsection{Digest Size} The \textit{hashsize} variable indicates the length of the output in octets. \subsection{Block Size} The \textit{blocksize} variable indicates the length of input (in octets) that the hash processes in a given invocation. \subsection{OID Identifier} This is the universal ASN.1 Object Identifier for the hash. \subsection{Initialization} The init function initializes the hash and prepares it to process message bytes. \subsection{Process} This processes message bytes. The algorithm must accept any length of input that the hash would allow. The input is not guaranteed to be a multiple of the block size in length. \subsection{Done} The done function terminates the hash and returns the message digest. \subsection{Acceleration} A compatible accelerator must allow processing data in any granularity which may require internal padding on the driver side. \subsection{HMAC Acceleration} The hmac\_block() callback is meant for single--shot optimized HMAC implementations. It is called directly by hmac\_memory() if present. If you need to be able to process multiple blocks per MAC then you will have to simply provide a process() callback and use hmac\_memory() as provided in LibTomCrypt. \mysection{Pseudo--Random Number Generators} The pseudo--random number generators are accessible through the ltc\_prng\_descriptor structure. \begin{small} \begin{verbatim} struct ltc_prng_descriptor { /** Name of the PRNG */ char *name; /** size in bytes of exported state */ int export_size; /** Start a PRNG state @param prng [out] The state to initialize @return CRYPT_OK if successful */ int (*start)(prng_state *prng); /** Add entropy to the PRNG @param in The entropy @param inlen Length of the entropy (octets) @param prng The PRNG state @return CRYPT_OK if successful */ int (*add_entropy)(const unsigned char *in, unsigned long inlen, prng_state *prng); /** Ready a PRNG state to read from @param prng The PRNG state to ready @return CRYPT_OK if successful */ int (*ready)(prng_state *prng); /** Read from the PRNG @param out [out] Where to store the data @param outlen Length of data desired (octets) @param prng The PRNG state to read from @return Number of octets read */ unsigned long (*read)(unsigned char *out, unsigned long outlen, prng_state *prng); /** Terminate a PRNG state @param prng The PRNG state to terminate @return CRYPT_OK if successful */ int (*done)(prng_state *prng); /** Export a PRNG state @param out [out] The destination for the state @param outlen [in/out] The max size and resulting size @param prng The PRNG to export @return CRYPT_OK if successful */ int (*pexport)(unsigned char *out, unsigned long *outlen, prng_state *prng); /** Import a PRNG state @param in The data to import @param inlen The length of the data to import (octets) @param prng The PRNG to initialize/import @return CRYPT_OK if successful */ int (*pimport)(const unsigned char *in, unsigned long inlen, prng_state *prng); /** Self-test the PRNG @return CRYPT_OK if successful, CRYPT_NOP if self-testing has been disabled */ int (*test)(void); }; \end{verbatim} \end{small} \subsection{Name} The name by which find\_prng() will find the PRNG. \subsection{Export Size} When an PRNG state is to be exported for future use you specify the space required in this variable. \subsection{Start} Initialize the PRNG and make it ready to accept entropy. \subsection{Entropy Addition} Add entropy to the PRNG state. The exact behaviour of this function depends on the particulars of the PRNG. \subsection{Ready} This function makes the PRNG ready to read from by processing the entropy added. The behaviour of this function depends on the specific PRNG used. \subsection{Read} Read from the PRNG and return the number of bytes read. This function does not have to fill the buffer but it is best if it does as many protocols do not retry reads and will fail on the first try. \subsection{Done} Terminate a PRNG state. The behaviour of this function depends on the particular PRNG used. \subsection{Exporting and Importing} An exported PRNG state is data that the PRNG can later import to resume activity. They're not meant to resume \textit{the same session} but should at least maintain the same level of state entropy. \mysection{BigNum Math Descriptors} The library also makes use of the math descriptors to access math functions. While bignum math libraries usually differ in implementation it hasn't proven hard to write \textit{glue} to use math libraries so far. The basic descriptor looks like. \begin{small} \begin{verbatim} /** math descriptor */ typedef struct { /** Name of the math provider */ char *name; /** Bits per digit, amount of bits must fit in an unsigned long */ int bits_per_digit; /* ---- init/deinit functions ---- */ /** initialize a bignum @param a The number to initialize @return CRYPT_OK on success */ int (*init)(void **a); /** init copy @param dst The number to initialize and write to @param src The number to copy from @return CRYPT_OK on success */ int (*init_copy)(void **dst, void *src); /** deinit @param a The number to free @return CRYPT_OK on success */ void (*deinit)(void *a); /* ---- data movement ---- */ /** copy @param src The number to copy from @param dst The number to write to @return CRYPT_OK on success */ int (*copy)(void *src, void *dst); /* ---- trivial low level functions ---- */ /** set small constant @param a Number to write to @param n Source upto bits_per_digit (meant for small constants) @return CRYPT_OK on success */ int (*set_int)(void *a, unsigned long n); /** get small constant @param a Small number to read @return The lower bits_per_digit of the integer (unsigned) */ unsigned long (*get_int)(void *a); /** get digit n @param a The number to read from @param n The number of the digit to fetch @return The bits_per_digit sized n'th digit of a */ unsigned long (*get_digit)(void *a, int n); /** Get the number of digits that represent the number @param a The number to count @return The number of digits used to represent the number */ int (*get_digit_count)(void *a); /** compare two integers @param a The left side integer @param b The right side integer @return LTC_MP_LT if a < b, LTC_MP_GT if a > b and LTC_MP_EQ otherwise. (signed comparison) */ int (*compare)(void *a, void *b); /** compare against int @param a The left side integer @param b The right side integer (upto bits_per_digit) @return LTC_MP_LT if a < b, LTC_MP_GT if a > b and LTC_MP_EQ otherwise. (signed comparison) */ int (*compare_d)(void *a, unsigned long n); /** Count the number of bits used to represent the integer @param a The integer to count @return The number of bits required to represent the integer */ int (*count_bits)(void * a); /** Count the number of LSB bits which are zero @param a The integer to count @return The number of contiguous zero LSB bits */ int (*count_lsb_bits)(void *a); /** Compute a power of two @param a The integer to store the power in @param n The power of two you want to store (a = 2^n) @return CRYPT_OK on success */ int (*twoexpt)(void *a , int n); /* ---- radix conversions ---- */ /** read ascii string @param a The integer to store into @param str The string to read @param radix The radix the integer has been represented in (2-64) @return CRYPT_OK on success */ int (*read_radix)(void *a, const char *str, int radix); /** write number to string @param a The integer to store @param str The destination for the string @param radix The radix the integer is to be represented in (2-64) @return CRYPT_OK on success */ int (*write_radix)(void *a, char *str, int radix); /** get size as unsigned char string @param a The integer to get the size @return The length of the integer in octets */ unsigned long (*unsigned_size)(void *a); /** store an integer as an array of octets @param src The integer to store @param dst The buffer to store the integer in @return CRYPT_OK on success */ int (*unsigned_write)(void *src, unsigned char *dst); /** read an array of octets and store as integer @param dst The integer to load @param src The array of octets @param len The number of octets @return CRYPT_OK on success */ int (*unsigned_read)( void *dst, unsigned char *src, unsigned long len); /* ---- basic math ---- */ /** add two integers @param a The first source integer @param b The second source integer @param c The destination of "a + b" @return CRYPT_OK on success */ int (*add)(void *a, void *b, void *c); /** add two integers @param a The first source integer @param b The second source integer (single digit of upto bits_per_digit in length) @param c The destination of "a + b" @return CRYPT_OK on success */ int (*addi)(void *a, unsigned long b, void *c); /** subtract two integers @param a The first source integer @param b The second source integer @param c The destination of "a - b" @return CRYPT_OK on success */ int (*sub)(void *a, void *b, void *c); /** subtract two integers @param a The first source integer @param b The second source integer (single digit of upto bits_per_digit in length) @param c The destination of "a - b" @return CRYPT_OK on success */ int (*subi)(void *a, unsigned long b, void *c); /** multiply two integers @param a The first source integer @param b The second source integer (single digit of upto bits_per_digit in length) @param c The destination of "a * b" @return CRYPT_OK on success */ int (*mul)(void *a, void *b, void *c); /** multiply two integers @param a The first source integer @param b The second source integer (single digit of upto bits_per_digit in length) @param c The destination of "a * b" @return CRYPT_OK on success */ int (*muli)(void *a, unsigned long b, void *c); /** Square an integer @param a The integer to square @param b The destination @return CRYPT_OK on success */ int (*sqr)(void *a, void *b); /** Divide an integer @param a The dividend @param b The divisor @param c The quotient (can be NULL to signify don't care) @param d The remainder (can be NULL to signify don't care) @return CRYPT_OK on success */ int (*div)(void *a, void *b, void *c, void *d); /** divide by two @param a The integer to divide (shift right) @param b The destination @return CRYPT_OK on success */ int (*div_2)(void *a, void *b); /** Get remainder (small value) @param a The integer to reduce @param b The modulus (upto bits_per_digit in length) @param c The destination for the residue @return CRYPT_OK on success */ int (*modi)(void *a, unsigned long b, unsigned long *c); /** gcd @param a The first integer @param b The second integer @param c The destination for (a, b) @return CRYPT_OK on success */ int (*gcd)(void *a, void *b, void *c); /** lcm @param a The first integer @param b The second integer @param c The destination for [a, b] @return CRYPT_OK on success */ int (*lcm)(void *a, void *b, void *c); /** Modular multiplication @param a The first source @param b The second source @param c The modulus @param d The destination (a*b mod c) @return CRYPT_OK on success */ int (*mulmod)(void *a, void *b, void *c, void *d); /** Modular squaring @param a The first source @param b The modulus @param c The destination (a*a mod b) @return CRYPT_OK on success */ int (*sqrmod)(void *a, void *b, void *c); /** Modular inversion @param a The value to invert @param b The modulus @param c The destination (1/a mod b) @return CRYPT_OK on success */ int (*invmod)(void *, void *, void *); /* ---- reduction ---- */ /** setup Montgomery @param a The modulus @param b The destination for the reduction digit @return CRYPT_OK on success */ int (*montgomery_setup)(void *a, void **b); /** get normalization value @param a The destination for the normalization value @param b The modulus @return CRYPT_OK on success */ int (*montgomery_normalization)(void *a, void *b); /** reduce a number @param a The number [and dest] to reduce @param b The modulus @param c The value "b" from montgomery_setup() @return CRYPT_OK on success */ int (*montgomery_reduce)(void *a, void *b, void *c); /** clean up (frees memory) @param a The value "b" from montgomery_setup() @return CRYPT_OK on success */ void (*montgomery_deinit)(void *a); /* ---- exponentiation ---- */ /** Modular exponentiation @param a The base integer @param b The power (can be negative) integer @param c The modulus integer @param d The destination @return CRYPT_OK on success */ int (*exptmod)(void *a, void *b, void *c, void *d); /** Primality testing @param a The integer to test @param b The destination of the result (FP_YES if prime) @return CRYPT_OK on success */ int (*isprime)(void *a, int *b); /* ---- (optional) ecc point math ---- */ /** ECC GF(p) point multiplication (from the NIST curves) @param k The integer to multiply the point by @param G The point to multiply @param R The destination for kG @param modulus The modulus for the field @param map Boolean indicated whether to map back to affine or not (can be ignored if you work in affine only) @return CRYPT_OK on success */ int (*ecc_ptmul)( void *k, ecc_point *G, ecc_point *R, void *modulus, int map); /** ECC GF(p) point addition @param P The first point @param Q The second point @param R The destination of P + Q @param modulus The modulus @param mp The "b" value from montgomery_setup() @return CRYPT_OK on success */ int (*ecc_ptadd)(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp); /** ECC GF(p) point double @param P The first point @param R The destination of 2P @param modulus The modulus @param mp The "b" value from montgomery_setup() @return CRYPT_OK on success */ int (*ecc_ptdbl)(ecc_point *P, ecc_point *R, void *modulus, void *mp); /** ECC mapping from projective to affine, currently uses (x,y,z) => (x/z^2, y/z^3, 1) @param P The point to map @param modulus The modulus @param mp The "b" value from montgomery_setup() @return CRYPT_OK on success @remark The mapping can be different but keep in mind a ecc_point only has three integers (x,y,z) so if you use a different mapping you have to make it fit. */ int (*ecc_map)(ecc_point *P, void *modulus, void *mp); /** Computes kA*A + kB*B = C using Shamir's Trick @param A First point to multiply @param kA What to multiple A by @param B Second point to multiply @param kB What to multiple B by @param C [out] Destination point (can overlap with A or B) @param modulus Modulus for curve @return CRYPT_OK on success */ int (*ecc_mul2add)(ecc_point *A, void *kA, ecc_point *B, void *kB, ecc_point *C, void *modulus); /* ---- (optional) rsa optimized math (for internal CRT) ---- */ /** RSA Key Generation @param prng An active PRNG state @param wprng The index of the PRNG desired @param size The size of the key in octets @param e The "e" value (public key). e==65537 is a good choice @param key [out] Destination of a newly created private key pair @return CRYPT_OK if successful, upon error all allocated ram is freed */ int (*rsa_keygen)(prng_state *prng, int wprng, int size, long e, rsa_key *key); /** RSA exponentiation @param in The octet array representing the base @param inlen The length of the input @param out The destination (to be stored in an octet array format) @param outlen The length of the output buffer and the resulting size (zero padded to the size of the modulus) @param which PK_PUBLIC for public RSA and PK_PRIVATE for private RSA @param key The RSA key to use @return CRYPT_OK on success */ int (*rsa_me)(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, int which, rsa_key *key); } ltc_math_descriptor; \end{verbatim} \end{small} Most of the functions are fairly straightforward and do not need documentation. We'll cover the basic conventions of the API and then explain the accelerated functions. \subsection{Conventions} All \textit{bignums} are accessed through an opaque \textit{void *} data type. You must internally cast the pointer if you need to access members of your bignum structure. During the init calls a \textit{void **} will be passed where you allocate your structure and set the pointer then initialize the number to zero. During the deinit calls you must free the bignum as well as the structure you allocated to place it in. All functions except the Montgomery reductions work from left to right with the arguments. For example, mul(a, b, c) computes $c \leftarrow ab$. All functions (except where noted otherwise) return \textbf{CRYPT\_OK} to signify a successful operation. All error codes must be valid LibTomCrypt error codes. The digit routines (including functions with the \textit{i} suffix) use a \textit{unsigned long} to represent the digit. If your internal digit is larger than this you must then partition your digits. Normally this does not matter as \textit{unsigned long} will be the same size as your register size. Note that if your digit is smaller than an \textit{unsigned long} that is also acceptable as the \textit{bits\_per\_digit} parameter will specify this. \subsection{ECC Functions} The ECC system in LibTomCrypt is based off of the NIST recommended curves over $GF(p)$ and is used to implement EC-DSA and EC-DH. The ECC functions work with the \textbf{ecc\_point} structure and assume the points are stored in Jacobian projective format. \begin{verbatim} /** A point on a ECC curve, stored in Jacobian format such that (x,y,z) => (x/z^2, y/z^3, 1) when interpreted as affine */ typedef struct { /** The x co-ordinate */ void *x; /** The y co-ordinate */ void *y; /** The z co-ordinate */ void *z; } ecc_point; \end{verbatim} All ECC functions must use this mapping system. The only exception is when you remap all ECC callbacks which will allow you to have more control over how the ECC math will be implemented. Out of the box you only have three parameters per point to use $(x, y, z)$ however, these are just void pointers. They could point to anything you want. The only further exception is the export functions which expects the values to be in affine format. \subsubsection{Point Multiply} This will multiply the point $G$ by the scalar $k$ and store the result in the point $R$. The value should be mapped to affine only if $map$ is set to one. \subsubsection{Point Addition} This will add the point $P$ to the point $Q$ and store it in the point $R$. The $mp$ parameter is the \textit{b} value from the montgomery\_setup() call. The input points may be in either affine (with $z = 1$) or projective format and the output point is always projective. \subsubsection{Point Mapping} This will map the point $P$ back from projective to affine. The output point $P$ must be of the form $(x, y, 1)$. \subsubsection{Shamir's Trick} \index{Shamir's Trick} \index{ltc\_ecc\_mul2add()} To accelerate EC--DSA verification the library provides a built--in function called ltc\_ecc\_mul2add(). This performs two point multiplications and an addition in roughly the time of one point multiplication. It is called from ecc\_verify\_hash() if an accelerator is not present. The acclerator function must allow the points to overlap (e.g., $A \leftarrow k_1A + k_2B$) and must return the final point in affine format. \subsection{RSA Functions} The RSA Modular Exponentiation (ME) function is used by the RSA API to perform exponentiations for private and public key operations. In particular for private key operations it uses the CRT approach to lower the time required. It is passed an RSA key with the following format. \begin{verbatim} /** RSA PKCS style key */ typedef struct Rsa_key { /** Type of key, PK_PRIVATE or PK_PUBLIC */ int type; /** The public exponent */ void *e; /** The private exponent */ void *d; /** The modulus */ void *N; /** The p factor of N */ void *p; /** The q factor of N */ void *q; /** The 1/q mod p CRT param */ void *qP; /** The d mod (p - 1) CRT param */ void *dP; /** The d mod (q - 1) CRT param */ void *dQ; } rsa_key; \end{verbatim} The call reads the \textit{in} buffer as an unsigned char array in big endian format. Then it performs the exponentiation and stores the output in big endian format to the \textit{out} buffer. The output must be zero padded (leading bytes) so that the length of the output matches the length of the modulus (in bytes). For example, for RSA--1024 the output is always 128 bytes regardless of how small the numerical value of the exponentiation is. Since the function is given the entire RSA key (for private keys only) CRT is possible as prescribed in the PKCS \#1 v2.1 specification. \newpage \markboth{Index}{Index} \input{crypt.ind} \end{document} % $Source: /cvs/libtom/libtomcrypt/crypt.tex,v $ % $Revision: 1.128 $ % $Date: 2007/03/10 23:59:54 $ libtomcrypt-1.17/Doxyfile0000644000175100001440000013461210621351501014240 0ustar tomusers# Doxyfile 1.3.9.1 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = LibTomCrypt # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = 1.17 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = doc/doxygen # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of source # files, where putting all generated files in the same directory would otherwise # cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, # Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, # Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, # Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, # Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # This tag can be used to specify the encoding used in the generated output. # The encoding is not always determined by the language that is chosen, # but also whether or not the output is meant for Windows or non-Windows users. # In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES # forces the Windows encoding (this is the default for the Windows binary), # whereas setting the tag to NO uses a Unix-style encoding (the default for # all platforms other than Windows). USE_WINDOWS_ENCODING = NO # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is used # as the annotated text. Otherwise, the brief description is used as-is. If left # blank, the following values are used ("$name" is automatically replaced with the # name of the entity): "The $name class" "The $name widget" "The $name file" # "is" "provides" "specifies" "contains" "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited # members of a class in the documentation of that class as if those members were # ordinary class members. Constructors, destructors and assignment operators of # the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = src # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = src/headers # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like the Qt-style comments (thus requiring an # explicit @brief command for a brief description. JAVADOC_AUTOBRIEF = YES # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the DETAILS_AT_TOP tag is set to YES then Doxygen # will output the detailed description near the top, like JavaDoc. # If set to NO, the detailed description appears after the member # documentation. DETAILS_AT_TOP = YES # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 4 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources # only. Doxygen will then generate output that is more tailored for Java. # For instance, namespaces will be presented as packages, qualified scopes # will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = YES # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = YES # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = YES # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = src # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp # *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm FILE_PATTERNS = # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories # that are symbolic links (a Unix filesystem feature) are excluded from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. EXCLUDE_PATTERNS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = YES # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = NO # If the REFERENCED_BY_RELATION tag is set to YES (the default) # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES (the default) # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = doc/header.html # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = doc/footer.html # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compressed HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 1 # If the GENERATE_TREEVIEW tag is set to YES, a side panel will be # generated containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. GENERATE_TREEVIEW = YES # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = YES # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = YES # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_PREDEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = src/headers # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse the # parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or # super classes. Setting the tag to NO turns the diagrams off. Note that this # option is superseded by the HAVE_DOT option below. This is only a fallback. It is # recommended to install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = NO # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a call dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable call graphs for selected # functions only using the \callgraph command. CALL_GRAPH = YES # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found on the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_WIDTH = 1024 # The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_HEIGHT = 1024 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes that # lay further from the root node will be omitted. Note that setting this option to # 1 or 2 may greatly reduce the computation time needed for large code bases. Also # note that a graph may be further truncated if the graph's image dimensions are # not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). # If 0 is used for the depth value (the default), the graph is not depth-constrained. MAX_DOT_GRAPH_DEPTH = 0 # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO libtomcrypt-1.17/testme.sh0000644000175100001440000000315710621351501014366 0ustar tomusers#!/bin/bash # date echo "date="`date` # output version echo "Testing verion" `grep "^VERSION=" makefile | sed "s/.*=//"` #grep "VERSION=" makefile | perl -e "@a = split('=', <>); print @a[1];"` # get uname echo "uname="`uname -a` # get gcc name echo "gcc="`gcc -dumpversion` echo # stock build bash run.sh "STOCK" " " "$1" "$2" "$3" || exit 1 # SMALL code bash run.sh "SMALL" "-DLTC_SMALL_CODE" "$1" "$2" "$3" || exit 1 # NOTABLES bash run.sh "NOTABLES" "-DLTC_NO_TABLES" "$1" "$2" "$3" || exit 1 # SMALL+NOTABLES bash run.sh "SMALL+NOTABLES" "-DLTC_SMALL_CODE -DLTC_NO_TABLES" "$1" "$2" "$3" || exit 1 # CLEANSTACK bash run.sh "CLEANSTACK" "-DLTC_CLEAN_STACK" "$1" "$2" "$3" || exit 1 # CLEANSTACK + SMALL bash run.sh "CLEANSTACK+SMALL" "-DLTC_SMALL_CODE -DLTC_CLEAN_STACK" "$1" "$2" "$3" || exit 1 # CLEANSTACK + NOTABLES bash run.sh "CLEANSTACK+NOTABLES" "-DLTC_NO_TABLES -DLTC_CLEAN_STACK" "$1" "$2" "$3" || exit 1 # CLEANSTACK + NOTABLES + SMALL bash run.sh "CLEANSTACK+NOTABLES+SMALL" "-DLTC_NO_TABLES -DLTC_CLEAN_STACK -DLTC_SMALL_CODE" "$1" "$2" "$3" || exit 1 # NO_FAST bash run.sh "NO_FAST" "-DLTC_NO_FAST" "$1" "$2" "$3" || exit 1 # NO_FAST + NOTABLES bash run.sh "NO_FAST+NOTABLES" "-DLTC_NO_FAST -DLTC_NO_TABLES" "$1" "$2" "$3" || exit 1 # NO_ASM bash run.sh "NO_ASM" "-DLTC_NO_ASM" "$1" "$2" "$3" || exit 1 # test build with no testing bash testbuild.sh "NOTEST" "-DLTC_NO_TEST" "$1" "$2" "$3" || exit 1 # test build with no file routines bash testbuild.sh "NOFILE" "-DLTC_NO_FILE" "$1" "$2" "$3" || exit 1 # $Source: /cvs/libtom/libtomcrypt/testme.sh,v $ # $Revision: 1.20 $ # $Date: 2006/01/26 14:49:43 $ libtomcrypt-1.17/changes0000644000175100001440000033130210621351501014060 0ustar tomusersMay 12th, 2007 v1.17 -- Cryptography Research Inc. contributed another small volley of patches, one to fix __WCHAR_DEFINED__ for BSD platforms, another to silence MSVC warnings. -- Added LTC_XCBC_PURE to XCBC mode which lets you use it in three-key mode. -- [CRI] Added libtomcrypt.dsp for Visual C++ users. -- [CRI] Added more functions for manipulating the ECC fixed point cache (including saving and loading) -- [CRI] Modified ecc_make_key() to always produce keys smaller than base point order, for standards-compliance -- Elliptic Semiconductor contributed XTS chaining mode to the cipher suite (subsequently optimized it) -- Fixed xcbc_init() keylen when using single key mode. -- Bruce Fortune pointed out a typo in the hmac_process() description in the manual. Fixed. -- Added variable width counter support to CTR mode -- Fixed CMAC (aka OMAC) when using 64-bit block ciphers and LTC_FAST ... my bad. -- Fixed bug in ecc_is_valid() that would basically always return true -- renamed a lot of macros to add the LTC_ prefix [e.g. RIJNDAEL => LTC_RIJNDAEL] December 16th, 2006 v1.16 -- Brian Gladman pointed out that a recent change to GCM broke how the IV was handled. Currently the code complies against his test vectors so the code should be considered frozen now. -- Trevor from Cryptography Research Inc. submitted patches to convert the ECC code to be generic allowing curve parameters to be submitted at runtime. -- Fixed various doxygen comments -- Added UTF8 support to the ASN1 code -- Fixed STOREXXH macros for x86 platforms (Fix found at Elliptic Inc.) -- Added makefile.unix which is BSD compatible, you have to manually tweak it since well I don't use it normally -- removed a few lingering memcpy's -- Fixed memory free errors in ecc_sign_hash() that can arise if the mp_init_multi() fails -- Fixed incorrect return value in pkcs_1_pss_decode() which would correctly set res to 0 (indicating an incorrect signature) but would return CRYPT_OK to the caller -- ltc_ecc_mulmod() could leak memory if mp_init(&mu) failed, fixed. Would you believe that ltc_ecc_mulmod_timing() had the same bug? Also fixed. :-) -- Added Shamir's trick to the ECC side (defined as LTC_ECC_SHAMIR, enabled by default), gets ~1.34x to ~1.40x faster ECC verifications -- Added Brian's vector #46 to the GCM code. It catches the ctr counter error from v1.15. Originally I was going to add all of his vectors, but they're not as easy to parse and I got a lot of other things to do. Regression! -- Various other small fixes to the ECC code to clean up error handling (I think most of that was from the move in 1.06 to the plugins) All of the errors were in cleaning up from heap failures. So they were not likely to be triggered in normal usage Made similar fixes to the RSA and DSA code (my bad) -- Cryptography Research Inc. contributed a bunch of fixes to silence warnings (with MSVC) w.r.t. assigned data to unsigned char types. -- Martin Marko suggested some fixes to make the RNG build with WinCE. -- Updates to the manual for print (some fixes thanks to Martin Marko) November 17th, 2006 v1.15 -- Andreas Lange found that if sha256_init DID fail in fortuna it wouldn't clean up the state correctly. Thanks. Fortunately sha256_init cannot fail (as of v1.14) :-) -- Andreas Lange contributed RMD-256 and RMD-320 code. -- Removed mutex locks from fortuna_import as they create a deadlock and aren't required anyways [Avi Zelmanovich] -- Added LTC_NO_PROTOTYPES to avoid prototyping functions like memset/memcpy. Required for fans of GCC 3.3.x -- David Eder caught a off by one overrun bug in pmac_done() which can be exploited if your output tag buffer is smaller than the block size of the cipher, e.g. if you have a 4-byte buffer and you tell pmac_done that you want a 4-byte TAG it will store 4 bytes but return an outlen of 5. -- Added signatures to the ECC and RSA benchmarks -- Added LTC_PROFILE to run the PK tests only once in the timing demo (so you can capture events properly) -- Andreas contributed PKCS #1 v1.5 code that merged cleanly with the existing PKCS code. w00t. (update: I had to fix it to include the digestInfo and what not. Bad Andreas, bad! hehehe) -- Fixed a signed variable error in gcm_process() (hard to trigger bug fortunately) -- Removed all memcmp/memset/memcpy from the source (replaced with X macros) -- Renamed macros HMAC/OMAC/PMAC to have a LTC_ prefix. If you pass these on the command line please update your makefiles -- Added XCBC-MAC support [RFC 3566] -- fixed LOAD32H and LOAD64H to stop putting out that darn warning :-) -- Added the Korean SEED block cipher [RFC 4269] -- Added LTC_VALGRIND define which makes SOBER-128 and RC4 a pure PRNG (and not a stream cipher). Useful if you use Valgrind to debug your code (reported by Andreas Lange) -- Made SOBER-128 more portable by removing the ASCII key in the test function (my bad, sorry). -- Martin Mocko pointed out that if you have no PRNGs defined the lib won't build. Fixed, also fixed for if you have no hashes defined. -- Sped up F8 mode with LTC_FAST -- Made CTR mode RFC 3686 compliant (increment counter first), to enable, OR the value LTC_CTR_RFC3686 to the "mode" parameter you pass to ctr_start(), otherwise it will be LTC compliant (e.g. encrypt then increment) -- Added ctr_test() to test CTR mode against RFC 3686 -- Added crypt_fsa() ... O_o -- Fixed LTC_ECC_TIMING_RESISTANT so it once again builds properly (pt add/dbl are through the plugin now) -- Added ANSI X9.63 (sec 4.3.6) import/export of public keys (cannot export to compressed formats but will import hybrid compressed) -- Added SECP curves for 112, 128, and 160 bits (only the 'r1' curves) -- Added 3GPP-F9 MAC (thanks to Greg Rose for the test vectors) -- Added the KASUMI block cipher -- Added F9/XCBC/OMAC callbacks to the cipher plugin -- Added RSA PKCS #1 v1.5 signature/encrypt tests to rsa_test.c -- Fix to yarrow_test() to not call yarrow_done() which is invalid in that context (thanks Valgrind) -- Christophe Devine pointed out that Anubis would fail on various 64-bit UNIX boxes when "x>>24" was used as an index, we needed to mask it with 0xFF. Thanks. Fixed. August 0x1E, 0x07D6 v1.14 -- Renamed the chaining mode macros from XXX to LTC_XXX_MODE. Should help avoid polluting the macro name space. -- clean up of SHA-256 -- Chris Colman pointed out that der_decode_sequence_* allows LTC_ASN1_SETOF to accept SEQUENCEs and vice versa. Decoder [non-flexi decoder that is] is more strict now and requires a match. -- Steffen Jaeckel pointed out a typo in the user manual (re: rsa_exptmod). Fixed. This disproves the notion that nobody reads it. :-) -- Made GCM a bit more portable w.r.t. handling the CTR IV (e.g. & with 255) -- Add LTC_VERBOSE if you really want to see what test is doing :-) -- Added SSE2 support to GCM [use GCM_TABLES_SSE2 to enable], shaves 2 cycles per byte on Opteron processors Shaved 4 cycles on a Prescott (Intel P4) Requires you align your gcm_state on a 16 byte boundary, see gcm_memory() for more info -- Added missing prototype for f8_test_mode() -- two fixes to CCM for corner cases [L+noncelen > 15] and fixing the CTR pad to encrypt the CBC-MAC tag -- Franz Glasner pointed out the ARGTYPE=4 is not actually valid. Fixed. -- Fixed bug in f8_start() if your key < saltkey unspecified behaviour occurs. :-( -- Documented F8 mode. Yeah, because you read the manual. -- Minor updates to the technotes. June 17th, 2006 v1.13 -- Fixed to fortuna_start() to clean up state if an error occurs. Not really useful at this stage (sha256 can't fail) but useful if I ever make fortuna pluggable -- Mike Marin submitted a whole bunch of patches for fixing up the libs on traditional UNIX platforms. Go AIX! Thanks! -- One of bugs found in the multi demo highlights that at least with gcc you need to pass integers with a UL prefix to ensure they're unsigned long -- Updated the FP ECC code to use affine points. It's teh fast. -- Made it so many functions which return CRYPT_BUFFER_OVERFLOW now also indicate the required buffer size, note that not all functions do this (most do though). -- Added F8 chaining mode. It's super neato. May 29th, 2006 v1.12 -- Fixed OID encoder/decoder/length to properly handle the first two parts of an OID, matches 2002 X.690 now. -- [Wesley Shields] Allows both GMP/LTM and TFM to be defined now. -- [Wesley Shields] GMP pluggin is cleaner now and doesn't use deprecated symbols. Yipee -- Added count_lsb_bits to get the number of leading LSB zero bits there are. -- Fixed a bug in the INTEGER encoders for values of -(256**k)/2 -- Added BOOLEAN type to ASN.1 thingy-ma-do-hicky -- Testprof doesn't strictly require GMP ... oops [Nils Durner] -- Added LTC_CALL and LTC_EXPORT macros in tomcrypt_cfg.h to support various calling and linker conventions (Thanks to John Kirk from Demonware) -- In what has to be the best thing since sliced bread I bring you MECC_FP which is the fixed point ECC point multiplier. It's fast, it's sexy and what's more it's hella fast [did I mention it's fast?] You can tune it somewhat with FP_LUT (default to 8) for look-up width. Read section 8.2 of the manual for more info. It is disabled by default, you'll have to build LTC with it defined to get it. -- Fixed bug in ecc_test.c (from testprof) to include the 521 [not 512] bit curve. :-) April 4th, 2006 v1.11 -- Removed printf's from lrw_test ... whoops -- lrw_process now checks the return of the cipher ecb encrypt/decrypt calls -- lrw_start was not using num_rounds ... -- Adam Miller reported a bug in the flexi decoder with elements past the end of a sequence. Fixed. -- Bruce Guenter suggested I use --tag=CC for libtool builds where the compiler may think it's C++. (I applied this to LTM and TFM) -- Optimized the ECC for TFM a bit by removing the useless "if" statements (most TFM functions don't return error codes) Actually shaved a good chunk of time off and made the code smaller. By default with TFM the stock LTC point add/dbl functions will be totally omitted (ECC-256 make key times on a Prescott for old vs. new are 11.03M vs. 9.59M cycles) -- added missing CVS tags to ltc_ecc_mulmod.c -- corrected typo in tomcrypt_cfg.h about what the file has been called -- corrected my address in the user manual. A "bit" out of date. -- added lrw_gen to tv_gen -- added GMP plugin, only tested on a AMD64 and x86_32 Gentoo Linux box so be aware -- made testme.sh runs diff case insensitivityly [whatever...] cuz GMP outputs lowercase satan text -- added LDFLAGS to the makefile to allow cross porting linking options -- added lrw_test() to the header file ... whoops -- changed libtomcrypt.org to libtomcrypt.com .... mumble mumble -- Updates to detect __STRICT_ANSI__ which is defined in --std=c99 modes (note -ansi is not supported as it lacks long long) so you can build LTC out of the box with c99 (note: it'll be slower as there is no asm in this case) -- Updated pelican.c and aes_tab.c to undef tables not-required. The tables are static so both AES and Pelican MAC would have copies. Save a few KB in the final binary. -- Added LTC_NO_FAST to the makefile.icc to compensate for the fact ICC v9 can't handle it (Pelican MAC fails for instance) February 11th, 2006 v1.10 -- Free ecb/cbc/ctr/lrw structures in timing code by calling the "done" function -- fixed bug in lrw_process() which would always use the slow update ... -- vastly sped up gcm_gf_mult() when LTC_FAST is defined. This speeds up LRW and GCM state creation, useful for servers with GCM -- Removed NLS since there are some attacks against it. -- fixed memory leak in rsa_import reported by John Kuhns ++ re-released as the rsa fix was incorrect (bad John bad ... hehehe) and I missed some NULLs in the static descriptor entry for ciphers January 26th, 2006 v1.09 -- Added missing doxygen comments to some of the ASN.1 routines -- Added "easy button" define LTC_EASY and LTC will build with a subset of all the algos. Reduces build times for typical configurations. Tunable [see tomcrypt_custom.h] -- Added some error detection to reg_algs() of the testprof.a library to detect when the PRNG is not setup correctly (took me 10 mins to figure out, PITA!) -- Similar fixes to timing demo (MD5 not defined when EASY is defined) -- Added the NLS enc+mac stream cipher from QUALCOMM, disabled for this release, waiting on test vectors -- Finally added an auto-update script for the makefiles. So when I add new files/dirs it can automatically fix up the makefiles [all four of them...] -- Added LRW to the list of cipher modes supported -- cleaned up ciphers definitions to remove cbc/cfb/ofb/ctr/etc from the namespace when not used. November 24th, 2005 v1.08 -- Added SET and SET OF support to the ASN.1 side -- Fixed up X macros, added QSORT to the mix [thanks SET/SETOF] -- Added XMEMCMP to the list of X macros -- In der_decode_sequence() the SHORT_INTEGER type was not being handled correctly [oddly enough it worked just enough to make RSA work ... go figure!] -- Fixed bug in math descriptors where if you hadn't defined MECC (ECC support) you would get linker errors -- Added RSA accelerators to the math descriptors to make it possible to not include the stock routines if you supply your own. -- dsa_decrypt_key() was erroneously dependent on MECC not MDSA ... whoops -- Moved DSA size limits to tomcrypt_pk.h so they're defined with LTC_NO_PK+MDSA -- cleaned up tomcrypt_custom.h to make customizable PK easier (and also cleaned up the error traps so they're correctly reported) November 18th, 2005 v1.07 -- Craig Schlenter pointed out the "encrypt" demo doesn't call ctr_start() correctly. That's because as of a few releases ago I added support to set the mode of the counter at init time -- Fixed some "testprof" make issues -- Added RSA keygen to the math descriptors -- Fixed install_test target ... oops -- made the "ranlib" program renamable useful for cross-compiling -- Made the cipher accelerators return error codes. :-) -- Made CCM accept a pre-scheduled key to speed it up if you use the same key for multiple packets -- Added "Katja" public key crypto. It's based on the recent N = p^2q work by Katja. I added OAEP padding to it. Note this code has been disabled not because it doesn't work but because it hasn't been thoroughly analyzed. It does carry some advantages over RSA (slightly smaller public key, faster decrypt) but also some annoying "setup" issues like the primes are smaller which makes ECM factoring more plausible. -- Made makefile accept a NODOCS flag to disable the requirement of tetex to install LTC for you no tetex people... all 3 of ya :-) -- Cleaned up rsa_export() since "zero" was handled with a SHORT_INTEGER -- Cleaned up the LIBTEST_S definitions in both GNU makefiles. A few minor touchups as well. -- Made the cipher ecb encrypt/decrypt return an int as well, changed ALL dependent code to check for this. -- der_decode_choice() would fail to mark a NULL as "used" when decoding. Fixed -- ecc_decrypt_key() now uses find_hash_oid() to clean up the code ;-) -- Added mp_neg() to the math descriptors. -- Swapped arguments for the pkcs_1_mgf1() function so the hash_idx is the first param (to be more consistent) -- Made the math descriptors buildable when RSA has been undefined -- ECC timing demo now capable of detecting which curves have been defined -- Refactored the ECC code so it's easier to maintain. (note: the form of this code hasn't really changed since I first added ECC ... :-/) -- Updated the documentation w.r.t. ECC and the accelerators to keep it current -- Fixed bug in ltc_init_multi() which would fail to free all allocated memory on error. -- Fixed bug in ecc_decrypt_key() which could possibly lead to overflows (if MAXBLOCKSIZE > ECC_BUF_SIZE and you have a hash that emits MAXBLOCKSIZE bytes) -- Added encrypt/decrypt to the DSA side (basically DH with DSA parameters) -- Updated makefiles to remove references to the old DH object files and the ecc_sys.o crap ... clean code ahead! -- ecc_import() now checks if the point it reads in lies on the curve (to prevent degenerative points from being used) -- ECC code now ALWAYS uses the accelerator interface. This allows people who use the accelerators to not have the stock ECC point add/dbl/mul code linked in. Yeah space savings! Rah Rah Rah. -- Added LTC_MUTEX_* support to Yarrow and Fortuna allowing you to use respective prng_state as a global PRNG state [e.g. thread-safe] if you define one of the LTC_* defines at build time (e.g. LTC_PTHREAD == pthreads) -- Added PPC32 support to the rotate macros (tested on an IBM PPC 405) and LTC_FAST macros (it aint fast but it's faster than stock) -- Added ltc_mp checks in all *_make_key() and *_import() which will help catch newbs who don't register their bignum first :-) -- the UTCTIME type was missing from der_length_sequence() [oops, oh like you've never done that] -- the main makefile allows you to rename the make command [e.g. MAKE=gmake gmake install] so you can build LTC on platforms where the default make command sucks [e.g. BSD] -- Added DER flexi decoder which allows the decoding of arbitrary DER encoded packets without knowing their structure in advance (thanks to MSVC for finding 3 bugs in it just prior to release! ... don't ask) August 1st, 2005 v1.06 -- Fixed rand_prime() to accept negative inputs as a signal for BBS primes. [Fredrik Olsson] -- Added fourth ARGCHK type which outputs to stderr and continues. Useful if you trap sigsegv. [Valient Gough] -- Removed the DH code from the tree -- Made the ECC code fully public (you can access ecc_mulmod directly now) useful for debuging -- Added ecc test to tv_gen -- Added hmac callback to hash descriptors. -- Fixed two doxy comment errors in the UTCTIME functions -- rsa_import() can now read OpenSSL format DER public keys as well as the PKCS #1 RSAPublicKey format. Note that rsa_export() **ONLY** writes PKCS #1 formats -- Changed MIN/MAX to only define if not already present. -- Kirk J from Demonware ... -- Ported tv_gen to new framework (and yes, I made ecc vectors BEFORE changing the API and YES they match now :-)) -- ported testing scripts to support pluggable math. yipee! -- Wrote a TFM descriptor ... yipee -- Cleaned up LTC_FAST in CBC mode a bit -- Merged in patches from Michael Brown for the sparc/sparc64 targets -- Added find_hash_oid() to search for a hash by its OID -- Cleaned up a few stray CLEAN_STACKs that should have been LTC_CLEAN_STACK -- Added timing resistant ECC, enable by defining LTC_ECC_TIMING_RESISTANT then use ECC API as normal -- Updated the ECC documentation as it was a bit out of date June 27th, 2005 v1.05 -- Added Technote #6 which covers the current PK compliance. -- Fixed buffer overflow in OAEP decoder -- Added CHOICE to the list of ASN.1 types -- Added UTCTIME to the list of ASN.1 types -- Added MUTEX locks around descriptor table functions [but not on the functions that are dependent on them] All functions call *_is_valid() before using a descriptor index which means the respective table must be unlocked before it can be accessed. However, during the operation [e.g. CCM] if the descriptor has been altered the results will be undefined. -- Minor updates to the manual to reflect recent changes -- Added a catch to for an error that should never come up in rsa_exptmod(). Just being thorough. June 15th, 2005 v1.04 -- Fixed off by one [bit] error in dsa_make_key() it was too high by one bit [not a security problem just inconsistent] -- ECC-224 curve was wrong [it was an ok curve just not NIST, so no security flaw just interoperability]. -- Removed point compression since it slows down ECC ops to save a measly couple bytes. This makes the ecc export format incompatible with 1.03 [it shouldn't change in the future] -- Removed ECC-160 from timing and added the other curves June 9th, 2005 v1.03 -- Users may want to note that on a P4/GCC3.4 platform "-fno-regmove" greatly accelerates the ciphers/hashes. -------------------------------------------------------------------------------------------------------------- -- Made it install the testing library in the icc/static makefiles -- Found bug in ccm_memory.c which would fail to compile when LTC_CLEAN_STACK was enabled -- Simon Johnson proposed I do a fully automated test suite. Hence "testme.sh" was born -- Added LTC_NO_TEST which forces test vectors off (regardless of what tomcrypt_custom.h has) -- Added LTC_NO_TABLES which disables large tables (where possible, regardless of what tomcrypt_custom.h has) -- New test script found a bug in twofish.c when TABLES was disabled. Yeah testing! -- Added a LTC_FAST specific test to the testing software. -- Updated test driver to actually halt on errors and just print them out (useful for say... automated testing...) -- Added bounds checking to Pelican MAC -- Added BIT and OCTET STRING to the ASN.1 side of things. -- Pekka Riikonen pointed out that my ctr_start() function should accept the counter mode. -- Cleaned up warnings in testprof -- Removed redundant mu and point mapping in ecc_verify_hash() so it should be a bit faster now -- Pekka pointed out that the AES key structure was using 32 bytes more than it ought to. -- Added quick defines to remove entire classes of algorithms. This makes it easier if you want to build with just one algorithm (say AES or SHA-256). Defines are LTC_NO_CIPHERS, LTC_NO_MODES, LTC_NO_HASHES, LTC_NO_MACS, LTC_NO_PRNGS, LTC_NO_PK, LTC_NO_PKCS -- As part of the move for ECC to X9.62 I've changed the signature algorithm to EC DSA. No API changes. -- Pekka helped me clean up the PKCS #1 v2.1 [OAEP/PSS] code -- Wrote new DER SEQUENCE coder/decoder -- RSA, DSA and ECDSA now use the DER SEQUENCE code (saves a lot of code!) -- DSA output is now a DER SEQUENCE (so not compatible with previous releases). -- Added Technote #5 which shows how to build LTC on an AMD64 to have a variety of algorithms in only ~80KB of code. -- Changed temp variable in LOAD/STORE macros to "ulong32" for 32-bit ops. Makes it safer on Big endian platforms -- Added INSTALL_GROUP and INSTALL_USER which you can specify on the build to override the default USER/GROUP the library is to be installed as -- Removed "testprof" from the default build. -- Added IA5, NULL and Object Identifier to the list of ASN.1 DER supported types -- The "no_oops" target (part of zipup) now scans for non-cvs files. This helps prevent temp/scratch files from appearing in releases ;-) -- Added DERs for missing hashes, but just the OID not the PKCS #1 v1.5 additions. -- Removed PKCS #1 v1.5 from the tree since it's taking up space and you ought to use v2.1 anyways -- Kevin Kenny pointed out a few stray // comments -- INTEGER code properly supports negatives and zero padding [Pekka!] -- Sorted asn1/der/ directory ... less of a mess now ;-) -- Added PRINTABLE STRING type -- Removed ECC-160 as it wasn't a standard curve -- Made ecc_shared_secret() ANSI X9.63 compliant -- Changed "printf" to "fprintf(stderr, " in the testbench... ;-) -- Optimized the GCM table creation. On 1KB packets [with key switching] the new GCM is 12.7x faster than before. -- Changed OID representation for hashes to be just a list of unsigned longs (so you can compare against them nicely after decoding a sequence) -- ECC code now uses Montgomery reduction ... it's even faster [ECC-256 make key down from 37.4M to 4.6M cycles on an Athlon64] -- Added SHORT_INTEGER so users can easily store DER encoded INTEGER types without using the bignum math library -- Fixed OMAC code so that with LTC_FAST it doesn't require that LTC_FAST_TYPE divides 16 [it has to divide the block size instead] -- ECC key export is now a simple [and documented] SEQUENCE, the "encrypt_key" also uses a new SEQUENCE format. -- Thanks goes to the following testers Michael Brown - Solaris 10/uSPARCII Richard Outerbridge - MacOS Martin Carpenter - Solaris 8/uSPARCII [Thanks for cleaning up the scripts] Greg Rose - ... SunOS 5.8/SPARC [... what's with the SPARCS?] Matt Johnston - MacOS X [Thanks for pointing out GCC 4 problems with -Os] April 19th, 2005 v1.02 -- Added LTC_TEST support to gcm_test() -- "pt/ct" can now be NULL in gcm_process() if you are processing zero bytes -- Optimized GCM by removing the "double copy" handling of the plaintext/aad -- Richard Outerbridge pointed out that x86_prof won't build on MACOS and that the manual erroneously refers to "mycrypt" all over the place. Fixed. April 17th, 2005 v1.01 ** Secure Science Corporation has supported this release cycle by sponsoring the development time taken. Their continuing support of this project has helped me maintain a steady pace in order to keep LibTomCrypt up to date, stable and more efficient. ----------------------------------------------------------------------------------------------------- -- Updated base64_decode.c so if there are more than 3 '=' signs it would stop parsing -- Merged in latest mpi that fixed a few bugs here and there -- Updated OAEP encoder/decoder to catch when the hash output is too large Cleaned up PSS code too -- Andy Bontoft fixed a bug in my demos/tests/makefile.msvc ... seems "dsa_test.c" isn't an object afterall. Thanks. -- Made invalid ECC key sizes (configuration) not hard fault the program (it returns an error code now) -- SAFER has been re-enabled after I was pointed to http://www.ciphersbyritter.com/NEWS2/95032301.HTM [Mark Kotiaho] -- Added CCM mode to the encauth list (now has EAX, OCB and CCM, c'est un treo magnifique!) -- Added missing ASN.1 header to the RSA keys ... oops... now the rsa_export/import are FULLY compatible with other libs like OpenSSL (comment: Test vectors would go a long way RSA...) -- Manually merged in fix to the prime_random_ex() LTM function that ensures the 2nd MSB is set properly. Now When you say "I want a 1024/8 byte RSA key" the MSB bit of the modulus is set as expected. Note I generally don't view this as a "huge issue" but it's just one less nit to worry about. [Bryan Klisch] -- A new CVS has been setup on my Athlon64 box... if you want developer access send me an email (and at this point the email would have to be awesome). -- Updated API for ECB and CBC shell code. Now can process N whole blocks in one call (like $DEITY intended) -- Introduced a new "hardware accel" framework that can be used to speed up cipher ECB, CBC and CTR mode calls. Later on dependent code (e.g. OMAC, CCM) will be re-written to use the generic cbc/ctr functions. But now if you [say] call ctr_encrypt() with a cipher descriptor that has hardware CTR it will automatically be used (e.g. no code rewrites) -- Now ships with 20% more love. -- x86_prof now uses ECB shell code (hint: accelerators) and outputs cycles per BLOCK not byte. This will make it a bit easier to compare hardware vs. software cipher implementations. It also emits timings for CBC and CTR modes -- [Peter LaDow] fixed a typo w.r.t. XREALLOC macro (spelling counts kids!) -- Fixed bug with __x86_64__ where ROL64/ROR64 with LTC_NO_ROLC would be the 32-bit versions instead... -- Shipping with preliminary GCM code (disabled). It's buggy (stack overflow hidden somewhere). If anyone can spot it let me know. -- Added Pelican MAC [it's an AES based fast MAC] to the list of supported MACs -- Added LTC_FAST [and you can disable by defining LTC_NO_FAST] so that CBC and CTR mode XOR whole words [e.g. 32 or 64 bits] at a time instead of one byte. On my AMD64 this reduced the overhead for AES-128-CBC from 4.56 cycles/byte to around 1 cycle/byte. This requires that you either allow unaligned read/writes [e.g. x86_32/x86_64] or align all your data. It won't go out of it's way to ensure aligned access. Only enabled for x86_* platforms by default since they allow unaligned read/writes. -- Added LTC_FAST support to PMAC (drops the cycle/byte by about 9 cycles on my AMD64) [note: I later rewrote this prior to release] -- Updated "profiled" target to work with the new directory layout -- Added [demo only] optimized RC5-CTR code to x86_prof demo to show off how to make an accelerator [This has been removed prior to release... It may re-appear later] -- Added CCM acelerator callbacks to the list [now supports ECB, CTR, CBC and now CCM]. -- Added chapter to manual about accelerators (you know you want it) -- Added "bswap" optimizations to x86 LOAD/STORE with big endian. Can be disabled by defining LTC_NO_BSWAP -- LTC_NO_ASM is now the official "disable all non-portable stuff" macro. When defined it will make the code endian-neutral, disable any form of ASM and disable LTC_FAST load/stores. Essentially build the library with this defined if you're having trouble building the library (old GCCs for instance dislike the ROLc macro) -- Added tomcrypt_mac.h and moved MAC/encMAC functions from tomcrypt_hash.h into it -- Added "done" function to ciphers and the five chaining modes [and things like omac/pmac/etc] -- Changed install group to "wheel" from "root". -- Replaced // comments with /**/ so it will build on older UNIX-like platforms -- x86_prof builds and runs with IntelCC fine now -- Added "stest" build to intel CC to test static linked from within the dir (so you don't have to install to test) -- Moved testing/benchmark into testprof directory and build it as part of the build. Now you can link against libtomcrypt_prof.a to get testing info (hint: hardware developers ;-) ) -- Added CCM to tv_gen -- Added demos to MSVC makefile -- Removed -funroll-all-loops from GCC makefile and replaced with -funroll-loops which is a bit more sane (P4 ain't got much cache for the IDATA) -- Fixed GCM prior to release and re-enabled it. It has not been optimized but it does conform when compiled with optimizations. -- I've since optimized GCM and CCM. They're close in speed but GCM is more flexible imho (though EAX is more flexible than both) -- For kicks I optimized the ECC code to use projective points. Gets between 3.21x (Prescott P4) to 4.53x (AMD64) times faster than before at 160-bit keys and the speedup grows as the keysize grows. Basically removing most practical reasons to "not use the ECC code". Enjoy. -- Added LTC_FAST support to OMAC/PMAC and doubled it's speed on my amd64 [faster on the P4 too I guess] -- Added GCM to tv_gen -- Removed "makefile.cygwin_dll" as it's not really used by anyone and not worth the effort (hell I hardly maintain the MSVC makefiles ...) -- Updated a few files in the "misc" directory to have correct @file comments for doxygen -- Removed "profile" target since it was slower anyways (go figure...) December 31st, 2004 v1.00 -- Added "r,s == 0" check to dsa_verify_hash() -- Added "multi block" helpers for hash, hmac, pmac and omac routines so you can process multiple non-adjacent blocks of data with one call (added demos/multi.c to make sure they work) -- Note these are not documented but they do have doxygen comments inside them -- Also I don't use them in other functions (like pkcs_5_2()) because I didn't have the time. Job for the new LTC maintainer ;-) -- Added tweaked Anubis test vectors and made it default (undefined ANUBIS_TWEAK to get original Anubis) -- Merged in fix for mp_prime_random_ex() to deal with MSB and LSB "bugs" -- Removed tim_exptmod() completely, updated several RSA functions (notably v15 and the decrypt/verify) so they don't require a prng now -- This release brought to you by the fine tunes of Macy Gray. We miss you. December 23rd, 2004 v1.00rc1 -- Renamed "mycrypt_*" to "tomcrypt_*" to be more specific and professional Now just include "tomcrypt.h" instead of "mycrypt.h" to get LTC ;-) -- Cleaned up makefiles to ensure all headers are correctly installed -- Added "rotate by constant" macros for portable, x86-32 and x86-64 You can disable this new code with LTC_NO_ROLC which is useful for older GCCs -- Cleaned up detection of x86-64 so it works for ROL/ROR macros -- Fixed rsa_import() so that it would detect multi-prime RSA keys and error appropriately -- Sorted the source files by category and updated the makefiles appropriately -- Added LTC_DER define so you can trim out DER code if not required -- Fixed up RSA's decrypt functions changing "res" to "stat" to be more in sync with the signature variables nomenclature. (no code change just renamed the arguments) -- Removed all labels starting with __ and replaced with LBL_ to avoid namespace conflicts (Randy Howard) -- Merged in LTM fix to mp_prime_random_ex() which zap'ed the most significant byte if the bit size requested was a multiple of eight. -- Made RSA_TIMING off by default as it's not terribly useful [and likely to be deprecated] -- Renamed SMALL_CODE, CLEAN_STACK and NO_FILE to have a LTC_ prefix to avoid namespace collisions with other programs. e.g. SMALL_CODE => LTC_SMALL_CODE -- Zed Shaw pointed out that on certain systems installing libs as "root" isn't possible as the super-user is not root. Now the makefiles allow this to be changed easily. -- Renamed "struct _*_descriptor" to "struct ltc_*_descriptor" to avoid using a leading _ Also renamed _ARGCHK to LTC_ARGCHK -- Zed Shaw pointed out that I still defined the prng structs in tomcrypt_prng.h even if they weren't defined. This made undef'ing FORTUNA break the build. -- Added LTC_NO_ASM to disable inline asm macros [ROL/ROR/etc] -- Changed RSA decrypt functions to change the output length variable name from "keylen" to "outlen" to make it more consistent. -- Added the 64-bit Khazad block cipher [NESSIE] -- Added the 128-bit Anubis block cipher [with key support for 128...320 bit keys] [NESSIE] -- Changes to several MAC functions to rename input arguments to more sensible names -- Removed FAST_PK support from dh_sys.c -- Declared deskey() from des.c as static instead of a global -- Added pretty much all practical GCC warning tests to the GCC [related] makefiles. These additional warnings can easily be disabled for those with older copies of GCC [or even non GNU cc's] -- Added doxygen @ tags to the code... phew that was a hell of a lot of [repetitive] work -- Also added pre-configured Doxygen script. -- Cleaned up quite a few functions [ciphers, pk, etc] to make the parameters naming style consistent E.g. ciphers keys are called "skey" consistently now. The input to PK encryption is called "in", etc. These changes require no code changes on the behalf of developers fortunately -- Started a SAFER+ optimizer [does encrypt only] which shaves a good 30 or so cycles/byte on my AMD64 at an expense of huge code. It's in notes/etc/saferp_optimizer.c -- DSA sign/verify now uses DER encoded output/inputs and no LTC style headers. -- Matt Johnston found a missing semi-colon in mp_exptmod(). Fix has been merged in. October 29th, 2004 v0.99 -- Merged in the latest version of LTM which includes all of the recent bug fixes -- Deprecated LTMSSE and removed it (to be replaced with TFM later on) -- Stefan Arentz pointed out that mp_s_rmap should be extern -- Kristian Gj?steen pointed out that there are typos in the "test" makefile and minor issues in Yarrow and Sober [just cosmetics really] -- Matthew P. Cashdollar pointed out that "export" is a C++ keyword so changed the PRNG api to use "pexport" and "pimport" -- Updated "hashsum" demo so it builds ;-) -- Added automatic support for x86-64 (will configure for 64-bit little endian automagically) -- Zhi Chen pointed out a bug in rsa_exptmod which would leak memory on error. -- Made hash functions "init" return an int. slight change to API ;-( -- Added "CHC" mode which turns any cipher into a hash the other LTC functions can use -- Added CHC mode stuff to demos such as tv_gen and hashsum -- Added "makefile.shared" which builds and installs shared/static object copies of the library. -- Added DER for bignum support -- RSA is now fully joy. rsa_export/rsa_import use PKCS #1 encodings and should be compatible with other crypto libs that use the format. -- Added support for x86-64 for the ROL/ROR macros -- Changed the DLL and SO makefiles to optimize for speed, commented SMALL_CODE in mycrypt_custom.h and added -DSMALL_CODE to the default makefile -- Updated primality testing code so it does a minimum of 5 tests [of Miller-Rabin] (AFAIK not a security fix, just warm fuzzies) -- Minor updates to the OMAC code (additional __ARGCHK and removed printf from omac_test... oops!) -- Update build and configuration info which was really really really out of date. (Chapter 14) ++ Minor update, switch RSA to use the PKCS style CRT August 6th, 2004 v0.98 -- Update to hmac_init to free all allocated memory on error -- Update to PRNG API to fix import/export functions of Fortuna and Yarrow -- Added test functions to PRNG api, RC4 now conforms ;-) [was a minor issue] -- Added the SOBER-128 PRNG based off of code donated by Greg Rose. -- Added Tech Note #4 [notes/tech0004.txt] -- Changed RC4 back [due to request]. It will now XOR the output so you can use it like a stream cipher easily. -- Update Fortuna's export() to emit a hash of each pool. This means that the accumulated entropy that was spread over all the pools isn't entirely lost when you export/import. -- Zhi Chen suggested a comment for rsa_encrypt_key() to let users know [easily] that it was PKCS #1 v2.0 padding. (updated other rsa_* functions) -- Cleaned up Noekeon to remove unrolling [wasn't required, was messy and actually slower with GCC/ICC] -- Updated RC4 so that when you feed it >256 bytes of entropy it quietly ignores additional bytes. Also removed the % from the key setup to speed it up a bit. -- Added cipher/hash/prng tests to x86_prof to help catch bugs while testing -- Made the PRNG "done" return int, fixed sprng_done to not require prng* to be non-null -- Spruced up mycrypt_custom.h to trap more errors and also help prevent LTMSSE from being defined on non-i386 platforms by accident. -- Added RSA/ECC/DH speed tests to x86_prof and cleaned it up to build with zero warnings -- Changed Fortuna to count only entropy [not the 2 byte header] added to pool[0] into the reseed mechanism. -- Added "export_size" member to prng_descriptor tables so you can know in advance the size of the exported state for any given PRNG. -- Ported over patch on LTM 0.30 [not ready to release LTM 0.31] that fixes bug in mp_mul()/mp_div() that used to result in negative zeroes when you multiplied zero by a negative integer. (patch due to "Wolfgang Ehrhardt" ) -- Fixed rsa_*decrypt_key() and rsa_*verify_hash() to default to invalid "stat" or "res". This way if any of the higher level functions fail [before you get to the padding] the result will be in a known state]. Applied to both v2 and v1.5 padding helpers. -- Added MACs to x86_prof -- Fixed up "warnings" in x86_prof and tv_gen -- Added a "profiled" target back [for GCC 3.4 and ICC v8]. Doesn't seem to help but might be worth tinkering with. -- Beefed up load/store test in demos/test ++ New note, in order to use the optimized LOAD/STORE macros your platform must support unaligned 32/64 bit load/stores. The x86s support this but some [ARM for instance] do not. If your platform cannot perform unaligned operations you must use the endian neutral code which is safe for any sort of platform. July 23rd, 2004 v0.97b -- Added PKCS #1 v1.5 RSA encrypt/sign helpers (like rsa_sign_hash, etc...) -- Added missing prng check to rsa_decrypt_key() [not critical as I don't use descriptors directly in that function] -- Merged in LTM-SSE, define LTMSSE before you build and you will get SSE2 optimized math ;-) (roughly 3x faster on a P4 Northwood). By default it will compile as ISO C portable code (when LTMSSE is undefined). -- Fixed bug in ltc_tommath.h where I had the kara/toom cutoffs not marked as ``extern'' Thanks to "Stefan Arentz" -- Steven Dake and Richard Amacker submitted patches to fix pkcs_5_2(). It now matches the output of another crypto library. Whoops... hehehe -- Updated PRNG api. Added Fortuna PRNG to the list of supported PRNGs -- Fixed up the descriptor tables since globals are automatically zero'ed on startup. -- Changed RC4 to store it's output. If you want to encrypt with RC4 you'll have to do the XOR yourself. -- Fixed buffer overflows/overruns in the HMAC code. ++ API change for the PRNGs there now is a done() function per PRNG. You should call it when you are done with a prng state. So far it's not absolutely required (won't cause problems) but is a good idea to start. June 23rd, 2004 v0.97a ++ Fixed several potentially crippling bugs... [read on] -- Fixed bug in OAEP decoder that would incorrectly report buffer overflows. [Zhi Chen] -- Fixed headers which had various C++ missing [extern "C"]'s -- Added "extern" to sha384_desc descriptor which I removed by mistake -- Fixed bugs in ENDIAN_BIG macros using the wrong byte order [Matt Johnston] -- Updated tiger.c and des.c to not shadow "round" which is intrinsic on some C compilers. -- Updated demos/test/rsa_test.c to test the RSA functionality better ++ This update has been tested with GCC [v3.3.3], ICC [v8] and MSVC [v6+SP6] all on a x86 P4 [GCC/ICC tested in Gentoo Linux, MSVC in WinXP] ++ Outcome: The bug Zhi Chen pointed out has been fixed. So have the bugs that Matt Johnston found. June 19th, 2004 v0.97 -- Removed spurious unused files [arrg!] -- Patched buffer overflow in tim_exptmod() -- Fixed buffer overrun bug in pkcs_1_v15_es_decode() -- Reduced stack usage in PKCS #1 v2.0 padding functions (by several KBs) -- Removed useless extern's that were an artifact from the project start... ;-) -- Replaced memcpy/memset with XMEMCPY and XMEMSET for greater flexibility -- fixed bugs in hmac_done()/hmac_init()/[various others()] where I didn't trap errors -- Reduced stack usage in OMAC/PMAC/HMAC/EAX/OCB/PKCS#5 by mallocing any significant sized arrays (e.g. > 100 bytes or so). Only in non-critical functions (e.g. eax_init()) -- "Zhi Chen" pointed out that rsa_decrypt_key() requires an incorrect output size (too large). Fixed. -- Added a "pretty" target to the GCC makefile. Requires PERL. It is NEAT! -- Minor updates to ch1 of the manual. -- Cleaned up the indentation and added comments to rsa_make_key(), rsa_exptmod() and rsa_verify_hash() -- Updated makefile.icc so the "install" target would work ;-) -- Removed demos/test.c [deprecated from demos/test/test.c] -- Changed MAXBLOCKSIZE from 128 to 64 to reflect the true size... May 30th, 2004 v0.96 -- Removed GF and Keyring code -- Extended OAEP decoder to distinguish better [and use a more uniform API] -- Changed PSS/OAEP API slightly to be more consistent with other PK functions (order of arguments) -- rsa_exptmod() now pads with leading zeroes as per I2OSP. -- added error checking to yarrow code -- pointed out that tommath.h from this distro will overwrite tommath.h from libtommath. I changed this to ltc_tommath.h to avoid any such problems. -- Fixed bug in PSS encoder/decoder that didn't handle the MSB properly -- refactored AES, now sports an "encrypt only" descriptor which uses half as much code space. -- modded Yarrow to try and use refactored AES code and added WHIRLPOOL support (d'oh) ;-) -- updated ECB, OCB and CBC decrypt functions to detect when "encrypt only" descriptor is used. -- replaced old RSA code with new code that uses PKCS #1 v2.0 padding -- replaced old test harness with new over-engineer'ed one in /demos/test/ -- updated cbc/cfb/ofb/ctr code with setiv/getiv functions to change/read the IV without re-keying. -- Added PKCS #1 v1.5 RSA encryption and signature padding routines -- Added DER OID's to most hash descriptors (as many as I could find) -- modded rsa_exptmod() to use timing-resilient tim_exptmod() when doing private key operations added #define RSA_TIMING which can turn on/off this feature. -- No more config.pl so please just read mycrypt_custom.h for build-time tweaks -- Small update to rand_prime() -- Updated sha1, md5 and sha256 so they are smaller when SMALL_CODE is defined. If you want speed though, you're going to have to undefine SMALL_CODE ;-) -- Worked over AES so that it's even smaller now [in both modes]. May 12th, 2004 v0.95 -- Optimized AES and WHIRLPOOL for SMALL_CODE by taking advantage of the fact the transforms are circulant. AES dropped 5KB and WHIRLPOOL dropped 13KB using the default build options on the x86. -- Updated eax so the eax_done() would clear the state [like hmac,pmac,ocb] when CLEAN_STACK has been defined. -- added LTC_TEST support to rmd160 -- updates to mycrypt_pk.h -- updated rand_prime() to faciliate making RSA composites -- DSA/RSA now makes composites of the exact size desired. -- Refactored quite a bit of the code, fewer functions per C file -- cleaned up the makefiles to organize the objects logically -- added ICC makefile along with "profiled" targets for both GNU and ICC compilers -- Marked functions for removal before v1.00 see PLAN for more information -- GCC 3.4.0 tested and seems to work -- Added PKCS #5 support -- Fixed typo in comment header of .C files ;-) -- Added PKCS #1 OAEP and PSS support. Feb 20th, 2004 v0.94 -- removed unused variables from ocb.c and fixed it to match known test vectors. -- Added PMAC support, minor changes to OMAC/EAX code [I think....] -- Teamed up with Brian Gladman. His code verifies against my vectors and my code verifies against his test vectors. Hazaa for co-operation! -- Various small changes (added missing ARGCHKs and cleaned up indentation) -- Optimization to base64, removed unused variable "c" -- Added base64 gen to demos/tv_gen.c -- Fix to demos/x86_prof.c to correctly identify the i386 architecture... weird... -- Fixed up all of the PK code by adding missing error checking, removed "res" variables, shrunk some stack variables, removed non-required stack variables and added proper error conversion from MPI to LTC codes. I also spotted a few "off by one" error checking which could have been used to force the code to read past the end of the buffer (in theory, haven't checked if it would work) by a few bytes. -- Added checks to OUTPUT_BIGNUM so the *_export() functions cannot overflow the output and I also modded it so it stores in the output provided to the function (that is not on the local stack) which saves memory and time. -- Made SAFER default to disabled for now (plans are to cleanhouse write an implementation later) -- Added the 512-bit one-way hash WHIRLPOOL which clocks in at 138 cycles per byte on my Athlon XP [for comparison, SHA-512 clocks in at 77 cycles per byte]. This code uses the teams new sbox design (not the original NESSIE one). Jan 25th, 2004 v0.93 -- [note: deleted v0.93 changes by accident... recreating from memory...] -- Fix to RC2 to not deference pointer before ARGCHK -- Fix to NOEKEON to match published test vectors as well as cleaned up the code a bit -- Optimized Twofish [down to 28 cycles/byte on my box] and Blowfish -- Fix to OMAC to test cipher block size first [prevents wasting any time] -- Added more OMAC test vectors -- Added EAX Encrypt+Authenticate support -- Fix to DSA to check return of a few LTM functions I forgot [mp_to_unsigned_bin] -- Added common headers to all C files -- CTR mode supports big and little [default] endian counters now. -- fix to find_cipher_any() so that it can handle a fragmented cipher_descriptor table. -- added find_hash_any() akin to find_cipher_any(). -- Added EAX code to demos/tv_gen.c Hazaa! -- Removed SONY defines and files from codebase. -- Added OCB support [patents be damned] and to demos/tv_gen.c -- Merge all of the INPUT/OUTPUT BIGNUM macros (less toc) into mycrypt_pk.h -- Made appropriate changes to the debug string in crypt.c Dec 24th, 2003 v0.92 -- Updated the config.pl script so the options have more details. -- Updated demos/tv_gen to include RIPEMD hashes -- Updated Twofish so when TWOFISH_ALL_TABLES is defined a pre-computed RS table is included [speedup: slight, about 4k cycles on my Athlon]. -- Re-wrote the twofish large key generation [the four 8x32 key dependent tables]. Now about twice as fast. With both optimizations [e.g. TWOFISH_ALL_TABLES defined] a 128-bit Twofish key can now be scheduled in 26,000 cycles on my Athlon XP [as opposed to 49,000 before] when optimized for size. -- config.pl has been updated so rmd128.o and rmd160.o are objects included in the build [oops] -- Andrew Mann found a bug in rsa_exptmod() which wouldn't indicate if the wrong type of key was specified (e.g. not PK_PRIVATE or PK_PUBLIC) -- Fixed up demos/x86_prof so it sorts the output now :-) -- The project is now powered by radioactive rubber pants. -- Fixed dh_encrypt_key() so if you pass it a hash with a smaller output than the input key it will return CRYPT_INVALID_HASH [to match what ecc_encrypt_key() will do] -- Merge the store/encrypt key part of ecc_encrypt_key() as per dh_encrypt_key() [can you guess what I'm upto?] -- Massive updates to the prime generation code. I use the LTM random prime functions [and provide a nice interface between the LTC PRNG's and the LTM generic prng prototype]. I also use a variable number of tests depending on the input size. This nicely speeds up most prime generation/testing within the library. -- Added SHA-224 to the list of hashes. -- Made HMAC test vectors constant and static [takes ROM space instead of RAM] -- This release was brought to you by the letter P which stands for Patent Infringement. -- Added generic HASH_PROCESS macro to mycrypt_hash.h which simplifies the hash "process" functions I also optimized the compression functions of all but MD2 to not perform input copies when avoidable. -- Removed the division from the Blowfish setup function [dropped 3k cycles on my Athlon] -- Added stack cleaning to rijndael, cast5 so now all ciphers have CLEAN_STACK code. -- Added Skipjack to the list of ciphers [made appropriate changes to demos/test.c, demos/tv_gen.c and demos/x86_prof.c] -- Added mechanical testing to cipher test vector routines. Now it encrypts 1000 times, then decrypts and compares. Any fault (e.g. bug in code, compiler) in the routines is likely to show through. Doesn't stress test the key gen though... -- Matt Johnson found a bug in the blowfish.c apparently I was out of my mind and put twofish defines in there The code now builds with any config. Thanks. -- Added OMAC1 Message Authentication Code support to the library. -- Re-prototyped the hash "process" and "done" to prevent buffer overflows [which don't seem easy to exploit]. Updated HMAC code to use them too. Hazaa! -- Fixed bug in ECC code which wouldn't do an _ARGCHK on stat in ecc_verify_hash(). -- Fixed [temp fix] bug in all PK where the OUTPUT_BIGNUM macros would not trap errors on the to_unsigned_bin conversion [now returns CRYPT_MEM, will fix it up better later] -- Added DSA to the list of supported PK algorithms. -- Fixed up various ciphers to &255 the input key bytes where required [e.g. where used to index a table] to prevent problems on platforms where CHAR_BIT != 8 -- Merged in LibTomMath v0.28 -- Updated demos/x86_prof.c to use Yarrow during the key sched testing [was horribly slow on platforms with blockable /dev/random]. -- Added OMAC/HMAC tests to demos/tv_gen and I now store the output of this in notes/ -- Fixed a bug in config.pl that wouldn't have TWOFISH_TABLES defined by default (too many commas on the line) -- Fixed bug in hmac_done(). Apparently FIPS-198 [HMAC] specifies that the output can be truncated. My code would not support that (does now just like the new OMAC code). -- Removed "hashsize" from hmac_state as it wasn't being used. -- Made demos/test.c stop if OMAC or HMAC tests fail (instead of just printing a failed message and keep going). -- Updated notes/tech0003.txt to take into account the existence of Skipjack [also I fixed a few typos]. -- Slight changes to Noekeon, with SMALL_CODE undefined it uses a fully unrolled version. Dropped +10 cycles/byte on my Athlon (35 cycles per byte or 410.4Mbit/sec at 1795Mhz) -- Added _ARGCHK() calls to is_prime() for the two input pointers. Sept 25th, 2003 v0.91 -- HMAC fix of 0.90 was incorrect for keys larger than the block size of the hash. -- Added error CRYPT_FILE_NOTFOUND for the file [hmac/hash] routines. -- Added RIPEMD hashes to the hashsum demo. -- Added hashsum demo to MSVC makefile. -- Added RMD160 to the x86_prof demo [oops] -- Merged in LibTomMath-0.27 with a patch to mp_shrink() that will be in LibTomMath-0.28 Fixes another potential memory leak. Sept 7th, 2003 v0.90 -- new ROL/ROR for x86 GCC -- Jochen Katz submitted a patch to the makefile to prevent "make" from making the .a library when not required. == By default the KR code is not enabled [it's only a demo anyways!] -- changed the "buf" in ecc_make_key from 4KB to 128 bytes [since the largest key is 65 bytes] -- hmac_done() now requires you pass it the size of the destination buffer to prevent buffer overflows. (API CHANGE) -- hmac/hash filebased routines now return CRYPT_NOP if NO_FILE is defined. -- I've removed the primes from dh.c and replaced them with DR safe primes suitable for the default configuration of LibTomMath. Check out these comparisons on a 1.3Ghz Athlon XP, optimized for size, 768-bit, 4 vs. 10 1024-bit, 8 vs. 18 1280-bit, 12 vs. 34 1536-bit, 20 vs. 56 1792-bit 28 vs. 88 2048-bit, 40 vs. 124 2560-bit, 71 vs. 234 3072-bit, 113 vs. 386 4096-bit, 283 vs. 916 Times are all in milliseconds for key generation. New primes times on the left. This makes the code binary incompatible with previous releases. However, this addition is long overdue as LibTomMath has supported DR reductions for quite some time. -- Added RIPE-MD 128 and 160 to the list of supported hashes [10 in total]. -- The project has been released as public domain. TDCAL no longer applies. July 15th, 2003 v0.89 -- Fix a bug in bits.c which would prevent it from building with msvc -- Merged in LibTomMath v0.24 [and I used the alloc/free macros this time!] -- Removed the LTC version of next_prime() and replaced it with a call to the mp_prime_next_prime() from LibTomMath -- reverted bits.c to the 0.86 copy since the new one doesn't build in MSVC or cygwin. Jul 10th, 2003 v0.88 -- Sped up CAST5 key schedule for MSVC -- added "ulong32" which allows people on 64-bit platforms to force the 32-bit tables in ciphers like blowfish and AES to be 32-bits. E.g. when unsigned long is 64-bits. -- Optimized the SAFER-SK64, SAFER-SK128, SAFER+, RC5 and RC6 key schedule [big time!] -- Optimized SHA-1 and SHA-256 quite a bit too. -- Fixed up the makefile to use -fomit-frame-pointer more liberally -- Added tv_gen program which makes test vectors for ciphers/hashes -- Merged in LibTomMath v0.22 Jun 19th, 2003 v0.87 -- Many MSVC optimizations to the code base -- Improved the AES and Twofish key schedule [faster, more constant time] -- Tons of optimizations here and there. Jun 15th, 2003 v0.86 -- Fixed up AES to workaround MSVC optimizer bug -- Merged in fresh LTM base [based on v0.20] so there are no warnings with MSVC -- Wrote x86_prof which will time the hashes and ciphers downto cycles per byte. -- Fixed up demos/encrypt to remove serpent_desc from the list -- Re-enabled MSVC optimizations w00t w00t -- Replaced "errno" with "err" in all functions that had it so it wouldn't clash with the global "errno" -- Removed a set of unused variables from certain functions -- Removed {#line 0 "..."} stuff from mpi.c to comply with ISO C :-) Jun 11th, 2003 v0.85 -- Swapped in a new AES routine -- Removed Serpent -- Added TDCAL policy document Jun 1st, 2003 v0.84 -- Removed a 4KB buffer from rsa_decrypt_key that wasn't being used no more -- Fixed another potential buffer problem. Not an overflow but could cause the PK import routines to read past the end of the buffer. -- Optimized the ECC mulmod more by removing a if condition that will always be false -- Optimized prime.c to not include a 2nd prime table, removed code from is_prime calls prime test from LibTomMath now -- Added LTC_TEST define which when defined will enable the test vector routines [see mycrypt_custom.h] -- Removed ampi.o from the depends cuz it ain't no not working in *nix with it [routines are in mpi.c now]. Mar 29th, 2003 v0.83 -- Optimized the ecc_mulmod, it's faster and takes less heap/stack space -- Fixed a free memory error in ecc_mulmod and del_point which would try to free NULL -- Fixed two serious bugs in rsa_decrypt_key and rsa_verify_hash that would allow a trivialy buffer overflow. -- Fixed a bug in the hmac testing code if you don't register all the hashes it won't return errors now. Mar 15th, 2003 v0.82 -- Manual updated -- Added MSVC makefile [back, actually its written from scratch to work with NMAKE] -- Change to HMAC helper functions API to avoid buffer overflow [source changes] -- the rsa_encrypt_key was supposed to reject key sizes out of bounds ... same fix to the rsa_sign_hash -- Added code to ensure that that chaining mode code (cfb/ofb/ctr/cbc) have valid structures when being called. E.g. the indexes to the pad/ivs are not out of bounds -- Cleaned up the DES code and simplified the core desfunc routine. -- Simplified one of the boolean functions in MD4 Jan 16th, 2003 v0.81 -- Merged in new makefile from Clay Culver and Mike Frysinger -- Sped up the ECC mulmod() routine by making the word size adapt to the input. Saves a whopping 9 point operations on 521-bit keys now (translates to about 8ms on my Athlon XP). I also now use barrett reduction as much as possible. This sped the routine up quite a bit. -- Fixed a huge flaw in ecc_verify_hash() where it would return CRYPT_OK on error... Now fixed. -- Fixed up config.pl by fixing an invalid query and the file is saved in non-windows [e.g. not CR/LF] format (fix due to Mika Bostr?m) -- Merged in LibTomMath for kicks -- Changed the build process so that by default "mycrypt_custom.h" is included and provided The makefile doesn't include any build options anymore -- Removed the PS2 and VC makefiles. Dec 16th, 2002 v0.80 -- Found a change I made to the MPI that is questionable. Not quite a bug but definately not desired. Had todo with the digit shifting. In v0.79 I simply truncated without zeroing. It didn't cause problems during my testing but I fixed it up none the less. -- Optimized s_mp_mul_dig() from MPI to do a minimal number of passes. -- Fixed in rsa_exptmod() where I was getting the size of the result. Basically it accomplishes the same thing but the fixed code is more readable. -- Fixed slight bug in dh_sign_hash() where the random "k" value was 1 byte shorter than it should have been. I've also made the #define FAST_PK speed up signatures as well. Essentially FAST_PK tells the DH sub-system to limit any private exponent to 256-bits. Note that when FAST_PK is defined does not make the library binary or source incompatible with a copy of the library with it undefined. -- Removed the DSA code. If you want fast diffie-hellman just define FAST_PK :-) -- Updated dh_sign_hash()/dh_verify_hash() to export "unsigned" bignums. Saves two bytes but is not binary compatible with the previous release... sorry! I've performed the same fix to the ecc code as well. -- Fixed up the PK code to remove all use of mp_toraw() and mp_read_raw() [get all the changes out of the way now] -- Fixed a bug in the DH code where it missed trapping a few errors if they occurred. -- Fixed a slight "its-not-a-bug-but-could-be-done-better" bug in the next_prime() function. Essentially it was testing to ensure that in the loop that searches for the next candidate that the step never grows beyond 65000. Should have been testing for MP_DIGIT_MAX -- Spruced up the config.pl script. It now makes a header file "mycrypt_custom.h" which can be included *before* you include mycrypt.h. This allows you to add libtomcrypt to a project without completely changing your make system around. Note that you should use the makefile it writes to at least build the library initially. -- Used splint to check alot of the code out. Tons of minor fixes and explicit casts added. -- Also made all the internal functions of MPI are now static to avoid poluting the namespace -- **Notice**: There are no planned future releases for at least a month from the this release date. Dec 14th, 2002 v0.79 -- Change to PK code [binary and source]. I made it so you have to pass the buffer size to the *_decrypt_key and *_verify_hash functions. This prevents malformed packets from performing buffer overflows. I've also trimmed the packet header size [by 4 bytes]. -- Made the test program halt on the first error it occurs. Also made it trap more errors than before. -- Wrote the first chapter of my new book [DRAFT!], not in this package but check my website! -- Included a perl script "config.pl" that will make "makefile.out" according to the users needs. -- Added shell script to look for latest release -- Merge DH and ECC key defines from mycrypt_cfg.h into the makefiles -- updated the makefile to use BSD friendly archiving invokations -- Changed the DH and ECC code to use base64 static key settings [e.g. the primes]. Dropped the code size by 3KB and is ever-so-slightly faster than before. -- added "mp_shrink" function to shrink the size of bignums. Specially useful for PK code :-) -- Added new exptmod function that calculates a^b mod c with fewer multiplies then before [~20% for crypto sized numbers]. Also added a "low mem" variant that doesn't use more than 20KB [upto 4096 bit nums] of heap todo the calculation. Both are #define'able controlled -- Added XREALLOC macro to provide realloc() functionality. -- Added fix where in rsa_import() if you imported a public key or a non-optimized key it would free the mp_int's not being used. -- Fixed potential bug in the ECC code. Only would occur on platforms where char is not eight bits [which isn't often!] -- Fixed up the ECC point multiplication, its about 15% faster now -- While I was at it [since the lib isn't binary backwards compatible anyways] I've fixed the PK export routines so they export as "unsigned" types saving 1 byte per bignum outputted. Not a lot but heck why not. Nov 28th, 2002 v0.78 -- Made the default ARGCHK macro a function call instead which reduced the code size from 264KB to 239KB. -- Fixed a bug in the XTEA keysize function which called ARGCHK incorrectly. -- Added Noekeon block cipher at 2,800 bytes of object code and 345Mbit/sec it is a welcome addition. -- Made the KR code check if the other PK systems are included [provides error when building otherwise]. -- Made "aes" an alias for Rijndael via a pre-processor macro. Now you can use "aes_ecb_encrypt", etc... :-) Thanks to Jean-Luc Cooke for the "buzzword conformance" suggestion. -- Removed the old PK code entirely (e.g. rsa_sign, dh_encrypt). The *_sign_hash and *_encrypt_key functions are all that is to remain. -- **NOTE** Changed the PK *_import (including the keyring) routine to accept a "inlen" parameter. This fixes a bug where improperly made key packets could result in reading passed the end of the buffer. This means the code is no longer source compatible but still binary compatible. -- Fixed a few other minor bugs in the PK import code while I was at it. Nov 26th, 2002 v0.77 -- Updated the XTEA code to use pre-computed keys. With optimizations for speed it achieves 222Mbit/sec compared to the 121Mbit/sec before. It is 288 bytes bigger than before. -- Cleaned up some of the ciphers and hashes (coding style, cosmetic changes) -- Optimized AES slightly for 256-bit keys [only one if statement now, still two for 192-bit keys] -- Removed most test cases from Blowfish, left three of them there. Makes it smaller and faster to test. -- Changed the primality routines around. I now use 8 rounds of Rabin-Miller, I use 256 primes in the sieve step and the "rand_prime" function uses a modified sieve that avoids alot of un-needed bignum work. -- Fixed a bug in the ECC/DH signatures where the keys "setting" value was not checked for validity. This means that a invalid value could have caused segfaults, etc... -- **NOTE** Changed the way the ECC/DH export/import functions work. They are source but not binary compatible with v0.76. Essentially insteading of exporting the setting index like before I export the key size. Now if you ever re-configure which key settings are supported the lib will still be able to make use of your keys. -- Optimized Blowfish by inlining the round function, unrolling it for four rounds then using a for loop for the rest. It achieves a rate of 425Mbit/sec with the new code compared to 314Mbit/sec before. The new blowfish object file is 7,813 bytes compared to 8,663 before and is 850 bytes smaller. So the code is both smaller and faster! -- Optimized Twofish as well by inlining the round function. Gets ~400Mbit/sec compared to 280Mbit/sec before and the code is only 78 bytes larger than the previous copy. -- Removed SMALL_PRIME_TAB build option. I use the smaller table always. -- Fixed some mistakes concerning prime generation in the manual. -- [Note: sizes/speeds are for GCC 3.2 on an x86 Athlon XP @ 1.53Ghz] Nov 25th, 2002 v0.76 -- Updated makefiles a bit more, use "-Os" instead of "-O2" to optimize for size. Got the lib downto 265KB using GCC 3.2 on my x86 box. -- Updated the SAFER+, Twofish and Rijndael test vector routine to use the table driven design. -- Updated all other test vector routines to return as soon as an error is found -- fixed a bug in the test program where errors in the hash test routines would not be reported correctly. I found this by temporarily changing one of the bytes of the test vectors. All the hashes check out [the demos/test.c would still have reported an error, just the wrong one]. Nov 24th, 2002 v0.75 -- Fixed a flaw in hash_filehandle, it should ARGCHK that the filehandle is not NULL -- Fixed a bug where in hash_file if the call to hash_filehandle failed the open file would not be closed. -- Added more strict rules to build process, starting to weed out "oh this works in GCC" style code In the next release "-Wconversion" will be enabled which will deal with all implicit casts. Nov 22nd, 2002 [later in the day] v0.74 -- Wrote a small variant of SAFER+ which shaved 50KB off the size of the library on x86 platforms -- Wrote a build option to remove the PK packet functions [keeps the encrypt_key/sign_hash functions] -- Wrote a small variant of Rijndael (trimmed 13KB) -- Trimmed the TIGER/192 hash function a bit -- Overall the entire lib compiled is 295KB [down from 400KB before] -- Fixed a few minor oversights in the MSVC makefile Nov 22nd, 2002 v0.73 -- Fixed bug in RC4 code where it could only use 255 byte keys. -- Fixed bug in yarrow code where it would allow cast5 or md2 to be used with it... -- Removed the ecc compress/expand points from the global scope. Reduces namespace polution -- Fixed bug where if you used the SPRNG you couldn't pass NULL as your prng_state which you should be able todo since the SPRNG has no state... -- Corrected some oversights in the manual and the examples... -- By default the GF(2^W) math library is excluded from the build. The source is maintained because I wrote it and like it :-). This way the built library is a tad smaller -- the MSVC makefile will now build for a SPACE optimized library rather than TIME optimized. Nov 21th, 2002 v0.72 -- Fixed bug in the prime testing. In the Miller-Rabin test I was raising the base to "N-1" not "r". The math still worked out fine because in effect it was performing a Fermat test. Tested the new code and it works properly -- Fixed some of the code where it was still using the old error syntax -- Sped up the RSA decrypt/sign routines -- Optimized the ecc_shared_secret routine to not use so much stack -- Fixed up the makefile to make releases where the version # is in the file name and directory it will unzip to Nov 19th, 2002 v0.71 -- HELP TOM. I need tuition for the January semester. Now I don't want to force donations [nor will I ever] but I really need the help! See my website http://tom.iahu.ca/help_tom.html for more details. Please help if you can! -------------------------------------------------------------------------------------------------------------- -- Officially the library is no longer supported in GCC 3.2 in windows [cygwin]. In windows you can either use GCC 2.95.3 or try your luck with 3.2 It seems that "-fomit-frame-pointer" is broken in the windows build [but not the linux x86 build???] If you simply must use 3.2 then I suggest you limit the optimizations to simply "-O2" -- Started new error handling API. Similar to the previous except there are more error codes than just CRYPT_ERROR -- Added my implementation of the MD2 hash function [despite the errors in the RFC I managed to get it right!] -- Merged in more changes from Sky Schulz. I have to make mention here that he has been a tremendous help in getting me motivated to make some much needed updates to the library! -- Fixed one of the many mistakes in the manual as pointed out by Daniel Richards -- Fixed a bug in the RC4 code [wasn't setting up the key correctly] -- Added my implementation of the CAST5 [aka CAST-128] block cipher (conforms...) -- Fixed numerous bugs in the PK code. Essentially I was "freeing" keys when the import failed. This is neither required nor a good a idea [double free]. -- Tom needs a job. -- Fixed up the test harness as requested by Sky Schulz. Also modifed the timing routines to run for X seconds and count # of ops performed. This is more suitable than say encrypting 10 million blocks on a slow processor where it could take minutes! -- Modified test programs hashsum/encrypt to use the new algorithms and error handling syntax -- Removed the PKCS code since it was incomplete. In the future I plan on writing a "add-on" library that provides PKCS support... -- updated the config system so the #defines are in the makefiles instead of mycrypt_cfg.h -- Willing to work on an hourly basis for 15$ CDN per hour. -- updated the test program to not test ciphers not included -- updated the makefile to make "rsa_sys.c" a dependency of rsa.o [helps develop the code...] -- fixed numerous failures to detect buffer overflows [minor] in the PK code. -- fixed the safer [64-bit block version] test routines which didn't check the returns of the setup function -- check out my CV at http://tom.iahu.ca/cv.html -- removed the GBA makefile and code from demos/test.c [not a particularly useful demo...] -- merged in rudimentary [for testing] PS2 RNG from Sky Schulz -- merged in PS2 timer code [only shell included due to NDA reasons...] -- updated HMAC code to return errors where possible -- Thanks go to Sky Schulz who bought me a RegCode for TextPad [the official editor of libtomcrypt] Nov 12th, 2002 v0.70 -- Updated so you can swap out the default malloc/calloc/free routines at build time with others. (Sky Schulz) -- Sky Schulz contributed some code towards autodetecting the PS2 in mycrypt_cfg.h -- Added PS2 makefile contributed by Sky Schulz [see a pattern forming?] -- Added ability to have no FILE I/O functions at all (see makefile), Sky Schulz.... -- Added support for substituting out the clock() function (Sky Schulz) -- Fixed up makefile to include new headers in the HEADERS variable -- Removed "coin.c" as its not really useful anyways -- Removed many "debug" printfs that would show up on failures. Basically I wanted to ensure the only output would be from the developer themselves. -- Added "rc4.c" a RC4 implementation with a PRNG interface. Since RC4 isn't a block cipher it wouldn't work too well as a block cipher. -- Fixed ARGCHK macro usage when ARGTYPE=1 throughout the code -- updated makefile to make subdirectory properly (Sku Schulz) -- Started towards new API setup. Instead of checking for "== CRYPT_ERROR" you should check "!= CRYPT_OK" In future releases functions will return things other than CRYPT_ERROR on error to give more useful thread safe error reporting. The manual will be updated to reflect this. For this release all errors are returned as CRYPT_ERROR (except as noted) but in future releases this will change. -- Removed the zlib branch since its not really required anyways. Makes the package smaller Nov 11th, 2002 v0.69 -- Added ARGCHK (see mycrypt_argchk.h) "arguement checking" to all functions that accept pointers -- Note I forgot to change the CRYPT version tag in v0.68... fixed now. Nov 8th, 2002 v0.68 -- Fixed flaw in kr_import/kr_export that wasted 4 bytes. Source but not binary compatible with v0.67 -- Fixed bug in kr_find_name that used memcmp to match strings. Uses strncmp now. -- kr_clear now sets the pointer to NULL to facilate debugging [e.g. using the keyring after clearing] -- static functions in _write/_read in keyring.c now check the return of ctr_encrypt/ctr_decrypt. -- Updated blowfish/rc2/rc5/rc6 keysize() function to not reject keys larger than the biggest key the respective ciphers can use. -- Fixed a bug in hashsum demo that would report the hash for files that don't exist! Oct 16th, 2002 v0.67 -- Moved the function prototypes into files mycrypt_*.h. To "install" the lib just copy all the header files "*.h" from the base of this project into your global include path. -- Made the OFB/CFB/CTR functions use "unsigned long" for the length instead of "int" -- Added keyring support for the PK functions -- ***API CHANGE*** changed the ecc_make_key and dh_make_key to act more like rsa_make_key. Basically move the first argument to the next to last. -- Fixed bug in dh_test() that wouldn't test the primality of the order of the sub-group -- replaced the primes in the DH code with new ones that are larger than the size they are associated with. That is a 1024-bit DH key will have a 1025-bit prime as the modulus -- cleaned up all the PK code, changed a bit of the API around [not source compatible with v0.66] -- major editing of the manual, started Docer program -- added 160 and 224 bit key settings for ECC. This makes the DH and ECC binary wise incompatible with v0.66 -- Added an additional check for memory errors in is_prime() and cleaned up prime.c a bit -- Removed ID_TAG from all files [meh, not a big fan...] -- Removed unused variable from yarrow state and made AES/SHA256 the default cipher/hash combo -- Fixed a bug in the Yarrow code that called prng_is_valid instead of cipher_is_valid from yarrow_start() -- The ECB/CBC/OFB/CFB/CTR wrappers now check that the cipher is valid in the encrypt/decrypt calls Returns int now instead of void. Sept 24th, 2002 v0.66 -- Updated the /demos/test.c program to time the hashes correctly. Also it uses the yarrow PRNG for all of the tests meaning its possible to run on RNG less platforms -- Updated the /demos/hashsum.c program to hash from the standard input -- Updated the RSA code to make keys a bit quicker [update by Wayne Scott] by not making both primes at the same time. -- Dan Kaminsky suggested some cleanups for the code and the MPI config Code ships in unix LF format by default now too... will still build in MSVC and all... but if you want to read the stuff you'll have to convert it -- Changes to the manual to reflect new API [e.g. hash_memory/file have v0.65 prototypes]and some typos fixed Sept 20th, 2002 v0.65 -- Wayne Scott (wscott@bitmover.com) made a few of suggestions to improve the library. Most importantly he pointed out the math lib is not really required. He's also tested the lib on 18 different platforms. According to him with only a few troubles [lack of /dev/random, etc] the library worked as it was supposed to. You can find the list at http://www.bitkeeper.com/Products.BitKeeper.Platforms.html -- Updated the hash_file and hash_memory functions to keep track of the size of the output -- Wayne Scott updated the demos/test.c file to use the SPRNG less and Yarrow more -- Modified the mycrypt_cfg.h to autodetect x86-32 machines Sept 19th, 2002 v0.64 -- wrote makefile for the GBA device [and hacked the demos/test.c file to support it conditionally] -- Fixed error in PK (e.g. ECC, RSA, DH) import functions where I was clobbering the packet error messages -- fixed more typos in the manual -- removed all unused variables from the core library (ignore the ID_TAG stuff) -- added "const char *crypt_build_settings" string which is a build time constant that gives a listing of all the build time options. Useful for debugging since you can send that to me and I will know what exactly you had set for the mycrypt_cfg.h file. -- Added control over endianess. Out of the box it defaults to endianess neutral but you can trivially configure the library for your platform. Using this I boosted RC5 from 660Mbit/sec to 785Mbit/sec on my Athlon box. See "mycrypt_cfg.h" for more information. Sept 11th, 2002 v0.63 -- Made hashsum demo output like the original md5sum program -- Made additions to the examples in the manual (fixed them up a bunch) -- Merged in the base64 code from Wayne Scott (wscott@bitmover.com) Aug 29th, 2002 v0.62 -- Added the CLEAN_STACK functionality to several of the hashes I forgot to update. Aug 9th, 2002 v0.61 -- Fixed a bug in the DES code [oops I read something wrong]. Aug 8th, 2002 v0.60 -- Merged in DES code [and wrote 3DES-EDE code based on it] from Dobes V. Aug 7th, 2002 v0.59 -- Fixed a "unsigned long long" bug that caused v0.58 not to build in MSVC. -- Cleaned up a little in the makefile -- added code that times the hash functions too in the test program Aug 3rd, 2002 v0.58 -- Added more stack cleaning conditionals throughout the code. -- corrected some CLEAR_STACK conditionals... should have been CLEAN_STACK -- Simplified the RSA, DH and ECC encrypt() routines where they use CTR to encode the message now they only make one call to ctr_encrypt()/ctr_decrypt(). Aug 2nd, 2002 v0.57 -- Fixed a few errors messages in the SAFER code to actually report the correct cipher name. -- rsa_encrypt() uses the "keysize()" method of the cipher being used to more accurately pick a key size. By default rsa_encrypt() will choose to use a 256-bit key but the cipher can turn that down if required. -- The rsa_exptmod() function will now more reliably detect invalid inputs (e.g. greater than the modulus). -- The padding method for RSA is more clearly documented. Namely if you want to encrypt/sign something of length N then your modulus must be of length 1+3N. So to sign a message with say SHA-384 [48 bytes] you need a 145 byte (1160 bits) modulus. This is all in the manual now. -- Added build option CLEAN_STACK which will allow you to choose whether you want to clean the stack or not after every cipher/hash call -- Sped up the hash "process()" functions by not copying one byte at a time. ++ (added just after I uploaded...) MD4 process() now handles input buffers > 64 bytes Aug 1st, 2002 v0.56 -- Cleaned up the comments in the Blowfish code. -- Oh yeah, in v0.55 I made all of the descriptor elements constant. I just forgot to mention it. -- fixed a couple of places where descriptor indexes were tested wrong. Not a huge bug but now its harder to mess up. -- Added the SAFER [64-bit block] ciphers K64, SK64, K128 and SK128 to the library. -- Added the RC2 block cipher to the library. -- Changed the SAFER define for the SAFER+ cipher to SAFERP so that the new SAFER [64-bit] ciphers can use them with less confusion. July 29th, 2002 v0.55 -- My god stupid Blowfish has yet again been fixed. I swear I hate that cipher. Next bug in it and boom its out of the library. Use AES or something else cuz I really hate Blowfish at this stage.... -- Partial PKCS support [hint DONT USE IT YET CUZ ITS UNTESTED!] July 19th, 2002 v0.54 -- Blowfish now conforms to known test vectors. Silly bad coding tom! -- RC5/RC6/Serpent all have more test vectors now [and they seemed to have been working before] July 18th, 2002 v0.53 -- Added more test vectors to the blowfish code just for kicks [and they are const now too :-)] -- added prng/hash/cipher is_valid functions and used them in all of the PK code so you can't enter the code with an invalid index ever now. -- Simplified the Yarrow code once again :-) July 12th, 2002 v0.52 -- Fixed a bug in MD4 where the hash descriptor ID was the same as SHA-512. Now MD4 will work with all the routines... -- Fixed the comments in SHA-512 to be a bit more meaningful -- In md4 I made the PADDING array const [again to store it in ROM] -- in hash_file I switched the constant "512" to "sizeof(buf)" to be a bit safer -- in SHA-1's test routine I fixed the string literal to say SHA-1 not sha1 -- Fixed a logical error in the CTR code which would make it skip the first IV value. This means the CTR code from v0.52 will be incompatible [binary wise] with previous releases but it makes more sense this way. -- Added {} braces for as many if/for/blocks of code I could find. My rule is that every for/if/while/do block must have {} braces around it. -- made the rounds table in saferp_setup const [again for the ROM think about the ROM!] -- fixed RC5 since it no longer requires rc5 to be registered in the lib. It used to since the descriptors used to be part of the table... -- the packet.c code now makes crypt_error literal string errors when an error occurs -- cleaned up the SAFER+ key schedule to be a bit easier to read. -- fixed a huge bug in Twofish with the TWOFISH_SMALL define. Because I clean the stack now I had changed the "g_func()" to be called indirectly. I forgot to actually return the return of the Twofish g_func() function which caused it not to work... [does now :-)] July 11th, 2002 v0.51 -- Fixed a bug in SHA512/384 code for multi-block messages. -- Added more test vectors to the SHA384/512 and TIGER hash functions -- cleaned up the hash done routines to make more sense July 10th, 2002 v0.50 -- Fixed yarrow.c so that the cipher/hash used would be registered. Also fixed a bug where the SAFER+ name was "safer" but should have been "safer+". -- Added an element to the hash descriptors that gives the size of a block [sent into the compressor] -- Cleaned up the support for HMAC's -- Cleaned up the test vector routines to make the test vector data const. This means on some platforms it will be placed in ROM not RAM now. -- Added MD4 code submited by Dobes Vandermeer (dobes@smartt.com) -- Added "burn_stack" function [idea taken from another source of crypto code]. The idea is if a function has alot of variables it will clean up better. Functions like the ecb serpent and twofish code will now have their stacks cleaned and the rest of the code is getting much more straightforward. -- Added a hashing demo by Daniel Richards (kyhwana@world-net.co.nz) -- I (Tom) modified some of the test vector routines to use more vectors ala Dobes style. For example, the MD5/SHA1 code now uses all of the test vectors from the RFC/FIPS spec. -- Fixed the register/unregister functions to properly report errors in crypt_error -- Correctly updated yarrow code to remove a few unused variables. -- Updated manual to fix a few erroneous examples. -- Added section on Hash based Message Authentication Codes (HMAC) to the manual June 19th, 2002 v0.46 -- Added in HMAC code from Dobes Vandermeer (dobes@smartt.com) June 8th, 2002 v0.45 -- Fixed bug in rc5.c where if you called rc5_setup() before registering RC5 it would cause undefined behaviour. -- Fixed mycrypt_cfg.h to eliminate the 224 bit ECC key. -- made the "default" makefile target have depends on mycrypt.h and mycrypt_cfg.h Apr 4th, 2002 v0.44 -- Fixed bug in ecc.c::new_point() where if the initial malloc fails it would not catch it. Mar 22nd, 2002 v0.43 -- Changed the ZLIB code over to the 1.1.4 code base to avoid the "double free" bug. -- Updated the GCC makefile not to use -O3 or -funroll-loops -- Version tag in mycrypt.h has been updated :-) Mar 10th, 2002 v0.42 -- The RNG code can now use /dev/urandom before trying /dev/random (J. Klapste) Mar 3rd, 2002 v0.41 -- Added support to link and use ciphers at compile time. This can greatly reduce the code size! -- Added a demo to show off how small an application can get... 46kb! -- Disastry pointed out that Blowfish is supposed to be high endian. -- Made registry code for the PRNGs as well [now the smallest useable link is 43kb] Feb 11th, 2002 v0.40 -- RSA signatures use [and check for] fixed padding scheme. -- I'm developing in Linux now :-) -- No more warnings from GCC 2.96 Feb 5th, 2002 v0.39 -- Updated the XTEA code to work in accordance with the XTEA design January 24th, 2002 v0.38 -- CFB and OFB modes can now handle blocks of variable size like the CTR code -- Wrote a wrapper around the memory compress functions in Zlib that act like the functions in the rest of my crypto lib January 23rd, 2002 v0.37 -- Added support code so that if a hash size and key size for a cipher don't match up they will use the next lower key supported. (mainly for the PK code). So you can now use SHA-1 with Twofish, etc... -- Added more options for Twofish. You can now tell it to use precomputed sboxes and MDS multiplications This will speed up the TWOFISH_SMALL implementation by increasing the code size by 1024 bytes. -- Fixed a bug in prime.c that would not use the correct table if you undefined SMALL_PRIME_TAB -- Fixed all of the PK packet code to use the same header format [see packet.c]. This makes the PK code binary wise incompatible with previous releases while the API has not changed at all. January 22nd, 2002 v0.36 -- Corrections to the manual -- Made a modification to Twofish which lets you build a "small ram" variant. It requires about 190 bytes of ram for the key storage compared to the 4,200 bytes the normal variant requires. -- Reduced the stack space used in all of the PK routines. January 19th, 2002 v0.35 -- If you removed the first hash or cipher from the library it wouldn't return an error if you used an ID=0 [i.e blowfish or sha256] in any routine. Now it checks for that and will return an error like it should -- Merged in new routines from Clay Culver. These routines are for the PK code so you can easily encode a symmetric key for multiple recipients. -- Made the ecc and DH make_key() routines make secret keys of the same size as the keysize listed. Originally I wanted to ensure that the keys were smaller than the order of the field used However, the bias is so insignifcant using full sizes. For example, with a ECC-192 key the order is about 2^191.99, so instead I rounded down and used a 184-bit secret key. Now I simply use a full 192-bit key the code will work just the same except that some 192-bit keys will be duplicates which is not a big deal since 1/2^192 is a very small bias! -- Made the configuration a bit simpler and more exacting. You can for example now select which DH or ECC key settings you wish to support without including the data for all other key settings. I put the #defines in a new file called "mycrypt_cfg.h" -- Configured "mpi-config.h" so its a bit more conservative with the memory required and code space used -- Jason Klapste submitted bug fixes to the yarrow, hash and various other issues. The yarrow code will now use what ever remaining hash/cipher combo is left [after you #undef them] at build time. He also suggested a fix to remove unused structures from the symmetric_key and hash_state unions. -- Made the CTR code handle variable length blocks better. It will buffer the encryption pad so you can encrypt messages any size block at a time. -- Simplified the yarrow code to take advantage of the new CTR code. -- Added a 4096-bit DH key setting. That took me about 36 hours to find! -- Changed the base64 routines to use a real base64 encoding scheme. -- Added in DH and ECC "encrypt_key()" functions. They are still rather "beta"ish. -- Added **Twofish** to the list of ciphers! January 18th, 2002 v0.34 -- Added "sha512" to the list of hashes. Produces a 512-bit message digest. Note that with the current padding with the rsa_sign() function you cannot use sha512 with a key less than 1536 bits for signatures. -- Cleaned up the other hash functions to use the LOAD and STORE macros... January 17th, 2002 v0.33 -- Made the lower limit on keysizes for RSA 1024 bits again because I realized that 768 bit keys wouldn't work with the padding scheme and large symmetric keys. -- Added information concerning the Zlib license to the manual -- Added a 3072-bit key setting for the DH code. -- Made the "find_xyz()" routines take "const char *" as per Clay Culver's suggestion. -- Fixed an embarassing typo in the manual concerning the hashes. Thank's Clay for finding it! -- Fixed rand_prime() so that it makes primes bigger than the setting you give. For example, if you want a 1024-bit prime it would make a 1023-bit one. Now it ensures that the prime it makes is always greater than 2^(8n) (n == bytes in prime). This doesn't have a huge impact on security but I corrected it just the same. -- Fixed the CTR routine to work on platforms where char != 8-bits -- Fixed sha1/sha256/md5/blowfish to not assume "unsigned long == 32-bits", Basically any operation with carries I "AND" with 0xFFFFFFFF. That forces only the lower 32-bits to have information in it. On x86 platforms most compilers optimize out the AND operation since its a nop. January 16th, 2002 v0.32 -- Made Rijndael's setup function fully static so it is thread safe -- Svante Seleborg suggested a cosmetic style fixup for aes.c, basically to remove some of the #defines to clean it up -- Made the PK routines not export the ASCII version of the names of ciphers/hashes which makes the PK message formats *incompatible* with previous releases. -- Merge in Zlib :-) January 15th, 2002 v0.31 -- The RSA routines can now use CRT to speed up decryption/signatures. The routines are backwards compatible with previous releases. -- Fixed another bug that Svante Seleborg found. Basically you could buffer-overrun the rsa_exptmod() function itself if you're not careful. That's fixed now. Fixed another bug in rsa_exptmod() where if it knows the buffer you passed is too small it wouldn't free all used memory. -- improved the readability of the PK import/export functions -- Added a fix to RSA.C by Clay Culver -- Changed the CONST64 macro for MSVC to use the "unsigned __int64" type, e.g. "ui64" instead of "i64". January 14th, 2002 v0.30 -- Major change to the Yarrow PRNG code, fixed a bug that Eugene Starokoltsev found. Basically if you added entropy to the pool in small increments it could in fact cancel out. Now I hash the pool with the new data which is way smarter. January 12th, 2002 v0.29 -- Added MPI code written by Svante Seleborg to the library. This will make the PK code much easier to follow and debug. Actually I've already fixed a memory leak in dh_shared_secret(). -- Memory leaks found and correct in all three PK routines. The leaks would occur when a bignum operation fails so it wouldn't normally turn up in the course of a program -- Fixed bugs in dh_key_size and ecc_key_size which would return garbage for invalid key idx'es January 11th, 2002 v0.28 -- Cleaned up some code so that it doesn't assume "char == 8bits". Mainly SAFER+ has been changed. -- ***HUGE*** changes in the PK code. I check all return values in the bignum code so if there are errors [insufficient memory, etc..] it will be reported. This makes the code fairly more robust and likely to catch any errors. -- Updated the is_prime() function to use a new prototype [it can return errors now] and it also does trial divisions against more primes before the Rabin Miller steps -- Added OFB, CFB and ECB generic wrappers for the symmetric ciphers to round out the implementations. -- Added Xtea to the list of ciphers, to the best of my ability I have verified this implementation. I should note that there is not alot of concrete information about the cipher. "Ansi C" versions I found did not address endianess and were not even portable!. This code is portable and to the best of my knowledge implements the Xtea algorithm as per the [short] X-Tea paper. -- Reformated the manual to include the **FULL** source code optimized to be pritable. January 9th, 2002 v0.27 -- Changed the char constants to numerical values. It is backwards compatible and should work on platforms where 'd' != 100 [for example]. -- Made a change to rand_prime() which takes the input length as a signed type so you can pass a negative len to get a "3 mod 4" style prime... oops -- changed the MSVC makefile to build with a warning level of three, no warnings! January 8th, 2002 v0.26 -- updated SHA-256 to use ROR() for a rotate so 64-bit machines won't corrupt the output -- Changed #include <> to #include "" for local .h files as per Richard Heathfields' suggestions. -- Fixed bug in MPI [well bug in MSVC] that compiled code incorrectly in mp_set_int() I added a work around that catches the error and continues normally. January 8th, 2002 v0.25 -- Added a stupid define so MSVC 6.00 can build the library. -- Big thanks to sci.crypt and "Ajay K. Agrawal" for helping me port this to MSVC January 7th, 2002 v0.24 -- Sped up Blowfish by unrolling and removing the swaps. -- Made the code comply with more traditional ANSI C standards Should compile with MSVC with less errors -- moved the demos and documentation into their own directories so you can easily build the library with other tool chains by compiling the files in the root -- converted functions with length of outputs to use "unsigned long" so 16-bit platforms will like this library more. January 5th, 2002 v0.23 -- Fixed a small error in the MPI config it should build fine anywhere. January 4th, 2002 v0.22 -- faster gf_mul() code -- gf_shl() and gf_shr() are safe on 64-bit platforms now -- Fixed an error in the hashes that Brian Gladman found. Basically if the message has exactly 56 bytes left to be compressed I handled them incorrectly. January 4th, 2002 v0.21 -- sped up the ECC code by removing redundant divisions in the point add and double routines. I also extract the bits more efficiently in "ecc_mulmod()" now. -- sped up [and documented] the rand_prime() function. Now it just makes a random integer and increments by two until a prime is found This is faster since it doesn't require alot of calls to the PRNG and it doesn't require loading huge integers over and over. rand_prime() can also make primes congruent to 3 mod 4 [i.e for a blum integer] -- added a gf_sqrt() function that finds square roots in a GF(2^w) field -- fixed a bug in gf_div() that would return the wrong results if the divisor had a greator divisor than the dividend. January 4th, 2002 v0.20 -- Added the fixed MPI back in so RSA and DH are much faster again v0.19 -- Updated the manual to reflect the fact that Brian Gladman wrote the AES and Serpent code. -- DH, ECC and RSA signature/decryption functions check if the key is private -- new DH signature/verification code works just like the RSA/ECC versions January 3rd, 2002 v0.18 -- Added way more comments to each .C file -- fixed a bug in cbc_decrypt(pt, ct, key) where pt == ct [i.e same buffer] -- fixed RC5 so it reads the default rounds out of the cipher_descriptor table -- cleaned up ecc_export() -- Cleaned up dh_import() and ecc_import() which also perform more error checking now -- Fixed a serious flaw in rsa_import() with private keys. January 2nd, 2002 v0.17 -- Fixed a bug in the random prime generator that fixes the wrong bits to one -- ECC and DH code verify that the moduli and orders are in fact prime. That slows down the test routines alot but what are you gonna do? -- Fixed a huge bug in the mp_exptmod() function which incorrectly calculates g^x mod p for some values of p. I replaced it with a slow function. Once the author of MPI fixes his faster routine I will switch back. January 1st, 2002 [whoa new year!] v0.16 -- Improved GF division code that is faster. -- documented the GF code December 31st, 2001 v0.15 -- A 1792-bit and 2048-bit DH setting was added. Took me all night to find a 1792 and 2048-bit strong prime but what the heck -- Library now has polynomial-basis GF(2^w) routines I wrote myself. Can be used to perform ECC over GF(2^w) later on.... -- Fixed a bug with the defines that allows it to build in windows December 30th, 2001 v0.14 -- Fixed the xxx_encrypt() packet routines to make an IV of appropriate size for the cipher used. It was defaulting to making a 256-bit IV... -- base64_encode() now appends a NULL byte, um "duh" stupid mistake now fixed... -- spell checked the manual again... :-) December 30th, 2001 v0.13 -- Switching back to older copy of MPI since it works! arrg.. -- Added sign/verify functions for ECC -- all signature verification routines default to invalid signatures. -- Changed all calls to memset to zeromem. Fixed up some buffer problems in other routines. All calls to zeromem let the compiler determine the size of the data to wipe. December 29th, 2001 v0.12 -- Imported a new version of MPI [the bignum library] that should be a bit more stable [if you want to write your own bignum routines with the library that is...] -- Manual has way more info -- hash_file() clears stack now [like it should] -- The artificial cap on the hash input size of 2^32 bits has been removed. Basically I was too lazy todo 64-bit math before [don't ask why... I can't remember]. Anyways the hashes support the size of 2^64 bits [if you ever use that many bits in a message that's just wierd...] -- The hashes now wipe the "hash_state" after the digest is computed. This helps prevent the internal state of the hash being leaked accidently [i.e stack problems] December 29th, 2001 v0.11 -- Made #define's so you can trim the library down by removing ciphers, hashs, modes of operation, prngs, and even PK algorithms For example, the library with rijndael+ctr+sha1+ECC is 91KB compared to the 246kb the full library takes. -- Added ECC packet routines for encrypt/decrypt/sign/verify much akin to the RSA packet routines. -- ECC now compresses the public key, a ECC-192 public key takes 33 bytes for example.... December 28th, 2001 v0.10 -- going to restart the manual from scratch to make it more clear and professional -- Added ECC over Z/pZ. Basically provides as much as DH except its faster since the numbers are smaller. For example, A comparable 256-bit ECC key provides as much security as expected from a DH key over 1024-bits. -- Cleaned up the DH code to not export the symbol "sets[]" -- Fixed a bug in the DH code that would not make the correct size random string if you made the key short. For instance if you wanted a 512-bit DH key it would make a 768-bit one but only make up 512-bits for the exponent... now it makes the full 768 bits [or whatever the case is] -- Fixed another ***SERIOUS*** bug in the DH code that would default to 768-bit keys by mistake. December 25th, 2001 v0.09 -- Includes a demo program called file_crypt which shows off how to use the library to make a command line tool which allows the user to encode/decode a file with any hash (on the passphrase) and cipher in CTR mode. -- Switched everything to use typedef's now to clear up the code. -- Added AES (128/192 and 256 bit key modes) December 24th, 2001 v0.08 -- fixed a typo in the manual. MPI stores its bignums in BIG endian not little. -- Started adding a RNG to the library. Right now it tries to open /dev/random and if that fails it uses either the MS CSP or the clock drift RNG. It also allows callbacks since the drift RNG is slow (about 3.5 bytes/sec) -- the RNG can also automatically setup a PRNG as well now v0.07 -- Added basic DH routines sufficient to negotiate shared secrets [see the manual for a complete example!] -- Fixed rsa_import to detect when the input could be corrupt. -- added more to the manual. December 22nd, 2001 v0.06 -- Fixed some formatting errors in the hash functions [just source code cleaning] -- Fixed a typo in the error message for sha256 :-) -- Fixed an error in base64_encode() that would fail to catch all buffer overruns -- Test program times the RSA and symmetric cipher routines for kicks... -- Added the "const" modifier to alot of routines to clear up the purpose of each function. -- Changed the name of the library to "TomCrypt" following a suggestion from a sci.crypt reader.... v0.05 -- Fixed the ROL/ROR macro to be safe on platforms where unsigned long is not 32-bits -- I have added a bit more to the documentation manual "crypt.pdf" provided. -- I have added a makefile for LCC-Win32. It should be easy to port to other LCC platforms by changing a few lines. -- Ran a spell checker over the manual. -- Changed the header and library from "crypt" to "mycrypt" to not clash with the *nix package "crypt". v0.04 -- Fixed a bug in the RC5,RC6,Blowfish key schedules where if the key was not a multiple of 4 bytes it would not get loaded correctly. December 21st, 2001 v0.03 -- Added Serpent to the list of ciphers. v0.02 -- Changed RC5 to only allow 12 to 24 rounds -- Added more to the manual. v0.01 -- We will call this the first version. /* $Source: /cvs/libtom/libtomcrypt/changes,v $ */ /* $Revision: 1.288 $ */ /* $Date: 2007/05/12 14:37:41 $ */ libtomcrypt-1.17/updatemakes.sh0000644000175100001440000000065010621351501015363 0ustar tomusers#!/bin/bash bash genlist.sh > tmplist perl filter.pl makefile tmplist mv -f tmp.delme makefile perl filter.pl makefile.icc tmplist mv -f tmp.delme makefile.icc perl filter.pl makefile.shared tmplist mv -f tmp.delme makefile.shared perl filter.pl makefile.unix tmplist mv -f tmp.delme makefile.unix perl filter.pl makefile.msvc tmplist sed -e 's/\.o /.obj /g' < tmp.delme > makefile.msvc rm -f tmplist rm -f tmp.delme libtomcrypt-1.17/libtomcrypt.dsp0000644000175100001440000010353210621351501015607 0ustar tomusers# Microsoft Developer Studio Project File - Name="libtomcrypt" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Static Library" 0x0104 CFG=libtomcrypt - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "libtomcrypt.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "libtomcrypt.mak" CFG="libtomcrypt - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "libtomcrypt - Win32 Release" (based on "Win32 (x86) Static Library") !MESSAGE "libtomcrypt - Win32 Debug" (based on "Win32 (x86) Static Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "libtomcrypt" # PROP Scc_LocalPath "." CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "libtomcrypt - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c # ADD CPP /nologo /W3 /GX /O2 /I "src\headers" /I "..\libtommath" /D "NDEBUG" /D "LTM_DESC" /D "WIN32" /D "_MBCS" /D "_LIB" /D "LTC_SOURCE" /D "USE_LTM" /YX /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo /out:"Release\tomcrypt.lib" !ELSEIF "$(CFG)" == "libtomcrypt - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "src\headers" /I "..\libtommath" /D "_DEBUG" /D "LTM_DESC" /D "WIN32" /D "_MBCS" /D "_LIB" /D "LTC_SOURCE" /D "USE_LTM" /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo /out:"Debug\tomcrypt.lib" !ENDIF # Begin Target # Name "libtomcrypt - Win32 Release" # Name "libtomcrypt - Win32 Debug" # Begin Group "ciphers" # PROP Default_Filter "" # Begin Group "aes" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\ciphers\aes\aes.c !IF "$(CFG)" == "libtomcrypt - Win32 Release" # PROP Ignore_Default_Tool 1 # Begin Custom Build InputPath=.\src\ciphers\aes\aes.c BuildCmds= \ cl /nologo /MLd /W3 /Gm /GX /ZI /Od /I "src\headers" /I "..\libtommath" /D "_DEBUG" /D "LTM_DESC" /D "WIN32" /D "_MBCS" /D "_LIB" /D "LTC_SOURCE" /D "USE_LTM" /Fp"Release/libtomcrypt.pch" /YX /Fo"Release/" /Fd"Release/" /FD /GZ /c $(InputPath) \ cl /nologo /DENCRYPT_ONLY /MLd /W3 /Gm /GX /ZI /Od /I "src\headers" /I "..\libtommath" /D "_DEBUG" /D "LTM_DESC" /D "WIN32" /D "_MBCS" /D "_LIB" /D "LTC_SOURCE" /D "USE_LTM" /Fp"Release/libtomcrypt.pch" /YX /Fo"Release/aes_enc.obj" /Fd"Release/" /FD /GZ /c $(InputPath) \ "Release/aes.obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "Release/aes_enc.obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) # End Custom Build !ELSEIF "$(CFG)" == "libtomcrypt - Win32 Debug" # PROP Ignore_Default_Tool 1 # Begin Custom Build InputPath=.\src\ciphers\aes\aes.c BuildCmds= \ cl /nologo /MLd /W3 /Gm /GX /ZI /Od /I "src\headers" /I "..\libtommath" /D "_DEBUG" /D "LTM_DESC" /D "WIN32" /D "_MBCS" /D "_LIB" /D "LTC_SOURCE" /D "USE_LTM" /Fp"Debug/libtomcrypt.pch" /YX /Fo"Debug/" /Fd"Debug/" /FD /GZ /c $(InputPath) \ cl /nologo /DENCRYPT_ONLY /MLd /W3 /Gm /GX /ZI /Od /I "src\headers" /I "..\libtommath" /D "_DEBUG" /D "LTM_DESC" /D "WIN32" /D "_MBCS" /D "_LIB" /D "LTC_SOURCE" /D "USE_LTM" /Fp"Debug/libtomcrypt.pch" /YX /Fo"Debug/aes_enc.obj" /Fd"Debug/" /FD /GZ /c $(InputPath) \ "Debug/aes.obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) "Debug/aes_enc.obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" $(BuildCmds) # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=.\src\ciphers\aes\aes_tab.c # PROP Exclude_From_Build 1 # End Source File # End Group # Begin Group "safer" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\ciphers\safer\safer.c # End Source File # Begin Source File SOURCE=.\src\ciphers\safer\safer_tab.c # PROP Exclude_From_Build 1 # End Source File # Begin Source File SOURCE=.\src\ciphers\safer\saferp.c # End Source File # End Group # Begin Group "twofish" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\ciphers\twofish\twofish.c # End Source File # Begin Source File SOURCE=.\src\ciphers\twofish\twofish_tab.c # PROP Exclude_From_Build 1 # End Source File # End Group # Begin Source File SOURCE=.\src\ciphers\anubis.c # End Source File # Begin Source File SOURCE=.\src\ciphers\blowfish.c # End Source File # Begin Source File SOURCE=.\src\ciphers\cast5.c # End Source File # Begin Source File SOURCE=.\src\ciphers\des.c # End Source File # Begin Source File SOURCE=.\src\ciphers\kasumi.c # End Source File # Begin Source File SOURCE=.\src\ciphers\khazad.c # End Source File # Begin Source File SOURCE=.\src\ciphers\kseed.c # End Source File # Begin Source File SOURCE=.\src\ciphers\multi2.c # End Source File # Begin Source File SOURCE=.\src\ciphers\noekeon.c # End Source File # Begin Source File SOURCE=.\src\ciphers\rc2.c # End Source File # Begin Source File SOURCE=.\src\ciphers\rc5.c # End Source File # Begin Source File SOURCE=.\src\ciphers\rc6.c # End Source File # Begin Source File SOURCE=.\src\ciphers\skipjack.c # End Source File # Begin Source File SOURCE=.\src\ciphers\xtea.c # End Source File # End Group # Begin Group "encauth" # PROP Default_Filter "" # Begin Group "ccm" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\encauth\ccm\ccm_memory.c # End Source File # Begin Source File SOURCE=.\src\encauth\ccm\ccm_test.c # End Source File # End Group # Begin Group "eax" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\encauth\eax\eax_addheader.c # End Source File # Begin Source File SOURCE=.\src\encauth\eax\eax_decrypt.c # End Source File # Begin Source File SOURCE=.\src\encauth\eax\eax_decrypt_verify_memory.c # End Source File # Begin Source File SOURCE=.\src\encauth\eax\eax_done.c # End Source File # Begin Source File SOURCE=.\src\encauth\eax\eax_encrypt.c # End Source File # Begin Source File SOURCE=.\src\encauth\eax\eax_encrypt_authenticate_memory.c # End Source File # Begin Source File SOURCE=.\src\encauth\eax\eax_init.c # End Source File # Begin Source File SOURCE=.\src\encauth\eax\eax_test.c # End Source File # End Group # Begin Group "gcm" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\encauth\gcm\gcm_add_aad.c # End Source File # Begin Source File SOURCE=.\src\encauth\gcm\gcm_add_iv.c # End Source File # Begin Source File SOURCE=.\src\encauth\gcm\gcm_done.c # End Source File # Begin Source File SOURCE=.\src\encauth\gcm\gcm_gf_mult.c # End Source File # Begin Source File SOURCE=.\src\encauth\gcm\gcm_init.c # End Source File # Begin Source File SOURCE=.\src\encauth\gcm\gcm_memory.c # End Source File # Begin Source File SOURCE=.\src\encauth\gcm\gcm_mult_h.c # End Source File # Begin Source File SOURCE=.\src\encauth\gcm\gcm_process.c # End Source File # Begin Source File SOURCE=.\src\encauth\gcm\gcm_reset.c # End Source File # Begin Source File SOURCE=.\src\encauth\gcm\gcm_test.c # End Source File # End Group # Begin Group "ocb" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\encauth\ocb\ocb_decrypt.c # End Source File # Begin Source File SOURCE=.\src\encauth\ocb\ocb_decrypt_verify_memory.c # End Source File # Begin Source File SOURCE=.\src\encauth\ocb\ocb_done_decrypt.c # End Source File # Begin Source File SOURCE=.\src\encauth\ocb\ocb_done_encrypt.c # End Source File # Begin Source File SOURCE=.\src\encauth\ocb\ocb_encrypt.c # End Source File # Begin Source File SOURCE=.\src\encauth\ocb\ocb_encrypt_authenticate_memory.c # End Source File # Begin Source File SOURCE=.\src\encauth\ocb\ocb_init.c # End Source File # Begin Source File SOURCE=.\src\encauth\ocb\ocb_ntz.c # End Source File # Begin Source File SOURCE=.\src\encauth\ocb\ocb_shift_xor.c # End Source File # Begin Source File SOURCE=.\src\encauth\ocb\ocb_test.c # End Source File # Begin Source File SOURCE=.\src\encauth\ocb\s_ocb_done.c # End Source File # End Group # End Group # Begin Group "hashes" # PROP Default_Filter "" # Begin Group "helper" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\hashes\helper\hash_file.c # End Source File # Begin Source File SOURCE=.\src\hashes\helper\hash_filehandle.c # End Source File # Begin Source File SOURCE=.\src\hashes\helper\hash_memory.c # End Source File # Begin Source File SOURCE=.\src\hashes\helper\hash_memory_multi.c # End Source File # End Group # Begin Group "sha2" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\hashes\sha2\sha224.c # PROP Exclude_From_Build 1 # End Source File # Begin Source File SOURCE=.\src\hashes\sha2\sha256.c # End Source File # Begin Source File SOURCE=.\src\hashes\sha2\sha384.c # PROP Exclude_From_Build 1 # End Source File # Begin Source File SOURCE=.\src\hashes\sha2\sha512.c # End Source File # End Group # Begin Group "whirl" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\hashes\whirl\whirl.c # End Source File # Begin Source File SOURCE=.\src\hashes\whirl\whirltab.c # PROP Exclude_From_Build 1 # End Source File # End Group # Begin Source File SOURCE=.\src\hashes\chc\chc.c # End Source File # Begin Source File SOURCE=.\src\hashes\md2.c # End Source File # Begin Source File SOURCE=.\src\hashes\md4.c # End Source File # Begin Source File SOURCE=.\src\hashes\md5.c # End Source File # Begin Source File SOURCE=.\src\hashes\rmd128.c # End Source File # Begin Source File SOURCE=.\src\hashes\rmd160.c # End Source File # Begin Source File SOURCE=.\src\hashes\rmd256.c # End Source File # Begin Source File SOURCE=.\src\hashes\rmd320.c # End Source File # Begin Source File SOURCE=.\src\hashes\sha1.c # End Source File # Begin Source File SOURCE=.\src\hashes\tiger.c # End Source File # End Group # Begin Group "mac" # PROP Default_Filter "" # Begin Group "f9" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\mac\f9\f9_done.c # End Source File # Begin Source File SOURCE=.\src\mac\f9\f9_file.c # End Source File # Begin Source File SOURCE=.\src\mac\f9\f9_init.c # End Source File # Begin Source File SOURCE=.\src\mac\f9\f9_memory.c # End Source File # Begin Source File SOURCE=.\src\mac\f9\f9_memory_multi.c # End Source File # Begin Source File SOURCE=.\src\mac\f9\f9_process.c # End Source File # Begin Source File SOURCE=.\src\mac\f9\f9_test.c # End Source File # End Group # Begin Group "hmac" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\mac\hmac\hmac_done.c # End Source File # Begin Source File SOURCE=.\src\mac\hmac\hmac_file.c # End Source File # Begin Source File SOURCE=.\src\mac\hmac\hmac_init.c # End Source File # Begin Source File SOURCE=.\src\mac\hmac\hmac_memory.c # End Source File # Begin Source File SOURCE=.\src\mac\hmac\hmac_memory_multi.c # End Source File # Begin Source File SOURCE=.\src\mac\hmac\hmac_process.c # End Source File # Begin Source File SOURCE=.\src\mac\hmac\hmac_test.c # End Source File # End Group # Begin Group "omac" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\mac\omac\omac_done.c # End Source File # Begin Source File SOURCE=.\src\mac\omac\omac_file.c # End Source File # Begin Source File SOURCE=.\src\mac\omac\omac_init.c # End Source File # Begin Source File SOURCE=.\src\mac\omac\omac_memory.c # End Source File # Begin Source File SOURCE=.\src\mac\omac\omac_memory_multi.c # End Source File # Begin Source File SOURCE=.\src\mac\omac\omac_process.c # End Source File # Begin Source File SOURCE=.\src\mac\omac\omac_test.c # End Source File # End Group # Begin Group "pelican" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\mac\pelican\pelican.c # End Source File # Begin Source File SOURCE=.\src\mac\pelican\pelican_memory.c # End Source File # Begin Source File SOURCE=.\src\mac\pelican\pelican_test.c # End Source File # End Group # Begin Group "pmac" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\mac\pmac\pmac_done.c # End Source File # Begin Source File SOURCE=.\src\mac\pmac\pmac_file.c # End Source File # Begin Source File SOURCE=.\src\mac\pmac\pmac_init.c # End Source File # Begin Source File SOURCE=.\src\mac\pmac\pmac_memory.c # End Source File # Begin Source File SOURCE=.\src\mac\pmac\pmac_memory_multi.c # End Source File # Begin Source File SOURCE=.\src\mac\pmac\pmac_ntz.c # End Source File # Begin Source File SOURCE=.\src\mac\pmac\pmac_process.c # End Source File # Begin Source File SOURCE=.\src\mac\pmac\pmac_shift_xor.c # End Source File # Begin Source File SOURCE=.\src\mac\pmac\pmac_test.c # End Source File # End Group # Begin Group "xcbc" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\mac\xcbc\xcbc_done.c # End Source File # Begin Source File SOURCE=.\src\mac\xcbc\xcbc_file.c # End Source File # Begin Source File SOURCE=.\src\mac\xcbc\xcbc_init.c # End Source File # Begin Source File SOURCE=.\src\mac\xcbc\xcbc_memory.c # End Source File # Begin Source File SOURCE=.\src\mac\xcbc\xcbc_memory_multi.c # End Source File # Begin Source File SOURCE=.\src\mac\xcbc\xcbc_process.c # End Source File # Begin Source File SOURCE=.\src\mac\xcbc\xcbc_test.c # End Source File # End Group # End Group # Begin Group "math" # PROP Default_Filter "" # Begin Group "fp" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\math\fp\ltc_ecc_fp_mulmod.c # End Source File # End Group # Begin Source File SOURCE=.\src\math\gmp_desc.c # End Source File # Begin Source File SOURCE=.\src\math\ltm_desc.c # End Source File # Begin Source File SOURCE=.\src\math\multi.c # End Source File # Begin Source File SOURCE=.\src\math\rand_prime.c # End Source File # Begin Source File SOURCE=.\src\math\tfm_desc.c # End Source File # End Group # Begin Group "misc" # PROP Default_Filter "" # Begin Group "base64" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\misc\base64\base64_decode.c # End Source File # Begin Source File SOURCE=.\src\misc\base64\base64_encode.c # End Source File # End Group # Begin Group "crypt" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\misc\crypt\crypt.c # End Source File # Begin Source File SOURCE=.\src\misc\crypt\crypt_argchk.c # End Source File # Begin Source File SOURCE=.\src\misc\crypt\crypt_cipher_descriptor.c # End Source File # Begin Source File SOURCE=.\src\misc\crypt\crypt_cipher_is_valid.c # End Source File # Begin Source File SOURCE=.\src\misc\crypt\crypt_find_cipher.c # End Source File # Begin Source File SOURCE=.\src\misc\crypt\crypt_find_cipher_any.c # End Source File # Begin Source File SOURCE=.\src\misc\crypt\crypt_find_cipher_id.c # End Source File # Begin Source File SOURCE=.\src\misc\crypt\crypt_find_hash.c # End Source File # Begin Source File SOURCE=.\src\misc\crypt\crypt_find_hash_any.c # End Source File # Begin Source File SOURCE=.\src\misc\crypt\crypt_find_hash_id.c # End Source File # Begin Source File SOURCE=.\src\misc\crypt\crypt_find_hash_oid.c # End Source File # Begin Source File SOURCE=.\src\misc\crypt\crypt_find_prng.c # End Source File # Begin Source File SOURCE=.\src\misc\crypt\crypt_fsa.c # End Source File # Begin Source File SOURCE=.\src\misc\crypt\crypt_hash_descriptor.c # End Source File # Begin Source File SOURCE=.\src\misc\crypt\crypt_hash_is_valid.c # End Source File # Begin Source File SOURCE=.\src\misc\crypt\crypt_ltc_mp_descriptor.c # End Source File # Begin Source File SOURCE=.\src\misc\crypt\crypt_prng_descriptor.c # End Source File # Begin Source File SOURCE=.\src\misc\crypt\crypt_prng_is_valid.c # End Source File # Begin Source File SOURCE=.\src\misc\crypt\crypt_register_cipher.c # End Source File # Begin Source File SOURCE=.\src\misc\crypt\crypt_register_hash.c # End Source File # Begin Source File SOURCE=.\src\misc\crypt\crypt_register_prng.c # End Source File # Begin Source File SOURCE=.\src\misc\crypt\crypt_unregister_cipher.c # End Source File # Begin Source File SOURCE=.\src\misc\crypt\crypt_unregister_hash.c # End Source File # Begin Source File SOURCE=.\src\misc\crypt\crypt_unregister_prng.c # End Source File # End Group # Begin Group "pkcs" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\misc\pkcs5\pkcs_5_1.c # End Source File # Begin Source File SOURCE=.\src\misc\pkcs5\pkcs_5_2.c # End Source File # End Group # Begin Source File SOURCE=.\src\misc\burn_stack.c # End Source File # Begin Source File SOURCE=.\src\misc\error_to_string.c # End Source File # Begin Source File SOURCE=.\src\misc\zeromem.c # End Source File # End Group # Begin Group "modes" # PROP Default_Filter "" # Begin Group "cbc" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\modes\cbc\cbc_decrypt.c # End Source File # Begin Source File SOURCE=.\src\modes\cbc\cbc_done.c # End Source File # Begin Source File SOURCE=.\src\modes\cbc\cbc_encrypt.c # End Source File # Begin Source File SOURCE=.\src\modes\cbc\cbc_getiv.c # End Source File # Begin Source File SOURCE=.\src\modes\cbc\cbc_setiv.c # End Source File # Begin Source File SOURCE=.\src\modes\cbc\cbc_start.c # End Source File # End Group # Begin Group "cfb" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\modes\cfb\cfb_decrypt.c # End Source File # Begin Source File SOURCE=.\src\modes\cfb\cfb_done.c # End Source File # Begin Source File SOURCE=.\src\modes\cfb\cfb_encrypt.c # End Source File # Begin Source File SOURCE=.\src\modes\cfb\cfb_getiv.c # End Source File # Begin Source File SOURCE=.\src\modes\cfb\cfb_setiv.c # End Source File # Begin Source File SOURCE=.\src\modes\cfb\cfb_start.c # End Source File # End Group # Begin Group "ctr" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\modes\ctr\ctr_decrypt.c # End Source File # Begin Source File SOURCE=.\src\modes\ctr\ctr_done.c # End Source File # Begin Source File SOURCE=.\src\modes\ctr\ctr_encrypt.c # End Source File # Begin Source File SOURCE=.\src\modes\ctr\ctr_getiv.c # End Source File # Begin Source File SOURCE=.\src\modes\ctr\ctr_setiv.c # End Source File # Begin Source File SOURCE=.\src\modes\ctr\ctr_start.c # End Source File # Begin Source File SOURCE=.\src\modes\ctr\ctr_test.c # End Source File # End Group # Begin Group "ecb" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\modes\ecb\ecb_decrypt.c # End Source File # Begin Source File SOURCE=.\src\modes\ecb\ecb_done.c # End Source File # Begin Source File SOURCE=.\src\modes\ecb\ecb_encrypt.c # End Source File # Begin Source File SOURCE=.\src\modes\ecb\ecb_start.c # End Source File # End Group # Begin Group "f8" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\modes\f8\f8_decrypt.c # End Source File # Begin Source File SOURCE=.\src\modes\f8\f8_done.c # End Source File # Begin Source File SOURCE=.\src\modes\f8\f8_encrypt.c # End Source File # Begin Source File SOURCE=.\src\modes\f8\f8_getiv.c # End Source File # Begin Source File SOURCE=.\src\modes\f8\f8_setiv.c # End Source File # Begin Source File SOURCE=.\src\modes\f8\f8_start.c # End Source File # Begin Source File SOURCE=.\src\modes\f8\f8_test_mode.c # End Source File # End Group # Begin Group "lrw" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\modes\lrw\lrw_decrypt.c # End Source File # Begin Source File SOURCE=.\src\modes\lrw\lrw_done.c # End Source File # Begin Source File SOURCE=.\src\modes\lrw\lrw_encrypt.c # End Source File # Begin Source File SOURCE=.\src\modes\lrw\lrw_getiv.c # End Source File # Begin Source File SOURCE=.\src\modes\lrw\lrw_process.c # End Source File # Begin Source File SOURCE=.\src\modes\lrw\lrw_setiv.c # End Source File # Begin Source File SOURCE=.\src\modes\lrw\lrw_start.c # End Source File # Begin Source File SOURCE=.\src\modes\lrw\lrw_test.c # End Source File # End Group # Begin Group "ofb" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\modes\ofb\ofb_decrypt.c # End Source File # Begin Source File SOURCE=.\src\modes\ofb\ofb_done.c # End Source File # Begin Source File SOURCE=.\src\modes\ofb\ofb_encrypt.c # End Source File # Begin Source File SOURCE=.\src\modes\ofb\ofb_getiv.c # End Source File # Begin Source File SOURCE=.\src\modes\ofb\ofb_setiv.c # End Source File # Begin Source File SOURCE=.\src\modes\ofb\ofb_start.c # End Source File # End Group # Begin Group "xts" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\modes\xts\xts_decrypt.c # End Source File # Begin Source File SOURCE=.\src\modes\xts\xts_done.c # End Source File # Begin Source File SOURCE=.\src\modes\xts\xts_encrypt.c # End Source File # Begin Source File SOURCE=.\src\modes\xts\xts_init.c # End Source File # Begin Source File SOURCE=.\src\modes\xts\xts_mult_x.c # End Source File # Begin Source File SOURCE=.\src\modes\xts\xts_test.c # End Source File # End Group # End Group # Begin Group "pk" # PROP Default_Filter "" # Begin Group "asn1" # PROP Default_Filter "" # Begin Group "der" # PROP Default_Filter "" # Begin Group "bit" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\pk\asn1\der\bit\der_decode_bit_string.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\bit\der_encode_bit_string.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\bit\der_length_bit_string.c # End Source File # End Group # Begin Group "boolean" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\pk\asn1\der\boolean\der_decode_boolean.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\boolean\der_encode_boolean.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\boolean\der_length_boolean.c # End Source File # End Group # Begin Group "choice" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\pk\asn1\der\choice\der_decode_choice.c # End Source File # End Group # Begin Group "ia5" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\pk\asn1\der\ia5\der_decode_ia5_string.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\ia5\der_encode_ia5_string.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\ia5\der_length_ia5_string.c # End Source File # End Group # Begin Group "integer" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\pk\asn1\der\integer\der_decode_integer.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\integer\der_encode_integer.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\integer\der_length_integer.c # End Source File # End Group # Begin Group "object_identifier" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\pk\asn1\der\object_identifier\der_decode_object_identifier.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\object_identifier\der_encode_object_identifier.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\object_identifier\der_length_object_identifier.c # End Source File # End Group # Begin Group "octet" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\pk\asn1\der\octet\der_decode_octet_string.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\octet\der_encode_octet_string.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\octet\der_length_octet_string.c # End Source File # End Group # Begin Group "printable_string" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\pk\asn1\der\printable_string\der_decode_printable_string.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\printable_string\der_encode_printable_string.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\printable_string\der_length_printable_string.c # End Source File # End Group # Begin Group "sequence" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\pk\asn1\der\sequence\der_decode_sequence_ex.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\sequence\der_decode_sequence_flexi.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\sequence\der_decode_sequence_multi.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\sequence\der_encode_sequence_ex.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\sequence\der_encode_sequence_multi.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\sequence\der_length_sequence.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\sequence\der_sequence_free.c # End Source File # End Group # Begin Group "set" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\pk\asn1\der\set\der_encode_set.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\set\der_encode_setof.c # End Source File # End Group # Begin Group "short_integer" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\pk\asn1\der\short_integer\der_decode_short_integer.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\short_integer\der_encode_short_integer.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\short_integer\der_length_short_integer.c # End Source File # End Group # Begin Group "utctime" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\pk\asn1\der\utctime\der_decode_utctime.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\utctime\der_encode_utctime.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\utctime\der_length_utctime.c # End Source File # End Group # Begin Group "utf8" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\pk\asn1\der\utf8\der_decode_utf8_string.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\utf8\der_encode_utf8_string.c # End Source File # Begin Source File SOURCE=.\src\pk\asn1\der\utf8\der_length_utf8_string.c # End Source File # End Group # End Group # End Group # Begin Group "dsa" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\pk\dsa\dsa_decrypt_key.c # End Source File # Begin Source File SOURCE=.\src\pk\dsa\dsa_encrypt_key.c # End Source File # Begin Source File SOURCE=.\src\pk\dsa\dsa_export.c # End Source File # Begin Source File SOURCE=.\src\pk\dsa\dsa_free.c # End Source File # Begin Source File SOURCE=.\src\pk\dsa\dsa_import.c # End Source File # Begin Source File SOURCE=.\src\pk\dsa\dsa_make_key.c # End Source File # Begin Source File SOURCE=.\src\pk\dsa\dsa_shared_secret.c # End Source File # Begin Source File SOURCE=.\src\pk\dsa\dsa_sign_hash.c # End Source File # Begin Source File SOURCE=.\src\pk\dsa\dsa_verify_hash.c # End Source File # Begin Source File SOURCE=.\src\pk\dsa\dsa_verify_key.c # End Source File # End Group # Begin Group "ecc" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\pk\ecc\ecc.c # End Source File # Begin Source File SOURCE=.\src\pk\ecc\ecc_ansi_x963_export.c # End Source File # Begin Source File SOURCE=.\src\pk\ecc\ecc_ansi_x963_import.c # End Source File # Begin Source File SOURCE=.\src\pk\ecc\ecc_decrypt_key.c # End Source File # Begin Source File SOURCE=.\src\pk\ecc\ecc_encrypt_key.c # End Source File # Begin Source File SOURCE=.\src\pk\ecc\ecc_export.c # End Source File # Begin Source File SOURCE=.\src\pk\ecc\ecc_free.c # End Source File # Begin Source File SOURCE=.\src\pk\ecc\ecc_get_size.c # End Source File # Begin Source File SOURCE=.\src\pk\ecc\ecc_import.c # End Source File # Begin Source File SOURCE=.\src\pk\ecc\ecc_make_key.c # End Source File # Begin Source File SOURCE=.\src\pk\ecc\ecc_shared_secret.c # End Source File # Begin Source File SOURCE=.\src\pk\ecc\ecc_sign_hash.c # End Source File # Begin Source File SOURCE=.\src\pk\ecc\ecc_sizes.c # End Source File # Begin Source File SOURCE=.\src\pk\ecc\ecc_test.c # End Source File # Begin Source File SOURCE=.\src\pk\ecc\ecc_verify_hash.c # End Source File # Begin Source File SOURCE=.\src\pk\ecc\ltc_ecc_is_valid_idx.c # End Source File # Begin Source File SOURCE=.\src\pk\ecc\ltc_ecc_map.c # End Source File # Begin Source File SOURCE=.\src\pk\ecc\ltc_ecc_mul2add.c # End Source File # Begin Source File SOURCE=.\src\pk\ecc\ltc_ecc_mulmod.c # End Source File # Begin Source File SOURCE=.\src\pk\ecc\ltc_ecc_mulmod_timing.c # End Source File # Begin Source File SOURCE=.\src\pk\ecc\ltc_ecc_points.c # End Source File # Begin Source File SOURCE=.\src\pk\ecc\ltc_ecc_projective_add_point.c # End Source File # Begin Source File SOURCE=.\src\pk\ecc\ltc_ecc_projective_dbl_point.c # End Source File # End Group # Begin Group "katja" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\pk\katja\katja_decrypt_key.c # End Source File # Begin Source File SOURCE=.\src\pk\katja\katja_encrypt_key.c # End Source File # Begin Source File SOURCE=.\src\pk\katja\katja_export.c # End Source File # Begin Source File SOURCE=.\src\pk\katja\katja_exptmod.c # End Source File # Begin Source File SOURCE=.\src\pk\katja\katja_free.c # End Source File # Begin Source File SOURCE=.\src\pk\katja\katja_import.c # End Source File # Begin Source File SOURCE=.\src\pk\katja\katja_make_key.c # End Source File # End Group # Begin Group "pkcs1" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\pk\pkcs1\pkcs_1_i2osp.c # End Source File # Begin Source File SOURCE=.\src\pk\pkcs1\pkcs_1_mgf1.c # End Source File # Begin Source File SOURCE=.\src\pk\pkcs1\pkcs_1_oaep_decode.c # End Source File # Begin Source File SOURCE=.\src\pk\pkcs1\pkcs_1_oaep_encode.c # End Source File # Begin Source File SOURCE=.\src\pk\pkcs1\pkcs_1_os2ip.c # End Source File # Begin Source File SOURCE=.\src\pk\pkcs1\pkcs_1_pss_decode.c # End Source File # Begin Source File SOURCE=.\src\pk\pkcs1\pkcs_1_pss_encode.c # End Source File # Begin Source File SOURCE=.\src\pk\pkcs1\pkcs_1_v1_5_decode.c # End Source File # Begin Source File SOURCE=.\src\pk\pkcs1\pkcs_1_v1_5_encode.c # End Source File # End Group # Begin Group "rsa" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\pk\rsa\rsa_decrypt_key.c # End Source File # Begin Source File SOURCE=.\src\pk\rsa\rsa_encrypt_key.c # End Source File # Begin Source File SOURCE=.\src\pk\rsa\rsa_export.c # End Source File # Begin Source File SOURCE=.\src\pk\rsa\rsa_exptmod.c # End Source File # Begin Source File SOURCE=.\src\pk\rsa\rsa_free.c # End Source File # Begin Source File SOURCE=.\src\pk\rsa\rsa_import.c # End Source File # Begin Source File SOURCE=.\src\pk\rsa\rsa_make_key.c # End Source File # Begin Source File SOURCE=.\src\pk\rsa\rsa_sign_hash.c # End Source File # Begin Source File SOURCE=.\src\pk\rsa\rsa_verify_hash.c # End Source File # End Group # End Group # Begin Group "prngs" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\prngs\fortuna.c # End Source File # Begin Source File SOURCE=.\src\prngs\rc4.c # End Source File # Begin Source File SOURCE=.\src\prngs\rng_get_bytes.c # End Source File # Begin Source File SOURCE=.\src\prngs\rng_make_prng.c # End Source File # Begin Source File SOURCE=.\src\prngs\sober128.c # End Source File # Begin Source File SOURCE=.\src\prngs\sober128tab.c # PROP Exclude_From_Build 1 # End Source File # Begin Source File SOURCE=.\src\prngs\sprng.c # End Source File # Begin Source File SOURCE=.\src\prngs\yarrow.c # End Source File # End Group # Begin Group "headers" # PROP Default_Filter "" # Begin Source File SOURCE=.\src\headers\tomcrypt.h # End Source File # Begin Source File SOURCE=.\src\headers\tomcrypt_argchk.h # End Source File # Begin Source File SOURCE=.\src\headers\tomcrypt_cfg.h # End Source File # Begin Source File SOURCE=.\src\headers\tomcrypt_cipher.h # End Source File # Begin Source File SOURCE=.\src\headers\tomcrypt_custom.h # End Source File # Begin Source File SOURCE=.\src\headers\tomcrypt_hash.h # End Source File # Begin Source File SOURCE=.\src\headers\tomcrypt_mac.h # End Source File # Begin Source File SOURCE=.\src\headers\tomcrypt_macros.h # End Source File # Begin Source File SOURCE=.\src\headers\tomcrypt_math.h # End Source File # Begin Source File SOURCE=.\src\headers\tomcrypt_misc.h # End Source File # Begin Source File SOURCE=.\src\headers\tomcrypt_pk.h # End Source File # Begin Source File SOURCE=.\src\headers\tomcrypt_pkcs.h # End Source File # Begin Source File SOURCE=.\src\headers\tomcrypt_prng.h # End Source File # End Group # End Target # End Project