Skip to content

Commit d37fd91

Browse files
authored
Merge branch 'master' into count_leading_0s_new_algo
2 parents 4bbf9a3 + 2a167f4 commit d37fd91

File tree

61 files changed

+3665
-481
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+3665
-481
lines changed

.github/workflows/build.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
uses: actions/setup-java@v4
1111
with:
1212
java-version: 21
13-
distribution: 'adopt'
13+
distribution: 'temurin'
1414
- name: Build with Maven
1515
run: mvn --batch-mode --update-snapshots verify
1616
- name: Upload coverage to codecov (tokenless)

.github/workflows/codeql.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
uses: actions/setup-java@v4
3131
with:
3232
java-version: 21
33-
distribution: 'adopt'
33+
distribution: 'temurin'
3434

3535
- name: Initialize CodeQL
3636
uses: github/codeql-action/init@v3

.github/workflows/infer.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
uses: actions/setup-java@v4
1919
with:
2020
java-version: 21
21-
distribution: 'adopt'
21+
distribution: 'temurin'
2222

2323
- name: Set up OCaml
2424
uses: ocaml/setup-ocaml@v3

DIRECTORY.md

+34
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package com.thealgorithms.ciphers;
2+
3+
/**
4+
* The Atbash cipher is a simple substitution cipher that replaces each letter
5+
* in the alphabet with its reverse.
6+
* For example, 'A' becomes 'Z', 'B' becomes 'Y', and so on. It works
7+
* identically for both uppercase and lowercase letters.
8+
* It's a symmetric cipher, meaning applying it twice returns the original text.
9+
* Hence, the encrypting and the decrypting functions are identical
10+
* @author https://github.com/Krounosity
11+
* Learn more: https://en.wikipedia.org/wiki/Atbash
12+
*/
13+
14+
public class AtbashCipher {
15+
16+
private String toConvert;
17+
18+
// Default constructor.
19+
AtbashCipher() {
20+
}
21+
22+
// String setting constructor.
23+
AtbashCipher(String str) {
24+
toConvert = str;
25+
}
26+
27+
// String getter method.
28+
public String getString() {
29+
return toConvert;
30+
}
31+
32+
// String setter method.
33+
public void setString(String str) {
34+
toConvert = str;
35+
}
36+
37+
// Checking whether the current character is capital.
38+
private boolean isCapital(char ch) {
39+
return ch >= 'A' && ch <= 'Z';
40+
}
41+
42+
// Checking whether the current character is smallcased.
43+
private boolean isSmall(char ch) {
44+
return ch >= 'a' && ch <= 'z';
45+
}
46+
47+
// Converting text to atbash cipher code or vice versa.
48+
public String convert() {
49+
50+
// Using StringBuilder to store new string.
51+
StringBuilder convertedString = new StringBuilder();
52+
53+
// Iterating for each character.
54+
for (char ch : toConvert.toCharArray()) {
55+
56+
// If the character is smallcased.
57+
if (isSmall(ch)) {
58+
convertedString.append((char) ('z' - (ch - 'a')));
59+
}
60+
// If the character is capital cased.
61+
else if (isCapital(ch)) {
62+
convertedString.append((char) ('Z' - (ch - 'A')));
63+
}
64+
// Non-alphabetical character.
65+
else {
66+
convertedString.append(ch);
67+
}
68+
}
69+
return convertedString.toString();
70+
}
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,236 @@
1+
package com.thealgorithms.ciphers;
2+
3+
import java.math.BigInteger;
4+
import java.security.SecureRandom;
5+
6+
/**
7+
* ECC - Elliptic Curve Cryptography
8+
* Elliptic Curve Cryptography is a public-key cryptography method that uses the algebraic structure of
9+
* elliptic curves over finite fields. ECC provides a higher level of security with smaller key sizes compared
10+
* to other public-key methods like RSA, making it particularly suitable for environments where computational
11+
* resources are limited, such as mobile devices and embedded systems.
12+
*
13+
* This class implements elliptic curve cryptography, providing encryption and decryption
14+
* functionalities based on public and private key pairs.
15+
*
16+
* @author xuyang
17+
*/
18+
public class ECC {
19+
20+
private BigInteger privateKey; // Private key used for decryption
21+
private ECPoint publicKey; // Public key used for encryption
22+
private EllipticCurve curve; // Elliptic curve used in cryptography
23+
private ECPoint basePoint; // Base point G on the elliptic curve
24+
25+
public ECC(int bits) {
26+
generateKeys(bits); // Generates public-private key pair
27+
}
28+
29+
public EllipticCurve getCurve() {
30+
return curve; // Returns the elliptic curve
31+
}
32+
33+
public void setCurve(EllipticCurve curve) {
34+
this.curve = curve;
35+
}
36+
37+
// Getter and Setter for private key
38+
public BigInteger getPrivateKey() {
39+
return privateKey;
40+
}
41+
42+
public void setPrivateKey(BigInteger privateKey) {
43+
this.privateKey = privateKey;
44+
}
45+
46+
/**
47+
* Encrypts the message using the public key.
48+
* The message is transformed into an ECPoint and encrypted with elliptic curve operations.
49+
*
50+
* @param message The plain message to be encrypted
51+
* @return The encrypted message as an array of ECPoints (R, S)
52+
*/
53+
public ECPoint[] encrypt(String message) {
54+
BigInteger m = new BigInteger(message.getBytes()); // Convert message to BigInteger
55+
SecureRandom r = new SecureRandom(); // Generate random value for k
56+
BigInteger k = new BigInteger(curve.getFieldSize(), r); // Generate random scalar k
57+
58+
// Calculate point r = k * G, where G is the base point
59+
ECPoint rPoint = basePoint.multiply(k, curve.getP(), curve.getA());
60+
61+
// Calculate point s = k * publicKey + encodedMessage
62+
ECPoint sPoint = publicKey.multiply(k, curve.getP(), curve.getA()).add(curve.encodeMessage(m), curve.getP(), curve.getA());
63+
64+
return new ECPoint[] {rPoint, sPoint}; // Return encrypted message as two ECPoints
65+
}
66+
67+
/**
68+
* Decrypts the encrypted message using the private key.
69+
* The decryption process is the reverse of encryption, recovering the original message.
70+
*
71+
* @param encryptedMessage The encrypted message as an array of ECPoints (R, S)
72+
* @return The decrypted plain message as a String
73+
*/
74+
public String decrypt(ECPoint[] encryptedMessage) {
75+
ECPoint rPoint = encryptedMessage[0]; // First part of ciphertext
76+
ECPoint sPoint = encryptedMessage[1]; // Second part of ciphertext
77+
78+
// Perform decryption: s - r * privateKey
79+
ECPoint decodedMessage = sPoint.subtract(rPoint.multiply(privateKey, curve.getP(), curve.getA()), curve.getP(), curve.getA());
80+
81+
BigInteger m = curve.decodeMessage(decodedMessage); // Decode the message from ECPoint
82+
83+
return new String(m.toByteArray()); // Convert BigInteger back to String
84+
}
85+
86+
/**
87+
* Generates a new public-private key pair for encryption and decryption.
88+
*
89+
* @param bits The size (in bits) of the keys to generate
90+
*/
91+
public final void generateKeys(int bits) {
92+
SecureRandom r = new SecureRandom();
93+
curve = new EllipticCurve(bits); // Initialize a new elliptic curve
94+
basePoint = curve.getBasePoint(); // Set the base point G
95+
96+
// Generate private key as a random BigInteger
97+
privateKey = new BigInteger(bits, r);
98+
99+
// Generate public key as the point publicKey = privateKey * G
100+
publicKey = basePoint.multiply(privateKey, curve.getP(), curve.getA());
101+
}
102+
103+
/**
104+
* Class representing an elliptic curve with the form y^2 = x^3 + ax + b.
105+
*/
106+
public static class EllipticCurve {
107+
private final BigInteger a; // Coefficient a in the curve equation
108+
private final BigInteger b; // Coefficient b in the curve equation
109+
private final BigInteger p; // Prime number p, defining the finite field
110+
private final ECPoint basePoint; // Base point G on the curve
111+
112+
// Constructor with explicit parameters for a, b, p, and base point
113+
public EllipticCurve(BigInteger a, BigInteger b, BigInteger p, ECPoint basePoint) {
114+
this.a = a;
115+
this.b = b;
116+
this.p = p;
117+
this.basePoint = basePoint;
118+
}
119+
120+
// Constructor that randomly generates the curve parameters
121+
public EllipticCurve(int bits) {
122+
SecureRandom r = new SecureRandom();
123+
this.p = BigInteger.probablePrime(bits, r); // Random prime p
124+
this.a = new BigInteger(bits, r); // Random coefficient a
125+
this.b = new BigInteger(bits, r); // Random coefficient b
126+
this.basePoint = new ECPoint(BigInteger.valueOf(4), BigInteger.valueOf(8)); // Fixed base point G
127+
}
128+
129+
public ECPoint getBasePoint() {
130+
return basePoint;
131+
}
132+
133+
public BigInteger getP() {
134+
return p;
135+
}
136+
137+
public BigInteger getA() {
138+
return a;
139+
}
140+
141+
public BigInteger getB() {
142+
return b;
143+
}
144+
145+
public int getFieldSize() {
146+
return p.bitLength();
147+
}
148+
149+
public ECPoint encodeMessage(BigInteger message) {
150+
// Simple encoding of a message as an ECPoint (this is a simplified example)
151+
return new ECPoint(message, message);
152+
}
153+
154+
public BigInteger decodeMessage(ECPoint point) {
155+
return point.getX(); // Decode the message from ECPoint (simplified)
156+
}
157+
}
158+
159+
/**
160+
* Class representing a point on the elliptic curve.
161+
*/
162+
public static class ECPoint {
163+
private final BigInteger x; // X-coordinate of the point
164+
private final BigInteger y; // Y-coordinate of the point
165+
166+
public ECPoint(BigInteger x, BigInteger y) {
167+
this.x = x;
168+
this.y = y;
169+
}
170+
171+
public BigInteger getX() {
172+
return x;
173+
}
174+
175+
public BigInteger getY() {
176+
return y;
177+
}
178+
179+
@Override
180+
public String toString() {
181+
return "ECPoint(x=" + x.toString() + ", y=" + y.toString() + ")";
182+
}
183+
184+
/**
185+
* Add two points on the elliptic curve.
186+
*/
187+
public ECPoint add(ECPoint other, BigInteger p, BigInteger a) {
188+
if (this.x.equals(BigInteger.ZERO) && this.y.equals(BigInteger.ZERO)) {
189+
return other; // If this point is the identity, return the other point
190+
}
191+
if (other.x.equals(BigInteger.ZERO) && other.y.equals(BigInteger.ZERO)) {
192+
return this; // If the other point is the identity, return this point
193+
}
194+
195+
BigInteger lambda;
196+
if (this.equals(other)) {
197+
// Special case: point doubling
198+
lambda = this.x.pow(2).multiply(BigInteger.valueOf(3)).add(a).multiply(this.y.multiply(BigInteger.valueOf(2)).modInverse(p)).mod(p);
199+
} else {
200+
// General case: adding two different points
201+
lambda = other.y.subtract(this.y).multiply(other.x.subtract(this.x).modInverse(p)).mod(p);
202+
}
203+
204+
BigInteger xr = lambda.pow(2).subtract(this.x).subtract(other.x).mod(p);
205+
BigInteger yr = lambda.multiply(this.x.subtract(xr)).subtract(this.y).mod(p);
206+
207+
return new ECPoint(xr, yr);
208+
}
209+
210+
/**
211+
* Subtract two points on the elliptic curve.
212+
*/
213+
public ECPoint subtract(ECPoint other, BigInteger p, BigInteger a) {
214+
ECPoint negOther = new ECPoint(other.x, p.subtract(other.y)); // Negate the Y coordinate
215+
return this.add(negOther, p, a); // Add the negated point
216+
}
217+
218+
/**
219+
* Multiply a point by a scalar (repeated addition).
220+
*/
221+
public ECPoint multiply(BigInteger k, BigInteger p, BigInteger a) {
222+
ECPoint result = new ECPoint(BigInteger.ZERO, BigInteger.ZERO); // Identity point
223+
ECPoint addend = this;
224+
225+
while (k.signum() > 0) {
226+
if (k.testBit(0)) {
227+
result = result.add(addend, p, a); // Add the current point
228+
}
229+
addend = addend.add(addend, p, a); // Double the point
230+
k = k.shiftRight(1); // Divide k by 2
231+
}
232+
233+
return result;
234+
}
235+
}
236+
}

0 commit comments

Comments
 (0)