Crypto-Utils

 view release on metacpan or  search on metacpan

lib/Crypto/Utils/OPAQUE.pm  view on Meta::CPAN

use Carp;

use Storable qw(dclone);
use Crypto::Utils::OpenSSL;
use Crypto::Utils::OPRF;

our $VERSION = 0.012;

our @ISA    = qw(Exporter);
our @EXPORT = qw/
  create_cleartext_credentials
  store
  recover
  create_registration_request
  create_registration_response
  finalize_registration_request
  derive_random_pwd
  create_credential_request
  create_credential_response
  recover_credentials
  /;

our @EXPORT_OK = @EXPORT;

sub recover_credentials {

    my (
        $cred_request,    $cred_response,       $pwd,
        $c_id,            $s_id,                $Nseed,
        $group_name,      $info,                $DST,
        $hash_name,       $expand_message_func, $mac_func,
        $pwd_harden_func, $unpack_func
    ) = @_;

    my $evaluate_element =

lib/Crypto/Utils/OPAQUE.pm  view on Meta::CPAN

        $randomized_pwd, $s_pub,     $envelope,            $s_id,
        $c_id,           $Nseed,     $group_name,          $info,
        $DST,            $hash_name, $expand_message_func, $mac_func
    );
    $recover_r->{s_pub} = $s_pub;
    ### recover s_pub: unpack("H*", $s_pub)
    ### recover c_priv:  BN_bn2hex($recover_r->{c_priv})
    ### recover export_key: unpack("H*", $recover_r->{export_key})

    return $recover_r;
} ## end sub recover_credentials

sub create_credential_response {
    my (
        $request,               $s_pub,               $oprf_seed,
        $credential_identifier, $DSI,                 $envelope,
        $masking_key,           $Nn,                  $Nseed,
        $group_name,            $info,                $DST,
        $hash_name,             $expand_message_func, $point_compress_t,
        $pack_func
    ) = @_;

lib/Crypto/Utils/OPAQUE.pm  view on Meta::CPAN

    ( $blind, $blindedElement ) =
      blind( $pwd, $blind, $DSI, $group_name, $type, $hash_name,
        $expand_message_func, $clear_cofactor_flag );

    my $ec_params          = get_ec_params($group_name);
    my $blindedElement_hex = sn_point2hex( $group_name, $blindedElement, 2 );
    my $request            = { data => pack( "H*", $blindedElement_hex ) };
    return { request => $request, blind => $blind, ec_params => $ec_params };
}

sub create_cleartext_credentials {
    my ( $s_pub, $c_pub, $s_id, $c_id ) = @_;

    $s_id //= $s_pub;
    $c_id //= $c_pub;

    my $cleartext_credentials =
      join( "", $s_pub, map { i2osp( length($_), 2 ) . $_ } ( $s_id, $c_id ) );

    return $cleartext_credentials;
}

sub store {
    my (
        $randomized_pwd, $s_pub,     $s_id,                $c_id,
        $Nn,             $Nseed,     $group_name,          $info,
        $DST,            $hash_name, $expand_message_func, $mac_func
    ) = @_;
    my $envelope_nonce_bn = is_bn($Nn) ? $Nn : random_bn($Nn);
    my $envelope_nonce    = BN_bn2bin($envelope_nonce_bn);

lib/Crypto/Utils/OPAQUE.pm  view on Meta::CPAN

    ### seed: unpack("H*", $seed)

    my $c_ec_key_r =
      derive_key_pair( $group_name, $seed, $info, $DST, $hash_name,
        $expand_message_func );
    my $c_priv = $c_ec_key_r->{priv_bn};
    my $c_pub  = $c_ec_key_r->{pub_bin};
    ### c_priv: BN_bn2hex($c_priv)
    ### c_pub: unpack("H*", $c_pub)

    my $cleartext_credentials =
      create_cleartext_credentials( $s_pub, $c_pub, $s_id, $c_id );
    ### cleartext_credentails: unpack("H*", $cleartext_credentials)

    my $auth_tag =
      $mac_func->( $envelope_nonce . $cleartext_credentials, $auth_key );

    my $envelope = { auth_tag => $auth_tag, nonce => $envelope_nonce };

    return {
        envelope              => $envelope,
        c_pub                 => $c_pub,
        masking_key           => $masking_key,
        export_key            => $export_key,
        c_priv                => $c_priv,
        auth_key              => $auth_key,
        cleartext_credentails => $cleartext_credentials,
    };
} ## end sub store

sub recover {
    my (
        $randomized_pwd, $s_pub,     $envelope,            $s_id,
        $c_id,           $Nseed,     $group_name,          $info,
        $DST,            $hash_name, $expand_message_func, $mac_func
    ) = @_;

lib/Crypto/Utils/OPAQUE.pm  view on Meta::CPAN

        $envelope->{nonce} . "PrivateKey", $Nseed );
    ### seed: unpack("H*", $seed)

    my $c_ec_key_r =
      derive_key_pair( $group_name, $seed, $info, $DST, $hash_name,
        $expand_message_func );
    my $c_priv = $c_ec_key_r->{priv_bn};
    my $c_pub  = $c_ec_key_r->{pub_bin};
    ### c_priv: BN_bn2hex($c_priv)

    my $cleartext_credentials =
      create_cleartext_credentials( $s_pub, $c_pub, $s_id, $c_id );
    my $expected_tag =
      $mac_func->( $envelope->{nonce} . $cleartext_credentials, $auth_key );

    if ( $envelope->{auth_tag} ne $expected_tag ) {
        croak "not match envelope.auth_tag";
    }

    return {
        export_key => $export_key,
        c_priv     => $c_priv,
        c_ec_key_r => $c_ec_key_r,
    };

lib/Crypto/Utils/OPAQUE.pm  view on Meta::CPAN

=head1 NAME

L<Crypto::Utils::OPAQUE> 

=head2 PROTOCOL

L<https://datatracker.ietf.org/doc/draft-irtf-cfrg-opaque/>

=head1 FUNCTION

=head2 create_cleartext_credentials
 
 my $cleartext_credentials = create_cleartext_credentials($s_pub, $c_pub, $s_id, $c_id);

=head2 store

 my $store_r = store($randomized_pwd, $s_pub, $s_id, $c_id, $Nn, $Nseed, $group_name, $info, $DST, $hash_name, $expand_message_func, $mac_func);

=head2 recover

 my $recover_r = recover($randomized_pwd, $s_pub, $envelope, $s_id, $c_id, $Nseed, $group_name, $info, $DST, $hash_name, $expand_message_func, $mac_func);

=head2 create_registration_request

lib/Crypto/Utils/OPAQUE.pm  view on Meta::CPAN

  my $randomize_pwd = derive_random_pwd($ec_params, $pwd, $blind, $evaluate_element, $hash_name, $harden_func);

=head2 create_credential_request
  
  my $cred_req_r = create_credential_request($request, $s_pub, $oprf_seed, $credential_identifier, $DSI, $Nseed, $group_name, $info, $DST, $hash_name, $expand_message_func, $point_compress_t);

=head2 create_credential_response

   my $cred_res_r = create_credential_response($request, $s_pub, $oprf_seed, $credential_identifier, $DSI, $envelope, $masking_key, $Nn, $Nseed, $group_name, $info, $DST, $hash_name, $expand_message_func, $point_compress_t, $pack_func);

=head2 recover_credentials

    my $recover_r = recover_credentials($cred_request, $cred_response, $pwd, $c_id, $s_id, $Nseed, $group_name, $info, $DST, $hash_name, $expand_message_func, $mac_func, $pwd_harden_func, $unpack_func);

=cut

t/14.opaque-register.t  view on Meta::CPAN

    my ($r) = @_;
    my $s_pub    = substr $r, 0,  33;
    my $nonce    = substr $r, 33, 32;
    my $auth_tag = substr $r, 65, 32;
    ### r: unpack("H*", $r)
    ### s_pub: unpack("H*", $s_pub)
    ### nonce: unpack("H*", $nonce)
    ### auth_tag: unpack("H*", $auth_tag)
    return [ $s_pub, $nonce, $auth_tag ];
};
my $recover_r = recover_credentials(
    $cred_req_r,      $cred_res_r,          $pwd,
    $c_id,            $s_id,                $Nseed,
    $group_name,      $finalize_info,       $finalize_DST,
    $hash_name,       $expand_message_func, $mac_func,
    $pwd_harden_func, $unpack_func
);
is(
    BN_bn2hex( $recover_r->{c_priv} ),
    'D1D280F712E4EBF3C881C686E13C281BC3A3FAB30A00411A350F4F8B7A1EA550',
    'recover_credentials'
);
is(
    $recover_r->{export_key},
    pack( "H*",
        '77869b0d11debf6fc88c1d192dde9546baf528b2f70c2aea89960fc2178586da' ),
    'recover_credentials'
);

done_testing;

1;

t/15.opaque-sigma_i.t  view on Meta::CPAN

    my ($r) = @_;
    my $s_pub    = substr $r, 0,  33;
    my $nonce    = substr $r, 33, 32;
    my $auth_tag = substr $r, 65, 32;
    ### r: unpack("H*", $r)
    ### s_pub: unpack("H*", $s_pub)
    ### nonce: unpack("H*", $nonce)
    ### auth_tag: unpack("H*", $auth_tag)
    return [ $s_pub, $nonce, $auth_tag ];
};
my $recover_r = recover_credentials(
    $cred_req_r,      $a_recv_cred_res_r,     $pwd,
    $id_a,            $a_recv_msg2_r->{id_b}, $Nseed,
    $group_name,      $finalize_info,         $finalize_DST,
    $hash_name,       $expand_message_func,   $mac_func,
    $pwd_harden_func, $unpack_func
);

is(
    $recover_r->{export_key},
    pack( "H*",
        '77869b0d11debf6fc88c1d192dde9546baf528b2f70c2aea89960fc2178586da' ),
    'recover_credentials'
);

is(
    BN_bn2hex( $recover_r->{c_priv} ),
    'D1D280F712E4EBF3C881C686E13C281BC3A3FAB30A00411A350F4F8B7A1EA550',
    'recover_credentials'
);

my $a_recover_a_s_priv_pkey =
  gen_ec_key( $group_name, BN_bn2hex( $recover_r->{c_priv} ) );
write_key_to_pem( "$Bin/opaque-a_recover_c_s_priv.pem",
    $a_recover_a_s_priv_pkey );

my $a_recover_b_s_pub_pkey =
  gen_ec_pubkey( $group_name, unpack( "H*", $recover_r->{s_pub} ) );
write_pubkey_to_pem( "$Bin/opaque-a_recover_b_s_pub.pem",



( run in 0.881 second using v1.01-cache-2.11-cpan-f4a522933cf )