2
0
mirror of synced 2025-02-22 18:38:12 +00:00

More localized noSideEffect overrides

This commit is contained in:
Zahary Karadjov 2020-11-14 19:03:40 +02:00 committed by zah
parent f1bdb572f4
commit a9d5cba699
2 changed files with 64 additions and 73 deletions

View File

@ -223,9 +223,8 @@ func fromRaw*(T: type SkSecretKey, data: openArray[byte]): SkResult[T] =
if len(data) < SkRawSecretKeySize: if len(data) < SkRawSecretKeySize:
return err(static(&"secp: raw private key should be {SkRawSecretKeySize} bytes")) return err(static(&"secp: raw private key should be {SkRawSecretKeySize} bytes"))
{.noSideEffect.}: # secp256k1_context_no_precomp is actually const, see above if secp256k1_ec_seckey_verify(secp256k1_context_no_precomp, data.ptr0) != 1:
if secp256k1_ec_seckey_verify(secp256k1_context_no_precomp, data.ptr0) != 1: return err("secp: invalid private key")
return err("secp: invalid private key")
ok(T(data: toArray(32, data.toOpenArray(0, SkRawSecretKeySize - 1)))) ok(T(data: toArray(32, data.toOpenArray(0, SkRawSecretKeySize - 1))))
@ -266,10 +265,9 @@ func fromRaw*(T: type SkPublicKey, data: openArray[byte]): SkResult[T] =
return err("secp: public key format not recognised") return err("secp: public key format not recognised")
var key {.noinit.}: secp256k1_pubkey var key {.noinit.}: secp256k1_pubkey
{.noSideEffect.}: # secp256k1_context_no_precomp is actually const, see above if secp256k1_ec_pubkey_parse(
if secp256k1_ec_pubkey_parse( secp256k1_context_no_precomp, addr key, data.ptr0, csize_t(length)) != 1:
secp256k1_context_no_precomp, addr key, data.ptr0, csize_t(length)) != 1: return err("secp: cannot parse public key")
return err("secp: cannot parse public key")
ok(SkPublicKey(data: key)) ok(SkPublicKey(data: key))
@ -281,11 +279,9 @@ func fromHex*(T: type SkPublicKey, data: string): SkResult[T] =
func toRaw*(pubkey: SkPublicKey): array[SkRawPublicKeySize, byte] = func toRaw*(pubkey: SkPublicKey): array[SkRawPublicKeySize, byte] =
## Serialize Secp256k1 `public key` ``key`` to raw uncompressed form ## Serialize Secp256k1 `public key` ``key`` to raw uncompressed form
var length = csize_t(len(result)) var length = csize_t(len(result))
let res = secp256k1_ec_pubkey_serialize(
{.noSideEffect.}: # secp256k1_context_no_precomp is actually const, see above secp256k1_context_no_precomp, result.ptr0, addr length,
let res = secp256k1_ec_pubkey_serialize( unsafeAddr pubkey.data, SECP256K1_EC_UNCOMPRESSED)
secp256k1_context_no_precomp, result.ptr0, addr length,
unsafeAddr pubkey.data, SECP256K1_EC_UNCOMPRESSED)
doAssert res == 1, "Can't fail, per documentation" doAssert res == 1, "Can't fail, per documentation"
func toHex*(pubkey: SkPublicKey): string = func toHex*(pubkey: SkPublicKey): string =
@ -294,10 +290,9 @@ func toHex*(pubkey: SkPublicKey): string =
func toRawCompressed*(pubkey: SkPublicKey): array[SkRawCompressedPublicKeySize, byte] = func toRawCompressed*(pubkey: SkPublicKey): array[SkRawCompressedPublicKeySize, byte] =
## Serialize Secp256k1 `public key` ``key`` to raw compressed form ## Serialize Secp256k1 `public key` ``key`` to raw compressed form
var length = csize_t(len(result)) var length = csize_t(len(result))
{.noSideEffect.}: # secp256k1_context_no_precomp is actually const, see above let res = secp256k1_ec_pubkey_serialize(
let res = secp256k1_ec_pubkey_serialize( secp256k1_context_no_precomp, result.ptr0, addr length,
secp256k1_context_no_precomp, result.ptr0, addr length, unsafeAddr pubkey.data, SECP256K1_EC_COMPRESSED)
unsafeAddr pubkey.data, SECP256K1_EC_COMPRESSED)
doAssert res == 1, "Can't fail, per documentation" doAssert res == 1, "Can't fail, per documentation"
func toHexCompressed*(pubkey: SkPublicKey): string = func toHexCompressed*(pubkey: SkPublicKey): string =
@ -309,10 +304,9 @@ func fromRaw*(T: type SkSignature, data: openArray[byte]): SkResult[T] =
return err(static(&"secp: signature must be {SkRawSignatureSize} bytes")) return err(static(&"secp: signature must be {SkRawSignatureSize} bytes"))
var sig {.noinit.}: secp256k1_ecdsa_signature var sig {.noinit.}: secp256k1_ecdsa_signature
{.noSideEffect.}: # secp256k1_context_no_precomp is actually const, see above if secp256k1_ecdsa_signature_parse_compact(
if secp256k1_ecdsa_signature_parse_compact( secp256k1_context_no_precomp, addr sig, data.ptr0) != 1:
secp256k1_context_no_precomp, addr sig, data.ptr0) != 1: return err("secp: cannot parse signaure")
return err("secp: cannot parse signaure")
ok(T(data: sig)) ok(T(data: sig))
@ -323,10 +317,9 @@ func fromDer*(T: type SkSignature, data: openarray[byte]): SkResult[T] =
return err("secp: DER signature too short") return err("secp: DER signature too short")
var sig {.noinit.}: secp256k1_ecdsa_signature var sig {.noinit.}: secp256k1_ecdsa_signature
{.noSideEffect.}: # secp256k1_context_no_precomp is actually const, see above if secp256k1_ecdsa_signature_parse_der(
if secp256k1_ecdsa_signature_parse_der( secp256k1_context_no_precomp, addr sig, data.ptr0, csize_t(len(data))) != 1:
secp256k1_context_no_precomp, addr sig, data.ptr0, csize_t(len(data))) != 1: return err("secp: cannot parse DER signature")
return err("secp: cannot parse DER signature")
ok(T(data: sig)) ok(T(data: sig))
@ -337,10 +330,9 @@ func fromHex*(T: type SkSignature, data: string): SkResult[T] =
func toRaw*(sig: SkSignature): array[SkRawSignatureSize, byte] = func toRaw*(sig: SkSignature): array[SkRawSignatureSize, byte] =
## Serialize signature to compact binary form ## Serialize signature to compact binary form
{.noSideEffect.}: # secp256k1_context_no_precomp is actually const, see above let res = secp256k1_ecdsa_signature_serialize_compact(
let res = secp256k1_ecdsa_signature_serialize_compact( secp256k1_context_no_precomp, result.ptr0, unsafeAddr sig.data)
secp256k1_context_no_precomp, result.ptr0, unsafeAddr sig.data) doAssert res == 1, "Can't fail, per documentation"
doAssert res == 1, "Can't fail, per documentation"
func toDer*(sig: SkSignature, data: var openarray[byte]): int = func toDer*(sig: SkSignature, data: var openarray[byte]): int =
## Serialize Secp256k1 `signature` ``sig`` to raw binary form and store it ## Serialize Secp256k1 `signature` ``sig`` to raw binary form and store it
@ -350,11 +342,10 @@ func toDer*(sig: SkSignature, data: var openarray[byte]): int =
## this is more than `data.len`, `data` is not written to. ## this is more than `data.len`, `data` is not written to.
var buffer: array[SkDerSignatureMaxSize, byte] var buffer: array[SkDerSignatureMaxSize, byte]
var plength = csize_t(len(buffer)) var plength = csize_t(len(buffer))
{.noSideEffect.}: # secp256k1_context_no_precomp is actually const, see above let res = secp256k1_ecdsa_signature_serialize_der(
let res = secp256k1_ecdsa_signature_serialize_der( secp256k1_context_no_precomp, buffer.ptr0, addr plength,
secp256k1_context_no_precomp, buffer.ptr0, addr plength, unsafeAddr sig.data)
unsafeAddr sig.data) doAssert res == 1, "Can't fail, per documentation"
doAssert res == 1, "Can't fail, per documentation"
result = int(plength) result = int(plength)
if len(data) >= result: if len(data) >= result:
copyMem(addr data[0], addr buffer[0], result) copyMem(addr data[0], addr buffer[0], result)
@ -375,10 +366,9 @@ func fromRaw*(T: type SkRecoverableSignature, data: openArray[byte]): SkResult[T
let recid = cint(data[64]) let recid = cint(data[64])
var sig {.noinit.}: secp256k1_ecdsa_recoverable_signature var sig {.noinit.}: secp256k1_ecdsa_recoverable_signature
{.noSideEffect.}: # secp256k1_context_no_precomp is actually const, see above if secp256k1_ecdsa_recoverable_signature_parse_compact(
if secp256k1_ecdsa_recoverable_signature_parse_compact( secp256k1_context_no_precomp, addr sig, data.ptr0, recid) != 1:
secp256k1_context_no_precomp, addr sig, data.ptr0, recid) != 1: return err("secp: invalid recoverable signature")
return err("secp: invalid recoverable signature")
ok(T(data: sig)) ok(T(data: sig))
@ -390,10 +380,9 @@ func fromHex*(T: type SkRecoverableSignature, data: string): SkResult[T] =
func toRaw*(sig: SkRecoverableSignature): array[SkRawRecoverableSignatureSize, byte] = func toRaw*(sig: SkRecoverableSignature): array[SkRawRecoverableSignatureSize, byte] =
## Converts recoverable signature to compact binary form ## Converts recoverable signature to compact binary form
var recid = cint(0) var recid = cint(0)
{.noSideEffect.}: # secp256k1_context_no_precomp is actually const, see above let res = secp256k1_ecdsa_recoverable_signature_serialize_compact(
let res = secp256k1_ecdsa_recoverable_signature_serialize_compact( secp256k1_context_no_precomp, result.ptr0, addr recid, unsafeAddr sig.data)
secp256k1_context_no_precomp, result.ptr0, addr recid, unsafeAddr sig.data) doAssert res == 1, "can't fail, per documentation"
doAssert res == 1, "can't fail, per documentation"
result[64] = byte(recid) result[64] = byte(recid)
@ -461,11 +450,10 @@ func recover*(sig: SkRecoverableSignature, msg: SkMessage): SkResult[SkPublicKey
func ecdh*(seckey: SkSecretKey, pubkey: SkPublicKey): SkEcdhSecret = func ecdh*(seckey: SkSecretKey, pubkey: SkPublicKey): SkEcdhSecret =
## Calculate ECDH shared secret. ## Calculate ECDH shared secret.
var secret {.noinit.}: array[SkEdchSecretSize, byte] var secret {.noinit.}: array[SkEdchSecretSize, byte]
{.noSideEffect.}: # secp256k1_context_no_precomp is actually const, see above let res = secp256k1_ecdh(
let res = secp256k1_ecdh( secp256k1_context_no_precomp, secret.ptr0, unsafeAddr pubkey.data,
secp256k1_context_no_precomp, secret.ptr0, unsafeAddr pubkey.data, seckey.data.ptr0)
seckey.data.ptr0) doAssert res == 1, "cannot compute ECDH secret, keys invalid?"
doAssert res == 1, "cannot compute ECDH secret, keys invalid?"
SkEcdhSecret(data: secret) SkEcdhSecret(data: secret)
@ -473,11 +461,10 @@ func ecdhRaw*(seckey: SkSecretKey, pubkey: SkPublicKey): SkEcdhRawSecret =
## Calculate ECDH shared secret, ethereum style ## Calculate ECDH shared secret, ethereum style
# TODO - deprecate: https://github.com/status-im/nim-eth/issues/222 # TODO - deprecate: https://github.com/status-im/nim-eth/issues/222
var secret {.noinit.}: array[SkEcdhRawSecretSize, byte] var secret {.noinit.}: array[SkEcdhRawSecretSize, byte]
{.noSideEffect.}: # secp256k1_context_no_precomp is actually const, see above let res = secp256k1_ecdh_raw(
let res = secp256k1_ecdh_raw( secp256k1_context_no_precomp, secret.ptr0, unsafeAddr pubkey.data,
secp256k1_context_no_precomp, secret.ptr0, unsafeAddr pubkey.data, seckey.data.ptr0)
seckey.data.ptr0) doAssert res == 1, "cannot compute raw ECDH secret, keys invalid?"
doAssert res == 1, "cannot compute raw ECDH secret, keys invalid?"
SkEcdhRawSecret(data: secret) SkEcdhRawSecret(data: secret)
@ -519,17 +506,16 @@ proc default*(T: type SkEcdhSecret): T {.error: "loophole".}
proc default*(T: type SkEcdhRawSecret): T {.error: "loophole".} proc default*(T: type SkEcdhRawSecret): T {.error: "loophole".}
func tweakAdd*(secretKey: var SkSecretKey, tweak: openArray[byte]): SkResult[void] = func tweakAdd*(secretKey: var SkSecretKey, tweak: openArray[byte]): SkResult[void] =
{.noSideEffect.}: # secp256k1_context_no_precomp is actually const, see above let res = secp256k1_ec_privkey_tweak_add(secp256k1_context_no_precomp, secretKey.data.ptr0, tweak.ptr0)
let res = secp256k1_ec_privkey_tweak_add(secp256k1_context_no_precomp, secretKey.data.ptr0, tweak.ptr0) if res != 1:
if res != 1: err("Tweak out of range, or invalid private key")
err("Tweak out of range, or invalid private key") else:
else: ok()
ok()
func tweakMul*(secretKey: var SkSecretKey, tweak: openArray[byte]): SkResult[void] = func tweakMul*(secretKey: var SkSecretKey, tweak: openArray[byte]): SkResult[void] =
{.noSideEffect.}: # secp256k1_context_no_precomp is actually const, see above let res = secp256k1_ec_privkey_tweak_mul(secp256k1_context_no_precomp, secretKey.data.ptr0, tweak.ptr0)
let res = secp256k1_ec_privkey_tweak_mul(secp256k1_context_no_precomp, secretKey.data.ptr0, tweak.ptr0) if res != 1:
if res != 1: err("Tweak out of range, or equal to zero")
err("Tweak out of range, or equal to zero") else:
else: ok()
ok()

View File

@ -74,12 +74,19 @@ const
var secp256k1_context_no_precomp_imp {. var secp256k1_context_no_precomp_imp {.
importc: "secp256k1_context_no_precomp".}: ptr secp256k1_context importc: "secp256k1_context_no_precomp".}: ptr secp256k1_context
let secp256k1_context_no_precomp* = secp256k1_context_no_precomp_imp
var secp256k1_ecdh_hash_function_default_imp {. var secp256k1_ecdh_hash_function_default_imp {.
importc: "secp256k1_ecdh_hash_function_default".}: secp256k1_ecdh_hash_function importc: "secp256k1_ecdh_hash_function_default".}: secp256k1_ecdh_hash_function
let secp256k1_ecdh_hash_function_default* =
secp256k1_ecdh_hash_function_default_imp template secp256k1_context_no_precomp*: ptr secp256k1_context =
# This is really a constant
{.noSideEffect.}:
secp256k1_context_no_precomp_imp
template secp256k1_ecdh_hash_function_default*: secp256k1_ecdh_hash_function =
# This is really a constant
{.noSideEffect.}:
secp256k1_ecdh_hash_function_default_imp
proc secp256k1_context_create*( proc secp256k1_context_create*(
flags: cuint): ptr secp256k1_context {.secp.} flags: cuint): ptr secp256k1_context {.secp.}
@ -282,12 +289,11 @@ proc secp256k1_ecdsa_recoverable_signature_parse_compact*(
sig: ptr secp256k1_ecdsa_recoverable_signature; sig: ptr secp256k1_ecdsa_recoverable_signature;
input64: ptr cuchar, recid: cint): cint {.secp.} input64: ptr cuchar, recid: cint): cint {.secp.}
proc secp256k1_ecdh*(ctx: ptr secp256k1_context; output32: ptr cuchar; func secp256k1_ecdh*(ctx: ptr secp256k1_context; output32: ptr cuchar;
pubkey: ptr secp256k1_pubkey; pubkey: ptr secp256k1_pubkey;
privkey: ptr cuchar, privkey: ptr cuchar,
hashfp: secp256k1_ecdh_hash_function, hashfp: secp256k1_ecdh_hash_function,
data: pointer data: pointer): cint {.secp.}
): cint {.secp.}
## Compute an EC Diffie-Hellman secret in constant time ## Compute an EC Diffie-Hellman secret in constant time
## Returns: 1: exponentiation was successful ## Returns: 1: exponentiation was successful
## 0: scalar was invalid (zero or overflow) ## 0: scalar was invalid (zero or overflow)
@ -300,11 +306,10 @@ proc secp256k1_ecdh*(ctx: ptr secp256k1_context; output32: ptr cuchar;
## ##
template secp256k1_ecdh*(ctx: ptr secp256k1_context; output32: ptr cuchar; template secp256k1_ecdh*(ctx: ptr secp256k1_context; output32: ptr cuchar;
pubkey: ptr secp256k1_pubkey; pubkey: ptr secp256k1_pubkey;
privkey: ptr cuchar privkey: ptr cuchar): cint =
): cint =
secp256k1_ecdh(ctx, output32, pubkey, privkey, secp256k1_ecdh(ctx, output32, pubkey, privkey,
secp256k1_ecdh_hash_function_default, nil) secp256k1_ecdh_hash_function_default(), nil)
proc secp256k1_ecdh_raw*(ctx: ptr secp256k1_context; output32: ptr cuchar; proc secp256k1_ecdh_raw*(ctx: ptr secp256k1_context; output32: ptr cuchar;
pubkey: ptr secp256k1_pubkey; pubkey: ptr secp256k1_pubkey;