@@ -9,18 +9,20 @@ type BigMap = HashMap<BigUint, u32>;
99fn build_table ( h : & BigUint , g : & BigUint , p : & BigUint , b : u32 ) -> BigMap {
1010 let mut table = HashMap :: with_capacity ( b as usize ) ;
1111
12- let two = vec ! [ 2 ] ;
13- let two = BigUint :: new ( two ) ;
14- let p_minus_2 = p - & two ;
15- let g_inverse = g. modpow ( & p_minus_2 , p) ;
12+ // Instead of doing modular inversion (g^x1)^(p-2) in the loop,
13+ // we can calculate g^(p-2) ahead of time
14+ let two = BigUint :: new ( vec ! [ 2 ] ) ;
15+ let g_inverse = g. modpow ( & ( p - & two ) , p) ;
1616
17- for x1 in 0 ..b {
18- let bytes = x1. to_le_bytes ( ) ;
19- let big_x1 = BigUint :: from_bytes_le ( & bytes) ;
20- let g_x1_inverse = g_inverse. modpow ( & big_x1, p) ;
21- let left = h * & g_x1_inverse % p;
22-
23- table. insert ( left, x1) ;
17+ // start with exponentiation base h instead of multiplying h,
18+ // h * g^(-x1), on every iteration
19+ let mut left = h. clone ( ) ;
20+ table. insert ( left. clone ( ) , 0 ) ;
21+ for x1 in 1 ..b {
22+ // reuse exponentiation: simply multiply
23+ // by g^(-1) to increase exponent by 1
24+ left = & left * & g_inverse % p;
25+ table. insert ( left. clone ( ) , x1) ;
2426 }
2527
2628 table
@@ -29,15 +31,16 @@ fn build_table(h: &BigUint, g: &BigUint, p: &BigUint, b: u32) -> BigMap {
2931fn lookup_x0_x1 ( table : & BigMap , g : & BigUint , p : & BigUint , b : u32 ) -> Option < ( u32 , u32 ) > {
3032 let big_b = BigUint :: from_bytes_le ( & b. to_le_bytes ( ) ) ;
3133 let g_b = g. modpow ( & big_b, p) ;
34+ let mut right = BigUint :: new ( vec ! [ 1 ] ) ;
3235
3336 for x0 in 0 ..b {
34- let bytes = x0. to_le_bytes ( ) ;
35- let big_x0 = BigUint :: from_bytes_le ( & bytes) ;
36- let right = g_b. modpow ( & big_x0, p) ;
37-
3837 if let Some ( & x1) = table. get ( & right) {
3938 return Some ( ( x0, x1) ) ;
4039 }
40+
41+ // reuse exponentiation: simply multiply
42+ // by g^b to increase exponent by 1
43+ right = & right * & g_b % p;
4144 }
4245 None
4346}
0 commit comments