i2pd/ElGamal.h

90 lines
2.2 KiB
C
Raw Normal View History

2013-09-01 17:45:06 +00:00
#ifndef EL_GAMAL_H__
#define EL_GAMAL_H__
#include <inttypes.h>
#include <cryptopp/integer.h>
#include <cryptopp/osrng.h>
2015-01-06 00:32:46 +00:00
#include <cryptopp/dh.h>
2013-09-01 17:45:06 +00:00
#include <cryptopp/sha.h>
#include "CryptoConst.h"
#include "Log.h"
namespace i2p
{
namespace crypto
{
2014-02-20 17:25:28 +00:00
class ElGamalEncryption
2013-09-01 17:45:06 +00:00
{
2014-02-20 17:25:28 +00:00
public:
2013-09-01 17:45:06 +00:00
2015-03-10 19:38:37 +00:00
ElGamalEncryption (const uint8_t * key)
2014-02-20 17:25:28 +00:00
{
2015-03-10 19:38:37 +00:00
CryptoPP::AutoSeededRandomPool rnd;
CryptoPP::Integer y (key, 256), k (rnd, CryptoPP::Integer::One(), elgp-1);
a = a_exp_b_mod_c (elgg, k, elgp);
b1 = a_exp_b_mod_c (y, k, elgp);
2014-02-20 17:25:28 +00:00
}
2015-04-07 18:40:36 +00:00
void Encrypt (const uint8_t * data, int len, uint8_t * encrypted, bool zeroPadding = false) const
2014-02-20 17:25:28 +00:00
{
// calculate b = b1*m mod p
uint8_t m[255];
m[0] = 0xFF;
memcpy (m+33, data, len);
CryptoPP::SHA256().CalculateDigest(m+1, m+33, 222);
CryptoPP::Integer b (a_times_b_mod_c (b1, CryptoPP::Integer (m, 255), elgp));
// copy a and b
if (zeroPadding)
2014-02-20 17:25:28 +00:00
{
encrypted[0] = 0;
a.Encode (encrypted + 1, 256);
encrypted[257] = 0;
b.Encode (encrypted + 258, 256);
}
else
{
a.Encode (encrypted, 256);
b.Encode (encrypted + 256, 256);
}
}
private:
2015-03-10 19:38:37 +00:00
CryptoPP::Integer a, b1;
2014-02-20 17:25:28 +00:00
};
2013-09-01 17:45:06 +00:00
2013-11-23 21:35:15 +00:00
inline bool ElGamalDecrypt (const uint8_t * key, const uint8_t * encrypted,
uint8_t * data, bool zeroPadding = false)
2013-09-01 17:45:06 +00:00
{
2013-11-23 21:35:15 +00:00
CryptoPP::Integer x(key, 256), a(zeroPadding? encrypted +1 : encrypted, 256),
b(zeroPadding? encrypted + 258 :encrypted + 256, 256);
2013-09-01 17:45:06 +00:00
uint8_t m[255], hash[32];
a_times_b_mod_c (b, a_exp_b_mod_c (a, elgp - x - 1, elgp), elgp).Encode (m, 255);
CryptoPP::SHA256().CalculateDigest(hash, m+33, 222);
for (int i = 0; i < 32; i++)
if (hash[i] != m[i+1])
{
LogPrint ("ElGamal decrypt hash doesn't match");
return false;
}
memcpy (data, m + 33, 222);
return true;
}
2015-01-06 00:32:46 +00:00
inline void GenerateElGamalKeyPair (CryptoPP::RandomNumberGenerator& rnd, uint8_t * priv, uint8_t * pub)
{
#if defined(__x86_64__) || defined(__i386__) || defined(_MSC_VER)
rnd.GenerateBlock (priv, 256);
a_exp_b_mod_c (elgg, CryptoPP::Integer (priv, 256), elgp).Encode (pub, 256);
#else
CryptoPP::DH dh (elgp, elgg);
dh.GenerateKeyPair(rnd, priv, pub);
#endif
}
2013-09-01 17:45:06 +00:00
}
}
#endif