@@ -738,54 +738,6 @@ impl Implementation for Ripemd160 {
738
738
}
739
739
}
740
740
741
- // calculate modexp: left-to-right binary exponentiation to keep multiplicands lower
742
- fn modexp ( mut base : BigUint , exp : Vec < u8 > , modulus : BigUint ) -> BigUint {
743
- const BITS_PER_DIGIT : usize = 8 ;
744
-
745
- // n^m % 0 || n^m % 1
746
- if modulus <= BigUint :: one ( ) {
747
- return BigUint :: zero ( ) ;
748
- }
749
-
750
- // normalize exponent
751
- let mut exp = exp. into_iter ( ) . skip_while ( |d| * d == 0 ) . peekable ( ) ;
752
-
753
- // n^0 % m
754
- if exp. peek ( ) . is_none ( ) {
755
- return BigUint :: one ( ) ;
756
- }
757
-
758
- // 0^n % m, n > 0
759
- if base. is_zero ( ) {
760
- return BigUint :: zero ( ) ;
761
- }
762
-
763
- base %= & modulus;
764
-
765
- // Fast path for base divisible by modulus.
766
- if base. is_zero ( ) { return BigUint :: zero ( ) }
767
-
768
- // Left-to-right binary exponentiation (Handbook of Applied Cryptography - Algorithm 14.79).
769
- // http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
770
- let mut result = BigUint :: one ( ) ;
771
-
772
- for digit in exp {
773
- let mut mask = 1 << ( BITS_PER_DIGIT - 1 ) ;
774
-
775
- for _ in 0 ..BITS_PER_DIGIT {
776
- result = & result * & result % & modulus;
777
-
778
- if digit & mask > 0 {
779
- result = result * & base % & modulus;
780
- }
781
-
782
- mask >>= 1 ;
783
- }
784
- }
785
-
786
- result
787
- }
788
-
789
741
impl Implementation for Modexp {
790
742
fn execute ( & self , input : & [ u8 ] , output : & mut BytesRef ) -> Result < ( ) , & ' static str > {
791
743
let mut reader = input. chain ( io:: repeat ( 0 ) ) ;
@@ -817,13 +769,14 @@ impl Implementation for Modexp {
817
769
} ;
818
770
819
771
let base = read_num ( & mut reader, base_len) ;
820
-
821
- let mut exp_buf = vec ! [ 0 ; exp_len] ;
822
- reader. read_exact ( & mut exp_buf[ ..exp_len] ) . expect ( "reading from zero-extended memory cannot fail; qed" ) ;
823
-
772
+ let exponent = read_num ( & mut reader, exp_len) ;
824
773
let modulus = read_num ( & mut reader, mod_len) ;
825
774
826
- modexp ( base, exp_buf, modulus)
775
+ if modulus. is_zero ( ) || modulus. is_one ( ) {
776
+ BigUint :: zero ( )
777
+ } else {
778
+ base. modpow ( & exponent, & modulus)
779
+ }
827
780
} ;
828
781
829
782
// write output to given memory, left padded and same length as the modulus.
@@ -1168,11 +1121,10 @@ mod tests {
1168
1121
} ;
1169
1122
use hex_literal:: hex;
1170
1123
use maplit:: btreemap;
1171
- use num:: { BigUint , Zero , One } ;
1172
1124
use parity_bytes:: BytesRef ;
1173
1125
use super :: {
1174
1126
Builtin , EthereumBuiltin , FromStr , Implementation , Linear ,
1175
- ModexpPricer , modexp as me , Pricing ,
1127
+ ModexpPricer , Pricing ,
1176
1128
Bls12ConstOperations ,
1177
1129
Bls12PairingPrice , Bls12PairingPricer
1178
1130
} ;
@@ -1296,39 +1248,6 @@ mod tests {
1296
1248
assert_eq ! ( & out[ ..] , & expected[ ..] ) ;
1297
1249
}
1298
1250
1299
- #[ test]
1300
- fn modexp_func ( ) {
1301
- // n^0 % m == 1
1302
- let mut base = BigUint :: parse_bytes ( b"12345" , 10 ) . unwrap ( ) ;
1303
- let mut exp = BigUint :: zero ( ) ;
1304
- let mut modulus = BigUint :: parse_bytes ( b"789" , 10 ) . unwrap ( ) ;
1305
- assert_eq ! ( me( base, exp. to_bytes_be( ) , modulus) , BigUint :: one( ) ) ;
1306
-
1307
- // 0^n % m == 0
1308
- base = BigUint :: zero ( ) ;
1309
- exp = BigUint :: parse_bytes ( b"12345" , 10 ) . unwrap ( ) ;
1310
- modulus = BigUint :: parse_bytes ( b"789" , 10 ) . unwrap ( ) ;
1311
- assert_eq ! ( me( base, exp. to_bytes_be( ) , modulus) , BigUint :: zero( ) ) ;
1312
-
1313
- // n^m % 1 == 0
1314
- base = BigUint :: parse_bytes ( b"12345" , 10 ) . unwrap ( ) ;
1315
- exp = BigUint :: parse_bytes ( b"789" , 10 ) . unwrap ( ) ;
1316
- modulus = BigUint :: one ( ) ;
1317
- assert_eq ! ( me( base, exp. to_bytes_be( ) , modulus) , BigUint :: zero( ) ) ;
1318
-
1319
- // if n % d == 0, then n^m % d == 0
1320
- base = BigUint :: parse_bytes ( b"12345" , 10 ) . unwrap ( ) ;
1321
- exp = BigUint :: parse_bytes ( b"789" , 10 ) . unwrap ( ) ;
1322
- modulus = BigUint :: parse_bytes ( b"15" , 10 ) . unwrap ( ) ;
1323
- assert_eq ! ( me( base, exp. to_bytes_be( ) , modulus) , BigUint :: zero( ) ) ;
1324
-
1325
- // others
1326
- base = BigUint :: parse_bytes ( b"12345" , 10 ) . unwrap ( ) ;
1327
- exp = BigUint :: parse_bytes ( b"789" , 10 ) . unwrap ( ) ;
1328
- modulus = BigUint :: parse_bytes ( b"97" , 10 ) . unwrap ( ) ;
1329
- assert_eq ! ( me( base, exp. to_bytes_be( ) , modulus) , BigUint :: parse_bytes( b"55" , 10 ) . unwrap( ) ) ;
1330
- }
1331
-
1332
1251
#[ test]
1333
1252
fn identity ( ) {
1334
1253
let f = EthereumBuiltin :: from_str ( "identity" ) . unwrap ( ) ;
0 commit comments