X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb-perl/blobdiff_plain/f9952aec1cf6c64a5681308eea817b6113a37433..fcd15e0b7a3d0f0ca2f30953573f8d1f6b8e8bd2:/Catacomb/GF.pm diff --git a/Catacomb/GF.pm b/Catacomb/GF.pm new file mode 100644 index 0000000..633bf78 --- /dev/null +++ b/Catacomb/GF.pm @@ -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 ----------------------------------------------------