/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: ECCX25519Private.cpp Date: 2022-2-15 Author: Reece ***/ #include #include "ECC.hpp" #include "ECCX25519Private.hpp" #include "ECCX25519Public.hpp" namespace Aurora::Crypto::ECC { PrivateCurve25519Impl::PrivateCurve25519Impl(bool isX25519, curve25519_key &&key) : bIsX25519_(isX25519), key_(key) { } PrivateCurve25519Impl::~PrivateCurve25519Impl() { } bool PrivateCurve25519Impl::Sign(const Memory::MemoryViewRead &plainText, AuHashing::EHashType method, Memory::ByteBuffer &out) { const int salt = 0; if (this->bIsX25519_) { return false; } if (!plainText.HasMemory()) { SysPushErrorParam(); return {}; } int hash = ::Crypto::HashMethodToId(method); if (hash == 0xFF) { SysPushErrorCrypt("invalid hash {}", AuUInt(method)); return false; } AuByteBuffer hashVec; if (!AuTryResize(hashVec, 128)) { SysPushErrorMem(); return false; } unsigned long hashSize = 1024; auto iRet = ::hash_memory(hash, reinterpret_cast(plainText.ptr), plainText.length, reinterpret_cast(hashVec.data()), &hashSize); if (iRet != CRYPT_OK) { SysPushErrorCrypt("{}", iRet); return false; } return Sign(hashVec, out); } bool PrivateCurve25519Impl::Sign(const Memory::MemoryViewRead &hash, Memory::ByteBuffer &out) { if (this->bIsX25519_) { return false; } if (!hash.HasMemory()) { SysPushErrorParam(); return {}; } if (!out.GetOrAllocateLinearWriteable(1024)) { SysPushErrorMem(); return {}; } unsigned long len = 1024; auto iRet = ::ed25519_sign(AuReinterpretCast(hash.ptr), hash.length, out.writePtr, &len, &this->key_); if (iRet != CRYPT_OK) { SysPushErrorCrypt("{}", iRet); return false; } out.writePtr += len; return true; } bool PrivateCurve25519Impl::ECDH(const AuSPtr &partnerPublic, Memory::ByteBuffer &sharedKey) { if (!this->bIsX25519_) { return false; } auto writeView = sharedKey.GetOrAllocateLinearWriteable(128); if (!writeView) { SysPushErrorMem(); return {}; } if (partnerPublic->GetType() != this->GetType()) { SysPushErrorCrypto("Can not EDCH with incompatible pairs curve (noting ed25519 requires translation to x25519)"); return false; } unsigned long actualSize = 128; auto iRet = ::x25519_shared_secret(&this->key_, &(AuReinterpretCast(partnerPublic)->GetKey()), sharedKey.writePtr, &actualSize); if (iRet != CRYPT_OK) { SysPushErrorCrypt("{}", iRet); return false; } sharedKey.writePtr += actualSize; return true; } bool PrivateCurve25519Impl::AsPublicECC(Memory::ByteBuffer &out) { auto writeView = out.GetOrAllocateLinearWriteable(4096); if (!writeView) { SysPushErrorMem(); return {}; } unsigned long actualSize; int ret; actualSize = 4096; if (this->bIsX25519_) { ret = x25519_export(out.writePtr, &actualSize, PK_PUBLIC | PK_STD, &this->key_); } else { ret = ed25519_export(out.writePtr, &actualSize, PK_PUBLIC | PK_STD, &this->key_); } if (ret != CRYPT_OK) { SysPushErrorCrypt("{}", ret); return false; } out.writePtr += actualSize; return true; } bool PrivateCurve25519Impl::AsPrivateECC(Memory::ByteBuffer &out) { auto writeView = out.GetOrAllocateLinearWriteable(4096); if (!writeView) { SysPushErrorMem(); return {}; } unsigned long actualSize; int ret; actualSize = 4096; if (this->bIsX25519_) { ret = x25519_export(out.writePtr, &actualSize, PK_PRIVATE | PK_STD, &this->key_); } else { ret = ed25519_export(out.writePtr, &actualSize, PK_PRIVATE | PK_STD, &this->key_); } if (ret != CRYPT_OK) { SysPushErrorCrypt("{}", ret); return false; } out.writePtr += actualSize; return true; } EECCCurve PrivateCurve25519Impl::GetType() { return this->bIsX25519_ ? EECCCurve::eCurveX25519 : EECCCurve::eCurveEd25519; } }