From msuinfo!uwm.edu!vixen.cso.uiuc.edu!howland.reston.ans.net!europa.eng.gtefsd.com!MathWorks.Com!news.kei.com!ddsw1!chinet!schneier Tue Mar 22 09:37:09 1994 Newsgroups: sci.crypt Path: msuinfo!uwm.edu!vixen.cso.uiuc.edu!howland.reston.ans.net!europa.eng.gtefsd.com!MathWorks.Com!news.kei.com!ddsw1!chinet!schneier From: schneier@chinet.chinet.com (Bruce Schneier) Subject: BLOWFISH - Corrected code and Data File - from Apr 94 DDJ Message-ID: Organization: Chinet - Public Access UNIX Distribution: usa Date: Mon, 21 Mar 1994 15:01:31 GMT Lines: 380 This is the corrected BLOWFISH code. BLOWFISH is a secret key algorithm that appeared in the Apr 94 Dr. Dobbs Journal. This posting includes: blowfish.h blowfish.c blowfish.dat.uu In deference to U.S. export laws, this code is being posted for "usa" distribution only. Bruce ************************************************************************** * Bruce Schneier * Counterpane Systems For a good prime, call 391581 * 2^216193 - 1 * schneier@chinet.com ************************************************************************** ********************BLOWFISH.H******************** #define MAXKEYBYTES 56 /* 448 bits */ // #define little_endian 1 /* Eg: Intel */ #define big_endian 1 /* Eg: Motorola */ short opensubkeyfile(void); unsigned long F(unsigned long x); void Blowfish_encipher(unsigned long *xl, unsigned long *xr); void Blowfish_decipher(unsigned long *xl, unsigned long *xr); short InitializeBlowfish(char key[], short keybytes); ********************BLOWFISH.C******************** #ifdef little_endian /* Eg: Intel */ #include #include #include #endif #include #include #include #include #ifdef little_endian /* Eg: Intel */ #include #endif #include #ifdef little_endian /* Eg: Intel */ #include #include #endif #ifdef big_endian #include #endif #include "Blowfish.h" #define N 16 #define noErr 0 #define DATAERROR -1 #define KEYBYTES 8 #define subkeyfilename "Blowfish.dat" unsigned long P[N + 2]; unsigned long S[4][256]; FILE* SubkeyFile; short opensubkeyfile(void) /* read only */ { short error; error = noErr; if((SubkeyFile = fopen(subkeyfilename,"rb")) == NULL) { error = DATAERROR; } return error; } unsigned long F(unsigned long x) { unsigned short a; unsigned short b; unsigned short c; unsigned short d; unsigned long y; d = x & 0x00FF; x >>= 8; c = x & 0x00FF; x >>= 8; b = x & 0x00FF; x >>= 8; a = x & 0x00FF; //y = ((S[0][a] + S[1][b]) ^ S[2][c]) + S[3][d]; y = S[0][a] + S[1][b]; y = y ^ S[2][c]; y = y + S[3][d]; return y; } void Blowfish_encipher(unsigned long *xl, unsigned long *xr) { unsigned long Xl; unsigned long Xr; unsigned long temp; short i; Xl = *xl; Xr = *xr; for (i = 0; i < N; ++i) { Xl = Xl ^ P[i]; Xr = F(Xl) ^ Xr; temp = Xl; Xl = Xr; Xr = temp; } temp = Xl; Xl = Xr; Xr = temp; Xr = Xr ^ P[N]; Xl = Xl ^ P[N + 1]; *xl = Xl; *xr = Xr; } void Blowfish_decipher(unsigned long *xl, unsigned long *xr) { unsigned long Xl; unsigned long Xr; unsigned long temp; short i; Xl = *xl; Xr = *xr; for (i = N + 1; i > 1; --i) { Xl = Xl ^ P[i]; Xr = F(Xl) ^ Xr; /* Exchange Xl and Xr */ temp = Xl; Xl = Xr; Xr = temp; } /* Exchange Xl and Xr */ temp = Xl; Xl = Xr; Xr = temp; Xr = Xr ^ P[1]; Xl = Xl ^ P[0]; *xl = Xl; *xr = Xr; } short InitializeBlowfish(char key[], short keybytes) { short i; short j; short k; short error; short numread; unsigned long data; unsigned long datal; unsigned long datar; /* First, open the file containing the array initialization data */ error = opensubkeyfile(); if (error == noErr) { for (i = 0; i < N + 2; ++i) { numread = fread(&data, 4, 1, SubkeyFile); #ifdef little_endian /* Eg: Intel We want to process things in byte */ /* order, not as rearranged in a longword */ data = ((data & 0xFF000000) >> 24) | ((data & 0x00FF0000) >> 8) | ((data & 0x0000FF00) << 8) | ((data & 0x000000FF) << 24); #endif if (numread != 1) { return DATAERROR; } else { P[i] = data; } } for (i = 0; i < 4; ++i) { for (j = 0; j < 256; ++j) { numread = fread(&data, 4, 1, SubkeyFile); #ifdef little_endian /* Eg: Intel We want to process things in byte */ /* order, not as rearranged in a longword */ data = ((data & 0xFF000000) >> 24) | ((data & 0x00FF0000) >> 8) | ((data & 0x0000FF00) << 8) | ((data & 0x000000FF) << 24); #endif if (numread != 1) { return DATAERROR; } else { S[i][j] = data; } } } fclose(SubkeyFile); j = 0; for (i = 0; i < N + 2; ++i) { data = 0x00000000; for (k = 0; k < 4; ++k) { data = (data << 8) | key[j]; j = j + 1; if (j >= keybytes) { j = 0; } } P[i] = P[i] ^ data; } datal = 0x00000000; datar = 0x00000000; for (i = 0; i < N + 2; i += 2) { Blowfish_encipher(&datal, &datar); P[i] = datal; P[i + 1] = datar; } for (i = 0; i < 4; ++i) { for (j = 0; j < 256; j += 2) { Blowfish_encipher(&datal, &datar); S[i][j] = datal; S[i][j + 1] = datar; } } } else { printf("Unable to open subkey initialization file : %d\n", error); } return error; } ********************BLOWFISH.DAT.UU******************** begin 0700 "Blowfish.dat" Mic]JBhvCbmlsfxHN`WaSqjpinbhIGSgpbb[ZFnQn;hEejbgFnm`s=[YtyL\T MZpQLPjPIM\E\tmT_AmvUMt?L;TsdkIIC?MzPO_wk;TaK?M[CA MK^UJiGZvNGRpq?dL?YDDHyEgLYeL]P@a\NjeCOPvxVD@VgewsFFDvoZC]il] M?@Vu=h]RCKyxBC[wew?aOsekiWBOk]IuxeQ@YEtE\ZIuJYqw MriABx^@tpewjnvHJJQbVMlQsgJ_vNCmLil]<>Cis@rBuAG<[CTBxzTNYK\r_ZaMFjbfsx=@i MSoLAJyeh?jQ@w>R`lN^dwuWIAwvQWbxC`NMEfX@CBsZaTYzLQp]M;_nc]dhY Mk@Md@Jrdh`qIRoajGA^;wBgfzdkVZvRzyPR]^o^taJV>tP[EVS@Ops`aKKaJt^V Mpi]@QeYOpF^ MX]`dWCmj_vxoj`we>[RF^lHaJguB[?eVG;UtjH]BA^_\nLySkfCd]u;;XqvwrCDF\r_NwDng=\MJD MRWXSxOLsp<[DQNCOhlKzmG=l`=a^GOXK\q^TE=OzszZpDyCJKxYQzYouHmbn MT=bOQRw@CCQ;kXYUEk>o]Nk[\AhKyhBhNajpc?`HfBoPQSqS_fqLZCa MKr\OhAB^cA=WZGtM_HLbgZgEHlPoMv]TZaBL\];nB>jyMjAoXoTsXk=\QcNa MTJVHVqy?HFz`EwhF@`NU>XXj\Dycz;\`FYgEuCDqUyWZzJ>lecB=Ez MtW\@?uNB`NvYQxlF`WyBE<^Id<@yzdYSrDfSqRWj>QrIrAMq`ejztRDuU@]w Mo[R;QNpKxjqV@>yT``BZ;[uwf^D?\I;LzRHmVqvVxVtAY[GYMO\Tar[eAuyD Mt[`MwzF?CZdhND>y;HtgzDMZXqDV`JuUbtPIHeDspnpxnCX_uiBzvTj=yvNo MYmzy]S_vH=jSeXizfL_oKKO MRsRwfaqKzGbAzg\UAej@XHzWGeleJE`gmSXgAaQ_WJYvam\kzWlBU=Crz\]VGJtqAq@_p`P[LRl<^Igt>p>hXSyD[Z@XOlHb[Hq@^ MLSenuhLXsVVYbf]bcpoVb@r_kk@rDbrw?gEv>;aROj^iK]Zz=Q_yDP@pLXNN MdMSooRYudGh?kFMQie`zW>z?AlVg>EAgfgphVA>\GYJ\ZtM]CnQZ[cK;AqWZ MxPEcyLqDP]kOgaAglAwybmUcnSNK\LgAt\;H;C MqwcJZv^QA@Y>bEH^jKmWg^<\BcLw\WTpfl_RCclMWOOFQzIvuxhxuHJY@b[LZEc]LOEsLJ M[WVMvVXOAatAMB@IaVeP[mUg=vf?eq`sSj@PZVf]E@lT_AZJ`VooMwmen[lAKQ@xBRGGjMy?Fh]?zCXmXBzE^lM=QgMDU\vzaja McCvhjeBZFu?UAjt;hGiCFXoc_QKbqI;mLPKKtRXPuh_yrnqM MOcdHvnOR[Ssf_^K^jnUA[GP\>yZfAtWgYdMgzCVaxEcoxJgRvXTF MqORh@ZcaQ[zC?QtDPVGk=iigAhHkuIjRApE;OPbMftB=efjQ=bnbc@axpHTJ McewUZAVM]cXCoWaAlWkPDHVs?Dgvw^SQ;bh[VWS>mUGk[Gq@phwRI\YWlFZF MaXbdf?ApGNCOVeuAVyB[cqsrd_=uGapX> MGLG;<]OsdevhSv=?VGGCyTm`Q\vW_hat^h>>oLcUjYNn? Mj]NcK??IouIHEhe`]_yliARtzrDTpqt@]WxbUo>\]fLNUjh`zmphigdShoqJ Mp[?tMU``xz\>n?xNERqeqApAsWr_BXA`syw\gyzUDz]P]mWsyJ`Oq;^\b>Pc MOy>e?ZQMTcgkAprvZR>Su?TYp=HEq^zKR@JzjeaXiuldj?pjkh;zZ;yM^VC< MefkwrfD`z`[`Ib>AC>Yoo_ZBZh>MCkvlX`yZ]mzVJLX>?mlWw^Sn>jnypfLJ MpBc^GCwy\XvY[CGwJSLrsHL=R?KWrVTxuBzCyCgJXY>RnF[Z=mU;pSiHp>?W MRG@@^_Lj]t[x_KnwqtavKkIhEr=utSHZhhnmA_YKJ;?pEIukuzAGOjduFECl MJrECF>g;lZxJrEx_lrwYwOq^gi`IlwS]^n@babYaaa\opd=YIeVh;AKVyoT<@RlkzkWjm`r>dvuMYs]ygThxN?l]?atrzmOAWUh^Ln=_r?S MoHT>bD=CpyDN_WpZ;VZK]oC]mZ@rWfbAZ]WXFqOAsmMNzPWf>Utp;v;]Vn];KmSDNL\PqvwF`iNjw]bXQkvAbKz?fzBL[dGulSg@N\qQJdDhW MMYiqYPzAN^yk^VmpfFLpfagj[?H]i;WxXNgcRtqbeEDjdAnfVpSL;MvKZBID MKV=nVHzHw[Z_ZxADYlo^G;R`u_cWPhy@>gOXx`m@s=g]@T;Vna^P=TvNamiONLFxxL=WXrdz@YYDu^uXDyNvxX@Me=P MCmuuDMW\yMNbIW`EFkpFAQcifl^AzgPhi M\kZlrIF@iqUN_A`zNsT=bZvDWZff\@\HzoeIWk?z@Uz^hPG=S^fpNoSMueuXboREM=@]?mmmKp_dgEcOwKeAYOBB MAqsy;edsof_uQ^=vXt[dmBJ_SMWfRc?wFChTDFnbdF?=uSbAUlTdWf MjsF[VZFZqEbLEr;HOE[CajgZU?aJkufzx^^lXIJf[Bk`B`ZJ< M\MbD@\aANIOIzDVoYqupNFq;UB@FHOFGnCKArZFuAN]uxNGgk^_s]UkWVC\d M;VEW^@Iy@nrIex>PA@f;b>zMnS[ED^Fp_uJ>mm>wkobWVphKBUfvUzPZ`wVF M?=gooMy\?rTHgY\ESZWRNiMzUKqRvHCUsn`IKgg@fzwFq[bL_>Vs^IOHT\rm MjcMwSoCuyBEYdRXH>e\aD>UUxewWE@YdX]m>Cate;=rh]fVZ`ZeAipuD\kWc MZYXuoiawHI@wts@PWhXWGuABDRcYD>IZDlk[oGOntrgn Myg=oOCjHMNm^PRD]qDC>tVEDd^z`HJXhdmUMLBqIArW]bpSQP@RjY;OO?=fUBmplSr`w]KMnn[WziJ?CIy_Tt^mpIdOksmUwkJSJCZ Myhr[CvxrKK\\;T?rF^qCub]=GJ[b=QOVsFmP=`XmC>=;dU?X@g[KiXaSh?KSgT?;o`qgc MH>BJQQJpATGts[VzTmK>R]tjVC@cnfPIT MptNCmhSeOGd@PWxRVm\UGXV;Fr\NY@MOqP_C\qWEsmItgMKxD<_moGYO MeABQyOTLgpvdC]ke]OLBF?tC\U>FlGxCDZ@Ulu;lSpjL\heBvGwKMvXvmI>h MTGolWIyBDHfYr=alti`;<Apjq>gpaLoR>YKiJEo]xJ@o`kLE MO^hUO=kVOHHc\iirWbbnz?MTYAlLYWXEMwC]_CnLmRYK@ZRPh@`CEZ;L;[v__oUmUl MOU[q]c_E@C[TZblMerKPYQCitEVRNNda^fYZ;yQHJrxZRFf^p MG@RDgWLW=RPrxcbebhBGtAEt;UQFOlLfiUqqua=RaUsYhpD[zMY;O MqJaiCPmF?>[>`ZPjL\rw]ITPjERn MY[Am[UHQLi;iZ_BmtrUXCGY``NZgXbKVPUBANPkHUZ_?G[cG>pZtjCL\fKKf M_Z>OG?>v^sh;Nypa=jBH[rhvkl_QNYGzJmuqImwDr^S=X^RHcG_uyeG\eyc@r]naxBEjPR[CIqn];eJmSQnVA M??S^ZOukR[Zg<^orQsgFMVbwb;D MtLCN_jS>gHrcnOmAhqTceSkalyQN=KdSARRvQcMs=ouL?SRMhafmouYi>Kd`jFLu>IRBsk?a@p=auTQ]pke MnHeetx=zylTPF?eIM?fjCgoNbUYwmH]L>?r[>EEy kiJJTGLzjRoS[@`a ` end