Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

blumgold.cpp

00001 // blumgold.cpp - written and placed in the public domain by Wei Dai
00002 
00003 #include "pch.h"
00004 #include "blumgold.h"
00005 #include "asn.h"
00006 #include "nbtheory.h"
00007 #include "blumshub.h"
00008 
00009 NAMESPACE_BEGIN(CryptoPP)
00010 
00011 BlumGoldwasserPublicKey::BlumGoldwasserPublicKey(const Integer &n)
00012         : n(n), modulusLen(n.ByteCount())
00013 {
00014 }
00015 
00016 BlumGoldwasserPublicKey::BlumGoldwasserPublicKey(BufferedTransformation &bt)
00017 {
00018         BERSequenceDecoder seq(bt);
00019         n.BERDecode(seq);
00020         seq.MessageEnd();
00021         modulusLen = n.ByteCount();
00022 }
00023 
00024 void BlumGoldwasserPublicKey::DEREncode(BufferedTransformation &bt) const
00025 {
00026         DERSequenceEncoder seq(bt);
00027         n.DEREncode(seq);
00028         seq.MessageEnd();
00029 }
00030 
00031 unsigned int BlumGoldwasserPublicKey::MaxPlainTextLength(unsigned int cipherTextLength) const
00032 {
00033         return cipherTextLength > modulusLen ? cipherTextLength - modulusLen : 0;
00034 }
00035 
00036 unsigned int BlumGoldwasserPublicKey::CipherTextLength(unsigned int plainTextLength) const
00037 {
00038         return modulusLen + plainTextLength;
00039 }
00040 
00041 void BlumGoldwasserPublicKey::Encrypt(RandomNumberGenerator &rng, const byte *input, unsigned int inputLen, byte *output)
00042 {
00043         Integer seed(rng, 1, n-1);
00044         PublicBlumBlumShub bbs(n, seed);
00045         bbs.ProcessString(output+modulusLen, input, inputLen);
00046         bbs.modn.Square(bbs.current).Encode(output, modulusLen);
00047 }
00048 
00049 // *****************************************************************************
00050 // private key operations:
00051 
00052 BlumGoldwasserPrivateKey::BlumGoldwasserPrivateKey(const Integer &n, const Integer &p, const Integer &q, const Integer &u)
00053         : BlumGoldwasserPublicKey(n),
00054           p(p), q(q), u(u)
00055 {
00056         assert(n == p*q);
00057         assert(u == EuclideanMultiplicativeInverse(p, q));
00058 }
00059 
00060 // generate a random private key
00061 BlumGoldwasserPrivateKey::BlumGoldwasserPrivateKey(RandomNumberGenerator &rng, unsigned int keybits)
00062 {
00063         assert(keybits >= 16);
00064         // generate 2 random primes of suitable size
00065         if (keybits%2==0)
00066         {
00067                 const Integer minP = Integer(182) << (keybits/2-8);
00068                 const Integer maxP = Integer::Power2(keybits/2)-1;
00069                 p.Randomize(rng, minP, maxP, Integer::PRIME, 3, 4);
00070                 q.Randomize(rng, minP, maxP, Integer::PRIME, 3, 4);
00071         }
00072         else
00073         {
00074                 const Integer minP = Integer::Power2((keybits-1)/2);
00075                 const Integer maxP = Integer(181) << ((keybits+1)/2-8);
00076                 p.Randomize(rng, minP, maxP, Integer::PRIME, 3, 4);
00077                 q.Randomize(rng, minP, maxP, Integer::PRIME, 3, 4);
00078         }
00079 
00080         n = p*q;
00081         u = EuclideanMultiplicativeInverse(p, q);
00082         modulusLen = n.ByteCount();
00083 }
00084 
00085 BlumGoldwasserPrivateKey::BlumGoldwasserPrivateKey(BufferedTransformation &bt)
00086 {
00087         BERSequenceDecoder seq(bt);
00088         n.BERDecode(seq);
00089         p.BERDecode(seq);
00090         q.BERDecode(seq);
00091         u.BERDecode(seq);
00092         seq.MessageEnd();
00093 
00094         modulusLen = n.ByteCount();
00095 
00096         assert(n == p*q);
00097         assert(u == EuclideanMultiplicativeInverse(p, q));
00098 }
00099 
00100 void BlumGoldwasserPrivateKey::DEREncode(BufferedTransformation &bt) const
00101 {
00102         DERSequenceEncoder seq(bt);
00103         n.DEREncode(seq);
00104         p.DEREncode(seq);
00105         q.DEREncode(seq);
00106         u.DEREncode(seq);
00107         seq.MessageEnd();
00108 }
00109 
00110 unsigned int BlumGoldwasserPrivateKey::Decrypt(const byte *input, unsigned int cipherTextLength, byte *output)
00111 {
00112         if (cipherTextLength <= modulusLen)
00113                 return 0;
00114 
00115         Integer xt(input, modulusLen);
00116         PublicBlumBlumShub bbs(n, Integer::Zero());
00117         unsigned int plainTextLength = cipherTextLength - modulusLen;
00118         unsigned int t = ((plainTextLength)*8 + bbs.maxBits-1) / bbs.maxBits;
00119         Integer dp = a_exp_b_mod_c((p+1)/4, t, p-1);
00120         Integer dq = a_exp_b_mod_c((q+1)/4, t, q-1);
00121         Integer xp = a_exp_b_mod_c(xt%p, dp, p);
00122         Integer xq = a_exp_b_mod_c(xt%q, dq, q);
00123         bbs.current = CRT(xp, p, xq, q, u);
00124         bbs.bitsLeft = bbs.maxBits;
00125 
00126         bbs.ProcessString(output, input+modulusLen, plainTextLength);
00127         return plainTextLength;
00128 }
00129 
00130 NAMESPACE_END

Generated at Mon Jan 15 01:16:29 2001 for Crypto++ by doxygen1.2.4 written by Dimitri van Heesch, © 1997-2000