Crypto++
xtrcrypt.cpp
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 
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  {
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
unsigned int PublicKeyLength() const
return length of public keys in this domain
Definition: xtrcrypt.h:31
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
to be implemented by derived classes, users should use one of the above functions instead ...
Definition: xtrcrypt.cpp:59
void AssignFrom(const NameValuePairs &source)
assign values from source to this object
Definition: xtrcrypt.cpp:68
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
check this object for errors
Definition: xtrcrypt.cpp:41
interface for random number generators
Definition: cryptlib.h:669
BER Sequence Decoder.
Definition: asn.h:177
interface for buffered transformations
Definition: cryptlib.h:771
static const Integer & One()
avoid calling constructors for these frequently used integers
Definition: integer.cpp:2867
bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
derive agreed value from your private key and couterparty's public key, return false in case of failu...
Definition: xtrcrypt.cpp:90
an element of GF(p^2)
Definition: xtr.h:13
void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const
generate public key
Definition: xtrcrypt.cpp:83
void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const
generate private key
Definition: xtrcrypt.cpp:77
XTR-DH with key validation.
Definition: xtrcrypt.h:14
unsigned int AgreedValueLength() const
return length of agreed value produced
Definition: xtrcrypt.h:29
multiple precision integer and basic arithmetics
Definition: integer.h:26
void Encode(byte *output, size_t outputLen, Signedness=UNSIGNED) const
encode in big-endian format
Definition: integer.cpp:3112
void DEREncode(BufferedTransformation &bt) const
encode using Distinguished Encoding Rules, put result into a BufferedTransformation object ...
Definition: integer.cpp:3133
DER Sequence Encoder.
Definition: asn.h:187
"The XTR public key system" by Arjen K.
static const Integer & Zero()
avoid calling constructors for these frequently used integers
Definition: integer.cpp:2862
GF(p^2), optimal normal basis.
Definition: xtr.h:43
unsigned int PrivateKeyLength() const
return length of private keys in this domain
Definition: xtrcrypt.h:30
interface for retrieving values given their names
Definition: cryptlib.h:225