/ libi2pd / CryptoKey.cpp
CryptoKey.cpp
  1  /*
  2  * Copyright (c) 2013-2025, The PurpleI2P Project
  3  *
  4  * This file is part of Purple i2pd project and licensed under BSD3
  5  *
  6  * See full license text in LICENSE file at top of project tree
  7  */
  8  
  9  #include <string.h>
 10  #include "Log.h"
 11  #include "Gost.h"
 12  #include "CryptoKey.h"
 13  
 14  namespace i2p
 15  {
 16  namespace crypto
 17  {
 18  	ElGamalEncryptor::ElGamalEncryptor (const uint8_t * pub)
 19  	{
 20  		memcpy (m_PublicKey, pub, 256);
 21  	}
 22  
 23  	void ElGamalEncryptor::Encrypt (const uint8_t * data, uint8_t * encrypted)
 24  	{
 25  		ElGamalEncrypt (m_PublicKey, data, encrypted);
 26  	}
 27  
 28  	ElGamalDecryptor::ElGamalDecryptor (const uint8_t * priv)
 29  	{
 30  		memcpy (m_PrivateKey, priv, 256);
 31  	}
 32  
 33  	bool ElGamalDecryptor::Decrypt (const uint8_t * encrypted, uint8_t * data)
 34  	{
 35  		return ElGamalDecrypt (m_PrivateKey, encrypted, data);
 36  	}
 37  
 38  	ECIESP256Encryptor::ECIESP256Encryptor (const uint8_t * pub)
 39  	{
 40  		m_Curve = EC_GROUP_new_by_curve_name (NID_X9_62_prime256v1);
 41  		m_PublicKey = EC_POINT_new (m_Curve);
 42  		BIGNUM * x = BN_bin2bn (pub, 32, nullptr);
 43  		BIGNUM * y = BN_bin2bn (pub + 32, 32, nullptr);
 44  		if (!EC_POINT_set_affine_coordinates (m_Curve, m_PublicKey, x, y, nullptr))
 45  			LogPrint (eLogError, "ECICS P256 invalid public key");
 46  		BN_free (x); BN_free (y);
 47  	}
 48  
 49  	ECIESP256Encryptor::~ECIESP256Encryptor ()
 50  	{
 51  		if (m_Curve) EC_GROUP_free (m_Curve);
 52  		if (m_PublicKey) EC_POINT_free (m_PublicKey);
 53  	}
 54  
 55  	void ECIESP256Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted)
 56  	{
 57  		if (m_Curve && m_PublicKey)
 58  			ECIESEncrypt (m_Curve, m_PublicKey, data, encrypted);
 59  	}
 60  
 61  	ECIESP256Decryptor::ECIESP256Decryptor (const uint8_t * priv)
 62  	{
 63  		m_Curve = EC_GROUP_new_by_curve_name (NID_X9_62_prime256v1);
 64  		m_PrivateKey = BN_bin2bn (priv, 32, nullptr);
 65  	}
 66  
 67  	ECIESP256Decryptor::~ECIESP256Decryptor ()
 68  	{
 69  		if (m_Curve) EC_GROUP_free (m_Curve);
 70  		if (m_PrivateKey) BN_free (m_PrivateKey);
 71  	}
 72  
 73  	bool ECIESP256Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data)
 74  	{
 75  		if (m_Curve && m_PrivateKey)
 76  			return ECIESDecrypt (m_Curve, m_PrivateKey, encrypted, data);
 77  		return false;
 78  	}
 79  
 80  	void CreateECIESP256RandomKeys (uint8_t * priv, uint8_t * pub)
 81  	{
 82  		EC_GROUP * curve = EC_GROUP_new_by_curve_name (NID_X9_62_prime256v1);
 83  		EC_POINT * p = nullptr;
 84  		BIGNUM * key = nullptr;
 85  		GenerateECIESKeyPair (curve, key, p);
 86  		bn2buf (key, priv, 32);
 87  		RAND_bytes (priv + 32, 224);
 88  		BN_free (key);
 89  		BIGNUM * x = BN_new (), * y = BN_new ();
 90  		EC_POINT_get_affine_coordinates (curve, p, x, y, NULL);
 91  		bn2buf (x, pub, 32);
 92  		bn2buf (y, pub + 32, 32);
 93  		RAND_bytes (pub + 64, 192);
 94  		EC_POINT_free (p);
 95  		BN_free (x); BN_free (y);
 96  		EC_GROUP_free (curve);
 97  	}
 98  
 99  	ECIESGOSTR3410Encryptor::ECIESGOSTR3410Encryptor (const uint8_t * pub)
100  	{
101  		auto& curve = GetGOSTR3410Curve (eGOSTR3410CryptoProA);
102  		m_PublicKey = EC_POINT_new (curve->GetGroup ());
103  		BIGNUM * x = BN_bin2bn (pub, 32, nullptr);
104  		BIGNUM * y = BN_bin2bn (pub + 32, 32, nullptr);
105  		if (!EC_POINT_set_affine_coordinates (curve->GetGroup (), m_PublicKey, x, y, nullptr))
106  			LogPrint (eLogError, "ECICS GOST R 34.10 invalid public key");
107  		BN_free (x); BN_free (y);
108  	}
109  
110  	ECIESGOSTR3410Encryptor::~ECIESGOSTR3410Encryptor ()
111  	{
112  		if (m_PublicKey) EC_POINT_free (m_PublicKey);
113  	}
114  
115  	void ECIESGOSTR3410Encryptor::Encrypt (const uint8_t * data, uint8_t * encrypted)
116  	{
117  		if (m_PublicKey)
118  			ECIESEncrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PublicKey, data, encrypted);
119  	}
120  
121  	ECIESGOSTR3410Decryptor::ECIESGOSTR3410Decryptor (const uint8_t * priv)
122  	{
123  		m_PrivateKey = BN_bin2bn (priv, 32, nullptr);
124  	}
125  
126  	ECIESGOSTR3410Decryptor::~ECIESGOSTR3410Decryptor ()
127  	{
128  		if (m_PrivateKey) BN_free (m_PrivateKey);
129  	}
130  
131  	bool ECIESGOSTR3410Decryptor::Decrypt (const uint8_t * encrypted, uint8_t * data)
132  	{
133  		if (m_PrivateKey)
134  			return ECIESDecrypt (GetGOSTR3410Curve (eGOSTR3410CryptoProA)->GetGroup (), m_PrivateKey, encrypted, data);
135  		return false;
136  	}
137  
138  
139  	void CreateECIESGOSTR3410RandomKeys (uint8_t * priv, uint8_t * pub)
140  	{
141  		auto& curve = GetGOSTR3410Curve (eGOSTR3410CryptoProA);
142  		EC_POINT * p = nullptr;
143  		BIGNUM * key = nullptr;
144  		GenerateECIESKeyPair (curve->GetGroup (), key, p);
145  		bn2buf (key, priv, 32);
146  		RAND_bytes (priv + 32, 224);
147  		BN_free (key);
148  		BIGNUM * x = BN_new (), * y = BN_new ();
149  		EC_POINT_get_affine_coordinates (curve->GetGroup (), p, x, y, NULL);
150  		bn2buf (x, pub, 32);
151  		bn2buf (y, pub + 32, 32);
152  		RAND_bytes (pub + 64, 192);
153  		EC_POINT_free (p);
154  		BN_free (x); BN_free (y);
155  	}
156  
157  	ECIESX25519AEADRatchetEncryptor::ECIESX25519AEADRatchetEncryptor (const uint8_t * pub)
158  	{
159  		memcpy (m_PublicKey, pub, 32);
160  	}
161  
162  	void ECIESX25519AEADRatchetEncryptor::Encrypt (const uint8_t *, uint8_t * pub)
163  	{
164  		memcpy (pub, m_PublicKey, 32);
165  	}
166  
167  	ECIESX25519AEADRatchetDecryptor::ECIESX25519AEADRatchetDecryptor (const uint8_t * priv, bool calculatePublic)
168  	{
169  		m_StaticKeys.SetPrivateKey (priv, calculatePublic);
170  	}
171  
172  	bool ECIESX25519AEADRatchetDecryptor::Decrypt (const uint8_t * epub, uint8_t * sharedSecret)
173  	{
174  		return m_StaticKeys.Agree (epub, sharedSecret);
175  	}
176  
177  	void CreateECIESX25519AEADRatchetRandomKeys (uint8_t * priv, uint8_t * pub)
178  	{
179  		X25519Keys k;
180  		k.GenerateKeys ();
181  		k.GetPrivateKey (priv);
182  		memcpy (pub, k.GetPublicKey (), 32);
183  	}
184  
185  	LocalEncryptionKey::LocalEncryptionKey (i2p::data::CryptoKeyType t): keyType(t) 
186  	{ 
187  		pub.resize (GetCryptoPublicKeyLen (keyType)); 
188  		priv.resize (GetCryptoPrivateKeyLen (keyType));
189  	}
190  	
191  	void LocalEncryptionKey::GenerateKeys () 
192  	{ 
193  		i2p::data::PrivateKeys::GenerateCryptoKeyPair (keyType, priv.data (), pub.data ()); 
194  	}
195  	
196  	void LocalEncryptionKey::CreateDecryptor () 
197  	{ 
198  		decryptor = i2p::data::PrivateKeys::CreateDecryptor (keyType, priv.data ()); 
199  	}
200  }
201  }