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 ----------------------------------------------------