NAME

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

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 );

"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/

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.

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 Crypt::PBC package is new(). Please see Crypt::PBC::Pairing and Crypt::PBC::Element for the guts of the intended OO interface.

Crypt::PBC::new()

Returns a new PBC pairing object. new() takes, as arguments, either the name of a file, a file stream (e.g., new 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

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.

Pairing Functions

(You can use these functions successfully, but the intended interface was described above. 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);

Element Initializer and Assignment Functions

(You can use these functions successfully, but the intended interface was described above. 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.

Arithmetic Functions

(You can use these functions successfully, but the intended interface was described above. 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.

Comparison Functions

(You can use these functions successfully, but the intended interface was described above. 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"

Export and Output

(You can use these functions successfully, but the intended interface was described above. 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.

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.

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.

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.

SEE ALSO

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

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

perl(1), Crypt::PBC::Pairing, Crypt::PBC::Element