📄 elgamal.cpp
字号:
/************************************************** ElGamal Source File ** (C) 1999-2002 The Botan Project **************************************************/#include <botan/elgamal.h>#include <botan/numthry.h>#include <botan/primes.h>namespace Botan {/************************************************** ElGamal_PublicKey Constructor **************************************************/ElGamal_PublicKey::ElGamal_PublicKey(const DL_Group& domain, const BigInt& key) : group(domain), p(group.get_p()), g(group.get_g()), y(key), powermod_g_p(g, p), powermod_y_p(y, p) { if(group.type() != DL_Group::DH_Group) throw Invalid_Argument("ElGamal: Domain is not a DH-style group"); if(y < 0 || y >= p) throw Invalid_Argument("ElGamal_PublicKey: Invalid public parameter"); }/************************************************** ElGamal_PublicKey Copy Constructor **************************************************/ElGamal_PublicKey::ElGamal_PublicKey(const ElGamal_PublicKey& key) : PK_Encrypting_Key(), group(key.group), p(group.get_p()), g(group.get_g()), y(key.get_y()), powermod_g_p(g, p), powermod_y_p(y, p) { }/************************************************** Check Public ElGamal Parameters **************************************************/bool ElGamal_PublicKey::check_params() const { if(y < 2 || y >= p) return false; if(!group.verify()) return false; return true; }/************************************************** ElGamal Encryption Function **************************************************/SecureVector<byte> ElGamal_PublicKey::encrypt(const byte in[], u32bit length) const { BigInt m(in, length); if(m >= p) throw Invalid_Argument("ElGamal::encrypt: The message is too large"); BigInt k(Random, 2 * dl_work_factor(p.bits())); BigInt a = powermod_g_p(k); BigInt b = (m * powermod_y_p(k)) % p; SecureVector<byte> output(2*p.bytes()); a.binary_encode(output + (p.bytes() - a.bytes())); b.binary_encode(output + output.size() / 2 + (p.bytes() - b.bytes())); return output; }/************************************************** ElGamal_PrivateKey Constructor **************************************************/ElGamal_PrivateKey::ElGamal_PrivateKey(const DL_Group& domain) : ElGamal_PublicKey(domain, 0) { x = random_integer(2 * dl_work_factor(p.bits())); y = powermod_g_p(x); powermod_y_p = FixedBase_Exp(y, p); }/************************************************** ElGamal_PrivateKey Constructor **************************************************/ElGamal_PrivateKey::ElGamal_PrivateKey(const DL_Group& domain, const BigInt& priv, const BigInt& pub) : ElGamal_PublicKey(domain, pub), x(priv) { if(x <= 1 || x >= p) throw Invalid_Argument("ElGamal_PrivateKey: Invalid private parameter"); }/************************************************** Check Private ElGamal Parameters **************************************************/bool ElGamal_PrivateKey::check_params() const { if(!ElGamal_PublicKey::check_params()) return false; if(y != powermod_g_p(x)) return false; return true; }/************************************************** ElGamal Decryption Function **************************************************/SecureVector<byte> ElGamal_PrivateKey::decrypt(const byte in[], u32bit length) const { if(length != 2*p.bytes()) throw Invalid_Argument("ElGamal::decrypt: Invalid message"); BigInt a(in, p.bytes()); BigInt b(in + p.bytes(), p.bytes()); if(a >= p || b >= p) throw Invalid_Argument("ElGamal::decrypt: Invalid message"); return encode((b * inverse_mod(power_mod(a, x, p), p)) % p); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -