diff --git a/Bignum.pm b/Bignum.pm new file mode 100755 index 0000000..06e9e82 --- /dev/null +++ b/Bignum.pm @@ -0,0 +1,423 @@ +package Crypt::OpenSSL::Bignum; + +use 5.005; +use strict; +use Carp; + +use vars qw( $VERSION @ISA ); + +use base qw(DynaLoader); + +$VERSION = '0.09'; + +bootstrap Crypt::OpenSSL::Bignum $VERSION; + +1; +__END__ + +=head1 NAME + +Crypt::OpenSSL::Bignum - OpenSSL's multiprecision integer arithmetic + +=head1 SYNOPSIS + + use Crypt::OpenSSL::Bignum; + + my $bn = Crypt::OpenSSL::Bignum->new_from_decimal( "1000" ); + # or + my $bn = Crypt::OpenSSL::Bignum->new_from_word( 1000 ); + # or + my $bn = Crypt::OpenSSL::Bignum->new_from_hex("3e8"); # no leading 0x + # or + my $bn = Crypt::OpenSSL::Bignum->new_from_bin(pack( "C*", 3, 232 )) + + use Crypt::OpenSSL::Bignum::CTX; + + sub print_factorial + { + my( $n ) = @_; + my $fac = Crypt::OpenSSL::Bignum->one(); + my $ctx = Crypt::OpenSSL::Bignum::CTX->new(); + foreach my $i (1 .. $n) + { + $fac->mul( Crypt::OpenSSL::Bignum->new_from_word( $i ), $ctx, $fac ); + } + print "$n factorial is ", $fac->to_decimal(), "\n"; + } + +=head1 DESCRIPTION + +Crypt::OpenSSL::Bignum provides access to OpenSSL multiprecision +integer arithmetic libraries. Presently, many though not all of the +arithmetic operations that OpenSSL provides are exposed to perl. In +addition, this module can be used to provide access to bignum values +produced by other OpenSSL modules, such as key parameters from +Crypt::OpenSSL::RSA. + +I: Many of the methods in this package can croak, so use eval, or +Error.pm's try/catch mechanism to capture errors. + +=head1 Constructors + +=over + +=item new_from_decimal + + my $bn = Crypt::OpenSSL::Bignum->new_from_decimal($decimal_string); + +Create a new Crypt::OpenSSL::Bignum object whose value is specified by +the given decimal representation. + +=item new_from_hex + + my $bn = Crypt::OpenSSL::Bignum->new_from_hex($hex_string); #no leading '0x' + +Create a new Crypt::OpenSSL::Bignum object whose value is specified by +the given hexidecimal representation. + +=item new_from_word + + my $bn = Crypt::OpenSSL::Bignum->new_from_word($unsigned_integer); + +Create a new Crypt::OpenSSL::Bignum object whose value will be the +word given. Note that numbers represented by objects created using +this method are necessarily between 0 and 2^32 - 1. + +=item new_from_bin + + my $bn = Crypt::OpenSSL::Bignum->new_from_bin($bin_buffer); + +Create a new Crypt::OpenSSL::Bignum object whose value is specified by +the given packed binary string (created by L). Note that objects +created using this method are necessarily nonnegative. + +=item new + + my $bn = Crypt::OpenSSL::Bignum->new; + +Returns a new Crypt::OpenSSL::Bignum object representing 0 + +=item zero + + my $bn = Crypt::OpenSSL::Bignum->zero; + +Returns a new Crypt::OpenSSL::Bignum object representing 0 (same as new) + +=item one + + my $bn = Crypt::OpenSSL::Bignum->one; + +Returns a new Crypt::OpenSSL::Bignum object representing 1 + +=item rand + + my $bn = Crypt::OpenSSL::Bignum->rand($bits, $top, $bottom) + # $bits, $top, $bottom are integers + +generates a cryptographically strong pseudo-random number of bits bits in +length and stores it in rnd. If top is -1, the most significant bit of the +random number can be zero. If top is 0, it is set to 1, and if top is 1, the +two most significant bits of the number will be set to 1, so that the product +of two such random numbers will always have 2*bits length. If bottom is true, +the number will be odd. + +=item pseudo_rand + + my $bn = Crypt::OpenSSL::Bignum->pseudo_rand($bits, $top, $bottom) + # $bits, $top, $bottom are integers + +does the same, but pseudo-random numbers generated by this function are not +necessarily unpredictable. They can be used for non-cryptographic purposes and +for certain purposes in cryptographic protocols, but usually not for key +generation etc. + +=item rand_range + + my $bn = Crypt::OpenSSL::Bignum->rand_range($bn_range) + +generates a cryptographically strong pseudo-random number rnd in the range 0 += rnd < range. BN_pseudo_rand_range() does the same, but is based on +BN_pseudo_rand(), and hence numbers generated by it are not necessarily +unpredictable. + +=item bless_pointer + + my $bn = Crypt::OpenSSL::Bignum->bless_pointer($BIGNUM_ptr) + +Given a pointer to a OpenSSL BIGNUM object in memory, construct and +return Crypt::OpenSSL::Bignum object around this. Note that the +underlying BIGNUM object will be destroyed (via BN_clear_free(3ssl)) +when the returned Crypt::OpenSSL::Bignum object is no longer +referenced, so the pointer passed to this method should only be +referenced via the returned perl object after calling bless_pointer. + +This method is intended only for use by XSUB writers writing code that +interfaces with OpenSSL library methods, and who wish to be able to +return a BIGNUM structure to perl as a Crypt::OpenSSL::Bignum object. + +=back + +=head1 Instance Methods + +=over + +=item to_decimal + + my $decimal_string = $self->to_decimal; + +Return a decimal string representation of this object. + +=item to_hex + + my $hex_string = $self->to_hex; + +Return a hexidecimal string representation of this object. + +=item to_bin + + my $bin_buffer = $self->to_bin; + +Return a packed binary string representation of this object. Note +that sign is ignored, so that to bin called on a +Crypt::OpenSSL::Bignum object representing a negative number returns +the same value as it would called on an object representing that +number's absolute value. + +=item get_word + + my $unsigned_int = $self->get_word; + +Return a scalar integer representation of this object, if it can be +represented as an unsigned long. + +=item is_zero + + my $bool = $self->is_zero; + +Returns true of this object represents 0. + +=item is_one + + my $bool = $self->is_one; + +Returns true of this object represents 1. + +=item is_odd + + my $bool = $self->is_odd; + +Returns true of this object represents an odd number. + +=item add + + my $new_bn_object = $self->add($bn_b); # $new_bn_object = $self + $bn_b + # or + $self->add($bn_b, $result_bn); # $result_bn = $self + $bn_b + +This method returns the sum of this object and the first argument. If +only one argument is passed, a new Crypt::OpenSSL::Bignum object is +created for the return value; otherwise, the value of second argument +is set to the result and returned. + +=item sub + + my $new_bn_object = $self->sub($bn_b); # $new_bn_object = $self - $bn_b + # or + $self->sub($bn_b, $result_bn); # $result_bn = $self - $bn_b + +This method returns the difference of this object and the first +argument. If only one argument is passed, a new +Crypt::OpenSSL::Bignum object is created for the return value; +otherwise, the value of second argument is set to the result and +returned. + +=item mul + + my $new_bn_object = $self->mul($bn_b, $ctx); # $new_bn_object = $self * $bn_b + # or + $self->mul($bn_b, $ctx, $result_bn); # $result_bn = $self * $bn_b + +This method returns the product of this object and the first argument, +using the second argument, a Crypt::OpenSSL::Bignum::CTX object, as a +scratchpad. If only two arguments are passed, a new +Crypt::OpenSSL::Bignum object is created for the return value; +otherwise, the value of third argument is set to the result and +returned. + +=item div + + my ($quotient, $remainder) = $self->div($bn_b, $ctx); + # or + $self->div($bn_b, $ctx, $quotient, $remainder); + +This method returns a list consisting of quotient and the remainder +obtained by dividing this object by the first argument, using the +second argument, a Crypt::OpenSSL::Bignum::CTX object, as a +scratchpad. If only two arguments are passed, new +Crypt::OpenSSL::Bignum objects are created for both return values. If +a third argument is passed, otherwise, the value of third argument is +set to the quotient. If a fourth argument is passed, the value of the +fourth argument is set to the remainder. + +=item mod + + my $remainder = $self->mod($bn_b, $ctx); + # or + $self->mod($bn_b, $ctx, $remainder); + +This method returns the remainder obtained by dividing this object by +the first argument, a Crypt::OpenSSL::Bignum::CTX object, as a +scratchpad. Crypt::OpenSSL::Bignum object is created for the return +value. If a third argument is passed, the value of third argument is +set to the remainder. + +=item sqr + + my $new_bn_object = $self->sqr($ctx); + # new object is created $self is not modified + +This method returns the square (C<$self ** 2>) of Crypt::OpenSSL::Bignum object. + +=item exp + + my $new_bn_object = $self->exp($bn_exp, $ctx); + # new object is created $self is not modified + +This method returns the product of this object exponentiated by the +first argument (Crypt::OpenSSL::Bignum object), using the second argument, a +Crypt::OpenSSL::Bignum::CTX object, as a scratchpad. + +=item mod_exp + + my $new_bn_object = $self->exp_mod($bn_exp, $bn_mod, $ctx); + # new object is created $self is not modified + +This method returns the product of this object exponentiated by the +first argument (Crypt::OpenSSL::Bignum object), modulo the second +argument (also Crypt::OpenSSL::Bignum object), using the third argument, +a Crypt::OpenSSL::Bignum::CTX object, as a scratchpad. + +=item mod_mul + + my $new_bn_object = $self->mod_mul($bn_b, $bn_mod, $ctx); + # new object is created $self is not modified + +This method returns C<($self * $bn_b) % $bn_mod>, using the third argument, +a Crypt::OpenSSL::Bignum::CTX object, as a scratchpad. + +=item mod_inverse + + my $new_bn_object = $self->mod_inverse($bn_n, $ctx); + # new object is created $self is not modified + +Computes the inverse of C<$self> modulo C<$bn_n> and returns the result in +a new Crypt::OpenSSL::Bignum object, using the second argument, +a Crypt::OpenSSL::Bignum::CTX object, as a scratchpad. + +=item gcd + + my $new_bn_object = $self->gcd($bn_b, $ctx); + # new object is created $self is not modified + +Computes the greatest common divisor of C<$self> and C<$bn_b> and returns the result in +a new Crypt::OpenSSL::Bignum object, using the second argument, +a Crypt::OpenSSL::Bignum::CTX object, as a scratchpad. + +=item cmp + + my $result = $self->cmp($bn_b); + #returns: + # -1 if self < bn_b + # 0 if self == bn_b + # 1 if self > bn_b + +Comparison of values C<$self> and C<$bn_b> (Crypt::OpenSSL::Bignum objects). + +=item ucmp + + my $result = $self->ucmp($bn_b); + #returns: + # -1 if |self| < |bn_b| + # 0 if |self| == |bn_b| + # 1 if |self| > |bn_b| + +Comparison using the absolute values of C<$self> and C<$bn_b> (Crypt::OpenSSL::Bignum objects). + +=item equals + + my $result = $self->equals($bn_b); + #returns: + # 1 if self == bn_b + # 0 otherwise + +=item num_bits + + my $bits = $self->num_bits; + +Returns the number of significant bits in a word. If we take 0x00000432 as an +example, it returns 11, not 16, not 32. Basically, except for a zero, it +returns C. + +=item num_bytes + + my $bytes = $self->num_bytes; + +Returns the size of binary represenatation in bytes. + +=item rshift + + my $new_bn_object = $self->rshift($n); + # new object is created $self is not modified + +Shifts a right by C<$n> (integer) bits and places the result into a newly created Crypt::OpenSSL::Bignum object. + +=item lshift + + my $new_bn_object = $self->lshift($n); + # new object is created $self is not modified + +Shifts a left by C<$n> (integer) bits and places the result into a newly created Crypt::OpenSSL::Bignum object. + +=item swap + + my $bn_a = Crypt::OpenSSL::Bignum->new_from_decimal("1234567890001"); + my $bn_b = Crypt::OpenSSL::Bignum->new_from_decimal("1234567890002"); + + $bn_a->swap($bn_b); + # or + $bn_b->swap($bn_a); + +Exchanges the values of two Crypt::OpenSSL::Bignum objects. + +=item copy + + my $new_bn_object = $self->copy; + +Returns a copy of this object. + +=item pointer_copy + + my $cloned_BIGNUM_ptr = $self->pointer_copy($BIGNUM_ptr); + +This method is intended only for use by XSUB writers wanting to have +access to the underlying BIGNUM structure referenced by a +Crypt::OpenSSL::Bignum perl object so that they can pass them to other +routines in the OpenSSL library. It returns a perl scalar whose IV +can be cast to a BIGNUM* value. This can then be passed to an XSUB +which can work with the BIGNUM directly. Note that the BIGNUM object +pointed to will be a copy of the BIGNUM object wrapped by the +instance; it is thus the responsibility of the client to free space +allocated by this BIGNUM object if and when it is done with it. See +also bless_pointer. + +=back + +=head1 AUTHOR + +Ian Robertson, iroberts@cpan.org + +=head1 SEE ALSO + +L + +=cut diff --git a/Bignum.xs b/Bignum.xs new file mode 100755 index 0000000..149fa52 --- /dev/null +++ b/Bignum.xs @@ -0,0 +1,440 @@ +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" + +#include +#include + +#define checkOpenSslCall( result ) if( ! ( result ) ) \ + croak( "OpenSSL error: %s", ERR_reason_error_string( ERR_get_error() ) ); + +typedef BIGNUM *Crypt__OpenSSL__Bignum; +typedef BN_CTX *Crypt__OpenSSL__Bignum__CTX; + +SV* new_obj( void* obj ) +{ + SV * tmp = sv_newmortal(); + sv_setref_pv(tmp, "Crypt::OpenSSL::Bignum", (void*)obj); + return tmp; +} + +BIGNUM* sv2bn( SV* sv ) +{ + if (SvROK(sv) && sv_derived_from(sv, "Crypt::OpenSSL::Bignum")) { + return INT2PTR(Crypt__OpenSSL__Bignum, SvIV((SV*)SvRV(sv))); + } + else Perl_croak(aTHX_ "argument is not a Crypt::OpenSSL::Bignum object"); +} + +MODULE = Crypt::OpenSSL::Bignum PACKAGE = Crypt::OpenSSL::Bignum PREFIX = BN_ + +BOOT: +#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER) + OPENSSL_init_crypto(0, NULL); +#else + ERR_load_crypto_strings(); +#endif + +void +DESTROY(Crypt::OpenSSL::Bignum self) + CODE: + BN_clear_free( self ); + +Crypt::OpenSSL::Bignum +new_from_word(CLASS, p_word) + unsigned long p_word; + PREINIT: + BIGNUM* bn; + CODE: + checkOpenSslCall( bn = BN_new() ); + checkOpenSslCall( BN_set_word( bn, p_word ) ); + RETVAL = bn; + OUTPUT: + RETVAL + +Crypt::OpenSSL::Bignum +new_from_decimal(CLASS, p_dec_string) + char* p_dec_string; + PREINIT: + BIGNUM* bn; + CODE: + bn = NULL; + checkOpenSslCall( BN_dec2bn( &bn, p_dec_string ) ); + RETVAL = bn; + OUTPUT: + RETVAL + +Crypt::OpenSSL::Bignum +new_from_hex(CLASS, p_hex_string) + char* p_hex_string; + PREINIT: + BIGNUM* bn; + CODE: + bn = NULL; + checkOpenSslCall( BN_hex2bn( &bn, p_hex_string ) ); + RETVAL = bn; + OUTPUT: + RETVAL + +Crypt::OpenSSL::Bignum +new_from_bin(CLASS, p_bin_string_SV) + SV* p_bin_string_SV; + PREINIT: + BIGNUM* bn; + unsigned char* bin; + STRLEN bin_length; + CODE: + bin = (unsigned char*) SvPV( p_bin_string_SV, bin_length ); + checkOpenSslCall( bn = BN_bin2bn( bin, bin_length, NULL ) ); + RETVAL = bn; + OUTPUT: + RETVAL + +Crypt::OpenSSL::Bignum +BN_new(CLASS) + PREINIT: + BIGNUM* bn; + CODE: + checkOpenSslCall( bn = BN_new() ); + checkOpenSslCall( BN_set_word( bn, 0 ) ); + RETVAL = bn; + OUTPUT: + RETVAL + +Crypt::OpenSSL::Bignum +BN_zero(CLASS) + PREINIT: + BIGNUM *bn; + CODE: + checkOpenSslCall( bn = BN_new() ); + checkOpenSslCall( BN_set_word( bn, 0 ) ); + RETVAL = bn; + OUTPUT: + RETVAL + +Crypt::OpenSSL::Bignum +BN_one(CLASS) + PREINIT: + BIGNUM *bn; + CODE: + checkOpenSslCall( bn = BN_new() ); + checkOpenSslCall( BN_one( bn ) ); + RETVAL = bn; + OUTPUT: + RETVAL + +Crypt::OpenSSL::Bignum +BN_rand(CLASS, int bits, int top, int bottom) + PREINIT: + BIGNUM* bn; + CODE: + checkOpenSslCall( bn = BN_new() ); + checkOpenSslCall( BN_rand( bn, bits, top, bottom) ); + RETVAL = bn; + OUTPUT: + RETVAL + +Crypt::OpenSSL::Bignum +BN_pseudo_rand(CLASS, int bits, int top, int bottom) + PREINIT: + BIGNUM* bn; + CODE: + checkOpenSslCall( bn = BN_new() ); + checkOpenSslCall( BN_pseudo_rand( bn, bits, top, bottom) ); + RETVAL = bn; + OUTPUT: + RETVAL + +Crypt::OpenSSL::Bignum +BN_rand_range(CLASS, Crypt::OpenSSL::Bignum r) + PREINIT: + BIGNUM* bn; + CODE: + checkOpenSslCall( bn = BN_new() ); + checkOpenSslCall( BN_rand_range( bn, r) ); + RETVAL = bn; + OUTPUT: + RETVAL + +void +BN_bless_pointer(CLASS, void *pointer) + PPCODE: + ST(0) = new_obj(pointer); + XSRETURN(1); + +char* +BN_to_decimal(Crypt::OpenSSL::Bignum self) + CODE: + checkOpenSslCall( RETVAL = BN_bn2dec( self ) ); + OUTPUT: + RETVAL + CLEANUP: + OPENSSL_free( RETVAL ); + +char* +BN_to_hex(Crypt::OpenSSL::Bignum self) + CODE: + checkOpenSslCall( RETVAL = BN_bn2hex( self ) ); + OUTPUT: + RETVAL + CLEANUP: + OPENSSL_free( RETVAL ); + +SV* +BN_to_bin(Crypt::OpenSSL::Bignum self) + PREINIT: + unsigned char* bin; + int length; + CODE: + length = BN_num_bytes( self ); + if (length>0) { + RETVAL = NEWSV(0, length); + SvPOK_only(RETVAL); + SvCUR_set(RETVAL, length); + bin = (unsigned char *)SvPV_nolen(RETVAL); + BN_bn2bin( self, bin ); + } + else { + RETVAL = newSVpvn("", 0); + } + OUTPUT: + RETVAL + +unsigned long +BN_get_word(Crypt::OpenSSL::Bignum self) + +int +BN_is_zero(Crypt::OpenSSL::Bignum self) + +int +BN_is_one(Crypt::OpenSSL::Bignum self) + +int +BN_is_odd(Crypt::OpenSSL::Bignum self) + +void +BN_add(Crypt::OpenSSL::Bignum self, Crypt::OpenSSL::Bignum b, ...) + PREINIT: + BIGNUM *bn; + PPCODE: + if( items > 3 ) + croak( "usage: $bn->add( $bn2[, $target] )" ); + bn = ( items < 3 ) ? BN_new() : sv2bn( ST(2) ); + checkOpenSslCall( BN_add( bn, self, b ) ); + ST(0) = ( (items < 3 ) ? new_obj( bn ) : ST(2) ); + XSRETURN(1); + +void +BN_sub(Crypt::OpenSSL::Bignum self, Crypt::OpenSSL::Bignum b, ...) + PREINIT: + BIGNUM *bn; + PPCODE: + if( items > 3 ) + croak( "usage: $bn->sub( $bn2[, $target] )" ); + bn = ( items < 3 ) ? BN_new() : sv2bn( ST(2) ); + checkOpenSslCall( BN_sub( bn, self, b ) ); + ST(0) = ( (items < 3 ) ? new_obj( bn ) : ST(2) ); + XSRETURN(1); + +void +BN_mul(self, b, ctx, ...) + Crypt::OpenSSL::Bignum self; + Crypt::OpenSSL::Bignum b; + Crypt::OpenSSL::Bignum::CTX ctx; + PREINIT: + BIGNUM* bn; + PPCODE: + if( items > 4 ) + croak( "usage: $bn->mul( $bn2, $ctx, [, $target] )" ); + bn = ( items < 4 ) ? BN_new() : sv2bn( ST(3) ); + checkOpenSslCall( BN_mul( bn, self, b, ctx ) ); + ST(0) = ( (items < 4 ) ? new_obj( bn ) : ST(3) ); + XSRETURN(1); + +void +BN_div(self, b, ctx, ...) + Crypt::OpenSSL::Bignum self; + Crypt::OpenSSL::Bignum b; + Crypt::OpenSSL::Bignum::CTX ctx; + PREINIT: + BIGNUM* quotient; + BIGNUM* remainder; + PPCODE: + if( items > 5 ) + croak( "usage: $bn->div( $bn2, $ctx, [, $quotient [, $remainder ] ] )" ); + quotient = ( items < 4 ) ? BN_new() : sv2bn( ST(3) ); + remainder = ( items < 5 ) ? BN_new() : sv2bn( ST(4) ); + checkOpenSslCall( BN_div( quotient, remainder, self, b, ctx ) ); + ST(0) = ( (items < 4 ) ? new_obj( quotient ) : ST(3) ); + ST(1) = ( (items < 5 ) ? new_obj( remainder ) : ST(4) ); + XSRETURN(2); + +Crypt::OpenSSL::Bignum +BN_sqr(Crypt::OpenSSL::Bignum self, Crypt::OpenSSL::Bignum::CTX ctx) + PREINIT: + BIGNUM* bn; + CODE: + checkOpenSslCall( bn = BN_new() ); + checkOpenSslCall( BN_sqr( bn, self, ctx ) ); + RETVAL = bn; + OUTPUT: + RETVAL + +void +BN_mod(self, b, ctx, ...) + Crypt::OpenSSL::Bignum self; + Crypt::OpenSSL::Bignum b; + Crypt::OpenSSL::Bignum::CTX ctx; + PREINIT: + BIGNUM* bn; + PPCODE: + if( items > 4 ) + croak( "usage: $bn->mod( $bn2, $ctx, [, $target] )" ); + bn = ( items < 4 ) ? BN_new() : sv2bn( ST(3) ); + checkOpenSslCall( BN_mod( bn, self, b, ctx ) ); + ST(0) = ( (items < 4 ) ? new_obj( bn ) : ST(3) ); + XSRETURN(1); + +Crypt::OpenSSL::Bignum +BN_mod_mul(self, b, m, ctx) + Crypt::OpenSSL::Bignum self; + Crypt::OpenSSL::Bignum b; + Crypt::OpenSSL::Bignum m; + Crypt::OpenSSL::Bignum::CTX ctx; + PREINIT: + BIGNUM* bn; + CODE: + checkOpenSslCall( bn = BN_new() ); + checkOpenSslCall( BN_mod_mul( bn, self, b, m, ctx ) ); + RETVAL = bn; + OUTPUT: + RETVAL + +Crypt::OpenSSL::Bignum +BN_exp(self, exp, ctx) + Crypt::OpenSSL::Bignum self; + Crypt::OpenSSL::Bignum exp; + Crypt::OpenSSL::Bignum::CTX ctx; + PREINIT: + BIGNUM* bn; + CODE: + checkOpenSslCall( bn = BN_new() ); + checkOpenSslCall( BN_exp( bn, self, exp, ctx ) ); + RETVAL = bn; + OUTPUT: + RETVAL + +Crypt::OpenSSL::Bignum +BN_mod_exp(self, exp, mod, ctx) + Crypt::OpenSSL::Bignum self; + Crypt::OpenSSL::Bignum exp; + Crypt::OpenSSL::Bignum mod; + Crypt::OpenSSL::Bignum::CTX ctx; + PREINIT: + BIGNUM* bn; + CODE: + checkOpenSslCall( bn = BN_new() ); + checkOpenSslCall( BN_mod_exp( bn, self, exp, mod, ctx ) ); + RETVAL = bn; + OUTPUT: + RETVAL + +Crypt::OpenSSL::Bignum +BN_mod_inverse(self, n, ctx) + Crypt::OpenSSL::Bignum self; + Crypt::OpenSSL::Bignum n; + Crypt::OpenSSL::Bignum::CTX ctx; + PREINIT: + BIGNUM* bn; + CODE: + checkOpenSslCall( bn = BN_new() ); + checkOpenSslCall( BN_mod_inverse( bn, self, n, ctx ) ); + RETVAL = bn; + OUTPUT: + RETVAL + +Crypt::OpenSSL::Bignum +BN_gcd(self, b, ctx) + Crypt::OpenSSL::Bignum self; + Crypt::OpenSSL::Bignum b; + Crypt::OpenSSL::Bignum::CTX ctx; + PREINIT: + BIGNUM* bn; + CODE: + checkOpenSslCall( bn = BN_new() ); + checkOpenSslCall( BN_gcd( bn, self, b, ctx ) ); + RETVAL = bn; + OUTPUT: + RETVAL + +int +BN_equals(Crypt::OpenSSL::Bignum self, Crypt::OpenSSL::Bignum b) + CODE: + RETVAL = BN_cmp(self, b) == 0 ? 1 : 0; + OUTPUT: + RETVAL + +int +BN_cmp(Crypt::OpenSSL::Bignum self, Crypt::OpenSSL::Bignum b) + +int +BN_num_bits(Crypt::OpenSSL::Bignum self) + +int +BN_num_bytes(Crypt::OpenSSL::Bignum self) + +Crypt::OpenSSL::Bignum +BN_rshift(Crypt::OpenSSL::Bignum self, int n) + PREINIT: + BIGNUM* bn; + CODE: + checkOpenSslCall( bn = BN_new() ); + checkOpenSslCall( BN_rshift( bn, self, n ) ); + RETVAL = bn; + OUTPUT: + RETVAL + +Crypt::OpenSSL::Bignum +BN_lshift(Crypt::OpenSSL::Bignum self, int n) + PREINIT: + BIGNUM* bn; + CODE: + checkOpenSslCall( bn = BN_new() ); + checkOpenSslCall( BN_lshift( bn, self, n ) ); + RETVAL = bn; + OUTPUT: + RETVAL + +int +BN_ucmp(Crypt::OpenSSL::Bignum self, Crypt::OpenSSL::Bignum b) + +void +BN_swap(Crypt::OpenSSL::Bignum self, Crypt::OpenSSL::Bignum b) + +Crypt::OpenSSL::Bignum +BN_copy(Crypt::OpenSSL::Bignum self) + CODE: + checkOpenSslCall( RETVAL = BN_dup(self) ); + OUTPUT: + RETVAL + +IV +BN_pointer_copy(Crypt::OpenSSL::Bignum self) + CODE: + checkOpenSslCall( RETVAL = PTR2IV(BN_dup(self)) ); + OUTPUT: + RETVAL + +MODULE = Crypt::OpenSSL::Bignum PACKAGE = Crypt::OpenSSL::Bignum::CTX + +Crypt::OpenSSL::Bignum::CTX +new(CLASS) + CODE: + RETVAL = BN_CTX_new(); + OUTPUT: + RETVAL + +void +DESTROY(Crypt::OpenSSL::Bignum::CTX self) + CODE: + BN_CTX_free(self); diff --git a/Bignum/CTX.pm b/Bignum/CTX.pm new file mode 100755 index 0000000..039af4b --- /dev/null +++ b/Bignum/CTX.pm @@ -0,0 +1,41 @@ +package Crypt::OpenSSL::Bignum::CTX; + +use 5.005; +use strict; +use Carp; + +use Crypt::OpenSSL::Bignum; +use vars qw( @ISA ); + +require DynaLoader; + +use base qw(DynaLoader); + +bootstrap Crypt::OpenSSL::Bignum $Crypt::OpenSSL::Bignum::VERSION; + +1; +__END__ +# Below is stub documentation for your module. You better edit it! + +=head1 NAME + +Crypt::OpenSSL::Bignum::CTX - Perl interface to the OpenSSL BN_CTX structure. + +=head1 SYNOPSIS + + use Crypt::OpenSSL::Bignum::CTX; + my $bn_ctx = Crypt::OpenSSL::Bignum::CTX->new(); + +=head1 DESCRIPTION + +See the man page for Crypt::OpenSSL::Bignum. + +=head1 AUTHOR + +Ian Robertson, iroberts@cpan.org + +=head1 SEE ALSO + +L, L, L + +=cut diff --git a/Changes b/Changes new file mode 100755 index 0000000..0e89f02 --- /dev/null +++ b/Changes @@ -0,0 +1,42 @@ +Revision history for Perl extension Crypt::OpenSSL::Bignum. + +0.09 2017/12/01 + - fix #4 License is not specified in metadata + - fix #6 Strip \n and \r out of $lib and $inc + - fix #7 Fix building with OpenSSL 1.1.0 + +0.08 2017/02/08 + - Makefile.PL MSWin32 fix + +0.07 2016/10/25 + - Makefile.PL supports OPENSSL_PREFIX or OPENSSL_LIB+OPENSSL_INCLUDE env variables + - Makefile.PL tries to find libcrypto via pkg-config + +0.06 2015/02/06 + - fix for #77911 Patch to add more functions + - new constructors: new, rand, pseudo_rand, rand_range + - new methods: ucmp, num_bits, num_bytes, rshift, lshift, swap + - improved pod documentation (added missing functions) + - XS code cleanup + +0.05 2015/02/04 + - fix for #84369 Win32 compatibility patch + - fix for #100993 Memory not reclaimed when CTX object goes out of scope + - fix for #86561 typo fixes + - fix for #82959 Error in synopsis: Crypt::OpenSSL::Bignum->new_from_hex("0x3e8") returns "0" + - fix for #81537 to_bin method returns garbage when value is zero + +0.04 2007/05/20 + - Add a LICENSE file. + - Add -DOPENSSL_NO_KRB5 to DEFINE to keep redhat happy. + +0.03 2003/04/27 + - Revert back to old declaration style so that we no longer + break under perl 5.005 (spotted by Rob Brown ). + +0.02 2003/02/21 + - link against libcrypto instead of libssl + - more documentation + +0.01 2003/02/17 + - original version diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000..05e86e0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,378 @@ + +Terms of Perl itself + +a) the GNU General Public License as published by the Free + Software Foundation; either version 1, or (at your option) any + later version, or +b) the "Artistic License" + +---------------------------------------------------------------------------- + +The General Public License (GPL) +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, +Cambridge, MA 02139, USA. Everyone is permitted to copy and distribute +verbatim copies of this license document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public License is intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. This General Public License applies to most of +the Free Software Foundation's software and to any other program whose +authors commit to using it. (Some other Free Software Foundation software is +covered by the GNU Library General Public License instead.) You can apply it to +your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our +General Public Licenses are designed to make sure that you have the freedom +to distribute copies of free software (and charge for this service if you wish), that +you receive source code or can get it if you want it, that you can change the +software or use pieces of it in new free programs; and that you know you can do +these things. + +To protect your rights, we need to make restrictions that forbid anyone to deny +you these rights or to ask you to surrender the rights. These restrictions +translate to certain responsibilities for you if you distribute copies of the +software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for a +fee, you must give the recipients all the rights that you have. You must make +sure that they, too, receive or can get the source code. And you must show +them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) offer +you this license which gives you legal permission to copy, distribute and/or +modify the software. + +Also, for each author's protection and ours, we want to make certain that +everyone understands that there is no warranty for this free software. If the +software is modified by someone else and passed on, we want its recipients to +know that what they have is not the original, so that any problems introduced by +others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We wish +to avoid the danger that redistributors of a free program will individually obtain +patent licenses, in effect making the program proprietary. To prevent this, we +have made it clear that any patent must be licensed for everyone's free use or +not licensed at all. + +The precise terms and conditions for copying, distribution and modification +follow. + +GNU GENERAL PUBLIC LICENSE +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND +MODIFICATION + +0. This License applies to any program or other work which contains a notice +placed by the copyright holder saying it may be distributed under the terms of +this General Public License. The "Program", below, refers to any such program +or work, and a "work based on the Program" means either the Program or any +derivative work under copyright law: that is to say, a work containing the +Program or a portion of it, either verbatim or with modifications and/or translated +into another language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not covered by +this License; they are outside its scope. The act of running the Program is not +restricted, and the output from the Program is covered only if its contents +constitute a work based on the Program (independent of having been made by +running the Program). Whether that is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source code as +you receive it, in any medium, provided that you conspicuously and appropriately +publish on each copy an appropriate copyright notice and disclaimer of warranty; +keep intact all the notices that refer to this License and to the absence of any +warranty; and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you may at +your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, thus +forming a work based on the Program, and copy and distribute such +modifications or work under the terms of Section 1 above, provided that you also +meet all of these conditions: + +a) You must cause the modified files to carry prominent notices stating that you +changed the files and the date of any change. + +b) You must cause any work that you distribute or publish, that in whole or in +part contains or is derived from the Program or any part thereof, to be licensed +as a whole at no charge to all third parties under the terms of this License. + +c) If the modified program normally reads commands interactively when run, you +must cause it, when started running for such interactive use in the most ordinary +way, to print or display an announcement including an appropriate copyright +notice and a notice that there is no warranty (or else, saying that you provide a +warranty) and that users may redistribute the program under these conditions, +and telling the user how to view a copy of this License. (Exception: if the +Program itself is interactive but does not normally print such an announcement, +your work based on the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Program, and can be reasonably +considered independent and separate works in themselves, then this License, +and its terms, do not apply to those sections when you distribute them as +separate works. But when you distribute the same sections as part of a whole +which is a work based on the Program, the distribution of the whole must be on +the terms of this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest your rights to +work written entirely by you; rather, the intent is to exercise the right to control +the distribution of derivative or collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program with the +Program (or with a work based on the Program) on a volume of a storage or +distribution medium does not bring the other work under the scope of this +License. + +3. You may copy and distribute the Program (or a work based on it, under +Section 2) in object code or executable form under the terms of Sections 1 and 2 +above provided that you also do one of the following: + +a) Accompany it with the complete corresponding machine-readable source +code, which must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange; or, + +b) Accompany it with a written offer, valid for at least three years, to give any +third party, for a charge no more than your cost of physically performing source +distribution, a complete machine-readable copy of the corresponding source +code, to be distributed under the terms of Sections 1 and 2 above on a medium +customarily used for software interchange; or, + +c) Accompany it with the information you received as to the offer to distribute +corresponding source code. (This alternative is allowed only for noncommercial +distribution and only if you received the program in object code or executable +form with such an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for making +modifications to it. For an executable work, complete source code means all the +source code for all modules it contains, plus any associated interface definition +files, plus the scripts used to control compilation and installation of the +executable. However, as a special exception, the source code distributed need +not include anything that is normally distributed (in either source or binary form) +with the major components (compiler, kernel, and so on) of the operating system +on which the executable runs, unless that component itself accompanies the +executable. + +If distribution of executable or object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the source +code from the same place counts as distribution of the source code, even though +third parties are not compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as +expressly provided under this License. Any attempt otherwise to copy, modify, +sublicense or distribute the Program is void, and will automatically terminate +your rights under this License. However, parties who have received copies, or +rights, from you under this License will not have their licenses terminated so long +as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed it. +However, nothing else grants you permission to modify or distribute the Program +or its derivative works. These actions are prohibited by law if you do not accept +this License. Therefore, by modifying or distributing the Program (or any work +based on the Program), you indicate your acceptance of this License to do so, +and all its terms and conditions for copying, distributing or modifying the +Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), +the recipient automatically receives a license from the original licensor to copy, +distribute or modify the Program subject to these terms and conditions. You +may not impose any further restrictions on the recipients' exercise of the rights +granted herein. You are not responsible for enforcing compliance by third parties +to this License. + +7. If, as a consequence of a court judgment or allegation of patent infringement +or for any other reason (not limited to patent issues), conditions are imposed on +you (whether by court order, agreement or otherwise) that contradict the +conditions of this License, they do not excuse you from the conditions of this +License. If you cannot distribute so as to satisfy simultaneously your obligations +under this License and any other pertinent obligations, then as a consequence +you may not distribute the Program at all. For example, if a patent license would +not permit royalty-free redistribution of the Program by all those who receive +copies directly or indirectly through you, then the only way you could satisfy +both it and this License would be to refrain entirely from distribution of the +Program. + +If any portion of this section is held invalid or unenforceable under any particular +circumstance, the balance of the section is intended to apply and the section as +a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents or other +property right claims or to contest validity of any such claims; this section has +the sole purpose of protecting the integrity of the free software distribution +system, which is implemented by public license practices. Many people have +made generous contributions to the wide range of software distributed through +that system in reliance on consistent application of that system; it is up to the +author/donor to decide if he or she is willing to distribute software through any +other system and a licensee cannot impose that choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain countries +either by patents or by copyrighted interfaces, the original copyright holder who +places the Program under this License may add an explicit geographical +distribution limitation excluding those countries, so that distribution is permitted +only in or among countries not thus excluded. In such case, this License +incorporates the limitation as if written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new versions of the +General Public License from time to time. Such new versions will be similar in +spirit to the present version, but may differ in detail to address new problems or +concerns. + +Each version is given a distinguishing version number. If the Program specifies a +version number of this License which applies to it and "any later version", you +have the option of following the terms and conditions either of that version or of +any later version published by the Free Software Foundation. If the Program does +not specify a version number of this License, you may choose any version ever +published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs +whose distribution conditions are different, write to the author to ask for +permission. For software which is copyrighted by the Free Software Foundation, +write to the Free Software Foundation; we sometimes make exceptions for this. +Our decision will be guided by the two goals of preserving the free status of all +derivatives of our free software and of promoting the sharing and reuse of +software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS +NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE +COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM +"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR +IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE +ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, +YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR +CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED +TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY +WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS +PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES +ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM +(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY +OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS +BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS + + +---------------------------------------------------------------------------- + +The Artistic License + +Preamble + +The intent of this document is to state the conditions under which a Package +may be copied, such that the Copyright Holder maintains some semblance of +artistic control over the development of the package, while giving the users of the +package the right to use and distribute the Package in a more-or-less customary +fashion, plus the right to make reasonable modifications. + +Definitions: + +- "Package" refers to the collection of files distributed by the Copyright + Holder, and derivatives of that collection of files created through textual + modification. +- "Standard Version" refers to such a Package if it has not been modified, + or has been modified in accordance with the wishes of the Copyright + Holder. +- "Copyright Holder" is whoever is named in the copyright or copyrights for + the package. +- "You" is you, if you're thinking about copying or distributing this Package. +- "Reasonable copying fee" is whatever you can justify on the basis of + media cost, duplication charges, time of people involved, and so on. (You + will not be required to justify it to the Copyright Holder, but only to the + computing community at large as a market that must bear the fee.) +- "Freely Available" means that no fee is charged for the item itself, though + there may be fees involved in handling the item. It also means that + recipients of the item may redistribute it under the same conditions they + received it. + +1. You may make and give away verbatim copies of the source form of the +Standard Version of this Package without restriction, provided that you duplicate +all of the original copyright notices and associated disclaimers. + +2. You may apply bug fixes, portability fixes and other modifications derived from +the Public Domain or from the Copyright Holder. A Package modified in such a +way shall still be considered the Standard Version. + +3. You may otherwise modify your copy of this Package in any way, provided +that you insert a prominent notice in each changed file stating how and when +you changed that file, and provided that you do at least ONE of the following: + + a) place your modifications in the Public Domain or otherwise + make them Freely Available, such as by posting said modifications + to Usenet or an equivalent medium, or placing the modifications on + a major archive site such as ftp.uu.net, or by allowing the + Copyright Holder to include your modifications in the Standard + Version of the Package. + + b) use the modified Package only within your corporation or + organization. + + c) rename any non-standard executables so the names do not + conflict with standard executables, which must also be provided, + and provide a separate manual page for each non-standard + executable that clearly documents how it differs from the Standard + Version. + + d) make other distribution arrangements with the Copyright Holder. + +4. You may distribute the programs of this Package in object code or executable +form, provided that you do at least ONE of the following: + + a) distribute a Standard Version of the executables and library + files, together with instructions (in the manual page or equivalent) + on where to get the Standard Version. + + b) accompany the distribution with the machine-readable source of + the Package with your modifications. + + c) accompany any non-standard executables with their + corresponding Standard Version executables, giving the + non-standard executables non-standard names, and clearly + documenting the differences in manual pages (or equivalent), + together with instructions on where to get the Standard Version. + + d) make other distribution arrangements with the Copyright Holder. + +5. You may charge a reasonable copying fee for any distribution of this Package. +You may charge any fee you choose for support of this Package. You may not +charge a fee for this Package itself. However, you may distribute this Package in +aggregate with other (possibly commercial) programs as part of a larger +(possibly commercial) software distribution provided that you do not advertise +this Package as a product of your own. + +6. The scripts and library files supplied as input to or produced as output from +the programs of this Package do not automatically fall under the copyright of this +Package, but belong to whomever generated them, and may be sold +commercially, and may be aggregated with this Package. + +7. C or perl subroutines supplied by you and linked into this Package shall not +be considered part of this Package. + +8. The name of the Copyright Holder may not be used to endorse or promote +products derived from this software without specific prior written permission. + +9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR +PURPOSE. + +The End + + diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..51eb8a6 --- /dev/null +++ b/MANIFEST @@ -0,0 +1,12 @@ +Bignum.pm +Bignum.xs +Bignum/CTX.pm +Changes +LICENSE +Makefile.PL +MANIFEST +META.yml Module meta-data (added by MakeMaker) +README +test.pl +typemap +META.json Module JSON meta-data (added by MakeMaker) diff --git a/META.json b/META.json new file mode 100644 index 0000000..47518f3 --- /dev/null +++ b/META.json @@ -0,0 +1,47 @@ +{ + "abstract" : "OpenSSL's multiprecision integer arithmetic", + "author" : [ + "Ian Robertson " + ], + "dynamic_config" : 1, + "generated_by" : "ExtUtils::MakeMaker version 7.3, CPAN::Meta::Converter version 2.150010", + "license" : [ + "perl_5" + ], + "meta-spec" : { + "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", + "version" : 2 + }, + "name" : "Crypt-OpenSSL-Bignum", + "no_index" : { + "directory" : [ + "t", + "inc" + ] + }, + "prereqs" : { + "build" : { + "requires" : { + "ExtUtils::MakeMaker" : "0" + } + }, + "configure" : { + "requires" : { + "ExtUtils::MakeMaker" : "0" + } + }, + "runtime" : { + "requires" : { + "perl" : "5.006002" + } + } + }, + "release_status" : "stable", + "resources" : { + "repository" : { + "url" : "https://github.com/kmx/perl-Crypt-OpenSSL-Bignum" + } + }, + "version" : "0.09", + "x_serialization_backend" : "JSON::PP version 2.94" +} diff --git a/META.yml b/META.yml new file mode 100644 index 0000000..24d7da0 --- /dev/null +++ b/META.yml @@ -0,0 +1,25 @@ +--- +abstract: "OpenSSL's multiprecision integer arithmetic" +author: + - 'Ian Robertson ' +build_requires: + ExtUtils::MakeMaker: '0' +configure_requires: + ExtUtils::MakeMaker: '0' +dynamic_config: 1 +generated_by: 'ExtUtils::MakeMaker version 7.3, CPAN::Meta::Converter version 2.150010' +license: perl +meta-spec: + url: http://module-build.sourceforge.net/META-spec-v1.4.html + version: '1.4' +name: Crypt-OpenSSL-Bignum +no_index: + directory: + - t + - inc +requires: + perl: '5.006002' +resources: + repository: https://github.com/kmx/perl-Crypt-OpenSSL-Bignum +version: '0.09' +x_serialization_backend: 'CPAN::Meta::YAML version 0.018' diff --git a/Makefile.PL b/Makefile.PL new file mode 100755 index 0000000..46380cf --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,45 @@ +use ExtUtils::MakeMaker; +use Config; + +my $lib = '-lcrypto'; +my $inc = ''; +my $nul = $^O eq 'MSWin32' ? 'nul' : '/dev/null'; +if (my $dir = $ENV{OPENSSL_PREFIX}) { + $lib = "-L$dir/lib -lcrypto"; + $inc = "-I$dir/include"; +} +elsif ($ENV{OPENSSL_LIB}) { + $lib = $ENV{OPENSSL_LIB}; + $inc = $ENV{OPENSSL_INCLUDE}; +} +elsif (`pkg-config --modversion libcrypto 2>$nul`) { + $lib = `pkg-config --libs libcrypto 2> $nul`; + $inc = `pkg-config --cflags libcrypto 2> $nul`; +} +elsif ($^O eq 'MSWin32') { + $lib = '-llibeay32' if $Config{cc} =~ /cl/; + $lib = '-leay32' if $Config{cc} =~ /gcc/; +} + +$lib =~ s/[\r\n]+/ /g; +$inc =~ s/[\r\n]+/ /g; + +WriteMakefile( + 'NAME' => 'Crypt::OpenSSL::Bignum', + 'VERSION_FROM' => 'Bignum.pm', + 'PREREQ_PM' => {}, + 'ABSTRACT_FROM' => 'Bignum.pm', # retrieve abstract from module + 'AUTHOR' => 'Ian Robertson ', + 'LICENSE' => 'perl', + 'LIBS' => [ $lib ], + 'DEFINE' => '-DPERL5 -DOPENSSL_NO_KRB5', + # perl-5.8/gcc-3.2 needs -DPERL5, and redhat9 likes -DOPENSSL_NO_KRB5 + 'INC' => $inc, + 'MIN_PERL_VERSION' => '5.006002', + 'META_MERGE' => { + resources => { + repository => 'https://github.com/kmx/perl-Crypt-OpenSSL-Bignum', + }, + }, + dist => { TARFLAGS => '--owner=0 --group=0 -cvf' }, +); diff --git a/README b/README new file mode 100755 index 0000000..b6d2e5f --- /dev/null +++ b/README @@ -0,0 +1,11 @@ +Crypt::OpenSSL::Bignum is an XS perl module designed to provide basic +access to the OpenSSL multiprecision integer arithmetic libraries. +Presently, many though not all of the arithmetic operations that +OpenSSL provides are exposed to perl. In addition, this module can be +used to provide access to bignum values produced by other OpenSSL +modules, such as key parameters from Crypt::OpenSSL::RSA. This module +requires that the OpenSSL libraries and header files be installed. + +Copyright (c) 2003 Ian Robertson. Crypt::OpenSSL::Bignum is free +software; you may redistribute it and/or modify it under the same +terms as Perl itself. diff --git a/test.pl b/test.pl new file mode 100755 index 0000000..5922973 --- /dev/null +++ b/test.pl @@ -0,0 +1,153 @@ +# Before `make install' is performed this script should be runnable with +# `make test'. After `make install' it should work as `perl test.pl' + +######################### + +# change 'tests => 1' to 'tests => last_test_to_print'; + +use Test; +BEGIN { plan tests => 67 }; +use Crypt::OpenSSL::Bignum; +use Crypt::OpenSSL::Bignum::CTX; + +######################### + +# Insert your test code below, the Test module is use()ed here so read +# its man page ( perldoc Test ) for help writing this test script. + +use strict; + +sub _new_bn +{ + return Crypt::OpenSSL::Bignum->new_from_word( shift ); +} + +my $bn; +my $decimal_string = "2342234235235235235"; +$bn = Crypt::OpenSSL::Bignum->new_from_decimal( $decimal_string ); +ok( $bn ); +ok( $bn->to_decimal() eq $decimal_string ); + +my $hex_string = "7f"; +$bn = Crypt::OpenSSL::Bignum->new_from_hex( $hex_string ); +ok( $bn ); +ok( $bn->to_hex() eq uc( $hex_string ) ); +ok( $bn->to_decimal() eq '127' ); + +my $bin_string = pack( "C*", 2, 0 ); +$bn = Crypt::OpenSSL::Bignum->new_from_bin( $bin_string ); +ok( $bn ); +ok( $bn->to_bin() eq $bin_string ); +ok( $bn->to_decimal() eq '512' ); + +my $bn23 = _new_bn( 23 ); +my $bn25 = _new_bn( 25 ); + +ok( $bn23->cmp($ bn25 ) == -1 ); +ok( $bn25->cmp( $bn23 ) == 1 ); +ok( $bn23->cmp( $bn23 ) == 0 ); +ok( $bn23->equals( $bn23 ) ); + +my $bn_copy = $bn->copy(); +ok( $bn_copy ne $bn ); +ok( $bn->equals( $bn_copy ) ); + +my $ptr = $bn->pointer_copy(); +ok( ! ref $ptr ); +ok( $bn + 0 != $ptr ); +my $from_ptr = Crypt::OpenSSL::Bignum->bless_pointer( $ptr ); +ok( $bn->equals( $from_ptr ) ); + + +my $zero = Crypt::OpenSSL::Bignum->zero(); +my $one = Crypt::OpenSSL::Bignum->one(); + +ok( $one->is_one() ); +ok( !$zero->is_one() ); + +ok( $zero->is_zero() ); +ok( !$one->is_zero() ); + +ok( !$zero->is_odd() ); +ok( $one->is_odd() ); + +my $word = 0xffffeeee; +ok( _new_bn($word)->get_word() == $word ); + +# test creation from object rather than class string. +my $bn2 = $bn->new_from_bin( $bin_string ); +ok( $bn2 ); +ok( $bn2->to_bin() eq $bn->to_bin() ); + +ok( '48' eq $bn23->add( $bn25 )->to_decimal() ); +$bn = _new_bn( 18 ); +$bn->add( $one, $bn ); +ok( 19 == $bn->get_word() ); + +ok( '-2' eq $bn23->sub( $bn25 )->to_decimal() ); +$bn = _new_bn( 18 ); +$bn->sub( $one, $bn ); +ok( 17 == $bn->get_word() ); + +my $ctx = Crypt::OpenSSL::Bignum::CTX->new(); + +ok( $ctx ); +ok( 575 == $bn23->mul( $bn25, $ctx )->get_word() ); +ok( 575 == $bn23->mul( $bn25, $ctx, $bn )->get_word() ); +ok( 575 == $bn->get_word() ); + +ok( 2 == $bn25->mod( $bn23, $ctx )->get_word() ); +ok( 2 == $bn25->mod( $bn23, $ctx, $bn )->get_word() ); +ok( 2 == $bn->get_word() ); + +my $bn6 = _new_bn( 6 ); +my $bn3 = _new_bn( 3 ); + +my( $quotient, $remainder ) = $bn25->div( $bn23, $ctx ); +ok( $quotient->is_one ); +ok( 2 == $remainder->get_word() ); +my( $quotient2, $remainder2 ) = + $bn25->div( $bn6, $ctx, $quotient, $remainder ); +ok( $quotient2 == $quotient ); +ok( $remainder2 == $remainder ); +ok( 4 == $quotient->get_word() ); +ok( $remainder->is_one ); +my( $quotient3, $remainder3 ) = + $bn25->div( $bn6, $ctx, $quotient ); +ok( $quotient3 == $quotient ); +ok( 4 == $quotient->get_word() ); +ok( $remainder3->is_one() ); + +ok( 6 == _new_bn( 18 )->gcd( _new_bn( 42 ), $ctx )->get_word() ); +ok( 5 == $bn23->mod_mul( $bn25, $bn6, $ctx )->get_word() ); +ok( 729 == $bn3->exp( $bn6, $ctx )->get_word() ); +ok( 4 == $bn3->mod_exp( $bn6, $bn25, $ctx )->get_word() ); +ok( 36 == $bn6->sqr( $ctx )->get_word() ); +ok( 12 == $bn23->mod_inverse( $bn25, $ctx )->get_word() ); + +ok(Crypt::OpenSSL::Bignum->new()->get_word == 0); +ok(Crypt::OpenSSL::Bignum->rand(32, 0, 0)); +ok(Crypt::OpenSSL::Bignum->pseudo_rand(32, 0, 0)); +my $range = Crypt::OpenSSL::Bignum->new_from_decimal('1000'); +ok(Crypt::OpenSSL::Bignum->rand_range($range)); + +my $d1010 = Crypt::OpenSSL::Bignum->new_from_decimal('1020'); +my $w1010 = Crypt::OpenSSL::Bignum->new_from_word(1020); +ok($w1010->equals($d1010)); +ok($d1010->num_bits() == 10); +ok($d1010->num_bytes() == 2); +ok($d1010->rshift(2)->get_word == 1020/4); +ok($d1010->lshift(2)->get_word == 1020*4); + +my $n1 = Crypt::OpenSSL::Bignum->new_from_decimal('-250'); +my $n2 = Crypt::OpenSSL::Bignum->new_from_decimal('250'); +ok($n1->cmp($n2) == -1); +ok($n1->ucmp($n2) == 0); + +my $one = Crypt::OpenSSL::Bignum->one; +my $zero = Crypt::OpenSSL::Bignum->zero; +ok($one->to_decimal eq "1"); +ok($zero->to_decimal eq "0"); +$one->swap($zero); +ok($one->to_decimal eq "0"); +ok($zero->to_decimal eq "1"); diff --git a/typemap b/typemap new file mode 100755 index 0000000..9040d9a --- /dev/null +++ b/typemap @@ -0,0 +1,3 @@ +TYPEMAP +Crypt::OpenSSL::Bignum T_PTROBJ +Crypt::OpenSSL::Bignum::CTX T_PTROBJ