gf2_32.cpp

00001 // gf2_32.cpp - written and placed in the public domain by Wei Dai
00002 
00003 #include "pch.h"
00004 #include "misc.h"
00005 #include "gf2_32.h"
00006 
00007 NAMESPACE_BEGIN(CryptoPP)
00008 
00009 GF2_32::Element GF2_32::Multiply(Element a, Element b) const
00010 {
00011         word32 table[4];
00012         table[0] = 0;
00013         table[1] = m_modulus;
00014         if (a & 0x80000000)
00015         {
00016                 table[2] = m_modulus ^ (a<<1);
00017                 table[3] = a<<1;
00018         }
00019         else
00020         {
00021                 table[2] = a<<1;
00022                 table[3] = m_modulus ^ (a<<1);
00023         }
00024 
00025 #ifdef FAST_ROTATE
00026         b = rotrFixed(b, 30U);
00027         word32 result = table[b&2];
00028 
00029         for (int i=29; i>=0; --i)
00030         {
00031                 b = rotlFixed(b, 1U);
00032                 result = (result<<1) ^ table[(b&2) + (result>>31)];
00033         }
00034 
00035         return (b&1) ? result ^ a : result;
00036 #else
00037         word32 result = table[(b>>30) & 2];
00038 
00039         for (int i=29; i>=0; --i)
00040                 result = (result<<1) ^ table[((b>>i)&2) + (result>>31)];
00041 
00042         return (b&1) ? result ^ a : result;
00043 #endif
00044 }
00045 
00046 GF2_32::Element GF2_32::MultiplicativeInverse(Element a) const
00047 {
00048         if (a <= 1)             // 1 is a special case
00049                 return a;
00050 
00051         // warning - don't try to adapt this algorithm for another situation
00052         word32 g0=m_modulus, g1=a, g2=a;
00053         word32 v0=0, v1=1, v2=1;
00054 
00055         assert(g1);
00056 
00057         while (!(g2 & 0x80000000))
00058         {
00059                 g2 <<= 1;
00060                 v2 <<= 1;
00061         }
00062 
00063         g2 <<= 1;
00064         v2 <<= 1;
00065 
00066         g0 ^= g2;
00067         v0 ^= v2;
00068 
00069         while (g0 != 1)
00070         {
00071                 if (g1 < g0 || ((g0^g1) < g0 && (g0^g1) < g1))
00072                 {
00073                         assert(BitPrecision(g1) <= BitPrecision(g0));
00074                         g2 = g1;
00075                         v2 = v1;
00076                 }
00077                 else
00078                 {
00079                         assert(BitPrecision(g1) > BitPrecision(g0));
00080                         g2 = g0; g0 = g1; g1 = g2;
00081                         v2 = v0; v0 = v1; v1 = v2;
00082                 }
00083 
00084                 while ((g0^g2) >= g2)
00085                 {
00086                         assert(BitPrecision(g0) > BitPrecision(g2));
00087                         g2 <<= 1;
00088                         v2 <<= 1;
00089                 }
00090 
00091                 assert(BitPrecision(g0) == BitPrecision(g2));
00092                 g0 ^= g2;
00093                 v0 ^= v2;
00094         }
00095 
00096         return v0;
00097 }
00098 
00099 NAMESPACE_END

Generated on Sat Dec 23 02:07:07 2006 for Crypto++ by  doxygen 1.5.1-p1