Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
folium-app
GitHub Repository: folium-app/Folium
Path: blob/a-new-beginning/SharedDependencies/Sources/cryptopp/ec2n.cpp
2 views
1
// ec2n.cpp - originally written and placed in the public domain by Wei Dai
2
3
#include "pch.h"
4
5
#ifndef CRYPTOPP_IMPORTS
6
7
#include "ec2n.h"
8
#include "asn.h"
9
#include "integer.h"
10
#include "filters.h"
11
#include "algebra.cpp"
12
#include "eprecomp.cpp"
13
14
ANONYMOUS_NAMESPACE_BEGIN
15
16
using CryptoPP::EC2N;
17
18
#if defined(HAVE_GCC_INIT_PRIORITY)
19
#define INIT_ATTRIBUTE __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 51)))
20
const EC2N::Point g_identity INIT_ATTRIBUTE = EC2N::Point();
21
#elif defined(HAVE_MSC_INIT_PRIORITY)
22
#pragma warning(disable: 4075)
23
#pragma init_seg(".CRT$XCU")
24
const EC2N::Point g_identity;
25
#pragma warning(default: 4075)
26
#elif defined(HAVE_XLC_INIT_PRIORITY)
27
#pragma priority(290)
28
const EC2N::Point g_identity;
29
#endif
30
31
ANONYMOUS_NAMESPACE_END
32
33
NAMESPACE_BEGIN(CryptoPP)
34
35
EC2N::EC2N(BufferedTransformation &bt)
36
: m_field(BERDecodeGF2NP(bt))
37
{
38
BERSequenceDecoder seq(bt);
39
m_field->BERDecodeElement(seq, m_a);
40
m_field->BERDecodeElement(seq, m_b);
41
// skip optional seed
42
if (!seq.EndReached())
43
{
44
SecByteBlock seed;
45
unsigned int unused;
46
BERDecodeBitString(seq, seed, unused);
47
}
48
seq.MessageEnd();
49
}
50
51
void EC2N::DEREncode(BufferedTransformation &bt) const
52
{
53
m_field->DEREncode(bt);
54
DERSequenceEncoder seq(bt);
55
m_field->DEREncodeElement(seq, m_a);
56
m_field->DEREncodeElement(seq, m_b);
57
seq.MessageEnd();
58
}
59
60
bool EC2N::DecodePoint(EC2N::Point &P, const byte *encodedPoint, size_t encodedPointLen) const
61
{
62
StringStore store(encodedPoint, encodedPointLen);
63
return DecodePoint(P, store, encodedPointLen);
64
}
65
66
bool EC2N::DecodePoint(EC2N::Point &P, BufferedTransformation &bt, size_t encodedPointLen) const
67
{
68
byte type;
69
if (encodedPointLen < 1 || !bt.Get(type))
70
return false;
71
72
switch (type)
73
{
74
case 0:
75
P.identity = true;
76
return true;
77
case 2:
78
case 3:
79
{
80
if (encodedPointLen != EncodedPointSize(true))
81
return false;
82
83
P.identity = false;
84
P.x.Decode(bt, m_field->MaxElementByteLength());
85
86
if (P.x.IsZero())
87
{
88
P.y = m_field->SquareRoot(m_b);
89
return true;
90
}
91
92
FieldElement z = m_field->Square(P.x);
93
CRYPTOPP_ASSERT(P.x == m_field->SquareRoot(z));
94
P.y = m_field->Divide(m_field->Add(m_field->Multiply(z, m_field->Add(P.x, m_a)), m_b), z);
95
CRYPTOPP_ASSERT(P.x == m_field->Subtract(m_field->Divide(m_field->Subtract(m_field->Multiply(P.y, z), m_b), z), m_a));
96
z = m_field->SolveQuadraticEquation(P.y);
97
CRYPTOPP_ASSERT(m_field->Add(m_field->Square(z), z) == P.y);
98
z.SetCoefficient(0, type & 1);
99
100
P.y = m_field->Multiply(z, P.x);
101
return true;
102
}
103
case 4:
104
{
105
if (encodedPointLen != EncodedPointSize(false))
106
return false;
107
108
unsigned int len = m_field->MaxElementByteLength();
109
P.identity = false;
110
P.x.Decode(bt, len);
111
P.y.Decode(bt, len);
112
return true;
113
}
114
default:
115
return false;
116
}
117
}
118
119
void EC2N::EncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const
120
{
121
if (P.identity)
122
NullStore().TransferTo(bt, EncodedPointSize(compressed));
123
else if (compressed)
124
{
125
bt.Put((byte)(2U + (!P.x ? 0U : m_field->Divide(P.y, P.x).GetBit(0))));
126
P.x.Encode(bt, m_field->MaxElementByteLength());
127
}
128
else
129
{
130
unsigned int len = m_field->MaxElementByteLength();
131
bt.Put(4); // uncompressed
132
P.x.Encode(bt, len);
133
P.y.Encode(bt, len);
134
}
135
}
136
137
void EC2N::EncodePoint(byte *encodedPoint, const Point &P, bool compressed) const
138
{
139
ArraySink sink(encodedPoint, EncodedPointSize(compressed));
140
EncodePoint(sink, P, compressed);
141
CRYPTOPP_ASSERT(sink.TotalPutLength() == EncodedPointSize(compressed));
142
}
143
144
EC2N::Point EC2N::BERDecodePoint(BufferedTransformation &bt) const
145
{
146
SecByteBlock str;
147
BERDecodeOctetString(bt, str);
148
Point P;
149
if (!DecodePoint(P, str, str.size()))
150
BERDecodeError();
151
return P;
152
}
153
154
void EC2N::DEREncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const
155
{
156
SecByteBlock str(EncodedPointSize(compressed));
157
EncodePoint(str, P, compressed);
158
DEREncodeOctetString(bt, str);
159
}
160
161
bool EC2N::ValidateParameters(RandomNumberGenerator &rng, unsigned int level) const
162
{
163
CRYPTOPP_UNUSED(rng);
164
bool pass = !!m_b;
165
pass = pass && m_a.CoefficientCount() <= m_field->MaxElementBitLength();
166
pass = pass && m_b.CoefficientCount() <= m_field->MaxElementBitLength();
167
168
if (level >= 1)
169
pass = pass && m_field->GetModulus().IsIrreducible();
170
171
return pass;
172
}
173
174
bool EC2N::VerifyPoint(const Point &P) const
175
{
176
const FieldElement &x = P.x, &y = P.y;
177
return P.identity ||
178
(x.CoefficientCount() <= m_field->MaxElementBitLength()
179
&& y.CoefficientCount() <= m_field->MaxElementBitLength()
180
&& !(((x+m_a)*x*x+m_b-(x+y)*y)%m_field->GetModulus()));
181
}
182
183
bool EC2N::Equal(const Point &P, const Point &Q) const
184
{
185
if (P.identity && Q.identity)
186
return true;
187
188
if (P.identity && !Q.identity)
189
return false;
190
191
if (!P.identity && Q.identity)
192
return false;
193
194
return (m_field->Equal(P.x,Q.x) && m_field->Equal(P.y,Q.y));
195
}
196
197
const EC2N::Point& EC2N::Identity() const
198
{
199
#if defined(HAVE_GCC_INIT_PRIORITY) || defined(HAVE_MSC_INIT_PRIORITY) || defined(HAVE_XLC_INIT_PRIORITY)
200
return g_identity;
201
#elif defined(CRYPTOPP_CXX11_STATIC_INIT)
202
static const EC2N::Point g_identity;
203
return g_identity;
204
#else
205
return Singleton<Point>().Ref();
206
#endif
207
}
208
209
const EC2N::Point& EC2N::Inverse(const Point &P) const
210
{
211
if (P.identity)
212
return P;
213
else
214
{
215
m_R.identity = false;
216
m_R.y = m_field->Add(P.x, P.y);
217
m_R.x = P.x;
218
return m_R;
219
}
220
}
221
222
const EC2N::Point& EC2N::Add(const Point &P, const Point &Q) const
223
{
224
if (P.identity) return Q;
225
if (Q.identity) return P;
226
if (Equal(P, Q)) return Double(P);
227
if (m_field->Equal(P.x, Q.x) && m_field->Equal(P.y, m_field->Add(Q.x, Q.y))) return Identity();
228
229
FieldElement t = m_field->Add(P.y, Q.y);
230
t = m_field->Divide(t, m_field->Add(P.x, Q.x));
231
FieldElement x = m_field->Square(t);
232
m_field->Accumulate(x, t);
233
m_field->Accumulate(x, Q.x);
234
m_field->Accumulate(x, m_a);
235
m_R.y = m_field->Add(P.y, m_field->Multiply(t, x));
236
m_field->Accumulate(x, P.x);
237
m_field->Accumulate(m_R.y, x);
238
239
m_R.x.swap(x);
240
m_R.identity = false;
241
return m_R;
242
}
243
244
const EC2N::Point& EC2N::Double(const Point &P) const
245
{
246
if (P.identity) return P;
247
if (!m_field->IsUnit(P.x)) return Identity();
248
249
FieldElement t = m_field->Divide(P.y, P.x);
250
m_field->Accumulate(t, P.x);
251
m_R.y = m_field->Square(P.x);
252
m_R.x = m_field->Square(t);
253
m_field->Accumulate(m_R.x, t);
254
m_field->Accumulate(m_R.x, m_a);
255
m_field->Accumulate(m_R.y, m_field->Multiply(t, m_R.x));
256
m_field->Accumulate(m_R.y, m_R.x);
257
258
m_R.identity = false;
259
return m_R;
260
}
261
262
// ********************************************************
263
264
#if 0
265
EcPrecomputation<EC2N>& EcPrecomputation<EC2N>::operator=(const EcPrecomputation<EC2N> &rhs)
266
{
267
m_ec = rhs.m_ec;
268
m_ep = rhs.m_ep;
269
m_ep.m_group = m_ec.get();
270
return *this;
271
}
272
273
void EcPrecomputation<EC2N>::SetCurveAndBase(const EC2N &ec, const EC2N::Point &base)
274
{
275
m_ec.reset(new EC2N(ec));
276
m_ep.SetGroupAndBase(*m_ec, base);
277
}
278
279
void EcPrecomputation<EC2N>::Precompute(unsigned int maxExpBits, unsigned int storage)
280
{
281
m_ep.Precompute(maxExpBits, storage);
282
}
283
284
void EcPrecomputation<EC2N>::Load(BufferedTransformation &bt)
285
{
286
BERSequenceDecoder seq(bt);
287
word32 version;
288
BERDecodeUnsigned<word32>(seq, version, INTEGER, 1, 1);
289
m_ep.m_exponentBase.BERDecode(seq);
290
m_ep.m_windowSize = m_ep.m_exponentBase.BitCount() - 1;
291
m_ep.m_bases.clear();
292
while (!seq.EndReached())
293
m_ep.m_bases.push_back(m_ec->BERDecodePoint(seq));
294
seq.MessageEnd();
295
}
296
297
void EcPrecomputation<EC2N>::Save(BufferedTransformation &bt) const
298
{
299
DERSequenceEncoder seq(bt);
300
DEREncodeUnsigned<word32>(seq, 1); // version
301
m_ep.m_exponentBase.DEREncode(seq);
302
for (unsigned i=0; i<m_ep.m_bases.size(); i++)
303
m_ec->DEREncodePoint(seq, m_ep.m_bases[i]);
304
seq.MessageEnd();
305
}
306
307
EC2N::Point EcPrecomputation<EC2N>::Exponentiate(const Integer &exponent) const
308
{
309
return m_ep.Exponentiate(exponent);
310
}
311
312
EC2N::Point EcPrecomputation<EC2N>::CascadeExponentiate(const Integer &exponent, const DL_FixedBasePrecomputation<Element> &pc2, const Integer &exponent2) const
313
{
314
return m_ep.CascadeExponentiate(exponent, static_cast<const EcPrecomputation<EC2N> &>(pc2).m_ep, exponent2);
315
}
316
#endif
317
318
NAMESPACE_END
319
320
#endif
321
322