File Coverage

blib/lib/Crypt/Passphrase/Argon2.pm
Criterion Covered Total %
statement 33 34 97.0
branch 2 4 50.0
condition 12 16 75.0
subroutine 10 11 90.9
pod 5 5 100.0
total 62 70 88.5


line stmt bran cond sub pod time code
1             package Crypt::Passphrase::Argon2;
2             $Crypt::Passphrase::Argon2::VERSION = '0.010';
3 4     4   224380 use strict;
  4         9  
  4         156  
4 4     4   15 use warnings;
  4         6  
  4         230  
5              
6 4     4   340 use parent 'Crypt::Passphrase::Encoder';
  4         229  
  4         23  
7              
8 4     4   7738 use Carp 'croak';
  4         9  
  4         240  
9 4     4   1432 use Crypt::Argon2 0.017 qw/argon2_pass argon2_needs_rehash argon2_verify argon2_types/;
  4         2683  
  4         1789  
10              
11             my %settings_for = (
12             interactive => {
13             time_cost => 2,
14             memory_cost => '64M',
15             },
16             moderate => {
17             time_cost => 3,
18             memory_cost => '256M',
19             },
20             sensitive => {
21             time_cost => 4,
22             memory_cost => '1G',
23             }
24             );
25              
26             my %valid_types = map { ($_ => 1) } argon2_types;
27              
28             sub _settings_for {
29 5     5   24 my %args = @_;
30 5   50     34 my $subtype = $args{subtype} // 'argon2id';
31 5 50       30 croak "Unknown subtype $subtype" unless $valid_types{$subtype};
32 5   100     20 my $profile = $args{profile} // 'moderate';
33 5 50       19 croak "Unknown profile $profile" unless $settings_for{$profile};
34             return {
35             memory_cost => $args{memory_cost} // $settings_for{$profile}{memory_cost},
36             time_cost => $args{time_cost} // $settings_for{$profile}{time_cost},
37             parallelism => $args{parallelism} // 1,
38             output_size => $args{output_size} // 32,
39 5   66     107 salt_size => $args{salt_size} // 16,
      66        
      50        
      100        
      100        
40             subtype => $subtype,
41             };
42             }
43              
44             sub new {
45 3     3 1 140827 my ($class, %args) = @_;
46 3         17 return bless _settings_for(%args), $class;
47             }
48              
49             sub hash_password {
50 2     2 1 17 my ($self, $password) = @_;
51 2         28 my $salt = $self->random_bytes($self->{salt_size});
52 2         56 local $SIG{__DIE__} = \&Carp::croak;
53 2         6 return argon2_pass($self->{subtype}, $password, $salt, @{$self}{qw/time_cost memory_cost parallelism output_size/});
  2         453932  
54             }
55              
56             sub needs_rehash {
57 5     5 1 20 my ($self, $hash) = @_;
58 5         19 return argon2_needs_rehash($hash, @{$self}{qw/subtype time_cost memory_cost parallelism output_size salt_size/});
  5         51  
59             }
60              
61             sub crypt_subtypes {
62 0     0 1 0 return argon2_types;
63             }
64              
65             sub verify_password {
66 5     5 1 69791 my ($class, $password, $hash) = @_;
67 5         335922 return argon2_verify($hash, $password);
68             }
69              
70             #ABSTRACT: An Argon2 encoder for Crypt::Passphrase
71              
72             __END__