7 # (c) 2004 Straylight/Edgeware
10 #----- Licensing notice -----------------------------------------------------
12 # This file is part of the Perl interface to Catacomb.
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.
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.
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.
28 #----- Abstract fields ------------------------------------------------------
30 package Catacomb::Field;
35 $cache = Catacomb::Cache->new();
38 croak("USage: Catacomb::Field::intern(f)") unless @_ == 1;
40 return $cache->intern($f);
44 croak("Usage: Catacomb::Field::elt(f, x)") unless @_ == 2;
46 return Catacomb::Field::Elt->new($f, $x);
50 croak("Usage: Catacomb::Field::zero(f)") unless @_ == 1;
52 return Catacomb::Field::Elt->new($f, $f->_zero());
56 croak("Usage: Catacomb::Field::one(f)") unless @_ == 1;
58 return Catacomb::Field::Elt->new($f, $f->_one());
62 croak("Usage: Catacomb::Field::rand(f, [rng])")
63 unless @_ >= 1 && @_ <= 2;
65 $rng ||= $Catacomb::random;
66 return Catacomb::Field::Elt->new($f, $f->_one($rng));
70 croak("Usage: Catacomb::Field::div(f, x, y)") unless @_ == 3;
72 return $f->mul($x, $f->inv($y));
76 croak("Usage: Catacomb::Field::primecurve(f, a, b)") unless @_ == 3;
78 croak("not a prime field") unless $f->type == Catacomb::FTY_PRIME;
79 return Catacomb::EC::Curve->prime($f, $a, $b);
83 croak("Usage: Catacomb::Field::primeprojcurve(f, a, b)") unless @_ == 3;
85 croak("not a prime field") unless $f->type == Catacomb::FTY_PRIME;
86 return Catacomb::EC::Curve->primeproj($f, $a, $b);
90 croak("Usage: Catacomb::Field::bincurve(f, a, b)") unless @_ == 3;
92 croak("not a prime field") unless $f->type == Catacomb::FTY_BINARY;
93 return Catacomb::EC::Curve->bincurve($f, $a, $b);
97 croak("Usage: Catacomb::Field::binprojcurve(f, a, b)") unless @_ == 3;
99 croak("not a prime field") unless $f->type == Catacomb::FTY_BINARY;
100 return Catacomb::EC::Curve->binproj($f, $a, $b);
103 #----- Field elements -------------------------------------------------------
105 package Catacomb::Field::Elt;
109 sub _elt { bless [@_], Catacomb::Field::Elt; }
112 croak("Usage: Catacomb::Field::Elt::new(me, f, x)"), unless @_ == 3;
113 my ($me, $f, $x) = @_;
115 ($f, $r) = $f->intern();
116 return _elt($f->in($x), $f, $r);
120 croak("Usage: Catacomb::Field::Elt::field(e)") unless @_ == 1;
125 croak("Usage: Catacomb::Field::Elt::value(e)") unless @_ == 1;
126 return $_[0][1]->out($_[0][0]);
130 croak("Usage: Catacomb::Field::Elt::elt(e, x)") unless @_ == 2;
133 return _elt($f->in($x), $f, $e->[2]);
137 croak("Usage: Catacomb::Field::Elt::tostring(e, [radix])")
138 unless @_ >= 1 && @_ <= 2;
139 my ($e, $radix) = @_;
140 $radix = 16 unless defined($radix);
141 return $e->value()->tostring($radix);
145 my ($x, $f, $r) = @_;
146 if (UNIVERSAL::isa($x, Catacomb::Field::Elt)) {
147 croak("field mismatch") unless $f == $x->[1];
151 return _elt($f->_zero(), $f, $r);
154 return _elt($f, $f->_one(), $f, $r);
156 croak("can't convert to field element");
160 my ($op, $x, $y, $swap) = @_;
163 $y = _convert($y, $f, $r);
165 &$op($f, $x->[0], $y->[0]) :
166 &$op($f, $y->[0], $x->[0]);
167 return _elt($z, $f, $r);
174 my $z = &$op($f, $x->[0]);
175 return _elt($z, $f, $r);
179 croak("Usage: Catacomb::Field::Elt::exp(x, n)") unless @_ == 2;
181 my ($xx, $f, $fr) = @$x;
182 return _elt($f->exp($xx, $n), $f, $fr);
186 croak("Usage: Catacomb::Field::Elt::sqrt(x)") unless @_ == 1;
188 my ($xx, $f, $fr) = @$x;
189 return _elt($f->sqrt($xx), $f, $fr);
193 croak("Usage: Catacomb::Field::Elt::zerop(x)") unless @_ == 1;
195 my ($xx, $f, $fr) = @$x;
196 return $f->zero($xx);
201 $y = _convert($y, $x->[1], $x->[2]);
202 return Catacomb::MP::eq($x->[0], $y->[0]);
206 '+' => sub { _binop(\&Catacomb::Field::add, @_); },
207 '-' => sub { _binop(\&Catacomb::Field::sub, @_); },
208 '*' => sub { _binop(\&Catacomb::Field::mul, @_); },
209 '/' => sub { _binop(\&Catacomb::Field::div, @_); },
210 '**' => sub { &exp($_[0], $_[1]); },
211 '==' => sub { _eq(@_); },
212 '!=' => sub { !_eq(@_); },
213 'eq' => sub { _eq(@_); },
214 'ne' => sub { !_eq(@_); },
215 '""' => sub { "0x" . $_[0]->tostring(16); },
216 '0+' => sub { $_[0][1]->toint(); },
217 'sqrt' => sub { _unop(\&Catacomb::Field::sqrt, @_); },
218 'neg' => sub { _unop(\&Catacomb::Field::neg, @_); };
220 sub inv { _unop(\&Catacomb::Field::inv, @_); }
222 #----- That's all, folks ----------------------------------------------------