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