Much wider support for Catacomb in all its glory.
[catacomb-perl] / Catacomb / Crypto.pm
diff --git a/Catacomb/Crypto.pm b/Catacomb/Crypto.pm
new file mode 100644 (file)
index 0000000..c4e886d
--- /dev/null
@@ -0,0 +1,213 @@
+# -*-perl-*-
+#
+# $Id$
+#
+# Cryptographic algorithms
+#
+# (c) 2004 Straylight/Edgeware
+#
+
+#----- Licensing notice -----------------------------------------------------
+#
+# This file is part of the Perl interface to Catacomb.
+#
+# Catacomb/Perl is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# Catacomb/Perl is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with Catacomb/Perl; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+#----- Symmetric crypto algorithms -----------------------------------------
+
+package Catacomb;
+use Catacomb::Base;
+use Exporter;
+
+foreach my $i (qw(PRP Cipher Hash MAC)) {
+  my $tag = lc($i);
+  my @v = ();
+  my $cl = "Catacomb::${i}Class";
+  foreach my $c (Catacomb::list($tag)) {
+    (my $x = $c) =~ tr/a-zA-Z0-9/_/cs;
+    $$x = undef; # SUYB
+    $$x = $cl->find($c);
+    push(@v, "\$$x");
+  }
+  $EXPORT_TAGS{$tag} = \@v;
+  Exporter::export_ok_tags($tag);
+}
+
+package Catacomb::PRPClass;
+use Carp;
+
+sub eblk {
+  croak("Usage: Catacomb::PRPClass::eblk(pc, k, pt)") unless @_ == 3;
+  my ($pc, $k, $pt) = @_;
+  my $P = $pc->init($k);
+  return $P->eblk($pt);
+}
+
+sub dblk {
+  croak("Usage: Catacomb::PRPClass::dblk(pc, k, ct)") unless @_ == 3;
+  my ($pc, $k, $pt) = @_;
+  my $P = $pc->init($k);
+  return $P->dblk($ct);
+}
+
+package Catacomb::CipherClass;
+use Carp;
+
+sub encrypt {
+  croak("Usage: Catacomb::CipherClass::encrypt(cc, k, [iv], plain)")
+    if @_ < 3 || @_ > 4;
+  my ($cc, $k, $iv, $p) = @_;
+  if (@_ == 3) {
+    $p = $iv;
+    $iv = undef;
+  }
+  my $c = $cc->init($k);
+  $c->setiv($iv) if defined($iv);
+  return $c->encrypt($p);
+}
+
+sub decrypt {
+  croak("Usage: Catacomb::CipherClass::decrypt(cc, k, [iv], cipher)")
+    if @_ < 3 || @_ > 4;
+  my ($cc, $k, $iv, $p) = @_;
+  if (@_ == 3) {
+    $p = $iv;
+    $iv = undef;
+  }
+  my $c = $cc->init($k);
+  $c->setiv($iv) if defined($iv);
+  return $c->decrypt($p);
+}
+
+package Catacomb::HashClass;
+use Carp;
+
+sub hash {
+  croak("Usage: Catacomb::HashClass::hash(hc, p)") unless @_ == 2;
+  my ($hc, $p) = @_;
+  my $h = $hc->init();
+  $h->hash($p);
+  return $h->done();
+}
+
+package Catacomb::MACClass;
+use Carp;
+
+sub mac {
+  croak("Usage: Catacomb::MACClass::mac(mc, k, p)") unless @_ == 3;
+  my ($mc, $k, $p) = @_;
+  my $m = $mc->key($k);
+  return $m->hash($p);
+}
+
+package Catacomb::MAC;
+use Carp;
+
+sub hash {
+  croak("Usage: Catacomb::MAC::hash(m, p)") unless @_ == 2;
+  my ($m, $p) = @_;
+  my $h = $m->init();
+  $h->hash($p);
+  return $h->done();
+}
+
+#----- DSA and KCDSA signing ------------------------------------------------
+
+package Catacomb::DSA;
+use Carp;
+sub new {
+  croak("Usage: ${me}::new(me, info)") unless @_ == 2;
+  my ($me, $info) = @_;
+  return bless $info, $me;
+}
+
+*Catacomb::KCDSA::new = \&new;
+
+foreach my $i (qw(DSA KCDSA)) {
+  @{"Catacomb::${i}::Public::ISA"} = ("Catacomb::${i}");
+  @{"Catacomb::${i}::Private::ISA"} = ("Catacomb::${i}::Public");
+}
+
+#----- RSA signing and encryption -------------------------------------------
+
+package Catacomb::RSA::Pad;
+use Carp;
+
+sub new {
+  croak("Usage: ${me}::new(me, info)") unless @_ == 2;
+  my ($me, $info) = @_;
+  return bless $info, $me;
+}
+
+foreach my $i (qw(PKCS1Crypt PKCS1Sign OAEP PSS)) {
+  @{"Catacomb::RSA::${i}::ISA"} = qw(Catacomb::RSA::Pad);
+}
+
+package Catacomb::RSA::Public;
+use Carp;
+use Catacomb::Base;
+use Catacomb::MP;
+
+sub encrypt {
+  croak("Usage: Catacomb::RSA::Public::encrypt(pub, pad, msg)")
+    unless @_ == 3;
+  my ($pub, $pad, $msg) = @_;
+  my $n = $pub->n();
+  my $r = $pad->pad($msg, $n->octets(), $n->bits());
+  return undef unless defined($r);
+  return $pub->op($r);
+}
+
+sub verify {
+  croak("Usage: Catacomb::RSA::Public::verify(pub, pad, sig, [msg])")
+    unless @_ >= 3 && @_ <= 4;
+  my ($pub, $pad, $sig, $msg) = @_;
+  my $n = $pub->n();
+  my $rc = $pad->unpad($pub->op($sig), $msg, $n->octets(), $n->bits());
+  return undef unless defined($rc);
+  if (defined($msg)) {
+    return undef unless $rc eq "" || $rc eq $msg;
+    return 1;
+  } else {
+    return $rc;
+  }
+}
+
+package Catacomb::RSA::Private;
+use Carp;
+use Catacomb::Base;
+use Catacomb::MP;
+
+sub sign {
+  croak("Usage: Catacomb::RSA::Private::sign(priv, pad, msg, [rng]")
+    unless @_ >= 3 && @_ <= 4;
+  my ($priv, $pad, $msg, $rng) = @_;
+  my $n = $priv->n();
+  my $r = $pad->pad($msg, $n->octets(), $n->bits());
+  return undef unless defined($r);
+  return $priv->op($r, $rng);
+}
+
+sub decrypt {
+  croak("Usage: Catacomb::RSA::Private::decrypt(priv, pad, ct, [rng]")
+    unless @_ >= 3 && @_ <= 4;
+  my ($priv, $pad, $ct, $rng) = @_;
+  my $n = $priv->n();
+  return $pad->unpad($priv->op($ct, $rng), $n->octets(), $n->bits());
+}
+
+#----- That's all, folks ----------------------------------------------------
+
+1;