Update IO: dumpHex -> toHex dumpRawUint -> serializeRawUint
This commit is contained in:
parent
343399ba1c
commit
6226d86726
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue