166 lines
4.3 KiB
C++
166 lines
4.3 KiB
C++
/***
|
|
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
|
|
|
File: PrivateECCImpl.cpp
|
|
File: ECCGeneric.cpp
|
|
Date: 2021-9-17
|
|
File: KCryptoECC.cpp
|
|
Date: 2021-1-15
|
|
Author: Reece
|
|
***/
|
|
#include <Source/RuntimeInternal.hpp>
|
|
#include "ECC.hpp"
|
|
#include "ECCGeneric.hpp"
|
|
#include "ECCCurves.hpp"
|
|
#include "PrivateECCImpl.hpp"
|
|
#include "PublicECCImpl.hpp"
|
|
|
|
namespace Aurora::Crypto::ECC
|
|
{
|
|
PrivateECCImpl::PrivateECCImpl(EECCCurve type, ecc_key &key) : _key(key), _type(type)
|
|
{
|
|
|
|
}
|
|
|
|
PrivateECCImpl::~PrivateECCImpl()
|
|
{
|
|
ecc_free(&this->_key);
|
|
}
|
|
|
|
EECCCurve PrivateECCImpl::GetType()
|
|
{
|
|
return this->_type;
|
|
}
|
|
|
|
bool PrivateECCImpl::Sign(const AuMemoryViewRead &plainText,
|
|
AuHashing::EHashType method,
|
|
AuByteBuffer &out)
|
|
{
|
|
const int salt = 0;
|
|
|
|
if (!plainText.HasMemory())
|
|
{
|
|
SysPushErrorParam();
|
|
return {};
|
|
}
|
|
|
|
int hash = ::Crypto::HashMethodToId(method);
|
|
if (hash == 0xFF)
|
|
{
|
|
SysPushErrorCrypt("invalid hash {}", AuUInt(method));
|
|
return false;
|
|
}
|
|
|
|
if (!AuTryResize(out, 1024))
|
|
{
|
|
SysPushErrorMem();
|
|
return false;
|
|
}
|
|
|
|
AuByteBuffer hashVec;
|
|
|
|
if (!AuTryResize(hashVec, 128))
|
|
{
|
|
SysPushErrorMem();
|
|
return false;
|
|
}
|
|
|
|
unsigned long hashSize = hashVec.size();
|
|
auto ret = ::hash_memory(hash,
|
|
AuReinterpretCast<const unsigned char *>(plainText.ptr), plainText.length,
|
|
AuReinterpretCast<unsigned char *>(hashVec.data()), &hashSize);
|
|
if (ret != CRYPT_OK)
|
|
{
|
|
SysPushErrorCrypt("{}", ret);
|
|
return false;
|
|
}
|
|
|
|
return Sign(hashVec, out);
|
|
}
|
|
|
|
bool PrivateECCImpl::Sign(const AuMemoryViewRead &hash,
|
|
AuByteBuffer &out)
|
|
{
|
|
int iRet;
|
|
prng_state yarrow_prng;
|
|
|
|
if (!hash.HasMemory())
|
|
{
|
|
SysPushErrorParam();
|
|
return {};
|
|
}
|
|
|
|
if (!out.GetOrAllocateLinearWriteable(1024))
|
|
{
|
|
SysPushErrorMem();
|
|
return {};
|
|
}
|
|
|
|
iRet = yarrow_start(&yarrow_prng);
|
|
if (iRet != CRYPT_OK)
|
|
{
|
|
SysPushErrorCrypt("{}", iRet);
|
|
return false;
|
|
}
|
|
|
|
unsigned long len = 1024;
|
|
iRet = ::ecc_sign_hash_ex(AuReinterpretCast<const unsigned char *>(hash.ptr), hash.length,
|
|
out.writePtr, &len,
|
|
&yarrow_prng,
|
|
::Crypto::gPrngYarrow,
|
|
LTC_ECCSIG_ETH27,
|
|
nullptr,
|
|
&this->_key);
|
|
if (iRet != CRYPT_OK)
|
|
{
|
|
SysPushErrorCrypt("{}", iRet);
|
|
return false;
|
|
}
|
|
|
|
out.writePtr += len;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool PrivateECCImpl::ECDH(const AuSPtr<IECCPublic> &partnerPublic,
|
|
AuByteBuffer &sharedKey)
|
|
{
|
|
auto writeView = sharedKey.GetOrAllocateLinearWriteable(128);
|
|
if (!writeView)
|
|
{
|
|
SysPushErrorMem();
|
|
return {};
|
|
}
|
|
|
|
if (partnerPublic->GetType() != this->GetType())
|
|
{
|
|
SysPushErrorCrypto("Can not EDCH with incompatible curve type (noting ed25519 requires translation to x25519)");
|
|
return false;
|
|
}
|
|
|
|
unsigned long actualSize = 128;
|
|
auto ret = ::ecc_shared_secret(&this->_key,
|
|
&(AuReinterpretCast<PublicECCImpl>(partnerPublic)->GetKey()),
|
|
sharedKey.writePtr,
|
|
&actualSize);
|
|
if (ret != CRYPT_OK)
|
|
{
|
|
SysPushErrorCrypt("{}", ret);
|
|
return false;
|
|
}
|
|
|
|
sharedKey.writePtr += actualSize;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool PrivateECCImpl::AsPublicECC(AuByteBuffer &out)
|
|
{
|
|
return ExportECCKey(this->_key, true, out);
|
|
}
|
|
|
|
bool PrivateECCImpl::AsPrivateECC(AuByteBuffer &out)
|
|
{
|
|
return ExportECCKey(this->_key, false, out);
|
|
}
|
|
} |