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_io.nim"
test "", "tests/test_bigints.nim" test "", "tests/test_bigints.nim"
test "", "tests/test_bigints_multimod.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 # 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` ## and store it into a BigInt of size `bits`
result.fromRawUint(cast[array[sizeof(src), byte]](src), cpuEndian) 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 # 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: elif T is uint16:
littleEndian16(outp, inp) littleEndian16(outp, inp)
func dumpRawUintLE( func serializeRawUintLE(
dst: var openarray[byte], dst: var openarray[byte],
src: BigInt) {.inline.}= src: BigInt) {.inline.}=
## Serialize a bigint into its canonical little-endian representation ## 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)) dst[dst_idx+i] = byte(lo shr ((tail-i)*8))
return return
func dumpRawUint*( func serializeRawUint*(
dst: var openarray[byte], dst: var openarray[byte],
src: BigInt, src: BigInt,
dstEndianness: static Endianness) = dstEndianness: static Endianness) =
@ -186,7 +193,7 @@ func dumpRawUint*(
zeroMem(dst, dst.len) zeroMem(dst, dst.len)
when dstEndianness == littleEndian: when dstEndianness == littleEndian:
dumpRawUintLE(dst, src) serializeRawUintLE(dst, src)
else: else:
{.error: "Not implemented at the moment".} {.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 # 2. Convert canonical uint to Big Int
result.fromRawUint(bytes, littleEndian) 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. ## Stringify an int to hex.
## Note. Leading zeros are not removed. ## Note. Leading zeros are not removed.
## Result is prefixed with 0x ## 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. ## Regardless of the machine endianness the output will be big-endian hex.
## ##
## For example a BigInt representing 10 will be ## For example a BigInt representing 10 will be
## - 0x0A for BigInt[8] ## - 0x0a for BigInt[8]
## - 0x000A for BigInt[16] ## - 0x000a for BigInt[16]
## - 0x00000000_0000000A for BigInt[64] ## - 0x00000000_0000000a for BigInt[64]
## (underscore added for docuentation readability only)
## ##
## CT: ## CT:
## - no leaks ## - no leaks
@ -348,7 +356,7 @@ func dumpHex*(big: BigInt, order: static Endianness = bigEndian): string =
# 1. Convert Big Int to canonical uint # 1. Convert Big Int to canonical uint
const canonLen = (big.bits + 8 - 1) div 8 const canonLen = (big.bits + 8 - 1) div 8
var bytes: array[canonLen, byte] var bytes: array[canonLen, byte]
dumpRawUint(bytes, big, cpuEndian) serializeRawUint(bytes, big, cpuEndian)
# 2 Convert canonical uint to hex # 2 Convert canonical uint to hex
result = bytes.toHex(order) 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. # at your option. This file may not be copied, modified, or distributed except according to those terms.
import unittest, random, strutils, import unittest, random, strutils,
../constantine/io/io, ../constantine/io/io_bigints,
../constantine/math/bigints_checked, ../constantine/math/bigints_checked,
../constantine/config/common, ../constantine/config/common,
../constantine/primitives/constant_time ../constantine/primitives/constant_time

View File

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

View File

@ -12,7 +12,7 @@ import
# Third-party # Third-party
gmp, stew/byteutils, gmp, stew/byteutils,
# Internal # Internal
../constantine/io/io, ../constantine/io/io_bigints,
../constantine/math/[bigints_raw, bigints_checked], ../constantine/math/[bigints_raw, bigints_checked],
../constantine/primitives/constant_time ../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) discard mpz_export(rGMP[0].addr, rW.addr, GMP_LeastSignificantWordFirst, 1, GMP_WordNativeEndian, 0, r)
var rConstantine: array[mLen, byte] var rConstantine: array[mLen, byte]
dumpRawUint(rConstantine, rTest, littleEndian) serializeRawUint(rConstantine, rTest, littleEndian)
# echo "rGMP: ", rGMP.toHex() # echo "rGMP: ", rGMP.toHex()
# echo "rConstantine: ", rConstantine.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. # at your option. This file may not be copied, modified, or distributed except according to those terms.
import unittest, random, 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. # at your option. This file may not be copied, modified, or distributed except according to those terms.
import unittest, random, import unittest, random,
../constantine/io/io, ../constantine/io/io_bigints,
../constantine/config/common, ../constantine/config/common,
../constantine/math/bigints_checked ../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 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] var r_bytes: array[8, byte]
dumpRawUint(r_bytes, big, littleEndian) serializeRawUint(r_bytes, big, littleEndian)
check: x_bytes == r_bytes check: x_bytes == r_bytes
block: # "Little-endian" - single random 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 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] var r_bytes: array[8, byte]
dumpRawUint(r_bytes, big, littleEndian) serializeRawUint(r_bytes, big, littleEndian)
check: x_bytes == r_bytes check: x_bytes == r_bytes
block: # "Little-endian" - 10 random cases 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 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] var r_bytes: array[8, byte]
dumpRawUint(r_bytes, big, littleEndian) serializeRawUint(r_bytes, big, littleEndian)
check: x_bytes == r_bytes check: x_bytes == r_bytes
test "Round trip on elliptic curve constants": test "Round trip on elliptic curve constants":
block: # Secp256k1 - https://en.bitcoin.it/wiki/Secp256k1 block: # Secp256k1 - https://en.bitcoin.it/wiki/Secp256k1
const p = "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f" const p = "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"
let x = BigInt[256].fromHex(p) let x = BigInt[256].fromHex(p)
let hex = x.dumpHex(bigEndian) let hex = x.toHex(bigEndian)
check: p == hex check: p == hex
block: # BN254 - https://github.com/ethereum/py_ecc/blob/master/py_ecc/fields/field_properties.py block: # BN254 - https://github.com/ethereum/py_ecc/blob/master/py_ecc/fields/field_properties.py
const p = "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47" const p = "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47"
let x = BigInt[254].fromHex(p) let x = BigInt[254].fromHex(p)
let hex = x.dumpHex(bigEndian) let hex = x.toHex(bigEndian)
check: p == hex check: p == hex
block: # BLS12-381 - https://github.com/ethereum/py_ecc/blob/master/py_ecc/fields/field_properties.py block: # BLS12-381 - https://github.com/ethereum/py_ecc/blob/master/py_ecc/fields/field_properties.py
const p = "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab" const p = "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab"
let x = BigInt[381].fromHex(p) let x = BigInt[381].fromHex(p)
let hex = x.dumpHex(bigEndian) let hex = x.toHex(bigEndian)
check: p == hex check: p == hex