mirror of
https://github.com/codex-storage/nim-poseidon2.git
synced 2025-02-23 08:18:05 +00:00
Only support unmarshalling of little-endian bytes
Big-endian bytes had weird padding; 0's to the right, then a single 0 to the left.
This commit is contained in:
parent
10b4a3659a
commit
03ed357ca4
@ -98,4 +98,4 @@ func merkleRoot*(xs: openArray[F]) : F =
|
|||||||
return merkleRoot(ys)
|
return merkleRoot(ys)
|
||||||
|
|
||||||
func merkleRoot*(bytes: openArray[byte]): F =
|
func merkleRoot*(bytes: openArray[byte]): F =
|
||||||
merkleRoot(seq[F].unmarshal(bytes, littleEndian))
|
merkleRoot(seq[F].unmarshal(bytes))
|
||||||
|
@ -2,32 +2,20 @@ import ./types
|
|||||||
import constantine/math/arithmetic
|
import constantine/math/arithmetic
|
||||||
import constantine/math/io/io_bigints
|
import constantine/math/io/io_bigints
|
||||||
|
|
||||||
func padRight(source: openArray[byte], endian: static Endianness): array[32, byte] =
|
func unmarshal*(_: type F, bytes: openArray[byte]): F =
|
||||||
assert source.len <= 31
|
|
||||||
when endian == littleEndian:
|
|
||||||
copyMem(addr result[0], unsafeAddr source[0], source.len)
|
|
||||||
when endian == bigEndian:
|
|
||||||
copyMem(addr result[1], unsafeAddr source[0], source.len)
|
|
||||||
|
|
||||||
func unmarshal*(
|
|
||||||
_: type F,
|
|
||||||
bytes: openArray[byte],
|
|
||||||
endian: static Endianness): F =
|
|
||||||
assert bytes.len <= 31
|
assert bytes.len <= 31
|
||||||
let padded = bytes.padRight(endian)
|
var padded: array[32, byte]
|
||||||
let bigint = B.unmarshal(padded, endian)
|
copyMem(addr padded[0], unsafeAddr bytes[0], bytes.len)
|
||||||
|
let bigint = B.unmarshal(padded, littleEndian)
|
||||||
return F.fromBig(bigint)
|
return F.fromBig(bigint)
|
||||||
|
|
||||||
func unmarshal*(
|
func unmarshal*(_: type seq[F], bytes: openArray[byte]): seq[F] =
|
||||||
_: type seq[F],
|
|
||||||
bytes: openArray[byte],
|
|
||||||
endian: static Endianness): seq[F] =
|
|
||||||
const chunkLen = 31
|
const chunkLen = 31
|
||||||
var elements: seq[F]
|
var elements: seq[F]
|
||||||
var chunkStart = 0
|
var chunkStart = 0
|
||||||
while chunkStart < bytes.len:
|
while chunkStart < bytes.len:
|
||||||
let chunkEnd = min(chunkStart + 31, bytes.len)
|
let chunkEnd = min(chunkStart + 31, bytes.len)
|
||||||
let element = F.unmarshal(bytes.toOpenArray(chunkStart, chunkEnd - 1), endian)
|
let element = F.unmarshal(bytes.toOpenArray(chunkStart, chunkEnd - 1))
|
||||||
elements.add(element)
|
elements.add(element)
|
||||||
chunkStart += chunkLen
|
chunkStart += chunkLen
|
||||||
return elements
|
return elements
|
||||||
|
@ -7,49 +7,29 @@ import poseidon2/io
|
|||||||
|
|
||||||
suite "unmarshalling":
|
suite "unmarshalling":
|
||||||
|
|
||||||
test "converts big endian bytes into field elements":
|
|
||||||
let bytes = toSeq 1'u8..31'u8
|
|
||||||
let paddedTo32 = @[0x00'u8] & bytes # most significant byte is not used
|
|
||||||
let expected = F.fromBig(B.unmarshal(paddedTo32, bigEndian))
|
|
||||||
let unmarshalled = F.unmarshal(bytes, bigEndian)
|
|
||||||
check bool(unmarshalled == expected)
|
|
||||||
|
|
||||||
test "converts little endian bytes into field elements":
|
test "converts little endian bytes into field elements":
|
||||||
let bytes = toSeq 1'u8..31'u8
|
let bytes = toSeq 1'u8..31'u8
|
||||||
let paddedTo32 = bytes & @[0x00'u8] # most significant byte is not used
|
let paddedTo32 = bytes & @[0'u8] # most significant byte is not used
|
||||||
let expected = F.fromBig(B.unmarshal(paddedTo32, littleEndian))
|
let expected = F.fromBig(B.unmarshal(paddedTo32, littleEndian))
|
||||||
let unmarshalled = F.unmarshal(bytes, littleEndian)
|
let unmarshalled = F.unmarshal(bytes)
|
||||||
check bool(unmarshalled == expected)
|
|
||||||
|
|
||||||
test "pads big endian bytes to the right with 0's":
|
|
||||||
let bytes = @[0x12'u8, 0x34, 0x56]
|
|
||||||
let paddedTo31 = bytes & 0x00'u8.repeat(31 - bytes.len)
|
|
||||||
let paddedTo32 = @[0x00'u8] & paddedTo31 # most significant byte is not used
|
|
||||||
let expected = F.fromBig(B.unmarshal(paddedTo32, bigEndian))
|
|
||||||
let unmarshalled = F.unmarshal(bytes, bigEndian)
|
|
||||||
check bool(unmarshalled == expected)
|
check bool(unmarshalled == expected)
|
||||||
|
|
||||||
test "pads little endian bytes to the right with 0's":
|
test "pads little endian bytes to the right with 0's":
|
||||||
let bytes = @[0x56'u8, 0x34, 0x12]
|
let bytes = @[0x56'u8, 0x34, 0x12]
|
||||||
let paddedTo31 = bytes & 0x00'u8.repeat(31 - bytes.len)
|
let paddedTo32 = bytes & 0'u8.repeat(32 - bytes.len)
|
||||||
let paddedTo32 = paddedTo31 & @[0x00'u8] # most significant byte is not used
|
|
||||||
let expected = F.fromBig(B.unmarshal(paddedTo32, littleEndian))
|
let expected = F.fromBig(B.unmarshal(paddedTo32, littleEndian))
|
||||||
let unmarshalled = F.unmarshal(bytes, littleEndian)
|
let unmarshalled = F.unmarshal(bytes)
|
||||||
check bool(unmarshalled == expected)
|
check bool(unmarshalled == expected)
|
||||||
|
|
||||||
test "converts every 31 bytes into a field element":
|
test "converts every 31 bytes into a field element":
|
||||||
template checkConversion(endian) =
|
let bytes = toSeq 1'u8..80'u8
|
||||||
let bytes = toSeq 1'u8..80'u8
|
let padded = bytes & 0'u8.repeat(93 - bytes.len)
|
||||||
let padded = bytes & 0'u8.repeat(93 - bytes.len)
|
let expected1 = F.fromBig(B.unmarshal(padded[ 0..<31] & @[0'u8], littleEndian))
|
||||||
let expected1 = F.fromBig(B.unmarshal(padded[ 0..<31], endian))
|
let expected2 = F.fromBig(B.unmarshal(padded[31..<62] & @[0'u8], littleEndian))
|
||||||
let expected2 = F.fromBig(B.unmarshal(padded[31..<62], endian))
|
let expected3 = F.fromBig(B.unmarshal(padded[62..<93] & @[0'u8], littleEndian))
|
||||||
let expected3 = F.fromBig(B.unmarshal(padded[62..<93], endian))
|
let elements = seq[F].unmarshal(bytes)
|
||||||
let elements = seq[F].unmarshal(bytes, endian)
|
check elements.len == 3
|
||||||
check elements.len == 3
|
check bool(elements[0] == expected1)
|
||||||
check bool(elements[0] == expected1)
|
check bool(elements[1] == expected2)
|
||||||
check bool(elements[1] == expected2)
|
check bool(elements[2] == expected3)
|
||||||
check bool(elements[2] == expected3)
|
|
||||||
|
|
||||||
checkConversion(littleEndian)
|
|
||||||
checkConversion(bigEndian)
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user