Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
BigNumber.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
7#include <algorithm>
8#include <openssl/bn.h>
9#include <openssl/crypto.h>
10
12 : _bn(BN_new())
13{ }
14
16 : _bn(BN_dup(bn.BN()))
17{
18}
19
21{
22 BN_free(_bn);
23}
24
26{
27 SetDword(uint32(abs(val)));
28 if (val < 0)
29 BN_set_negative(_bn, 1);
30}
31
33{
34 BN_set_word(_bn, val);
35}
36
38{
39 BN_set_word(_bn, (uint32)(val >> 32));
40 BN_lshift(_bn, _bn, 32);
41 BN_add_word(_bn, (uint32)(val & 0xFFFFFFFF));
42}
43
44void BigNumber::SetBinary(uint8 const* bytes, int32 len, bool littleEndian)
45{
46 if (littleEndian)
47 {
48#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L
49 uint8* array = new uint8[len];
50
51 for (int i = 0; i < len; i++)
52 array[i] = bytes[len - 1 - i];
53
54 BN_bin2bn(array, len, _bn);
55
56 delete[] array;
57#else
58 BN_lebin2bn(bytes, len, _bn);
59#endif
60 }
61 else
62 BN_bin2bn(bytes, len, _bn);
63}
64
65void BigNumber::SetHexStr(char const* str)
66{
67 BN_hex2bn(&_bn, str);
68}
69
71{
72 BN_rand(_bn, numbits, 0, 1);
73}
74
76{
77 if (this == &bn)
78 return *this;
79
80 BN_copy(_bn, bn._bn);
81 return *this;
82}
83
85{
86 BN_add(_bn, _bn, bn._bn);
87 return *this;
88}
89
91{
92 BN_sub(_bn, _bn, bn._bn);
93 return *this;
94}
95
97{
98 BN_CTX* bnctx;
99
100 bnctx = BN_CTX_new();
101 BN_mul(_bn, _bn, bn._bn, bnctx);
102 BN_CTX_free(bnctx);
103
104 return *this;
105}
106
108{
109 BN_CTX* bnctx;
110
111 bnctx = BN_CTX_new();
112 BN_div(_bn, NULL, _bn, bn._bn, bnctx);
113 BN_CTX_free(bnctx);
114
115 return *this;
116}
117
119{
120 BN_CTX* bnctx;
121
122 bnctx = BN_CTX_new();
123 BN_mod(_bn, _bn, bn._bn, bnctx);
124 BN_CTX_free(bnctx);
125
126 return *this;
127}
128
130{
131 BigNumber ret;
132 BN_CTX* bnctx;
133
134 bnctx = BN_CTX_new();
135 BN_exp(ret._bn, _bn, bn._bn, bnctx);
136 BN_CTX_free(bnctx);
137
138 return ret;
139}
140
141BigNumber BigNumber::ModExp(BigNumber const& bn1, BigNumber const& bn2) const
142{
143 BigNumber ret;
144 BN_CTX* bnctx;
145
146 bnctx = BN_CTX_new();
147 BN_mod_exp(ret._bn, _bn, bn1._bn, bn2._bn, bnctx);
148 BN_CTX_free(bnctx);
149
150 return ret;
151}
152
154{
155 return BN_num_bytes(_bn);
156}
157
159{
160 return (uint32)BN_get_word(_bn);
161}
162
164{
165 return BN_is_zero(_bn);
166}
167
168
169void BigNumber::GetBytes(uint8* buf, size_t bufsize, bool littleEndian) const
170{
171#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER < 0x10100000L
172 int nBytes = GetNumBytes();
173 ASSERT(nBytes >= 0);
174 std::size_t numBytes = static_cast<std::size_t>(nBytes);
175
176 // too large to store
177 ASSERT(numBytes <= bufsize);
178
179 // If we need more bytes than length of BigNumber set the rest to 0
180 if (numBytes < bufsize)
181 memset((void*)buf, 0, bufsize);
182
183 BN_bn2bin(_bn, buf + (bufsize - numBytes));
184
185 // openssl's BN stores data internally in big endian format, reverse if little endian desired
186 if (littleEndian)
187 std::reverse(buf, buf + bufsize);
188#else
189 int res = littleEndian ? BN_bn2lebinpad(_bn, buf, bufsize) : BN_bn2binpad(_bn, buf, bufsize);
190 ASSERT(res > 0);
191#endif
192}
193
194std::vector<uint8> BigNumber::ToByteVector(int32 minSize, bool littleEndian) const
195{
196 std::size_t length = GetNumBytes() > minSize ? GetNumBytes() : minSize;
197 std::vector<uint8> v;
198 v.resize(length);
199 GetBytes(v.data(), length, littleEndian);
200 return v;
201}
202
204{
205 return BN_bn2hex(_bn);
206}
207
209{
210 return BN_bn2dec(_bn);
211}
212
std::int32_t int32
Definition Define.h:73
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
std::uint64_t uint64
Definition Define.h:76
#define ASSERT
Definition Errors.h:29
BigNumber Exp(BigNumber const &) const
struct bignum_st * BN()
Definition BigNumber.h:86
BigNumber ModExp(BigNumber const &bn1, BigNumber const &bn2) const
std::vector< uint8 > ToByteVector(int32 minSize=0, bool littleEndian=true) const
BigNumber operator%=(BigNumber const &bn)
void SetRand(int32 numbits)
Definition BigNumber.cpp:70
void SetDword(int32)
Definition BigNumber.cpp:25
uint32 AsDword()
void SetBinary(uint8 const *bytes, int32 len, bool littleEndian=true)
Definition BigNumber.cpp:44
BigNumber operator*=(BigNumber const &bn)
Definition BigNumber.cpp:96
void SetHexStr(char const *str)
Definition BigNumber.cpp:65
char * AsHexStr() const
char * AsDecStr() const
int32 GetNumBytes(void) const
BigNumber operator+=(BigNumber const &bn)
Definition BigNumber.cpp:84
struct bignum_st * _bn
Definition BigNumber.h:106
BigNumber operator/=(BigNumber const &bn)
bool isZero() const
void GetBytes(uint8 *buf, size_t bufsize, bool littleEndian=true) const
void SetQword(uint64)
Definition BigNumber.cpp:37
BigNumber & operator=(BigNumber const &bn)
Definition BigNumber.cpp:75
BigNumber operator-=(BigNumber const &bn)
Definition BigNumber.cpp:90