Merge pull request #65 from status-im/ssz-le
ssz: switch to little-endian
This commit is contained in:
commit
55128978ba
|
@ -20,20 +20,20 @@ from milagro_crypto import getRaw, fromRaw
|
|||
# toBytesSSZ convert simple fixed-length types to their SSZ wire representation
|
||||
func toBytesSSZ(x: SomeInteger): array[sizeof(x), byte] =
|
||||
## Convert directly to bytes the size of the int. (e.g. ``uint16 = 2 bytes``)
|
||||
## All integers are serialized as **big endian**.
|
||||
## All integers are serialized as **little endian**.
|
||||
|
||||
when x.sizeof == 8: bigEndian64(result.addr, x.unsafeAddr)
|
||||
elif x.sizeof == 4: bigEndian32(result.addr, x.unsafeAddr)
|
||||
elif x.sizeof == 2: bigEndian16(result.addr, x.unsafeAddr)
|
||||
when x.sizeof == 8: littleEndian64(result.addr, x.unsafeAddr)
|
||||
elif x.sizeof == 4: littleEndian32(result.addr, x.unsafeAddr)
|
||||
elif x.sizeof == 2: littleEndian16(result.addr, x.unsafeAddr)
|
||||
elif x.sizeof == 1: copyMem(result.addr, x.unsafeAddr, sizeof(result))
|
||||
else: {.fatal: "Unsupported type serialization: " & $(type(x)).name.}
|
||||
|
||||
func toBytesSSZ(x: Uint24): array[3, byte] =
|
||||
## Integers are all encoded as bigendian and not padded
|
||||
## Integers are all encoded as little endian and not padded
|
||||
let v = x.uint32
|
||||
result[2] = byte(v and 0xff)
|
||||
result[0] = byte(v and 0xff)
|
||||
result[1] = byte((v shr 8) and 0xff)
|
||||
result[0] = byte((v shr 16) and 0xff)
|
||||
result[2] = byte((v shr 16) and 0xff)
|
||||
|
||||
func toBytesSSZ(x: bool): array[1, byte] =
|
||||
[if x: 1'u8 else: 0'u8]
|
||||
|
@ -74,7 +74,7 @@ func sszLen(v: seq | array): int =
|
|||
# there's enough data in the buffer
|
||||
func fromBytesSSZUnsafe(T: typedesc[SomeInteger], data: pointer): T =
|
||||
## Convert directly to bytes the size of the int. (e.g. ``uint16 = 2 bytes``)
|
||||
## All integers are serialized as **big endian**.
|
||||
## All integers are serialized as **little endian**.
|
||||
## TODO: Assumes data points to a sufficiently large buffer
|
||||
|
||||
# TODO: any better way to get a suitably aligned buffer in nim???
|
||||
|
@ -83,9 +83,9 @@ func fromBytesSSZUnsafe(T: typedesc[SomeInteger], data: pointer): T =
|
|||
var alignedBuf = cast[ptr byte](tmp.addr)
|
||||
copyMem(alignedBuf, data, result.sizeof)
|
||||
|
||||
when result.sizeof == 8: bigEndian64(result.addr, alignedBuf)
|
||||
elif result.sizeof == 4: bigEndian32(result.addr, alignedBuf)
|
||||
elif result.sizeof == 2: bigEndian16(result.addr, alignedBuf)
|
||||
when result.sizeof == 8: littleEndian64(result.addr, alignedBuf)
|
||||
elif result.sizeof == 4: littleEndian32(result.addr, alignedBuf)
|
||||
elif result.sizeof == 2: littleEndian16(result.addr, alignedBuf)
|
||||
elif result.sizeof == 1: copyMem(result.addr, alignedBuf, sizeof(result))
|
||||
else: {.fatal: "Unsupported type deserialization: " & $(type(result)).name.}
|
||||
|
||||
|
@ -95,12 +95,12 @@ func fromBytesSSZUnsafe(T: typedesc[bool], data: pointer): T =
|
|||
fromBytesSSZUnsafe(uint8, data) != 0
|
||||
|
||||
func fromBytesSSZUnsafe(T: typedesc[Uint24], data: pointer): T =
|
||||
## Integers are all encoded as bigendian and not padded
|
||||
## Integers are all encoded as littleendian and not padded
|
||||
var tmp: uint32
|
||||
let p = cast[ptr UncheckedArray[byte]](data)
|
||||
tmp = tmp or uint32(p[2])
|
||||
tmp = tmp or uint32(p[0])
|
||||
tmp = tmp or uint32(p[1]) shl 8
|
||||
tmp = tmp or uint32(p[0]) shl 16
|
||||
tmp = tmp or uint32(p[2]) shl 16
|
||||
result = tmp.Uint24
|
||||
|
||||
func fromBytesSSZUnsafe(T: typedesc[EthAddress], data: pointer): T =
|
||||
|
@ -212,7 +212,7 @@ func serialize[T: not enum](dest: var seq[byte], src: T) =
|
|||
|
||||
# Write size (we only know it once we've serialized the object!)
|
||||
var objLen = dest.len() - lenPos - 4
|
||||
bigEndian32(dest[lenPos].addr, objLen.addr)
|
||||
littleEndian32(dest[lenPos].addr, objLen.addr)
|
||||
|
||||
# ################### Core functions ###################################
|
||||
|
||||
|
@ -262,12 +262,12 @@ func merkleHash[T](lst: openArray[T]): array[32, byte]
|
|||
|
||||
func hash_tree_root*(x: SomeInteger | bool): array[sizeof(x), byte] =
|
||||
## Convert directly to bytes the size of the int. (e.g. ``uint16 = 2 bytes``)
|
||||
## All integers are serialized as **big endian**.
|
||||
## All integers are serialized as **little endian**.
|
||||
toBytesSSZ(x)
|
||||
|
||||
func hash_tree_root*(x: Uint24): array[3, byte] =
|
||||
## Convert directly to bytes the size of the int. (e.g. ``uint16 = 2 bytes``)
|
||||
## All integers are serialized as **big endian**.
|
||||
## All integers are serialized as **little endian**.
|
||||
toBytesSSZ(x)
|
||||
|
||||
func hash_tree_root*(x: EthAddress): array[sizeof(x), byte] =
|
||||
|
@ -333,7 +333,7 @@ func merkleHash[T](lst: openArray[T]): array[32, byte] =
|
|||
# Store length of list (to compensate for non-bijectiveness of padding)
|
||||
var dataLen: array[32, byte]
|
||||
var lstLen = uint64(len(lst))
|
||||
bigEndian64(dataLen[32-8].addr, lstLen.addr)
|
||||
littleEndian64(dataLen[32-8].addr, lstLen.addr)
|
||||
|
||||
# Divide into chunks
|
||||
var chunkz: seq[seq[byte]]
|
||||
|
|
|
@ -39,14 +39,14 @@ suite "Simple serialization":
|
|||
)
|
||||
|
||||
var expected_ser = @[
|
||||
byte 0, 0, 0, 67, # length
|
||||
byte 67, 0, 0, 0, # length
|
||||
5,
|
||||
'\xFF'.ord, '\xFF'.ord, '\xFF'.ord, '\xFD'.ord,
|
||||
0xFD, 0xFF, 0xFF, 0xFF,
|
||||
]
|
||||
expected_ser &= EthAddress.filled(byte 35)
|
||||
expected_ser &= MDigest[256].filled(byte 35).data
|
||||
expected_ser &= [byte 0, 0, 0, 3, 'c'.ord, 'o'.ord, 'w'.ord]
|
||||
expected_ser &= [byte 0, 0, 79]
|
||||
expected_ser &= [byte 3, 0, 0, 0, 'c'.ord, 'o'.ord, 'w'.ord]
|
||||
expected_ser &= [byte 79, 0, 0]
|
||||
|
||||
test "Object deserialization":
|
||||
let deser = expected_ser.deserialize(Foo).get()
|
||||
|
@ -119,5 +119,5 @@ suite "Tree hashing":
|
|||
check: hash_tree_root(bb).len > 0
|
||||
|
||||
test "Hash integer":
|
||||
check: hash_tree_root(0x01'u32) == [0'u8, 0, 0, 1] # big endian!
|
||||
check: hash_tree_root(Uint24(0x01)) == [0'u8, 0, 1] # big endian!
|
||||
check: hash_tree_root(0x01'u32) == [1'u8, 0, 0, 0] # little endian!
|
||||
check: hash_tree_root(Uint24(0x01)) == [1'u8, 0, 0] # little endian!
|
||||
|
|
Loading…
Reference in New Issue