Update IO: dumpHex -> toHex dumpRawUint -> serializeRawUint

This commit is contained in:
Mamy André-Ratsimbazafy 2020-02-12 21:57:39 +01:00
parent 343399ba1c
commit 6226d86726
No known key found for this signature in database
GPG Key ID: 7B88AD1FE79492E1
8 changed files with 42 additions and 21 deletions

View File

@ -20,4 +20,4 @@ task test, "Run all tests":
test "", "tests/test_io.nim"
test "", "tests/test_bigints.nim"
test "", "tests/test_bigints_multimod.nim"
# test " -d:testingCurves", "tests/test_field_fp.nim"
test "", "tests/test_bigints_vs_gmp.nim"

View File

@ -1 +1,7 @@
# I/O and serialization
## References
- Standards for Efficient Cryptography Group (SECG),
"SEC 1: Elliptic Curve Cryptography", May 2009,
http://www.secg.org/sec1-v2.pdf

View File

@ -100,6 +100,13 @@ func fromUint*(
## and store it into a BigInt of size `bits`
result.fromRawUint(cast[array[sizeof(src), byte]](src), cpuEndian)
func fromUint*(
dst: var BigInt,
src: SomeUnsignedInt) =
## Parse a regular unsigned integer
## and store it into a BigInt of size `bits`
dst.fromRawUint(cast[array[sizeof(src), byte]](src), cpuEndian)
# ############################################################
#
# Serialising from internal representation to canonical format
@ -122,7 +129,7 @@ template littleEndianXX[T: uint16 or uint32 or uint64](outp: pointer, inp: ptr T
elif T is uint16:
littleEndian16(outp, inp)
func dumpRawUintLE(
func serializeRawUintLE(
dst: var openarray[byte],
src: BigInt) {.inline.}=
## Serialize a bigint into its canonical little-endian representation
@ -168,7 +175,7 @@ func dumpRawUintLE(
dst[dst_idx+i] = byte(lo shr ((tail-i)*8))
return
func dumpRawUint*(
func serializeRawUint*(
dst: var openarray[byte],
src: BigInt,
dstEndianness: static Endianness) =
@ -186,7 +193,7 @@ func dumpRawUint*(
zeroMem(dst, dst.len)
when dstEndianness == littleEndian:
dumpRawUintLE(dst, src)
serializeRawUintLE(dst, src)
else:
{.error: "Not implemented at the moment".}
@ -327,7 +334,7 @@ func fromHex*(T: type BigInt, s: string): T =
# 2. Convert canonical uint to Big Int
result.fromRawUint(bytes, littleEndian)
func dumpHex*(big: BigInt, order: static Endianness = bigEndian): string =
func toHex*(big: BigInt, order: static Endianness = bigEndian): string =
## Stringify an int to hex.
## Note. Leading zeros are not removed.
## Result is prefixed with 0x
@ -338,9 +345,10 @@ func dumpHex*(big: BigInt, order: static Endianness = bigEndian): string =
## Regardless of the machine endianness the output will be big-endian hex.
##
## For example a BigInt representing 10 will be
## - 0x0A for BigInt[8]
## - 0x000A for BigInt[16]
## - 0x00000000_0000000A for BigInt[64]
## - 0x0a for BigInt[8]
## - 0x000a for BigInt[16]
## - 0x00000000_0000000a for BigInt[64]
## (underscore added for docuentation readability only)
##
## CT:
## - no leaks
@ -348,7 +356,7 @@ func dumpHex*(big: BigInt, order: static Endianness = bigEndian): string =
# 1. Convert Big Int to canonical uint
const canonLen = (big.bits + 8 - 1) div 8
var bytes: array[canonLen, byte]
dumpRawUint(bytes, big, cpuEndian)
serializeRawUint(bytes, big, cpuEndian)
# 2 Convert canonical uint to hex
result = bytes.toHex(order)

View File

@ -7,7 +7,7 @@
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import unittest, random, strutils,
../constantine/io/io,
../constantine/io/io_bigints,
../constantine/math/bigints_checked,
../constantine/config/common,
../constantine/primitives/constant_time

View File

@ -10,7 +10,7 @@ import
# Standard library
unittest, random, strutils,
# Third-party
../constantine/io/io,
../constantine/io/io_bigints,
../constantine/math/[bigints_raw, bigints_checked],
../constantine/primitives/constant_time

View File

@ -12,7 +12,7 @@ import
# Third-party
gmp, stew/byteutils,
# Internal
../constantine/io/io,
../constantine/io/io_bigints,
../constantine/math/[bigints_raw, bigints_checked],
../constantine/primitives/constant_time
@ -138,7 +138,7 @@ proc main() =
discard mpz_export(rGMP[0].addr, rW.addr, GMP_LeastSignificantWordFirst, 1, GMP_WordNativeEndian, 0, r)
var rConstantine: array[mLen, byte]
dumpRawUint(rConstantine, rTest, littleEndian)
serializeRawUint(rConstantine, rTest, littleEndian)
# echo "rGMP: ", rGMP.toHex()
# echo "rConstantine: ", rConstantine.toHex()

View File

@ -7,4 +7,11 @@
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import unittest, random,
../constantine/[io, bigints, primitives, field_fp]
../constantine/math/[io, primitives, finite_fields]
proc main() =
suite "Basic arithmetic over finite fields":
test "Addition mod 101":
block:
var x: Fp[Fake101]
x.fromUint()

View File

@ -7,7 +7,7 @@
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import unittest, random,
../constantine/io/io,
../constantine/io/io_bigints,
../constantine/config/common,
../constantine/math/bigints_checked
@ -34,7 +34,7 @@ proc main() =
let big = BigInt[64].fromRawUint(x_bytes, littleEndian) # It's fine even on big-endian platform. We only want the byte-pattern
var r_bytes: array[8, byte]
dumpRawUint(r_bytes, big, littleEndian)
serializeRawUint(r_bytes, big, littleEndian)
check: x_bytes == r_bytes
block: # "Little-endian" - single random
@ -43,7 +43,7 @@ proc main() =
let big = BigInt[64].fromRawUint(x_bytes, littleEndian) # It's fine even on big-endian platform. We only want the byte-pattern
var r_bytes: array[8, byte]
dumpRawUint(r_bytes, big, littleEndian)
serializeRawUint(r_bytes, big, littleEndian)
check: x_bytes == r_bytes
block: # "Little-endian" - 10 random cases
@ -53,28 +53,28 @@ proc main() =
let big = BigInt[64].fromRawUint(x_bytes, littleEndian) # It's fine even on big-endian platform. We only want the byte-pattern
var r_bytes: array[8, byte]
dumpRawUint(r_bytes, big, littleEndian)
serializeRawUint(r_bytes, big, littleEndian)
check: x_bytes == r_bytes
test "Round trip on elliptic curve constants":
block: # Secp256k1 - https://en.bitcoin.it/wiki/Secp256k1
const p = "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"
let x = BigInt[256].fromHex(p)
let hex = x.dumpHex(bigEndian)
let hex = x.toHex(bigEndian)
check: p == hex
block: # BN254 - https://github.com/ethereum/py_ecc/blob/master/py_ecc/fields/field_properties.py
const p = "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47"
let x = BigInt[254].fromHex(p)
let hex = x.dumpHex(bigEndian)
let hex = x.toHex(bigEndian)
check: p == hex
block: # BLS12-381 - https://github.com/ethereum/py_ecc/blob/master/py_ecc/fields/field_properties.py
const p = "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab"
let x = BigInt[381].fromHex(p)
let hex = x.dumpHex(bigEndian)
let hex = x.toHex(bigEndian)
check: p == hex