/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: ECCGeneric.cpp Date: 2021-9-17 Author: Reece ***/ #include #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) { } PrivateECCImpl::~PrivateECCImpl() { ecc_free(&_key); } EECCCurve PrivateECCImpl::GetType() { return _type; } bool PrivateECCImpl::Sign(const Memory::MemoryViewRead &plainText, EHashType method, AuList &out) { prng_state yarrow_prng; const int salt = 0; 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; } AuList 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 PrivateECCImpl::Sign(const Memory::MemoryViewRead &hash, AuList &out) { prng_state yarrow_prng; const int salt = 0; if (!hash.HasMemory()) { SysPushErrorParam(); return {}; } if (!AuTryResize(out, 1024)) { SysPushErrorMem(); return false; } unsigned long len = out.size(); auto ret = ecc_sign_hash_ex(reinterpret_cast(hash.ptr), hash.length, out.data(), &len, &yarrow_prng, ::Crypto::gPrngYarrow, LTC_ECCSIG_ETH27, nullptr, &_key); if (ret != CRYPT_OK) { SysPushErrorCrypt("{}", ret); return false; } if (!AuTryResize(out, len)) { SysPushErrorMem(); return false; } return true; } bool PrivateECCImpl::ECDH(const AuSPtr &partnerPublic, AuList &sharedKey) { AuList 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 = ecc_shared_secret(&_key, &(std::reinterpret_pointer_cast(partnerPublic)->GetKey()), sharedSecret.data(), &actualSize); if (ret != CRYPT_OK) { SysPushErrorCrypt("{}", ret); return false; } if (!AuTryResize(sharedSecret, actualSize)) { SysPushErrorMem(); return false; } return true; } bool PrivateECCImpl::AsPublicECC(AuList &out) { return ExportECCKey(_key, true, out); } bool PrivateECCImpl::AsPrivateECC(AuList &out) { return ExportECCKey(_key, false, out); } }