Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Add Baby-Step Giant-Step (BSGS) Discrete Logarithm Algorithm #7118

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

Open
rajucreate wants to merge 12 commits into TheAlgorithms:master
base: master
Choose a base branch
Loading
from rajucreate:master
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
12 commits
Select commit Hold shift + click to select a range
91845a5
Add BSGS algorithm to DIRECTORY.md
rajucreate Nov 25, 2025
1539125
Add Wikipedia reference to BSGS algorithm Javadoc
rajucreate Nov 25, 2025
6c83fc8
Fix incorrect BSGS test cases
rajucreate Nov 25, 2025
7d4de81
Fix spacing after private constructor for Checkstyle
rajucreate Nov 25, 2025
c448ffb
Mark utility class as final to satisfy Checkstyle
rajucreate Nov 25, 2025
f094f3e
Fix PMD useless parentheses violations
rajucreate Nov 25, 2025
4a27eca
Fix formatting for clang-format
rajucreate Nov 25, 2025
cf027be
Add newline at end of file to satisfy Checkstyle
rajucreate Nov 25, 2025
fd8d4ba
test: improve coverage for DiscreteLogarithmBSGS
rajucreate Nov 26, 2025
864c3d3
test: improve coverage for DiscreteLogarithmBSGS
rajucreate Nov 26, 2025
c92e485
Merge branch 'master' into master
rajucreate Nov 26, 2025
29e7dbe
Merge branch 'master' into master
rajucreate Nov 26, 2025
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
1 change: 1 addition & 0 deletions DIRECTORY.md
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,7 @@
- 📄 [ConvolutionFFT](src/main/java/com/thealgorithms/maths/ConvolutionFFT.java)
- 📄 [CrossCorrelation](src/main/java/com/thealgorithms/maths/CrossCorrelation.java)
- 📄 [DeterminantOfMatrix](src/main/java/com/thealgorithms/maths/DeterminantOfMatrix.java)
- [DiscreteLogarithmBSGS](src/main/java/com/thealgorithms/maths/DiscreteLogarithmBSGS.java)
- 📄 [DigitalRoot](src/main/java/com/thealgorithms/maths/DigitalRoot.java)
- 📄 [DistanceFormula](src/main/java/com/thealgorithms/maths/DistanceFormula.java)
- 📄 [DudeneyNumber](src/main/java/com/thealgorithms/maths/DudeneyNumber.java)
Expand Down
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.thealgorithms.maths;

import java.util.HashMap;
import java.util.Map;

/**
* Baby-Step Giant-Step algorithm for the Discrete Logarithm Problem.
*
* <p>
* Solves for x in: a^x ≡ b (mod m),
* where a, b, m are given, and m is prime (or a has order in modulo m).
*
* <p>
* Time complexity: O(√m)
* Space complexity: O(√m)
*
* @see <a href="https://en.wikipedia.org/wiki/Baby-step_giant-step">Baby-step giant-step algorithm</a>
*/
public final class DiscreteLogarithmBSGS {

private DiscreteLogarithmBSGS() {
throw new UnsupportedOperationException("Utility class");
}

/**
* Computes x such that (a^x) % m == b.
* Returns -1 if no solution exists.
*/
public static long discreteLog(long a, long b, long m) {
a %= m;
b %= m;

if (b == 1) {
return 0;
}

long n = (long) Math.ceil(Math.sqrt(m));

Map<Long, Long> babySteps = new HashMap<>();

long value = 1;
for (long i = 0; i < n; i++) {
babySteps.put(value, i);
value = value * a % m; // PMD fix
}

long factor = modPow(a, m - n - 1, m);

long gamma = b;
for (long j = 0; j <= n; j++) {
if (babySteps.containsKey(gamma)) {
return j * n + babySteps.get(gamma);
}
gamma = gamma * factor % m; // PMD fix
}

return -1; // no solution
}

/** Fast modular exponentiation */
public static long modPow(long base, long exp, long mod) {
long result = 1;
base %= mod;

while (exp > 0) {
if ((exp & 1) == 1) {
result = result * base % mod; // PMD fix
}
base = base * base % mod; // PMD fix
exp >>= 1;
}
return result;
}
}
View file Open in desktop
Copy link
Member

@DenizAltunkapan DenizAltunkapan Dec 3, 2025
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add a test case with m being not prime. E.g. a=2 b=8 m=9 => x=3 ? @rajucreate

Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.thealgorithms.maths;

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

import org.junit.jupiter.api.Test;

public class DiscreteLogarithmBSGSTest {

@Test
public void testSmallValues() {
assertEquals(3, DiscreteLogarithmBSGS.discreteLog(2, 8, 13));
assertEquals(4, DiscreteLogarithmBSGS.discreteLog(3, 81, 1000000007));
}

@Test
public void testNoSolution() {
// choose a true NO-SOLUTION example:
// modulo 15, base 4 generates only {1,4}
assertEquals(-1, DiscreteLogarithmBSGS.discreteLog(4, 2, 15));
}

@Test
public void testLargeMod() {
// use a valid solvable case
long x = DiscreteLogarithmBSGS.discreteLog(5, 5, 1000003);
assertEquals(1, x);
}

@Test
public void testImmediateReturnCase() {
// because a^0 ≡ 1 (mod m)
assertEquals(0, DiscreteLogarithmBSGS.discreteLog(7, 1, 13));
}

@Test
public void testModPowBranchCoverage() {
assertEquals(1, DiscreteLogarithmBSGS.modPow(10, 0, 17)); // exp=0 branch
assertEquals(10 % 17, DiscreteLogarithmBSGS.modPow(10, 1, 17)); // odd exp branch
assertEquals(100 % 17, DiscreteLogarithmBSGS.modPow(10, 2, 17)); // even exp branch
}
}

AltStyle によって変換されたページ (->オリジナル) /