Adds check to ensure value fits in prime field.

This commit is contained in:
benbierens 2023-12-22 13:17:00 +01:00 committed by Dmitriy Ryajov
parent fbf95e21b8
commit 1d12c38584
No known key found for this signature in database
GPG Key ID: DA8C680CE7C657A4
2 changed files with 7 additions and 3 deletions

View File

@ -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] =

View File

@ -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..<bytes.len] = bytes[0..<bytes.len]
func toArray32(bytes: openArray[byte]): array[32, byte] =
result[0..<bytes.len] = bytes[0..<bytes.len]
test "converts 31 little endian bytes into a field elements":
let bytes = toArray toSeq 1'u8..31'u8
let paddedTo32 = @bytes & @[0'u8] # most significant byte is not used
@ -19,13 +23,13 @@ suite "conversion to/from bytes":
check bool(unmarshalled == expected)
test "converts 32 little endian bytes into a field elements":
let bytes = toArray toSeq 1'u8..32'u8
let bytes = toArray32(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 bytes = toArray32(toSeq((255'u8).repeat(32)))
let expected = F.fromBig(B.unmarshal(bytes, littleEndian))
let unmarshalled = F.fromBytes(bytes)
check not unmarshalled.isSome()