00001
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
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);
00178 }
00179
00180 NAMESPACE_END