Electroneum
rctTypes.cpp
Go to the documentation of this file.
1 // Copyright (c) 2016, Electroneum Research Labs
2 //
3 // Author: Shen Noether <shen.noether@gmx.com>
4 //
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without modification, are
8 // permitted provided that the following conditions are met:
9 //
10 // 1. Redistributions of source code must retain the above copyright notice, this list of
11 // conditions and the following disclaimer.
12 //
13 // 2. Redistributions in binary form must reproduce the above copyright notice, this list
14 // of conditions and the following disclaimer in the documentation and/or other
15 // materials provided with the distribution.
16 //
17 // 3. Neither the name of the copyright holder nor the names of its contributors may be
18 // used to endorse or promote products derived from this software without specific
19 // prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
22 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
23 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
24 // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
29 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 #include "misc_log_ex.h"
32 #include "cryptonote_config.h"
33 #include "rctTypes.h"
34 using namespace crypto;
35 using namespace std;
36 
37 #undef ELECTRONEUM_DEFAULT_LOG_CATEGORY
38 #define ELECTRONEUM_DEFAULT_LOG_CATEGORY "ringct"
39 
40 namespace rct {
41 
42  //dp
43  //Debug printing for the above types
44  //Actually use DP(value) and #define DBG
45 
46  void dp(key a) {
47  int j = 0;
48  printf("\"");
49  for (j = 0; j < 32; j++) {
50  printf("%02x", (unsigned char)a.bytes[j]);
51  }
52  printf("\"");
53  printf("\n");
54  }
55 
56  void dp(bool a) {
57  printf(" ... %s ... ", a ? "true" : "false");
58  printf("\n");
59  }
60 
61  void dp(const char * a, int l) {
62  int j = 0;
63  printf("\"");
64  for (j = 0; j < l; j++) {
65  printf("%02x", (unsigned char)a[j]);
66  }
67  printf("\"");
68  printf("\n");
69  }
70  void dp(keyV a) {
71  size_t j = 0;
72  printf("[");
73  for (j = 0; j < a.size(); j++) {
74  dp(a[j]);
75  if (j < a.size() - 1) {
76  printf(",");
77  }
78  }
79  printf("]");
80  printf("\n");
81  }
82  void dp(keyM a) {
83  size_t j = 0;
84  printf("[");
85  for (j = 0; j < a.size(); j++) {
86  dp(a[j]);
87  if (j < a.size() - 1) {
88  printf(",");
89  }
90  }
91  printf("]");
92  printf("\n");
93  }
94  void dp(etn_amount vali) {
95  printf("x: ");
96  std::cout << vali;
97  printf("\n\n");
98  }
99 
100  void dp(int vali) {
101  printf("x: %d\n", vali);
102  printf("\n");
103  }
104  void dp(bits amountb) {
105  for (int i = 0; i < 64; i++) {
106  printf("%d", amountb[i]);
107  }
108  printf("\n");
109 
110  }
111 
112  void dp(const char * st) {
113  printf("%s\n", st);
114  }
115 
116  //Various Conversions
117 
118  //uint long long to 32 byte key
119  void d2h(key & amounth, const etn_amount in) {
120  sc_0(amounth.bytes);
121  etn_amount val = in;
122  int i = 0;
123  while (val != 0) {
124  amounth[i] = (unsigned char)(val & 0xFF);
125  i++;
126  val /= (etn_amount)256;
127  }
128  }
129 
130  //uint long long to 32 byte key
131  key d2h(const etn_amount in) {
132  key amounth;
133  sc_0(amounth.bytes);
134  etn_amount val = in;
135  int i = 0;
136  while (val != 0) {
137  amounth[i] = (unsigned char)(val & 0xFF);
138  i++;
139  val /= (etn_amount)256;
140  }
141  return amounth;
142  }
143 
144  //uint long long to int[64]
145  void d2b(bits amountb, etn_amount val) {
146  int i = 0;
147  while (val != 0) {
148  amountb[i] = val & 1;
149  i++;
150  val >>= 1;
151  }
152  while (i < 64) {
153  amountb[i] = 0;
154  i++;
155  }
156  }
157 
158  //32 byte key to uint long long
159  // if the key holds a value > 2^64
160  // then the value in the first 8 bytes is returned
161  etn_amount h2d(const key & test) {
162  etn_amount vali = 0;
163  int j = 0;
164  for (j = 7; j >= 0; j--) {
165  vali = (etn_amount)(vali * 256 + (unsigned char)test.bytes[j]);
166  }
167  return vali;
168  }
169 
170  //32 byte key to int[64]
171  void h2b(bits amountb2, const key & test) {
172  int val = 0, i = 0, j = 0;
173  for (j = 0; j < 8; j++) {
174  val = (unsigned char)test.bytes[j];
175  i = 8 * j;
176  while (val != 0) {
177  amountb2[i] = val & 1;
178  i++;
179  val >>= 1;
180  }
181  while (i < 8 * (j + 1)) {
182  amountb2[i] = 0;
183  i++;
184  }
185  }
186  }
187 
188  //int[64] to 32 byte key
189  void b2h(key & amountdh, const bits amountb2) {
190  int byte, i, j;
191  for (j = 0; j < 8; j++) {
192  byte = 0;
193  i = 8 * j;
194  for (i = 7; i > -1; i--) {
195  byte = byte * 2 + amountb2[8 * j + i];
196  }
197  amountdh[j] = (unsigned char)byte;
198  }
199  for (j = 8; j < 32; j++) {
200  amountdh[j] = (unsigned char)(0x00);
201  }
202  }
203 
204  //int[64] to uint long long
205  etn_amount b2d(bits amountb) {
206  etn_amount vali = 0;
207  int j = 0;
208  for (j = 63; j >= 0; j--) {
209  vali = (etn_amount)(vali * 2 + amountb[j]);
210  }
211  return vali;
212  }
213 
214  bool is_rct_simple(int type)
215  {
216  switch (type)
217  {
218  case RCTTypeSimple:
219  case RCTTypeBulletproof:
220  case RCTTypeBulletproof2:
221  return true;
222  default:
223  return false;
224  }
225  }
226 
227  bool is_rct_bulletproof(int type)
228  {
229  switch (type)
230  {
231  case RCTTypeBulletproof:
232  case RCTTypeBulletproof2:
233  return true;
234  default:
235  return false;
236  }
237  }
238 
239  bool is_rct_borromean(int type)
240  {
241  switch (type)
242  {
243  case RCTTypeSimple:
244  case RCTTypeFull:
245  return true;
246  default:
247  return false;
248  }
249  }
250 
251  size_t n_bulletproof_amounts(const Bulletproof &proof)
252  {
253  CHECK_AND_ASSERT_MES(proof.L.size() >= 6, 0, "Invalid bulletproof L size");
254  CHECK_AND_ASSERT_MES(proof.L.size() == proof.R.size(), 0, "Mismatched bulletproof L/R size");
255  static const size_t extra_bits = 4;
256  static_assert((1 << extra_bits) == BULLETPROOF_MAX_OUTPUTS, "log2(BULLETPROOF_MAX_OUTPUTS) is out of date");
257  CHECK_AND_ASSERT_MES(proof.L.size() <= 6 + extra_bits, 0, "Invalid bulletproof L size");
258  CHECK_AND_ASSERT_MES(proof.V.size() <= (1u<<(proof.L.size()-6)), 0, "Invalid bulletproof V/L");
259  CHECK_AND_ASSERT_MES(proof.V.size() * 2 > (1u<<(proof.L.size()-6)), 0, "Invalid bulletproof V/L");
260  CHECK_AND_ASSERT_MES(proof.V.size() > 0, 0, "Empty bulletproof");
261  return proof.V.size();
262  }
263 
264  size_t n_bulletproof_amounts(const std::vector<Bulletproof> &proofs)
265  {
266  size_t n = 0;
267  for (const Bulletproof &proof: proofs)
268  {
269  size_t n2 = n_bulletproof_amounts(proof);
270  CHECK_AND_ASSERT_MES(n2 < std::numeric_limits<uint32_t>::max() - n, 0, "Invalid number of bulletproofs");
271  if (n2 == 0)
272  return 0;
273  n += n2;
274  }
275  return n;
276  }
277 
279  {
280  CHECK_AND_ASSERT_MES(proof.L.size() >= 6, 0, "Invalid bulletproof L size");
281  CHECK_AND_ASSERT_MES(proof.L.size() == proof.R.size(), 0, "Mismatched bulletproof L/R size");
282  static const size_t extra_bits = 4;
283  static_assert((1 << extra_bits) == BULLETPROOF_MAX_OUTPUTS, "log2(BULLETPROOF_MAX_OUTPUTS) is out of date");
284  CHECK_AND_ASSERT_MES(proof.L.size() <= 6 + extra_bits, 0, "Invalid bulletproof L size");
285  return 1 << (proof.L.size() - 6);
286  }
287 
288  size_t n_bulletproof_max_amounts(const std::vector<Bulletproof> &proofs)
289  {
290  size_t n = 0;
291  for (const Bulletproof &proof: proofs)
292  {
293  size_t n2 = n_bulletproof_max_amounts(proof);
294  CHECK_AND_ASSERT_MES(n2 < std::numeric_limits<uint32_t>::max() - n, 0, "Invalid number of bulletproofs");
295  if (n2 == 0)
296  return 0;
297  n += n2;
298  }
299  return n;
300  }
301 
302 }
void dp(const char *st)
Definition: rctTypes.cpp:112
bool is_rct_borromean(int type)
Definition: rctTypes.cpp:239
etn_amount h2d(const key &test)
Definition: rctTypes.cpp:161
#define CHECK_AND_ASSERT_MES(expr, fail_ret_val, message)
Definition: misc_log_ex.h:181
void sc_0(unsigned char *)
bool is_rct_simple(int type)
Definition: rctTypes.cpp:214
size_t n_bulletproof_max_amounts(const std::vector< Bulletproof > &proofs)
Definition: rctTypes.cpp:288
crypto namespace.
Definition: crypto.cpp:58
#define BULLETPROOF_MAX_OUTPUTS
STL namespace.
void d2b(bits amountb, etn_amount val)
Definition: rctTypes.cpp:145
rct::keyV R
Definition: rctTypes.h:184
size_t n_bulletproof_amounts(const std::vector< Bulletproof > &proofs)
Definition: rctTypes.cpp:264
std::vector< key > keyV
Definition: rctTypes.h:88
bool is_rct_bulletproof(int type)
Definition: rctTypes.cpp:227
uint64_t etn_amount
Definition: rctTypes.h:135
rct::keyV L
Definition: rctTypes.h:184
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1124
std::vector< keyV > keyM
Definition: rctTypes.h:89
key d2h(const etn_amount in)
Definition: rctTypes.cpp:131
unsigned char bytes[32]
Definition: rctTypes.h:86
etn_amount b2d(bits amountb)
Definition: rctTypes.cpp:205
void b2h(key &amountdh, const bits amountb2)
Definition: rctTypes.cpp:189
void h2b(bits amountb2, const key &test)
Definition: rctTypes.cpp:171
unsigned int bits[ATOMS]
Definition: rctTypes.h:136
rct::keyV V
Definition: rctTypes.h:181