1
by weidai
Initial revision |
1 |
// xtrcrypt.cpp - written and placed in the public domain by Wei Dai
|
2 |
||
3 |
#include "pch.h" |
|
4 |
#include "xtrcrypt.h" |
|
5 |
#include "nbtheory.h" |
|
6 |
#include "asn.h" |
|
7 |
#include "argnames.h" |
|
8 |
||
9 |
NAMESPACE_BEGIN(CryptoPP) |
|
10 |
||
11 |
XTR_DH::XTR_DH(const Integer &p, const Integer &q, const GFP2Element &g) |
|
12 |
: m_p(p), m_q(q), m_g(g) |
|
13 |
{
|
|
14 |
}
|
|
15 |
||
16 |
XTR_DH::XTR_DH(RandomNumberGenerator &rng, unsigned int pbits, unsigned int qbits) |
|
17 |
{
|
|
18 |
XTR_FindPrimesAndGenerator(rng, m_p, m_q, m_g, pbits, qbits); |
|
19 |
}
|
|
20 |
||
21 |
XTR_DH::XTR_DH(BufferedTransformation &bt) |
|
22 |
{
|
|
23 |
BERSequenceDecoder seq(bt); |
|
24 |
m_p.BERDecode(seq); |
|
25 |
m_q.BERDecode(seq); |
|
26 |
m_g.c1.BERDecode(seq); |
|
27 |
m_g.c2.BERDecode(seq); |
|
28 |
seq.MessageEnd(); |
|
29 |
}
|
|
30 |
||
31 |
void XTR_DH::DEREncode(BufferedTransformation &bt) const |
|
32 |
{
|
|
33 |
DERSequenceEncoder seq(bt); |
|
34 |
m_p.DEREncode(seq); |
|
35 |
m_q.DEREncode(seq); |
|
36 |
m_g.c1.DEREncode(seq); |
|
37 |
m_g.c2.DEREncode(seq); |
|
38 |
seq.MessageEnd(); |
|
39 |
}
|
|
40 |
||
41 |
bool XTR_DH::Validate(RandomNumberGenerator &rng, unsigned int level) const |
|
42 |
{
|
|
43 |
bool pass = true; |
|
44 |
pass = pass && m_p > Integer::One() && m_p.IsOdd(); |
|
45 |
pass = pass && m_q > Integer::One() && m_q.IsOdd(); |
|
46 |
GFP2Element three = GFP2_ONB<ModularArithmetic>(m_p).ConvertIn(3); |
|
47 |
pass = pass && !(m_g.c1.IsNegative() || m_g.c2.IsNegative() || m_g.c1 >= m_p || m_g.c2 >= m_p || m_g == three); |
|
48 |
if (level >= 1) |
|
49 |
pass = pass && ((m_p.Squared()-m_p+1)%m_q).IsZero(); |
|
50 |
if (level >= 2) |
|
51 |
{
|
|
52 |
pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2); |
|
53 |
pass = pass && XTR_Exponentiate(m_g, (m_p.Squared()-m_p+1)/m_q, m_p) != three; |
|
54 |
pass = pass && XTR_Exponentiate(m_g, m_q, m_p) == three; |
|
55 |
}
|
|
56 |
return pass; |
|
57 |
}
|
|
58 |
||
59 |
bool XTR_DH::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const |
|
60 |
{
|
|
61 |
return GetValueHelper(this, name, valueType, pValue).Assignable() |
|
62 |
CRYPTOPP_GET_FUNCTION_ENTRY(Modulus) |
|
63 |
CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupOrder) |
|
64 |
CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupGenerator) |
|
65 |
;
|
|
66 |
}
|
|
67 |
||
68 |
void XTR_DH::AssignFrom(const NameValuePairs &source) |
|
69 |
{
|
|
70 |
AssignFromHelper(this, source) |
|
71 |
CRYPTOPP_SET_FUNCTION_ENTRY(Modulus) |
|
72 |
CRYPTOPP_SET_FUNCTION_ENTRY(SubgroupOrder) |
|
73 |
CRYPTOPP_SET_FUNCTION_ENTRY(SubgroupGenerator) |
|
74 |
;
|
|
75 |
}
|
|
76 |
||
77 |
void XTR_DH::GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const |
|
78 |
{
|
|
79 |
Integer x(rng, Integer::Zero(), m_q-1); |
|
80 |
x.Encode(privateKey, PrivateKeyLength()); |
|
81 |
}
|
|
82 |
||
83 |
void XTR_DH::GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const |
|
84 |
{
|
|
85 |
Integer x(privateKey, PrivateKeyLength()); |
|
86 |
GFP2Element y = XTR_Exponentiate(m_g, x, m_p); |
|
87 |
y.Encode(publicKey, PublicKeyLength()); |
|
88 |
}
|
|
89 |
||
90 |
bool XTR_DH::Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey) const |
|
91 |
{
|
|
92 |
GFP2Element w(otherPublicKey, PublicKeyLength()); |
|
93 |
if (validateOtherPublicKey) |
|
94 |
{
|
|
95 |
GFP2_ONB<ModularArithmetic> gfp2(m_p); |
|
96 |
GFP2Element three = gfp2.ConvertIn(3); |
|
97 |
if (w.c1.IsNegative() || w.c2.IsNegative() || w.c1 >= m_p || w.c2 >= m_p || w == three) |
|
98 |
return false; |
|
99 |
if (XTR_Exponentiate(w, m_q, m_p) != three) |
|
100 |
return false; |
|
101 |
}
|
|
102 |
Integer s(privateKey, PrivateKeyLength()); |
|
103 |
GFP2Element z = XTR_Exponentiate(w, s, m_p); |
|
104 |
z.Encode(agreedValue, AgreedValueLength()); |
|
105 |
return true; |
|
106 |
}
|
|
107 |
||
108 |
NAMESPACE_END
|