00001
00002
00003 #include "pch.h"
00004
00005 #include "asn.h"
00006 #include "integer.h"
00007 #include "xtrcrypt.h"
00008 #include "nbtheory.h"
00009 #include "modarith.h"
00010 #include "argnames.h"
00011
00012 NAMESPACE_BEGIN(CryptoPP)
00013
00014 XTR_DH::XTR_DH(const Integer &p, const Integer &q, const GFP2Element &g)
00015 : m_p(p), m_q(q), m_g(g)
00016 {
00017 }
00018
00019 XTR_DH::XTR_DH(RandomNumberGenerator &rng, unsigned int pbits, unsigned int qbits)
00020 {
00021 XTR_FindPrimesAndGenerator(rng, m_p, m_q, m_g, pbits, qbits);
00022 }
00023
00024 XTR_DH::XTR_DH(BufferedTransformation &bt)
00025 {
00026 BERSequenceDecoder seq(bt);
00027 m_p.BERDecode(seq);
00028 m_q.BERDecode(seq);
00029 m_g.c1.BERDecode(seq);
00030 m_g.c2.BERDecode(seq);
00031 seq.MessageEnd();
00032 }
00033
00034 void XTR_DH::DEREncode(BufferedTransformation &bt) const
00035 {
00036 DERSequenceEncoder seq(bt);
00037 m_p.DEREncode(seq);
00038 m_q.DEREncode(seq);
00039 m_g.c1.DEREncode(seq);
00040 m_g.c2.DEREncode(seq);
00041 seq.MessageEnd();
00042 }
00043
00044 bool XTR_DH::Validate(RandomNumberGenerator &rng, unsigned int level) const
00045 {
00046 bool pass = true;
00047 pass = pass && m_p > Integer::One() && m_p.IsOdd();
00048 pass = pass && m_q > Integer::One() && m_q.IsOdd();
00049 GFP2Element three = GFP2_ONB<ModularArithmetic>(m_p).ConvertIn(3);
00050 pass = pass && !(m_g.c1.IsNegative() || m_g.c2.IsNegative() || m_g.c1 >= m_p || m_g.c2 >= m_p || m_g == three);
00051 if (level >= 1)
00052 pass = pass && ((m_p.Squared()-m_p+1)%m_q).IsZero();
00053 if (level >= 2)
00054 {
00055 pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2);
00056 pass = pass && XTR_Exponentiate(m_g, (m_p.Squared()-m_p+1)/m_q, m_p) != three;
00057 pass = pass && XTR_Exponentiate(m_g, m_q, m_p) == three;
00058 }
00059 return pass;
00060 }
00061
00062 bool XTR_DH::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
00063 {
00064 return GetValueHelper(this, name, valueType, pValue).Assignable()
00065 CRYPTOPP_GET_FUNCTION_ENTRY(Modulus)
00066 CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupOrder)
00067 CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupGenerator)
00068 ;
00069 }
00070
00071 void XTR_DH::AssignFrom(const NameValuePairs &source)
00072 {
00073 AssignFromHelper(this, source)
00074 CRYPTOPP_SET_FUNCTION_ENTRY(Modulus)
00075 CRYPTOPP_SET_FUNCTION_ENTRY(SubgroupOrder)
00076 CRYPTOPP_SET_FUNCTION_ENTRY(SubgroupGenerator)
00077 ;
00078 }
00079
00080 void XTR_DH::GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
00081 {
00082 Integer x(rng, Integer::Zero(), m_q-1);
00083 x.Encode(privateKey, PrivateKeyLength());
00084 }
00085
00086 void XTR_DH::GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
00087 {
00088 CRYPTOPP_UNUSED(rng);
00089 Integer x(privateKey, PrivateKeyLength());
00090 GFP2Element y = XTR_Exponentiate(m_g, x, m_p);
00091 y.Encode(publicKey, PublicKeyLength());
00092 }
00093
00094 bool XTR_DH::Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey) const
00095 {
00096 GFP2Element w(otherPublicKey, PublicKeyLength());
00097 if (validateOtherPublicKey)
00098 {
00099 GFP2_ONB<ModularArithmetic> gfp2(m_p);
00100 GFP2Element three = gfp2.ConvertIn(3);
00101 if (w.c1.IsNegative() || w.c2.IsNegative() || w.c1 >= m_p || w.c2 >= m_p || w == three)
00102 return false;
00103 if (XTR_Exponentiate(w, m_q, m_p) != three)
00104 return false;
00105 }
00106 Integer s(privateKey, PrivateKeyLength());
00107 GFP2Element z = XTR_Exponentiate(w, s, m_p);
00108 z.Encode(agreedValue, AgreedValueLength());
00109 return true;
00110 }
00111
00112 NAMESPACE_END