1package Crypt::OpenSSL::Bignum;
2
3use 5.005;
4use strict;
5use Carp;
6
7use vars qw( $VERSION @ISA );
8
9use base qw(DynaLoader);
10
11$VERSION = '0.09';
12
13bootstrap Crypt::OpenSSL::Bignum $VERSION;
14
151;
16__END__
17
18=head1 NAME
19
20Crypt::OpenSSL::Bignum - OpenSSL's multiprecision integer arithmetic
21
22=head1 SYNOPSIS
23
24  use Crypt::OpenSSL::Bignum;
25
26  my $bn = Crypt::OpenSSL::Bignum->new_from_decimal( "1000" );
27  # or
28  my $bn = Crypt::OpenSSL::Bignum->new_from_word( 1000 );
29  # or
30  my $bn = Crypt::OpenSSL::Bignum->new_from_hex("3e8"); # no leading 0x
31  # or
32  my $bn = Crypt::OpenSSL::Bignum->new_from_bin(pack( "C*", 3, 232 ))
33
34  use Crypt::OpenSSL::Bignum::CTX;
35
36  sub print_factorial
37  {
38    my( $n ) = @_;
39    my $fac = Crypt::OpenSSL::Bignum->one();
40    my $ctx = Crypt::OpenSSL::Bignum::CTX->new();
41    foreach my $i (1 .. $n)
42    {
43      $fac->mul( Crypt::OpenSSL::Bignum->new_from_word( $i ), $ctx, $fac );
44    }
45    print "$n factorial is ", $fac->to_decimal(), "\n";
46  }
47
48=head1 DESCRIPTION
49
50Crypt::OpenSSL::Bignum provides access to OpenSSL multiprecision
51integer arithmetic libraries.  Presently, many though not all of the
52arithmetic operations that OpenSSL provides are exposed to perl.  In
53addition, this module can be used to provide access to bignum values
54produced by other OpenSSL modules, such as key parameters from
55Crypt::OpenSSL::RSA.
56
57I<NOTE>: Many of the methods in this package can croak, so use eval, or
58Error.pm's try/catch mechanism to capture errors.
59
60=head1 Constructors
61
62=over
63
64=item new_from_decimal
65
66 my $bn = Crypt::OpenSSL::Bignum->new_from_decimal($decimal_string);
67
68Create a new Crypt::OpenSSL::Bignum object whose value is specified by
69the given decimal representation.
70
71=item new_from_hex
72
73 my $bn = Crypt::OpenSSL::Bignum->new_from_hex($hex_string); #no leading '0x'
74
75Create a new Crypt::OpenSSL::Bignum object whose value is specified by
76the given hexidecimal representation.
77
78=item new_from_word
79
80 my $bn = Crypt::OpenSSL::Bignum->new_from_word($unsigned_integer);
81
82Create a new Crypt::OpenSSL::Bignum object whose value will be the
83word given.  Note that numbers represented by objects created using
84this method are necessarily between 0 and 2^32 - 1.
85
86=item new_from_bin
87
88 my $bn = Crypt::OpenSSL::Bignum->new_from_bin($bin_buffer);
89
90Create a new Crypt::OpenSSL::Bignum object whose value is specified by
91the given packed binary string (created by L</to_bin>). Note that objects
92created using this method are necessarily nonnegative.
93
94=item new
95
96 my $bn = Crypt::OpenSSL::Bignum->new;
97
98Returns a new Crypt::OpenSSL::Bignum object representing 0
99
100=item zero
101
102 my $bn = Crypt::OpenSSL::Bignum->zero;
103
104Returns a new Crypt::OpenSSL::Bignum object representing 0 (same as new)
105
106=item one
107
108 my $bn = Crypt::OpenSSL::Bignum->one;
109
110Returns a new Crypt::OpenSSL::Bignum object representing 1
111
112=item rand
113
114 my $bn = Crypt::OpenSSL::Bignum->rand($bits, $top, $bottom)
115 # $bits, $top, $bottom are integers
116
117generates a cryptographically strong pseudo-random number of bits bits in
118length and stores it in rnd. If top is -1, the most significant bit of the
119random number can be zero. If top is 0, it is set to 1, and if top is 1, the
120two most significant bits of the number will be set to 1, so that the product
121of two such random numbers will always have 2*bits length. If bottom is true,
122the number will be odd.
123
124=item pseudo_rand
125
126 my $bn = Crypt::OpenSSL::Bignum->pseudo_rand($bits, $top, $bottom)
127 # $bits, $top, $bottom are integers
128
129does the same, but pseudo-random numbers generated by this function are not
130necessarily unpredictable. They can be used for non-cryptographic purposes and
131for certain purposes in cryptographic protocols, but usually not for key
132generation etc.
133
134=item rand_range
135
136 my $bn = Crypt::OpenSSL::Bignum->rand_range($bn_range)
137
138generates a cryptographically strong pseudo-random number rnd in the range 0
139<lt>= rnd < range. BN_pseudo_rand_range() does the same, but is based on
140BN_pseudo_rand(), and hence numbers generated by it are not necessarily
141unpredictable.
142
143=item bless_pointer
144
145 my $bn = Crypt::OpenSSL::Bignum->bless_pointer($BIGNUM_ptr)
146
147Given a pointer to a OpenSSL BIGNUM object in memory, construct and
148return Crypt::OpenSSL::Bignum object around this.  Note that the
149underlying BIGNUM object will be destroyed (via BN_clear_free(3ssl))
150when the returned Crypt::OpenSSL::Bignum object is no longer
151referenced, so the pointer passed to this method should only be
152referenced via the returned perl object after calling bless_pointer.
153
154This method is intended only for use by XSUB writers writing code that
155interfaces with OpenSSL library methods, and who wish to be able to
156return a BIGNUM structure to perl as a Crypt::OpenSSL::Bignum object.
157
158=back
159
160=head1 Instance Methods
161
162=over
163
164=item to_decimal
165
166 my $decimal_string = $self->to_decimal;
167
168Return a decimal string representation of this object.
169
170=item to_hex
171
172 my $hex_string = $self->to_hex;
173
174Return a hexidecimal string representation of this object.
175
176=item to_bin
177
178 my $bin_buffer = $self->to_bin;
179
180Return a packed binary string representation of this object.  Note
181that sign is ignored, so that to bin called on a
182Crypt::OpenSSL::Bignum object representing a negative number returns
183the same value as it would called on an object representing that
184number's absolute value.
185
186=item get_word
187
188 my $unsigned_int = $self->get_word;
189
190Return a scalar integer representation of this object, if it can be
191represented as an unsigned long.
192
193=item is_zero
194
195 my $bool = $self->is_zero;
196
197Returns true of this object represents 0.
198
199=item is_one
200
201 my $bool = $self->is_one;
202
203Returns true of this object represents 1.
204
205=item is_odd
206
207 my $bool = $self->is_odd;
208
209Returns true of this object represents an odd number.
210
211=item add
212
213 my $new_bn_object = $self->add($bn_b); # $new_bn_object = $self + $bn_b
214 # or
215 $self->add($bn_b, $result_bn);         # $result_bn = $self + $bn_b
216
217This method returns the sum of this object and the first argument.  If
218only one argument is passed, a new Crypt::OpenSSL::Bignum object is
219created for the return value; otherwise, the value of second argument
220is set to the result and returned.
221
222=item sub
223
224 my $new_bn_object = $self->sub($bn_b); # $new_bn_object = $self - $bn_b
225 # or
226 $self->sub($bn_b, $result_bn);         # $result_bn = $self - $bn_b
227
228This method returns the difference of this object and the first
229argument.  If only one argument is passed, a new
230Crypt::OpenSSL::Bignum object is created for the return value;
231otherwise, the value of second argument is set to the result and
232returned.
233
234=item mul
235
236 my $new_bn_object = $self->mul($bn_b, $ctx); # $new_bn_object = $self * $bn_b
237 # or
238 $self->mul($bn_b, $ctx, $result_bn);         # $result_bn = $self * $bn_b
239
240This method returns the product of this object and the first argument,
241using the second argument, a Crypt::OpenSSL::Bignum::CTX object, as a
242scratchpad.  If only two arguments are passed, a new
243Crypt::OpenSSL::Bignum object is created for the return value;
244otherwise, the value of third argument is set to the result and
245returned.
246
247=item div
248
249 my ($quotient, $remainder) = $self->div($bn_b, $ctx);
250 # or
251 $self->div($bn_b, $ctx, $quotient, $remainder);
252
253This method returns a list consisting of quotient and the remainder
254obtained by dividing this object by the first argument, using the
255second argument, a Crypt::OpenSSL::Bignum::CTX object, as a
256scratchpad.  If only two arguments are passed, new
257Crypt::OpenSSL::Bignum objects are created for both return values.  If
258a third argument is passed, otherwise, the value of third argument is
259set to the quotient.  If a fourth argument is passed, the value of the
260fourth argument is set to the remainder.
261
262=item mod
263
264 my $remainder = $self->mod($bn_b, $ctx);
265 # or
266 $self->mod($bn_b, $ctx, $remainder);
267
268This method returns the remainder obtained by dividing this object by
269the first argument, a Crypt::OpenSSL::Bignum::CTX object, as a
270scratchpad. Crypt::OpenSSL::Bignum object is created for the return
271value. If a third argument is passed, the value of third argument is
272set to the remainder.
273
274=item sqr
275
276 my $new_bn_object = $self->sqr($ctx);
277 # new object is created $self is not modified
278
279This method returns the square (C<$self ** 2>) of Crypt::OpenSSL::Bignum object.
280
281=item exp
282
283 my $new_bn_object = $self->exp($bn_exp, $ctx);
284 # new object is created $self is not modified
285
286This method returns the product of this object exponentiated by the
287first argument (Crypt::OpenSSL::Bignum object), using the second argument, a
288Crypt::OpenSSL::Bignum::CTX object, as a scratchpad.
289
290=item mod_exp
291
292 my $new_bn_object = $self->exp_mod($bn_exp, $bn_mod, $ctx);
293 # new object is created $self is not modified
294
295This method returns the product of this object exponentiated by the
296first argument (Crypt::OpenSSL::Bignum object), modulo the second
297argument (also Crypt::OpenSSL::Bignum object), using the third argument,
298a Crypt::OpenSSL::Bignum::CTX object, as a scratchpad.
299
300=item mod_mul
301
302 my $new_bn_object = $self->mod_mul($bn_b, $bn_mod, $ctx);
303 # new object is created $self is not modified
304
305This method returns C<($self * $bn_b) % $bn_mod>, using the third argument,
306a Crypt::OpenSSL::Bignum::CTX object, as a scratchpad.
307
308=item mod_inverse
309
310 my $new_bn_object = $self->mod_inverse($bn_n, $ctx);
311 # new object is created $self is not modified
312
313Computes the inverse of C<$self> modulo C<$bn_n> and returns the result in
314a new Crypt::OpenSSL::Bignum object, using the second argument,
315a Crypt::OpenSSL::Bignum::CTX object, as a scratchpad.
316
317=item gcd
318
319 my $new_bn_object = $self->gcd($bn_b, $ctx);
320 # new object is created $self is not modified
321
322Computes the greatest common divisor of C<$self> and C<$bn_b> and returns the result in
323a new Crypt::OpenSSL::Bignum object, using the second argument,
324a Crypt::OpenSSL::Bignum::CTX object, as a scratchpad.
325
326=item cmp
327
328 my $result = $self->cmp($bn_b);
329 #returns:
330 # -1 if self <  bn_b
331 #  0 if self == bn_b
332 #  1 if self >  bn_b
333
334Comparison of values C<$self> and C<$bn_b> (Crypt::OpenSSL::Bignum objects).
335
336=item ucmp
337
338 my $result = $self->ucmp($bn_b);
339 #returns:
340 # -1 if |self| <  |bn_b|
341 #  0 if |self| == |bn_b|
342 #  1 if |self| >  |bn_b|
343
344Comparison using the absolute values of C<$self> and C<$bn_b> (Crypt::OpenSSL::Bignum objects).
345
346=item equals
347
348 my $result = $self->equals($bn_b);
349 #returns:
350 # 1 if self == bn_b
351 # 0 otherwise
352
353=item num_bits
354
355 my $bits = $self->num_bits;
356
357Returns the number of significant bits in a word. If we take 0x00000432 as an
358example, it returns 11, not 16, not 32. Basically, except for a zero, it
359returns C<floor(log2(w)) + 1>.
360
361=item num_bytes
362
363 my $bytes = $self->num_bytes;
364
365Returns the size of binary represenatation in bytes.
366
367=item rshift
368
369 my $new_bn_object = $self->rshift($n);
370 # new object is created $self is not modified
371
372Shifts a right by C<$n> (integer) bits and places the result into a newly created Crypt::OpenSSL::Bignum object.
373
374=item lshift
375
376 my $new_bn_object = $self->lshift($n);
377 # new object is created $self is not modified
378
379Shifts a left by C<$n> (integer) bits and places the result into a newly created Crypt::OpenSSL::Bignum object.
380
381=item swap
382
383 my $bn_a = Crypt::OpenSSL::Bignum->new_from_decimal("1234567890001");
384 my $bn_b = Crypt::OpenSSL::Bignum->new_from_decimal("1234567890002");
385
386 $bn_a->swap($bn_b);
387 # or
388 $bn_b->swap($bn_a);
389
390Exchanges the values of two Crypt::OpenSSL::Bignum objects.
391
392=item copy
393
394 my $new_bn_object = $self->copy;
395
396Returns a copy of this object.
397
398=item pointer_copy
399
400 my $cloned_BIGNUM_ptr = $self->pointer_copy($BIGNUM_ptr);
401
402This method is intended only for use by XSUB writers wanting to have
403access to the underlying BIGNUM structure referenced by a
404Crypt::OpenSSL::Bignum perl object so that they can pass them to other
405routines in the OpenSSL library.  It returns a perl scalar whose IV
406can be cast to a BIGNUM* value.  This can then be passed to an XSUB
407which can work with the BIGNUM directly.  Note that the BIGNUM object
408pointed to will be a copy of the BIGNUM object wrapped by the
409instance; it is thus the responsibility of the client to free space
410allocated by this BIGNUM object if and when it is done with it. See
411also bless_pointer.
412
413=back
414
415=head1 AUTHOR
416
417Ian Robertson, iroberts@cpan.org
418
419=head1 SEE ALSO
420
421L<https://www.openssl.org/docs/crypto/bn.html>
422
423=cut
424