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 1.222 second using v1.01-cache-2.11-cpan-f4a522933cf )