Algorithm-IRCSRP2

 view release on metacpan or  search on metacpan

lib/Algorithm/IRCSRP2/Alice.pm  view on Meta::CPAN

package Algorithm::IRCSRP2::Alice;

BEGIN {
    $Algorithm::IRCSRP2::Alice::VERSION = '0.501';
}

# ABSTRACT: Alice interface

use Moose;

extends 'Algorithm::IRCSRP2';

with 'Algorithm::IRCSRP2::Exchange';

# core
use MIME::Base64;
use Digest::SHA;

# CPAN
use Crypt::OpenSSL::AES;
use Moose::Util::TypeConstraints qw(enum);

# local
use Algorithm::IRCSRP2::Utils qw(:all);

has '+am_i_dave' => ('default' => 0, 'is' => 'ro');

has 'state' => (
    'isa'     => enum([qw(null error init srpa0 srpa1 srpa2 srpa3 authenticated)]),
    'is'      => 'rw',
    'default' => 'null',
    'trigger' => sub {
        my ($self, $new, $old) = @_;

        $self->debug_cb->("State change $old -> $new");

        if ($new eq 'error') {
            $self->debug_cb->('Fatal error: ', $self->error);
        }
    }
);

sub srpa0 {
    my ($self) = @_;

    $self->state('srpa0');

    return '+srpa0 ' . $self->I();
}

sub verify_srpa1 {
    my ($self, $msg) = @_;

    $msg =~ s/^\+srpa1 //;

    my $decoded = MIME::Base64::decode_base64($msg);

    my $s = substr($decoded, 0, 32, '');
    $self->s($s);

    my $B = $self->B(bytes2int($decoded));

    if ($B->copy->bmod(N()) != 0) {
        $self->state('srpa1');

        return $self->srpa2();
    }
    else {
        $self->error('srpa1');
        $self->state('error');
        return 0;
    }
}

sub srpa2 {
    my ($self) = @_;

    # a = random integer with 1 < a < N.
    my $a = Math::BigInt->new(gen_a());
    $self->a($a);

    # A = g^a (mod N)
    my $A = Math::BigInt->new(g());
    $A->bmodpow($a->bstr, N());
    $self->A($A);

    # x = H(s || I || P)
    my $x = bytes2int(H($self->s . $self->I . $self->P));
    $self->x($x);

    # u = H(A || B)
    my $u = bytes2int(H(int2bytes($A) . int2bytes($self->B)));
    $self->u($u);

    # S = (B - 3g^x)^(a + ux) (mod N)
    my $t = Math::BigInt->new(g());
    $t->bmodpow($x->bstr, N());
    $t->bmul(3);

    my $q = $self->B->copy;
    $q->bsub($t);

    $t = $q->copy;

    my $t2 = $u->copy;
    $t2->bmul($x->bstr);
    $t2->badd($a->bstr);
    $t2->bmod(N());

    my $S = $t->copy;

    $S->bmodpow($t2->bstr, N());
    $self->debug_cb->('h' x 20 . $S->bstr);
    $self->S($S);

    # K1 = H(S || "enc")
    my $K1 = Digest::SHA::sha256(int2bytes($S) . 'enc');
    $self->K1($K1);

    # K2 = H(S || "auth")
    my $K2 = Digest::SHA::sha256(int2bytes($S) . 'auth');



( run in 3.585 seconds using v1.01-cache-2.11-cpan-6b5c3043376 )