Initial checkin.
[catacomb-perl] / Catacomb.pm
CommitLineData
660b443c 1# -*-perl-*-
2#
3# $Id: Catacomb.pm,v 1.1 2004/04/02 18:04:01 mdw Exp $
4#
5# Perl interface to Catacomb crypto library
6#
7# (c) 2001 Straylight/Edgeware
8#
9
10#----- Licensing notice -----------------------------------------------------
11#
12# This file is part of the Perl interface to Catacomb.
13#
14# Catacomb/Perl is free software; you can redistribute it and/or modify
15# it under the terms of the GNU General Public License as published by
16# the Free Software Foundation; either version 2 of the License, or
17# (at your option) any later version.
18#
19# Catacomb/Perl is distributed in the hope that it will be useful,
20# but WITHOUT ANY WARRANTY; without even the implied warranty of
21# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22# GNU General Public License for more details.
23#
24# You should have received a copy of the GNU General Public License
25# along with Catacomb/Perl; if not, write to the Free Software Foundation,
26# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27
28#----- Revision history -----------------------------------------------------
29#
30# $Log: Catacomb.pm,v $
31# Revision 1.1 2004/04/02 18:04:01 mdw
32# Initial checkin.
33#
34
35#----- Basic stuff ----------------------------------------------------------
36
37package Catacomb;
38use DynaLoader;
39use Exporter;
40@ISA = qw(DynaLoader Exporter);
41
42$VERSION = "1.0.0";
43
44bootstrap Catacomb;
45
46@EXPORT_OK = qw($random);
47%EXPORT_TAGS = ("const" => [qw(GRAND_CRYPTO PGEN_TRY PGEN_FAIL PGEN_PASS
48 PGEN_DONE PGEN_ABORT PGEN_BEGIN)]);
49Exporter::export_ok_tags("const");
50
51sub AUTOLOAD {
52 my $val = const($AUTOLOAD);
53 *$AUTOLOAD = sub { $val };
54 goto &$AUTOLOAD;
55}
56
57#----- Multiprecision arithmetic --------------------------------------------
58
59package Catacomb::MP;
60use Carp;
61
62use overload
63 '+' => sub { _binop(\&add, @_); },
64 '-' => sub { _binop(\&sub, @_); },
65 '*' => sub { _binop(\&mul, @_); },
66 '/' => sub { _binop(\&div, @_); },
67 '%' => sub { _binop(\&mod, @_); },
68 '&' => sub { _binop(\&and, @_); },
69 '|' => sub { _binop(\&or, @_); },
70 '^' => sub { _binop(\&xor, @_); },
71 '**' => sub { _binop(\&pow, @_); },
72 '>>' => sub { &lsr(@_[0, 1]); },
73 '<<' => sub { &lsl(@_[0, 1]); },
74 '~' => sub { &not($_[0]) },
75 '==' => sub { _binop(\&eq, @_); },
76 '<=>' => sub { _binop(\&cmp, @_); },
77 '""' => sub { &tostring($_[0]); },
78 '0+' => sub { &toint($_[0]); },
79 'sqrt' => sub { &sqrt($_[0]); },
80 'neg' => sub { &neg($_[0]); };
81
82sub mod { (&div($_[0], $_[1]))[1]; }
83
84sub pow {
85 croak("Usage: Catacomb::MP::pow(a, b)") unless @_ == 2;
86 my ($a, $b) = @_;
87 my $r = Catacomb::MP->new(1);
88 while ($b) {
89 $r *= $a if $b & 1;
90 $a = sqr($a);
91 $b >>= 1;
92 }
93 return $r;
94}
95
96sub _binop {
97 my ($func, $a, $b, $flag) = @_;
98 return $flag ? &$func($b, $a) : &$func($a, $b);
99}
100
101sub modexp {
102 croak("Usage: Catacomb::MP::modexp(p, g, x)") unless @_ == 3;
103 my ($p, $g, $x) = @_;
104 $g = $p - $g if $g < 0;
105 $g = $g % $p if $g > $p;
106 if ($p & 1) {
107 my $mm = Catacomb::MP::Mont->new($p);
108 return $mm->exp($g, $x);
109 } else {
110 my $mb = Catacomb::MP::Barrett->new($p);
111 return $mb->exp($g, $x);
112 }
113}
114
115sub modinv {
116 croak("Usage: Catacomb::MP::modinv(p, x)") unless @_ == 2;
117 my ($g, undef, $i) = gcd($_[0], $_[1]);
118 croak("Arguments aren't coprime in Catacomb::MP::modinv") unless $g == 1;
119 return $i;
120}
121
122#----- Prime testing --------------------------------------------------------
123
124{
125 my $cmpg = "Catacomb::MP::Prime::Gen";
126 foreach my $i (qw(FilterStepper JumpStepper RabinTester)) {
127 @{"${cmpg}::${i}::ISA"} = ("${cmpg}::MagicProc");
128 }
129 @{"${cmpg}::MagicProc::ISA"} = ("${cmpg}::Proc");
130}
131
132#----- Crypto algorithms ----------------------------------------------------
133
134package Catacomb;
135
136foreach my $i (qw(Cipher Hash MAC)) {
137 my $tag = lc($i);
138 my @v = ();
139 my $cl = "Catacomb::${i}Class";
140 foreach my $c (&{"${cl}::list"}($cl)) {
141 my $x = $c->name(); $x =~ tr/a-zA-Z0-9/_/cs;
142 ${"Catacomb::${i}::${x}"} = undef; # SUYB
143 ${"Catacomb::${i}::${x}"} = $c;
144 push(@v, "\$Catacomb::${i}::${x}");
145 }
146 $EXPORT_TAGS{$tag} = \@v;
147 Exporter::export_ok_tags($tag);
148}
149
150package Catacomb::CipherClass;
151use Carp;
152
153sub encrypt {
154 croak("Usage: Catacomb::CipherClass::encrypt(cc, k, [iv], plain)")
155 if @_ < 3 || @_ > 4;
156 my ($cc, $k, $iv, $p) = @_;
157 if (@_ == 3) {
158 $p = $iv;
159 $iv = undef;
160 }
161 my $c = $cc->init($k);
162 $c->setiv($iv) if defined($iv);
163 return $c->encrypt($p);
164}
165
166sub decrypt {
167 croak("Usage: Catacomb::CipherClass::decrypt(cc, k, [iv], cipher)")
168 if @_ < 3 || @_ > 4;
169 my ($cc, $k, $iv, $p) = @_;
170 if (@_ == 3) {
171 $p = $iv;
172 $iv = undef;
173 }
174 my $c = $cc->init($k);
175 return $c->decrypt($p);
176}
177
178package Catacomb::HashClass;
179use Carp;
180
181sub hash {
182 croak("Usage: Catacomb::HashClass::hash(hc, p)") unless @_ == 2;
183 my ($hc, $p) = @_;
184 my $h = $hc->init();
185 $h->hash($p);
186 return $h->done();
187}
188
189package Catacomb::MACClass;
190use Carp;
191
192sub mac {
193 croak("Usage: Catacomb::MACClass::mac(mc, k, p)") unless @_ == 3;
194 my ($mc, $k, $p) = @_;
195 my $m = $mc->key($k);
196 return $m->hash($p);
197}
198
199package Catacomb::MAC;
200use Carp;
201
202sub hash {
203 croak("Usage: Catacomb::MAC::hash(m, p)") unless @_ == 2;
204 my ($m, $p) = @_;
205 my $h = $m->init();
206 $h->hash($p);
207 return $h->done();
208}
209
210#----- Random number generators ---------------------------------------------
211
212package Catacomb;
213
214foreach my $i (qw(True Fib LC DSA RC4 SEAL MGF Counter OFB Magic)) {
215 @{"Catacomb::Rand::${i}::ISA"} = qw(Catacomb::Rand);
216}
217
218$Catacomb::random = Catacomb::Rand::True->_global();
219$Catacomb::random->noisesrc();
220$Catacomb::random->seed(160);
221
222#----- That's all, folks ----------------------------------------------------
223
2241;