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             #ABSTRACT: Generate shared secret using elliptic-curve Diffie-Hellman function
3              
4 6     6   427737 use strict;
  6         63  
  6         178  
5 6     6   35 use warnings;
  6         13  
  6         172  
6 6     6   31 use Carp qw( croak );
  6         14  
  6         3437  
7              
8             require Exporter;
9             our @ISA = qw(Exporter);
10             our $VERSION = '0.07';
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 4118 my $value = shift;
32 11 100       282 croak 'Secret key requires 32 bytes' if length($value) != 32;
33 10         44 vec($value, 0 , 8) &= 248;
34 10         31 vec($value, 31, 8) &= 127;
35 10         25 vec($value, 31, 8) |= 64;
36 10         30 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 185 return bless(\(my $o = 1), ref $_[0] ? ref $_[0] : $_[0] );
46             }
47              
48             sub secret_key {
49 4     4 1 182 my ($self, $psk) = (shift, shift);
50              
51 4         32 my $masked = curve25519_secret_key( pack('H64', $psk) );
52              
53 4         18 return unpack('H64', $masked);
54             }
55              
56             sub public_key {
57 4     4 1 22 my ($self, $sk) = (shift, shift);
58 4         15 my @args = pack('H64', $sk);
59 4 50       11 if ( @_ ) {
60 0         0 push @args, pack('H64', shift);
61             }
62              
63 4         2512 my $pk = unpack('H64', curve25519_public_key( @args ));
64              
65 4         25 return $pk;
66             }
67              
68             sub shared_secret {
69 4     4 1 31 my ($self, $sk, $pk) = @_;
70              
71 4         2496 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__