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

nr.cpp

00001 // nr.cpp - written and placed in the public domain by Wei Dai
00002 
00003 #include "pch.h"
00004 #include "nr.h"
00005 #include "asn.h"
00006 #include "nbtheory.h"
00007 
00008 NAMESPACE_BEGIN(CryptoPP)
00009 
00010 Integer NR_EncodeDigest(unsigned int modulusBits, const byte *digest, unsigned int digestLen)
00011 {
00012         Integer h;
00013         if (digestLen*8 < modulusBits)
00014                 h.Decode(digest, digestLen);
00015         else
00016         {
00017                 h.Decode(digest, bitsToBytes(modulusBits));
00018                 h >>= bitsToBytes(modulusBits)*8 - modulusBits + 1;
00019         }
00020         return h;
00021 }
00022 
00023 NRDigestVerifier::NRDigestVerifier(const Integer &p, const Integer &q,
00024                            const Integer &g, const Integer &y)
00025         : m_p(p), m_q(q), m_g(g), m_y(y),
00026           m_gpc(p, g), m_ypc(p, y)
00027 {
00028 }
00029 
00030 void NRDigestVerifier::Precompute(unsigned int precomputationStorage)
00031 {
00032         m_gpc.Precompute(ExponentBitLength(), precomputationStorage);
00033         m_ypc.Precompute(ExponentBitLength(), precomputationStorage);
00034 }
00035 
00036 void NRDigestVerifier::LoadPrecomputation(BufferedTransformation &bt)
00037 {
00038         m_gpc.Load(bt);
00039         m_ypc.Load(bt);
00040 }
00041 
00042 void NRDigestVerifier::SavePrecomputation(BufferedTransformation &bt) const
00043 {
00044         m_gpc.Save(bt);
00045         m_ypc.Save(bt);
00046 }
00047 
00048 Integer NRDigestVerifier::EncodeDigest(const byte *digest, unsigned int digestLen) const
00049 {
00050         return NR_EncodeDigest(m_q.BitCount(), digest, digestLen);
00051 }
00052 
00053 unsigned int NRDigestVerifier::ExponentBitLength() const
00054 {
00055         return m_q.BitCount();
00056 }
00057 
00058 NRDigestVerifier::NRDigestVerifier(BufferedTransformation &bt)
00059 {
00060         BERSequenceDecoder seq(bt);
00061         m_p.BERDecode(seq);
00062         m_q.BERDecode(seq);
00063         m_g.BERDecode(seq);
00064         m_y.BERDecode(seq);
00065         seq.MessageEnd();
00066 
00067         m_gpc.SetModulusAndBase(m_p, m_g);
00068         m_ypc.SetModulusAndBase(m_p, m_y);
00069 }
00070 
00071 void NRDigestVerifier::DEREncode(BufferedTransformation &bt) const
00072 {
00073         DERSequenceEncoder seq(bt);
00074         m_p.DEREncode(seq);
00075         m_q.DEREncode(seq);
00076         m_g.DEREncode(seq);
00077         m_y.DEREncode(seq);
00078         seq.MessageEnd();
00079 }
00080 
00081 bool NRDigestVerifier::VerifyDigest(const byte *digest, unsigned int digestLen, const byte *signature) const
00082 {
00083         assert(digestLen <= MaxDigestLength());
00084 
00085         Integer h = EncodeDigest(digest, digestLen);
00086         unsigned int qLen = m_q.ByteCount();
00087         Integer r(signature, qLen);
00088         Integer s(signature+qLen, qLen);
00089         return RawVerify(h, r, s);
00090 }
00091 
00092 bool NRDigestVerifier::RawVerify(const Integer &m, const Integer &r, const Integer &s) const
00093 {
00094         if (r>=m_q || r<1 || s>=m_q)
00095                 return false;
00096 
00097         // check r == (m_g^s * m_y^r + m) mod m_q
00098         return r == (m_gpc.CascadeExponentiate(s, m_ypc, r) + m) % m_q;
00099 }
00100 
00101 // ******************************************************************
00102 
00103 NRDigestSigner::NRDigestSigner(const Integer &p, const Integer &q, const Integer &g, const Integer &y, const Integer &x)
00104         : NRDigestVerifier(p, q, g, y), m_x(x)
00105 {
00106 }
00107 
00108 NRDigestSigner::NRDigestSigner(RandomNumberGenerator &rng, unsigned int pbits)
00109 {
00110         PrimeAndGenerator pg(1, rng, pbits, 2*DiscreteLogWorkFactor(pbits));
00111         m_p = pg.Prime();
00112         m_q = pg.SubPrime();
00113         m_g = pg.Generator();
00114         m_x.Randomize(rng, 1, m_q-1, Integer::ANY);
00115         m_gpc.SetModulusAndBase(m_p, m_g);
00116         m_y = m_gpc.Exponentiate(m_x);
00117         m_ypc.SetModulusAndBase(m_p, m_y);
00118 }
00119 
00120 NRDigestSigner::NRDigestSigner(RandomNumberGenerator &rng, const Integer &pIn, const Integer &qIn, const Integer &gIn)
00121 {
00122         m_p = pIn;
00123         m_q = qIn;
00124         m_g = gIn;
00125         m_x.Randomize(rng, 1, m_q-1, Integer::ANY);
00126         m_gpc.SetModulusAndBase(m_p, m_g);
00127         m_y = m_gpc.Exponentiate(m_x);
00128         m_ypc.SetModulusAndBase(m_p, m_y);
00129 }
00130 
00131 NRDigestSigner::NRDigestSigner(BufferedTransformation &bt)
00132 {
00133         BERSequenceDecoder seq(bt);
00134         m_p.BERDecode(seq);
00135         m_q.BERDecode(seq);
00136         m_g.BERDecode(seq);
00137         m_y.BERDecode(seq);
00138         m_x.BERDecode(seq);
00139         seq.MessageEnd();
00140 
00141         m_gpc.SetModulusAndBase(m_p, m_g);
00142         m_ypc.SetModulusAndBase(m_p, m_y);
00143 }
00144 
00145 void NRDigestSigner::DEREncode(BufferedTransformation &bt) const
00146 {
00147         DERSequenceEncoder seq(bt);
00148         m_p.DEREncode(seq);
00149         m_q.DEREncode(seq);
00150         m_g.DEREncode(seq);
00151         m_y.DEREncode(seq);
00152         m_x.DEREncode(seq);
00153         seq.MessageEnd();
00154 }
00155 
00156 void NRDigestSigner::SignDigest(RandomNumberGenerator &rng, const byte *digest, unsigned int digestLen, byte *signature) const
00157 {
00158         assert(digestLen <= MaxDigestLength());
00159 
00160         Integer h = EncodeDigest(digest, digestLen);
00161         Integer r;
00162         Integer s;
00163 
00164         RawSign(rng, h, r, s);
00165         unsigned int qLen = m_q.ByteCount();
00166         r.Encode(signature, qLen);
00167         s.Encode(signature+qLen, qLen);
00168 }
00169 
00170 void NRDigestSigner::RawSign(RandomNumberGenerator &rng, const Integer &m, Integer &r, Integer &s) const
00171 {
00172         do
00173         {
00174                 Integer k(rng, 1, m_q-1, Integer::ANY);
00175                 r = (m_gpc.Exponentiate(k) + m) % m_q;
00176                 s = (k - m_x*r) % m_q;
00177         } while (!r);                   // make sure r != 0
00178 }
00179 
00180 NAMESPACE_END

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