|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
  
 
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package Crypt::Perl::ECDSA::PrivateKey;  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =encoding utf-8  | 
| 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 NAME  | 
| 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Crypt::Perl::ECDSA::PrivateKey - object representation of ECDSA private key  | 
| 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SYNOPSIS  | 
| 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #Use Generate.pm or Parse.pm rather  | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #than instantiating this class directly.  | 
| 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #This works even if the object came from a key file that doesn’t  | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #contain the curve name.  | 
| 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $prkey->get_curve_name();  | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     if ($payload > ($prkey->max_sign_bits() / 8)) {  | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         die "Payload too long!";  | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #$payload is probably a hash (e.g., SHA-256) of your original message.  | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $sig = $prkey->sign($payload);  | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #For JSON Web Algorithms (JWT et al.), cf. RFC 7518 page 8  | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #This will also apply the appropriate SHA algorithm before signing.  | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $sig_jwa = $prkey->sign_jwa($payload);  | 
| 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $prkey->verify($payload, $sig) or die "Invalid signature!";  | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $prkey->verify_jwa($payload, $sig_jwa) or die "Invalid signature!";  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #Corresponding “der” methods exist as well.  | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $cn_pem = $prkey->to_pem_with_curve_name();  | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $expc_pem = $prkey->to_pem_with_explicit_curve();  | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #----------------------------------------------------------------------  | 
| 
37
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $pbkey = $prkey->get_public_key();  | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #----------------------------------------------------------------------  | 
| 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #Includes “kty”, “crv”, “x”, “y”, and (for private) “d”.  | 
| 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #Add in whatever else your application needs afterward.  | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #These will die() if you try to run it with a curve that  | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #doesn’t have a known JWK “crv” value.  | 
| 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #  | 
| 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $prv_jwk = $prkey->get_struct_for_private_jwk();  | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $pub_jwk = $prkey->get_struct_for_public_jwk();  | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #Useful for JWTs  | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $jwt_alg = $pbkey->get_jwa_alg();  | 
| 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 DISCUSSION  | 
| 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The SYNOPSIS above should be illustration enough of how to use this class.  | 
| 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
58
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SECURITY  | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 The security advantages of elliptic-curve cryptography (ECC) are a matter of  | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 some controversy. While the math itself is apparently bulletproof, there are  | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 varying opinions about the integrity of the various curves that are recommended  | 
| 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 for ECC. Some believe that some curves contain “backdoors” that would allow  | 
| 
64
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 L to sniff a transmission.  | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
66
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 That said, RSA will eventually no longer be viable: as the keys get bigger, the  | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 security advantage of increasing their size diminishes.  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 TODO  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This minimal set of functionality can be augmented as feature requests come in.  | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Patches are welcome—particularly with tests!  | 
| 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
76
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
58
 | 
 use strict;  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
    | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
253
 | 
    | 
| 
77
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
56
 | 
 use warnings;  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
    | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
243
 | 
    | 
| 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
79
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
47
 | 
 use parent qw( Crypt::Perl::ECDSA::KeyBase );  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
    | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
97
 | 
    | 
| 
80
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
81
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
452
 | 
 use Try::Tiny;  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
    | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
430
 | 
    | 
| 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
83
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
55
 | 
 use Bytes::Random::Secure::Tiny ();  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
    | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
116
 | 
    | 
| 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
85
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
40
 | 
 use Crypt::Perl::ASN1 ();  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
    | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
132
 | 
    | 
| 
86
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
36
 | 
 use Crypt::Perl::BigInt ();  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
    | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
229
 | 
    | 
| 
87
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
42
 | 
 use Crypt::Perl::Math ();  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
    | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
159
 | 
    | 
| 
88
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
2299
 | 
 use Crypt::Perl::ToDER ();  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
54
 | 
    | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
162
 | 
    | 
| 
89
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
54
 | 
 use Crypt::Perl::X ();  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
72
 | 
    | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
281
 | 
    | 
| 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
91
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #This is not the standard ASN.1 template as found in RFC 5915,  | 
| 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #but it seems to generate equivalent results.  | 
| 
93
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
94
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
742
 | 
 use constant ASN1_PRIVATE => Crypt::Perl::ECDSA::KeyBase->ASN1_Params() . q<  | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ECPrivateKey ::= SEQUENCE {  | 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         version         INTEGER,  | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         privateKey      OCTET STRING,  | 
| 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         parameters      [0] EXPLICIT EcpkParameters OPTIONAL,  | 
| 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         publicKey       [1] EXPLICIT BIT STRING  | 
| 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
102
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
43
 | 
 >;  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
    | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
104
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
63
 | 
 use constant _PEM_HEADER => 'EC PRIVATE KEY';  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
    | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
397
 | 
    | 
| 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
106
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
 
 | 
48
 | 
 use constant NUMBER_CLASS => 'Crypt::Perl::BigInt';  | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
    | 
| 
 
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11011
 | 
    | 
| 
107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #$curve_parts is also a hash ref, defined as whatever the ASN.1  | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #parse of the main key’s “parameters” returned, whether that be  | 
| 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #explicit key parameters or a named curve.  | 
| 
111
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub new {  | 
| 
113
 | 
546
 | 
 
 | 
 
 | 
  
546
  
 | 
  
0
  
 | 
2399
 | 
     my ($class, $key_parts, $curve_parts) = @_;  | 
| 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
115
 | 
546
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
3141
 | 
     if (!length $key_parts->{'version'}) {  | 
| 
116
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         die Crypt::Perl::X::create('Generic', 'Need a “version”! (Try 1)');  | 
| 
117
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my $self = {  | 
| 
120
 | 
546
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2309
 | 
         version => $key_parts->{'version'},  | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     };  | 
| 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
123
 | 
546
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1452
 | 
     bless $self, $class;  | 
| 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
125
 | 
546
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5302
 | 
     $self->_set_public( $key_parts->{'public'} );  | 
| 
126
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
127
 | 
546
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2907
 | 
     for my $k ( qw( private ) ) {  | 
| 
128
 | 
546
 | 
  
 50
  
 | 
 
 | 
  
546
  
 | 
 
 | 
6177
 | 
         if ( try { $key_parts->{$k}->isa(NUMBER_CLASS()) } ) {  | 
| 
 
 | 
546
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18144
 | 
    | 
| 
129
 | 
546
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8753
 | 
             $self->{$k} = $key_parts->{$k};  | 
| 
130
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
131
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         else {  | 
| 
132
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             die Crypt::Perl::X::create('Generic', sprintf "“$k” must be “%s”, not “$key_parts->{$k}”!", NUMBER_CLASS());  | 
| 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
134
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
136
 | 
546
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3819
 | 
     return $self->_add_params( $curve_parts );  | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
138
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub sign {  | 
| 
140
 | 
274
 | 
 
 | 
 
 | 
  
274
  
 | 
  
0
  
 | 
117072
 | 
     return $_[0]->_sign_and_serialize($_[1]);  | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _sign_and_serialize {  | 
| 
144
 | 
487
 | 
 
 | 
 
 | 
  
487
  
 | 
 
 | 
3337
 | 
     my ($self, $whatsit, $hashfn) = @_;  | 
| 
145
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
146
 | 
487
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4168
 | 
     my ($r, $s) = $self->_sign($whatsit, $hashfn);  | 
| 
147
 | 
445
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5083
 | 
     return $self->_serialize_sig( $r, $s );  | 
| 
148
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
150
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _hash_sign_and_serialize {  | 
| 
151
 | 
213
 | 
 
 | 
 
 | 
  
213
  
 | 
 
 | 
2885
 | 
     my ($self, $whatsit, $hashfn) = @_;  | 
| 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
153
 | 
213
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3348
 | 
     require Digest::SHA;  | 
| 
154
 | 
213
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9198
 | 
     $whatsit = Digest::SHA->can($hashfn)->($whatsit);  | 
| 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
156
 | 
213
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3073
 | 
     return $self->_sign_and_serialize($whatsit, $hashfn);  | 
| 
157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
158
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
159
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub sign_sha1 {  | 
| 
160
 | 
199
 | 
 
 | 
 
 | 
  
199
  
 | 
  
0
  
 | 
7853850
 | 
     my ($self, $whatsit) = @_;  | 
| 
161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
162
 | 
199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1120
 | 
     return $_[0]->_hash_sign_and_serialize($whatsit, 'sha1');  | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
164
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
165
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub sign_sha224 {  | 
| 
166
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
  
0
  
 | 
1121
 | 
     my ($self, $whatsit) = @_;  | 
| 
167
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
168
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
     return $_[0]->_hash_sign_and_serialize($whatsit, 'sha224');  | 
| 
169
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
170
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
171
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub sign_sha256 {  | 
| 
172
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
  
0
  
 | 
1146
 | 
     my ($self, $whatsit) = @_;  | 
| 
173
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
174
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
60
 | 
     return $_[0]->_hash_sign_and_serialize($whatsit, 'sha256');  | 
| 
175
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub sign_sha384 {  | 
| 
178
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
  
0
  
 | 
1152
 | 
     my ($self, $whatsit) = @_;  | 
| 
179
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
180
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
50
 | 
     return $_[0]->_hash_sign_and_serialize($whatsit, 'sha384');  | 
| 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
182
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
183
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub sign_sha512 {  | 
| 
184
 | 
3
 | 
 
 | 
 
 | 
  
3
  
 | 
  
0
  
 | 
1081
 | 
     my ($self, $whatsit) = @_;  | 
| 
185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
186
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
63
 | 
     return $_[0]->_hash_sign_and_serialize($whatsit, 'sha512');  | 
| 
187
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
189
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #cf. RFC 7518, page 8  | 
| 
190
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub sign_jwa {  | 
| 
191
 | 
6
 | 
 
 | 
 
 | 
  
6
  
 | 
  
0
  
 | 
4000
 | 
     my ($self, $whatsit) = @_;  | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
193
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # As of version 0.34 this method creates deterministic signatures.  | 
| 
194
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
195
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
     my $dgst_name = $self->_get_jwk_digest_name();  | 
| 
196
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
197
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
35
 | 
     require Digest::SHA;  | 
| 
198
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
200
 | 
     $whatsit = Digest::SHA->can($dgst_name)->($whatsit);  | 
| 
199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
200
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
     my ($r, $s) = map { $_->as_bytes() } $self->_sign($whatsit, $dgst_name);  | 
| 
 
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
60
 | 
    | 
| 
201
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
202
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
72
 | 
     my $octet_length = Crypt::Perl::Math::ceil($self->max_sign_bits() / 8);  | 
| 
203
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
204
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
43
 | 
     substr( $_, 0, 0 ) = "\0" x ($octet_length - length) for ($r, $s);  | 
| 
205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
206
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
46
 | 
     return $r . $s;  | 
| 
207
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
208
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
209
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get_public_key {  | 
| 
210
 | 
13
 | 
 
 | 
 
 | 
  
13
  
 | 
  
0
  
 | 
202
 | 
     my ($self) = @_;  | 
| 
211
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
212
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1333
 | 
     require Crypt::Perl::ECDSA::PublicKey;  | 
| 
213
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
214
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
186
 | 
     my $curve_hr = $self->_explicit_curve_parameters( seed => 1 );  | 
| 
215
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
83
 | 
     my $ccurve_hr = $curve_hr->{'ecParameters'}{'curve'};  | 
| 
216
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52
 | 
     $ccurve_hr->{'seed'} = [ $ccurve_hr->{'seed'} ];  | 
| 
217
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
218
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
110
 | 
     return Crypt::Perl::ECDSA::PublicKey->new(  | 
| 
219
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $self->_decompress_public_point(),  | 
| 
220
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $curve_hr,  | 
| 
221
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
222
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
223
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
224
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub get_struct_for_private_jwk {  | 
| 
225
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
  
0
  
 | 
839
 | 
     my ($self) = @_;  | 
| 
226
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
227
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     my $hr = $self->get_struct_for_public_jwk();  | 
| 
228
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
229
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
     require MIME::Base64;  | 
| 
230
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
231
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     $hr->{'d'} = MIME::Base64::encode_base64url( $self->{'private'}->as_bytes() );  | 
| 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
233
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
     return $hr;  | 
| 
234
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
236
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #----------------------------------------------------------------------  | 
| 
237
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #$whatsit is probably a message digest, e.g., from SHA256  | 
| 
239
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _sign {  | 
| 
240
 | 
493
 | 
 
 | 
 
 | 
  
493
  
 | 
 
 | 
2277
 | 
     my ($self, $whatsit, $det_hashfuncname) = @_;  | 
| 
241
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
242
 | 
493
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3409
 | 
     my $dgst = Crypt::Perl::BigInt->from_bytes( $whatsit );  | 
| 
243
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
244
 | 
493
 | 
 
 | 
 
 | 
 
 | 
 
 | 
117050
 | 
     my $priv_num = $self->{'private'}; #Math::BigInt->from_hex( $priv_hex );  | 
| 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
246
 | 
493
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3383
 | 
     my $n = $self->_curve()->{'n'}; #$curve_data->{'n'};  | 
| 
247
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
248
 | 
493
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3020
 | 
     my $key_len = $self->max_sign_bits();  | 
| 
249
 | 
493
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24705
 | 
     my $dgst_len = $dgst->bit_length();  | 
| 
250
 | 
493
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
15223
 | 
     if ( $dgst_len > $key_len ) {  | 
| 
251
 | 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
453
 | 
         die Crypt::Perl::X::create('TooLongToSign', $key_len, $dgst_len );  | 
| 
252
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
253
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
254
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #isa ECPoint  | 
| 
255
 | 
451
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4869
 | 
     my $G = $self->_G();  | 
| 
256
 | 
451
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1839
 | 
     my ($k, $r);  | 
| 
257
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
258
 | 
451
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1244
 | 
     do {  | 
| 
259
 | 
451
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
3561
 | 
         if ($det_hashfuncname) {  | 
| 
260
 | 
219
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4397
 | 
             require Crypt::Perl::ECDSA::Deterministic;  | 
| 
261
 | 
219
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4364
 | 
             $k = Crypt::Perl::ECDSA::Deterministic::generate_k(  | 
| 
262
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 $n,  | 
| 
263
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 $priv_num,  | 
| 
264
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 $whatsit,  | 
| 
265
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 $det_hashfuncname,  | 
| 
266
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             );  | 
| 
267
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
268
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         else {  | 
| 
269
 | 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3725
 | 
             $k = Crypt::Perl::Math::randint($n);  | 
| 
270
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
271
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
272
 | 
451
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4419
 | 
         my $Q = $G->multiply($k);   #$Q isa ECPoint  | 
| 
273
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
274
 | 
451
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4350
 | 
         $r = $Q->get_x()->to_bigint()->copy()->bmod($n);  | 
| 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } while !$r->is_positive();  | 
| 
276
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
277
 | 
451
 | 
 
 | 
 
 | 
 
 | 
 
 | 
65628
 | 
     my $s = $k->bmodinv($n);  | 
| 
278
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
279
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #$s *= ( $dgst + ( $priv_num * $r ) );  | 
| 
280
 | 
451
 | 
 
 | 
 
 | 
 
 | 
 
 | 
89685
 | 
     $s->bmul( $priv_num->copy()->bmuladd( $r, $dgst ) );  | 
| 
281
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
282
 | 
451
 | 
 
 | 
 
 | 
 
 | 
 
 | 
70316
 | 
     $s->bmod($n);  | 
| 
283
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
284
 | 
451
 | 
 
 | 
 
 | 
 
 | 
 
 | 
44002
 | 
     return ($r, $s);  | 
| 
285
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
286
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
287
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _get_asn1_parts {  | 
| 
288
 | 
418
 | 
 
 | 
 
 | 
  
418
  
 | 
 
 | 
2495
 | 
     my ($self, $curve_parts, @params) = @_;  | 
| 
289
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
290
 | 
418
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2652
 | 
     my $private_str = $self->{'private'}->as_bytes();  | 
| 
291
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
292
 | 
418
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7767
 | 
     return $self->__to_der(  | 
| 
293
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         'ECPrivateKey',  | 
| 
294
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ASN1_PRIVATE(),  | 
| 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         {  | 
| 
296
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             version => 1,  | 
| 
297
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             privateKey => $private_str,  | 
| 
298
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             parameters => $curve_parts,  | 
| 
299
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         },  | 
| 
300
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         @params,  | 
| 
301
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     );  | 
| 
302
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
303
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
304
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _serialize_sig {  | 
| 
305
 | 
445
 | 
 
 | 
 
 | 
  
445
  
 | 
 
 | 
2116
 | 
     my ($self, $r, $s) = @_;  | 
| 
306
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
307
 | 
445
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4406
 | 
     my $asn1 = Crypt::Perl::ASN1->new()->prepare( $self->ASN1_SIGNATURE() );  | 
| 
308
 | 
445
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5052
 | 
     return $asn1->encode( r => $r, s => $s );  | 
| 
309
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
310
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
311
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  |