mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
add KeyPairHedera mostly copied from KeyPairEd25519 but not testet yet. Maybe I must use the iroha ed25519 implementation because in the past sodium don't work together with hedera
This commit is contained in:
parent
cb86ed9422
commit
ba23cf7e37
148
src/cpp/Crypto/KeyPairHedera.cpp
Normal file
148
src/cpp/Crypto/KeyPairHedera.cpp
Normal file
@ -0,0 +1,148 @@
|
||||
#include "KeyPairHedera.h"
|
||||
#include "../lib/DataTypeConverter.h"
|
||||
#include <assert.h>
|
||||
|
||||
#include "../SingletonManager/ErrorManager.h"
|
||||
|
||||
KeyPairHedera::KeyPairHedera()
|
||||
: mPrivateKey(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
KeyPairHedera::KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publicKey /* = nullptr*/)
|
||||
: mPrivateKey(nullptr)
|
||||
{
|
||||
auto derPrefixPriv = DataTypeConverter::hexToBin("302e020100300506032b657004220420");
|
||||
auto derPrefixPub = DataTypeConverter::hexToBin("302a300506032b6570032100");
|
||||
|
||||
auto mm = MemoryManager::getInstance();
|
||||
|
||||
if (privateKey) {
|
||||
switch (privateKey->size()) {
|
||||
case 48:
|
||||
// key with prefix
|
||||
if (0 == sodium_memcmp(*privateKey, *derPrefixPriv, derPrefixPriv->size())) {
|
||||
//int crypto_sign_seed_keypair(unsigned char *pk, unsigned char *sk, const unsigned char *seed);
|
||||
auto seed = mm->getFreeMemory(crypto_sign_ed25519_SEEDBYTES);
|
||||
memcpy(*seed, privateKey->data(derPrefixPriv->size()), crypto_sign_ed25519_SEEDBYTES);
|
||||
createKeyFromSeed(seed);
|
||||
break;
|
||||
}
|
||||
case 32:
|
||||
createKeyFromSeed(privateKey);
|
||||
break;
|
||||
case 64:
|
||||
//mPrivateKey = privateKey;
|
||||
if (!mPrivateKey || mPrivateKey->size() != privateKey->size()) {
|
||||
if (mPrivateKey) {
|
||||
mm->releaseMemory(mPrivateKey);
|
||||
}
|
||||
mPrivateKey = mm->getFreeMemory(privateKey->size());
|
||||
memcpy(*mPrivateKey, *privateKey, privateKey->size());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw std::exception("[KeyPairHedera] invalid private key");
|
||||
}
|
||||
crypto_sign_ed25519_sk_to_pk(mPublicKey, *mPrivateKey);
|
||||
}
|
||||
else if (publicKey) {
|
||||
switch (publicKey->size())
|
||||
{
|
||||
case 32: { // raw public key
|
||||
memcpy(mPublicKey, *publicKey, publicKey->size());
|
||||
break;
|
||||
}
|
||||
case 44: // DER encoded public key
|
||||
if (0 == sodium_memcmp(*publicKey, *derPrefixPub, derPrefixPub->size())) {
|
||||
memcpy(mPublicKey, publicKey->data(derPrefixPub->size()), ed25519_pubkey_SIZE);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw std::exception("[KeyPairHedera] invalid public key");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mm->releaseMemory(derPrefixPriv);
|
||||
mm->releaseMemory(derPrefixPub);
|
||||
}
|
||||
|
||||
KeyPairHedera::~KeyPairHedera()
|
||||
{
|
||||
auto mm = MemoryManager::getInstance();
|
||||
if (mPrivateKey) {
|
||||
mm->releaseMemory(mPrivateKey);
|
||||
mPrivateKey = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void KeyPairHedera::createKeyFromSeed(const MemoryBin* seed)
|
||||
{
|
||||
assert(seed && seed->size() == crypto_sign_ed25519_SEEDBYTES);
|
||||
|
||||
auto mm = MemoryManager::getInstance();
|
||||
auto secret_key = mm->getFreeMemory(crypto_sign_SECRETKEYBYTES);
|
||||
crypto_sign_seed_keypair(mPublicKey, *secret_key, *seed);
|
||||
|
||||
if (mPrivateKey) {
|
||||
mm->releaseMemory(mPrivateKey);
|
||||
}
|
||||
mPrivateKey = secret_key;
|
||||
|
||||
// iroha
|
||||
//ed25519_privkey_SIZE
|
||||
//ed25519_derive_public_key(const private_key_t* sk,public_key_t* pk);
|
||||
}
|
||||
|
||||
MemoryBin* KeyPairHedera::sign(const unsigned char* message, size_t messageSize) const
|
||||
{
|
||||
if (!message || !messageSize) return nullptr;
|
||||
if (!mPrivateKey) return nullptr;
|
||||
auto mm = MemoryManager::getInstance();
|
||||
auto em = ErrorManager::getInstance();
|
||||
|
||||
const static char functionName[] = "KeyPairHedera::sign";
|
||||
|
||||
auto signBinBuffer = mm->getFreeMemory(crypto_sign_BYTES);
|
||||
unsigned long long actualSignLength = 0;
|
||||
|
||||
if (crypto_sign_detached(*signBinBuffer, &actualSignLength, message, messageSize, *mPrivateKey)) {
|
||||
em->addError(new Error(functionName, "sign failed"));
|
||||
auto messageHex = DataTypeConverter::binToHex(message, messageSize);
|
||||
em->addError(new ParamError(functionName, "message as hex", messageHex));
|
||||
mm->releaseMemory(signBinBuffer);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (crypto_sign_verify_detached(*signBinBuffer, message, messageSize, mPublicKey) != 0) {
|
||||
// Incorrect signature!
|
||||
//printf("c[KeyBuffer::%s] sign verify failed\n", __FUNCTION__);
|
||||
em->addError(new Error(functionName, "sign verify failed"));
|
||||
auto messageHex = DataTypeConverter::binToHex(message, messageSize);
|
||||
em->addError(new ParamError(functionName, "message as hex", messageHex));
|
||||
mm->releaseMemory(signBinBuffer);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// debug
|
||||
/*const size_t hex_sig_size = crypto_sign_BYTES * 2 + 1;
|
||||
char sig_hex[hex_sig_size];
|
||||
sodium_bin2hex(sig_hex, hex_sig_size, *signBinBuffer, crypto_sign_BYTES);
|
||||
printf("[User::sign] signature hex: %s\n", sig_hex);
|
||||
*/
|
||||
|
||||
return signBinBuffer;
|
||||
|
||||
}
|
||||
|
||||
bool KeyPairHedera::verify(const unsigned char* message, size_t messageSize, MemoryBin* signature) const
|
||||
{
|
||||
if (crypto_sign_verify_detached(*signature, message, messageSize, mPublicKey) != 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
82
src/cpp/Crypto/KeyPairHedera.h
Normal file
82
src/cpp/Crypto/KeyPairHedera.h
Normal file
@ -0,0 +1,82 @@
|
||||
#ifndef __GRADIDO_LOGIN_SERVER_CRYPTO_HEDERA_KEYS_H
|
||||
#define __GRADIDO_LOGIN_SERVER_CRYPTO_HEDERA_KEYS_H
|
||||
|
||||
#include "IKeyPair.h"
|
||||
|
||||
/*!
|
||||
* \author: Dario Rekowski
|
||||
*
|
||||
* \date: 2020-08-28
|
||||
*
|
||||
* \brief: Key Pairs class for ed25519 keys, used by hedera for transaction sign
|
||||
*/
|
||||
|
||||
|
||||
#include "sodium.h"
|
||||
#include "iroha-ed25519/include/ed25519/ed25519.h"
|
||||
|
||||
class KeyPairHedera : public IKeyPair
|
||||
{
|
||||
public:
|
||||
//! \param privateKey: copy
|
||||
//! \param publicKey: copy
|
||||
//!
|
||||
KeyPairHedera(const MemoryBin* privateKey, const MemoryBin* publicKey = nullptr);
|
||||
|
||||
~KeyPairHedera();
|
||||
|
||||
|
||||
//! \return caller take ownership of return value
|
||||
MemoryBin* sign(const MemoryBin* message) const { return sign(message->data(), message->size()); }
|
||||
inline MemoryBin* sign(const std::string& bodyBytes) const { return sign((const unsigned char*)bodyBytes.data(), bodyBytes.size()); }
|
||||
MemoryBin* sign(const unsigned char* message, size_t messageSize) const;
|
||||
|
||||
bool verify(const unsigned char* message, size_t messageSize, MemoryBin* signature) const;
|
||||
|
||||
inline const unsigned char* getPublicKey() const { return mPublicKey; }
|
||||
|
||||
inline bool isTheSame(const KeyPairHedera& b) const {
|
||||
return 0 == sodium_memcmp(mPublicKey, b.mPublicKey, ed25519_pubkey_SIZE);
|
||||
}
|
||||
inline bool isTheSame(const unsigned char* pubkey) const {
|
||||
if (!pubkey)
|
||||
return false;
|
||||
return 0 == sodium_memcmp(mPublicKey, pubkey, ed25519_pubkey_SIZE);
|
||||
}
|
||||
//! \return 0 if the same
|
||||
//! \return -1 if not the same
|
||||
//! \return 1 if hasn't private key
|
||||
inline int isTheSame(const MemoryBin* privkey) const {
|
||||
if (!mPrivateKey) return 1;
|
||||
if (privkey->size() != mPrivateKey->size()) return -1;
|
||||
return sodium_memcmp(*mPrivateKey, *privkey, privkey->size());
|
||||
}
|
||||
|
||||
inline bool operator == (const KeyPairHedera& b) const { return isTheSame(b); }
|
||||
inline bool operator != (const KeyPairHedera& b) const { return !isTheSame(b); }
|
||||
|
||||
inline bool operator == (const unsigned char* b) const { return isTheSame(b); }
|
||||
inline bool operator != (const unsigned char* b) const { return !isTheSame(b); }
|
||||
|
||||
inline bool hasPrivateKey() const { return mPrivateKey != nullptr; }
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
KeyPairHedera();
|
||||
void createKeyFromSeed(const MemoryBin* seed);
|
||||
|
||||
private:
|
||||
// 64 Byte
|
||||
//! \brief ed25519 libsodium private key
|
||||
//!
|
||||
//! TODO: replace MemoryBin by a memory obfuscation class which make it hard to steal the private key from memory
|
||||
MemoryBin* mPrivateKey;
|
||||
|
||||
// 32 Byte
|
||||
//! \brief ed25519 libsodium public key
|
||||
unsigned char mPublicKey[ed25519_pubkey_SIZE];
|
||||
};
|
||||
|
||||
#endif //__GRADIDO_LOGIN_SERVER_CRYPTO_HEDERA_KEYS_H
|
||||
Loading…
x
Reference in New Issue
Block a user