PRCYCoin  2.0.0.7rc1
P2P Digital Currency
uint256.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin developers
3 // Copyright (c) 2017-2019 The PIVX developers
4 // Distributed under the MIT/X11 software license, see the accompanying
5 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 
7 #include "uint256.h"
8 #include "crypto/common.h"
9 
12 // This implementation directly uses shifts instead of going
13 // through an intermediate MPI representation.
14 uint256& uint256::SetCompact(uint32_t nCompact, bool* pfNegative, bool* pfOverflow)
15 {
16  int nSize = nCompact >> 24;
17  uint32_t nWord = nCompact & 0x007fffff;
18  if (nSize <= 3) {
19  nWord >>= 8 * (3 - nSize);
20  *this = nWord;
21  } else {
22  *this = nWord;
23  *this <<= 8 * (nSize - 3);
24  }
25  if (pfNegative)
26  *pfNegative = nWord != 0 && (nCompact & 0x00800000) != 0;
27  if (pfOverflow)
28  *pfOverflow = nWord != 0 && ((nSize > 34) ||
29  (nWord > 0xff && nSize > 33) ||
30  (nWord > 0xffff && nSize > 32));
31  return *this;
32 }
33 
34 uint32_t uint256::GetCompact(bool fNegative) const
35 {
36  int nSize = (bits() + 7) / 8;
37  uint32_t nCompact = 0;
38  if (nSize <= 3) {
39  nCompact = GetLow64() << 8 * (3 - nSize);
40  } else {
41  uint256 bn = *this >> 8 * (nSize - 3);
42  nCompact = bn.GetLow64();
43  }
44  // The 0x00800000 bit denotes the sign.
45  // Thus, if it is already set, divide the mantissa by 256 and increase the exponent.
46  if (nCompact & 0x00800000) {
47  nCompact >>= 8;
48  nSize++;
49  }
50  assert((nCompact & ~0x007fffff) == 0);
51  assert(nSize < 256);
52  nCompact |= nSize << 24;
53  nCompact |= (fNegative && (nCompact & 0x007fffff) ? 0x00800000 : 0);
54  return nCompact;
55 }
56 
57 static void inline HashMix(uint32_t& a, uint32_t& b, uint32_t& c)
58 {
59  // Taken from lookup3, by Bob Jenkins.
60  a -= c;
61  a ^= ((c << 4) | (c >> 28));
62  c += b;
63  b -= a;
64  b ^= ((a << 6) | (a >> 26));
65  a += c;
66  c -= b;
67  c ^= ((b << 8) | (b >> 24));
68  b += a;
69  a -= c;
70  a ^= ((c << 16) | (c >> 16));
71  c += b;
72  b -= a;
73  b ^= ((a << 19) | (a >> 13));
74  a += c;
75  c -= b;
76  c ^= ((b << 4) | (b >> 28));
77  b += a;
78 }
79 
80 static void inline HashFinal(uint32_t& a, uint32_t& b, uint32_t& c)
81 {
82  // Taken from lookup3, by Bob Jenkins.
83  c ^= b;
84  c -= ((b << 14) | (b >> 18));
85  a ^= c;
86  a -= ((c << 11) | (c >> 21));
87  b ^= a;
88  b -= ((a << 25) | (a >> 7));
89  c ^= b;
90  c -= ((b << 16) | (b >> 16));
91  a ^= c;
92  a -= ((c << 4) | (c >> 28));
93  b ^= a;
94  b -= ((a << 14) | (a >> 18));
95  c ^= b;
96  c -= ((b << 24) | (b >> 8));
97 }
98 
99 uint64_t uint256::GetHash(const uint256& salt) const
100 {
101  uint32_t a, b, c;
102  a = b = c = 0xdeadbeef + (WIDTH << 2);
103 
104  a += pn[0] ^ salt.pn[0];
105  b += pn[1] ^ salt.pn[1];
106  c += pn[2] ^ salt.pn[2];
107  HashMix(a, b, c);
108  a += pn[3] ^ salt.pn[3];
109  b += pn[4] ^ salt.pn[4];
110  c += pn[5] ^ salt.pn[5];
111  HashMix(a, b, c);
112  a += pn[6] ^ salt.pn[6];
113  b += pn[7] ^ salt.pn[7];
114  HashFinal(a, b, c);
115 
116  return ((((uint64_t)b) << 32) | c);
117 }
118 
120 {
121  uint256 b;
122  for(int x=0; x<a.WIDTH; ++x)
123  WriteLE32(b.begin() + x*4, a.pn[x]);
124  return b;
125 }
127 {
129  for(int x=0; x<b.WIDTH; ++x)
130  b.pn[x] = ReadLE32(a.begin() + x*4);
131  return b;
132 }
133 
135 {
136  uint512 b;
137  for(int x=0; x<a.WIDTH; ++x)
138  WriteLE32(b.begin() + x*4, a.pn[x]);
139  return b;
140 }
141 
143 {
145  for(int x=0; x<b.WIDTH; ++x)
146  b.pn[x] = ReadLE32(a.begin() + x*4);
147  return b;
148 }
UintToArith512
arith_uint512 UintToArith512(const uint512 &a)
Definition: uint256.cpp:142
b
void const uint64_t * b
Definition: field_5x52_asm_impl.h:10
base_uint::begin
unsigned char * begin()
Definition: arith_uint256.h:240
arith_uint512
512-bit unsigned big integer.
Definition: arith_uint256.h:377
uint256.h
arith_uint256
256-bit unsigned big integer.
Definition: arith_uint256.h:340
uint256::SetCompact
uint256 & SetCompact(uint32_t nCompact, bool *pfNegative=nullptr, bool *pfOverflow=nullptr)
The "compact" format is a representation of a whole number N using an unsigned 32bit number similar t...
Definition: uint256.cpp:14
base_uint< 256 >::bits
unsigned int bits() const
Returns the position of the highest bit set plus one, or zero if the value is zero.
Definition: arith_uint256.cpp:214
uint256::GetCompact
uint32_t GetCompact(bool fNegative=false) const
Definition: uint256.cpp:34
UintToArith256
arith_uint256 UintToArith256(const uint256 &a)
Definition: uint256.cpp:126
base_uint< 256 >::GetLow64
uint64_t GetLow64() const
Definition: arith_uint256.h:280
uint256
256-bit unsigned big integer.
Definition: uint256.h:38
uint256::GetHash
uint64_t GetHash(const uint256 &salt) const
Definition: uint256.cpp:99
common.h
base_uint< 256 >::WIDTH
@ WIDTH
Definition: arith_uint256.h:33
ArithToUint256
uint256 ArithToUint256(const arith_uint256 &a)
Definition: uint256.cpp:119
ArithToUint512
uint512 ArithToUint512(const arith_uint512 &a)
Definition: uint256.cpp:134
uint512
512-bit unsigned big integer.
Definition: uint256.h:73
base_uint< 256 >::pn
uint32_t pn[WIDTH]
Definition: arith_uint256.h:34