16 * EnanoMath GMP backend |
16 * EnanoMath GMP backend |
17 */ |
17 */ |
18 |
18 |
19 class EnanoMath_GMP |
19 class EnanoMath_GMP |
20 { |
20 { |
21 var $api = 'GMP'; |
21 var $api = 'GMP'; |
22 |
22 |
23 /** |
23 /** |
24 * Initializes a number to a GMP integer. |
24 * Initializes a number to a GMP integer. |
25 * @param string String representation of the number |
25 * @param string String representation of the number |
26 * @param int Base the number is currently in, defaults to 10 |
26 * @param int Base the number is currently in, defaults to 10 |
27 * @return resource |
27 * @return resource |
28 */ |
28 */ |
29 |
29 |
30 function init($int, $base = 10) |
30 function init($int, $base = 10) |
31 { |
31 { |
32 return ( is_resource($int) ) ? $int : gmp_init($int, $base); |
32 return ( is_resource($int) ) ? $int : gmp_init($int, $base); |
33 } |
33 } |
34 |
34 |
35 /** |
35 /** |
36 * Converts a number from a GMP integer to a string |
36 * Converts a number from a GMP integer to a string |
37 * @param resource |
37 * @param resource |
38 * @param int Base, default is 10 |
38 * @param int Base, default is 10 |
39 * @return string |
39 * @return string |
40 */ |
40 */ |
41 |
41 |
42 function str($int, $base = 10) |
42 function str($int, $base = 10) |
43 { |
43 { |
44 return ( is_string($int) ) ? $int : gmp_strval($int, $base); |
44 return ( is_string($int) ) ? $int : gmp_strval($int, $base); |
45 } |
45 } |
46 |
46 |
47 /** |
47 /** |
48 * Converts a number between bases. |
48 * Converts a number between bases. |
49 * @param resource BigInt to convert |
49 * @param resource BigInt to convert |
50 * @param int Base to convert from |
50 * @param int Base to convert from |
51 * @param int Base to convert to |
51 * @param int Base to convert to |
52 */ |
52 */ |
53 |
53 |
54 function basecon($int, $from, $to) |
54 function basecon($int, $from, $to) |
55 { |
55 { |
56 return $this->init(gmp_strval(gmp_init($this->str($int), $from), $to)); |
56 return $this->init(gmp_strval(gmp_init($this->str($int), $from), $to)); |
57 } |
57 } |
58 |
58 |
59 /** |
59 /** |
60 * Generates a random integer. |
60 * Generates a random integer. |
61 * @param int Length |
61 * @param int Length |
62 * @return resource |
62 * @return resource |
63 */ |
63 */ |
64 |
64 |
65 function random($len) |
65 function random($len) |
66 { |
66 { |
67 return gmp_random($len / 8); |
67 return gmp_random($len / 8); |
68 } |
68 } |
69 |
69 |
70 /** |
70 /** |
71 * Powmod operation (calculates (a ^ b) mod m) |
71 * Powmod operation (calculates (a ^ b) mod m) |
72 * @param resource a |
72 * @param resource a |
73 * @param resource b |
73 * @param resource b |
74 * @param resource m |
74 * @param resource m |
75 * @return resource |
75 * @return resource |
76 */ |
76 */ |
77 |
77 |
78 function powmod($a, $b, $m) |
78 function powmod($a, $b, $m) |
79 { |
79 { |
80 $a = $this->init($a); |
80 $a = $this->init($a); |
81 $b = $this->init($b); |
81 $b = $this->init($b); |
82 $m = $this->init($m); |
82 $m = $this->init($m); |
83 return ( function_exists('gmp_powm') ) ? gmp_powm($a, $b, $m) : gmp_mod(gmp_pow($a, $b), $m); |
83 return ( function_exists('gmp_powm') ) ? gmp_powm($a, $b, $m) : gmp_mod(gmp_pow($a, $b), $m); |
84 } |
84 } |
85 } |
85 } |
86 |
86 |
87 /** |
87 /** |
88 * EnanoMath big_int backend |
88 * EnanoMath big_int backend |
89 */ |
89 */ |
90 |
90 |
91 class EnanoMath_BigInt |
91 class EnanoMath_BigInt |
92 { |
92 { |
93 var $api = 'big_int'; |
93 var $api = 'big_int'; |
94 |
94 |
95 /** |
95 /** |
96 * Initializes a number to a BigInt integer. |
96 * Initializes a number to a BigInt integer. |
97 * @param string String representation of the number |
97 * @param string String representation of the number |
98 * @param int Base the number is in, defaults to 10 |
98 * @param int Base the number is in, defaults to 10 |
99 * @return resource |
99 * @return resource |
100 */ |
100 */ |
101 |
101 |
102 function init($int, $base = 10) |
102 function init($int, $base = 10) |
103 { |
103 { |
104 return (is_resource($int)) ? $int : bi_from_str($int, $base); |
104 return (is_resource($int)) ? $int : bi_from_str($int, $base); |
105 } |
105 } |
106 |
106 |
107 /** |
107 /** |
108 * Converts a number from a BigInt integer to a string |
108 * Converts a number from a BigInt integer to a string |
109 * @param resource |
109 * @param resource |
110 * @param int Base, default is 10 |
110 * @param int Base, default is 10 |
111 * @return string |
111 * @return string |
112 */ |
112 */ |
113 |
113 |
114 function str($int, $base = 10) |
114 function str($int, $base = 10) |
115 { |
115 { |
116 return ( is_string($int) ) ? $int : bi_to_str($int, $base); |
116 return ( is_string($int) ) ? $int : bi_to_str($int, $base); |
117 } |
117 } |
118 |
118 |
119 /** |
119 /** |
120 * Generates a random integer |
120 * Generates a random integer |
121 * @param int Length (bits) |
121 * @param int Length (bits) |
122 * @return resource |
122 * @return resource |
123 */ |
123 */ |
124 |
124 |
125 function random($len) |
125 function random($len) |
126 { |
126 { |
127 return bi_rand($len); |
127 return bi_rand($len); |
128 } |
128 } |
129 |
129 |
130 /** |
130 /** |
131 * Converts a number between bases. |
131 * Converts a number between bases. |
132 * @param resource BigInt to convert |
132 * @param resource BigInt to convert |
133 * @param int Base to convert from |
133 * @param int Base to convert from |
134 * @param int Base to convert to |
134 * @param int Base to convert to |
135 */ |
135 */ |
136 |
136 |
137 function basecon($int, $from, $to) |
137 function basecon($int, $from, $to) |
138 { |
138 { |
139 return bi_base_convert($this->str($int, $from), $from, $to); |
139 return bi_base_convert($this->str($int, $from), $from, $to); |
140 } |
140 } |
141 |
141 |
142 /** |
142 /** |
143 * Powmod operation (calculates (a ^ b) mod m) |
143 * Powmod operation (calculates (a ^ b) mod m) |
144 * @param resource a |
144 * @param resource a |
145 * @param resource b |
145 * @param resource b |
146 * @param resource m |
146 * @param resource m |
147 * @return resource |
147 * @return resource |
148 */ |
148 */ |
149 |
149 |
150 function powmod($a, $b, $m) |
150 function powmod($a, $b, $m) |
151 { |
151 { |
152 $a = $this->init($a); |
152 $a = $this->init($a); |
153 $b = $this->init($b); |
153 $b = $this->init($b); |
154 $m = $this->init($m); |
154 $m = $this->init($m); |
155 return bi_powmod($a, $b, $m); |
155 return bi_powmod($a, $b, $m); |
156 } |
156 } |
157 } |
157 } |
158 |
158 |
159 /** |
159 /** |
160 * EnanoMath BCMath backend |
160 * EnanoMath BCMath backend |
161 */ |
161 */ |
162 |
162 |
163 class EnanoMath_BCMath |
163 class EnanoMath_BCMath |
164 { |
164 { |
165 var $api = 'BCMath'; |
165 var $api = 'BCMath'; |
166 |
166 |
167 /** |
167 /** |
168 * Initializes a number to a BCMath integer. |
168 * Initializes a number to a BCMath integer. |
169 * @param string String representation of the number |
169 * @param string String representation of the number |
170 * @param int Base the number is in, defaults to 10 |
170 * @param int Base the number is in, defaults to 10 |
171 * @return resource |
171 * @return resource |
172 */ |
172 */ |
173 |
173 |
174 function init($int, $base = 10) |
174 function init($int, $base = 10) |
175 { |
175 { |
176 return $this->basecon($int, $base, 10); |
176 return $this->basecon($int, $base, 10); |
177 } |
177 } |
178 |
178 |
179 /** |
179 /** |
180 * Converts a number from a BCMath integer to a string |
180 * Converts a number from a BCMath integer to a string |
181 * @param resource |
181 * @param resource |
182 * @param int Base, default is 10 |
182 * @param int Base, default is 10 |
183 * @return string |
183 * @return string |
184 */ |
184 */ |
185 |
185 |
186 function str($res) |
186 function str($res) |
187 { |
187 { |
188 return ( is_string($res) ) ? $res : strval($this->basecon($res, 10, $base)); |
188 return ( is_string($res) ) ? $res : strval($this->basecon($res, 10, $base)); |
189 } |
189 } |
190 |
190 |
191 /** |
191 /** |
192 * Generates a random integer |
192 * Generates a random integer |
193 * @param int Length in bits |
193 * @param int Length in bits |
194 * @return resource |
194 * @return resource |
195 */ |
195 */ |
196 |
196 |
197 function random($len) |
197 function random($len) |
198 { |
198 { |
199 $len = 4 * $len; |
199 $len = 4 * $len; |
200 $chars = '0123456789abcdef'; |
200 $chars = '0123456789abcdef'; |
201 $ret = ''; |
201 $ret = ''; |
202 for ( $i = 0; $i < $len; $i++ ) |
202 for ( $i = 0; $i < $len; $i++ ) |
203 { |
203 { |
204 $chid = mt_rand ( 0, strlen($chars) - 1 ); |
204 $chid = mt_rand ( 0, strlen($chars) - 1 ); |
205 $chr = $chars{$chid}; |
205 $chr = $chars{$chid}; |
206 $ret .= $chr; |
206 $ret .= $chr; |
207 } |
207 } |
208 return $this->basecon($this->init($ret), 16, 10); |
208 return $this->basecon($this->init($ret), 16, 10); |
209 } |
209 } |
210 |
210 |
211 /** |
211 /** |
212 * Converts a number between bases. |
212 * Converts a number between bases. |
213 * @param resource BigInt to convert |
213 * @param resource BigInt to convert |
214 * @param int Base to convert from |
214 * @param int Base to convert from |
215 * @param int Base to convert to |
215 * @param int Base to convert to |
216 */ |
216 */ |
217 |
217 |
218 function basecon($int, $from, $to) |
218 function basecon($int, $from, $to) |
219 { |
219 { |
220 if ( $from != 10 ) |
220 if ( $from != 10 ) |
221 $int = $this->_bcmath_base2dec($int, $from); |
221 $int = $this->_bcmath_base2dec($int, $from); |
222 if ( $to != 10 ) |
222 if ( $to != 10 ) |
223 $int = $this->_bcmath_dec2base($int, $to); |
223 $int = $this->_bcmath_dec2base($int, $to); |
224 return $int; |
224 return $int; |
225 } |
225 } |
226 |
226 |
227 /** |
227 /** |
228 * Powmod operation (calculates (a ^ b) mod m) |
228 * Powmod operation (calculates (a ^ b) mod m) |
229 * @param resource a |
229 * @param resource a |
230 * @param resource b |
230 * @param resource b |
231 * @param resource m |
231 * @param resource m |
232 * @return resource |
232 * @return resource |
233 */ |
233 */ |
234 |
234 |
235 function powmod($a, $b, $m) |
235 function powmod($a, $b, $m) |
236 { |
236 { |
237 $a = $this->init($a); |
237 $a = $this->init($a); |
238 $b = $this->init($b); |
238 $b = $this->init($b); |
239 $m = $this->init($m); |
239 $m = $this->init($m); |
240 return ( function_exists('bcpowmod') ) ? bcpowmod($a, $b, $m) : bcmod( bcpow($a, $b), $m ); |
240 return ( function_exists('bcpowmod') ) ? bcpowmod($a, $b, $m) : bcmod( bcpow($a, $b), $m ); |
241 } |
241 } |
242 |
242 |
243 // from us.php.net/bc: |
243 // from us.php.net/bc: |
244 // convert a decimal value to any other base value |
244 // convert a decimal value to any other base value |
245 function _bcmath_dec2base($dec,$base,$digits=FALSE) { |
245 function _bcmath_dec2base($dec,$base,$digits=FALSE) { |
246 if($base<2 or $base>256) die("Invalid Base: ".$base); |
246 if($base<2 or $base>256) die("Invalid Base: ".$base); |
247 bcscale(0); |
247 bcscale(0); |
248 $value=""; |
248 $value=""; |
249 if(!$digits) $digits=$this->_bcmath_digits($base); |
249 if(!$digits) $digits=$this->_bcmath_digits($base); |
250 while($dec>$base-1) { |
250 while($dec>$base-1) { |
251 $rest=bcmod($dec,$base); |
251 $rest=bcmod($dec,$base); |
252 $dec=bcdiv($dec,$base); |
252 $dec=bcdiv($dec,$base); |
253 $value=$digits[$rest].$value; |
253 $value=$digits[$rest].$value; |
254 } |
254 } |
255 $value=$digits[intval($dec)].$value; |
255 $value=$digits[intval($dec)].$value; |
256 return (string) $value; |
256 return (string) $value; |
257 } |
257 } |
258 |
258 |
259 // convert another base value to its decimal value |
259 // convert another base value to its decimal value |
260 function _bcmath_base2dec($value,$base,$digits=FALSE) { |
260 function _bcmath_base2dec($value,$base,$digits=FALSE) { |
261 if($base<2 or $base>256) die("Invalid Base: ".$base); |
261 if($base<2 or $base>256) die("Invalid Base: ".$base); |
262 bcscale(0); |
262 bcscale(0); |
263 if($base<37) $value=strtolower($value); |
263 if($base<37) $value=strtolower($value); |
264 if(!$digits) $digits=$this->_bcmath_digits($base); |
264 if(!$digits) $digits=$this->_bcmath_digits($base); |
265 $size=strlen($value); |
265 $size=strlen($value); |
266 $dec="0"; |
266 $dec="0"; |
267 for($loop=0;$loop<$size;$loop++) { |
267 for($loop=0;$loop<$size;$loop++) { |
268 $element=strpos($digits,$value[$loop]); |
268 $element=strpos($digits,$value[$loop]); |
269 $power=bcpow($base,$size-$loop-1); |
269 $power=bcpow($base,$size-$loop-1); |
270 $dec=bcadd($dec,bcmul($element,$power)); |
270 $dec=bcadd($dec,bcmul($element,$power)); |
271 } |
271 } |
272 return (string) $dec; |
272 return (string) $dec; |
273 } |
273 } |
274 |
274 |
275 function _bcmath_digits($base) { |
275 function _bcmath_digits($base) { |
276 if($base>64) { |
276 if($base>64) { |
277 $digits=""; |
277 $digits=""; |
278 for($loop=0;$loop<256;$loop++) { |
278 for($loop=0;$loop<256;$loop++) { |
279 $digits.=chr($loop); |
279 $digits.=chr($loop); |
280 } |
280 } |
281 } else { |
281 } else { |
282 $digits ="0123456789abcdefghijklmnopqrstuvwxyz"; |
282 $digits ="0123456789abcdefghijklmnopqrstuvwxyz"; |
283 $digits.="ABCDEFGHIJKLMNOPQRSTUVWXYZ-_"; |
283 $digits.="ABCDEFGHIJKLMNOPQRSTUVWXYZ-_"; |
284 } |
284 } |
285 $digits=substr($digits,0,$base); |
285 $digits=substr($digits,0,$base); |
286 return (string) $digits; |
286 return (string) $digits; |
287 } |
287 } |
288 } |
288 } |
289 |
289 |
290 /** |
290 /** |
291 * Creates a new math object based on what libraries are available. |
291 * Creates a new math object based on what libraries are available. |
292 * @return object |
292 * @return object |
293 */ |
293 */ |
294 |
294 |
295 function enanomath_create() |
295 function enanomath_create() |
296 { |
296 { |
297 if ( function_exists('gmp_init') ) |
297 if ( function_exists('gmp_init') ) |
298 return new EnanoMath_GMP(); |
298 return new EnanoMath_GMP(); |
299 else if ( function_exists('bi_from_str') ) |
299 else if ( function_exists('bi_from_str') ) |
300 return new EnanoMath_BigInt(); |
300 return new EnanoMath_BigInt(); |
301 else if ( function_exists('bcadd') ) |
301 else if ( function_exists('bcadd') ) |
302 return new EnanoMath_BCMath(); |
302 return new EnanoMath_BCMath(); |
303 else |
303 else |
304 throw new Exception('dh_err_not_supported'); |
304 throw new Exception('dh_err_not_supported'); |
305 } |
305 } |
306 |
306 |
307 ?> |
307 ?> |