1package Net::DNS::SEC::EdDSA;
2
3use strict;
4use warnings;
5
6our $VERSION = (qw$Id: EdDSA.pm 1853 2021-10-11 10:40:59Z willem $)[2];
7
8
9=head1 NAME
10
11Net::DNS::SEC::EdDSA - DNSSEC EdDSA digital signature algorithm
12
13
14=head1 SYNOPSIS
15
16    require Net::DNS::SEC::EdDSA;
17
18    $signature = Net::DNS::SEC::EdDSA->sign( $sigdata, $private );
19
20    $validated = Net::DNS::SEC::EdDSA->verify( $sigdata, $keyrr, $sigbin );
21
22
23=head1 DESCRIPTION
24
25Implementation of EdDSA Edwards curve digital signature
26generation and verification procedures.
27
28=head2 sign
29
30    $signature = Net::DNS::SEC::EdDSA->sign( $sigdata, $private );
31
32Generates the wire-format signature from the sigdata octet string
33and the appropriate private key object.
34
35=head2 verify
36
37    $validated = Net::DNS::SEC::EdDSA->verify( $sigdata, $keyrr, $signature );
38
39Verifies the signature over the sigdata octet string using the specified
40public key resource record.
41
42=cut
43
44use integer;
45use MIME::Base64;
46
47use constant EdDSA_configured => Net::DNS::SEC::libcrypto->can('EVP_PKEY_new_raw_public_key');
48
49BEGIN { die 'EdDSA disabled or application has no "use Net::DNS::SEC"' unless EdDSA_configured }
50
51
52my %parameters = (
53	15 => [1087, 32, 64],
54	16 => [1088, 57, 114],
55	);
56
57sub _index { return keys %parameters }
58
59
60sub sign {
61	my ( $class, $sigdata, $private ) = @_;
62
63	my $algorithm = $private->algorithm;
64	my ( $nid, $keylen ) = @{$parameters{$algorithm} || []};
65	die 'private key not EdDSA' unless $nid;
66
67	my $rawkey = pack "a$keylen", decode_base64( $private->PrivateKey );
68	my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_raw_private_key( $nid, $rawkey );
69
70	return Net::DNS::SEC::libcrypto::EVP_sign( $sigdata, $evpkey );
71}
72
73
74sub verify {
75	my ( $class, $sigdata, $keyrr, $signature ) = @_;
76
77	my $algorithm = $keyrr->algorithm;
78	my ( $nid, $keylen, $siglen ) = @{$parameters{$algorithm} || []};
79	die 'public key not EdDSA' unless $nid;
80
81	return unless $signature;
82
83	my $rawkey = pack "a$keylen", $keyrr->keybin;
84	my $evpkey = Net::DNS::SEC::libcrypto::EVP_PKEY_new_raw_public_key( $nid, $rawkey );
85
86	my $sigbin = pack "a$siglen", $signature;
87	return Net::DNS::SEC::libcrypto::EVP_verify( $sigdata, $sigbin, $evpkey );
88}
89
90
911;
92
93__END__
94
95########################################
96
97=head1 ACKNOWLEDGMENT
98
99Thanks are due to Eric Young and the many developers and
100contributors to the OpenSSL cryptographic library.
101
102
103=head1 COPYRIGHT
104
105Copyright (c)2014,2018 Dick Franks.
106
107All rights reserved.
108
109
110=head1 LICENSE
111
112Permission to use, copy, modify, and distribute this software and its
113documentation for any purpose and without fee is hereby granted, provided
114that the original copyright notices appear in all copies and that both
115copyright notice and this permission notice appear in supporting
116documentation, and that the name of the author not be used in advertising
117or publicity pertaining to distribution of the software without specific
118prior written permission.
119
120THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
121IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
122FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
123THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
124LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
125FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
126DEALINGS IN THE SOFTWARE.
127
128
129=head1 SEE ALSO
130
131L<Net::DNS>, L<Net::DNS::SEC>,
132RFC8032, RFC8080,
133L<OpenSSL|http://www.openssl.org/docs>
134
135=cut
136
137