[clef] DH implementation started

This commit is contained in:
Daniel A. Nagy 2018-09-24 17:55:28 +02:00
parent 6f31075706
commit b989466239
2 changed files with 46 additions and 2 deletions

View file

@ -16,6 +16,7 @@ package secp256k1
#define NDEBUG #define NDEBUG
#include "./libsecp256k1/src/secp256k1.c" #include "./libsecp256k1/src/secp256k1.c"
#include "./libsecp256k1/src/modules/recovery/main_impl.h" #include "./libsecp256k1/src/modules/recovery/main_impl.h"
#include "./libsecp256k1/src/modules/ecdh/main_impl.h"
#include "ext.h" #include "ext.h"
typedef void (*callbackFunc) (const char* msg, void* data); typedef void (*callbackFunc) (const char* msg, void* data);
@ -86,6 +87,22 @@ func Sign(msg []byte, seckey []byte) ([]byte, error) {
return sig, nil return sig, nil
} }
// SharedSecret computes the hashed ECDH shared secret.
// pubkey must be an EC public key
// seckey must be an EC private key
func SharedSecret(pubkey []byte, seckey []byte) ([]byte, error) {
if len(seckey) != 32 {
return nil, ErrInvalidKey
}
seckeydata := (*C.uchar)(unsafe.Pointer(&seckey[0]))
pubkeydata := (*C.uchar)(unsafe.Pointer(&pubkey[0]))
result := make([]byte, 32)
if C.secp256k1_ecdh(context, &result, pubkeydata, seckeydata) != 1 {
return nil, ErrInvalidKey
}
return result, nil
}
// RecoverPubkey returns the public key of the signer. // RecoverPubkey returns the public key of the signer.
// msg must be the 32-byte hash of the message to be signed. // msg must be the 32-byte hash of the message to be signed.
// sig must be a 65-byte compact ECDSA signature containing the // sig must be a 65-byte compact ECDSA signature containing the

View file

@ -443,6 +443,34 @@ func (api *SignerAPI) EcRecover(ctx context.Context, data, sig hexutil.Bytes) (c
return crypto.PubkeyToAddress(*rpk), nil return crypto.PubkeyToAddress(*rpk), nil
} }
// SharedSecret returns the shared ECDH secret, salted and hashed.
// TODO: Documentation in the Wiki
func (api *SignerAPI) SharedSecret(ctx context.Context, otherKey, salt hexutil.Bytes) (hexutil.Bytes, error) {
// Get the other public key
otherPubKey, err := crypto.UnmarshalPubkey(otherKey)
if err != nil {
return nil, err
}
addr := crypto.PubkeyToAddress(otherPubKey)
// We make the request prior to looking up if we actually have the account, to prevent
// account-enumeration via the API
req := &SharedSecretRequest{Address: addr}
res, err := api.UI.ApproveSharedSecret(req)
if err != nil {
return nil, err
}
if !res.Approved {
return nil, ErrRequestDenied
}
// Look up the wallet containing the requested signer
account := accounts.Account{Address: addr.Address()}
wallet, err := api.am.Find(account)
if err != nil {
return nil, err
}
}
// SignHash is a helper function that calculates a hash for the given message that can be // SignHash is a helper function that calculates a hash for the given message that can be
// safely used to calculate a signature from. // safely used to calculate a signature from.
// //
@ -500,4 +528,3 @@ func (api *SignerAPI) Import(ctx context.Context, keyJSON json.RawMessage) (Acco
} }
return Account{Typ: "Account", URL: acc.URL, Address: acc.Address}, nil return Account{Typ: "Account", URL: acc.URL, Address: acc.Address}, nil
} }