OpenCBDC Transaction Processor
Loading...
Searching...
No Matches
math.cpp
Go to the documentation of this file.
1// Copyright (c) 2022 MIT Digital Currency Initiative,
2// Federal Reserve Bank of Boston
3// Distributed under the MIT software license, see the accompanying
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6#include "math.hpp"
7
8#include <limits>
9
10// Until std::span is available in C++20, we don't have a bounds-checked way
11// to access the data behind evmc::uint256be.
12// NOLINTBEGIN(cppcoreguidelines-pro-bounds-constant-array-index)
14 auto operator+(const evmc::uint256be& lhs, const evmc::uint256be& rhs)
15 -> evmc::uint256be {
16 auto ret = evmc::uint256be{};
17 auto tmp = uint64_t{};
18 auto carry = uint8_t{};
19 constexpr uint64_t max_val = std::numeric_limits<uint8_t>::max();
20 for(int i = sizeof(lhs.bytes) - 1; i >= 0; i--) {
21 tmp = lhs.bytes[i] + rhs.bytes[i] + carry;
22 carry = static_cast<unsigned char>(tmp > max_val);
23 ret.bytes[i] = (tmp & max_val);
24 }
25 return ret;
26 }
27
28 auto operator-(const evmc::uint256be& lhs, const evmc::uint256be& rhs)
29 -> evmc::uint256be {
30 auto ret = evmc::uint256be{};
31 auto tmp1 = uint64_t{};
32 auto tmp2 = uint64_t{};
33 auto res = uint64_t{};
34 auto borrow = uint8_t{};
35 constexpr uint64_t max_val = std::numeric_limits<uint8_t>::max();
36 for(int i = sizeof(lhs.bytes) - 1; i >= 0; i--) {
37 tmp1 = lhs.bytes[i] + (max_val + 1);
38 tmp2 = rhs.bytes[i] + borrow;
39 res = tmp1 - tmp2;
40 ret.bytes[i] = (res & max_val);
41 borrow = static_cast<unsigned char>(res <= max_val);
42 }
43 return ret;
44 }
45
46 auto operator*(const evmc::uint256be& lhs, const evmc::uint256be& rhs)
47 -> evmc::uint256be {
48 auto ret = evmc::uint256be{};
49 for(size_t i = 0; i < sizeof(lhs.bytes); i++) {
50 auto row = evmc::uint256be{};
51 if(lhs.bytes[i] == 0) {
52 continue;
53 }
54 for(size_t j = 0; j < sizeof(rhs.bytes); j++) {
55 if(rhs.bytes[j] == 0) {
56 continue;
57 }
58 auto shift = (sizeof(lhs.bytes) - i - 1)
59 + (sizeof(rhs.bytes) - j - 1);
60 if(shift >= sizeof(ret.bytes)) {
61 continue;
62 }
63 auto intermediate
64 = static_cast<uint64_t>(lhs.bytes[i] * rhs.bytes[j]);
65 auto tmp = evmc::uint256be(intermediate);
66 tmp = tmp << static_cast<size_t>(shift);
67 row = row + tmp;
68 }
69 ret = ret + row;
70 }
71 return ret;
72 }
73
74 auto operator<<(const evmc::uint256be& lhs, size_t count)
75 -> evmc::uint256be {
76 auto ret = evmc::uint256be{};
77 if(count >= sizeof(lhs.bytes)) {
78 return ret;
79 }
80 for(size_t i = 0; i + count < sizeof(lhs.bytes); i++) {
81 ret.bytes[i] = lhs.bytes[i + count];
82 }
83 return ret;
84 }
85}
86// NOLINTEND(cppcoreguidelines-pro-bounds-constant-array-index)
auto operator+(const evmc::uint256be &lhs, const evmc::uint256be &rhs) -> evmc::uint256be
Adds two uint256be values.
Definition math.cpp:14
auto operator*(const evmc::uint256be &lhs, const evmc::uint256be &rhs) -> evmc::uint256be
Multiplies two uint256be values.
Definition math.cpp:46
auto operator<<(const evmc::uint256be &lhs, size_t count) -> evmc::uint256be
Left shifts a uint256be value by a given number of bytes.
Definition math.cpp:74
auto operator-(const evmc::uint256be &lhs, const evmc::uint256be &rhs) -> evmc::uint256be
Subtracts two uint256be values.
Definition math.cpp:28