Bitcoin Core  31.0.0
P2P Digital Currency
muhash.h
Go to the documentation of this file.
1 // Copyright (c) 2017-present The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #ifndef BITCOIN_CRYPTO_MUHASH_H
6 #define BITCOIN_CRYPTO_MUHASH_H
7 
8 #include <serialize.h>
9 
10 #include <cstddef>
11 #include <cstdint>
12 #include <span>
13 
14 class uint256;
15 
16 class Num3072
17 {
18 private:
19  void FullReduce();
20  bool IsOverflow() const;
21  Num3072 GetInverse() const;
22 
23 public:
24  static constexpr size_t BYTE_SIZE = 384;
25 
26 #ifdef __SIZEOF_INT128__
27  typedef unsigned __int128 double_limb_t;
28  typedef signed __int128 signed_double_limb_t;
29  typedef uint64_t limb_t;
30  typedef int64_t signed_limb_t;
31  static constexpr int LIMBS = 48;
32  static constexpr int SIGNED_LIMBS = 50;
33  static constexpr int LIMB_SIZE = 64;
34  static constexpr int SIGNED_LIMB_SIZE = 62;
35 #else
36  typedef uint64_t double_limb_t;
37  typedef int64_t signed_double_limb_t;
38  typedef uint32_t limb_t;
39  typedef int32_t signed_limb_t;
40  static constexpr int LIMBS = 96;
41  static constexpr int SIGNED_LIMBS = 103;
42  static constexpr int LIMB_SIZE = 32;
43  static constexpr int SIGNED_LIMB_SIZE = 30;
44 #endif
46 
47  // Sanity check for Num3072 constants
48  static_assert(LIMB_SIZE * LIMBS == 3072, "Num3072 isn't 3072 bits");
49  static_assert(sizeof(double_limb_t) == sizeof(limb_t) * 2, "bad size for double_limb_t");
50  static_assert(sizeof(limb_t) * 8 == LIMB_SIZE, "LIMB_SIZE is incorrect");
51  static_assert(SIGNED_LIMB_SIZE * SIGNED_LIMBS > 3072, "SIGNED_LIMBS * SIGNED_LIMB_SIZE is too small");
52  static_assert(3072 / SIGNED_LIMB_SIZE == SIGNED_LIMBS - 1, "Bit 3072 must land in top signed limb");
53 
54  // Hard coded values in MuHash3072 constructor and Finalize
55  static_assert(sizeof(limb_t) == 4 || sizeof(limb_t) == 8, "bad size for limb_t");
56 
57  void Multiply(const Num3072& a);
58  void Divide(const Num3072& a);
59  void SetToOne();
60  void ToBytes(unsigned char (&out)[BYTE_SIZE]);
61 
62  Num3072() { this->SetToOne(); };
63  Num3072(const unsigned char (&data)[BYTE_SIZE]);
64 
66  {
67  for (auto& limb : obj.limbs) {
68  READWRITE(limb);
69  }
70  }
71 };
72 
103 {
104 private:
107 
108  Num3072 ToNum3072(std::span<const unsigned char> in);
109 
110 public:
111  /* The empty set. */
112  MuHash3072() noexcept = default;
113 
114  /* A singleton with variable sized data in it. */
115  explicit MuHash3072(std::span<const unsigned char> in) noexcept;
116 
117  /* Insert a single piece of data into the set. */
118  MuHash3072& Insert(std::span<const unsigned char> in) noexcept;
119 
120  /* Remove a single piece of data from the set. */
121  MuHash3072& Remove(std::span<const unsigned char> in) noexcept;
122 
123  /* Multiply (resulting in a hash for the union of the sets) */
124  MuHash3072& operator*=(const MuHash3072& mul) noexcept;
125 
126  /* Divide (resulting in a hash for the difference of the sets) */
127  MuHash3072& operator/=(const MuHash3072& div) noexcept;
128 
129  /* Finalize into a 32-byte hash. Does not change this object's value. */
130  void Finalize(uint256& out) noexcept;
131 
133  {
134  READWRITE(obj.m_numerator);
135  READWRITE(obj.m_denominator);
136  }
137 };
138 
139 #endif // BITCOIN_CRYPTO_MUHASH_H
Definition: muhash.h:16
limb_t limbs[LIMBS]
Definition: muhash.h:45
uint64_t double_limb_t
Definition: muhash.h:36
static constexpr size_t BYTE_SIZE
Definition: muhash.h:24
uint32_t limb_t
Definition: muhash.h:38
Definition: common.h:29
Num3072()
Definition: muhash.h:62
bool IsOverflow() const
Indicates whether d is larger than the modulus.
Definition: muhash.cpp:116
SERIALIZE_METHODS(Num3072, obj)
Definition: muhash.h:65
Num3072 m_denominator
Definition: muhash.h:106
void Divide(const Num3072 &a)
Definition: muhash.cpp:499
static constexpr int LIMB_SIZE
Definition: muhash.h:42
int32_t signed_limb_t
Definition: muhash.h:39
static constexpr int LIMBS
Definition: muhash.h:40
SERIALIZE_METHODS(MuHash3072, obj)
Definition: muhash.h:132
MuHash3072() noexcept=default
Num3072 m_numerator
Definition: muhash.h:105
void Multiply(const Num3072 &a)
Definition: muhash.cpp:456
Num3072 ToNum3072(std::span< const unsigned char > in)
Definition: muhash.cpp:536
MuHash3072 & Insert(std::span< const unsigned char > in) noexcept
Definition: muhash.cpp:577
int64_t signed_double_limb_t
Definition: muhash.h:37
void Finalize(uint256 &out) noexcept
Definition: muhash.cpp:552
Num3072 GetInverse() const
Definition: muhash.cpp:384
void ToBytes(unsigned char(&out)[BYTE_SIZE])
Definition: muhash.cpp:526
256-bit opaque blob.
Definition: uint256.h:195
static constexpr int SIGNED_LIMB_SIZE
Definition: muhash.h:43
A class representing MuHash sets.
Definition: muhash.h:102
MuHash3072 & Remove(std::span< const unsigned char > in) noexcept
Definition: muhash.cpp:582
void SetToOne()
Definition: muhash.cpp:493
#define READWRITE(...)
Definition: serialize.h:145
void FullReduce()
Definition: muhash.cpp:125
static constexpr int SIGNED_LIMBS
Definition: muhash.h:41