Package list libcryptx-perl / 93b0f91
Add tests and docs for PK::Ed25519 and PK::X25519 manuel 1 year, 8 months ago
6 changed file(s) with 399 addition(s) and 14 deletion(s). Raw diff Collapse all Expand all
184184 CODE:
185185 {
186186 int rv;
187 unsigned char out[4096];
187 unsigned char out[32];
188188 unsigned long int out_len = sizeof(out);
189189
190190 RETVAL = newSVpvn(NULL, 0); /* undef */
115115 int
116116 is_private(Crypt::PK::X25519 self)
117117 CODE:
118 if (self->key.type == -1) XSRETURN_UNDEF;
118 if (self->initialized == 0 || self->key.type == -1) XSRETURN_UNDEF;
119119 RETVAL = (self->key.type == PK_PRIVATE) ? 1 : 0;
120120 OUTPUT:
121121 RETVAL
163163
164164 RETVAL = newSVpvn(NULL, 0); /* undef */
165165 if (strnEQ(type, "private", 7)) {
166 rv = x25519_export(out, &out_len, PK_PRIVATE, &self->key);
167 if (rv != CRYPT_OK) croak("FATAL: x25519_export(PK_PRIVATE) failed: %s", error_to_string(rv));
166 rv = x25519_export(out, &out_len, PK_PRIVATE|PK_STD, &self->key);
167 if (rv != CRYPT_OK) croak("FATAL: x25519_export(PK_PRIVATE|PK_STD) failed: %s", error_to_string(rv));
168168 RETVAL = newSVpvn((char*)out, out_len);
169169 }
170170 else if (strnEQ(type, "public", 6)) {
179179 OUTPUT:
180180 RETVAL
181181
182 SV*
183 export_key_raw(Crypt::PK::X25519 self, char * type)
184 CODE:
185 {
186 int rv;
187 unsigned char out[32];
188 unsigned long int out_len = sizeof(out);
189
190 RETVAL = newSVpvn(NULL, 0); /* undef */
191 if (strnEQ(type, "private", 7)) {
192 rv = x25519_export(out, &out_len, PK_PRIVATE, &self->key);
193 if (rv != CRYPT_OK) croak("FATAL: x25519_export(PK_PRIVATE) failed: %s", error_to_string(rv));
194 RETVAL = newSVpvn((char*)out, out_len);
195 }
196 else if (strnEQ(type, "public", 6)) {
197 rv = x25519_export(out, &out_len, PK_PUBLIC, &self->key);
198 if (rv != CRYPT_OK) croak("FATAL: x25519_export(PK_PUBLIC) failed: %s", error_to_string(rv));
199 RETVAL = newSVpvn((char*)out, out_len);
200 }
201 else {
202 croak("FATAL: export_key_raw invalid type '%s'", type);
203 }
204 }
205 OUTPUT:
206 RETVAL
207
182208 SV *
183209 shared_secret(Crypt::PK::X25519 self, Crypt::PK::X25519 pubkey)
184210 CODE:
198224 DESTROY(Crypt::PK::X25519 self)
199225 CODE:
200226 Safefree(self);
201
162162
163163 =head2 import_key
164164
165 TODO
165 Loads private or public key in DER or PEM format.
166
167 $pk->import_key($filename);
168 #or
169 $pk->import_key(\$buffer_containing_key);
170
171 Support for password protected PEM keys:
172
173 $pk->import_key($filename, $password);
174 #or
175 $pk->import_key(\$buffer_containing_key, $password);
176
177 Loading private or public keys form perl hash:
178
179 $pk->import_key($hashref);
180
181 # the $hashref is either a key exported via key2hash
182 $pk->import_key({
183 curve => "ed25519",
184 pub => "A05D1AEA5830AC9A65CDFB384660D497E3697C46B419CF2CEC85DE8BD245459D",
185 priv => "45C109BA6FD24E8B67D23EFB6B92D99CD457E2137172C0D749FE2B5A0C142DAD",
186 });
187
188 # or a hash with items corresponding to JWK (JSON Web Key)
189 $pk->import_key({
190 kty => "OKP",
191 crv => "Ed25519",
192 d => "RcEJum_STotn0j77a5LZnNRX4hNxcsDXSf4rWgwULa0",
193 x => "oF0a6lgwrJplzfs4RmDUl-NpfEa0Gc8s7IXei9JFRZ0",
194 });
195
196 Supported key formats:
197
198 # all formats can be loaded from a file
199 my $pk = Crypt::PK::Ed25519->new($filename);
200
201 # or from a buffer containing the key
202 my $pk = Crypt::PK::Ed25519->new(\$buffer_with_key);
203
204 =over
205
206 =item * Ed25519 private keys in PEM format
207
208 -----BEGIN ED25519 PRIVATE KEY-----
209 MC4CAQAwBQYDK2VwBCIEIEXBCbpv0k6LZ9I++2uS2ZzUV+ITcXLA10n+K1oMFC2t
210 -----END ED25519 PRIVATE KEY-----
211
212 =item * Ed25519 private keys in password protected PEM format
213
214 -----BEGIN ED25519 PRIVATE KEY-----
215 Proc-Type: 4,ENCRYPTED
216 DEK-Info: DES-CBC,6A64D756D49C1EFF
217
218 8xQ7OyfQ10IITNEKcJGZA53Z1yk+NJQU7hrKqXwChZtgWNInhMBJRl9pozLKDSkH
219 v7u6EOve8NY=
220 -----END ED25519 PRIVATE KEY-----
221
222 =item * PKCS#8 private keys
223
224 -----BEGIN PRIVATE KEY-----
225 MC4CAQAwBQYDK2VwBCIEIEXBCbpv0k6LZ9I++2uS2ZzUV+ITcXLA10n+K1oMFC2t
226 -----END PRIVATE KEY-----
227
228 =item * PKCS#8 encrypted private keys
229
230 -----BEGIN ENCRYPTED PRIVATE KEY-----
231 MIGHMEsGCSqGSIb3DQEFDTA+MCkGCSqGSIb3DQEFDDAcBAjPx9JkdpRH2QICCAAw
232 DAYIKoZIhvcNAgkFADARBgUrDgMCBwQIWWieQojaWTcEOGj43SxqHUys4Eb2M27N
233 AkhqpmhosOxKrpGi0L3h8m8ipHE8EwI94NeOMsjfVw60aJuCrssY5vKN
234 -----END ENCRYPTED PRIVATE KEY-----
235
236 =item * Ed25519 public keys in PEM format
237
238 -----BEGIN PUBLIC KEY-----
239 MCowBQYDK2VwAyEAoF0a6lgwrJplzfs4RmDUl+NpfEa0Gc8s7IXei9JFRZ0=
240 -----END PUBLIC KEY-----
241
242 =item * Ed25519 public key from X509 certificate
243
244 -----BEGIN CERTIFICATE-----
245 MIIBODCB66ADAgECAhRWDU9FZBBUZ7KTdX8f7Bco8jsoaTAFBgMrZXAwETEPMA0G
246 A1UEAwwGQ3J5cHRYMCAXDTIwMDExOTEzMDIwMloYDzIyOTMxMTAyMTMwMjAyWjAR
247 MQ8wDQYDVQQDDAZDcnlwdFgwKjAFBgMrZXADIQCgXRrqWDCsmmXN+zhGYNSX42l8
248 RrQZzyzshd6L0kVFnaNTMFEwHQYDVR0OBBYEFHCGFtVibAxxWYyRt5wazMpqSZDV
249 MB8GA1UdIwQYMBaAFHCGFtVibAxxWYyRt5wazMpqSZDVMA8GA1UdEwEB/wQFMAMB
250 Af8wBQYDK2VwA0EAqG/+98smzqF/wmFX3zHXSaA67as202HnBJod1Tiurw1f+lr3
251 BX6OMtsDpgRq9O77IF1Qyx/MdJEwwErczOIbAA==
252 -----END CERTIFICATE-----
253
254 =item * SSH public Ed25519 keys
255
256 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL0XsiFcRDp6Hpsoak8OdiiBMJhM2UKszNTxoGS7dJ++
257
258 =item * SSH public Ed25519 keys (RFC-4716 format)
259
260 ---- BEGIN SSH2 PUBLIC KEY ----
261 Comment: "256-bit ED25519, converted from OpenSSH"
262 AAAAC3NzaC1lZDI1NTE5AAAAIL0XsiFcRDp6Hpsoak8OdiiBMJhM2UKszNTxoGS7dJ++
263 ---- END SSH2 PUBLIC KEY ----
264
265 =item * Ed25519 private keys in JSON Web Key (JWK) format
266
267 See L<https://tools.ietf.org/html/rfc8037>
268
269 {
270 "kty":"OKP",
271 "crv":"Ed25519",
272 "x":"oF0a6lgwrJplzfs4RmDUl-NpfEa0Gc8s7IXei9JFRZ0",
273 "d":"RcEJum_STotn0j77a5LZnNRX4hNxcsDXSf4rWgwULa0",
274 }
275
276 B<BEWARE:> For JWK support you need to have L<JSON::PP>, L<JSON::XS> or L<Cpanel::JSON::XS> module.
277
278 =item * Ed25519 public keys in JSON Web Key (JWK) format
279
280 {
281 "kty":"OKP",
282 "crv":"Ed25519",
283 "x":"oF0a6lgwrJplzfs4RmDUl-NpfEa0Gc8s7IXei9JFRZ0",
284 }
285
286 B<BEWARE:> For JWK support you need to have L<JSON::PP>, L<JSON::XS> or L<Cpanel::JSON::XS> module.
166287
167288 =head2 import_key_raw
168289
2222 sub import_key_raw {
2323 my ($self, $key, $type) = @_;
2424 croak "FATAL: undefined key" unless $key;
25 croak "FATAL: invalid key" unless length($key) == 32;
2526 croak "FATAL: undefined type" unless $type;
2627 return $self->_import_raw($key, 1) if $type eq 'private';
2728 return $self->_import_raw($key, 0) if $type eq 'public';
134135
135136 =head2 generate_key
136137
138 Uses Yarrow-based cryptographically strong random number generator seeded with
139 random data taken from C</dev/random> (UNIX) or C<CryptGenRandom> (Win32).
140
141 $pk->generate_key;
142
137143 =head2 import_key
138144
145 Loads private or public key in DER or PEM format.
146
147 $pk->import_key($filename);
148 #or
149 $pk->import_key(\$buffer_containing_key);
150
151 Support for password protected PEM keys:
152
153 $pk->import_key($filename, $password);
154 #or
155 $pk->import_key(\$buffer_containing_key, $password);
156
157 Loading private or public keys form perl hash:
158
159 $pk->import_key($hashref);
160
161 # the $hashref is either a key exported via key2hash
162 $pk->import_key({
163 curve => "x25519",
164 pub => "EA7806F721A8570512C8F6EFB4E8D620C49A529E4DF5EAA77DEC646FB1E87E41",
165 priv => "002F93D10BA5728D8DD8E9527721DABA3261C0BB1BEFDE7B4BBDAC631D454651",
166 });
167
168 # or a hash with items corresponding to JWK (JSON Web Key)
169 $pk->import_key({
170 kty => "OKP",
171 crv => "X25519",
172 d => "AC-T0Qulco2N2OlSdyHaujJhwLsb7957S72sYx1FRlE",
173 x => "6ngG9yGoVwUSyPbvtOjWIMSaUp5N9eqnfexkb7HofkE",
174 });
175
176 Supported key formats:
177
178 # all formats can be loaded from a file
179 my $pk = Crypt::PK::X25519->new($filename);
180
181 # or from a buffer containing the key
182 my $pk = Crypt::PK::X25519->new(\$buffer_with_key);
183
184 =over
185
186 =item * X25519 private keys in PEM format
187
188 -----BEGIN X25519 PRIVATE KEY-----
189 MC4CAQAwBQYDK2VuBCIEIAAvk9ELpXKNjdjpUnch2royYcC7G+/ee0u9rGMdRUZR
190 -----END X25519 PRIVATE KEY-----
191
192 =item * X25519 private keys in password protected PEM format
193
194 -----BEGIN X25519 PRIVATE KEY-----
195 Proc-Type: 4,ENCRYPTED
196 DEK-Info: DES-CBC,DEEFD3D6B714E75A
197
198 dfFWP5bKn49aZ993NVAhQQPdFWgsTb4j8CWhRjGBVTPl6ITstAL17deBIRBwZb7h
199 pAyIka81Kfs=
200 -----END X25519 PRIVATE KEY-----
201
202 =item * X25519 public keys in PEM format
203
204 -----BEGIN PUBLIC KEY-----
205 MCowBQYDK2VuAyEA6ngG9yGoVwUSyPbvtOjWIMSaUp5N9eqnfexkb7HofkE=
206 -----END PUBLIC KEY-----
207
208 =item * PKCS#8 private keys
209
210 -----BEGIN PRIVATE KEY-----
211 MC4CAQAwBQYDK2VuBCIEIAAvk9ELpXKNjdjpUnch2royYcC7G+/ee0u9rGMdRUZR
212 -----END PRIVATE KEY-----
213
214 =item * PKCS#8 encrypted private keys
215
216 -----BEGIN ENCRYPTED PRIVATE KEY-----
217 MIGHMEsGCSqGSIb3DQEFDTA+MCkGCSqGSIb3DQEFDDAcBAiS0NOFZmjJswICCAAw
218 DAYIKoZIhvcNAgkFADARBgUrDgMCBwQIGd40Hdso8Y4EONSRCTrqvftl9hl3zbH9
219 2QmHF1KJ4HDMdLDRxD7EynonCw2SV7BO+XNRHzw2yONqiTybfte7nk9t
220 -----END ENCRYPTED PRIVATE KEY-----
221
222 =item * X25519 private keys in JSON Web Key (JWK) format
223
224 See L<https://tools.ietf.org/html/rfc8037>
225
226 {
227 "kty":"OKP",
228 "crv":"X25519",
229 "x":"6ngG9yGoVwUSyPbvtOjWIMSaUp5N9eqnfexkb7HofkE",
230 "d":"AC-T0Qulco2N2OlSdyHaujJhwLsb7957S72sYx1FRlE",
231 }
232
233 B<BEWARE:> For JWK support you need to have L<JSON::PP>, L<JSON::XS> or L<Cpanel::JSON::XS> module.
234
235 =item * X25519 public keys in JSON Web Key (JWK) format
236
237 {
238 "kty":"OKP",
239 "crv":"X25519",
240 "x":"6ngG9yGoVwUSyPbvtOjWIMSaUp5N9eqnfexkb7HofkE",
241 }
242
243 B<BEWARE:> For JWK support you need to have L<JSON::PP>, L<JSON::XS> or L<Cpanel::JSON::XS> module.
244
139245 =head2 import_key_raw
140246
247 Import raw public/private key - can load raw key data exported by L</export_key_raw>.
248
249 $pk->import_key_raw($key, 'public');
250 $pk->import_key_raw($key, 'private');
251
141252 =head2 export_key_der
142253
254 my $private_der = $pk->export_key_der('private');
255 #or
256 my $public_der = $pk->export_key_der('public');
257
143258 =head2 export_key_pem
144259
260 my $private_pem = $pk->export_key_pem('private');
261 #or
262 my $public_pem = $pk->export_key_pem('public');
263
145264 =head2 export_key_jwk
146265
266 Exports public/private keys as a JSON Web Key (JWK).
267
268 my $private_json_text = $pk->export_key_jwk('private');
269 #or
270 my $public_json_text = $pk->export_key_jwk('public');
271
272 Also exports public/private keys as a perl HASH with JWK structure.
273
274 my $jwk_hash = $pk->export_key_jwk('private', 1);
275 #or
276 my $jwk_hash = $pk->export_key_jwk('public', 1);
277
278 B<BEWARE:> For JWK support you need to have L<JSON::PP>, L<JSON::XS> or L<Cpanel::JSON::XS> module.
279
147280 =head2 export_key_raw
148281
282 Export raw public/private key
283
284 my $private_pem = $pk->export_key_raw('private');
285 #or
286 my $public_pem = $pk->export_key_raw('public');
287
149288 =head2 shared_secret
150289
290 # Alice having her priv key $pk and Bob's public key $pkb
291 my $pk = Crypt::PK::X25519->new($priv_key_filename);
292 my $pkb = Crypt::PK::X25519->new($pub_key_filename);
293 my $shared_secret = $pk->shared_secret($pkb);
294
295 # Bob having his priv key $pk and Alice's public key $pka
296 my $pk = Crypt::PK::X25519->new($priv_key_filename);
297 my $pka = Crypt::PK::X25519->new($pub_key_filename);
298 my $shared_secret = $pk->shared_secret($pka); # same value as computed by Alice
299
151300 =head2 is_private
152301
302 my $rv = $pk->is_private;
303 # 1 .. private key loaded
304 # 0 .. public key loaded
305 # undef .. no key loaded
306
153307 =head2 key2hash
154308
309 my $hash = $pk->key2hash;
310
311 # returns hash like this (or undef if no key loaded):
312 {
313 curve => "x25519",
314 # raw public key as a hexadecimal string
315 pub => "EA7806F721A8570512C8F6EFB4E8D620C49A529E4DF5EAA77DEC646FB1E87E41",
316 # raw private key as a hexadecimal string. undef if key is public only
317 priv => "002F93D10BA5728D8DD8E9527721DABA3261C0BB1BEFDE7B4BBDAC631D454651",
318 }
319
320 =head1 SEE ALSO
321
322 =over
323
324 =item * L<https://en.wikipedia.org/wiki/Curve25519>
325
326 =item * L<https://tools.ietf.org/html/rfc7748>
327
328 =back
329
155330 =cut
00 use strict;
11 use warnings;
2 use Test::More tests => 74;
2 use Test::More tests => 78;
33
44 use Crypt::PK::Ed25519;
55 use Crypt::Misc qw(read_rawfile);
66
77 {
8 my $k;
8 my ($k, $k2);
99
1010 # t/data/openssl_ed25519_sk.pem
1111 # ED25519 Private-Key:
2020 is(uc($k->key2hash->{pub}), 'A05D1AEA5830AC9A65CDFB384660D497E3697C46B419CF2CEC85DE8BD245459D', 'key2hash->{pub} raw-priv');
2121 is($k->export_key_raw('private'), $sk_data, 'export_key_raw private');
2222
23 $k2 = Crypt::PK::Ed25519->new->import_key($k->key2hash);
24 ok($k2->is_private, 'is_private raw-priv');
25 is($k->export_key_der('private'), $k2->export_key_der('private'), 'import_key hash');
26
2327 my $pk_data = pack("H*", "A05D1AEA5830AC9A65CDFB384660D497E3697C46B419CF2CEC85DE8BD245459D");
2428 $k = Crypt::PK::Ed25519->new->import_key_raw($pk_data, 'public');
2529 ok($k, 'new+import_key_raw raw-pub');
2630 ok(!$k->is_private, '!is_private raw-pub');
2731 is(uc($k->key2hash->{pub}), 'A05D1AEA5830AC9A65CDFB384660D497E3697C46B419CF2CEC85DE8BD245459D', 'key2hash->{pub} raw-pub');
2832 is($k->export_key_raw('public'), $pk_data, 'export_key_raw public');
33
34 $k2 = Crypt::PK::Ed25519->new->import_key($k->key2hash);
35 ok(!$k2->is_private, 'is_private raw-priv');
36 is($k->export_key_der('public'), $k2->export_key_der('public'), 'import_key hash');
2937
3038 my $sk_jwk = { kty=>"OKP",crv=>"Ed25519",d=>"RcEJum_STotn0j77a5LZnNRX4hNxcsDXSf4rWgwULa0",x=>"oF0a6lgwrJplzfs4RmDUl-NpfEa0Gc8s7IXei9JFRZ0" };
3139 $k = Crypt::PK::Ed25519->new($sk_jwk);
00 use strict;
11 use warnings;
2 use Test::More tests => 46;
2 use Test::More tests => 65;
33
44 use Crypt::PK::X25519;
5 use Crypt::Misc qw(read_rawfile);
56
67 {
7 my $k;
8 my ($k, $k2);
89
910 # t/data/openssl_x25519_sk.pem
1011 # X25519 Private-Key:
1112 # priv = 002F93D10BA5728D8DD8E9527721DABA3261C0BB1BEFDE7B4BBDAC631D454651 == AC-T0Qulco2N2OlSdyHaujJhwLsb7957S72sYx1FRlE
1213 # pub = EA7806F721A8570512C8F6EFB4E8D620C49A529E4DF5EAA77DEC646FB1E87E41 == 6ngG9yGoVwUSyPbvtOjWIMSaUp5N9eqnfexkb7HofkE
1314
14 $k = Crypt::PK::X25519->new->import_key_raw(pack("H*", "002F93D10BA5728D8DD8E9527721DABA3261C0BB1BEFDE7B4BBDAC631D454651"), 'private');
15 my $sk_data = pack("H*", "002F93D10BA5728D8DD8E9527721DABA3261C0BB1BEFDE7B4BBDAC631D454651");
16 $k = Crypt::PK::X25519->new->import_key_raw($sk_data, 'private');
1517 ok($k, 'new+import_key_raw raw-priv');
1618 ok($k->is_private, 'is_private raw-priv');
1719 is(uc($k->key2hash->{priv}), '002F93D10BA5728D8DD8E9527721DABA3261C0BB1BEFDE7B4BBDAC631D454651', 'key2hash->{priv} raw-priv');
1820 is(uc($k->key2hash->{pub}), 'EA7806F721A8570512C8F6EFB4E8D620C49A529E4DF5EAA77DEC646FB1E87E41', 'key2hash->{pub} raw-priv');
21 is($k->export_key_raw('private'), $sk_data, 'export_key_raw private');
1922
20 $k = Crypt::PK::X25519->new->import_key_raw(pack("H*", "EA7806F721A8570512C8F6EFB4E8D620C49A529E4DF5EAA77DEC646FB1E87E41"), 'public');
23 $k2 = Crypt::PK::X25519->new->import_key($k->key2hash);
24 ok($k2->is_private, 'is_private raw-priv');
25 is($k->export_key_der('private'), $k2->export_key_der('private'), 'import_key hash');
26
27 my $pk_data = pack("H*", "EA7806F721A8570512C8F6EFB4E8D620C49A529E4DF5EAA77DEC646FB1E87E41");
28 $k = Crypt::PK::X25519->new->import_key_raw($pk_data, 'public');
2129 ok($k, 'new+import_key_raw raw-pub');
2230 ok(!$k->is_private, '!is_private raw-pub');
2331 is(uc($k->key2hash->{pub}), 'EA7806F721A8570512C8F6EFB4E8D620C49A529E4DF5EAA77DEC646FB1E87E41', 'key2hash->{pub} raw-pub');
32 is($k->export_key_raw('public'), $pk_data, 'export_key_raw public');
2433
25 $k = Crypt::PK::X25519->new({ kty=>"OKP",crv=>"X25519",d=>"AC-T0Qulco2N2OlSdyHaujJhwLsb7957S72sYx1FRlE",x=>"6ngG9yGoVwUSyPbvtOjWIMSaUp5N9eqnfexkb7HofkE"});
34 $k2 = Crypt::PK::X25519->new->import_key($k->key2hash);
35 ok(!$k2->is_private, 'is_private raw-priv');
36 is($k->export_key_der('public'), $k2->export_key_der('public'), 'import_key hash');
37
38 my $sk_jwk = { kty=>"OKP",crv=>"X25519",d=>"AC-T0Qulco2N2OlSdyHaujJhwLsb7957S72sYx1FRlE",x=>"6ngG9yGoVwUSyPbvtOjWIMSaUp5N9eqnfexkb7HofkE" };
39 $k = Crypt::PK::X25519->new($sk_jwk);
2640 ok($k, 'new JWKHASH/priv');
2741 ok($k->is_private, 'is_private JWKHASH/priv');
2842 is(uc($k->key2hash->{priv}), '002F93D10BA5728D8DD8E9527721DABA3261C0BB1BEFDE7B4BBDAC631D454651', 'key2hash->{priv} JWKHASH/priv');
43 ok(eq_hash($sk_jwk, $k->export_key_jwk('private', 1)), 'JWKHASH export private');
2944
30 $k = Crypt::PK::X25519->new({ kty=>"OKP",crv=>"X25519",x=>"6ngG9yGoVwUSyPbvtOjWIMSaUp5N9eqnfexkb7HofkE"});
45 my $pk_jwk = { kty=>"OKP",crv=>"X25519",x=>"6ngG9yGoVwUSyPbvtOjWIMSaUp5N9eqnfexkb7HofkE"};
46 $k = Crypt::PK::X25519->new($pk_jwk);
3147 ok($k, 'new JWKHASH/pub');
3248 ok(!$k->is_private, '!is_private JWKHASH/pub');
3349 is(uc($k->key2hash->{pub}), 'EA7806F721A8570512C8F6EFB4E8D620C49A529E4DF5EAA77DEC646FB1E87E41', 'key2hash->{pub} JWKHASH/pub');
50 ok(eq_hash($pk_jwk, $k->export_key_jwk('public', 1)), 'JWKHASH export public');
3451
3552 $k = Crypt::PK::X25519->new('t/data/jwk_x25519-priv1.json');
3653 ok($k, 'new JWK/priv');
87104 ok(!$k->is_private, '!is_private openssl_x25519_pk.pem');
88105 is(uc($k->key2hash->{pub}), 'EA7806F721A8570512C8F6EFB4E8D620C49A529E4DF5EAA77DEC646FB1E87E41', 'key2hash->{pub} openssl_x25519_pk.pem');
89106 }
107
108 {
109 my $k = Crypt::PK::X25519->new;
110 $k->generate_key;
111 ok($k, 'generate_key');
112 ok($k->is_private, 'is_private');
113 ok($k->export_key_der('private'), 'export_key_der pri');
114 ok($k->export_key_der('public'), 'export_key_der pub');
115 }
116
117 {
118 for (qw( openssl_x25519_pk.der openssl_x25519_pk.pem )) {
119 my $k = Crypt::PK::X25519->new("t/data/$_");
120 is($k->export_key_der('public'), read_rawfile("t/data/$_"), 'export_key_der public') if (substr($_, -3) eq "der");
121 is($k->export_key_pem('public'), read_rawfile("t/data/$_"), 'export_key_pem public') if (substr($_, -3) eq "pem");
122 }
123
124 for (qw( openssl_x25519_sk.der openssl_x25519_sk_t.pem )) {
125 my $k = Crypt::PK::X25519->new("t/data/$_");
126 is($k->export_key_der('private'), read_rawfile("t/data/$_"), 'export_key_der private') if (substr($_, -3) eq "der");
127 is($k->export_key_pem('private'), read_rawfile("t/data/$_"), 'export_key_pem private') if (substr($_, -3) eq "pem");
128 }
129 }
130
131 {
132 my $sk1 = Crypt::PK::X25519->new;
133 $sk1->import_key('t/data/openssl_x25519_sk.der');
134 my $pk1 = Crypt::PK::X25519->new->import_key_raw($sk1->export_key_raw('public'), 'public');
135 ok(!$pk1->is_private, '!is_private');
136
137 my $sk2 = Crypt::PK::X25519->new;
138 $sk2->generate_key;
139 my $pk2 = Crypt::PK::X25519->new->import_key_raw($sk2->export_key_raw('public'), 'public');
140 ok(!$pk2->is_private, '!is_private');
141
142 my $ss1 = $sk1->shared_secret($pk2);
143 my $ss2 = $sk2->shared_secret($pk1);
144 is(unpack("H*",$ss1), unpack("H*",$ss2), 'shared_secret');
145 }