diff --git a/poseidon2/io.nim b/poseidon2/io.nim index 33b822f..cc612ab 100644 --- a/poseidon2/io.nim +++ b/poseidon2/io.nim @@ -1,6 +1,7 @@ import ./types import constantine/math/arithmetic import constantine/math/io/io_bigints +import constantine/math/config/curves func unmarshal*(_: type F, bytes: openArray[byte]): F = ## Converts bytes into a field element. The byte array is interpreted as a @@ -25,3 +26,9 @@ func unmarshal*(_: type seq[F], bytes: openArray[byte]): seq[F] = elements.add(element) chunkStart += chunkLen return elements + +func marshal*(element: F): array[32, byte] = + ## Converts a field element into its canonical representation in little-endian + ## byte order. Uses at most 254 bits, the remaining 6 most-significant bits + ## are set to 0. + assert marshal(result, element.toBig(), littleEndian) diff --git a/tests/poseidon2/testIo.nim b/tests/poseidon2/testIo.nim index 98c5a80..e416ff5 100644 --- a/tests/poseidon2/testIo.nim +++ b/tests/poseidon2/testIo.nim @@ -33,3 +33,9 @@ suite "unmarshalling": check bool(elements[1] == expected2) check bool(elements[2] == expected3) + test "converts field element into little-endian bytes": + var element: F + setMinusOne(element) # largest element in the field + var expected: array[32, byte] + marshal(expected, element.toBig(), littleEndian) + check element.marshal() == expected