Get rid of ecdhRaw and export ecdh with custom hash func
This commit is contained in:
parent
05b4bde6d0
commit
206e5360b8
|
@ -7,3 +7,5 @@ nimble.paths
|
|||
ci/build_nim.sh
|
||||
ci/NimBinaries/
|
||||
ci/nim/
|
||||
|
||||
*.exe
|
||||
|
|
|
@ -72,9 +72,6 @@ const
|
|||
SkEdchSecretSize* = 32
|
||||
## ECDH-agreed key size
|
||||
|
||||
SkEcdhRawSecretSize* = 33
|
||||
## ECDH-agreed raw key size
|
||||
|
||||
type
|
||||
SkPublicKey* {.requiresInit.} = object
|
||||
## Representation of public key.
|
||||
|
@ -116,10 +113,7 @@ type
|
|||
## Representation of ECDH shared secret
|
||||
data*: array[SkEdchSecretSize, byte]
|
||||
|
||||
SkEcdhRawSecret* {.requiresInit.} = object
|
||||
## Representation of ECDH shared secret, with leading `y` byte
|
||||
# (`y` is 0x02 when pubkey.y is even or 0x03 when odd)
|
||||
data*: array[SkEcdhRawSecretSize, byte]
|
||||
SkEcdhHashFunc* = secp256k1_ecdh_hash_function
|
||||
|
||||
SkResult*[T] = Result[T, cstring]
|
||||
|
||||
|
@ -607,26 +601,26 @@ func recover*(sig: SkRecoverableSignature, msg: SkMessage): SkResult[SkPublicKey
|
|||
|
||||
ok(SkPublicKey(data: data))
|
||||
|
||||
func ecdh*(seckey: SkSecretKey, pubkey: SkPublicKey): SkEcdhSecret =
|
||||
func ecdh*(seckey: SkSecretKey, pubkey: SkPublicKey): SkResult[SkEcdhSecret] =
|
||||
## Calculate ECDH shared secret.
|
||||
var secret {.noinit.}: array[SkEdchSecretSize, byte]
|
||||
let res = secp256k1_ecdh(
|
||||
if secp256k1_ecdh(
|
||||
secp256k1_context_no_precomp, secret.baseAddr, unsafeAddr pubkey.data,
|
||||
seckey.data.baseAddr)
|
||||
doAssert res == 1, "cannot compute ECDH secret, keys invalid?"
|
||||
seckey.data.baseAddr) != 1:
|
||||
return err("cannot compute ECDH secret, keys invalid?")
|
||||
|
||||
SkEcdhSecret(data: secret)
|
||||
ok(SkEcdhSecret(data: secret))
|
||||
|
||||
func ecdhRaw*(seckey: SkSecretKey, pubkey: SkPublicKey): SkEcdhRawSecret =
|
||||
## Calculate ECDH shared secret, ethereum style
|
||||
# TODO - deprecate: https://github.com/status-im/nim-eth/issues/222
|
||||
var secret {.noinit.}: array[SkEcdhRawSecretSize, byte]
|
||||
let res = secp256k1_ecdh_raw(
|
||||
func ecdh*[N: static[int]](seckey: SkSecretKey, pubkey: SkPublicKey,
|
||||
hashfn: SkEcdhHashFunc, data: pointer): SkResult[array[N, byte]] =
|
||||
## Calculate ECDH shared secret using custom hash function.
|
||||
var secret {.noinit.}: array[N, byte]
|
||||
if secp256k1_ecdh(
|
||||
secp256k1_context_no_precomp, secret.baseAddr, unsafeAddr pubkey.data,
|
||||
seckey.data.baseAddr)
|
||||
doAssert res == 1, "cannot compute raw ECDH secret, keys invalid?"
|
||||
seckey.data.baseAddr, hashfn, data) != 1:
|
||||
return err("cannot compute ECDH secret, keys invalid?")
|
||||
|
||||
SkEcdhRawSecret(data: secret)
|
||||
ok(secret)
|
||||
|
||||
func clear*(v: var SkSecretKey) =
|
||||
## Wipe and clear memory of Secp256k1 `private key`.
|
||||
|
@ -640,12 +634,6 @@ func clear*(v: var SkEcdhSecret) =
|
|||
## result in undefined behaviour or Defect
|
||||
burnMem(v.data)
|
||||
|
||||
func clear*(v: var SkEcdhRawSecret) =
|
||||
## Wipe and clear memory of ECDH `shared secret`.
|
||||
## After calling this function, the key is invalid and using it elsewhere will
|
||||
## result in undefined behaviour or Defect
|
||||
burnMem(v.data)
|
||||
|
||||
func `$`*(
|
||||
v: SkPublicKey | SkSecretKey | SkXOnlyPublicKey | SkSignature | SkRecoverableSignature | SkSchnorrSignature): string =
|
||||
toHex(v)
|
||||
|
@ -665,7 +653,6 @@ proc default*(T: type SkSignature): T {.error: "loophole".}
|
|||
proc default*(T: type SkRecoverableSignature): T {.error: "loophole".}
|
||||
proc default*(T: type SkSchnorrSignature): T {.error: "loophole".}
|
||||
proc default*(T: type SkEcdhSecret): T {.error: "loophole".}
|
||||
proc default*(T: type SkEcdhRawSecret): T {.error: "loophole".}
|
||||
|
||||
func tweakAdd*(secretKey: var SkSecretKey, tweak: openArray[byte]): SkResult[void] =
|
||||
let res = secp256k1_ec_privkey_tweak_add(
|
||||
|
|
|
@ -35,7 +35,7 @@ type
|
|||
|
||||
secp256k1_ecdh_hash_function* = proc (output: ptr byte,
|
||||
x32, y32: ptr byte,
|
||||
data: pointer) {.cdecl, raises: [].}
|
||||
data: pointer): cint {.cdecl, raises: [].}
|
||||
|
||||
secp256k1_context* = object
|
||||
secp256k1_scratch_space* = object
|
||||
|
@ -312,23 +312,6 @@ template secp256k1_ecdh*(ctx: ptr secp256k1_context; output32: ptr byte;
|
|||
secp256k1_ecdh(ctx, output32, pubkey, privkey,
|
||||
secp256k1_ecdh_hash_function_default(), nil)
|
||||
|
||||
proc secp256k1_ecdh_raw*(ctx: ptr secp256k1_context; output32: ptr byte;
|
||||
pubkey: ptr secp256k1_pubkey;
|
||||
input32: ptr byte): cint {.secp.}
|
||||
## Compute an EC Diffie-Hellman secret in constant time
|
||||
## Returns: 1: exponentiation was successful
|
||||
## 0: scalar was invalid (zero or overflow)
|
||||
## Args: ctx: pointer to a context object (cannot be NULL)
|
||||
## Out: result: a 33-byte array which will be populated by an ECDH
|
||||
## secret computed from the point and scalar in form
|
||||
## of compressed point
|
||||
## In: pubkey: a pointer to a secp256k1_pubkey containing an
|
||||
## initialized public key
|
||||
## privkey: a 32-byte scalar with which to multiply the point
|
||||
##
|
||||
|
||||
## Multikey interface follows
|
||||
|
||||
type
|
||||
secp256k1_xonly_pubkey* = object
|
||||
## Opaque data structure that holds a parsed and valid "x-only" public key.
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
import ../secp256k1, unittest
|
||||
import
|
||||
../secp256k1,
|
||||
unittest,
|
||||
stew/ptrops
|
||||
|
||||
{.used.}
|
||||
|
||||
|
@ -15,13 +18,13 @@ const
|
|||
1'u8, 0, 0, 0, 0, 0, 0, 0,
|
||||
1'u8, 0, 0, 0, 0, 0, 0, 0,
|
||||
])
|
||||
msg2 = array[40, byte]([
|
||||
msg2: array[40, byte] = [
|
||||
0'u8, 0, 0, 0, 0, 0, 0, 0,
|
||||
0'u8, 0, 0, 0, 0, 0, 0, 0,
|
||||
0'u8, 0, 0, 0, 0, 0, 0, 0,
|
||||
0'u8, 0, 0, 0, 0, 0, 0, 0,
|
||||
0'u8, 0, 0, 0, 0, 0, 0, 0,
|
||||
])
|
||||
]
|
||||
|
||||
proc workingRng(data: var openArray[byte]): bool =
|
||||
data[0] += 1
|
||||
|
@ -72,3 +75,34 @@ suite "secp256k1":
|
|||
SkMessage.fromBytes([]).isErr()
|
||||
SkMessage.fromBytes([0'u8]).isErr()
|
||||
SkMessage.fromBytes(array[32, byte](msg0)).isOk()
|
||||
|
||||
test "Custom hash function":
|
||||
proc customHash(output: ptr byte, x32, y32: ptr byte, data: pointer): cint
|
||||
{.cdecl, raises: [].} =
|
||||
# Save x and y as uncompressed public key
|
||||
output[] = 0x04
|
||||
copyMem(output.offset(1), x32, 32)
|
||||
copyMem(output.offset(33), y32, 32)
|
||||
return 1
|
||||
|
||||
proc skone(_: type SkSecretKey): SkSecretKey =
|
||||
# silence noisy warning: Cannot prove that 'result' is initialized.
|
||||
result = SkSecretKey.random(workingRng)[]
|
||||
var data: array[SkRawSecretKeySize, byte]
|
||||
zeroMem(data[0].addr, data.len)
|
||||
data[31] = 1
|
||||
copyMem(result.addr, data[0].addr, data.len)
|
||||
|
||||
let
|
||||
sone = SkSecretKey.skone()
|
||||
sb32 = SkSecretKey.random(workingRng)[]
|
||||
pk0 = sone.toPublicKey
|
||||
pk1 = sb32.toPublicKey
|
||||
|
||||
var
|
||||
# compute using ECDH function with custom hash function
|
||||
outputEcdh = ecdh[65](sb32, pk0, customHash, nil).get
|
||||
# compute "explicitly"
|
||||
pointSer = pk1.toRaw
|
||||
|
||||
check equalMem(outputEcdh.addr, pointSer.addr, 65)
|
||||
|
|
Loading…
Reference in New Issue