55import static java .lang .Math .sqrt ;
66
77/**
8- * https://en.wikipedia.org/wiki/Discrete_logarithm
9- * a^x = b mod p
10- * x = ?
8+ * In mathematics, a discrete logarithm is an integer k exponent solving the equation bk = g, where b and g are
9+ * elements of a group. Discrete logarithms are thus the group-theoretic analogue of ordinary logarithms, which
10+ * solve the same equation for real numbers b and g, where b is the base of the logarithm and g is the value whose
11+ * logarithm is being taken.
12+ * <p>
13+ * @see <a href="https://en.wikipedia.org/wiki/Discrete_logarithm">Discrete Logarithm (Wikipedia)</a>
1114 * <br>
12- * Created on 03.07.2017.
13- *
14- * @author lucjanroslanowski
15+ * @author Lucjan Rosłanowski <[email protected] > 16+ * @author Justin Wetherell <[email protected] > 1517 */
1618public class DiscreteLogarithm {
17- private static long NO_SOLUTION = -1 ;
18- private HashMap <Long , Long > set = new HashMap <>();
19+
20+ public static final long NO_SOLUTION = -1 ;
21+
22+ private final HashMap <Long , Long > set = new HashMap <Long , Long >();
1923
2024 private long pow (long a , long x , long p ) {
21- if (x == 0 ) {
25+ if (x == 0 )
2226 return 1 ;
23- }
2427
25- if (x == 1 ) {
28+ if (x == 1 )
2629 return a % p ;
27- }
2830
29- if (x % 2 != 0 ) {
31+ if (x % 2 != 0 )
3032 return (a * pow (a , x - 1 , p )) % p ;
31- } else {
32- long temp = pow (a , x / 2 , p ) % p ;
33- return (temp * temp ) % p ;
34- }
35- }
3633
34+ final long temp = pow (a , x / 2 , p ) % p ;
35+ return (temp * temp ) % p ;
36+ }
3737
3838 private long getDiscreteLogarithm (long s , long a , long p ) {
3939 for (long i = 0 ; i < s ; ++i ) {
4040 long el = pow (a , (i * s ) % p , p );
4141 el = pow (el , p - 2 , p );
4242
43- if (set .containsKey (el )) {
43+ if (set .containsKey (el ))
4444 return i * s + set .get (el );
45- }
4645 }
4746 return NO_SOLUTION ;
4847 }
4948
5049 private void generateSet (long a , long b_1 , long p , long s ) {
5150 for (long i = 0 ; i < s ; ++i ) {
52- long first = (pow (a , i , p ) * b_1 ) % p ;
53- if (!set .containsKey (first )) {
51+ final long first = (pow (a , i , p ) * b_1 ) % p ;
52+ if (!set .containsKey (first ))
5453 set .put (first , i );
55- }
5654 }
5755 }
5856
57+ /**
58+ * Returns DiscreteLogarithm.NO_SOLUTION when a solution cannot be found
59+ */
5960 public long countDiscreteLogarithm (final long a , final long b , final long p ) {
60- long s = (long ) sqrt (p ) + 1 ;
61- long b_1 = pow (b , p - 2 , p );
61+ final long s = (long ) sqrt (p ) + 1 ;
62+ final long b_1 = pow (b , p - 2 , p );
63+ set .clear ();
64+
6265 generateSet (a , b_1 , p , s );
6366 return getDiscreteLogarithm (s ,a ,p );
6467 }
65- }
68+ }
0 commit comments