From aceccb23672c96d6962ad323e828abf4f2534447 Mon Sep 17 00:00:00 2001 From: Dmitriy Ryajov Date: Mon, 18 Dec 2023 16:03:48 -0600 Subject: [PATCH 1/6] style check complains about style in codex --- poseidon2/compress.nim | 2 +- poseidon2/permutation.nim | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/poseidon2/compress.nim b/poseidon2/compress.nim index 85c5d8c..5fc9dd0 100644 --- a/poseidon2/compress.nim +++ b/poseidon2/compress.nim @@ -6,5 +6,5 @@ func compress*(a, b : F, key = zero) : F = var x = a var y = b var z = key - permInplace(x, y, z) + permInPlace(x, y, z) return x diff --git a/poseidon2/permutation.nim b/poseidon2/permutation.nim index 6911f00..6e41f15 100644 --- a/poseidon2/permutation.nim +++ b/poseidon2/permutation.nim @@ -2,7 +2,7 @@ import ./types import ./roundfun # the Poseidon2 permutation (mutable, in-place version) -proc permInplace*(x, y, z : var F) = +proc permInPlace*(x, y, z : var F) = linearLayer(x, y, z) for j in 0..3: externalRound(j, x, y, z) @@ -14,5 +14,5 @@ proc permInplace*(x, y, z : var F) = # the Poseidon2 permutation func perm*(xyz: S) : S = var (x,y,z) = xyz - permInplace(x, y, z) + permInPlace(x, y, z) return (x,y,z) From fbf95e21b824d7a4ec71783bbb39346dcbfc602e Mon Sep 17 00:00:00 2001 From: benbierens Date: Thu, 21 Dec 2023 14:24:43 +0100 Subject: [PATCH 2/6] 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) From 1d12c385840bac75b8d95501f4767c193a8a2c0f Mon Sep 17 00:00:00 2001 From: benbierens Date: Fri, 22 Dec 2023 13:17:00 +0100 Subject: [PATCH 3/6] Adds check to ensure value fits in prime field. --- poseidon2/io.nim | 2 +- tests/poseidon2/testIo.nim | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/poseidon2/io.nim b/poseidon2/io.nim index 3ca8fca..68d7157 100644 --- a/poseidon2/io.nim +++ b/poseidon2/io.nim @@ -19,7 +19,7 @@ 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(): + if bool(big < F.fieldMod()): return some(F.fromBig(big)) func toBytes*(element: F): array[32, byte] = diff --git a/tests/poseidon2/testIo.nim b/tests/poseidon2/testIo.nim index 2ff6555..83d9929 100644 --- a/tests/poseidon2/testIo.nim +++ b/tests/poseidon2/testIo.nim @@ -1,5 +1,6 @@ import std/unittest import std/sequtils +import std/options import constantine/math/io/io_bigints import constantine/math/io/io_fields import constantine/math/arithmetic @@ -11,6 +12,9 @@ suite "conversion to/from bytes": func toArray(bytes: openArray[byte]): array[31, byte] = result[0.. Date: Fri, 22 Dec 2023 15:43:57 +0100 Subject: [PATCH 4/6] Adds test for preserving field element after conversion --- tests/poseidon2/testIo.nim | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/poseidon2/testIo.nim b/tests/poseidon2/testIo.nim index 83d9929..a8189b1 100644 --- a/tests/poseidon2/testIo.nim +++ b/tests/poseidon2/testIo.nim @@ -42,6 +42,13 @@ suite "conversion to/from bytes": check bool(elements[0] == expected1) check bool(elements[1] == expected2) + test "conversion preserves field element": + let + expected = toF(1234) + bytes = expected.toBytes() + actual = F.fromBytes(bytes).get() + check bool(expected == actual) + test "conversion from bytes adds 0x1 as an end marker": let bytes = toSeq 1'u8..62'u8 let marker = @[1'u8] From 3b403b0752790438bed6342b431412cc05474acb Mon Sep 17 00:00:00 2001 From: Dmitriy Ryajov Date: Fri, 22 Dec 2023 12:51:53 -0600 Subject: [PATCH 5/6] fix style check --- tests/poseidon2/testPermutation.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/poseidon2/testPermutation.nim b/tests/poseidon2/testPermutation.nim index b8239fb..b6808e5 100644 --- a/tests/poseidon2/testPermutation.nim +++ b/tests/poseidon2/testPermutation.nim @@ -15,7 +15,7 @@ suite "permutation": var y: F = toF(1) var z: F = toF(2) - permInplace(x, y, z) + permInPlace(x, y, z) check toDecimal(x) == "21882471761025344482456282050943515707267606647948403374880378562101343146243" check toDecimal(y) == "09030699330013392132529464674294378792132780497765201297316864012141442630280" From eef2603c11eeb5069eaed6c0296f3a1c5d23aad1 Mon Sep 17 00:00:00 2001 From: benbierens Date: Mon, 8 Jan 2024 11:29:30 +0100 Subject: [PATCH 6/6] Adds equality compare for field elements --- poseidon2/types.nim | 3 +++ 1 file changed, 3 insertions(+) diff --git a/poseidon2/types.nim b/poseidon2/types.nim index 5cc931c..2c9fa52 100644 --- a/poseidon2/types.nim +++ b/poseidon2/types.nim @@ -38,3 +38,6 @@ func arrayFromHex*[N]( for i in low(inp)..high(inp): tmp[i] = hexToF(inp[i], endian) return tmp + +func `==`*(a, b: F): bool = + bool(arithmetic.`==`(a, b))