Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

beecrypt/mtprng.c

Go to the documentation of this file.
00001 
00018 /* Copyright (c) 1998, 1999, 2000, 2001 Virtual Unlimited B.V.
00019  *
00020  * Author: Bob Deblier <bob@virtualunlimited.com>
00021  *
00022  * This library is free software; you can redistribute it and/or
00023  * modify it under the terms of the GNU Lesser General Public
00024  * License as published by the Free Software Foundation; either
00025  * version 2.1 of the License, or (at your option) any later version.
00026  *
00027  * This library is distributed in the hope that it will be useful,
00028  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00029  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00030  * Lesser General Public License for more details.
00031  *
00032  * You should have received a copy of the GNU Lesser General Public
00033  * License along with this library; if not, write to the Free Software
00034  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00035  *
00036  */
00037 
00038 #include "system.h"
00039 #include "beecrypt.h"
00040 #include "mtprng.h"
00041 #include "mp32opt.h"
00042 #include "mp32.h"
00043 #include "debug.h"
00044 
00045 #define hiBit(a)                ((a) & 0x80000000)
00046 #define loBit(a)                ((a) & 0x1)
00047 #define loBits(a)               ((a) & 0x7FFFFFFF)
00048 #define mixBits(a, b)   (hiBit(a) | loBits(b))
00049 
00050 /*@-sizeoftype@*/
00051 const randomGenerator mtprng = { "Mersenne Twister", sizeof(mtprngParam), (randomGeneratorSetup) mtprngSetup, (randomGeneratorSeed) mtprngSeed, (randomGeneratorNext) mtprngNext, (randomGeneratorCleanup) mtprngCleanup };
00052 /*@=sizeoftype@*/
00053 
00056 /*@-boundsread@*/
00057 static void mtprngReload(mtprngParam* mp)
00058         /*@modifies mp @*/
00059 {
00060     register uint32* p0 = mp->state;
00061     register uint32* p2=p0+2, *pM = p0+M, s0, s1;
00062     register int j;
00063 
00064     for (s0=mp->state[0], s1=mp->state[1], j=N-M+1; --j; s0=s1, s1=*(p2++))
00065         *(p0++) = *(pM++) ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0);
00066 
00067     for (pM=mp->state, j=M; --j; s0=s1, s1=*(p2++))
00068         *(p0++) = *(pM++) ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0);
00069 
00070     s1 = mp->state[0], *p0 = *pM ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0);
00071 
00072     mp->left = N;
00073     mp->nextw = mp->state;
00074 }
00075 /*@=boundsread@*/
00076 
00077 int mtprngSetup(mtprngParam* mp)
00078 {
00079         if (mp)
00080         {
00081                 #ifdef _REENTRANT
00082                 # if WIN32
00083                 if (!(mp->lock = CreateMutex(NULL, FALSE, NULL)))
00084                         return -1;
00085                 # else
00086                 #  if HAVE_THREAD_H && HAVE_SYNCH_H
00087                 if (mutex_init(&mp->lock, USYNC_THREAD, (void *) 0))
00088                         return -1;
00089                 #  elif HAVE_PTHREAD_H
00090                 /*@-nullpass@*/
00091                 /*@-moduncon@*/
00092                 if (pthread_mutex_init(&mp->lock, (pthread_mutexattr_t *) 0))
00093                         return -1;
00094                 /*@=moduncon@*/
00095                 /*@=nullpass@*/
00096                 #  endif
00097                 # endif
00098                 #endif
00099 
00100                 mp->left = 0;
00101 
00102                 return entropyGatherNext(mp->state, N+1);
00103         }
00104         return -1;
00105 }
00106 
00107 /*@-boundswrite@*/
00108 int mtprngSeed(mtprngParam* mp, const uint32* data, int size)
00109 {
00110         if (mp)
00111         {
00112                 int     needed = N+1;
00113                 uint32* dest = mp->state;
00114 
00115                 #ifdef _REENTRANT
00116                 # if WIN32
00117                 if (WaitForSingleObject(mp->lock, INFINITE) != WAIT_OBJECT_0)
00118                         return -1;
00119                 # else
00120                 #  if HAVE_THREAD_H && HAVE_SYNCH_H
00121                 if (mutex_lock(&mp->lock))
00122                         return -1;
00123                 #  elif HAVE_PTHREAD_H
00124                 /*@-moduncon@*/
00125                 if (pthread_mutex_lock(&mp->lock))
00126                         return -1;
00127                 /*@=moduncon@*/
00128                 #  endif
00129                 # endif
00130                 #endif
00131                 while (size < needed)
00132                 {
00133                         mp32copy(size, dest, data);
00134                         dest += size;
00135                         needed -= size;
00136                 }
00137                 mp32copy(needed, dest, data);
00138                 #ifdef _REENTRANT
00139                 # if WIN32
00140                 if (!ReleaseMutex(mp->lock))
00141                         return -1;
00142                 # else
00143                 #  if HAVE_THREAD_H && HAVE_SYNCH_H
00144                 if (mutex_unlock(&mp->lock))
00145                         return -1;
00146                 #  elif HAVE_PTHREAD_H
00147                 /*@-moduncon@*/
00148                 if (pthread_mutex_unlock(&mp->lock))
00149                         return -1;
00150                 /*@=moduncon@*/
00151                 #  endif
00152                 # endif
00153                 #endif
00154                 return 0;
00155         }
00156         return -1;
00157 }
00158 /*@=boundswrite@*/
00159 
00160 /*@-boundswrite@*/
00161 int mtprngNext(mtprngParam* mp, uint32* data, int size)
00162 {
00163         if (mp)
00164         {
00165                 register uint32 tmp;
00166 
00167                 #ifdef _REENTRANT
00168                 # if WIN32
00169                 if (WaitForSingleObject(mp->lock, INFINITE) != WAIT_OBJECT_0)
00170                         return -1;
00171                 # else
00172                 #  if HAVE_THREAD_H && HAVE_SYNCH_H
00173                 if (mutex_lock(&mp->lock))
00174                         return -1;
00175                 #  elif HAVE_PTHREAD_H
00176                 /*@-moduncon@*/
00177                 if (pthread_mutex_lock(&mp->lock))
00178                         return -1;
00179                 /*@=moduncon@*/
00180                 #  endif
00181                 # endif
00182                 #endif
00183                 /*@-branchstate@*/
00184                 while (size--)
00185                 {
00186                         if (mp->left == 0)
00187                                 mtprngReload(mp);
00188 
00189                         tmp = *(mp->nextw++);
00190                         tmp ^= (tmp >> 11);
00191                         tmp ^= (tmp << 7) & 0x9D2C5680;
00192                         tmp ^= (tmp << 15) & 0xEFC60000;
00193                         tmp ^= (tmp >> 18);
00194                         mp->left--;
00195                         *(data++) = tmp;
00196                 }
00197                 /*@=branchstate@*/
00198                 #ifdef _REENTRANT
00199                 # if WIN32
00200                 if (!ReleaseMutex(mp->lock))
00201                         return -1;
00202                 # else
00203                 #  if HAVE_THREAD_H && HAVE_SYNCH_H
00204                 if (mutex_unlock(&mp->lock))
00205                         return -1;
00206                 #  elif HAVE_PTHREAD_H
00207                 /*@-moduncon@*/
00208                 if (pthread_mutex_unlock(&mp->lock))
00209                         return -1;
00210                 /*@=moduncon@*/
00211                 #  endif
00212                 # endif
00213                 #endif
00214                 return 0;
00215         }
00216         return -1;
00217 }
00218 /*@=boundswrite@*/
00219 
00220 int mtprngCleanup(mtprngParam* mp)
00221 {
00222         if (mp)
00223         {
00224                 #ifdef _REENTRANT
00225                 # if WIN32
00226                 if (!CloseHandle(mp->lock))
00227                         return -1;
00228                 # else
00229                 #  if HAVE_THREAD_H && HAVE_SYNCH_H
00230                 if (mutex_destroy(&mp->lock))
00231                         return -1;
00232                 #  elif HAVE_PTHREAD_H
00233                 /*@-moduncon@*/
00234                 if (pthread_mutex_destroy(&mp->lock))
00235                         return -1;
00236                 /*@=moduncon@*/
00237                 #  endif
00238                 # endif
00239                 #endif
00240                 return 0;
00241         }
00242         return -1;
00243 }

Generated on Tue Sep 17 15:56:37 2002 for rpm by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002