This class implements the ElGamal public-key cryptosystem for encrypting data up to 222 bytes in size. It incorporates integrity protection by prepending a random byte and SHA-256 hash to data before encryption, which are verified and stripped during decryption.
Note: ECIES or post-quantum schemes are preferred for new applications, but this engine remains in active use by existing code.
The encryption process:
- Generate random nonce byte
- Calculate SHA-256 hash of plaintext
- Prepend nonce + hash + plaintext
- Apply ElGamal encryption
Field Summary
FieldsModifier and TypeFieldDescriptionprivate final I2PAppContextSupplies the random source and precomputation.private final LogLogger for this class.private final YKGeneratorPrecomputed y-k pairs for encryption.private static final intLargest cleartext an ElGamal block can carry, in bytes.private static final intSize of an ElGamal block on the wire, in bytes.private static final intHalf of that block, the size of each of its two halves.private static final BigIntegerThe ElGamal prime minus one, for range checks.Constructor Summary
ConstructorsConstructorDescriptionElGamalEngine(I2PAppContext context) The ElGamal engine should only be constructed and accessed through the application context.Method Summary
Modifier and TypeMethodDescriptionbyte[]decrypt(byte[] encrypted, PrivateKey privateKey) Decrypt the data.byte[]Encrypt the data to the public key.private BigInteger[]Takes the next precomputed y-k pair.voidrestart()This is now a noop.voidshutdown()Note that this stops the precalc thread and it cannot be restarted.
Field Details
_log
Logger for this class._context
Supplies the random source and precomputation._ykgen
Precomputed y-k pairs for encryption.ELGPM1
The ElGamal prime minus one, for range checks.ELG_CLEARTEXT_LENGTH
private static final int ELG_CLEARTEXT_LENGTHLargest cleartext an ElGamal block can carry, in bytes.- See Also:
ELG_ENCRYPTED_LENGTH
private static final int ELG_ENCRYPTED_LENGTHSize of an ElGamal block on the wire, in bytes.- See Also:
ELG_HALF_LENGTH
private static final int ELG_HALF_LENGTHHalf of that block, the size of each of its two halves.- See Also:
Constructor Details
ElGamalEngine
The ElGamal engine should only be constructed and accessed through the application context. This constructor should only be used by the appropriate application context itself.Starts the YK precalc thread if context is RouterContext or Android.
- Parameters:
context- application context supplying the log manager and the YK generator; a RouterContext or Android context also starts the YK precalc thread
Method Details
shutdown
public void shutdown()Note that this stops the precalc thread and it cannot be restarted.restart
public void restart()This is now a noop. Cannot be restarted.getNextYK
Takes the next precomputed y-k pair.- Returns:
- the pair, freshly generated if none is ready
encrypt
Encrypt the data to the public key. If the cleartext is smaller than 222 bytes, it is recommended that the caller pad the cleartext to 222 bytes with random data, as the encrypted data may otherwise contain a substantial number of zeros.- Parameters:
data- data to encrypt, must be 222 bytes or lesspublicKey- public key encrypt to- Returns:
- encrypted data, will be exactly 514 bytes long Contains the two-part encrypted data starting at bytes 0 and 257. If the encrypted parts are smaller than 257 bytes, they will be padded with leading zeros. The parts appear to always be 256 bytes or less, in other words, bytes 0 and 257 are always zero.
decrypt
Decrypt the data.The too-small-payload branch below is effectively unreachable. The encrypt side builds the masked value as one random non-zero byte, then a 32-byte SHA-256, then the payload, so a correctly-recovered value always has a non-zero leading byte and
payloadLenis at least 0. Reaching that branch requires(d * y^a) mod pto fall below 2^256 against a 2048-bit prime, a probability of roughly 2^-1888 for any input an attacker can supply. It is kept as a defensive guard, and the pooled buffer is released on that path so the acquire/release accounting stays uniform across every exit from this method.- Parameters:
encrypted- encrypted data, must be exactly 514 bytes Contains the two-part encrypted data starting at bytes 0 and 257. If the encrypted parts are smaller than 257 bytes, they must be padded with leading zeros.privateKey- private key to decrypt with- Returns:
- unencrypted data or null on failure