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