File Coverage

blib/lib/Crypt/Elijah.pm
Criterion Covered Total %
statement 45 45 100.0
branch 5 6 83.3
condition 18 24 75.0
subroutine 5 5 100.0
pod 0 3 0.0
total 73 83 87.9


line stmt bran cond sub pod time code
1             package Crypt::Elijah;
2              
3 1     1   10417 use Carp;
  1         2  
  1         1006  
4              
5             our $VERSION = '0.11';
6              
7             sub _rand {
8 7     7   115 return sprintf( '%04X', int( rand(0xFFFF) ) );
9             }
10              
11             sub init {
12 12 100 100 12 0 4840 croak()
      100        
13             if ( !defined( $_[0] ) || ref( $_[0] ) || ( length( $_[0] ) < 12 ) );
14 9         24 my ( @k, @s, $a, $b, $c, $d, $e, $i, $pc );
15              
16 9         19 $_[0] .= "\0" x 16;
17 9         40 @k = unpack( 'C16', $_[0] );
18              
19 9         18 $pc = 21;
20 9         24 for ( $i = 360 ; $i > 0 ; $i-- ) {
21 3240         4227 $a = $i % 256;
22 3240         3327 $b = $a % 16;
23 3240         5984 $c = ( $b + 1 ) * ( $b + 1 );
24 3240         4690 $d = ( $c + $a ) % 256;
25 3240         4820 $e = ( $d + $k[$b] + $pc ) % 256;
26 3240         3337 $pc = $e;
27 3240         7336 push( @s, $e );
28             }
29 9         32 for ( $i = 359 ; $i > -1 ; $i-- ) {
30 3240         3339 $a = ( $i + 2 ) % 360;
31 3240         7721 $s[$i] = ( $s[$i] + $s[$a] ) % 256;
32             }
33              
34 9         126 return \@s;
35             }
36              
37             sub enc {
38 11 100 100 11 0 2089 croak()
      100        
      100        
39             if ( !defined( $_[0] )
40             || !defined( $_[1] )
41             || ref( $_[0] )
42             || !ref( $_[1] ) );
43 7         19 my ( @t, @salt, $s, $pc, $i );
44              
45 7         43 @t = unpack( 'C*', $_[0] );
46 7         22 @salt = unpack( 'C4', _rand() );
47 7         22 unshift( @t, @salt );
48 7         12 $s = $_[1];
49 7         11 $pc = $$s[359];
50              
51 7         22 for ( $i = 0 ; $i <= $#t ; $i++ ) {
52 142         166 $t[$i] = ( $t[$i] + $pc ) % 256;
53 142         154 $t[$i] ^= $$s[ $i % 360 ];
54 142         296 $pc = ( $t[$i] + $i ) % 256;
55             }
56 7         67 $_[0] = pack( 'C*', @t );
57             }
58              
59             sub dec {
60 7 50 33 7 0 498 croak()
      33        
      33        
61             if ( !defined( $_[0] )
62             || !defined( $_[1] )
63             || ref( $_[0] )
64             || !ref( $_[1] ) );
65 7         9 my ( @t, $s, $pc, $i, $a );
66              
67 7         41 @t = unpack( 'C*', $_[0] );
68 7         14 $s = $_[1];
69 7         10 $pc = $$s[359];
70              
71 7         22 for ( $i = 0 ; $i <= $#t ; $i++ ) {
72 142         144 $a = $t[$i];
73 142         183 $t[$i] ^= $$s[ $i % 360 ];
74 142         180 $t[$i] = ( $t[$i] - $pc ) % 256;
75 142         294 $pc = ( $a + $i ) % 256;
76             }
77              
78 7         14 splice( @t, 0, 4 );
79 7         54 $_[0] = pack( 'C*', @t );
80             }
81              
82             1;
83              
84             =head1 NAME
85              
86             Crypt::Elijah - cipher module
87              
88             =head1 SYNOPSIS
89              
90             use Crypt::Elijah;
91              
92             $text = 'secretive';
93             $key = '0123456789abcdef';
94             $keyref = Crypt::Elijah::init($key);
95             Crypt::Elijah::enc($text, $keyref);
96             Crypt::Elijah::dec($text, $keyref);
97              
98             =head1 DESCRIPTION
99              
100             This module provides a pure Perl implementation of the Elijah cipher.
101              
102             Call init() to prepare the encryption key.
103             This function takes a single argument: a packed string containing your key.
104             The key must be at least 12 bytes long.
105             Keys longer than 16 bytes are truncated.
106             This function returns a reference to the prepared key.
107              
108             Call enc() and dec() to process your data.
109             These functions take the same parameters.
110             The first argument is a string containing your data.
111             The second argument is a reference returned by init().
112             Salt is added to your data; ciphertext will always be larger than the
113             corresponding plaintext.
114              
115             =head1 BUGS
116              
117             This module is not intended for bulk encryption.
118             It would be more sensible to use an XS encryption module for processing large
119             amounts of data.
120              
121             It is a good idea to remove redundancy from your data prior to encryption (e.g.
122             using compression); this module has no built-in mechanism for achieving this.
123             Redundancy in your data may allow information to be discovered from the
124             ciphertext.
125              
126             This module is experimental software and should be used with caution.
127             Please report any bugs to the author.
128              
129             =head1 AUTHOR
130              
131             Michael W. Bombardieri
132              
133             =head1 COPYRIGHT
134              
135             Copyright 2007, 2008 Michael W. Bombardieri.
136              
137             This program is free software; you can redistribute it and/or modify it under
138             the same terms as Perl itself.
139              
140             =head1 DEDICATION
141              
142             This software is dedicated to Elijah DePiazza.
143              
144             =cut