Fabcoin Core  0.16.2
P2P Digital Currency
esign.cpp
Go to the documentation of this file.
1 // esign.cpp - written and placed in the public domain by Wei Dai
2 
3 #include "pch.h"
4 #include "config.h"
5 
6 // TODO: fix the C4589 warnings
7 #if CRYPTOPP_MSC_VERSION
8 # pragma warning(disable: 4589)
9 #endif
10 
11 #include "esign.h"
12 #include "modarith.h"
13 #include "integer.h"
14 #include "nbtheory.h"
15 #include "algparam.h"
16 #include "sha.h"
17 #include "asn.h"
18 
20 
21 #if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
22 void ESIGN_TestInstantiations()
23 {
24  ESIGN<SHA>::Verifier x1(1, 1);
25  ESIGN<SHA>::Signer x2(NullRNG(), 1);
26  ESIGN<SHA>::Verifier x3(x2);
27  ESIGN<SHA>::Verifier x4(x2.GetKey());
28  ESIGN<SHA>::Verifier x5(x3);
29  ESIGN<SHA>::Signer x6 = x2;
30 
31  x6 = x2;
32  x3 = ESIGN<SHA>::Verifier(x2);
33  x4 = x2.GetKey();
34 }
35 #endif
36 
38 {
39  BERSequenceDecoder seq(bt);
40  m_n.BERDecode(seq);
41  m_e.BERDecode(seq);
42  seq.MessageEnd();
43 }
44 
46 {
47  DERSequenceEncoder seq(bt);
48  m_n.DEREncode(seq);
49  m_e.DEREncode(seq);
50  seq.MessageEnd();
51 }
52 
54 {
56  return STDMIN(a_exp_b_mod_c(x, m_e, m_n) >> (2*GetK()+2), MaxImage());
57 }
58 
59 bool ESIGNFunction::Validate(RandomNumberGenerator& rng, unsigned int level) const
60 {
61  CRYPTOPP_UNUSED(rng), CRYPTOPP_UNUSED(level);
62  bool pass = true;
63  pass = pass && m_n > Integer::One() && m_n.IsOdd();
64  pass = pass && m_e >= 8 && m_e < m_n;
65  return pass;
66 }
67 
68 bool ESIGNFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
69 {
70  return GetValueHelper(this, name, valueType, pValue).Assignable()
72  CRYPTOPP_GET_FUNCTION_ENTRY(PublicExponent)
73  ;
74 }
75 
77 {
78  AssignFromHelper(this, source)
80  CRYPTOPP_SET_FUNCTION_ENTRY(PublicExponent)
81  ;
82 }
83 
84 // *****************************************************************************
85 
87 {
88  int modulusSize = 1023*2;
89  param.GetIntValue("ModulusSize", modulusSize) || param.GetIntValue("KeySize", modulusSize);
90 
91  if (modulusSize < 24)
92  throw InvalidArgument("InvertibleESIGNFunction: specified modulus size is too small");
93 
94  if (modulusSize % 3 != 0)
95  throw InvalidArgument("InvertibleESIGNFunction: modulus size must be divisible by 3");
96 
97  m_e = param.GetValueWithDefault("PublicExponent", Integer(32));
98 
99  if (m_e < 8)
100  throw InvalidArgument("InvertibleESIGNFunction: public exponents less than 8 may not be secure");
101 
102  // VC70 workaround: putting these after primeParam causes overlapped stack allocation
103  ConstByteArrayParameter seedParam;
104  SecByteBlock seed;
105 
106  const Integer minP = Integer(204) << (modulusSize/3-8);
107  const Integer maxP = Integer::Power2(modulusSize/3)-1;
108  AlgorithmParameters primeParam = MakeParameters("Min", minP)("Max", maxP)("RandomNumberType", Integer::PRIME);
109 
110  if (param.GetValue("Seed", seedParam))
111  {
112  seed.resize(seedParam.size() + 4);
113  memcpy(seed + 4, seedParam.begin(), seedParam.size());
114 
115  PutWord(false, BIG_ENDIAN_ORDER, seed, (word32)0);
116  m_p.GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters("Seed", ConstByteArrayParameter(seed))));
117  PutWord(false, BIG_ENDIAN_ORDER, seed, (word32)1);
118  m_q.GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters("Seed", ConstByteArrayParameter(seed))));
119  }
120  else
121  {
122  m_p.GenerateRandom(rng, primeParam);
123  m_q.GenerateRandom(rng, primeParam);
124  }
125 
126  m_n = m_p * m_p * m_q;
127 
128  CRYPTOPP_ASSERT(m_n.BitCount() == (unsigned int)modulusSize);
129 }
130 
132 {
133  BERSequenceDecoder privateKey(bt);
134  m_n.BERDecode(privateKey);
135  m_e.BERDecode(privateKey);
136  m_p.BERDecode(privateKey);
137  m_q.BERDecode(privateKey);
138  privateKey.MessageEnd();
139 }
140 
142 {
143  DERSequenceEncoder privateKey(bt);
144  m_n.DEREncode(privateKey);
145  m_e.DEREncode(privateKey);
146  m_p.DEREncode(privateKey);
147  m_q.DEREncode(privateKey);
148  privateKey.MessageEnd();
149 }
150 
152 {
154 
155  Integer pq = m_p * m_q;
156  Integer p2 = m_p * m_p;
157  Integer r, z, re, a, w0, w1;
158 
159  do
160  {
161  r.Randomize(rng, Integer::Zero(), pq);
162  z = x << (2*GetK()+2);
163  re = a_exp_b_mod_c(r, m_e, m_n);
164  a = (z - re) % m_n;
165  Integer::Divide(w1, w0, a, pq);
166  if (w1.NotZero())
167  {
168  ++w0;
169  w1 = pq - w1;
170  }
171  }
172  while ((w1 >> (2*GetK()+1)).IsPositive());
173 
174  ModularArithmetic modp(m_p);
175  Integer t = modp.Divide(w0 * r % m_p, m_e * re % m_p);
176  Integer s = r + t*pq;
177  CRYPTOPP_ASSERT(s < m_n);
178 #if 0
179  using namespace std;
180  cout << "f = " << x << endl;
181  cout << "r = " << r << endl;
182  cout << "z = " << z << endl;
183  cout << "a = " << a << endl;
184  cout << "w0 = " << w0 << endl;
185  cout << "w1 = " << w1 << endl;
186  cout << "t = " << t << endl;
187  cout << "s = " << s << endl;
188 #endif
189  return s;
190 }
191 
192 bool InvertibleESIGNFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const
193 {
194  bool pass = ESIGNFunction::Validate(rng, level);
195  pass = pass && m_p > Integer::One() && m_p.IsOdd() && m_p < m_n;
196  pass = pass && m_q > Integer::One() && m_q.IsOdd() && m_q < m_n;
197  pass = pass && m_p.BitCount() == m_q.BitCount();
198  if (level >= 1)
199  pass = pass && m_p * m_p * m_q == m_n;
200  if (level >= 2)
201  pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2);
202  return pass;
203 }
204 
205 bool InvertibleESIGNFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
206 {
207  return GetValueHelper<ESIGNFunction>(this, name, valueType, pValue).Assignable()
210  ;
211 }
212 
214 {
215  AssignFromHelper<ESIGNFunction>(this, source)
218  ;
219 }
220 
Used to pass byte array input as part of a NameValuePairs object.
Definition: algparam.h:29
Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const
Applies the inverse of the trapdoor function, using random data if required.
Definition: esign.cpp:151
An invalid argument was detected.
Definition: cryptlib.h:184
Classes for working with NameValuePairs.
a number which is probabilistically prime
Definition: integer.h:89
bool NotZero() const
Determines if the Integer is non-0.
Definition: integer.h:327
bool IsOdd() const
Determines if the Integer is odd parity.
Definition: integer.h:345
T GetValueWithDefault(const char *name, T defaultValue) const
Get a named value.
Definition: cryptlib.h:350
PK_FinalTemplate< TF_VerifierImpl< SchemeOptions > > Verifier
implements PK_Verifier interface
Definition: pubkey.h:2121
unsigned int GetK() const
Definition: esign.h:56
void resize(size_type newSize)
Change size and preserve contents.
Definition: secblock.h:705
void MessageEnd()
Definition: asn.cpp:524
void PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock=NULL)
Access a block of memory.
Definition: misc.h:2123
#define NAMESPACE_BEGIN(x)
Definition: config.h:200
CRYPTOPP_DLL bool GetIntValue(const char *name, int &value) const
Get a named value with type int.
Definition: cryptlib.h:373
size_t size() const
Length of the memory block.
Definition: algparam.h:93
Library configuration file.
Ring of congruence classes modulo n.
Definition: modarith.h:34
std::hash for asio::adress
Definition: Common.h:323
void DEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
Definition: esign.cpp:141
Interface for random number generators.
Definition: cryptlib.h:1188
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
Definition: esign.cpp:192
void Randomize(RandomNumberGenerator &rng, size_t bitCount)
Set this Integer to random integer.
Definition: integer.cpp:3458
Combines two sets of NameValuePairs.
Definition: algparam.h:135
BER Sequence Decoder.
Definition: asn.h:303
Interface for buffered transformations.
Definition: cryptlib.h:1352
const byte * begin() const
Pointer to the first byte in the memory block.
Definition: algparam.h:89
static const Integer &CRYPTOPP_API One()
Integer representing 1.
Definition: integer.cpp:3035
Classes providing ESIGN signature schemes as defined in IEEE P1363a.
bool VerifyPrime(RandomNumberGenerator &rng, const Integer &p, unsigned int level)
Verifies a prime number.
Definition: nbtheory.cpp:249
unsigned int BitCount() const
Determines the number of bits required to represent the Integer.
Definition: integer.cpp:3305
void BERDecode(BufferedTransformation &bt)
Decode this object from a BufferedTransformation.
Definition: esign.cpp:131
#define a(i)
#define x(i)
const char * source
Definition: rpcconsole.cpp:60
bool Validate(RandomNumberGenerator &rng, unsigned int level) const
Check this object for errors.
Definition: esign.cpp:59
bool GetValue(const char *name, T &value) const
Get a named value.
Definition: cryptlib.h:337
AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed=true)
Create an object that implements NameValuePairs.
Definition: algparam.h:498
const char * name
Definition: rest.cpp:36
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
Definition: esign.cpp:213
static Integer CRYPTOPP_API Power2(size_t e)
Exponentiates to a power of 2.
Definition: integer.cpp:3008
Multiple precision integer with arithmetic operations.
Definition: integer.h:43
Integer m_e
Definition: esign.h:58
virtual Integer MaxImage() const
Returns the maximum size of a message after the trapdoor function is applied bound to a public key...
Definition: pubkey.h:93
Integer m_n
Definition: esign.h:58
void BERDecode(BufferedTransformation &bt)
Decode this object from a BufferedTransformation.
Definition: esign.cpp:37
AssignFromHelperClass< T, BASE > AssignFromHelper(T *pObject, const NameValuePairs &source)
Definition: algparam.h:286
byte order is big-endian
Definition: cryptlib.h:128
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:477
#define CRYPTOPP_ASSERT(exp)
Definition: trap.h:92
static void CRYPTOPP_API Divide(Integer &r, Integer &q, const Integer &a, const Integer &d)
calculate r and q such that (a == d*q + r) && (0 <= r < abs(d))
Definition: integer.cpp:4144
const Integer & Divide(const Integer &a, const Integer &b) const
Divides elements in the ring.
Definition: modarith.h:198
Classes and functions for working with ANS.1 objects.
Classes for SHA-1 and SHA-2 family of message digests.
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: esign.cpp:205
void MessageEnd()
Definition: asn.cpp:456
#define CRYPTOPP_SET_FUNCTION_ENTRY(name)
Definition: algparam.h:505
Classes and functions for number theoretic operations.
void DEREncode(BufferedTransformation &bt) const
Encode in DER format.
Definition: integer.cpp:3391
DER Sequence Encoder.
Definition: asn.h:313
#define pass(a, b, c, mul, X)
#define CRYPTOPP_GET_FUNCTION_ENTRY(name)
Definition: algparam.h:504
void * memcpy(void *a, const void *b, size_t c)
#define CRYPTOPP_UNUSED(x)
Definition: config.h:741
RandomNumberGenerator & NullRNG()
Random Number Generator that does not produce random numbers.
Definition: cryptlib.cpp:402
An object that implements NameValuePairs.
Definition: algparam.h:433
Multiple precision integer with arithmetic operations.
static const Integer &CRYPTOPP_API Zero()
Integer representing 0.
Definition: integer.cpp:3027
#define NAMESPACE_END
Definition: config.h:201
void BERDecode(const byte *input, size_t inputLen)
Decode from BER format.
Definition: integer.cpp:3398
void AssignFrom(const NameValuePairs &source)
Assign values to this object.
Definition: esign.cpp:76
Class file for performing modular arithmetic.
#define z(i)
Integer a_exp_b_mod_c(const Integer &x, const Integer &e, const Integer &m)
Definition: integer.cpp:4359
void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg)
Definition: esign.cpp:86
unsigned int word32
Definition: config.h:231
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
Get a named value.
Definition: esign.cpp:68
void DEREncode(BufferedTransformation &bt) const
Encode this object into a BufferedTransformation.
Definition: esign.cpp:45
Integer ApplyFunction(const Integer &x) const
Applies the trapdoor.
Definition: esign.cpp:53
Interface for retrieving values given their names.
Definition: cryptlib.h:279
void DoQuickSanityCheck() const
Perform a quick sanity check.
Definition: cryptlib.h:2145
Template implementing constructors for public key algorithm classes.
Definition: pubkey.h:1989
GetValueHelperClass< T, BASE > GetValueHelper(const T *pObject, const char *name, const std::type_info &valueType, void *pValue, const NameValuePairs *searchFirst=NULL)
Definition: algparam.h:224