/* * Copyright (c) 2013-2021, The PurpleI2P Project * * This file is part of Purple i2pd project and licensed under BSD3 * * See full license text in LICENSE file at top of project tree */ #include #include "Log.h" #include "Gost.h" #include "CryptoKey.h" namespace i2p { namespace crypto { ElGamalEncryptor::ElGamalEncryptor(const uint8_t *pub) { memcpy(m_PublicKey, pub, 256); } void ElGamalEncryptor::Encrypt(const uint8_t *data, uint8_t *encrypted) { ElGamalEncrypt(m_PublicKey, data, encrypted); } ElGamalDecryptor::ElGamalDecryptor(const uint8_t *priv) { memcpy(m_PrivateKey, priv, 256); } bool ElGamalDecryptor::Decrypt(const uint8_t *encrypted, uint8_t *data) { return ElGamalDecrypt(m_PrivateKey, encrypted, data); } ECIESP256Encryptor::ECIESP256Encryptor(const uint8_t *pub) { m_Curve = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); m_PublicKey = EC_POINT_new(m_Curve); BIGNUM *x = BN_bin2bn(pub, 32, nullptr); BIGNUM *y = BN_bin2bn(pub + 32, 32, nullptr); if (!EC_POINT_set_affine_coordinates_GFp(m_Curve, m_PublicKey, x, y, nullptr)) LogPrint(eLogError, "ECICS P256 invalid public key"); BN_free(x); BN_free(y); } ECIESP256Encryptor::~ECIESP256Encryptor() { if (m_Curve) EC_GROUP_free(m_Curve); if (m_PublicKey) EC_POINT_free(m_PublicKey); } void ECIESP256Encryptor::Encrypt(const uint8_t *data, uint8_t *encrypted) { if (m_Curve && m_PublicKey) ECIESEncrypt(m_Curve, m_PublicKey, data, encrypted); } ECIESP256Decryptor::ECIESP256Decryptor(const uint8_t *priv) { m_Curve = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); m_PrivateKey = BN_bin2bn(priv, 32, nullptr); } ECIESP256Decryptor::~ECIESP256Decryptor() { if (m_Curve) EC_GROUP_free(m_Curve); if (m_PrivateKey) BN_free(m_PrivateKey); } bool ECIESP256Decryptor::Decrypt(const uint8_t *encrypted, uint8_t *data) { if (m_Curve && m_PrivateKey) return ECIESDecrypt(m_Curve, m_PrivateKey, encrypted, data); return false; } void CreateECIESP256RandomKeys(uint8_t *priv, uint8_t *pub) { EC_GROUP *curve = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1); EC_POINT *p = nullptr; BIGNUM *key = nullptr; GenerateECIESKeyPair(curve, key, p); bn2buf(key, priv, 32); RAND_bytes(priv + 32, 224); BN_free(key); BIGNUM *x = BN_new(), *y = BN_new(); EC_POINT_get_affine_coordinates_GFp(curve, p, x, y, NULL); bn2buf(x, pub, 32); bn2buf(y, pub + 32, 32); RAND_bytes(pub + 64, 192); EC_POINT_free(p); BN_free(x); BN_free(y); EC_GROUP_free(curve); } ECIESGOSTR3410Encryptor::ECIESGOSTR3410Encryptor(const uint8_t *pub) { auto &curve = GetGOSTR3410Curve(eGOSTR3410CryptoProA); m_PublicKey = EC_POINT_new(curve->GetGroup()); BIGNUM *x = BN_bin2bn(pub, 32, nullptr); BIGNUM *y = BN_bin2bn(pub + 32, 32, nullptr); if (!EC_POINT_set_affine_coordinates_GFp(curve->GetGroup(), m_PublicKey, x, y, nullptr)) LogPrint(eLogError, "ECICS GOST R 34.10 invalid public key"); BN_free(x); BN_free(y); } ECIESGOSTR3410Encryptor::~ECIESGOSTR3410Encryptor() { if (m_PublicKey) EC_POINT_free(m_PublicKey); } void ECIESGOSTR3410Encryptor::Encrypt(const uint8_t *data, uint8_t *encrypted) { if (m_PublicKey) ECIESEncrypt(GetGOSTR3410Curve(eGOSTR3410CryptoProA)->GetGroup(), m_PublicKey, data, encrypted); } ECIESGOSTR3410Decryptor::ECIESGOSTR3410Decryptor(const uint8_t *priv) { m_PrivateKey = BN_bin2bn(priv, 32, nullptr); } ECIESGOSTR3410Decryptor::~ECIESGOSTR3410Decryptor() { if (m_PrivateKey) BN_free(m_PrivateKey); } bool ECIESGOSTR3410Decryptor::Decrypt(const uint8_t *encrypted, uint8_t *data) { if (m_PrivateKey) return ECIESDecrypt(GetGOSTR3410Curve(eGOSTR3410CryptoProA)->GetGroup(), m_PrivateKey, encrypted, data); return false; } void CreateECIESGOSTR3410RandomKeys(uint8_t *priv, uint8_t *pub) { auto &curve = GetGOSTR3410Curve(eGOSTR3410CryptoProA); EC_POINT *p = nullptr; BIGNUM *key = nullptr; GenerateECIESKeyPair(curve->GetGroup(), key, p); bn2buf(key, priv, 32); RAND_bytes(priv + 32, 224); BN_free(key); BIGNUM *x = BN_new(), *y = BN_new(); EC_POINT_get_affine_coordinates_GFp(curve->GetGroup(), p, x, y, NULL); bn2buf(x, pub, 32); bn2buf(y, pub + 32, 32); RAND_bytes(pub + 64, 192); EC_POINT_free(p); BN_free(x); BN_free(y); } ECIESX25519AEADRatchetEncryptor::ECIESX25519AEADRatchetEncryptor(const uint8_t *pub) { memcpy(m_PublicKey, pub, 32); } void ECIESX25519AEADRatchetEncryptor::Encrypt(const uint8_t *, uint8_t *pub) { memcpy(pub, m_PublicKey, 32); } ECIESX25519AEADRatchetDecryptor::ECIESX25519AEADRatchetDecryptor(const uint8_t *priv, bool calculatePublic) { m_StaticKeys.SetPrivateKey(priv, calculatePublic); } bool ECIESX25519AEADRatchetDecryptor::Decrypt(const uint8_t *epub, uint8_t *sharedSecret) { return m_StaticKeys.Agree(epub, sharedSecret); } void CreateECIESX25519AEADRatchetRandomKeys(uint8_t *priv, uint8_t *pub) { X25519Keys k; k.GenerateKeys(); k.GetPrivateKey(priv); memcpy(pub, k.GetPublicKey(), 32); } } }