=head1 NAME Catacomb - cryptographic library =head1 SYNOPSIS use Catacomb qw(:const :mp :random :pgen); $x = Catacomb::MP->new($str, [$radix]); $x = Catacomb::MP->new($i); $x = Catacomb::MP->loadb($bytes); $x = Catacomb::MP->loadl($bytes); $x = Catacomb::MP->loadb2c($bytes); $x = Catacomb::MP->loadl2c($bytes); ($x, $rest) = Catacomb::MP->fromstring($str, [$radix]); $x = mp($str, [$radix]); $x = mp($i); ($x, $rest) = mp_fromstring($str, [$radix]); $a = $b + $c; $a = $b - $c; $a = $b * $c; $a = $b / $c; $a = $b % $c; $a = $b ** $n; $a = $b << $n; $a = $b >> $n; $a = $b & $c; $a = $b | $c; $a = $b ^ $c; $a = ~$b; $p = $b == $c; $p = $b != $c; $p = $b < $c; $p = $b > $c; $p = $b <= $c; $p = $b >= $c; $a = sqrt($b); $a = -$b; $a = $b->add($c); $a = $b->sub($c); $a = $b->mul($c); ($q, $r) = $a->div($b); $a = $b->exp($c); $a = $b->sqr(); $a = $b->sqrt(); $a = $b->neg(); $a = $b->not(); $a = $b->not2c(); $a = $b->mod($c); $p = $b->eq($c); $cmp = $b->cmp($c); $a = $b->and($c); $a = $b->and2c($c); $a = $b->or($c); $a = $b->or2c($c); $a = $b->xor($c); $a = $b->xor2c($c); $a = $b->nand($c); $a = $b->nand2c($c); $a = $b->nor($c); $a = $b->nor2c($c); $a = $b->not(); $a = $b->not2c(); $a = $b->lsl($n); $a = $b->lsl2c($n); $a = $b->lsr($n); $a = $b->lsr2c($n); $a = $b->setbit($n); $a = $b->setbit2c($n); $a = $b->clearbit($n); $a = $b->clearbit2c($n); $p = $b->testbit($n); $p = $b->testbit2c($n); $x = $y->copy(); # largely useless $g = $a->gcd($b); ($g, $u, $v) = $a->gcd($b); ($s, $t) = $m->odd(); # m = 2^s t $a = $p->modexp($x, $e); $a = $p->modinv($b); $r = $p->modsqrt($x); $q = $n->jac($a); $p = $x->primep([$rng]); $nbits = $x->bits(); $nbytes = $x->octets(); $bytes = $x->storeb([$nbytes]); $bytes = $x->storel([$nbytes]); $bytes = $x->storeb2c([$nbytes]); $bytes = $x->storel2c([$nbytes]); $str = $x->tostring([$radix]); $n = $x->toint(); $barrett = Catacomb::MP::Barrett->new($p); $barrett = $p->barrett(); $p = $barrett->m(); $x = $barrett->reduce($y); $a = $barrett->exp($x, $y); $mont = Catacomb::MP::Mont->new($p); $mont = $p->mont(); $r = $mont->r(); $r2 = $mont->r2(); $p = $mont->m(); $x = $mont->in($y); $a = $mont->mul($x, $y); $a = $mont->expr($x, $y); $a = $mont->mexpr($x0, $e0, $x1, $e1, ...); $x = $mont->reduce($y); $x = $mont->out($y); $a = $mont->exp($x, $y); $a = $mont->mexp($x0, $e0, $x1, $e1, ...); $reduce = Catacomb::MP::Reduce->new($p); $reduce = $p->mkreduce(); $p = $reduce->m(); $x = $reduce->reduce($y); $a = $barrett->exp($x, $y); $crt = Catacomb::MP::CRT->new(@n); $n = $crt->product(); @n = $crt->moduli(); $x = $crt->solve(@r); $p = newprime($nbits, [$rng]); $filt = Catacomb::MP::Prime::Filter->new($x); $filt = $x->filter(); $rc = $filt->status(); $x = $filt->m(); $rc = $filt->step($n); $rc = $filt->jump($jfilt); $newfilt = $filt->muladd($mul, $add); # integers $stepper = Catacomb::MP::Prime::Filter->stepper($step); # integer $stepper = filterstepper($step); $jumper = Catacomb::MP::Prime::Filter->stepper($jump); # MP $jumper = filterjumper($jump); $rabin = Catacomb::MP::Prime::Rabin->new($m); $rabin = $p->rabin(); $m = $rabin->m(); $rc = $rabin->test($wit); $n = $rabin->iters(); $n = Catacomb::MP::Prime::Rabin->ntests($bits); $tester = Catacomb::MP::Prime::Rabin->tester(); $tester = $rabintester; $events = Catacomb::MP::Prime::Gen::Proc->ev(); $events = Catacomb::MP::Prime::Gen::Proc->evspin(); $events = Catacomb::MP::Prime::Gen::Proc->subev(); $p = Catacomb::MP::Prime->gen ($name, $x, $nsteps, $stepper, $ntests, $tester, [$events]); $p = primegen ($name, $x, $nsteps, $stepper, $ntests, $tester, [$events]); if (($x, $j) = Catacomb::MP::Prime->strongprime_setup ($name, $nbits, [$rng], [$nsteps], [$subevents])) { $p = Catacomb::MP::Prime->gen ($name, $x, $nsteps, $j, $ntests, $tester, [$events]); } ($p, @f) = Catacomb::MP::Prime->limlee ($name, $qbits, $pbits, [$rng], [$on], [$oev], [$iev]); ($p, @f) = limleegen ($name, $qbits, $pbits, [$rng], [$on], [$oev], [$iev]); package MyPrimeGenObject; sub new { ... }; sub BEGIN { ... }; sub TRY { ... }; sub FAIL { ... }; sub PASS { ... }; sub DONE { ... }; sub ABORT { ... }; $name = $ev->name(); $x = $ev->m([$xx]); $rng = $ev->rand(); $a = Catacomb::GF->new($x); $a = Catacomb::GF->loadb($bytes); $a = Catacomb::GF->loadl($bytes); ($x, $rest) = Catacomb::GF->fromstring($str, [$radix]); $a = gf($mp); $a = gf($str); $a = gf($i); $a = gf_loadb($bytes); $a = gf_loadl($bytes); ($x, $rest) = gf_fromstring($str, [$radix]); $x = mp($a); $a = $b + $c; $a = $b - $c; # same as + $a = $b * $c; $a = $b / $c; $a = $b % $c; $a = $b << $n; $a = $b >> $n; $a = $b & $c; $a = $b | $c; $a = $b ^ $c; $a = ~$b; $p = $b == $c; $p = $b != $c; $a = -$b; # does nothing $a = $b->copy(); # largely pointless $a = $b->add($c); $a = $b->sub($c); $a = $b->mul($c); $a = $b->sqr(); ($q, $r) = $a->div($b); $a = $b->lsl($n); $a = $b->lsr($n); $a = $b->and($c); $a = $b->or($c); $a = $b->xor($c); $a = $b->nand($c); $a = $b->nor($c); $a = $b->setbit($n); $a = $b->clearbit($n); $g = $a->gcd($b); ($g, $u, $v) = $a->gcd($b); $p = $p->irreduciblep(); $a = $b->modinv($c); $a = $b->modexp($c, $n); # and all the Catacomb::MP methods $F = Catacomb::Field->prime($p); $F = Catacomb::Field->niceprime($p); $F = Catacomb::Field->binpoly($p); $F = Catacomb::Field->binnorm($p, $beta); $F = Catacomb::Field->byname($name); $F = $p->primefield(); $F = $p->niceprimefield(); $F = $p->binpolyfield(); $F = $p>binnormfield($beta); $name = $F->name(); $ty = $F->type(); $info = $F->get(); $p = $F->samep($FF); $q = $F->q(); $m = $F->m(); $nbits = $F->nbits(); $nbytes = $F-noctets(); $xi = $F->in($x); $x = $F->out($xi); $p = $F->zerop($xi); $xi = $F->neg($yi); $xi = $F->add($yi, $zi); $xi = $F->sub($yi, $zi); $xi = $F->mul($yi, $zi); $xi = $F->div($yi, $zi); $xi = $F->sqr($yi, $zi); $xi = $F->inv($yi); $xi = $F->reduce($yi); $xi = $F->sqrt($yi); $xi = $F->quadsolve($yi); $xi = $F->dbl($yi); $xi = $F->tpl($yi); $xi = $F->hlv($yi); $e = Catacomb::Field::Elt->new($F, $x); $e = $F->elt($x); $e = $F->zero(); $e = $F->one(); $e = $F->rand([$rng]); $F = $e->field(); $x = $e->value(); $str = $e->tostring([$radix]); $e = $f->inv(); $e = $f + $g; $e = $f - $g; $e = $f * $g; $e = $f / $g; $e = $f ** $n; $p = $f == $g; $p = $f != $g; $e = -$f; $e = sqrt($f); $p = $f->zerop(); $P = Catacomb::EC::Point->new([$x], [$y], [$z]); ($P, $rest) = Catacomb::EC::Point->get($buf); $p = $P->atinfp(); $x = $P->x(); $y = $P->y(); $z = $P->z(); $p = $P->eq($Q); $buf = $P->put(); $str = $P->tostring(); $C = Catacomb::EC::Curve->prime($F, $a, $b); $C = Catacomb::EC::Curve->primeproj($F, $a, $b); $C = Catacomb::EC::Curve->bin($F, $a, $b); $C = Catacomb::EC::Curve->binproj($F, $a, $b); ($C, $G, $r, $h) = Catacomb::EC::Curve->getinfo($name); $C = $F->primecurve($F, $a, $b); $C = $F->primeprojcurve($F, $a, $b); $C = $F->bincurve($F, $a, $b); $C = $F->binprojcurve($F, $a, $b); $name = $C->name(); $a = $C->a(); $b = $C->b(); $F = $C->field(); $info = $C->get(); $p = $C->samep($CC); $bytes = $C->putraw($P); ($pp, $rest) = $C->getraw($bytes); $buf = $C->putraw($P); ($P, $rest) = $C->getraw($buf); $P = $C->neg($Q); $P = $C->add($Q, $R); $P = $C->dbl($Q); $p = $C->check($P); $P = $C->mul($Q, $n); $P = $C->mmul($P0, $n0, $P1, $n1, ...); $err = $C->checkinfo($G, $r, $h); $Pi = $C->in($P); $Pi = $C->fix($Pi); $Pi = $C->ifind($xi); $Pi = $C->ineg($Qi); $Pi = $C->iadd($Qi, $Ri); $Pi = $C->isub($Qi, $Ri); $Pi = $C->idbl($Qi); $p = $C->icheck($Pi); $Pi = $C->imul($Qi, $n); $Pi = $C->immul($Qi0, $n0, $Qi1, $n1, ...); $P = $C->out($Pi); $P = Catacomb::EC::Point->new($C, [$p]); $P = Catacomb::EC::Point->new($C, $x, $y); $P = $C->inf(); $P = $C->pt($p); $P = $C->pt($x, $y); $P = $C->find($x); $P = $C->rand([$rng]); $C = $P->curve(); $F = $P->field(); $P = $Q->point(); $p = $P->atinfp(); $x = $P->x(); $y = $P->y(); $p = $P->check(); $P = $Q->mul($n); $P = $Q + $R; $P = $Q - $R; $P = $Q * $n; $P = $n * $Q; $p = $Q == $R; $p = $Q != $R; $P = -$Q; $G = Catacomb::Group->prime($p, $g, $q); $G = Catacomb::Group->binary($p, $g, $q); $G = Catacomb::Group->ec($C, $G, $r, $h); $G = Catacomb::Group->byname($name); $G = $p->primegroup($g, $q); $G = $p->binpolygroup($g, $q); $G = $C->ecgroup($G, $r, $h); $info = $G->get(); $a = $G->mexp($a0, $n0, $a1, $n1, ...); $p = $G->samep($GG); $r = $G->r(); $h = $G->h(); ($p, $err) = $G->check($rng); $a = Catacomb::Group::Elt($G, [$x]); $a = $G->elt([$x]); $a = $G->id(); $g = $G->g(); $a = $G->fromint($x); $a = $G->fromec($P); ($a, $rest) = $G->frombuf($buf); ($a, $rest) = $G->fromraw($buf); ($a, $rest) = $G->fromstring($str); $x = $a->toint(); $P = $a->toec(); $buf = $a->tobuf(); $buf = $a->toraw(); $str = $a->tostring(); $G = $a->group(); $p = $a->identp(); $p = $a->check(); $a = $b->exp($n); $a = $b->inv(); $a = $b * $c; $a = $b / $c; $a = $b ** $n; $p = $b == $c; $p = $b != $c; $pc = Catacomb::PRPClass->find($name); $pc = $Catacomb::rijndael; $ksz = $pc->keysz(); $name = $pc->name(); $blksz = $pc->blksz(); $ct = $pc->eblk($k, $pt); $pt = $pc->eblk($k, $ct); $P = $pc->init($k); $ct = $P->eblk($pt); $pt = $P->dblk($ct); $pc = $P->class(); $cc = Catacomb::CipherClass->find($name); $cc = $Catacomb::rijndael_cbc; $ksz = $cc->keysz(); $name = $cc->name(); $blksz = $cc->blksz(); $ct = $cc->encrypt($k, $pt, [$iv]); $pt = $cc->decrypt($k, $ct, [$iv]); $c = $cc->init(); $ct = $c->encrypt($pt); $pt = $c->decrypt($ct); $c->setiv($iv); $c->bdry(); $pc = $c->class(); $hc = Catacomb::HashClass->find($name); $hc = $Catacomb::sha; $hsz = $hc->hashsz(); $name = $hc->name(); $res = $hc->hash($msg); $h = $hc->init(); $h->hash($buf); # as often as necessary $hh = $h->copy(); $hc = $h->class(); $res = $h->done(); $mc = Catacomb::MACClass->find($name); $mc = $Catacomb::sha_hmac; $hsz = $mc->hashsz(); $ksz = $mc->keysz(); $name = $mc->name(); $t = $mc->mac($k, $msg); $m = $mc->key($k); $mc = $m->class(); $t = $m->hash($msg); $h = $m->init(); $rng = Catacomb::Rand::True->new(); $rng = Catacomb::random; $rng->gate(); $rng->stretch(); $rng->key($k); $rng->noisesrc(); $rng->seed([$nbits]); $rng = Catacomb::Rand::DSA->new($k); $rng->passes($n); $k = $rng->seed(); $rng = Catacomb::Rand::Fib->new($seed); $rng = Catacomb::Rand::LC->new($seed); $rng = Catacomb::Rand::RC4->new($k); $rng = Catacomb::Rand::SEAL->new($k); $rng = Catacomb::Rand::MGF->new($name, $k); $rng = Catacomb::Rand::Counter->new($name, $k); $rng = Catacomb::Rand::OFB->new($name, $k); $rng->seedint($i); $rng->seedblock($buf); $rng->seedmp($x); $rng->seedrand($rng2); $u = $rng->raw(); $u = $rng->word(); $b = $rng->byte(); $c = $rng->char(); $u = $rng->range($max); $x = $rng->mp($nbits, [$or]); $x = $rng->mprange($max); $buf = $rng->fill($nbytes); $name = $rng->name(); $f = $rng->flags(); $u = $rng->max(); ($p, $g, $q) = Catacomb::PubKey->gen_dh ($ql, $pl, [$steps], [$r], [$events]); ($p, $g, $q, @f) = Catacomb::PubKey->gen_limlee ($ql, $pl, [$flags], [$steps], [$r], [$oevents], [$ievents]); ($p, $g, $q, $seed, $count) = Catacomb::PubKey->gen_dsa ($ql, $pl, [$steps], [$k], [$events]); $dsapub = Catacomb::DSA::Public->new([$G, $p, $hunoz, $h, $rng]); $dsapub = Catacomb::DSA::Public->new ({ G => $G, p => $p, h => $h, rng => $rng}); $h = $dsapub->beginhash(); $dsapub->endhash($h); $p = $dsapub->verify($msg, $r, $s); $dsapriv = Catacomb::DSA::Private->new([$G, $p, $u, $h, $rng]); ($r, $s) = $dsapriv->sign($msg, [$k]); $kcdsapub = Catacomb::KCDSA::Public->new([$G, $p, $hunoz, $h, $rng]); $h = $kcdsapub->beginhash(); $kcdsapub->endhash($h); $p = $kcdsapub->verify($msg, $r, $s); $kcdsapriv = Catacomb::KCDSA::Private->new([$G, $p, $u, $h, $rng]); ($r, $s) = $kcdsapriv->sign($msg, [$k]); $p1pad = Catacomb::RSA::PKCS1Crypt->new([$ep, $rng]); $p1pad = Catacomb::RSA::PKCS1Sign->new([$ep, $rng]); $oaeppad = Catacomb::RSA::OAEP->new([$c, $h, $ep, $rng]); $psspad = Catacomb::RSA::PSS->new([$c, $h, $ssz, $rng]); $x = $pad->pad($m, $sz, $nbits); $m = $cryptpad->unpad($m, $sz, $nbits); $m = $sigpad->unpad($s, $m, $sz, $nbits); $rsapub = Catacomb::RSA::Public->new([$n, $e]); $rsapub = Catacomb::RSA::Public->new({ n => $n, e => $e }); $n = $rsapub->n(); $h = $rsapub->extract(); $x = $rsapub->op($y); $c = $rsapub->encrypt($cryptpad, $m); $rc = $rsapub->verify($signpad, $s, [$m]); $rsapriv = Catacomb::RSA::Private->new ([$n, $e, $d, $p, $q, $dp, $dq, $qi]); $rsapriv = Catacomb::RSA::Public->new ({ n => $n, e => $e, d => $d, p => $p, q => $q, dp => $dp, dq => $dq, qi => $qi }); $rsapriv = Catacomb::RSA::Private->generate ($nbits, [$rng], [$steps], [$events]); $n = $rsapriv->n(); $h = $rsapriv->extract(); $x = $rsapriv->op($y, [$rng]); $m = $rsapriv->decrypt($cryptpad, $c, [$rng]); $s = $rsapriv->sign($signpad, $m, [$rng]); $s = Catacomb::Share::GF->new($t, $sz); $sz = $s->sz(); $t = $s->t(); $i = $s->i(); $s->mkshares($secret, [$rng]); $share = $s->get($i); $left = $s->add($i, $share); $secret = $s->combine(); $s = Catacomb::Share::Prime->new($t, [$p]); $p = $s->p(); $t = $s->t(); $i = $s->i(); $s->mkshares($secret, [$rng]); $share = $s->get($i); $left = $s->add($i, $share); $secret = $s->combine(); $pp = Catacomb::Passphrase->read($tag, [$len]); $pp = Catacomb::Passphrase->verify($tag, [$len]); Catacomb::Passphrase->cancel($tag); $ssz = $ksz->keysz($sz); @ksz = $ksz->expand(); $kf = Catacomb::Key::File->new($name, [$kopen], [$reporter]); $p = $kf->merge($name, $fh, [$reporter]); $p = $kf->extract($key, $fh, [$kfilt]); $kwriteerr = $kf->save(); $i = $kf->iterate(); $key = $i->next(); $key = $kf->bytype($kf, $type); $key = $kf->byid($kf, $id); $key = $kf->bytag($kf, $tag); $key = $kf->newkey($kf, $id, $type, $exp); ($key, $kd, $ftag) = $kf->qtag($qtag); $p = $key->chkident($id); $p = $key->chkcomment($id); $exp = $key->exp(); $exp = $key->del(); $comm = $key->comment(); $id = $key->id(); $tag = $key->tag(); $type = $key->type(); $p = $key->setcomment($comm); $p = $key->settag($tag); $p = $key->delete(); $ftag = $key->fulltag(); $v = $key->getattr($a); $p = $key->putattr($a, $v); $p = $key->expiredp(); $p = $key->used(); $p = $key->fingerprint($h, [$kfilt]); $Catacomb::Key::error; $str = Catacomb::Key->strerror($errnum); $ah = $key->attrs(); # returns hashref $i = $key->attriter(); ($a, $v) = $i->next(); $kfilt = Catacomb::Key::Filter->new($f, $m); $kfilt = Catacomb::Key::Filter->new($fstr); $fstr = $kfilt->tostring(); $f = $kfilt->f(); $m = $kfilt->m(); $kd = Catacomb::Key::Data->new(); ($kd, $rest) = Catacomb::Key::Data->read($str); $kd = Catacomb::Key::Data->decode($buf); $kd = $key->data(); $kd->setbinary($bin); $kd->setencrypted($crypted); $kd->setmp($x); $kd->setstring($str); $kd->setec($P); $f = $kd->flags(); $bin = $kd->getbinary(); $crypted = $kd->getcrypted(); $x = $kd->getmp(); $str = $kd->getstring(); $P = $kd->getec(); $kd->setstruct(); $kkd = $kd->structfind($t); $kkd = $kd->structcreate($t); $kd->structdel($t); $kh = $kd->structopen(); # returns hashref $kkd = $kd->copy(); $kkd = $kd->lock($k); $kkd = $kd->unlock($k); $kkd = $kd->plock($tag); $kkd = $kd->punlock($tag); $str = $kd->write(); $buf = $kd->encode(); $i = $kd->structiter(); =head1 DESCRIPTION =head1 SEE ALSO Catacomb(3). =head1 AUTHOR Mark Wooding,