This commit is contained in:
cheatfate 2020-01-09 10:33:57 +02:00 committed by zah
parent 58cdefac21
commit 107e71203d

View File

@ -31,7 +31,7 @@ type
seckey*: SkPrivateKey seckey*: SkPrivateKey
pubkey*: SkPublicKey pubkey*: SkPublicKey
SkSignature* = secp256k1_ecdsa_recoverable_signature SkSignature* = secp256k1_ecdsa_signature
## Representation of signature. ## Representation of signature.
SkContext* = ref object SkContext* = ref object
@ -152,10 +152,10 @@ proc init*(sig: var SkSignature, data: openarray[byte]): bool =
## Procedure returns ``true`` on success. ## Procedure returns ``true`` on success.
let ctx = getContext() let ctx = getContext()
let length = len(data) let length = len(data)
if length >= SkRawSignatureSize: if length >= 0:
var recid = cint(data[SkRawPrivateKeySize * 2]) let res = secp256k1_ecdsa_signature_parse_der(ctx.context, addr sig,
let res = secp256k1_ecdsa_recoverable_signature_parse_compact(ctx.context, cast[ptr cuchar](unsafeAddr data[0]),
addr sig, cast[ptr cuchar](unsafeAddr data[0]), recid) csize(length))
result = (res == 1) and (len(ctx.error) == 0) result = (res == 1) and (len(ctx.error) == 0)
proc init*(sig: var SkSignature, data: string): bool = proc init*(sig: var SkSignature, data: string): bool =
@ -279,14 +279,15 @@ proc toBytes*(sig: SkSignature, data: var openarray[byte]): int =
## Procedure returns number of bytes (octets) needed to store ## Procedure returns number of bytes (octets) needed to store
## Secp256k1 signature. ## Secp256k1 signature.
let ctx = getContext() let ctx = getContext()
var recid = cint(0) var buffer: array[72, byte]
result = SkRawSignatureSize let pdata = cast[ptr cuchar](addr buffer[0])
if len(data) >= SkRawSignatureSize: var plength = csize(len(buffer))
let res = secp256k1_ecdsa_recoverable_signature_serialize_compact( discard secp256k1_ecdsa_signature_serialize_der(ctx.context, pdata,
ctx.context, cast[ptr cuchar](unsafeAddr data[0]), addr plength,
addr recid, unsafeAddr sig) unsafeAddr sig)
if (res == 1) and (len(ctx.error) == 0): result = plength
data[64] = uint8(recid) if len(data) >= plength:
copyMem(addr data[0], addr buffer[0], plength)
proc getBytes*(key: SkPrivateKey): seq[byte] {.inline.} = proc getBytes*(key: SkPrivateKey): seq[byte] {.inline.} =
## Serialize Secp256k1 `private key` and return it. ## Serialize Secp256k1 `private key` and return it.
@ -299,8 +300,9 @@ proc getBytes*(key: SkPublicKey): seq[byte] {.inline.} =
proc getBytes*(sig: SkSignature): seq[byte] {.inline.} = proc getBytes*(sig: SkSignature): seq[byte] {.inline.} =
## Serialize Secp256k1 `signature` and return it. ## Serialize Secp256k1 `signature` and return it.
result = newSeq[byte](SkRawSignatureSize) result = newSeq[byte](72)
discard toBytes(sig, result) let length = toBytes(sig, result)
result.setLen(length)
proc `==`*(ska, skb: SkPrivateKey): bool = proc `==`*(ska, skb: SkPrivateKey): bool =
## Compare Secp256k1 `private key` objects for equality. ## Compare Secp256k1 `private key` objects for equality.
@ -335,31 +337,28 @@ proc `$`*(key: SkPublicKey): string =
proc `$`*(sig: SkSignature): string = proc `$`*(sig: SkSignature): string =
## Return string representation of Secp256k1 `signature`.s ## Return string representation of Secp256k1 `signature`.s
var ssig: array[SkRawSignatureSize, byte] result = toHex(sig.data)
discard sig.toBytes(ssig)
result = toHex(ssig)
proc sign*[T: byte|char](key: SkPrivateKey, msg: openarray[T]): SkSignature {.gcsafe.} = proc sign*[T: byte|char](key: SkPrivateKey, msg: openarray[T]): SkSignature =
## Sign message `msg` using private key `key` and return signature object. ## Sign message `msg` using private key `key` and return signature object.
let ctx = getContext() let ctx = getContext()
var hash = sha256.digest(msg) var hash = sha256.digest(msg)
let res = secp256k1_ecdsa_sign_recoverable(ctx.context, addr result, let res = secp256k1_ecdsa_sign(ctx.context, addr result,
cast[ptr cuchar](addr hash.data[0]), cast[ptr cuchar](addr hash.data[0]),
cast[ptr cuchar](unsafeAddr key), cast[ptr cuchar](unsafeAddr key),
nil, nil) nil, nil)
if (res != 1) or (len(ctx.error) != 0): if (res != 1) or (len(ctx.error) != 0):
raiseSecp256k1Error() raiseSecp256k1Error()
proc verify*[T: byte|char](sig: SkSignature, msg: openarray[T], proc verify*[T: byte|char](sig: SkSignature, msg: openarray[T],
key: SkPublicKey): bool = key: SkPublicKey): bool =
var pubkey: SkPublicKey
let ctx = getContext() let ctx = getContext()
var hash = sha256.digest(msg) var hash = sha256.digest(msg)
let res = secp256k1_ecdsa_recover(ctx.context, addr pubkey, unsafeAddr sig, let res = secp256k1_ecdsa_verify(ctx.context, unsafeAddr sig,
cast[ptr cuchar](addr hash.data[0])) cast[ptr cuchar](addr hash.data[0]),
unsafeAddr key)
if (res == 1) and (len(ctx.error) == 0): if (res == 1) and (len(ctx.error) == 0):
if key == pubkey: result = true
result = true
proc clear*(key: var SkPrivateKey) {.inline.} = proc clear*(key: var SkPrivateKey) {.inline.} =
## Wipe and clear memory of Secp256k1 `private key`. ## Wipe and clear memory of Secp256k1 `private key`.