Crypto++
|
00001 // blumshub.cpp - written and placed in the public domain by Wei Dai 00002 00003 #include "pch.h" 00004 #include "blumshub.h" 00005 00006 NAMESPACE_BEGIN(CryptoPP) 00007 00008 PublicBlumBlumShub::PublicBlumBlumShub(const Integer &n, const Integer &seed) 00009 : modn(n), 00010 maxBits(BitPrecision(n.BitCount())-1) 00011 { 00012 current = modn.Square(modn.Square(seed)); 00013 bitsLeft = maxBits; 00014 } 00015 00016 unsigned int PublicBlumBlumShub::GenerateBit() 00017 { 00018 if (bitsLeft==0) 00019 { 00020 current = modn.Square(current); 00021 bitsLeft = maxBits; 00022 } 00023 00024 return current.GetBit(--bitsLeft); 00025 } 00026 00027 byte PublicBlumBlumShub::GenerateByte() 00028 { 00029 byte b=0; 00030 for (int i=0; i<8; i++) 00031 b = (b << 1) | PublicBlumBlumShub::GenerateBit(); 00032 return b; 00033 } 00034 00035 void PublicBlumBlumShub::GenerateBlock(byte *output, size_t size) 00036 { 00037 while (size--) 00038 *output++ = PublicBlumBlumShub::GenerateByte(); 00039 } 00040 00041 void PublicBlumBlumShub::ProcessData(byte *outString, const byte *inString, size_t length) 00042 { 00043 while (length--) 00044 *outString++ = *inString++ ^ PublicBlumBlumShub::GenerateByte(); 00045 } 00046 00047 BlumBlumShub::BlumBlumShub(const Integer &p, const Integer &q, const Integer &seed) 00048 : PublicBlumBlumShub(p*q, seed), 00049 p(p), q(q), 00050 x0(modn.Square(seed)) 00051 { 00052 } 00053 00054 void BlumBlumShub::Seek(lword index) 00055 { 00056 Integer i(Integer::POSITIVE, index); 00057 i *= 8; 00058 Integer e = a_exp_b_mod_c (2, i / maxBits + 1, (p-1)*(q-1)); 00059 current = modn.Exponentiate(x0, e); 00060 bitsLeft = maxBits - i % maxBits; 00061 } 00062 00063 NAMESPACE_END