File Coverage

blib/lib/Crypt/Curve25519.pm
Criterion Covered Total %
statement 26 29 89.6
branch 4 6 66.6
condition n/a
subroutine 8 9 88.8
pod 6 6 100.0
total 44 50 88.0


line stmt bran cond sub pod time code
1             package Crypt::Curve25519;
2             our $AUTHORITY = 'cpan:AJGB';
3             #ABSTRACT: Generate shared secret using elliptic-curve Diffie-Hellman function
4             $Crypt::Curve25519::VERSION = '0.06';
5 6     6   87059 use strict;
  6         10  
  6         152  
6 6     6   24 use warnings;
  6         9  
  6         192  
7 6     6   23 use Carp qw( croak );
  6         8  
  6         2641  
8              
9             require Exporter;
10             our @ISA = qw(Exporter);
11              
12             our %EXPORT_TAGS = ( 'all' => [ qw(
13             curve25519
14             curve25519_secret_key
15             curve25519_public_key
16             curve25519_shared_secret
17             ) ] );
18              
19             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
20              
21             our @EXPORT = qw(
22             curve25519_secret_key
23             curve25519_public_key
24             curve25519_shared_secret
25             );
26              
27             # Although curve25519_donna is also clamping the secret key this function
28             # has been provided for completeness and to ensure that secret keys generated
29             # here can be used in other implementations of the algorithm.
30             sub curve25519_secret_key {
31 11     11 1 3122 my $value = shift;
32 11 100       194 croak 'Secret key requires 32 bytes' if length($value) != 32;
33 10         32 vec($value, 0 , 8) &= 248;
34 10         22 vec($value, 31, 8) &= 127;
35 10         43 vec($value, 31, 8) |= 64;
36 10         19 return $value;
37             }
38              
39             require XSLoader;
40             XSLoader::load('Crypt::Curve25519', $Crypt::Curve25519::{VERSION} ?
41             ${ $Crypt::Curve25519::{VERSION} } : ()
42             );
43              
44             sub new {
45 2 50   2 1 30 return bless(\(my $o = 1), ref $_[0] ? ref $_[0] : $_[0] );
46             }
47              
48             sub secret_key {
49 4     4 1 108 my ($self, $psk) = (shift, shift);
50              
51 4         23 my $masked = curve25519_secret_key( pack('H64', $psk) );
52              
53 4         15 return unpack('H64', $masked);
54             }
55              
56             sub public_key {
57 4     4 1 16 my ($self, $sk) = (shift, shift);
58 4         12 my @args = pack('H64', $sk);
59 4 50       8 if ( @_ ) {
60 0         0 push @args, pack('H64', shift);
61             }
62              
63 4         2116 my $pk = unpack('H64', curve25519_public_key( @args ));
64              
65 4         13 return $pk;
66             }
67              
68             sub shared_secret {
69 4     4 1 18 my ($self, $sk, $pk) = @_;
70              
71 4         2004 return unpack('H64', curve25519_shared_secret( pack('H64', $sk), pack('H64', $pk) ));
72             }
73              
74             sub generate {
75 0     0 1   my ($self, $sk, $bp) = @_;
76              
77 0           return unpack('H64', curve25519( pack('H64', $sk), pack('H64', $bp) ));
78             }
79              
80             1;
81              
82             __END__