230 lines
6.2 KiB
Perl
Executable file
230 lines
6.2 KiB
Perl
Executable file
#/**********************************************************\
|
|
#| |
|
|
#| The implementation of PHPRPC Protocol 3.0 |
|
|
#| |
|
|
#| xxtea.pm |
|
|
#| |
|
|
#| Release 3.0.0 beta |
|
|
#| Copyright (c) 2005-2007 by Team-PHPRPC |
|
|
#| |
|
|
#| WebSite: http://www.phprpc.org/ |
|
|
#| http://www.phprpc.net/ |
|
|
#| http://www.phprpc.com/ |
|
|
#| http://sourceforge.net/projects/php-rpc/ |
|
|
#| |
|
|
#| Author: Ma Bingyao <andot@ujn.edu.cn> |
|
|
#| |
|
|
#| This file may be distributed and/or modified under the |
|
|
#| terms of the GNU Lesser General Public License (LGPL) |
|
|
#| version 3.0 as published by the Free Software Foundation |
|
|
#| and appearing in the included file LICENSE. |
|
|
#| |
|
|
#\**********************************************************/
|
|
#
|
|
# XXTEA encryption arithmetic module.
|
|
#
|
|
# Copyright (C) 2006-2007 Ma Bingyao <andot@ujn.edu.cn>
|
|
# Version: 1.00
|
|
# LastModified: Nov 7, 2007
|
|
# This library is free. You can redistribute it and/or modify it.
|
|
#
|
|
|
|
package Crypt::XXTEA;
|
|
|
|
use bytes;
|
|
use integer;
|
|
use strict;
|
|
|
|
use Exporter;
|
|
use vars qw($VERSION @ISA @EXPORT);
|
|
|
|
$VERSION = 1.00;
|
|
@ISA = qw(Exporter);
|
|
@EXPORT = qw(xxtea_encrypt xxtea_decrypt);
|
|
|
|
*encrypt = \&xxtea_encrypt;
|
|
*decrypt = \&xxtea_decrypt;
|
|
|
|
sub _long2str {
|
|
my ($v, $w) = @_;
|
|
my $len = @{$v};
|
|
my $n = ($len - 1) << 2;
|
|
if ($w) {
|
|
my $m = $v->[$len - 1];
|
|
if (($m < $n - 3) || ($m > $n)) {
|
|
return 0;
|
|
}
|
|
$n = $m;
|
|
}
|
|
my @s = ();
|
|
for (my $i = 0; $i < $len; $i++) {
|
|
$s[$i] = pack("V", $v->[$i]);
|
|
}
|
|
if ($w) {
|
|
return substr(join('', @s), 0, $n);
|
|
}
|
|
else {
|
|
return join('', @s);
|
|
}
|
|
}
|
|
|
|
sub _str2long {
|
|
my ($s, $w) = @_;
|
|
my @v = unpack("V*", $s. "\0"x((4 - length($s) % 4) & 3));
|
|
if ($w) {
|
|
$v[@v] = length($s);
|
|
}
|
|
return @v;
|
|
}
|
|
|
|
sub xxtea_encrypt {
|
|
my ($s, $k) = @_;
|
|
if ($s eq "") {
|
|
return "";
|
|
}
|
|
my @v = _str2long($s, 1);
|
|
my @k = _str2long($k, 0);
|
|
if (@k < 4) {
|
|
for (my $i = @k; $i < 4; $i++) {
|
|
$k[$i] = 0;
|
|
}
|
|
}
|
|
my $n = $#v;
|
|
my $z = $v[$n];
|
|
my $y = $v[0];
|
|
my $delta = 0x9E3779B9;
|
|
my $q = 6 + 52 / ($n + 1);
|
|
my $sum = 0;
|
|
my $e;
|
|
my $p;
|
|
my $mx;
|
|
while (0 < $q--) {
|
|
$sum = ($sum + $delta) & 0xffffffff;
|
|
$e = $sum >> 2 & 3;
|
|
for ($p = 0; $p < $n; $p++) {
|
|
$y = $v[$p + 1];
|
|
$mx = ((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ (($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z)) & 0xffffffff;
|
|
$z = $v[$p] = ($v[$p] + $mx) & 0xffffffff;
|
|
}
|
|
$y = $v[0];
|
|
$mx = ((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ (($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z)) & 0xffffffff;
|
|
$z = $v[$n] = ($v[$n] + $mx) & 0xffffffff;
|
|
}
|
|
return _long2str(\@v, 0);
|
|
}
|
|
|
|
sub xxtea_decrypt {
|
|
my ($s, $k) = @_;
|
|
if ($s eq "") {
|
|
return "";
|
|
}
|
|
my @v = _str2long($s, 0);
|
|
my @k = _str2long($k, 0);
|
|
if (@k < 4) {
|
|
for (my $i = @k; $i < 4; $i++) {
|
|
$k[$i] = 0;
|
|
}
|
|
}
|
|
my $n = $#v;
|
|
my $z = $v[$n];
|
|
my $y = $v[0];
|
|
my $delta = 0x9E3779B9;
|
|
my $q = 6 + 52 / ($n + 1);
|
|
my $sum = ($q * $delta) & 0xffffffff;
|
|
my $e;
|
|
my $p;
|
|
my $mx;
|
|
while ($sum != 0) {
|
|
$e = $sum >> 2 & 3;
|
|
for ($p = $n; $p > 0; $p--) {
|
|
$z = $v[$p - 1];
|
|
$mx = ((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ (($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z)) & 0xffffffff;
|
|
$y = $v[$p] = ($v[$p] - $mx) & 0xffffffff;
|
|
}
|
|
$z = $v[$n];
|
|
$mx = ((($z >> 5 & 0x07ffffff) ^ $y << 2) + (($y >> 3 & 0x1fffffff) ^ $z << 4)) ^ (($sum ^ $y) + ($k[$p & 3 ^ $e] ^ $z)) & 0xffffffff;
|
|
$y = $v[0] = ($v[0] - $mx) & 0xffffffff;
|
|
$sum = ($sum - $delta) & 0xffffffff;
|
|
}
|
|
return _long2str(\@v, 1);
|
|
}
|
|
|
|
1;
|
|
|
|
__END__
|
|
|
|
=head1 NAME
|
|
|
|
Crypt::XXTEA - XXTEA encryption arithmetic module.
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
use Crypt::XXTEA;
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
XXTEA is a secure and fast encryption algorithm. It's suitable for web development. This module allows you to encrypt or decrypt a string using the algorithm.
|
|
|
|
=head1 FUNCTIONS
|
|
|
|
=over 4
|
|
|
|
=item xxtea_encrypt
|
|
|
|
my $ciphertext = xxtea_encrypt($plaintext, $key);
|
|
|
|
This function encrypts $plaintext using $key and returns the $ciphertext.
|
|
|
|
=item encrypt
|
|
|
|
my $ciphertext = Crypt::XXTEA::encrypt($plaintext, $key);
|
|
|
|
This function is the same as xxtea_encrypt.
|
|
|
|
=item xxtea_decrypt
|
|
|
|
my $plaintext = xxtea_decrypt($ciphertext, $key);
|
|
|
|
This function decrypts $ciphertext using $key and returns the $plaintext.
|
|
|
|
=item decrypt
|
|
|
|
my $plaintext = Crypt::XXTEA::decrypt($ciphertext, $key);
|
|
|
|
This function is the same as xxtea_decrypt.
|
|
|
|
=back
|
|
|
|
=head1 EXAMPLE
|
|
|
|
use Crypt::XXTEA;
|
|
my $ciphertext = xxtea_encrypt("Hello XXTEA.", "1234567890abcdef");
|
|
my $plaintext = xxtea_decrypt($ciphertext, "1234567890abcdef");
|
|
print $plaintext;
|
|
|
|
$ciphertext = Crypt::XXTEA::encrypt("Hi XXTEA.", "1234567890abcdef");
|
|
$plaintext = Crypt::XXTEA::decrypt($ciphertext, "1234567890abcdef");
|
|
print $plaintext;
|
|
|
|
=head1 NOTES
|
|
|
|
If $plaintext is equal to "", it returns "".
|
|
|
|
It returns 0 when fails to decrypt.
|
|
|
|
Only the first 16 bytes of $key is used. if $key is shorter than 16 bytes, it will be padding \0.
|
|
|
|
The XXTEA algorithm is stronger and faster than Crypt::DES, Crypt::Blowfish & Crypt::IDEA.
|
|
|
|
=head1 SEE ALSO
|
|
|
|
Crypt::DES
|
|
Crypt::Blowfish
|
|
Crypt::IDEA
|
|
|
|
=head1 COPYRIGHT
|
|
|
|
The implementation of the XXTEA algorithm was developed by,
|
|
and is copyright of, Ma Bingyao (andot@ujn.edu.cn).
|
|
|
|
=cut
|