/*** 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) : isX25519_(isX25519), key_(key) { } PrivateCurve25519Impl::~PrivateCurve25519Impl() { } bool PrivateCurve25519Impl::Sign(const Memory::MemoryViewRead &plainText, EHashType method, Memory::ByteBuffer &out) { const int salt = 0; if (this->isX25519_) { return false; } if (!plainText.HasMemory()) { SysPushErrorParam(); return {}; } int hash = HashMethodToId(method); if (hash == 0xFF) { SysPushErrorCrypt("invalid hash {}", 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, reinterpret_cast(plainText.ptr), plainText.length, reinterpret_cast(hashVec.data()), &hashSize); if (ret != CRYPT_OK) { SysPushErrorCrypt("{}", ret); return false; } return Sign(hashVec, out); } bool PrivateCurve25519Impl::Sign(const Memory::MemoryViewRead &hash, Memory::ByteBuffer &out) { if (this->isX25519_) { return false; } if (!hash.HasMemory()) { SysPushErrorParam(); return {}; } if (!AuTryResize(out, 1024)) { SysPushErrorMem(); return false; } unsigned long len = out.size(); auto ret = ed25519_sign(reinterpret_cast(hash.ptr), hash.length, out.data(), &len, &key_); if (ret != CRYPT_OK) { SysPushErrorCrypt("{}", ret); return false; } if (!AuTryResize(out, len)) { SysPushErrorMem(); return false; } return true; } bool PrivateCurve25519Impl::ECDH(const AuSPtr &partnerPublic, Memory::ByteBuffer &sharedKey) { if (!this->isX25519_) { return false; } AuByteBuffer sharedSecret; if (!AuTryResize(sharedSecret, 128)) { SysPushErrorMem(); return false; } if (partnerPublic->GetType() == this->GetType()) { SysPushErrorCrypto("Can not EDCH with incompatible curve curve type (noting, ed25519 requires translation to x25519)"); return false; } unsigned long actualSize = sharedSecret.size(); auto ret = x25519_shared_secret(&key_, &(AuReinterpretCast(partnerPublic)->GetKey()), sharedSecret.data(), &actualSize); if (ret != CRYPT_OK) { SysPushErrorCrypt("{}", ret); return false; } if (!AuTryResize(sharedSecret, actualSize)) { SysPushErrorMem(); return false; } return true; } bool PrivateCurve25519Impl::AsPublicECC(Memory::ByteBuffer &out) { if (!AuTryResize(out, 1024)) { return false; } unsigned long actualSize; int ret; if (this->isX25519_) { actualSize = out.size(); ret = x25519_export(out.data(), &actualSize, PK_PUBLIC, &this->key_); } else { actualSize = out.size(); ret = ed25519_export(out.data(), &actualSize, PK_PUBLIC, &this->key_); } if (ret != CRYPT_OK) { SysPushErrorCrypt("{}", ret); return false; } if (!AuTryResize(out, actualSize)) { SysPushErrorMem(); return false; } return true; } bool PrivateCurve25519Impl::AsPrivateECC(Memory::ByteBuffer &out) { if (!AuTryResize(out, 1024)) { return false; } unsigned long actualSize; int ret; if (this->isX25519_) { actualSize = out.size(); ret = x25519_export(out.data(), &actualSize, PK_PRIVATE, &this->key_); } else { actualSize = out.size(); ret = ed25519_export(out.data(), &actualSize, PK_PRIVATE, &this->key_); } if (ret != CRYPT_OK) { SysPushErrorCrypt("{}", ret); return false; } if (!AuTryResize(out, actualSize)) { SysPushErrorMem(); return false; } return true; } EECCCurve PrivateCurve25519Impl::GetType() { return this->isX25519_ ? EECCCurve::eCurveX25519 : EECCCurve::eCurveEd25519; } }