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__ |