From b9a37825a3ff94eb3d69b44723f36dfeed573220 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mamy=20Andr=C3=A9-Ratsimbazafy?= Date: Sun, 9 Feb 2020 15:38:30 +0100 Subject: [PATCH] COnsistent IO API between fromRawUint and fromHex and add fromUint --- constantine/io.nim | 25 ++++++++++++++++--------- tests/test_io.nim | 16 ++++++++-------- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/constantine/io.nim b/constantine/io.nim index 8430a58..e02ad15 100644 --- a/constantine/io.nim +++ b/constantine/io.nim @@ -20,9 +20,9 @@ import # # ############################################################ -func parseRawUintLE( - src: openarray[byte], - bits: static int): BigInt[bits] {.inline.}= +func fromRawUintLE( + T: type BigInt, + src: openarray[byte]): T = ## Parse an unsigned integer from its canonical ## little-endian unsigned representation ## And store it into a BigInt of size bits @@ -52,22 +52,29 @@ func parseRawUintLE( if acc_len != 0: result.limbs[dst_idx] = acc -func parseRawUint*( +func fromRawUint*( + T: type BigInt, src: openarray[byte], - bits: static int, - srcEndianness: static Endianness): BigInt[bits] = + srcEndianness: static Endianness): T {.inline.}= ## Parse an unsigned integer from its canonical ## big-endian or little-endian unsigned representation - ## And store it into a BigInt of size bits + ## And store it into a BigInt of size `bits` ## ## CT: ## - no leaks when srcEndianness == littleEndian: - parseRawUintLE(src, bits) + fromRawUintLE(T, src) else: {.error: "Not implemented at the moment".} +func fromUint*( + T: type BigInt, + src: SomeUnsignedInt): T = + ## Parse a regular unsigned integer + ## and store it into a BigInt of size `bits` + fromRawUint(T, cast[array[sizeof(src), byte]](src), cpuEndian) + # ############################################################ # # Serialising from internal representation to canonical format @@ -291,7 +298,7 @@ func fromHex*(T: type BigInt, s: string): T = hexToPaddedByteArray(s, bytes, littleEndian) # 2. Convert canonical uint to Big Int - result = parseRawUint(bytes, T.bits, littleEndian) + result = T.fromRawUint(bytes, littleEndian) func dumpHex*(big: BigInt, order: static Endianness = bigEndian): string = ## Stringify an int to hex. diff --git a/tests/test_io.nim b/tests/test_io.nim index afa1467..ae5368d 100644 --- a/tests/test_io.nim +++ b/tests/test_io.nim @@ -17,7 +17,7 @@ suite "IO": block: # Sanity check let x = 0'u64 let x_bytes = cast[array[8, byte]](x) - let big = parseRawUint(x_bytes, 64, cpuEndian) + let big = BigInt[64].fromRawUint(x_bytes, cpuEndian) check: T(big.limbs[0]) == 0 @@ -26,7 +26,7 @@ suite "IO": block: # 2^63 is properly represented on 2 limbs let x = 1'u64 shl 63 let x_bytes = cast[array[8, byte]](x) - let big = parseRawUint(x_bytes, 64, cpuEndian) + let big = BigInt[64].fromRawUint(x_bytes, cpuEndian) check: T(big.limbs[0]) == 0 @@ -37,7 +37,7 @@ suite "IO": # "Little-endian" - 2^63 let x = 1'u64 shl 63 let x_bytes = cast[array[8, byte]](x) - let big = parseRawUint(x_bytes, 64, 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] dumpRawUint(r_bytes, big, littleEndian) @@ -46,7 +46,7 @@ suite "IO": block: # "Little-endian" - single random let x = uint64 rand(0..high(int)) let x_bytes = cast[array[8, byte]](x) - let big = parseRawUint(x_bytes, 64, 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] dumpRawUint(r_bytes, big, littleEndian) @@ -56,7 +56,7 @@ suite "IO": for _ in 0 ..< 10: let x = uint64 rand(0..high(int)) let x_bytes = cast[array[8, byte]](x) - let big = parseRawUint(x_bytes, 64, 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] dumpRawUint(r_bytes, big, littleEndian) @@ -65,21 +65,21 @@ suite "IO": test "Round trip on elliptic curve constants": block: # Secp256k1 - https://en.bitcoin.it/wiki/Secp256k1 const p = "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f" - let x = fromHex(BigInt[256], p) + let x = BigInt[256].fromHex(p) let hex = x.dumpHex(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 = fromHex(BigInt[254], p) + let x = BigInt[254].fromHex(p) let hex = x.dumpHex(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 = fromHex(BigInt[381], p) + let x = BigInt[381].fromHex(p) let hex = x.dumpHex(bigEndian) check: p == hex