TheAlgorithms/Java · error · IllegalArgumentException
Message must be non-negative.
Error message
Message must be non-negative.
What it means
Thrown by ElGamalCipher.encrypt when the message BigInteger is negative (compareTo(ZERO) < 0). ElGamal encrypts a message in the range [0, p-1]; a negative message has no valid representation under the modulus, so it is rejected after the null check and before the upper-bound check.
Source
Thrown at src/main/java/com/thealgorithms/ciphers/ElGamalCipher.java:113
return new KeyPair(p, g, y, x);
}
/**
* Encrypts a message using the public key.
*
* @param message The message converted to BigInteger.
* @param p The prime modulus.
* @param g The generator.
* @param y The public key component.
* @return The CipherText pair (a, b).
* @throws IllegalArgumentException if inputs are null, negative, or message >= p.
*/
public static CipherText encrypt(BigInteger message, BigInteger p, BigInteger g, BigInteger y) {
if (message == null || p == null || g == null || y == null) {
throw new IllegalArgumentException("Inputs cannot be null.");
}
if (message.compareTo(BigInteger.ZERO) < 0) {
throw new IllegalArgumentException("Message must be non-negative.");
}
if (message.compareTo(p) >= 0) {
throw new IllegalArgumentException("Message must be smaller than the prime modulus p.");
}
BigInteger k;
BigInteger pMinus1 = p.subtract(BigInteger.ONE);
// Select ephemeral key k such that 1 < k < p-1 and gcd(k, p-1) = 1
do {
k = new BigInteger(p.bitLength(), RANDOM);
} while (k.compareTo(BigInteger.ONE) <= 0 || k.compareTo(pMinus1) >= 0 || !k.gcd(pMinus1).equals(BigInteger.ONE));
BigInteger a = g.modPow(k, p);
BigInteger b = y.modPow(k, p).multiply(message).mod(p);
return new CipherText(a, b);
}View on GitHub (pinned to fdfb9a395b)
Solutions
- Ensure the message BigInteger is non-negative before encrypting.
- Construct BigIntegers from byte arrays using the 1-arg BigInteger(byte[]) constructor only after confirming the sign, or use BigInteger(1, bytes) to force positive.
- Reduce or reject negative values upstream.
Example fix
// before BigInteger msg = new BigInteger(messageBytes); CipherText ct = ElGamalCipher.encrypt(msg, p, g, y); // after BigInteger msg = new BigInteger(1, messageBytes); // force non-negative if (msg.compareTo(p) >= 0) msg = msg.mod(p); CipherText ct = ElGamalCipher.encrypt(msg, p, g, y);
Defensive patterns
Strategy: validation
Validate before calling
if (message == null || message.signum() < 0) {
throw new IllegalArgumentException("message must be non-negative");
}
CipherText ct = ElGamalCipher.encrypt(message, p, g, y); Type guard
static boolean isNonNegative(BigInteger m) { return m != null && m.signum() >= 0; } Try / catch
try {
CipherText ct = ElGamalCipher.encrypt(message, p, g, y);
} catch (IllegalArgumentException e) {
// message negative; rebuild as positive using BigInteger(1, bytes)
} Prevention
- Build messages with new BigInteger(1, bytes) to force non-negative.
- Avoid BigInteger.valueOf on signed longs with the high bit set.
- Validate sign before encrypting.
When it happens
Trigger: Passing a message whose BigInteger value is negative. Common when converting a signed numeric or a hash interpreted as signed.
Common situations: Message derived from arithmetic that can go negative; interpreting a byte array's leading bit as a sign; converting a long with the high bit set via BigInteger.valueOf.
Related errors
- Message must be smaller than the prime modulus p.
- Base, secret, and prime must be non-null and positive values
- Other public value must be non-null and positive.
- Bit length must be at least {} for security.
- Inputs cannot be null.
AI-assisted analysis of TheAlgorithms/Java@fdfb9a395b (2026-08-13).
Data as JSON: /api/errors/9582ab5443c71b7c.
Report an issue: GitHub.