File Coverage

blib/lib/Crypt/AllOrNothing.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1             package Crypt::AllOrNothing;
2              
3 2     2   71646 use warnings;
  2         5  
  2         63  
4 2     2   10 use strict;
  2         5  
  2         66  
5 2     2   1786 use Crypt::OpenSSL::AES;
  2         4169  
  2         186  
6 2     2   1446 use Crypt::AllOrNothing::Util qw/:all/;
  0            
  0            
7             use Carp;
8             use Crypt::Random qw/makerandom/;
9              
10             =head1 NAME
11              
12             Crypt::AllOrNothing - All-Or-Nothing Encryption
13              
14             =head1 VERSION
15              
16             Version 0.10
17              
18             =cut
19              
20             our $VERSION = '0.10';
21              
22             =head1 SYNOPSIS
23              
24             use Crypt::AllOrNothing;
25              
26             my $AllOrNothing = Crypt::AllOrNothing->new(K_0=>$K_0);
27             my $K_0 = $AllOrNothing->get_K_0();
28             my $K_0 = $AllOrNothing->set_K_0($K_0);
29             my $size = $AllOrNothing->get_size();
30             my @AllOrNothing_text = $AllOrNothing->encrypt(text=>$plaintext);
31             my $plaintext = $AllOrNothing->decrypt(text=>@AllOrNothing_text);
32              
33             =head1 CONSTANTS
34              
35             $SIZE = 128 bits;
36              
37             =cut
38              
39             my $SIZE = 128;
40              
41             =head1 FUNCTIONS
42              
43             =head2 new(K_0=>$K_0)
44              
45             Create AllOrNothing object. Good idea to provide K_0, which must be ascii encoded(characters) and of length given in size.
46             If K_0 is not given, you must retrieve it later with $AllOrNothing->K_0() else you will not be able to decrypt the message.
47              
48             =cut
49              
50             sub new {
51             my $class = shift;
52             my %params = @_;
53             my $self;
54             ########
55             #Check params
56             ########
57             if (!exists $params{size}) {
58             $self->{size} = $SIZE;
59             } elsif ($params{size} =~ /^(128)$/) {
60             $self->{size} = $params{size};
61             } else {
62             croak "Given size($params{size}) is invalid, valid sizes are 128 256 512 1024";
63             }
64              
65             if (!exists $params{K_0}) {
66             #carp 'No K_0 given. One will be automatically generated. You must manually get this value with $AllOrNothing->get_K_0() to decrypt.';
67             $self->{K_0}=randomValue(size=>$self->{size}, 'return'=>'ascii');
68             } elsif (length $params{K_0} == $self->{size}/8) {
69             $self->{K_0}=$params{K_0};
70             } else {
71             croak "Given K_0 was invalid, if given in new() it must be the correct length and characters(not int, hex, or base64)";
72             }
73              
74             bless $self, $class;
75             }
76              
77             =head2 K_0(K_0=>$K_0)
78              
79             get/set K_0. K_0 must be ascii encoded(characters) and length given in size.
80              
81             =cut
82              
83             sub K_0 {
84             my $self = shift;
85             if (@_) {
86             my $tmp_K_0 = shift;
87             if (length $tmp_K_0 != $self->{size}) {
88             carp 'K_0 passed is not correct length(must be equal to $AllOrNothing->size()), K_0 will not be set';
89             } else {
90             $self->{K_0} = $tmp_K_0;
91             }
92             }
93             return $self->{K_0};
94             }
95              
96             =head2 size()
97              
98             get size.
99              
100             =cut
101              
102             sub size {
103             my $self = shift;
104             return $self->{size};
105             }
106              
107             =head2 @ciphertext = encrypt(plaintext=>$plaintext, padding=>$padding)
108              
109             encrypt plaintext with All Or Nothing transform to array of messages. Optionally pass padding which will be used internally
110              
111             =cut
112              
113             sub encrypt {
114             my $self = shift;
115             my %params = @_;
116              
117             #break packets into length size packets
118             my @message = breakString(string=>$params{plaintext}, size=>$self->{size}/8);
119            
120             #create K_Prime
121             my $K_Prime = randomValue(size=>$self->{size}, 'return'=>'ascii');
122             my $cipher_K_Prime = Crypt::OpenSSL::AES->new($K_Prime) or croak "Could not create AES cipher with K_Prime";
123              
124             #add length and padding to message
125             addLength_andPad(array=>\@message, size=>$self->{size}/8, padding=>$params{padding});
126              
127             #encrypt
128             #m_Prime_sub_i = m_sub_i xor E(K_Prime, i) for i=1..s
129             #i must be made to a character and padded to size 'size' bits
130             my @messagePrime = ();
131             for (my $i=0; $i
132             push @messagePrime, $message[$i] ^ ($cipher_K_Prime->encrypt((sprintf("%c",0x00) x ($self->{size}/8-4)) . pack("L",$i)));
133             }
134             #m_Prime_sub_s_Prime = K_Prime xor h_1 xor h_2 xor ... h_s
135             #h_i = E(K_sub_0, m_Prime_sub_i xor i) for i=1..s
136             #i must be made to be 'size' bits
137             #K_sub_0 is a fixed publicly known encryption key
138             my $cipher_K_0 = Crypt::OpenSSL::AES->new($self->{K_0}) or croak "Could not create AES cipher with K_0";
139             my $m_Prime_sub_s = $K_Prime;
140             for (my $i=0; $i
141             $m_Prime_sub_s ^= $cipher_K_0->encrypt($messagePrime[$i]^((sprintf("%c",0x00) x ($self->{size}/8-4)) . pack("L",$i)));
142             }
143             push @messagePrime, $m_Prime_sub_s;
144             return @messagePrime;
145             }
146              
147             =head2 $plaintext = decrypt(cryptotext=>\@cryptotext)
148              
149             decrypt cryptotext array with All Or Nothing transform to plaintext
150              
151             =cut
152              
153             sub decrypt {
154             my $self = shift;
155             my %params = @_;
156             my $cipher_K_0 = Crypt::OpenSSL::AES->new($self->{K_0}) or croak "Could not create AES cipher with K_0";
157             #get K_Prime
158             my $m_prime_sub_s_prime = $params{cryptotext}->[$#{$params{cryptotext}}];
159             my $add_tmp = '';
160             for (my $i=0;$i<$#{$params{cryptotext}};$i++) {
161             $add_tmp ^= $cipher_K_0->encrypt($params{cryptotext}->[$i]^((sprintf("%c",0x00) x ($self->{size}/8-4)) . pack("L",$i)));
162             }
163             my $K_prime = $m_prime_sub_s_prime ^ $add_tmp;
164             pop @{$params{cryptotext}};
165             my $cipher_K_prime = Crypt::OpenSSL::AES->new($K_prime) or die "did not work to create K_Prime AES cipher";
166             my @m=();
167             for (my $i=0;$i
168             push @m, $params{cryptotext}->[$i]^$cipher_K_prime->encrypt(((sprintf("%c",0x00) x 12) . pack("L",$i)));
169             }
170             remLength_andPad(array=>\@m);
171             my $plaintext='';
172             for (@m) {
173             $plaintext .= $_;
174             }
175             return $plaintext;
176             }
177              
178             =head1 AUTHOR
179              
180             Timothy Zander, C<< >>
181              
182             The All Or Nothing Encryption and Package Transform algorithm was developed by Ronald Rivest
183              
184             =head1 BUGS
185              
186             Please report any bugs or feature requests to
187             C, or through the web interface at
188             L.
189             I will be notified, and then you'll automatically be notified of progress on
190             your bug as I make changes.
191              
192             =head1 SUPPORT
193              
194             You can find documentation for this module with the perldoc command.
195              
196             perldoc Crypt::AllOrNothing
197              
198             You can also look for information at:
199              
200             =over 4
201              
202             =item * Original Paper by Ronald Rivest
203              
204             L
205              
206             =item * AnnoCPAN: Annotated CPAN documentation
207              
208             L
209              
210             =item * CPAN Ratings
211              
212             L
213              
214             =item * RT: CPAN's request tracker
215              
216             L
217              
218             =item * Search CPAN
219              
220             L
221              
222             =back
223              
224             =head1 ACKNOWLEDGEMENTS
225              
226             Thanks to Prof. Bulent Yener at RPI for his assistance.
227              
228             =head1 COPYRIGHT & LICENSE
229              
230             Copyright 2007 Timothy Zander, all rights reserved.
231              
232             This program is free software; you can redistribute it and/or modify it
233             under the same terms as Perl itself.
234              
235             =cut
236              
237             1; # End of Crypt::AllOrNothing