From fbf95e21b824d7a4ec71783bbb39346dcbfc602e Mon Sep 17 00:00:00 2001 From: benbierens Date: Thu, 21 Dec 2023 14:24:43 +0100 Subject: [PATCH] Adds method for converting 32 bytes to field element --- poseidon2/io.nim | 10 +++++++++- tests/poseidon2/testIo.nim | 12 ++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/poseidon2/io.nim b/poseidon2/io.nim index 2c8dd6b..3ca8fca 100644 --- a/poseidon2/io.nim +++ b/poseidon2/io.nim @@ -1,8 +1,9 @@ -import ./types +import std/options import constantine/math/arithmetic import constantine/math/io/io_bigints import constantine/math/io/io_fields import constantine/math/config/curves +import ./types export curves @@ -14,6 +15,13 @@ func fromBytes*(_: type F, bytes: array[31, byte]): F = ## canonical little-endian big integer. F.fromOpenArray(bytes) +func fromBytes*(_: type F, bytes: array[32, byte]): Option[F] = + ## Converts bytes into a field element. The byte array is interpreted as a + ## canonical little-endian big integer. + let big = B.unmarshal(bytes, littleEndian) + if big < F.fieldMod(): + return some(F.fromBig(big)) + func toBytes*(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 most-significant bits are diff --git a/tests/poseidon2/testIo.nim b/tests/poseidon2/testIo.nim index 23b1ce9..2ff6555 100644 --- a/tests/poseidon2/testIo.nim +++ b/tests/poseidon2/testIo.nim @@ -18,6 +18,18 @@ suite "conversion to/from bytes": let unmarshalled = F.fromBytes(bytes) check bool(unmarshalled == expected) + test "converts 32 little endian bytes into a field elements": + let bytes = toArray toSeq 1'u8..32'u8 + let expected = F.fromBig(B.unmarshal(bytes, littleEndian)) + let unmarshalled = F.fromBytes(bytes).get() + check bool(unmarshalled == expected) + + test "convert fails for 32 little endian bytes larger than the prime field": + let bytes = toArray toSeq(255'u8).repeat(32) + let expected = F.fromBig(B.unmarshal(bytes, littleEndian)) + let unmarshalled = F.fromBytes(bytes) + check not unmarshalled.isSome() + test "converts every 31 bytes into a field element": let bytes = toSeq 1'u8..62'u8 let expected1 = F.fromBytes(bytes[0..<31].toArray)