Blame Bignum.pm

Packit 19ef86
package Crypt::OpenSSL::Bignum;
Packit 19ef86
Packit 19ef86
use 5.005;
Packit 19ef86
use strict;
Packit 19ef86
use Carp;
Packit 19ef86
Packit 19ef86
use vars qw( $VERSION @ISA );
Packit 19ef86
Packit 19ef86
use base qw(DynaLoader);
Packit 19ef86
Packit 19ef86
$VERSION = '0.09';
Packit 19ef86
Packit 19ef86
bootstrap Crypt::OpenSSL::Bignum $VERSION;
Packit 19ef86
Packit 19ef86
1;
Packit 19ef86
__END__
Packit 19ef86
Packit 19ef86
=head1 NAME
Packit 19ef86
Packit 19ef86
Crypt::OpenSSL::Bignum - OpenSSL's multiprecision integer arithmetic
Packit 19ef86
Packit 19ef86
=head1 SYNOPSIS
Packit 19ef86
Packit 19ef86
  use Crypt::OpenSSL::Bignum;
Packit 19ef86
Packit 19ef86
  my $bn = Crypt::OpenSSL::Bignum->new_from_decimal( "1000" );
Packit 19ef86
  # or
Packit 19ef86
  my $bn = Crypt::OpenSSL::Bignum->new_from_word( 1000 );
Packit 19ef86
  # or
Packit 19ef86
  my $bn = Crypt::OpenSSL::Bignum->new_from_hex("3e8"); # no leading 0x
Packit 19ef86
  # or
Packit 19ef86
  my $bn = Crypt::OpenSSL::Bignum->new_from_bin(pack( "C*", 3, 232 ))
Packit 19ef86
Packit 19ef86
  use Crypt::OpenSSL::Bignum::CTX;
Packit 19ef86
Packit 19ef86
  sub print_factorial
Packit 19ef86
  {
Packit 19ef86
    my( $n ) = @_;
Packit 19ef86
    my $fac = Crypt::OpenSSL::Bignum->one();
Packit 19ef86
    my $ctx = Crypt::OpenSSL::Bignum::CTX->new();
Packit 19ef86
    foreach my $i (1 .. $n)
Packit 19ef86
    {
Packit 19ef86
      $fac->mul( Crypt::OpenSSL::Bignum->new_from_word( $i ), $ctx, $fac );
Packit 19ef86
    }
Packit 19ef86
    print "$n factorial is ", $fac->to_decimal(), "\n";
Packit 19ef86
  }
Packit 19ef86
Packit 19ef86
=head1 DESCRIPTION
Packit 19ef86
Packit 19ef86
Crypt::OpenSSL::Bignum provides access to OpenSSL multiprecision
Packit 19ef86
integer arithmetic libraries.  Presently, many though not all of the
Packit 19ef86
arithmetic operations that OpenSSL provides are exposed to perl.  In
Packit 19ef86
addition, this module can be used to provide access to bignum values
Packit 19ef86
produced by other OpenSSL modules, such as key parameters from
Packit 19ef86
Crypt::OpenSSL::RSA.
Packit 19ef86
Packit 19ef86
I<NOTE>: Many of the methods in this package can croak, so use eval, or
Packit 19ef86
Error.pm's try/catch mechanism to capture errors.
Packit 19ef86
Packit 19ef86
=head1 Constructors
Packit 19ef86
Packit 19ef86
=over
Packit 19ef86
Packit 19ef86
=item new_from_decimal
Packit 19ef86
Packit 19ef86
 my $bn = Crypt::OpenSSL::Bignum->new_from_decimal($decimal_string);
Packit 19ef86
Packit 19ef86
Create a new Crypt::OpenSSL::Bignum object whose value is specified by
Packit 19ef86
the given decimal representation.
Packit 19ef86
Packit 19ef86
=item new_from_hex
Packit 19ef86
Packit 19ef86
 my $bn = Crypt::OpenSSL::Bignum->new_from_hex($hex_string); #no leading '0x'
Packit 19ef86
Packit 19ef86
Create a new Crypt::OpenSSL::Bignum object whose value is specified by
Packit 19ef86
the given hexidecimal representation.
Packit 19ef86
Packit 19ef86
=item new_from_word
Packit 19ef86
Packit 19ef86
 my $bn = Crypt::OpenSSL::Bignum->new_from_word($unsigned_integer);
Packit 19ef86
Packit 19ef86
Create a new Crypt::OpenSSL::Bignum object whose value will be the
Packit 19ef86
word given.  Note that numbers represented by objects created using
Packit 19ef86
this method are necessarily between 0 and 2^32 - 1.
Packit 19ef86
Packit 19ef86
=item new_from_bin
Packit 19ef86
Packit 19ef86
 my $bn = Crypt::OpenSSL::Bignum->new_from_bin($bin_buffer);
Packit 19ef86
Packit 19ef86
Create a new Crypt::OpenSSL::Bignum object whose value is specified by
Packit 19ef86
the given packed binary string (created by L</to_bin>). Note that objects
Packit 19ef86
created using this method are necessarily nonnegative.
Packit 19ef86
Packit 19ef86
=item new
Packit 19ef86
Packit 19ef86
 my $bn = Crypt::OpenSSL::Bignum->new;
Packit 19ef86
Packit 19ef86
Returns a new Crypt::OpenSSL::Bignum object representing 0
Packit 19ef86
Packit 19ef86
=item zero
Packit 19ef86
Packit 19ef86
 my $bn = Crypt::OpenSSL::Bignum->zero;
Packit 19ef86
Packit 19ef86
Returns a new Crypt::OpenSSL::Bignum object representing 0 (same as new)
Packit 19ef86
Packit 19ef86
=item one
Packit 19ef86
Packit 19ef86
 my $bn = Crypt::OpenSSL::Bignum->one;
Packit 19ef86
Packit 19ef86
Returns a new Crypt::OpenSSL::Bignum object representing 1
Packit 19ef86
Packit 19ef86
=item rand
Packit 19ef86
Packit 19ef86
 my $bn = Crypt::OpenSSL::Bignum->rand($bits, $top, $bottom)
Packit 19ef86
 # $bits, $top, $bottom are integers
Packit 19ef86
Packit 19ef86
generates a cryptographically strong pseudo-random number of bits bits in
Packit 19ef86
length and stores it in rnd. If top is -1, the most significant bit of the
Packit 19ef86
random number can be zero. If top is 0, it is set to 1, and if top is 1, the
Packit 19ef86
two most significant bits of the number will be set to 1, so that the product
Packit 19ef86
of two such random numbers will always have 2*bits length. If bottom is true,
Packit 19ef86
the number will be odd.
Packit 19ef86
Packit 19ef86
=item pseudo_rand
Packit 19ef86
Packit 19ef86
 my $bn = Crypt::OpenSSL::Bignum->pseudo_rand($bits, $top, $bottom)
Packit 19ef86
 # $bits, $top, $bottom are integers
Packit 19ef86
Packit 19ef86
does the same, but pseudo-random numbers generated by this function are not
Packit 19ef86
necessarily unpredictable. They can be used for non-cryptographic purposes and
Packit 19ef86
for certain purposes in cryptographic protocols, but usually not for key
Packit 19ef86
generation etc.
Packit 19ef86
Packit 19ef86
=item rand_range
Packit 19ef86
Packit 19ef86
 my $bn = Crypt::OpenSSL::Bignum->rand_range($bn_range)
Packit 19ef86
Packit 19ef86
generates a cryptographically strong pseudo-random number rnd in the range 0
Packit 19ef86
<lt>= rnd < range. BN_pseudo_rand_range() does the same, but is based on
Packit 19ef86
BN_pseudo_rand(), and hence numbers generated by it are not necessarily
Packit 19ef86
unpredictable.
Packit 19ef86
Packit 19ef86
=item bless_pointer
Packit 19ef86
Packit 19ef86
 my $bn = Crypt::OpenSSL::Bignum->bless_pointer($BIGNUM_ptr)
Packit 19ef86
Packit 19ef86
Given a pointer to a OpenSSL BIGNUM object in memory, construct and
Packit 19ef86
return Crypt::OpenSSL::Bignum object around this.  Note that the
Packit 19ef86
underlying BIGNUM object will be destroyed (via BN_clear_free(3ssl))
Packit 19ef86
when the returned Crypt::OpenSSL::Bignum object is no longer
Packit 19ef86
referenced, so the pointer passed to this method should only be
Packit 19ef86
referenced via the returned perl object after calling bless_pointer.
Packit 19ef86
Packit 19ef86
This method is intended only for use by XSUB writers writing code that
Packit 19ef86
interfaces with OpenSSL library methods, and who wish to be able to
Packit 19ef86
return a BIGNUM structure to perl as a Crypt::OpenSSL::Bignum object.
Packit 19ef86
Packit 19ef86
=back
Packit 19ef86
Packit 19ef86
=head1 Instance Methods
Packit 19ef86
Packit 19ef86
=over
Packit 19ef86
Packit 19ef86
=item to_decimal
Packit 19ef86
Packit 19ef86
 my $decimal_string = $self->to_decimal;
Packit 19ef86
Packit 19ef86
Return a decimal string representation of this object.
Packit 19ef86
Packit 19ef86
=item to_hex
Packit 19ef86
Packit 19ef86
 my $hex_string = $self->to_hex;
Packit 19ef86
Packit 19ef86
Return a hexidecimal string representation of this object.
Packit 19ef86
Packit 19ef86
=item to_bin
Packit 19ef86
Packit 19ef86
 my $bin_buffer = $self->to_bin;
Packit 19ef86
Packit 19ef86
Return a packed binary string representation of this object.  Note
Packit 19ef86
that sign is ignored, so that to bin called on a
Packit 19ef86
Crypt::OpenSSL::Bignum object representing a negative number returns
Packit 19ef86
the same value as it would called on an object representing that
Packit 19ef86
number's absolute value.
Packit 19ef86
Packit 19ef86
=item get_word
Packit 19ef86
Packit 19ef86
 my $unsigned_int = $self->get_word;
Packit 19ef86
Packit 19ef86
Return a scalar integer representation of this object, if it can be
Packit 19ef86
represented as an unsigned long.
Packit 19ef86
Packit 19ef86
=item is_zero
Packit 19ef86
Packit 19ef86
 my $bool = $self->is_zero;
Packit 19ef86
Packit 19ef86
Returns true of this object represents 0.
Packit 19ef86
Packit 19ef86
=item is_one
Packit 19ef86
Packit 19ef86
 my $bool = $self->is_one;
Packit 19ef86
Packit 19ef86
Returns true of this object represents 1.
Packit 19ef86
Packit 19ef86
=item is_odd
Packit 19ef86
Packit 19ef86
 my $bool = $self->is_odd;
Packit 19ef86
Packit 19ef86
Returns true of this object represents an odd number.
Packit 19ef86
Packit 19ef86
=item add
Packit 19ef86
Packit 19ef86
 my $new_bn_object = $self->add($bn_b); # $new_bn_object = $self + $bn_b
Packit 19ef86
 # or
Packit 19ef86
 $self->add($bn_b, $result_bn);         # $result_bn = $self + $bn_b
Packit 19ef86
Packit 19ef86
This method returns the sum of this object and the first argument.  If
Packit 19ef86
only one argument is passed, a new Crypt::OpenSSL::Bignum object is
Packit 19ef86
created for the return value; otherwise, the value of second argument
Packit 19ef86
is set to the result and returned.
Packit 19ef86
Packit 19ef86
=item sub
Packit 19ef86
Packit 19ef86
 my $new_bn_object = $self->sub($bn_b); # $new_bn_object = $self - $bn_b
Packit 19ef86
 # or
Packit 19ef86
 $self->sub($bn_b, $result_bn);         # $result_bn = $self - $bn_b
Packit 19ef86
Packit 19ef86
This method returns the difference of this object and the first
Packit 19ef86
argument.  If only one argument is passed, a new
Packit 19ef86
Crypt::OpenSSL::Bignum object is created for the return value;
Packit 19ef86
otherwise, the value of second argument is set to the result and
Packit 19ef86
returned.
Packit 19ef86
Packit 19ef86
=item mul
Packit 19ef86
Packit 19ef86
 my $new_bn_object = $self->mul($bn_b, $ctx); # $new_bn_object = $self * $bn_b
Packit 19ef86
 # or
Packit 19ef86
 $self->mul($bn_b, $ctx, $result_bn);         # $result_bn = $self * $bn_b
Packit 19ef86
Packit 19ef86
This method returns the product of this object and the first argument,
Packit 19ef86
using the second argument, a Crypt::OpenSSL::Bignum::CTX object, as a
Packit 19ef86
scratchpad.  If only two arguments are passed, a new
Packit 19ef86
Crypt::OpenSSL::Bignum object is created for the return value;
Packit 19ef86
otherwise, the value of third argument is set to the result and
Packit 19ef86
returned.
Packit 19ef86
Packit 19ef86
=item div
Packit 19ef86
Packit 19ef86
 my ($quotient, $remainder) = $self->div($bn_b, $ctx);
Packit 19ef86
 # or
Packit 19ef86
 $self->div($bn_b, $ctx, $quotient, $remainder);
Packit 19ef86
Packit 19ef86
This method returns a list consisting of quotient and the remainder
Packit 19ef86
obtained by dividing this object by the first argument, using the
Packit 19ef86
second argument, a Crypt::OpenSSL::Bignum::CTX object, as a
Packit 19ef86
scratchpad.  If only two arguments are passed, new
Packit 19ef86
Crypt::OpenSSL::Bignum objects are created for both return values.  If
Packit 19ef86
a third argument is passed, otherwise, the value of third argument is
Packit 19ef86
set to the quotient.  If a fourth argument is passed, the value of the
Packit 19ef86
fourth argument is set to the remainder.
Packit 19ef86
Packit 19ef86
=item mod
Packit 19ef86
Packit 19ef86
 my $remainder = $self->mod($bn_b, $ctx);
Packit 19ef86
 # or
Packit 19ef86
 $self->mod($bn_b, $ctx, $remainder);
Packit 19ef86
Packit 19ef86
This method returns the remainder obtained by dividing this object by
Packit 19ef86
the first argument, a Crypt::OpenSSL::Bignum::CTX object, as a
Packit 19ef86
scratchpad. Crypt::OpenSSL::Bignum object is created for the return
Packit 19ef86
value. If a third argument is passed, the value of third argument is
Packit 19ef86
set to the remainder.
Packit 19ef86
Packit 19ef86
=item sqr
Packit 19ef86
Packit 19ef86
 my $new_bn_object = $self->sqr($ctx);
Packit 19ef86
 # new object is created $self is not modified
Packit 19ef86
Packit 19ef86
This method returns the square (C<$self ** 2>) of Crypt::OpenSSL::Bignum object.
Packit 19ef86
Packit 19ef86
=item exp
Packit 19ef86
Packit 19ef86
 my $new_bn_object = $self->exp($bn_exp, $ctx);
Packit 19ef86
 # new object is created $self is not modified
Packit 19ef86
Packit 19ef86
This method returns the product of this object exponentiated by the
Packit 19ef86
first argument (Crypt::OpenSSL::Bignum object), using the second argument, a
Packit 19ef86
Crypt::OpenSSL::Bignum::CTX object, as a scratchpad.
Packit 19ef86
Packit 19ef86
=item mod_exp
Packit 19ef86
Packit 19ef86
 my $new_bn_object = $self->exp_mod($bn_exp, $bn_mod, $ctx);
Packit 19ef86
 # new object is created $self is not modified
Packit 19ef86
Packit 19ef86
This method returns the product of this object exponentiated by the
Packit 19ef86
first argument (Crypt::OpenSSL::Bignum object), modulo the second
Packit 19ef86
argument (also Crypt::OpenSSL::Bignum object), using the third argument,
Packit 19ef86
a Crypt::OpenSSL::Bignum::CTX object, as a scratchpad.
Packit 19ef86
Packit 19ef86
=item mod_mul
Packit 19ef86
Packit 19ef86
 my $new_bn_object = $self->mod_mul($bn_b, $bn_mod, $ctx);
Packit 19ef86
 # new object is created $self is not modified
Packit 19ef86
Packit 19ef86
This method returns C<($self * $bn_b) % $bn_mod>, using the third argument,
Packit 19ef86
a Crypt::OpenSSL::Bignum::CTX object, as a scratchpad.
Packit 19ef86
Packit 19ef86
=item mod_inverse
Packit 19ef86
Packit 19ef86
 my $new_bn_object = $self->mod_inverse($bn_n, $ctx);
Packit 19ef86
 # new object is created $self is not modified
Packit 19ef86
Packit 19ef86
Computes the inverse of C<$self> modulo C<$bn_n> and returns the result in
Packit 19ef86
a new Crypt::OpenSSL::Bignum object, using the second argument,
Packit 19ef86
a Crypt::OpenSSL::Bignum::CTX object, as a scratchpad.
Packit 19ef86
Packit 19ef86
=item gcd
Packit 19ef86
Packit 19ef86
 my $new_bn_object = $self->gcd($bn_b, $ctx);
Packit 19ef86
 # new object is created $self is not modified
Packit 19ef86
Packit 19ef86
Computes the greatest common divisor of C<$self> and C<$bn_b> and returns the result in
Packit 19ef86
a new Crypt::OpenSSL::Bignum object, using the second argument,
Packit 19ef86
a Crypt::OpenSSL::Bignum::CTX object, as a scratchpad.
Packit 19ef86
Packit 19ef86
=item cmp
Packit 19ef86
Packit 19ef86
 my $result = $self->cmp($bn_b);
Packit 19ef86
 #returns:
Packit 19ef86
 # -1 if self <  bn_b
Packit 19ef86
 #  0 if self == bn_b
Packit 19ef86
 #  1 if self >  bn_b
Packit 19ef86
Packit 19ef86
Comparison of values C<$self> and C<$bn_b> (Crypt::OpenSSL::Bignum objects).
Packit 19ef86
Packit 19ef86
=item ucmp
Packit 19ef86
Packit 19ef86
 my $result = $self->ucmp($bn_b);
Packit 19ef86
 #returns:
Packit 19ef86
 # -1 if |self| <  |bn_b|
Packit 19ef86
 #  0 if |self| == |bn_b|
Packit 19ef86
 #  1 if |self| >  |bn_b|
Packit 19ef86
Packit 19ef86
Comparison using the absolute values of C<$self> and C<$bn_b> (Crypt::OpenSSL::Bignum objects).
Packit 19ef86
Packit 19ef86
=item equals
Packit 19ef86
Packit 19ef86
 my $result = $self->equals($bn_b);
Packit 19ef86
 #returns:
Packit 19ef86
 # 1 if self == bn_b
Packit 19ef86
 # 0 otherwise
Packit 19ef86
Packit 19ef86
=item num_bits
Packit 19ef86
Packit 19ef86
 my $bits = $self->num_bits;
Packit 19ef86
Packit 19ef86
Returns the number of significant bits in a word. If we take 0x00000432 as an
Packit 19ef86
example, it returns 11, not 16, not 32. Basically, except for a zero, it
Packit 19ef86
returns C<floor(log2(w)) + 1>.
Packit 19ef86
Packit 19ef86
=item num_bytes
Packit 19ef86
Packit 19ef86
 my $bytes = $self->num_bytes;
Packit 19ef86
Packit 19ef86
Returns the size of binary represenatation in bytes.
Packit 19ef86
Packit 19ef86
=item rshift
Packit 19ef86
Packit 19ef86
 my $new_bn_object = $self->rshift($n);
Packit 19ef86
 # new object is created $self is not modified
Packit 19ef86
Packit 19ef86
Shifts a right by C<$n> (integer) bits and places the result into a newly created Crypt::OpenSSL::Bignum object.
Packit 19ef86
Packit 19ef86
=item lshift
Packit 19ef86
Packit 19ef86
 my $new_bn_object = $self->lshift($n);
Packit 19ef86
 # new object is created $self is not modified
Packit 19ef86
Packit 19ef86
Shifts a left by C<$n> (integer) bits and places the result into a newly created Crypt::OpenSSL::Bignum object.
Packit 19ef86
Packit 19ef86
=item swap
Packit 19ef86
Packit 19ef86
 my $bn_a = Crypt::OpenSSL::Bignum->new_from_decimal("1234567890001");
Packit 19ef86
 my $bn_b = Crypt::OpenSSL::Bignum->new_from_decimal("1234567890002");
Packit 19ef86
Packit 19ef86
 $bn_a->swap($bn_b);
Packit 19ef86
 # or
Packit 19ef86
 $bn_b->swap($bn_a);
Packit 19ef86
Packit 19ef86
Exchanges the values of two Crypt::OpenSSL::Bignum objects.
Packit 19ef86
Packit 19ef86
=item copy
Packit 19ef86
Packit 19ef86
 my $new_bn_object = $self->copy;
Packit 19ef86
Packit 19ef86
Returns a copy of this object.
Packit 19ef86
Packit 19ef86
=item pointer_copy
Packit 19ef86
Packit 19ef86
 my $cloned_BIGNUM_ptr = $self->pointer_copy($BIGNUM_ptr);
Packit 19ef86
Packit 19ef86
This method is intended only for use by XSUB writers wanting to have
Packit 19ef86
access to the underlying BIGNUM structure referenced by a
Packit 19ef86
Crypt::OpenSSL::Bignum perl object so that they can pass them to other
Packit 19ef86
routines in the OpenSSL library.  It returns a perl scalar whose IV
Packit 19ef86
can be cast to a BIGNUM* value.  This can then be passed to an XSUB
Packit 19ef86
which can work with the BIGNUM directly.  Note that the BIGNUM object
Packit 19ef86
pointed to will be a copy of the BIGNUM object wrapped by the
Packit 19ef86
instance; it is thus the responsibility of the client to free space
Packit 19ef86
allocated by this BIGNUM object if and when it is done with it. See
Packit 19ef86
also bless_pointer.
Packit 19ef86
Packit 19ef86
=back
Packit 19ef86
Packit 19ef86
=head1 AUTHOR
Packit 19ef86
Packit 19ef86
Ian Robertson, iroberts@cpan.org
Packit 19ef86
Packit 19ef86
=head1 SEE ALSO
Packit 19ef86
Packit 19ef86
L<https://www.openssl.org/docs/crypto/bn.html>
Packit 19ef86
Packit 19ef86
=cut