Hiding fields, removing ttmath from libsecp backend
This commit is contained in:
parent
0c4bc995d2
commit
6383b00bc2
|
@ -20,13 +20,13 @@ proc `=destroy`(ctx: ptr secp256k1_context) =
|
|||
ctx.secp256k1_context_destroy
|
||||
|
||||
type
|
||||
Serialized_PubKey = ByteArrayBE[65]
|
||||
Serialized_PubKey = array[65, byte]
|
||||
|
||||
proc asPtrPubKey(key: PublicKey): ptr secp256k1_pubkey =
|
||||
cast[ptr secp256k1_pubkey](unsafeAddr key.raw_key)
|
||||
cast[ptr secp256k1_pubkey](unsafeAddr key)
|
||||
|
||||
proc asPtrCuchar(key: PrivateKey): ptr cuchar =
|
||||
cast[ptr cuchar](unsafeAddr key.raw_key)
|
||||
cast[ptr cuchar](unsafeAddr key)
|
||||
|
||||
proc asPtrCuchar(key: Serialized_PubKey): ptr cuchar =
|
||||
cast[ptr cuchar](unsafeAddr key)
|
||||
|
|
|
@ -7,22 +7,43 @@
|
|||
#
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import ./private/lowlevel_types
|
||||
import ttmath
|
||||
import ./private/conversion_bytes
|
||||
export toHex, hexToByteArrayBE, hexToSeqByteBE
|
||||
|
||||
export lowlevel_types, ttmath
|
||||
|
||||
# Note: Fields are intentionally kept private
|
||||
type
|
||||
PublicKey* = object
|
||||
raw_key*: ByteArrayBE[64]
|
||||
Fraw_key: array[64, byte]
|
||||
|
||||
PrivateKey* = object
|
||||
raw_key*: ByteArrayBE[32]
|
||||
public_key*: PublicKey
|
||||
|
||||
BaseKey* = PrivateKey|PublicKey
|
||||
Fraw_key: array[32, byte]
|
||||
Fpublic_key: PublicKey
|
||||
|
||||
Signature* {.packed.}= object
|
||||
r*: UInt256
|
||||
s*: UInt256
|
||||
v*: range[0.byte .. 1.byte]
|
||||
Fr: array[32, byte]
|
||||
Fs: array[32, byte]
|
||||
Fv: range[0.byte .. 1.byte]
|
||||
|
||||
|
||||
# "Public" accessors, only exposed to internal modules
|
||||
|
||||
template genAccessors(name: untyped, fieldType, objType: typedesc): untyped =
|
||||
# Access
|
||||
proc name*(obj: objType): fieldType {.noSideEffect, inline, noInit.} =
|
||||
obj.`F name`
|
||||
|
||||
# Assignement
|
||||
proc `name=`*(obj: var objType, value: fieldType): fieldType {.noSideEffect, inline.} =
|
||||
obj.`F name` = value
|
||||
|
||||
# Mutable
|
||||
proc `name`*(obj: var objType): var fieldType {.noSideEffect, inline.} =
|
||||
obj.`F name`
|
||||
|
||||
genAccessors(raw_key, array[64, byte], PublicKey)
|
||||
genAccessors(raw_key, array[32, byte], PrivateKey)
|
||||
genAccessors(public_key, PublicKey, PrivateKey)
|
||||
genAccessors(s, array[32, byte], Signature)
|
||||
genAccessors(r, array[32, byte], Signature)
|
||||
genAccessors(v, range[0.byte .. 1.byte], Signature)
|
||||
|
|
|
@ -7,13 +7,12 @@
|
|||
#
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import ./datatypes,
|
||||
./datatypes_interface
|
||||
import ./datatypes
|
||||
export PublicKey, PrivateKey, Signature
|
||||
|
||||
import ./datatypes_interface
|
||||
export datatypes_interface
|
||||
|
||||
export datatypes,
|
||||
datatypes_interface
|
||||
|
||||
|
||||
import ttmath
|
||||
export ttmath
|
||||
when defined(backend_native):
|
||||
import ttmath
|
||||
export ttmath
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import ttmath, strutils
|
||||
import strutils
|
||||
|
||||
# Note on endianness:
|
||||
# - UInt256 uses host endianness
|
||||
|
@ -19,24 +19,7 @@ import ttmath, strutils
|
|||
# https://www.reddit.com/r/crypto/comments/6287my/explanations_on_the_keccaksha3_paddingbyte/
|
||||
# Note: Since Nim's Keccak-Tiny only accepts string as input, endianness does not matter.
|
||||
|
||||
type ByteArrayBE*[N: static[int]] = array[N, byte]
|
||||
## A byte array that stores bytes in big-endian order
|
||||
|
||||
proc readUint256BE*(ba: ByteArrayBE[32]): UInt256 {.noSideEffect, inline.}=
|
||||
## Convert a big-endian array of Bytes to an UInt256 (in native host endianness)
|
||||
const N = 32
|
||||
for i in 0 ..< N:
|
||||
{.unroll: 4.}
|
||||
result = result shl 8 or ba[i].u256
|
||||
|
||||
proc toByteArrayBE*(num: UInt256): ByteArrayBE[32] {.noSideEffect, noInit, inline.}=
|
||||
## Convert an UInt256 (in native host endianness) to a big-endian byte array
|
||||
const N = 32
|
||||
for i in 0 ..< N:
|
||||
{.unroll: 4.}
|
||||
result[i] = byte getUInt(num shr uint((N-1-i) * 8))
|
||||
|
||||
proc readHexChar(c: char): byte {.noSideEffect.}=
|
||||
proc readHexChar*(c: char): byte {.noSideEffect.}=
|
||||
## Converts an hex char to a byte
|
||||
case c
|
||||
of '0'..'9': result = byte(ord(c) - ord('0'))
|
||||
|
@ -45,7 +28,7 @@ proc readHexChar(c: char): byte {.noSideEffect.}=
|
|||
else:
|
||||
raise newException(ValueError, $c & "is not a hexademical character")
|
||||
|
||||
proc skip0xPrefix(hexStr: string): int {.inline.} =
|
||||
proc skip0xPrefix*(hexStr: string): int {.inline.} =
|
||||
## Returns the index of the first meaningful char in `hexStr` by skipping
|
||||
## "0x" prefix
|
||||
if hexStr[0] == '0' and hexStr[1] in {'x', 'X'}:
|
||||
|
@ -68,7 +51,7 @@ proc hexToByteArrayBE*(hexStr: string, output: var openArray[byte]) {.inline.} =
|
|||
## Read a hex string and store it in a Byte Array `output` in Big-Endian order
|
||||
hexToByteArrayBE(hexStr, output, 0, output.high)
|
||||
|
||||
proc hexToByteArrayBE*[N: static[int]](hexStr: string): ByteArrayBE[N] {.noSideEffect, noInit, inline.}=
|
||||
proc hexToByteArrayBE*[N: static[int]](hexStr: string): array[N, byte] {.noSideEffect, noInit, inline.}=
|
||||
## Read an hex string and store it in a Byte Array in Big-Endian order
|
||||
hexToByteArrayBE(hexStr, result)
|
||||
|
||||
|
@ -83,33 +66,6 @@ proc hexToSeqByteBE*(hexStr: string): seq[byte] {.noSideEffect.}=
|
|||
result[i] = hexStr[2*i].readHexChar shl 4 or hexStr[2*i+1].readHexChar
|
||||
inc(i)
|
||||
|
||||
proc hexToUInt256*(hexStr: string): UInt256 {.noSideEffect.}=
|
||||
## Read an hex string and store it in a UInt256
|
||||
const N = 32
|
||||
|
||||
var i = skip0xPrefix(hexStr)
|
||||
|
||||
assert hexStr.len - i == 2*N
|
||||
|
||||
while i < 2*N:
|
||||
result = result shl 4 or hexStr[i].readHexChar.uint.u256
|
||||
inc(i)
|
||||
|
||||
proc toHex*(n: UInt256): string {.noSideEffect.}=
|
||||
## Convert uint256 to its hex representation
|
||||
## Output is in lowercase
|
||||
|
||||
var rem = n # reminder to encode
|
||||
|
||||
const
|
||||
N = 32 # nb of bytes in n
|
||||
hexChars = "0123456789abcdef"
|
||||
|
||||
result = newString(2*N)
|
||||
for i in countdown(2*N - 1, 0):
|
||||
result[i] = hexChars[(rem and 0xF.u256).getUInt.int]
|
||||
rem = rem shr 4
|
||||
|
||||
proc toHexAux(ba: openarray[byte]): string {.noSideEffect.} =
|
||||
## Convert a byte-array to its hex representation
|
||||
## Output is in lowercase
|
||||
|
@ -132,7 +88,7 @@ proc toHex*(ba: openarray[byte]): string {.noSideEffect, inline.} =
|
|||
## - It is resistant against timing attack
|
||||
toHexAux(ba)
|
||||
|
||||
proc toHex*(ba: ByteArrayBE): string {.noSideEffect, inline.} =
|
||||
proc toHex*[N: static[int]](ba: array[N, byte]): string {.noSideEffect, inline.} =
|
||||
## Convert a byte-array to its hex representation
|
||||
## Output is in lowercase
|
||||
##
|
|
@ -0,0 +1,63 @@
|
|||
# Nim Eth-keys
|
||||
# Copyright (c) 2018 Status Research & Development GmbH
|
||||
# Licensed under either of
|
||||
#
|
||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
|
||||
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
||||
#
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import ttmath, strutils,
|
||||
conversion_bytes
|
||||
|
||||
|
||||
# Note on endianness:
|
||||
# - UInt256 uses host endianness
|
||||
# - Libsecp256k1, Ethereum EVM expect Big Endian
|
||||
# https://github.com/ethereum/evmjit/issues/91
|
||||
# - Keccak expects least-significant byte first: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf
|
||||
# Appendix B.1 p37 and outputs a hash with the same endianness as input
|
||||
# http://www.dianacoman.com/2018/02/08/eucrypt-chapter-9-byte-order-and-bit-disorder-in-keccak/
|
||||
# https://www.reddit.com/r/crypto/comments/6287my/explanations_on_the_keccaksha3_paddingbyte/
|
||||
# Note: Since Nim's Keccak-Tiny only accepts string as input, endianness does not matter.
|
||||
|
||||
proc toByteArrayBE*(num: UInt256): array[32, byte] {.noSideEffect, noInit, inline.}=
|
||||
## Convert an UInt256 (in native host endianness) to a big-endian byte array
|
||||
const N = 32
|
||||
for i in 0 ..< N:
|
||||
{.unroll: 4.}
|
||||
result[i] = byte getUInt(num shr uint((N-1-i) * 8))
|
||||
|
||||
proc readUint256BE*(ba: array[32, byte]): UInt256 {.noSideEffect, inline.}=
|
||||
## Convert a big-endian array of Bytes to an UInt256 (in native host endianness)
|
||||
const N = 32
|
||||
for i in 0 ..< N:
|
||||
{.unroll: 4.}
|
||||
result = result shl 8 or ba[i].u256
|
||||
|
||||
proc hexToUInt256*(hexStr: string): UInt256 {.noSideEffect.}=
|
||||
## Read an hex string and store it in a UInt256
|
||||
const N = 32
|
||||
|
||||
var i = skip0xPrefix(hexStr)
|
||||
|
||||
assert hexStr.len - i == 2*N
|
||||
|
||||
while i < 2*N:
|
||||
result = result shl 4 or hexStr[i].readHexChar.uint.u256
|
||||
inc(i)
|
||||
|
||||
proc toHex*(n: UInt256): string {.noSideEffect.}=
|
||||
## Convert uint256 to its hex representation
|
||||
## Output is in lowercase
|
||||
|
||||
var rem = n # reminder to encode
|
||||
|
||||
const
|
||||
N = 32 # nb of bytes in n
|
||||
hexChars = "0123456789abcdef"
|
||||
|
||||
result = newString(2*N)
|
||||
for i in countdown(2*N - 1, 0):
|
||||
result[i] = hexChars[(rem and 0xF.u256).getUInt.int]
|
||||
rem = rem shr 4
|
|
@ -7,8 +7,8 @@
|
|||
#
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import ../src/private/lowlevel_types
|
||||
import unittest, ttmath, strutils
|
||||
import ../src/private/[conversion_bytes, conversion_ttmath]
|
||||
import unittest, ttmath, strutils # TODO remove ttmath needs if backend libsecp256k1
|
||||
|
||||
|
||||
suite "Testing conversion functions: Hex, Bytes, Endianness":
|
||||
|
|
Loading…
Reference in New Issue