From b21162cf8e06f40baa1f58be6a8c17435cebc34d Mon Sep 17 00:00:00 2001 From: weidai Date: Fri, 4 Oct 2002 17:31:41 +0000 Subject: Initial revision git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@2 57ff6487-cd31-0410-9ec3-f628ee90f5f0 --- xtrcrypt.cpp | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 xtrcrypt.cpp (limited to 'xtrcrypt.cpp') diff --git a/xtrcrypt.cpp b/xtrcrypt.cpp new file mode 100644 index 0000000..20e78e7 --- /dev/null +++ b/xtrcrypt.cpp @@ -0,0 +1,108 @@ +// xtrcrypt.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "xtrcrypt.h" +#include "nbtheory.h" +#include "asn.h" +#include "argnames.h" + +NAMESPACE_BEGIN(CryptoPP) + +XTR_DH::XTR_DH(const Integer &p, const Integer &q, const GFP2Element &g) + : m_p(p), m_q(q), m_g(g) +{ +} + +XTR_DH::XTR_DH(RandomNumberGenerator &rng, unsigned int pbits, unsigned int qbits) +{ + XTR_FindPrimesAndGenerator(rng, m_p, m_q, m_g, pbits, qbits); +} + +XTR_DH::XTR_DH(BufferedTransformation &bt) +{ + BERSequenceDecoder seq(bt); + m_p.BERDecode(seq); + m_q.BERDecode(seq); + m_g.c1.BERDecode(seq); + m_g.c2.BERDecode(seq); + seq.MessageEnd(); +} + +void XTR_DH::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + m_p.DEREncode(seq); + m_q.DEREncode(seq); + m_g.c1.DEREncode(seq); + m_g.c2.DEREncode(seq); + seq.MessageEnd(); +} + +bool XTR_DH::Validate(RandomNumberGenerator &rng, unsigned int level) const +{ + bool pass = true; + pass = pass && m_p > Integer::One() && m_p.IsOdd(); + pass = pass && m_q > Integer::One() && m_q.IsOdd(); + GFP2Element three = GFP2_ONB(m_p).ConvertIn(3); + pass = pass && !(m_g.c1.IsNegative() || m_g.c2.IsNegative() || m_g.c1 >= m_p || m_g.c2 >= m_p || m_g == three); + if (level >= 1) + pass = pass && ((m_p.Squared()-m_p+1)%m_q).IsZero(); + if (level >= 2) + { + pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2); + pass = pass && XTR_Exponentiate(m_g, (m_p.Squared()-m_p+1)/m_q, m_p) != three; + pass = pass && XTR_Exponentiate(m_g, m_q, m_p) == three; + } + return pass; +} + +bool XTR_DH::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + return GetValueHelper(this, name, valueType, pValue).Assignable() + CRYPTOPP_GET_FUNCTION_ENTRY(Modulus) + CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupOrder) + CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupGenerator) + ; +} + +void XTR_DH::AssignFrom(const NameValuePairs &source) +{ + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(Modulus) + CRYPTOPP_SET_FUNCTION_ENTRY(SubgroupOrder) + CRYPTOPP_SET_FUNCTION_ENTRY(SubgroupGenerator) + ; +} + +void XTR_DH::GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const +{ + Integer x(rng, Integer::Zero(), m_q-1); + x.Encode(privateKey, PrivateKeyLength()); +} + +void XTR_DH::GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const +{ + Integer x(privateKey, PrivateKeyLength()); + GFP2Element y = XTR_Exponentiate(m_g, x, m_p); + y.Encode(publicKey, PublicKeyLength()); +} + +bool XTR_DH::Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey) const +{ + GFP2Element w(otherPublicKey, PublicKeyLength()); + if (validateOtherPublicKey) + { + GFP2_ONB gfp2(m_p); + GFP2Element three = gfp2.ConvertIn(3); + if (w.c1.IsNegative() || w.c2.IsNegative() || w.c1 >= m_p || w.c2 >= m_p || w == three) + return false; + if (XTR_Exponentiate(w, m_q, m_p) != three) + return false; + } + Integer s(privateKey, PrivateKeyLength()); + GFP2Element z = XTR_Exponentiate(w, s, m_p); + z.Encode(agreedValue, AgreedValueLength()); + return true; +} + +NAMESPACE_END -- cgit v1.2.1