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 #----- Elliptic curves ------------------------------------------------------
30 package Catacomb::EC::Curve;
36 $cache = Catacomb::Cache->new();
39 croak("Usage: Catacomb::EC::Curve::intern(c)") unless @_ == 1;
41 return $cache->intern($c);
45 croak("Usage: Catacomb::EC::Curve::pt(c, [x, y | p])")
46 unless @_ >= 1 && @_ <= 3;
47 return Catacomb::EC::Pt->new(@_);
51 croak("Usage: Catacomb::EC::Curve::a(c)") unless @_ == 1;
53 return $c->field()->elt($c->_a());
57 croak("Usage: Catacomb::EC::Curve::b(c)") unless @_ == 1;
59 return $c->field()->elt($c->_b());
63 croak("Usage: Catacomb::EC::Curve::inf(c)") unless @_ == 1;
64 return Catacomb::EC::Pt->new($_[0]);
68 croak("Usage: Catacomb::EC::Curve::getraw(c, s)") unless @_ == 2;
70 my ($p, $rest) = $c->_getraw($s);
71 $p = Catacomb::EC::Pt->new($c, $p);
72 return !wantarray() ? $p : ($p, $rest);
76 croak("Usage: Catacomb::EC::Curve::find(c, x)") unless @_ == 2;
78 my $p = $c->_find($x);
79 return undef unless defined $p;
80 return Catacomb::EC::Pt->new($c, $p);
84 croak("Usage: Catacomb::EC::Curve::rand(c, [rng])")
85 unless @_ >= 1 && @_ <= 2;
87 $rng ||= $Catacomb::random;
88 my $p = $c->_rand($rng);
89 return Catacomb::EC::Pt->new($c, $p);
93 croak("Usage: Catacomb::EC::Curve::mmul(c, p_0, x_0, p_1, x_1, ...)")
94 unless @_ >= 3 && @_ % 2 == 1;
99 for ($i = 0; $i < @_; $i += 2) {
102 if (UNIVERSAL::isa($p, Catacomb::EC::Pt)) {
103 $p->[1] == $c or croak("curve mismatch");
104 @r or @r = @$p[1, 2, 3, 4];
106 } elsif (UNIVERSAL::isa($p, Catacomb::EC::Point)) {
109 croak("not a curve point");
115 ($c, $cr) = $c->intern();
116 ($f, $fr) = $c->field()->intern();
117 @r = ($c, $cr, $f, $fr);
119 return Catacomb::EC::Pt::_pt(immul($c, @v), $c, $cr, $f, $fr);
123 croak("Usage: Catacomb::EC::Curve::getinfo(me, spec)") unless @_ == 2;
124 my ($me, $spec) = @_;
125 my ($c, $p, $r, $h) = _getinfo($me, $spec);
127 ($c, $cr) = $c->intern();
128 return $c, $c->pt($p), $r, $h;
132 croak("Usage: Catacomb::EC::Curve::ecgroup(c, p, r, h)") unless @_ == 4;
133 return Catacomb::Group->ec(@_);
136 #----- Elliptic curve points ------------------------------------------------
138 package Catacomb::EC::Point;
141 croak("Usage: Catacomb::EC::Point::tostring(p)") unless @_ == 1;
146 return "0x" . $p->x()->tostring(16) . ", 0x" . $p->y()->tostring(16);
150 package Catacomb::EC::Pt;
155 sub _pt { bless [@_], Catacomb::EC::Pt; }
158 my ($c, $cr, $f, $fr, $x) = @_;
159 if (UNIVERSAL::isa($x, Catacomb::EC::Pt)) {
160 croak("curve mismatch") unless $c == $x->[1];
163 if (UNIVERSAL::isa($x, Catacomb::EC::Point)) {
164 return _pt($x, $c, $cr, $f, $fr);
166 croak("can't convert to curve point");
170 croak("Usage: Catacomb::EC::Pt::new(me, c, [x, y | p])")
171 unless @_ >= 2 && @_ <= 4;
175 $p = Catacomb::EC::Point->new();
178 if (UNIVERSAL::isa($p, Catacomb::EC::Pt)) {
180 } elsif (!UNIVERSAL::isa($p, Catacomb::EC::Point)) {
181 croak("not a curve point");
185 ($me, $c, $x, $y) = @_;
186 $p = Catacomb::EC::Point->new($x, $y);
189 ($c, $cr) = $c->intern();
190 ($f, $fr) = $c->field()->intern();
191 return _pt($c->in($p), $c, $cr, $f, $fr);
195 croak("Usage: Catacomb::EC::Pt::point(p)") unless @_ == 1;
196 return $_[0][1]->out($_[0][0]);
200 croak("Usage: Catacomb::EC::Pt::curve(p)") unless @_ == 1;
205 croak("Usage: Catacomb::EC::Pt::field(p)") unless @_ == 1;
210 croak("Usage: Catacomb::EC::Pt::atinfp(p)") unless @_ == 1;
211 return $_[0]->point()->atinfp();
215 croak("Usage: Catacomb::EC::Pt::x(p)") unless @_ == 1;
216 return $_[0][3]->elt($_[0]->point()->x());
220 croak("Usage: Catacomb::EC::Pt::y(p)") unless @_ == 1;
221 return $_[0][3]->elt($_[0]->point()->y());
225 croak("Usage: Catacomb::EC::Curve::check(c)") unless @_ == 1;
226 return $_[0][1]->check($_[0][0]);
230 croak("Usage: Catacomb::EC::Pt::pt(pp, [x, y | p])")
231 unless @_ >= 1 && @_ <= 3;
235 $p = Catacomb::EC::Point->new();
238 if (UNIVERSAL::isa($p, Catacomb::EC::Pt)) {
240 } elsif (!UNIVERSAL::isa($p, Catacomb::EC::Point)) {
241 croak("not a curve point");
246 $p = Catacomb::EC::Point->new($x, $y);
248 my (undef, $c, $cr, $f, $fr) = @$pp;
249 return _pt($c->in($p), $c, $cr, $f, $fr);
253 my ($op, $x, $y, $swap) = @_;
254 my (undef, $c, $cr, $f, $fr) = @$x;
255 $y = _convert($c, $cr, $f, $fr, $y);
257 &$op($c, $x->[0], $y->[0]) :
258 &$op($c, $y->[0], $x->[0]);
259 return _pt($z, $c, $cr, $f, $fr);
264 my (undef, $c, $cr, $f, $fr) = @$x;
265 my $z = &$op($c, $x->[0]);
266 return _pt($z, $c, $cr, $f, $fr);
271 my (undef, $c, $cr, $f, $fr) = @$x;
272 $y = _convert($c, $cr, $f, $fr, $y);
273 return Catacomb::EC::Point::eq($c->out($x), $c->out($y));
277 croak("Usage: Catacomb::EC::Pt::mul(p, n)") unless @_ == 2;
279 my ($pp, $c, $cr, $f, $fr) = @$p;
280 return _pt($c->imul($pp, $x), $c, $cr, $f, $fr);
284 '+' => sub { _binop(\&Catacomb::EC::Curve::iadd, @_); },
285 '-' => sub { _binop(\&Catacomb::EC::Curve::isub, @_); },
286 '*' => sub { mul($_[0], $_[1]); },
287 '==' => sub { _eq(@_); },
288 '!=' => sub { !_eq(@_); },
289 'eq' => sub { _eq(@_); },
290 'ne' => sub { !_eq(@_); },
291 '""' => sub { $_[0]->point()->tostring(); },
292 '0+' => sub { $_[0]->point()->x()->toint(); },
293 'neg' => sub { _unop(\&Catacomb::EC::Curve::ineg, @_); };
295 #----- That's all, folks ----------------------------------------------------