=head1 NAME

Crypt::PBC - OO interface for the Stanford PBC library

=head1 SYNOPSIS

    use Crypt::PBC;

    my $pairing = new Crypt::PBC("params_d.txt");
    my $G1      = $pairing->init_G1->random;
    my $G2      = $pairing->init_G2->random->double->square;
    my $GT      = $pairing->init_GT->pairing_apply( $G1, $G2 );


=head1 "Chapter 1. Overview"

The following text is the Overview chapter from the PBC library
documentation:

    The PBC library is a free portable C library designed to make it
    easy to implement pairing-based cryptosystems. It provides an
    abstract interface to a cyclic group with a bilinear pairing, and
    the programmer does not need to worry about, or even know about
    elliptic curves.

    It is built on top of GMP, another C library which performs
    arbitrary precision arithmetic on integers, rationals and floats
    with strong emphasis on portability and speed.

    The PBC library homepage: http://crypto.stanford.edu/pbc/

    The GMP library homepage: http://www.swox.com/gmp/

=head1 Nomenclature

The documentation (and error messages) for these modules frequently refer to
the LHS, the RHS, EXPO, and BASE.  They are the left hand side, right hand
side, exponent and base.  In an algebraic equation: LHS=RHS and LHS=BASE^EXPO.
In other words, the LHS is the element to which a value is being assigned.
There may sometimes be more than one RHS, or it might be called the a1 or n1;
but, there will only be one LHS.

=head1 Perl Module Methods

The Perl Module methods implement an OO interface that the author (Paul) highly
recommends using.  The only Perl Module OO function in the L<Crypt::PBC>
package is C<new()>.  Please see L<Crypt::PBC::Pairing> and
L<Crypt::PBC::Element> for the guts of the intended OO interface.

=head2 Crypt::PBC::new()

Returns a new PBC pairing object.  C<new()> takes, as arguments, either the
name of a file, a file stream (e.g., new C<Crypt::PBC(\*STDIN)>), or the params
for a curve as a string.  Ben Lynn provides a zip file of d-type curves:

    MNT curve parameters for embedding degree 6 (which I
    call type D curves), for all D less than a million, and
    for subgroup sizes at least 80 bits and less than 300
    bits long. Generated using test programs bundled with
    PBC library.

    http://crypto.stanford.edu/pbc/download.html

=head1 XS Loaded Functions

This section is basically a listing of the PBC functions as they are
imported.  You can use them directly if you're already comfortable with the
layout of PBC.  If you're starting from scratch and aren't much of a C
coder, you'll have an easier time using the Perl Module methods because
they implement a little type-safety to protect perl coders from segfaults.

Mixing and matching direct calls with the Perl Module methods is a sure way
to run into trouble, since the Perl Module methods tag the PBC elements
with a type.

=head2 Pairing Functions

(You can use these functions successfully, but the intended interface was
described above. L<Crypt::PBC::Element> describes that interface in detail.)

    # Initialize a pairing from a a $string
    my $pairing = Crypt::PBC::pairing_init_str($string);

    # Clear the memory malloced for the pairing
    Crypt::PBC::pairing_clear($pairing);

    # Apply the pairing.  Be careful here.  If you pass the wrong type of
    # elements, GT = apply(G1, G2), this will segmentation fault!  Please
    # see the PBC documentation for further information:
    #   http://crypto.stanford.edu/pbc/manual/
    Crypt::PBC::pairing_apply($LHS, $RHS1, $RHS2, $pairing);

=head2 Element Initializer and Assignment Functions

(You can use these functions successfully, but the intended interface was
described above. L<Crypt::PBC::Element> describes that interface in detail.)

    my $element_in_G1 = Crypt::PBC::element_init_G1($pairing);
    my $element_in_G2 = Crypt::PBC::element_init_G2($pairing);
    my $element_in_GT = Crypt::PBC::element_init_GT($pairing);
    my $element_in_Zr = Crypt::PBC::element_init_Zr($pairing);

    # Do not forget to clear your memory!
    Crypt::PBC::element_clear( $element ); # in any group

    # assign some random to $element
    # (uses /dev/urandom if possible, or rand() if necessary)
    Crypt::PBC::element_random( $element );
    Crypt::PBC::element_set0( $element ); # set to 0
    Crypt::PBC::element_set1( $element ); # set to 1
    Crypt::PBC::element_set( $a, $b );    # a=b
    Crypt::PBC::element_set_si( $a, 5 );  # a=5

    Crypt::PBC::element_set_mpz( $a, $bigint ); 
      # For this one, construct a Math::BigInt::GMP and pass that for
      # $bigint. Alternatively, you can construct a $i=Math::BigInt and
      # pass the $i->{value}.  (That interface is probably not well
      # supported but is the only one of which the author is aware.)

    Crypt::PBC::element_from_hash( $element, $hash ); 
      # Set $element based on the bytes in $hash.  You must use some kind
      # of hashing algorithm (e.g., Digest::SHA1) to map data to an
      # element:
      #
      # "In general you cannot feed it plaintext. You should only give it
      # short strings of bytes (e.g. 160 bits if G1 has order around 2^160,
      # which is the case for most of the bundled pairing parameters)."
      # -- Lynn

    Crypt::PBC::element_from_bytes( $element, $bytes ); 
      # Set $element based on the bytes in $bytes.  this probably isn't useful
      # unless $bytes is like $spewed_result from element_export() below.

=head2 Arithmetic Functions

(You can use these functions successfully, but the intended interface was
described above. L<Crypt::PBC::Element> describes that interface in detail.)

    # lhs=rhs1+rhs2 -- make sure these are all the same type ...
    Crypt::PBC::element_add($lhs, $rhs1, $rhs2);
    Crypt::PBC::element_sub($lhs, $rhs1, $rhs2); # lhs=rhs1-rhs2
    Crypt::PBC::element_mul($lhs, $rhs1, $rhs2);
    Crypt::PBC::element_div($lhs, $rhs1, $rhs2);

    # (whatever these mean is in the context of the $pairing)
    Crypt::PBC::element_double($lhs, $rhs); # lhs = 2*rhs 
    Crypt::PBC::element_halve( $lhs, $rhs); # lhs = rhs/2
    Crypt::PBC::element_square($lhs, $rhs); # lhs = rhs^2
    Crypt::PBC::element_neg(   $lhs, $rhs); # (please see the PBC docs)
    Crypt::PBC::element_invert($lhs, $rhs); # lhs = 1/rhs

    # Here's a few other choices for mul
    Crypt::PBC::element_mul_zn( $lhs, $rhs1, $rhs2 );
      # $rhs1 and $lhs should be of the same type, but here $rhs2 should be
      # in Zr instead of being in the same group like in element_mul()
      # above 

    Crypt::PBC::element_mul_mpz( $lhs, $rhs1, $rhs2 );
      # For this one, construct a Math::BigInt::GMP and pass that for
      # $rhs2 or pass $i->{value} from a Math::BigInt.

    Crypt::PBC::element_mul_si( $lhs, $rhs1, $rhs2 );
      # Here, $rhs2 is a regular old integer...

    Crypt::PBC::element_pow_zn( $lhs, $a, $n); # lhs = a^n
    Crypt::PBC::element_pow2_zn($lhs, $a1, $n1, $a2, $n2); # a1^n1 * a2^n2
    Crypt::PBC::element_pow3_zn($lhs, $a1, $n1, $a2, $n2, $a3, $n3);
      # in the above, the lhs and a\d+ should be in the same group, n\d+ in Zr

    Crypt::PBC::element_pow_mpz( $lhs, $a, $n);
    Crypt::PBC::element_pow2_mpz($lhs, $a1, $n1, $a2, $n2);
    Crypt::PBC::element_pow3_mpz($lhs, $a1, $n1, $a2, $n2, $a3, $n3);
      # like the _zn functions, but n\d+ should be Math::BigInt::GMP
      # or pass $i->{value} from a Math::BigInt.

=head2 Comparison Functions

(You can use these functions successfully, but the intended interface was
described above. L<Crypt::PBC::Element> describes that interface in detail.)

    Crypt::PBC::element_is0( $a );    # 1 when $a is 0
    Crypt::PBC::element_is1( $a );    # 1 when $a is 1
    Crypt::PBC::element_cmp( $a,$b ); # paradoxically, false when $a == $b
    Crypt::PBC::element_is_sqr( $a ); # 1 when $a is a perfect square ...
     # see the PBC docs for words like "residue"

=head2 Export and Output

(You can use these functions successfully, but the intended interface was
described above. L<Crypt::PBC::Element> describes that interface in detail.)

    # Please check the PBC docs ...
    Crypt::PBC::element_fprintf(\*OUTFILE, $format, $element);
    Crypt::PBC::element_fprintf(\*STDOUT, "example element=\%B\n", $element);
    # (You may be surprised how many bigints are in these group elements.)

    my $spewed_result = Crypt::PBC::export_element($element);
    # These are bytes, dumped from the $element, that can be used to
    # reconstruct the element or used for interacting with real life data.

    # Example:
    my $cipher = new Crypt::CBC({
        header => "randomiv", 
        key    => Crypt::PBC::export_element($element), 
        cipher => 'Blowfish', # hehe
    });

    my $big = Crypt::PBC::element_to_mpz( $element );
    # Returns a Math::BigInt::GMP, not a Math::BigInt!  WARNING: the
    # DESTROY() method from Math::BigInt::GMP will be missing unless you
    # require that package into your program.  You'll want to do that or you'll
    # have a memory leak...  Lastly, this is really only useful for elements in
    # Zr -- element_fprintf() to see what I mean.

=head1 XS AUTHOR

Paul Miller <jettero@cpan.org>

Paul is using this software in his own projects...  If you find bugs, please
please please let him know. :) Actually, let him know if you find it handy at
all.  Half the fun of releasing this stuff is knowing that people use it.

Additionally, he is aware that the documentation sucks.  Should you email him
for help, he will most likely try to give it.

=head1 COPYRIGHT

Copyright (c) 2008 Paul Miller -- LGPL [attached]

This interface is intended to be LGPL to whatever extent allowed by the license
for the pbc library itself.  That license is GPL and probably therefore makes
this package GPL.  I'm not expert on these matters, so I'm choosing LGPL if
possible.

=head1 SPECIAL THANKS

Without the direction of Dr. Leszek T. Lilien
(http://www.cs.wmich.edu/~llilien/), I never would have heard of IBE/PBC --
much less develop any interest in it.  Crypto is not his specialty, but
like any good professor, he's interested in everything.

=head1 SEE ALSO

    http://crypto.stanford.edu/pbc/

    http://groups.google.com/group/pbc-devel

perl(1), L<Crypt::PBC::Pairing>, L<Crypt::PBC::Element>
