Much wider support for Catacomb in all its glory.
[catacomb-perl] / Catacomb / GF.pm
diff --git a/Catacomb/GF.pm b/Catacomb/GF.pm
new file mode 100644 (file)
index 0000000..633bf78
--- /dev/null
@@ -0,0 +1,112 @@
+# -*-perl-*-
+#
+# $Id$
+#
+# Binary polynomial arithmetic
+#
+# (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.
+
+#----- Binary polynomials ---------------------------------------------------
+
+package Catacomb::GF;
+use Catacomb::Base;
+use Catacomb::MP;
+use Carp;
+
+@ISA = qw(Catacomb::MP);
+
+sub gf { new(Catacomb::GF, $_[0]); }
+sub gf_loadb { loadb(Catacomb::GF, $_[0]); }
+sub gf_loadl { loadl(Catacomb::GF, $_[0]); }
+sub gf_fromstring { fromstring(Catacomb::GF, $_[0]); }
+
+use overload
+  '+' => sub { _binop(\&add, @_); },
+  '-' => sub { _binop(\&add, @_); },
+  '*' => sub { _binop(\&mul, @_); },
+  '/' => sub { _binop(\&div, @_); },
+  '%' => sub { _binop(\&mod, @_); },
+  '&' => sub { _binop(\&Catacomb::MP::and, @_); },
+  '|' => sub { _binop(\&Catacomb::MP::or, @_); },
+  '^' => sub { _binop(\&Catacomb::MP::xor, @_); },
+  '**' => sub { _binop(\&pow, @_); },
+  '>>' => sub { new(undef, &Catacomb::MP::lsr(@_[0, 1])); },
+  '<<' => sub { new(undef, &Catacomb::MP::lsl(@_[0, 1])); },
+  '~' => sub { new(undef, &Catacomb::MP::not($_[0])) },
+  '==' => sub { _binop(\&Catacomb::MP::eq, @_); },
+  '!=' => sub { !_binop(\&Catacomb::MP::eq, @_); },
+  'eq' => sub { _binop(\&Catacomb::MP::eq, @_); },
+  'ne' => sub { !_binop(\&Catacomb::MP::eq, @_); },
+  '""' => sub { "0x" . &Catacomb::MP::tostring($_[0], 16); },
+  'neg' => sub { $_[0]; },
+  '0+' => sub { &Catacomb::MP::toint($_[0]); };
+
+sub binpolyfield {
+  croak("Usage: Catacomb::GF::binpolyfield(p)") unless @_ == 1;
+  return Catacomb::Field->binpoly($_[0]);
+}
+
+sub binnormfield {
+  croak("Usage: Catacomb::GF::binnormfield(p, beta)") unless @_ == 2;
+  return Catacomb::Field->binnormfield($_[0], $_[1]);
+}
+
+sub binpolygroup {
+  croak("Usage: Catacomb::GF::binpolygroup(p, g, q)") unless @_ == 3;
+  return Catacomb::Group->binary(@_);
+}
+
+sub mod { (&div($_[0], $_[1]))[1]; }
+
+sub pow {
+  croak("Usage: Catacomb::GF::pow(a, b)") unless @_ == 2;
+  my ($a, $b) = @_;
+  my $r = Catacomb::GF->new(1);
+  while ($b) {
+    $r *= $a if $b & 1;
+    $a = sqr($a);
+    $b >>= 1;
+  }
+  return $r;
+}
+
+sub _binop {
+  my ($func, $a, $b, $flag) = @_;
+  return new(undef, $flag ? &$func($b, $a) : &$func($a, $b));
+}
+
+sub modexp {
+  croak("Usage: Catacomb::GF::modexp(p, g, x)") unless @_ == 3;
+  my ($p, $g, $x) = @_;
+  my $r = Catacomb::GF::Reduce->new($p);
+  $g = $r->reduce($g);
+  return $r->exp($g, $x);
+}
+
+sub modinv {
+  croak("Usage: Catacomb::GF::modinv(p, g)") unless @_ == 3;
+  my ($g, undef, $i) = gcd($_[0], $_[1]);
+  croak("Arguments aren't coprime in Catacomb::GF::modinv") unless $g == 1;
+  return $i;
+}
+
+#----- That's all, folks ----------------------------------------------------