The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
package Crypt::SEAL2;

use strict;
use warnings;
require Exporter;

our @EXPORT_OK = qw(new encrypt decrypt keysize reset repos);
our $VERSION = '1.0.4';
our @ISA = qw(Exporter);

require XSLoader;
XSLoader::load('Crypt::SEAL2', $VERSION);

# Preloaded methods go here.

1;

__END__

=head1 NAME

Crypt::SEAL2 - The SEAL stream cipher, version 2.0

=head1 SYNOPSIS

    use Crypt::SEAL2;

    $cipher = new Crypt::SEAL2 $key;
    $ciphertext = $cipher->encrypt($plaintext);
    $cipher->reset();
    $ks = $cipher->keysize();
    $plaintext  = $cipher->decrypt($ciphertext);
    $cipher->repos($position);

=head1 DESCRIPTION

SEAL2 is the second version of the stream cipher, SEAL, designed by Don
Coppersmith and Phillip Rogaway.

This module supports the following functions:

=over

=item B<new()>

Creates a pseudorandom string (PRS), using a user-supplied key as a
B<seed> to the pseudorandom generator of SEAL2. A PRS pointer
initially points at the beginning of the PRS.

=item B<encrypt($data)>

Encrypts the data stream B<$data> by B<XOR>-ing it with the PRS,
starting at the position being pointed to by the PRS pointer, and
returns the resulting ciphertext. The PRS pointer is advanced 1 byte
position for every byte of B<$data> that is encrypted.

=item B<decrypt($data)>

Decrypts the data stream B<$data> by B<XOR>-ing it with the PRS,
starting at the position being pointed to by the PRS pointer, and
returns the resulting plaintext. The PRS pointer is advanced 1 byte
position for every byte of B<$data> that is decrypted.

B<decrypt($data)> is exactly the same as B<encrypt($data)>.


=item B<reset()>

Every time a call to either B<encrypt()> or B<decrypt()> is performed,
the PRS pointer is advanced. Therefore, it is necessary to B<reset()>
the pointer in order to encrypt/decrypt the data stream correctly.
Alternatively, you may use B<repos()> to manually re-position the
PRS pointer to where the encryption/decryption will start (see next
function).

=item B<repos($position)>

Re-positions the PRS pointer at byte position B<$position>

=item B<keysize()>

Returns the size (in bytes) of the key used (20, in this case)

=back

=head2 Note

Since the pseudorandom sequence generated by SEAL2 is XOR-ed with the
data stream, a call to B<encrypt> is the same as a call to B<decrypt>.
Mathematically,

                    P xor R = C
                    C xor R = P

=head1 EXAMPLE

    #!/usr/local/bin/perl

    use diagnostics;
    use strict;
    use warnings;
    use Crypt::SEAL2;

    my $key = pack "H40", "00112233445566778899aabbccddeeff00112233";
    my $cipher = new Crypt::SEAL2 $key;

    my $plaintext1 = pack "H16", "0123456789abcdef";
    print "old plaintext1  : ", unpack("H*", $plaintext1), "\n";

    my $ciphertext1 = $cipher->encrypt($plaintext1);
    print "ciphertext1     : ", unpack("H*", $ciphertext1), "\n";

    $cipher->reset();

    my $decrypted1 = $cipher->decrypt($ciphertext1);
    print "new plaintext1  : ", unpack("H*", $decrypted1), "\n";

    print "\n";

    my $plaintext2 = pack "H40", "fedcba98765432100123456789abcdef01234567";
    print "old plaintext2  : ", unpack("H*", $plaintext2), "\n";

    $cipher->reset();

    my $ciphertext2 = $cipher->encrypt($plaintext2);
    print "ciphertext2     : ", unpack("H*", $ciphertext2), "\n";

    $cipher->reset();

    my $decrypted2 = $cipher->decrypt($ciphertext2);
    print "new plaintext2  : ", unpack("H*", $decrypted2), "\n";

=head1 CAVEAT

SEAL2 is designed to generate up to 2^48 bytes of output per seed. In
1997, Handschuh and Gilbert showed, however, that the output stream can
be distinguished from a random sequence after only seeing roughly 2^34
bytes of output. Thus, it is prudent to avoid using the same seed for
more than 2^34 bytes of output.

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2003 Julius C. Duque. Please read contact.html that comes
with this distribution for details on how to contact the author.

This library is free software; you can redistribute it and/or modify
it under the same terms as the GNU General Public License.

=cut