WizardsToolkit  1.0.7
serpent.c
Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %               SSSSS  EEEEE  RRRR   PPPP   EEEEE  N   N  TTTTT               %
00007 %               SS     E      R   R  P   P  E      NN  N    T                 %
00008 %                SSS   EEE    RRRR   PPPP   EEE    N N N    T                 %
00009 %                  SS  E      R R    P      E      N  NN    T                 %
00010 %               SSSSS  EEEEE  R  R   P      EEEEE  N   N    T                 %
00011 %                                                                             %
00012 %                                                                             %
00013 %                    Wizard's Toolkit Serpent Cipher Methods                  %
00014 %                                                                             %
00015 %                               Software Design                               %
00016 %                                 John Cristy                                 %
00017 %                                 March 2003                                  %
00018 %                                                                             %
00019 %  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization      %
00020 %  dedicated to making software imaging solutions freely available.           %
00021 %                                                                             %
00022 %  You may not use this file except in compliance with the License.  You may  %
00023 %  obtain a copy of the License at                                            %
00024 %                                                                             %
00025 %    http://www.wizards-toolkit.org/script/license.php                        %
00026 %                                                                             %
00027 %  Unless required by applicable law or agreed to in writing, software        %
00028 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00029 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00030 %  See the License for the specific language governing permissions and        %
00031 %  limitations under the License.                                             %
00032 %                                                                             %
00033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00034 %
00035 %
00036 */
00037 
00038 /*
00039   Include declarations.
00040 */
00041 #include "wizard/studio.h"
00042 #include "wizard/exception.h"
00043 #include "wizard/exception-private.h"
00044 #include "wizard/memory_.h"
00045 #include "wizard/serpent.h"
00046 
00047 /*
00048   Typedef declarations.
00049 */
00050 struct _SerpentInfo
00051 {
00052   unsigned int
00053     blocksize,
00054     crypt_key[132];
00055 
00056   time_t
00057     timestamp;
00058 
00059   size_t
00060     signature;
00061 };
00062 
00063 /*
00064   Define declarations.
00065 */
00066 #define Read32Bits(value,p) \
00067 { \
00068   (value)=(*p++); \
00069   (value)|=(*p++) << 8; \
00070   (value)|=(*p++) << 16; \
00071   (value)|=(*p++) << 24; \
00072 }
00073 #define SerpentBlocksize 32
00074 #define Write32Bits(p,value) \
00075 { \
00076   *p++=(unsigned char) (value); \
00077   *p++=(unsigned char) ((value) >> 8); \
00078   *p++=(unsigned char) ((value) >> 16); \
00079   *p++=(unsigned char) ((value) >> 24); \
00080 }
00081 
00082 /*
00083 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00084 %                                                                             %
00085 %                                                                             %
00086 %                                                                             %
00087 %   A c q u i r e S e r p e n t I n f o                                       %
00088 %                                                                             %
00089 %                                                                             %
00090 %                                                                             %
00091 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00092 %
00093 %  AcquireSerpentInfo() allocate the SerpentInfo structure.
00094 %
00095 %  The format of the AcquireSerpentInfo method is:
00096 %
00097 %      SerpentInfo *AcquireSerpentInfo(void)
00098 %
00099 */
00100 WizardExport SerpentInfo *AcquireSerpentInfo(void)
00101 {
00102   SerpentInfo
00103     *serpent_info;
00104 
00105   serpent_info=(SerpentInfo *) AcquireWizardMemory(sizeof(*serpent_info));
00106   if (serpent_info == (SerpentInfo *) NULL)
00107     ThrowWizardFatalError(CipherError,MemoryError);
00108   (void) ResetWizardMemory(serpent_info,0,sizeof(*serpent_info));
00109   serpent_info->blocksize=SerpentBlocksize;
00110   serpent_info->timestamp=time((time_t *) NULL);
00111   serpent_info->signature=WizardSignature;
00112   return(serpent_info);
00113 }
00114 
00115 /*
00116 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00117 %                                                                             %
00118 %                                                                             %
00119 %                                                                             %
00120 %   D e c i p h e r S e r p e n t B l o c k                                   %
00121 %                                                                             %
00122 %                                                                             %
00123 %                                                                             %
00124 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00125 %
00126 %  DecipherSerpentBlock() deciphers a single block of ciphertext to produce a
00127 %  block of plaintext.
00128 %
00129 %  The format of the DecipherSerpentBlock method is:
00130 %
00131 %     void DecipherSerpentBlock(SerpentInfo *serpent_info,
00132 %       const unsigned char *ciphertext,unsigned char plaintext)
00133 %
00134 %  A description of each parameter follows:
00135 %
00136 %    o serpent_info: The cipher context.
00137 %
00138 %    o ciphertext: The cipher text.
00139 %
00140 %    o plaintext: The plaint text.
00141 %
00142 */
00143 
00144 static inline unsigned int Trunc32(unsigned int x)
00145 {
00146   return((unsigned int) (x & 0xffffffffUL));
00147 }
00148 
00149 static inline unsigned int RotateRight(unsigned int x,unsigned int n)
00150 {
00151   return(Trunc32((x >> n) | (x << (32-n))));
00152 }
00153 
00154 WizardExport void DecipherSerpentBlock(SerpentInfo *serpent_info,
00155   const unsigned char *ciphertext,unsigned char *plaintext)
00156 {
00157 #define DecipherSbox0(alpha,beta,gamma,delta,epsilon) \
00158 { \
00159   beta^=alpha; epsilon=delta; delta|=beta; epsilon^=beta; \
00160   alpha=(~alpha); gamma^=delta; delta^=alpha; alpha&=beta; \
00161   alpha^=gamma; gamma&=delta; delta^=epsilon; gamma^=delta; \
00162   beta^=delta; delta&=alpha; beta^=alpha; alpha^=gamma; epsilon^=delta; \
00163 }
00164 #define DecipherSbox1(alpha,beta,gamma,delta,epsilon) \
00165 { \
00166   beta^=delta; epsilon=alpha; alpha^=gamma; gamma=(~gamma); \
00167   epsilon|=beta; epsilon^=delta; delta&=beta; beta^=gamma; \
00168   gamma&=epsilon; epsilon^=beta; beta|=delta; delta^=alpha; \
00169   gamma^=alpha; alpha|=epsilon; gamma^=epsilon; beta^=alpha; epsilon^=beta; \
00170 }
00171 #define DecipherSbox2(alpha,beta,gamma,delta,epsilon) \
00172 { \
00173   gamma^=beta; epsilon=delta; delta=(~delta); delta|=gamma; \
00174   gamma^=epsilon; epsilon^=alpha; delta^=beta; beta|=gamma; \
00175   gamma^=alpha;  beta^=epsilon; epsilon|=delta; gamma^=delta; \
00176   epsilon^=gamma; gamma&=beta; gamma^=delta; delta^=epsilon; epsilon^=alpha; \
00177 }
00178 #define DecipherSbox3(alpha,beta,gamma,delta,epsilon) \
00179 { \
00180   gamma^=beta; epsilon=beta; beta&=gamma; beta^=alpha; \
00181   alpha|=epsilon; epsilon^=delta; alpha^=delta; delta|=beta; \
00182   beta^=gamma; beta^=delta; alpha^=gamma; gamma^=delta; delta&=beta; \
00183   beta^=alpha; alpha&=gamma; epsilon^=delta; delta^=alpha; alpha^=beta; \
00184 }
00185 #define DecipherSbox4(alpha,beta,gamma,delta,epsilon) \
00186 { \
00187   gamma^=delta; epsilon=alpha; alpha&=beta; alpha^=gamma; \
00188   gamma|=delta; epsilon=(~epsilon); beta^=alpha; alpha^=gamma; \
00189   gamma&=epsilon; gamma^=alpha; alpha|=epsilon; alpha^=delta; \
00190   delta&=gamma; epsilon^=delta; delta^=beta; beta&=alpha; \
00191   epsilon^=beta; alpha^=delta; \
00192 }
00193 #define DecipherSbox5(alpha,beta,gamma,delta,epsilon) \
00194 { \
00195   epsilon=beta; beta|=gamma; gamma^=epsilon; beta^=delta; \
00196   delta&=epsilon; gamma^=delta; delta|=alpha; alpha=(~alpha); \
00197   delta^=gamma; gamma|=alpha; epsilon^=beta; gamma^=epsilon; \
00198   epsilon&=alpha; alpha^=beta; beta^=delta; alpha&=gamma; \
00199   gamma^=delta; alpha^=gamma; gamma^=epsilon; epsilon^=delta; \
00200 }
00201 #define DecipherSbox6(alpha,beta,gamma,delta,epsilon) \
00202 { \
00203   alpha^=gamma; epsilon=alpha; alpha&=delta; gamma^=delta; \
00204   alpha^=gamma; delta^=beta; gamma|=epsilon; gamma^=delta; \
00205   delta&=alpha; alpha=(~alpha); delta^=beta; beta&=gamma; \
00206   epsilon^=alpha; delta^=epsilon; epsilon^=gamma; alpha^=beta; gamma^=alpha; \
00207 }
00208 #define DecipherSbox7(alpha,beta,gamma,delta,epsilon) \
00209 { \
00210   epsilon=delta; delta&=alpha; alpha^=gamma; gamma|=epsilon; \
00211   epsilon^=beta; alpha=(~alpha); beta|=delta; epsilon^=alpha; \
00212   alpha&=gamma; alpha^=beta; beta&=gamma; delta^=gamma; \
00213   epsilon^=delta; gamma&=delta; delta|=alpha; beta^=epsilon; \
00214   delta^=epsilon; epsilon&=alpha;  epsilon^=gamma; \
00215 }
00216 #define DecipherK(alpha,beta,gamma,delta,epsilon,i) \
00217 { \
00218   MixKey(alpha,beta,gamma,delta,i) \
00219   alpha=RotateRight(alpha,5); gamma=RotateRight(gamma,22); \
00220   alpha^=delta; gamma^=delta; epsilon=beta << 7; alpha^=beta; \
00221   beta=RotateRight(beta,1); gamma^=epsilon; delta=RotateRight(delta,7); \
00222   epsilon=alpha << 3; beta^=alpha; delta^=epsilon; \
00223   alpha=RotateRight(alpha,13); beta^=gamma; delta^=gamma; \
00224   gamma=RotateRight(gamma,3); \
00225 }
00226 #define MixKey(alpha,beta,gamma,delta,i) \
00227 { \
00228   alpha^=crypt_key[4*(i)+0]; beta^=crypt_key[4*(i)+1]; \
00229   gamma^=crypt_key[4*(i)+2]; delta^=crypt_key[4*(i)+3]; \
00230 }
00231 
00232   register const unsigned char
00233     *p;
00234 
00235   register unsigned char
00236     *q;
00237 
00238   register unsigned int
00239     *crypt_key;
00240 
00241   unsigned int
00242     alpha,
00243     beta,
00244     gamma,
00245     delta,
00246     epsilon;
00247 
00248   /*
00249     Exercise 32 deciphering rounds.
00250   */
00251   p=(const unsigned char *) ciphertext;
00252   Read32Bits(alpha,p);
00253   Read32Bits(beta,p);
00254   Read32Bits(gamma,p);
00255   Read32Bits(delta,p);
00256   crypt_key=serpent_info->crypt_key;
00257   MixKey(alpha,beta,gamma,delta,32);
00258   DecipherSbox7(alpha,beta,gamma,delta,epsilon);
00259   DecipherK(beta,delta,alpha,epsilon,gamma,31);
00260   DecipherSbox6(beta,delta,alpha,epsilon,gamma);
00261   DecipherK(alpha,gamma,epsilon,beta,delta,30);
00262   DecipherSbox5(alpha,gamma,epsilon,beta,delta);
00263   DecipherK(gamma,delta,alpha,epsilon,beta,29);
00264   DecipherSbox4(gamma,delta,alpha,epsilon,beta);
00265   DecipherK(gamma,alpha,beta,epsilon,delta,28);
00266   DecipherSbox3(gamma,alpha,beta,epsilon,delta);
00267   DecipherK(beta,gamma,delta,epsilon,alpha,27);
00268   DecipherSbox2(beta,gamma,delta,epsilon,alpha);
00269   DecipherK(gamma,alpha,epsilon,delta,beta,26);
00270   DecipherSbox1(gamma,alpha,epsilon,delta,beta);
00271   DecipherK(beta,alpha,epsilon,delta,gamma,25);
00272   DecipherSbox0(beta,alpha,epsilon,delta,gamma);
00273   DecipherK(epsilon,gamma,alpha,beta,delta,24);
00274   DecipherSbox7(epsilon,gamma,alpha,beta,delta);
00275   DecipherK(gamma,beta,epsilon,delta,alpha,23);
00276   DecipherSbox6(gamma,beta,epsilon,delta,alpha);
00277   DecipherK(epsilon,alpha,delta,gamma,beta,22);
00278   DecipherSbox5(epsilon,alpha,delta,gamma,beta);
00279   DecipherK(alpha,beta,epsilon,delta,gamma,21);
00280   DecipherSbox4(alpha,beta,epsilon,delta,gamma);
00281   DecipherK(alpha,epsilon,gamma,delta,beta,20);
00282   DecipherSbox3(alpha,epsilon,gamma,delta,beta);
00283   DecipherK(gamma,alpha,beta,delta,epsilon,19);
00284   DecipherSbox2(gamma,alpha,beta,delta,epsilon);
00285   DecipherK(alpha,epsilon,delta,beta,gamma,18);
00286   DecipherSbox1(alpha,epsilon,delta,beta,gamma);
00287   DecipherK(gamma,epsilon,delta,beta,alpha,17);
00288   DecipherSbox0(gamma,epsilon,delta,beta,alpha);
00289   DecipherK(delta,alpha,epsilon,gamma,beta,16);
00290   DecipherSbox7(delta,alpha,epsilon,gamma,beta);
00291   DecipherK(alpha,gamma,delta,beta,epsilon,15);
00292   DecipherSbox6(alpha,gamma,delta,beta,epsilon);
00293   DecipherK(delta,epsilon,beta,alpha,gamma,14);
00294   DecipherSbox5(delta,epsilon,beta,alpha,gamma);
00295   DecipherK(epsilon,gamma,delta,beta,alpha,13);
00296   DecipherSbox4(epsilon,gamma,delta,beta,alpha);
00297   DecipherK(epsilon,delta,alpha,beta,gamma,12);
00298   DecipherSbox3(epsilon,delta,alpha,beta,gamma);
00299   DecipherK(alpha,epsilon,gamma,beta,delta,11);
00300   DecipherSbox2(alpha,epsilon,gamma,beta,delta);
00301   DecipherK(epsilon,delta,beta,gamma,alpha,10);
00302   DecipherSbox1(epsilon,delta,beta,gamma,alpha);
00303   DecipherK(alpha,delta,beta,gamma,epsilon,9);
00304   DecipherSbox0(alpha,delta,beta,gamma,epsilon);
00305   DecipherK(beta,epsilon,delta,alpha,gamma,8);
00306   DecipherSbox7(beta,epsilon,delta,alpha,gamma);
00307   DecipherK(epsilon,alpha,beta,gamma,delta,7);
00308   DecipherSbox6(epsilon,alpha,beta,gamma,delta);
00309   DecipherK(beta,delta,gamma,epsilon,alpha,6);
00310   DecipherSbox5(beta,delta,gamma,epsilon,alpha);
00311   DecipherK(delta,alpha,beta,gamma,epsilon,5);
00312   DecipherSbox4(delta,alpha,beta,gamma,epsilon);
00313   DecipherK(delta,beta,epsilon,gamma,alpha,4);
00314   DecipherSbox3(delta,beta,epsilon,gamma,alpha);
00315   DecipherK(epsilon,delta,alpha,gamma,beta,3);
00316   DecipherSbox2(epsilon,delta,alpha,gamma,beta);
00317   DecipherK(delta,beta,gamma,alpha,epsilon,2);
00318   DecipherSbox1(delta,beta,gamma,alpha,epsilon);
00319   DecipherK(epsilon,beta,gamma,alpha,delta,1);
00320   DecipherSbox0(epsilon,beta,gamma,alpha,delta);
00321   MixKey(gamma,delta,beta,epsilon,0);
00322   q=(unsigned char *) plaintext;
00323   Write32Bits(q,gamma);
00324   Write32Bits(q,delta);
00325   Write32Bits(q,beta);
00326   Write32Bits(q,epsilon);
00327   /*
00328     Reset registers.
00329   */
00330   alpha=0;
00331   beta=0;
00332   gamma=0;
00333   delta=0;
00334   epsilon=0;
00335 }
00336 
00337 /*
00338 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00339 %                                                                             %
00340 %                                                                             %
00341 %                                                                             %
00342 %   D e s t r o y S e r p e n t I n f o                                       %
00343 %                                                                             %
00344 %                                                                             %
00345 %                                                                             %
00346 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00347 %
00348 %  DestroySerpentInfo() zeros memory associated with the SerpentInfo structure.
00349 %
00350 %  The format of the DestroySerpentInfo method is:
00351 %
00352 %      SerpentInfo *DestroySerpentInfo(SerpentInfo *serpent_info)
00353 %
00354 %  A description of each parameter follows:
00355 %
00356 %    o serpent_info: The cipher context.
00357 %
00358 */
00359 WizardExport SerpentInfo *DestroySerpentInfo(SerpentInfo *serpent_info)
00360 {
00361   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00362   WizardAssert(CipherDomain,serpent_info != (SerpentInfo *) NULL);
00363   WizardAssert(CipherDomain,serpent_info->signature == WizardSignature);
00364   serpent_info->signature=(~WizardSignature);
00365   serpent_info=(SerpentInfo *) RelinquishWizardMemory(serpent_info);
00366   return(serpent_info);
00367 }
00368 
00369 /*
00370 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00371 %                                                                             %
00372 %                                                                             %
00373 %                                                                             %
00374 %   E n c i p h e r S e r p e n t B l o c k                                   %
00375 %                                                                             %
00376 %                                                                             %
00377 %                                                                             %
00378 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00379 %
00380 %  EncipherSerpentBlock() enciphers a single block of plaintext to produce a
00381 %  block of ciphertext.
00382 %
00383 %  The format of the EncipherSerpentBlock method is:
00384 %
00385 %      void EncipherSerpentBlock(SerpentInfo *serpent_info,
00386 %        const unsigned char *plaintext,unsigned char ciphertext)
00387 %
00388 %  A description of each parameter follows:
00389 %
00390 %    o serpent_info: The cipher context.
00391 %
00392 %    o plaintext: The plain text.
00393 %
00394 %    o ciphertext: The cipher text.
00395 %
00396 */
00397 
00398 static inline unsigned int RotateLeft(unsigned int x,unsigned int n)
00399 {
00400   return(Trunc32((x << n) | (x >> (32-n))));
00401 }
00402 
00403 WizardExport void EncipherSerpentBlock(SerpentInfo *serpent_info,
00404   const unsigned char *plaintext,unsigned char *ciphertext)
00405 {
00406 #define EncipherK(alpha,beta,gamma,delta,epsilon,i) \
00407 { \
00408   alpha=RotateLeft(alpha,13); gamma=RotateLeft(gamma,3); \
00409   beta^=alpha; epsilon=alpha << 3; delta^=gamma; beta^=gamma; \
00410   beta=RotateLeft(beta,1); delta^=epsilon; delta=RotateLeft(delta,7); \
00411   epsilon=beta << 7; alpha^=beta; gamma^=delta; alpha^=delta; \
00412   gamma^=epsilon; delta^=crypt_key[4*(i)+3]; beta^=crypt_key[4*(i)+1]; \
00413   alpha=RotateLeft(alpha,5); gamma=RotateLeft(gamma,22); \
00414   alpha^=crypt_key[4*(i)+0]; gamma^=crypt_key[4*(i)+2]; \
00415 }
00416 #define EncipherSbox0(alpha,beta,gamma,delta,epsilon) \
00417 { \
00418   epsilon=delta; delta|=alpha; alpha^=epsilon; epsilon^=gamma; \
00419   epsilon=(~epsilon); delta^=beta; beta&=alpha; beta^=epsilon; \
00420   gamma^=alpha; alpha^=delta; epsilon|=alpha; alpha^=gamma; \
00421   gamma&=beta; delta^=gamma; beta=(~beta); gamma^=epsilon; beta^=gamma; \
00422 }
00423 #define EncipherSbox1(alpha,beta,gamma,delta,epsilon) \
00424 { \
00425   epsilon=beta; beta^=alpha; alpha^=delta; delta=~delta; \
00426   epsilon&=beta; alpha|=beta; delta^=gamma; alpha^=delta; \
00427   beta^=delta; delta^=epsilon; beta|=epsilon; epsilon^=gamma; \
00428   gamma&=alpha; gamma^=beta; beta|=alpha; alpha=(~alpha); \
00429   alpha^=gamma; epsilon^=beta; \
00430 }
00431 #define EncipherSbox2(alpha,beta,gamma,delta,epsilon) \
00432 { \
00433   delta=(~delta); beta^=alpha; epsilon=alpha; alpha&=gamma; \
00434   alpha^=delta; delta|=epsilon; gamma^=beta; delta^=beta; \
00435   beta&=alpha; alpha^=gamma; gamma&=delta; delta|=beta; \
00436   alpha=(~alpha); delta^=alpha; epsilon^=alpha; alpha^=gamma; beta|=gamma; \
00437 }
00438 #define EncipherSbox3(alpha,beta,gamma,delta,epsilon) \
00439 { \
00440   epsilon=beta; beta^=delta; delta|=alpha; epsilon&=alpha; \
00441   alpha^=gamma; gamma^=beta; beta&=delta; gamma^=delta; \
00442   alpha|=epsilon; epsilon^=delta; beta^=alpha; alpha&=delta; \
00443   delta&=epsilon; delta^=gamma; epsilon|=beta; gamma&=beta; \
00444   epsilon^=delta; alpha^=delta; delta^=gamma; \
00445 }
00446 #define EncipherSbox4(alpha,beta,gamma,delta,epsilon) \
00447 { \
00448   epsilon=delta; delta&=alpha; alpha^=epsilon; delta^=gamma; \
00449   gamma|=epsilon; alpha^=beta; epsilon^=delta; gamma|=alpha; \
00450   gamma^=beta; beta&=alpha; beta^=epsilon; epsilon&=gamma; \
00451   gamma^=delta; epsilon^=alpha; delta|=beta; beta=(~beta); delta^=alpha; \
00452 }
00453 #define EncipherSbox5(alpha,beta,gamma,delta,epsilon) \
00454 { \
00455   epsilon=beta;  beta|=alpha; gamma^=beta; delta=(~delta); \
00456   epsilon^=alpha; alpha^=gamma; beta&=epsilon; epsilon|=delta; \
00457   epsilon^=alpha; alpha&=delta; beta^=delta; delta^=gamma; \
00458   alpha^=beta; gamma&=epsilon; beta^=gamma; gamma&=alpha; delta^=gamma; \
00459 }
00460 #define EncipherSbox6(alpha,beta,gamma,delta,epsilon) \
00461 { \
00462   epsilon=beta;  delta^=alpha;  beta^=gamma;  gamma^=alpha; \
00463   alpha&=delta; beta|=delta; epsilon=(~epsilon); alpha^=beta; \
00464   beta^=gamma; delta^=epsilon; epsilon^=alpha; gamma&=alpha; \
00465   epsilon^=beta; gamma^=delta; delta&=beta; delta^=alpha; beta^=gamma; \
00466 }
00467 #define EncipherSbox7(alpha,beta,gamma,delta,epsilon) \
00468 { \
00469   beta=(~beta); epsilon=beta; alpha=(~alpha); beta&=gamma; \
00470   beta^=delta; delta|=epsilon; epsilon^=gamma; gamma^=delta; \
00471   delta^=alpha; alpha|=beta;  gamma&=alpha; alpha^=epsilon; \
00472   epsilon^=delta; delta&=alpha; epsilon^=beta; gamma^=epsilon; \
00473   delta^=beta; epsilon|=alpha; epsilon^=beta; \
00474 }
00475 
00476   register const unsigned char
00477     *p;
00478 
00479   register unsigned char
00480     *q;
00481 
00482   register unsigned int
00483     *crypt_key;
00484 
00485   unsigned int
00486     alpha,
00487     beta,
00488     gamma,
00489     delta,
00490     epsilon;
00491 
00492   /*
00493     Exercise 32 enciphering rounds.
00494   */
00495   p=(const unsigned char *) plaintext;
00496   Read32Bits(alpha,p);
00497   Read32Bits(beta,p);
00498   Read32Bits(gamma,p);
00499   Read32Bits(delta,p);
00500   crypt_key=serpent_info->crypt_key;
00501   MixKey(alpha,beta,gamma,delta,0);
00502   EncipherSbox0(alpha,beta,gamma,delta,epsilon);
00503   EncipherK(gamma,beta,delta,alpha,epsilon,1);
00504   EncipherSbox1(gamma,beta,delta,alpha,epsilon);
00505   EncipherK(epsilon,delta,alpha,gamma,beta,2);
00506   EncipherSbox2(epsilon,delta,alpha,gamma,beta);
00507   EncipherK(beta,delta,epsilon,gamma,alpha,3);
00508   EncipherSbox3(beta,delta,epsilon,gamma,alpha);
00509   EncipherK(gamma,alpha,delta,beta,epsilon,4);
00510   EncipherSbox4(gamma,alpha,delta,beta,epsilon);
00511   EncipherK(alpha,delta,beta,epsilon,gamma,5);
00512   EncipherSbox5(alpha,delta,beta,epsilon,gamma);
00513   EncipherK(gamma,alpha,delta,epsilon,beta,6);
00514   EncipherSbox6(gamma,alpha,delta,epsilon,beta);
00515   EncipherK(delta,beta,alpha,epsilon,gamma,7);
00516   EncipherSbox7(delta,beta,alpha,epsilon,gamma);
00517   EncipherK(gamma,alpha,epsilon,delta,beta,8);
00518   EncipherSbox0(gamma,alpha,epsilon,delta,beta);
00519   EncipherK(epsilon,alpha,delta,gamma,beta,9);
00520   EncipherSbox1(epsilon,alpha,delta,gamma,beta);
00521   EncipherK(beta,delta,gamma,epsilon,alpha,10);
00522   EncipherSbox2(beta,delta,gamma,epsilon,alpha);
00523   EncipherK(alpha,delta,beta,epsilon,gamma,11);
00524   EncipherSbox3(alpha,delta,beta,epsilon,gamma);
00525   EncipherK(epsilon,gamma,delta,alpha,beta,12);
00526   EncipherSbox4(epsilon,gamma,delta,alpha,beta);
00527   EncipherK(gamma,delta,alpha,beta,epsilon,13);
00528   EncipherSbox5(gamma,delta,alpha,beta,epsilon);
00529   EncipherK(epsilon,gamma,delta,beta,alpha,14);
00530   EncipherSbox6(epsilon,gamma,delta,beta,alpha);
00531   EncipherK(delta,alpha,gamma,beta,epsilon,15);
00532   EncipherSbox7(delta,alpha,gamma,beta,epsilon);
00533   EncipherK(epsilon,gamma,beta,delta,alpha,16);
00534   EncipherSbox0(epsilon,gamma,beta,delta,alpha);
00535   EncipherK(beta,gamma,delta,epsilon,alpha,17);
00536   EncipherSbox1(beta,gamma,delta,epsilon,alpha);
00537   EncipherK(alpha,delta,epsilon,beta,gamma,18);
00538   EncipherSbox2(alpha,delta,epsilon,beta,gamma);
00539   EncipherK(gamma,delta,alpha,beta,epsilon,19);
00540   EncipherSbox3(gamma,delta,alpha,beta,epsilon);
00541   EncipherK(beta,epsilon,delta,gamma,alpha,20);
00542   EncipherSbox4(beta,epsilon,delta,gamma,alpha);
00543   EncipherK(epsilon,delta,gamma,alpha,beta,21);
00544   EncipherSbox5(epsilon,delta,gamma,alpha,beta);
00545   EncipherK(beta,epsilon,delta,alpha,gamma,22);
00546   EncipherSbox6(beta,epsilon,delta,alpha,gamma);
00547   EncipherK(delta,gamma,epsilon,alpha,beta,23);
00548   EncipherSbox7(delta,gamma,epsilon,alpha,beta);
00549   EncipherK(beta,epsilon,alpha,delta,gamma,24);
00550   EncipherSbox0(beta,epsilon,alpha,delta,gamma);
00551   EncipherK(alpha,epsilon,delta,beta,gamma,25);
00552   EncipherSbox1(alpha,epsilon,delta,beta,gamma);
00553   EncipherK(gamma,delta,beta,alpha,epsilon,26);
00554   EncipherSbox2(gamma,delta,beta,alpha,epsilon);
00555   EncipherK(epsilon,delta,gamma,alpha,beta,27);
00556   EncipherSbox3(epsilon,delta,gamma,alpha,beta);
00557   EncipherK(alpha,beta,delta,epsilon,gamma,28);
00558   EncipherSbox4(alpha,beta,delta,epsilon,gamma);
00559   EncipherK(beta,delta,epsilon,gamma,alpha,29);
00560   EncipherSbox5(beta,delta,epsilon,gamma,alpha);
00561   EncipherK(alpha,beta,delta,gamma,epsilon,30);
00562   EncipherSbox6(alpha,beta,delta,gamma,epsilon);
00563   EncipherK(delta,epsilon,beta,gamma,alpha,31);
00564   EncipherSbox7(delta,epsilon,beta,gamma,alpha);
00565   MixKey(alpha,beta,gamma,delta,32);
00566   q=(unsigned char * ) ciphertext;
00567   Write32Bits(q,alpha);
00568   Write32Bits(q,beta);
00569   Write32Bits(q,gamma);
00570   Write32Bits(q,delta);
00571   /*
00572     Reset registers.
00573   */
00574   alpha=0;
00575   beta=0;
00576   gamma=0;
00577   delta=0;
00578   epsilon=0;
00579 }
00580 
00581 /*
00582 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00583 %                                                                             %
00584 %                                                                             %
00585 %                                                                             %
00586 %   G e t S e r p e n t B l o c k s i z e                                     %
00587 %                                                                             %
00588 %                                                                             %
00589 %                                                                             %
00590 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00591 %
00592 %  GetSerpentBlocksize() returns the Serpent blocksize.
00593 %
00594 %  The format of the GetSerpentBlocksize method is:
00595 %
00596 %      unsigned int *GetSerpentBlocksize(const SerpentInfo *serpent_info)
00597 %
00598 %  A description of each parameter follows:
00599 %
00600 %    o serpent_info: The serpent info.
00601 %
00602 */
00603 WizardExport unsigned int GetSerpentBlocksize(const SerpentInfo *serpent_info)
00604 {
00605   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00606   WizardAssert(CipherDomain,serpent_info != (SerpentInfo *) NULL);
00607   WizardAssert(CipherDomain,serpent_info->signature == WizardSignature);
00608   return(serpent_info->blocksize);
00609 }
00610 
00611 /*
00612 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00613 %                                                                             %
00614 %                                                                             %
00615 %                                                                             %
00616 %   S e t S e r p e n t K e y                                                 %
00617 %                                                                             %
00618 %                                                                             %
00619 %                                                                             %
00620 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00621 %
00622 %  SetSerpentKey() sets the key for the Serpent cipher.  The key length is
00623 %  specified in bits.  Valid values are 128,192,or 256 requiring a key
00624 %  buffer length in bytes of 16,24,and 32 respectively.
00625 %
00626 %  The format of the SetSerpentKey method is:
00627 %
00628 %      SetSerpentKey(SerpentInfo *serpent_info,const StringInfo *key)
00629 %
00630 %  A description of each parameter follows:
00631 %
00632 %    o serpent_info: The cipher context.
00633 %
00634 %    o key: The key.
00635 %
00636 */
00637 WizardExport void SetSerpentKey(SerpentInfo *serpent_info,const StringInfo *key)
00638 {
00639 #define ChurnKey(alpha,beta,gamma,delta,i,j) \
00640 { \
00641   beta^=delta; beta^=gamma; beta^=alpha; beta^=0x9e3779b9UL ^ i; \
00642   beta=RotateLeft(beta,11); crypt_key[j]=beta; \
00643 }
00644 #define LoadKey(alpha,beta,gamma,delta,i) \
00645 { \
00646   alpha=crypt_key[i]; beta=crypt_key[(i)+1]; \
00647   gamma=crypt_key[(i)+2]; delta=crypt_key[(i)+3]; \
00648 }
00649 #define MaximumSerpentKeyLength  32
00650 #define StoreKey(alpha,beta,gamma,delta,i) \
00651 { \
00652   crypt_key[i]=alpha; crypt_key[(i)+1]=beta; \
00653   crypt_key[(i)+2]=gamma; crypt_key[(i)+3]=delta; \
00654 }
00655 
00656   register size_t
00657     i;
00658 
00659   register unsigned char
00660     *p;
00661 
00662   register unsigned int
00663     *crypt_key;
00664 
00665   unsigned char
00666     *datum;
00667 
00668   unsigned int
00669     alpha,
00670     beta,
00671     gamma,
00672     delta,
00673     epsilon,
00674     rho;
00675 
00676   /*
00677     Generate crypt key.
00678   */
00679   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00680   WizardAssert(CipherDomain,serpent_info != (SerpentInfo *) NULL);
00681   WizardAssert(CipherDomain,serpent_info->signature == WizardSignature);
00682   WizardAssert(CipherDomain,key != (StringInfo *) NULL);
00683   crypt_key=serpent_info->crypt_key;
00684   p=(unsigned char *) crypt_key;
00685   datum=GetStringInfoDatum(key);
00686   for (i=0; i < Min(GetStringInfoLength(key),MaximumSerpentKeyLength); i++)
00687     p[i]=datum[i];
00688   if (i < MaximumSerpentKeyLength)
00689     p[i++]=1;
00690   while (i < MaximumSerpentKeyLength)
00691     p[i++]=0;
00692   p=(unsigned char *) crypt_key;
00693   p+=12;
00694   Read32Bits(alpha,p);
00695   Read32Bits(beta,p);
00696   Read32Bits(gamma,p);
00697   Read32Bits(delta,p);
00698   Read32Bits(epsilon,p);
00699   p=(unsigned char *) crypt_key;
00700   Read32Bits(rho,p);
00701   ChurnKey(rho,alpha,epsilon,gamma,0,0);
00702   Read32Bits(rho,p);
00703   ChurnKey(rho,beta,alpha,delta,1,1);
00704   Read32Bits(rho,p);
00705   ChurnKey(rho,gamma,beta,epsilon,2,2);
00706   Read32Bits(rho,p);
00707   ChurnKey(rho,delta,gamma,alpha,3,3);
00708   Read32Bits(rho,p);
00709   ChurnKey(rho,epsilon,delta,beta,4,4);
00710   Read32Bits(rho,p);
00711   ChurnKey(rho,alpha,epsilon,gamma,5,5);
00712   Read32Bits(rho,p);
00713   ChurnKey(rho,beta,alpha,delta,6,6);
00714   Read32Bits(rho,p);
00715   ChurnKey(rho,gamma,beta,epsilon,7,7);
00716   ChurnKey(crypt_key[0],delta,gamma,alpha,8,8);
00717   ChurnKey(crypt_key[1],epsilon,delta,beta,9,9);
00718   ChurnKey(crypt_key[2],alpha,epsilon,gamma,10,10);
00719   ChurnKey(crypt_key[3],beta,alpha,delta,11,11);
00720   ChurnKey(crypt_key[4],gamma,beta,epsilon,12,12);
00721   ChurnKey(crypt_key[5],delta,gamma,alpha,13,13);
00722   ChurnKey(crypt_key[6],epsilon,delta,beta,14,14);
00723   ChurnKey(crypt_key[7],alpha,epsilon,gamma,15,15);
00724   ChurnKey(crypt_key[8],beta,alpha,delta,16,16);
00725   ChurnKey(crypt_key[9],gamma,beta,epsilon,17,17);
00726   ChurnKey(crypt_key[10],delta,gamma,alpha,18,18);
00727   ChurnKey(crypt_key[11],epsilon,delta,beta,19,19);
00728   ChurnKey(crypt_key[12],alpha,epsilon,gamma,20,20);
00729   ChurnKey(crypt_key[13],beta,alpha,delta,21,21);
00730   ChurnKey(crypt_key[14],gamma,beta,epsilon,22,22);
00731   ChurnKey(crypt_key[15],delta,gamma,alpha,23,23);
00732   ChurnKey(crypt_key[16],epsilon,delta,beta,24,24);
00733   ChurnKey(crypt_key[17],alpha,epsilon,gamma,25,25);
00734   ChurnKey(crypt_key[18],beta,alpha,delta,26,26);
00735   ChurnKey(crypt_key[19],gamma,beta,epsilon,27,27);
00736   ChurnKey(crypt_key[20],delta,gamma,alpha,28,28);
00737   ChurnKey(crypt_key[21],epsilon,delta,beta,29,29);
00738   ChurnKey(crypt_key[22],alpha,epsilon,gamma,30,30);
00739   ChurnKey(crypt_key[23],beta,alpha,delta,31,31);
00740   crypt_key+=50;
00741   ChurnKey(crypt_key[-26],gamma,beta,epsilon,32,-18);
00742   ChurnKey(crypt_key[-25],delta,gamma,alpha,33,-17);
00743   ChurnKey(crypt_key[-24],epsilon,delta,beta,34,-16);
00744   ChurnKey(crypt_key[-23],alpha,epsilon,gamma,35,-15);
00745   ChurnKey(crypt_key[-22],beta,alpha,delta,36,-14);
00746   ChurnKey(crypt_key[-21],gamma,beta,epsilon,37,-13);
00747   ChurnKey(crypt_key[-20],delta,gamma,alpha,38,-12);
00748   ChurnKey(crypt_key[-19],epsilon,delta,beta,39,-11);
00749   ChurnKey(crypt_key[-18],alpha,epsilon,gamma,40,-10);
00750   ChurnKey(crypt_key[-17],beta,alpha,delta,41,-9);
00751   ChurnKey(crypt_key[-16],gamma,beta,epsilon,42,-8);
00752   ChurnKey(crypt_key[-15],delta,gamma,alpha,43,-7);
00753   ChurnKey(crypt_key[-14],epsilon,delta,beta,44,-6);
00754   ChurnKey(crypt_key[-13],alpha,epsilon,gamma,45,-5);
00755   ChurnKey(crypt_key[-12],beta,alpha,delta,46,-4);
00756   ChurnKey(crypt_key[-11],gamma,beta,epsilon,47,-3);
00757   ChurnKey(crypt_key[-10],delta,gamma,alpha,48,-2);
00758   ChurnKey(crypt_key[-9],epsilon,delta,beta,49,-1);
00759   ChurnKey(crypt_key[-8],alpha,epsilon,gamma,50,0);
00760   ChurnKey(crypt_key[-7],beta,alpha,delta,51,1);
00761   ChurnKey(crypt_key[-6],gamma,beta,epsilon,52,2);
00762   ChurnKey(crypt_key[-5],delta,gamma,alpha,53,3);
00763   ChurnKey(crypt_key[-4],epsilon,delta,beta,54,4);
00764   ChurnKey(crypt_key[-3],alpha,epsilon,gamma,55,5);
00765   ChurnKey(crypt_key[-2],beta,alpha,delta,56,6);
00766   ChurnKey(crypt_key[-1],gamma,beta,epsilon,57,7);
00767   ChurnKey(crypt_key[0],delta,gamma,alpha,58,8);
00768   ChurnKey(crypt_key[1],epsilon,delta,beta,59,9);
00769   ChurnKey(crypt_key[2],alpha,epsilon,gamma,60,10);
00770   ChurnKey(crypt_key[3],beta,alpha,delta,61,11);
00771   ChurnKey(crypt_key[4],gamma,beta,epsilon,62,12);
00772   ChurnKey(crypt_key[5],delta,gamma,alpha,63,13);
00773   ChurnKey(crypt_key[6],epsilon,delta,beta,64,14);
00774   ChurnKey(crypt_key[7],alpha,epsilon,gamma,65,15);
00775   ChurnKey(crypt_key[8],beta,alpha,delta,66,16);
00776   ChurnKey(crypt_key[9],gamma,beta,epsilon,67,17);
00777   ChurnKey(crypt_key[10],delta,gamma,alpha,68,18);
00778   ChurnKey(crypt_key[11],epsilon,delta,beta,69,19);
00779   ChurnKey(crypt_key[12],alpha,epsilon,gamma,70,20);
00780   ChurnKey(crypt_key[13],beta,alpha,delta,71,21);
00781   ChurnKey(crypt_key[14],gamma,beta,epsilon,72,22);
00782   ChurnKey(crypt_key[15],delta,gamma,alpha,73,23);
00783   ChurnKey(crypt_key[16],epsilon,delta,beta,74,24);
00784   ChurnKey(crypt_key[17],alpha,epsilon,gamma,75,25);
00785   ChurnKey(crypt_key[18],beta,alpha,delta,76,26);
00786   ChurnKey(crypt_key[19],gamma,beta,epsilon,77,27);
00787   ChurnKey(crypt_key[20],delta,gamma,alpha,78,28);
00788   ChurnKey(crypt_key[21],epsilon,delta,beta,79,29);
00789   ChurnKey(crypt_key[22],alpha,epsilon,gamma,80,30);
00790   ChurnKey(crypt_key[23],beta,alpha,delta,81,31);
00791   crypt_key+=50;
00792   ChurnKey(crypt_key[-26],gamma,beta,epsilon,82,-18);
00793   ChurnKey(crypt_key[-25],delta,gamma,alpha,83,-17);
00794   ChurnKey(crypt_key[-24],epsilon,delta,beta,84,-16);
00795   ChurnKey(crypt_key[-23],alpha,epsilon,gamma,85,-15);
00796   ChurnKey(crypt_key[-22],beta,alpha,delta,86,-14);
00797   ChurnKey(crypt_key[-21],gamma,beta,epsilon,87,-13);
00798   ChurnKey(crypt_key[-20],delta,gamma,alpha,88,-12);
00799   ChurnKey(crypt_key[-19],epsilon,delta,beta,89,-11);
00800   ChurnKey(crypt_key[-18],alpha,epsilon,gamma,90,-10);
00801   ChurnKey(crypt_key[-17],beta,alpha,delta,91,-9);
00802   ChurnKey(crypt_key[-16],gamma,beta,epsilon,92,-8);
00803   ChurnKey(crypt_key[-15],delta,gamma,alpha,93,-7);
00804   ChurnKey(crypt_key[-14],epsilon,delta,beta,94,-6);
00805   ChurnKey(crypt_key[-13],alpha,epsilon,gamma,95,-5);
00806   ChurnKey(crypt_key[-12],beta,alpha,delta,96,-4);
00807   ChurnKey(crypt_key[-11],gamma,beta,epsilon,97,-3);
00808   ChurnKey(crypt_key[-10],delta,gamma,alpha,98,-2);
00809   ChurnKey(crypt_key[-9],epsilon,delta,beta,99,-1);
00810   ChurnKey(crypt_key[-8],alpha,epsilon,gamma,100,0);
00811   ChurnKey(crypt_key[-7],beta,alpha,delta,101,1);
00812   ChurnKey(crypt_key[-6],gamma,beta,epsilon,102,2);
00813   ChurnKey(crypt_key[-5],delta,gamma,alpha,103,3);
00814   ChurnKey(crypt_key[-4],epsilon,delta,beta,104,4);
00815   ChurnKey(crypt_key[-3],alpha,epsilon,gamma,105,5);
00816   ChurnKey(crypt_key[-2],beta,alpha,delta,106,6);
00817   ChurnKey(crypt_key[-1],gamma,beta,epsilon,107,7);
00818   ChurnKey(crypt_key[0],delta,gamma,alpha,108,8);
00819   ChurnKey(crypt_key[1],epsilon,delta,beta,109,9);
00820   ChurnKey(crypt_key[2],alpha,epsilon,gamma,110,10);
00821   ChurnKey(crypt_key[3],beta,alpha,delta,111,11);
00822   ChurnKey(crypt_key[4],gamma,beta,epsilon,112,12);
00823   ChurnKey(crypt_key[5],delta,gamma,alpha,113,13);
00824   ChurnKey(crypt_key[6],epsilon,delta,beta,114,14);
00825   ChurnKey(crypt_key[7],alpha,epsilon,gamma,115,15);
00826   ChurnKey(crypt_key[8],beta,alpha,delta,116,16);
00827   ChurnKey(crypt_key[9],gamma,beta,epsilon,117,17);
00828   ChurnKey(crypt_key[10],delta,gamma,alpha,118,18);
00829   ChurnKey(crypt_key[11],epsilon,delta,beta,119,19);
00830   ChurnKey(crypt_key[12],alpha,epsilon,gamma,120,20);
00831   ChurnKey(crypt_key[13],beta,alpha,delta,121,21);
00832   ChurnKey(crypt_key[14],gamma,beta,epsilon,122,22);
00833   ChurnKey(crypt_key[15],delta,gamma,alpha,123,23);
00834   ChurnKey(crypt_key[16],epsilon,delta,beta,124,24);
00835   ChurnKey(crypt_key[17],alpha,epsilon,gamma,125,25);
00836   ChurnKey(crypt_key[18],beta,alpha,delta,126,26);
00837   ChurnKey(crypt_key[19],gamma,beta,epsilon,127,27);
00838   ChurnKey(crypt_key[20],delta,gamma,alpha,128,28);
00839   ChurnKey(crypt_key[21],epsilon,delta,beta,129,29);
00840   ChurnKey(crypt_key[22],alpha,epsilon,gamma,130,30);
00841   ChurnKey(crypt_key[23],beta,alpha,delta,131,31);
00842   /*
00843     Apply S-boxes.
00844   */
00845   EncipherSbox3(delta,epsilon,alpha,beta,gamma);
00846   StoreKey(beta,gamma,epsilon,delta,28);
00847   LoadKey(beta,gamma,epsilon,delta,24);
00848   EncipherSbox4(beta,gamma,epsilon,delta,alpha);
00849   StoreKey(gamma,epsilon,delta,alpha,24);
00850   LoadKey(gamma,epsilon,delta,alpha,20);
00851   EncipherSbox5(gamma,epsilon,delta,alpha,beta);
00852   StoreKey(beta,gamma,epsilon,alpha,20);
00853   LoadKey(beta,gamma,epsilon,alpha,16);
00854   EncipherSbox6(beta,gamma,epsilon,alpha,delta);
00855   StoreKey(epsilon,delta,gamma,alpha,16);
00856   LoadKey(epsilon,delta,gamma,alpha,12);
00857   EncipherSbox7(epsilon,delta,gamma,alpha,beta);
00858   StoreKey(beta,gamma,alpha,epsilon,12);
00859   LoadKey(beta,gamma,alpha,epsilon,8);
00860   EncipherSbox0(beta,gamma,alpha,epsilon,delta);
00861   StoreKey(alpha,gamma,epsilon,beta,8);
00862   LoadKey(alpha,gamma,epsilon,beta,4);
00863   EncipherSbox1(alpha,gamma,epsilon,beta,delta);
00864   StoreKey(delta,epsilon,beta,alpha,4);
00865   LoadKey(delta,epsilon,beta,alpha,0);
00866   EncipherSbox2(delta,epsilon,beta,alpha,gamma);
00867   StoreKey(gamma,epsilon,delta,alpha,0);
00868   LoadKey(gamma,epsilon,delta,alpha,-4);
00869   EncipherSbox3(gamma,epsilon,delta,alpha,beta);
00870   StoreKey(alpha,beta,epsilon,gamma,-4);
00871   LoadKey(alpha,beta,epsilon,gamma,-8);
00872   EncipherSbox4(alpha,beta,epsilon,gamma,delta);
00873   StoreKey(beta,epsilon,gamma,delta,-8);
00874   LoadKey(beta,epsilon,gamma,delta,-12);
00875   EncipherSbox5(beta,epsilon,gamma,delta,alpha);
00876   StoreKey(alpha,beta,epsilon,delta,-12);
00877   LoadKey(alpha,beta,epsilon,delta,-16);
00878   EncipherSbox6(alpha,beta,epsilon,delta,gamma);
00879   StoreKey(epsilon,gamma,beta,delta,-16);
00880   LoadKey(epsilon,gamma,beta,delta,-20);
00881   EncipherSbox7(epsilon,gamma,beta,delta,alpha);
00882   StoreKey(alpha,beta,delta,epsilon,-20);
00883   LoadKey(alpha,beta,delta,epsilon,-24);
00884   EncipherSbox0(alpha,beta,delta,epsilon,gamma);
00885   StoreKey(delta,beta,epsilon,alpha,-24);
00886   LoadKey(delta,beta,epsilon,alpha,-28);
00887   crypt_key-=50;
00888   EncipherSbox1(delta,beta,epsilon,alpha,gamma);
00889   StoreKey(gamma,epsilon,alpha,delta,22);
00890   LoadKey(gamma,epsilon,alpha,delta,18);
00891   EncipherSbox2(gamma,epsilon,alpha,delta,beta);
00892   StoreKey(beta,epsilon,gamma,delta,18);
00893   LoadKey(beta,epsilon,gamma,delta,14);
00894   EncipherSbox3(beta,epsilon,gamma,delta,alpha);
00895   StoreKey(delta,alpha,epsilon,beta,14);
00896   LoadKey(delta,alpha,epsilon,beta,10);
00897   EncipherSbox4(delta,alpha,epsilon,beta,gamma);
00898   StoreKey(alpha,epsilon,beta,gamma,10);
00899   LoadKey(alpha,epsilon,beta,gamma,6);
00900   EncipherSbox5(alpha,epsilon,beta,gamma,delta);
00901   StoreKey(delta,alpha,epsilon,gamma,6);
00902   LoadKey(delta,alpha,epsilon,gamma,2);
00903   EncipherSbox6(delta,alpha,epsilon,gamma,beta);
00904   StoreKey(epsilon,beta,alpha,gamma,2);
00905   LoadKey(epsilon,beta,alpha,gamma,-2);
00906   EncipherSbox7(epsilon,beta,alpha,gamma,delta);
00907   StoreKey(delta,alpha,gamma,epsilon,-2);
00908   LoadKey(delta,alpha,gamma,epsilon,-6);
00909   EncipherSbox0(delta,alpha,gamma,epsilon,beta);
00910   StoreKey(gamma,alpha,epsilon,delta,-6);
00911   LoadKey(gamma,alpha,epsilon,delta,-10);
00912   EncipherSbox1(gamma,alpha,epsilon,delta,beta);
00913   StoreKey(beta,epsilon,delta,gamma,-10);
00914   LoadKey(beta,epsilon,delta,gamma,-14);
00915   EncipherSbox2(beta,epsilon,delta,gamma,alpha);
00916   StoreKey(alpha,epsilon,beta,gamma,-14);
00917   LoadKey(alpha,epsilon,beta,gamma,-18);
00918   EncipherSbox3(alpha,epsilon,beta,gamma,delta);
00919   StoreKey(gamma,delta,epsilon,alpha,-18);
00920   LoadKey(gamma,delta,epsilon,alpha,-22);
00921   crypt_key-=50;
00922   EncipherSbox4(gamma,delta,epsilon,alpha,beta);
00923   StoreKey(delta,epsilon,alpha,beta,28);
00924   LoadKey(delta,epsilon,alpha,beta,24);
00925   EncipherSbox5(delta,epsilon,alpha,beta,gamma);
00926   StoreKey(gamma,delta,epsilon,beta,24);
00927   LoadKey(gamma,delta,epsilon,beta,20);
00928   EncipherSbox6(gamma,delta,epsilon,beta,alpha);
00929   StoreKey(epsilon,alpha,delta,beta,20);
00930   LoadKey(epsilon,alpha,delta,beta,16);
00931   EncipherSbox7(epsilon,alpha,delta,beta,gamma);
00932   StoreKey(gamma,delta,beta,epsilon,16);
00933   LoadKey(gamma,delta,beta,epsilon,12);
00934   EncipherSbox0(gamma,delta,beta,epsilon,alpha);
00935   StoreKey(beta,delta,epsilon,gamma,12);
00936   LoadKey(beta,delta,epsilon,gamma,8);
00937   EncipherSbox1(beta,delta,epsilon,gamma,alpha);
00938   StoreKey(alpha,epsilon,gamma,beta,8);
00939   LoadKey(alpha,epsilon,gamma,beta,4);
00940   EncipherSbox2(alpha,epsilon,gamma,beta,delta);
00941   StoreKey(delta,epsilon,alpha,beta,4);
00942   LoadKey(delta,epsilon,alpha,beta,0);
00943   EncipherSbox3(delta,epsilon,alpha,beta,gamma);
00944   StoreKey(beta,gamma,epsilon,delta,0);
00945   /*
00946     Reset registers.
00947   */
00948   alpha=0;
00949   beta=0;
00950   gamma=0;
00951   delta=0;
00952   epsilon=0;
00953   rho=0;
00954 }