1
- use std:: fmt:: LowerHex ;
2
-
3
- use num_bigint_dig :: BigUint ;
4
- use num_bigint_dig :: RandBigInt ;
5
- use num_bigint_dig :: RandPrime ;
6
- use num_bigint_dig :: BigInt ;
7
- use num_bigint_dig :: ToBigInt ;
8
- use num_traits :: { One , RefNum , Zero } ;
1
+ use std:: fmt:: { Debug , Display } ;
2
+ use std :: process :: Output ;
3
+ use std :: ops :: Sub ;
4
+
5
+ use num :: { BigUint , BigInt } ;
6
+ use num :: bigint :: { ToBigInt , RandBigInt , ToBigUint } ;
7
+ use num :: traits :: { One , RefNum , Zero , int } ;
8
+ use num :: Integer ;
9
9
use rand:: { prelude:: ThreadRng , thread_rng} ;
10
10
11
11
pub struct PrimeUtils {
12
- bit_size : usize ,
13
- times : usize ,
12
+ bit_size : u64 ,
14
13
rng : ThreadRng ,
14
+ current_p : Option < BigUint >
15
15
}
16
16
17
17
type RSAPublicKey = ( BigUint , BigUint ) ;
18
18
type RSAPrivateKey = ( BigUint , BigUint ) ;
19
19
20
20
impl PrimeUtils {
21
- pub fn new ( bit_size : usize ) -> Self {
22
- let bit_size_f64 = bit_size as f64 ;
23
- let times = ( bit_size_f64 / bit_size_f64. ln ( ) / 2_f64 ) as usize ;
24
- // println!("Times is {}", ×);
21
+ pub fn new ( bit_size : u64 ) -> Self {
25
22
Self {
26
23
bit_size,
27
- times,
28
24
rng : thread_rng ( ) ,
25
+ current_p : None
29
26
}
30
27
}
31
28
32
- fn is_prime ( & mut self , testee : & BigUint ) -> bool {
33
- let mut count = 0 ;
34
- let one: BigUint = One :: one ( ) ;
35
- let testee_minus_one: BigUint = testee. clone ( ) - & one;
36
- while count < self . times {
37
- let rand_num = self . rng . gen_biguint ( self . bit_size ) % testee;
38
- if & rand_num == & one || & rand_num == & testee_minus_one {
39
- continue ;
29
+ fn is_prime ( & mut self ) -> bool {
30
+ self . current_p . as_ref ( ) . map_or ( false , |testee| {
31
+ let mut count = 0 ;
32
+ let one: BigUint = One :: one ( ) ;
33
+ let testee_minus_one: BigUint = testee. clone ( ) - & one;
34
+ // let prime_factor = Factorization::prime_factor(testee_minus_one).unwrap();
35
+ while count < 10 {
36
+ let rand_num = self . rng . gen_biguint ( self . bit_size ) % testee;
37
+ if & rand_num == & one || & rand_num == & testee_minus_one {
38
+ continue ;
39
+ }
40
+ if !miller_rabin_single ( testee, rand_num. clone ( ) ) {
41
+ // println!("This is not a prime");
42
+ return false ;
43
+ }
44
+ count += 1 ;
40
45
}
41
- if !miller_rabin_single ( testee, rand_num. clone ( ) ) {
42
- println ! ( "This is not a prime" ) ;
43
- return false ;
46
+ true
47
+ } )
48
+ }
49
+
50
+ pub fn gen_prime ( & mut self ) -> BigUint {
51
+ if self . current_p . is_none ( ) {
52
+ let random_val = self . rng . gen_biguint ( self . bit_size ) ;
53
+ self . current_p = Some ( if & random_val % BigUint :: from ( 2_u32 ) == Zero :: zero ( ) {
54
+ random_val + BigUint :: from ( 1_u32 )
55
+ } else {
56
+ random_val
57
+ } ) ;
58
+ }
59
+ loop {
60
+ if self . is_prime ( ) {
61
+ break self . current_p . as_ref ( ) . unwrap ( ) . clone ( )
62
+ } else {
63
+ self . current_p = Some ( self . current_p . as_ref ( ) . unwrap ( ) + BigUint :: from ( 2_u32 ) )
44
64
}
45
- count += 1 ;
46
65
}
47
- true
48
66
}
49
67
50
68
pub fn gen_key ( & mut self ) -> ( RSAPublicKey , RSAPrivateKey ) {
51
69
// (pub_key, pri_key)
52
70
// ((N, e), (N, d))
53
71
let e = BigUint :: from ( 65537_u32 ) ;
54
72
loop {
55
- let p = self . rng . gen_prime ( self . bit_size ) ;
56
- let q = self . rng . gen_prime ( self . bit_size ) ;
73
+ let p = self . gen_prime ( ) ;
74
+ let q = self . gen_prime ( ) ;
75
+ // let p = self.rng.gen_prime(self.bit_size);
76
+ // let q = self.rng.gen_prime(self.bit_size);
57
77
let n = & p * & q;
58
78
let phi = & n - & p - & q + BigUint :: from ( 1_u32 ) ;
59
- let ( mut x, _, d) = exgcd ( & e, & phi) ;
79
+ let result = BigInt :: extended_gcd ( & e. to_bigint ( ) . unwrap ( ) , & phi. to_bigint ( ) . unwrap ( ) ) ;
80
+ let ( mut x, d) = ( result. x , result. gcd ) ;
60
81
if d == One :: one ( ) {
61
82
if x < Zero :: zero ( ) {
62
83
let k = ( -& x) . to_biguint ( ) . unwrap ( ) / & phi + BigUint :: from ( 1_u32 ) ;
@@ -75,6 +96,21 @@ impl PrimeUtils {
75
96
}
76
97
}
77
98
99
+ fn get_rank < T > ( testee : & T ) -> T
100
+ where
101
+ T : RefNum < T > + From < u32 > + Ord + Clone ,
102
+ for < ' a > & ' a T : RefNum < T > ,
103
+ {
104
+ let zero = T :: from ( 0_u32 ) ;
105
+ let one = T :: from ( 1_u32 ) ;
106
+ let two = T :: from ( 2_u32 ) ;
107
+ let mut num: T = testee. clone ( ) - & one;
108
+ while & num % & two == zero {
109
+ num = num / & two;
110
+ }
111
+ num
112
+ }
113
+
78
114
fn encrypt_uint ( private_key : & RSAPublicKey , message : & BigUint ) -> BigUint {
79
115
let ( n, e) = private_key;
80
116
quick_pow ( message. clone ( ) , e. clone ( ) , Some ( n. clone ( ) ) )
@@ -85,35 +121,57 @@ fn decrypt_uint(public_key: &RSAPrivateKey, secret: &BigUint) -> BigUint {
85
121
quick_pow ( secret. clone ( ) , d. clone ( ) , Some ( n. clone ( ) ) )
86
122
}
87
123
124
+ pub fn oct_to_base64 ( octet : & BigUint ) -> String {
125
+ base64:: encode ( octet. to_bytes_be ( ) )
126
+ }
127
+
128
+ pub fn base64_to_oct ( base64 : & str ) -> BigUint {
129
+ BigUint :: from_bytes_be ( & base64:: decode ( base64. as_bytes ( ) ) . unwrap ( ) )
130
+ }
131
+
88
132
pub fn oct_to_str ( encoded : BigUint ) -> String {
89
- let ret = unsafe {
133
+ unsafe {
90
134
String :: from_utf8_unchecked ( encoded
91
135
. to_bytes_be ( )
92
136
)
93
- } ;
94
- println ! ( "From oct is: {}" , ret) ;
95
- ret
137
+ }
96
138
}
97
139
98
140
fn str_to_oct ( to_encode : & str ) -> BigUint {
99
141
BigUint :: from_radix_be ( to_encode. as_bytes ( ) , 256 ) . unwrap ( )
100
142
}
101
143
102
144
pub fn encrypt ( private_key : & RSAPublicKey , message : & str ) -> String {
103
- oct_to_str ( encrypt_uint ( private_key, & str_to_oct ( message) ) )
145
+ oct_to_base64 ( & encrypt_uint ( private_key, & str_to_oct ( message) ) )
104
146
}
105
147
106
148
pub fn decrypt ( public_key : & RSAPrivateKey , secret : & str ) -> String {
107
- oct_to_str ( decrypt_uint ( public_key, & str_to_oct ( secret) ) )
149
+ oct_to_str ( decrypt_uint ( public_key, & base64_to_oct ( secret) ) )
108
150
}
109
151
110
152
pub fn miller_rabin_single < T > ( testee : & T , base : T ) -> bool
111
153
where
112
- T : RefNum < T > + From < u32 > + Ord + Clone ,
154
+ T : RefNum < T > + From < u32 > + Ord + Clone + Display ,
113
155
for < ' a > & ' a T : RefNum < T > ,
114
156
{
115
- let exp: T = testee. clone ( ) - T :: from ( 1_u32 ) ;
116
- quick_pow ( base, exp, Some ( testee. clone ( ) ) ) == 1 . into ( )
157
+ let mut exp: T = get_rank ( testee) ;
158
+ // println!("testee is {}, rank is {}", &testee, &exp);
159
+ let one: T = 1 . into ( ) ;
160
+ let two: T = 2 . into ( ) ;
161
+ let testee_minus_one = testee - & one;
162
+ let mut intermediate = quick_pow ( base. clone ( ) , exp. clone ( ) , Some ( testee. clone ( ) ) ) ;
163
+ if intermediate == one {
164
+ return true ;
165
+ }
166
+ exp = exp * & two;
167
+ while & exp <= testee {
168
+ intermediate = & intermediate * & intermediate % testee;
169
+ if intermediate == testee_minus_one {
170
+ return true ;
171
+ }
172
+ exp = exp * & two;
173
+ }
174
+ false
117
175
}
118
176
119
177
pub fn quick_pow < T > ( base : T , mut exp : T , prime : Option < T > ) -> T
0 commit comments