Clearmatics Libff  0.1
C++ library for Finite Fields and Elliptic Curves
serialization.cpp
Go to the documentation of this file.
1 
10 
11 #include <assert.h>
12 #include <stdexcept>
13 
14 namespace libff
15 {
16 
17 // Converts a single character to a nibble. Throws std::invalid_argument if the
18 // character is not hex.
19 uint8_t char_to_nibble(const char c)
20 {
21  const char cc = (char)std::tolower(c);
22  if (cc < '0') {
23  throw std::invalid_argument("invalid hex character");
24  }
25  if (cc <= '9') {
26  return cc - '0';
27  }
28  if (cc < 'a') {
29  throw std::invalid_argument("invalid hex character");
30  }
31  if (cc <= 'f') {
32  return cc - 'a' + 10;
33  }
34  throw std::invalid_argument("invalid hex character");
35 }
36 
37 static uint8_t chars_to_byte(const char *cs)
38 {
39  const uint8_t *data = (const uint8_t *)cs;
40  return (char_to_nibble(data[0]) << 4) | char_to_nibble(data[1]);
41 }
42 
43 static char nibble_hex(const uint8_t nibble)
44 {
45  assert((nibble & 0xf0) == 0);
46  if (nibble > 9) {
47  return (char)('a' + nibble - 10);
48  }
49 
50  return (char)('0' + nibble);
51 }
52 
55 static const char *find_hex_string_of_length(
56  const std::string &hex, const size_t bytes)
57 {
58  if ('0' == hex[0] && 'x' == hex[1]) {
59  if (hex.size() != 2 + bytes * 2) {
60  throw std::invalid_argument("invalid hex length");
61  }
62  return hex.c_str() + 2;
63  }
64 
65  if (hex.size() != bytes * 2) {
66  throw std::invalid_argument("invalid hex length");
67  }
68 
69  return hex.c_str();
70 }
71 
72 void hex_to_bytes_reversed(const std::string &hex, void *dest, size_t bytes)
73 {
74  if (bytes == 0) {
75  return;
76  }
77  const char *cur = find_hex_string_of_length(hex, bytes);
78  uint8_t *const dest_bytes_end = (uint8_t *)dest;
79  uint8_t *dest_bytes = dest_bytes_end + bytes;
80  do {
81  --dest_bytes;
82  *dest_bytes = chars_to_byte(cur);
83  cur += 2;
84  } while (dest_bytes > dest_bytes_end);
85 }
86 
88  const void *bytes, size_t num_bytes, bool prefix)
89 {
90  if (num_bytes == 0) {
91  return "";
92  }
93 
94  std::string out;
95  if (prefix) {
96  out.reserve(num_bytes * 2 + 2);
97  out.push_back('0');
98  out.push_back('x');
99  } else {
100  out.reserve(num_bytes * 2);
101  }
102 
103  const uint8_t *const src_bytes_end = (const uint8_t *)bytes;
104  const uint8_t *src_bytes = src_bytes_end + num_bytes;
105  do {
106  --src_bytes;
107  const uint8_t byte = *src_bytes;
108  out.push_back(nibble_hex(byte >> 4));
109  out.push_back(nibble_hex(byte & 0x0f));
110  } while (src_bytes > src_bytes_end);
111 
112  return out;
113 }
114 
115 } // namespace libff
libff
Definition: ffi.cpp:8
libff::hex_to_bytes_reversed
void hex_to_bytes_reversed(const std::string &hex, void *dest, size_t bytes)
Definition: serialization.cpp:72
libff::char_to_nibble
uint8_t char_to_nibble(const char c)
Definition: serialization.cpp:19
serialization.hpp
libff::bytes_to_hex_reversed
std::string bytes_to_hex_reversed(const void *bytes, size_t num_bytes, bool prefix)
"prefix" here refers to "0x"
Definition: serialization.cpp:87