Skip to content

Added ECC implementation and unit tests #5621

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions src/main/java/com/thealgorithms/ciphers/ECC.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.thealgorithms.ciphers;

import java.math.BigInteger;
import java.security.SecureRandom;

/**
* Elliptic Curve Cryptography (ECC) implementation
* @author P.Sai Srujan Reddy on 7-Oct-24.
*/
public class ECC {
/**
* Elliptic Curve Cryptography (ECC) implementation
* More details: https://en.wikipedia.org/wiki/Elliptic-curve_cryptography
*/
private BigInteger privateKey;
private BigInteger publicKey;
private BigInteger prime;
private BigInteger a; // Curve parameter
private BigInteger b; // Curve parameter
private BigInteger Gx; // Generator point (x-coordinate)
private BigInteger Gy; // Generator point (y-coordinate)
private SecureRandom random;

public ECC(int bits) {
generateKeys(bits);
}

/**
* Encrypts the given message using ECC.
* @param message Message to encrypt
* @return Encrypted message as a BigInteger
*/
public synchronized BigInteger encrypt(BigInteger message) {
// ECC encryption logic using the public key
BigInteger k = new BigInteger(prime.bitLength(), random); // Random value
BigInteger C1x = Gx.multiply(k).mod(prime); // First part of the ciphertext (x-coordinate of point)
BigInteger C1y = Gy.multiply(k).mod(prime); // First part of the ciphertext (y-coordinate of point)
BigInteger C2 = message.multiply(publicKey.modPow(k, prime)).mod(prime); // Second part of ciphertext
return C2; // Return C2 as encrypted message (for simplicity)
}

/**
* Decrypts the given encrypted message.
* @param encryptedMessage Encrypted message as BigInteger
* @return Decrypted message as a BigInteger
*/
public synchronized BigInteger decrypt(BigInteger encryptedMessage) {
// ECC decryption logic using the private key
BigInteger decryptedMessage = encryptedMessage.multiply(privateKey.modInverse(prime)).mod(prime);
return decryptedMessage;
}

/**
* Generates the public and private keys.
*/
private void generateKeys(int bits) {
random = new SecureRandom();
prime = new BigInteger(bits, 100, random); // Prime number for ECC curve
a = new BigInteger(bits, random); // Curve parameter a
b = new BigInteger(bits, random); // Curve parameter b
Gx = new BigInteger(bits, random); // Generator point x
Gy = new BigInteger(bits, random); // Generator point y

privateKey = new BigInteger(bits, random); // Private key
publicKey = Gx.multiply(privateKey).mod(prime); // Public key using generator point Gx
}
}
24 changes: 24 additions & 0 deletions src/test/java/com/thealgorithms/ciphers/ECCTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.thealgorithms.ciphers;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.math.BigInteger;
import org.junit.jupiter.api.Test;

class ECCTest {

ECC ecc = new ECC(256); // ECC with 256-bit key

@Test
void testECC() {
// given
BigInteger message = new BigInteger("123456789"); // Message to encrypt

// when
BigInteger cipherText = ecc.encrypt(message);
BigInteger decryptedMessage = ecc.decrypt(cipherText);

// then
assertEquals(message, decryptedMessage);
}
}
Loading