1

With regards to the monero Genesis TX breakdown. I'm still puzzled as to how they got the Decimal number (17592186044415) = (ffffffffffff03) in the genesis block.

Does one simply use a Hex to Decimal converter ? What conversion is used ? I thought it was a hexadecimal number but I don't get the correct one when converting ffffffffffff03.

user36303
  • 34,858
  • 2
  • 57
  • 123
W. Kadou
  • 125
  • 8

1 Answers1

2

The encoding of a varint is answered in this comment. It's not a straight hex string to decimal conversion.

From the specification:

Varints are a method of serializing integers using one or more bytes. Smaller numbers take a smaller number of bytes.

Each byte in a varint, except the last byte, has the most significant bit (msb) set – this indicates that there are further bytes to come. The lower 7 bits of each byte are used to store the two's complement representation of the number in groups of 7 bits, least significant group first.

Therefore, you first drop the MSB of each 8 bit group then reverse the order of the remaining 7 bit groups (because varints store numbers with the least significant group first).

So in the case of FFFFFFFFFFFF03:

FFFFFFFFFFFF03 = 11111111111111111111111111111111111111111111111100000011
converts to
0000011111111111111111111111111111111111111111111
which is
17592186044415
jtgrassie
  • 19,111
  • 4
  • 14
  • 51
  • 1
    Thanks a million, this did help me. Sorry for responding late – W. Kadou Jun 25 '18 at 22:29
  • Am I correct in thinking varints occupy up to 9 bytes of space, and can contain up to 63 bits of information? based on section 1.2 here https://tukaani.org/xz/xz-file-format.txt – koe Jan 06 '20 at 03:17
  • "Am I correct in thinking varints occupy up to 9 bytes of space, and can contain up to 63 bits of information?" <- No you are incorrect. Varints can be as small as 1 byte and in theory, any size as a maximum. It even states this in the part I quoted from the spec. In Monero the range used is 1 byte to 8 bytes, because they are typically decoded to unsigned 64 bit integers. As you lose N-1 bits due to the encoding, for an 8 byte varint the maximum decoded value would be 2^57-1 – jtgrassie Jan 06 '20 at 03:23
  • If I'm understanding right, is it 2^57 instead of 2^56 because the MSB of the 8th byte is, unlike the previous 7 bytes, an information bit? – koe Jan 06 '20 at 03:51
  • 1
    A normal, max 8 bytes number is 2^64-1. With a varint you would have to remove 7 bits from your 64 bits because the most significant bit of each byte is used to signify another byte is needed. Thus (N-1) as in 8 bytes minus the last byte is 7. 7 bits used in the encoding. 64-7 = 57. Max 57 bit number is 2^57-1 - as I stated in previous comment. Checking the Monero source, it treats the last byte just as the others, so only 7 bits can be used from that also. If the 8th bit of that bytes is set, it's considered an overflow. So yes, in fact the max number would be 2^56-1. – jtgrassie Jan 06 '20 at 05:03
  • I'm also ignoring the other type of varints you can find in Monero code! EPEE has another type it uses in its binary serialization. Not relevant to this question however. – jtgrassie Jan 06 '20 at 05:42