Skip to content

Commit 5fa0036

Browse files
ludamadludamad0
andauthored
fix: broken uint256_t implicit copy (AztecProtocol#3625)
Look at the diff, then consider this code ``` #include <iostream> #include <concepts> class Uint256_t { public: // Conversion operator (explicit) template <std::integral T> explicit operator T() const { std::cout << "Uint256_t conversion operator called\n"; return static_cast<T>(data[0]); } int data[4] = {0,0,0,0}; }; class Field { public: Field() {} // Constructor that takes a Uint256_t Field(int x) { std::cout << "This is silly!!!!" << std::endl; } Field(const Uint256_t& input) { (void)input; std::cout << "Field constructor called\n"; // Additional initialization code here } }; class Toot { public: Toot(Field f) { (void)f; } }; int main() { Uint256_t uint256_value; Field x = uint256_value; Toot t{uint256_value}; return 0; } ``` With std::integral concept on the cast: ``` Field constructor called Field constructor called ``` but without! which was caught in practice passing a uint256 to FieldSponge ``` Field constructor called Uint256_t conversion operator called This is silly!!!! ``` This truncated the field mysteriously! Open-ended implicit conversions are dangerous --------- Co-authored-by: ludamad <adam@aztecprotocol.com>
1 parent 44b8081 commit 5fa0036

File tree

3 files changed

+5
-3
lines changed

3 files changed

+5
-3
lines changed

barretenberg/cpp/src/barretenberg/numeric/uint128/uint128.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#ifdef __i386__
77
#include "barretenberg/common/serialize.hpp"
8+
#include <concepts>
89

910
namespace numeric {
1011

@@ -37,7 +38,7 @@ class alignas(32) uint128_t {
3738
constexpr ~uint128_t() = default;
3839
explicit constexpr operator bool() const { return static_cast<bool>(data[0]); };
3940

40-
template <typename T> explicit constexpr operator T() const { return static_cast<T>(data[0]); };
41+
template <std::integral T> explicit constexpr operator T() const { return static_cast<T>(data[0]); };
4142

4243
[[nodiscard]] constexpr bool get_bit(uint64_t bit_index) const;
4344
[[nodiscard]] constexpr uint64_t get_msb() const;

barretenberg/cpp/src/barretenberg/numeric/uint256/uint256.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "../uint128/uint128.hpp"
1515
#include "barretenberg/common/serialize.hpp"
1616
#include "barretenberg/common/throw_or_abort.hpp"
17+
#include <concepts>
1718
#include <cstdint>
1819
#include <iomanip>
1920
#include <iostream>
@@ -91,7 +92,7 @@ class alignas(32) uint256_t {
9192

9293
explicit constexpr operator bool() const { return static_cast<bool>(data[0]); };
9394

94-
template <typename T> explicit constexpr operator T() const { return static_cast<T>(data[0]); };
95+
template <std::integral T> explicit constexpr operator T() const { return static_cast<T>(data[0]); };
9596

9697
[[nodiscard]] constexpr bool get_bit(uint64_t bit_index) const;
9798
[[nodiscard]] constexpr uint64_t get_msb() const;

barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.fuzzer.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ template <typename Builder> class BigFieldBase {
266266
mask = (uint256_t(1) << mask_size) - 1;
267267
// Choose the bit range
268268
// Return instruction
269-
return { .id = instruction_opcode, .arguments.element = Element(temp & mask) };
269+
return { .id = instruction_opcode, .arguments.element = Element(static_cast<uint64_t>(temp & mask)) };
270270

271271
break;
272272
case OPCODE::RANDOMSEED:

0 commit comments

Comments
 (0)