Codebase list libcryptx-perl / f92241e
merge Karel Miko 10 years ago
154 changed file(s) with 4908 addition(s) and 1619 deletion(s). Raw diff Collapse all Expand all
2121 MANIFEST
2222 lib/CryptX.c
2323 CryptX-*
24 poznamky.txt
24 poznamky.txt
25 t/openssl/*.der
26 t/openssl/*.pem
27 t/openssl/*.data
28 t/openssl/*.sig
29 t/openssl/*.rsa
0 language: perl
1 perl:
2 - "5.8"
3 - "5.10"
4 - "5.12"
5 - "5.14"
6 - "5.16"
7 - "5.18"
8 - "5.19"
44 use Config;
55
66 my $flags = '-Isrc/ltc/headers -Isrc/ltm -DLTC_SOURCE -DLTC_NO_TEST -DLTC_NO_PROTOTYPES -DLTM_DESC';
7 #$flags .= ' -DLTC_NO_ASM';
87 #$flags .= ' -Wall';
9
10 unless ($ENV{CRYPTX_USE_ASM} || $Config{archname} =~ /MSWin32-x86/) {
11 $flags .= ' -DLTC_NO_ASM';
12 }
8 #$flags .= ' -DLTC_NO_ASM' if $ENV{CRYPTX_NO_ASM} || $Config{archname} !~ /(MSWin32-(x86|x64)|(i.86|x86_64)-linux|(i.86|amd64)-(freebsd|openbsd)|cygwin|darwin)/;
139
1410 my $class = Module::Build->subclass(
1511 class => 'My::Builder',
00 Changes for CryptX
11
22 TODO:
3 - CRITICAL: fix broken camellia
4 - more investigation crash/memleak/or_what_it_is related to rsa_free/dsa_free
5 - RSA->check_key (basic check + extented primality test)
6 - croak with the "real caller" (Crypt::Mac::*, Crypt::Mode::*, ...)
7 - croak when mode does not call start_(en|de)crypt
8 - "libtom-src/bn_mp_invmod.c", line 37: warning: statement not reached
9 - solaris crash:
3 - RSA|DSA|ECC: verify_key($level) (basic check + extented primality test)
4 - better primality testing: http://questhub.io/realm/perl/quest/519032ee1088c76505000035
5 - DSA: generate_key($p, $q, $g), generate_key(\$dsa_params_der), generate_key($dsa_params_file)
6 - DH: generate_key($base, $prime), generate_key(\$dh_params_der), generate_key($dh_params_file)
7 - DH: key2hash should dump $base and $prime as well (perhasp add base, prime to dh_key struct)
8 - investigate - "libtom-src/bn_mp_invmod.c", line 37: warning: statement not reached
9 - investigate - solaris crash:
1010 - http://ppm4.activestate.com/sun4-solaris/5.14/1400/M/MI/MIK/CryptX-0.017.d/log-20130924T103600.txt
1111 - t/pk_rsa.t crashes after: ok 32 - verify_hash
1212 - t/pk_dsa.t crashes after: ok 28 - decrypt
13 - better primality testing: http://questhub.io/realm/perl/quest/519032ee1088c76505000035
14 - libtomcrypt patch: https://secure.ucc.asn.au/hg/dropbear/rev/9a789fc03f40?revcount=240 (free rsa key)
13 - XS croaks should report the "real caller" (Crypt::Mac::*, Crypt::Mode::*, ...)
14
15 0.021 2014/01/23
16 - fixed asm(...) related compiler failures
17 - dsa_encrypt_key small correction
18 - optimized ecc_encrypt_key
19
20 0.020 2014/01/18
21 - INCOMPATIBLE CHANGE: huge redesign of Crypt::PK::ECC
22 - ECC now supports curves y^2 = x^3 + a*x + b
23 - ECC you can use custom curves
24 - ECC import/export of keys in DER/PEM format now compatible with openssl
25 - enabling compile options ASM + ECC_TIMING_RESISTANT
26 - added many test vectors (RSA, DSA, EC) for interoperability with openssl
27
28 0.019 2013/10/20
29 - fixed broken CAMELLIA implementation
30
31 0.018 2013/10/18
32 - DSA: make_key + sign_hash fixes
1533
1634 0.017 2013/09/24
1735 - lowering MIME::Base64 version requirement
2727 ^tmp*
2828 ^poznamky*
2929 \.stackdump$
30 ^.travis*
31 t/openssl/.*$
183183
184184 =head2 add_bits
185185
186 $d->addfile('filename.dat');
187 #or
188 $d->addfile(*FILEHANDLE);
186 $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010");
187 #or
188 $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16);
189189
190190 =head2 hashsize
191191
110110 if (rv != CRYPT_OK) croak("FATAL: [%lc_name%]_decrypt failed: %s", error_to_string(rv));
111111 }
112112 else {
113 croak("FATAL: [%lc_name%]_crypt failed: call start() first");
113 croak("FATAL: [%lc_name%]_crypt failed: call start_encrypt or start_decrypt first");
114114 }
115115 }
116116 }
7878 STRLEN in_data_len, in_data_start;
7979 unsigned char *in_data, *out_data, tmp_block[MAXBLOCKSIZE];
8080
81 if (self->direction != 1) croak("FATAL: encrypt error, call start('enc') first (%d)", self->direction);
81 if (self->direction != 1) croak("FATAL: encrypt error, call start_encrypt first (%d)", self->direction);
8282
8383 blen = (&self->state)->blocklen;
8484 in_data_start = 0;
166166 blen = 0;
167167 }
168168
169 self->direction = 0;
169170 RETVAL = newSVpvn((char*)tmp_block, blen);
170171 }
171172 OUTPUT:
180181 STRLEN in_data_len, in_data_start;
181182 unsigned char *in_data, *out_data, tmp_block[MAXBLOCKSIZE];
182183
183 if (self->direction != -1) croak("FATAL: decrypt error, call start('dec') first (%d)", self->direction);
184 if (self->direction != -1) croak("FATAL: decrypt error, call start_decryt first (%d)", self->direction);
184185
185186 blen = (&self->state)->blocklen;
186187 in_data_start = 0;
292293 if (rv_len<0) rv_len = 0;
293294 }
294295 }
296
297 self->direction = 0;
295298 RETVAL = newSVpvn((char*)tmp_block, rv_len);
296299 }
297300 OUTPUT:
99 __END__
1010
1111 =head1 NAME
12
12
1313 Crypt::AuthEnc - [internal only]
14
14
1515 =cut
183183
184184 =head2 add_bits
185185
186 $d->addfile('filename.dat');
187 #or
188 $d->addfile(*FILEHANDLE);
186 $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010");
187 #or
188 $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16);
189189
190190 =head2 hashsize
191191
183183
184184 =head2 add_bits
185185
186 $d->addfile('filename.dat');
187 #or
188 $d->addfile(*FILEHANDLE);
186 $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010");
187 #or
188 $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16);
189189
190190 =head2 hashsize
191191
183183
184184 =head2 add_bits
185185
186 $d->addfile('filename.dat');
187 #or
188 $d->addfile(*FILEHANDLE);
186 $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010");
187 #or
188 $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16);
189189
190190 =head2 hashsize
191191
183183
184184 =head2 add_bits
185185
186 $d->addfile('filename.dat');
187 #or
188 $d->addfile(*FILEHANDLE);
186 $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010");
187 #or
188 $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16);
189189
190190 =head2 hashsize
191191
183183
184184 =head2 add_bits
185185
186 $d->addfile('filename.dat');
187 #or
188 $d->addfile(*FILEHANDLE);
186 $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010");
187 #or
188 $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16);
189189
190190 =head2 hashsize
191191
183183
184184 =head2 add_bits
185185
186 $d->addfile('filename.dat');
187 #or
188 $d->addfile(*FILEHANDLE);
186 $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010");
187 #or
188 $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16);
189189
190190 =head2 hashsize
191191
183183
184184 =head2 add_bits
185185
186 $d->addfile('filename.dat');
187 #or
188 $d->addfile(*FILEHANDLE);
186 $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010");
187 #or
188 $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16);
189189
190190 =head2 hashsize
191191
183183
184184 =head2 add_bits
185185
186 $d->addfile('filename.dat');
187 #or
188 $d->addfile(*FILEHANDLE);
186 $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010");
187 #or
188 $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16);
189189
190190 =head2 hashsize
191191
183183
184184 =head2 add_bits
185185
186 $d->addfile('filename.dat');
187 #or
188 $d->addfile(*FILEHANDLE);
186 $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010");
187 #or
188 $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16);
189189
190190 =head2 hashsize
191191
183183
184184 =head2 add_bits
185185
186 $d->addfile('filename.dat');
187 #or
188 $d->addfile(*FILEHANDLE);
186 $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010");
187 #or
188 $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16);
189189
190190 =head2 hashsize
191191
183183
184184 =head2 add_bits
185185
186 $d->addfile('filename.dat');
187 #or
188 $d->addfile(*FILEHANDLE);
186 $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010");
187 #or
188 $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16);
189189
190190 =head2 hashsize
191191
183183
184184 =head2 add_bits
185185
186 $d->addfile('filename.dat');
187 #or
188 $d->addfile(*FILEHANDLE);
186 $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010");
187 #or
188 $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16);
189189
190190 =head2 hashsize
191191
183183
184184 =head2 add_bits
185185
186 $d->addfile('filename.dat');
187 #or
188 $d->addfile(*FILEHANDLE);
186 $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010");
187 #or
188 $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16);
189189
190190 =head2 hashsize
191191
183183
184184 =head2 add_bits
185185
186 $d->addfile('filename.dat');
187 #or
188 $d->addfile(*FILEHANDLE);
186 $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010");
187 #or
188 $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16);
189189
190190 =head2 hashsize
191191
183183
184184 =head2 add_bits
185185
186 $d->addfile('filename.dat');
187 #or
188 $d->addfile(*FILEHANDLE);
186 $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010");
187 #or
188 $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16);
189189
190190 =head2 hashsize
191191
307307 This method is available mostly for compatibility with other Digest::SOMETHING modules on CPAN, you are very unlikely to need it.
308308 The return value is the digest object itself.
309309
310 $d->add_bits("111100001010");
311 #or
312 $d->add_bits("\xF0\xA0", 16);
310 $d->add_bits($bit_string); # e.g. $d->add_bits("111100001010");
311 #or
312 $d->add_bits($data, $nbits); # e.g. $d->add_bits("\xF0\xA0", 16);
313313
314314 B<BEWARE:> It is not possible to add bits that are not a multiple of 8.
315315
4545 __END__
4646
4747 =head1 NAME
48
48
4949 Crypt::mode - [internal only]
50
50
5151 =cut
4343
4444 sub _crypt {
4545 my $self = shift;
46 return $self->_encrypt(@_) if $self->_get_dir == 1;
47 return $self->_decrypt(@_) if $self->_get_dir == -1;
48 return undef;
46 my $dir = $self->_get_dir;
47 return $self->_encrypt(@_) if $dir == 1;
48 return $self->_decrypt(@_) if $dir == -1;
49 return;
4950 }
5051
5152 sub _finish {
5253 my $self = shift;
53 return $self->_finish_enc(@_) if $self->_get_dir == 1;
54 return $self->_finish_dec(@_) if $self->_get_dir == -1;
55 return undef;
54 my $dir = $self->_get_dir;
55 return $self->_finish_enc(@_) if $dir == 1;
56 return $self->_finish_dec(@_) if $dir == -1;
57 return;
5658 }
5759
5860 sub CLONE_SKIP { 1 } # prevent cloning
6264 __END__
6365
6466 =head1 NAME
65
67
6668 Crypt::Mode - [internal only]
67
69
6870 =cut
1818 my $self = _new();
1919 $self->import_key($f) if $f;
2020 return $self;
21 }
22
23 sub generate_key {
24 my $self = shift;
25 $self->_generate_key(@_);
26 return $self;
2721 }
2822
2923 sub import_key {
4034 croak "FATAL: non-existing file '$key'";
4135 }
4236 croak "FATAL: invalid key format" unless $data;
43 $self->_import($data);
44 return $self;
37 return $self->_import($data);
4538 }
4639
4740 sub encrypt {
187180
188181 #Shared secret
189182 my $shared_secret = dh_shared_secret('Alice_priv_dh1.key', 'Bob_pub_dh1.key');
190
191 =head1 FUNCTIONS
192
193 =head2 dh_encrypt
194
195 DH based encryption as implemented by libtomcrypt. See method L</encrypt> below.
196
197 my $ct = dh_encrypt($pub_key_filename, $message);
198 #or
199 my $ct = dh_encrypt(\$buffer_containing_pub_key, $message);
200 #or
201 my $ct = dh_encrypt($pub_key_filename, $message, $hash_name);
202
203 #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
204
205 Encryption works similar to the L<Crypt::PK::ECC> encryption whereas shared DH key is computed, and
206 the hash of the shared key XOR'ed against the plaintext forms the ciphertext.
207
208 =head2 dh_decrypt
209
210 DH based decryption as implemented by libtomcrypt. See method L</decrypt> below.
211
212 my $pt = dh_decrypt($priv_key_filename, $ciphertext);
213 #or
214 my $pt = dh_decrypt(\$buffer_containing_priv_key, $ciphertext);
215
216 =head2 dh_sign_message
217
218 Generate DH signature as implemented by libtomcrypt. See method L</sign_message> below.
219
220 my $sig = dh_sign_message($priv_key_filename, $message);
221 #or
222 my $sig = dh_sign_message(\$buffer_containing_priv_key, $message);
223 #or
224 my $sig = dh_sign_message($priv_key, $message, $hash_name);
225
226 =head2 dh_verify_message
227
228 Verify DH signature as implemented by libtomcrypt. See method L</verify_message> below.
229
230 dh_verify_message($pub_key_filename, $signature, $message) or die "ERROR";
231 #or
232 dh_verify_message(\$buffer_containing_pub_key, $signature, $message) or die "ERROR";
233 #or
234 dh_verify_message($pub_key, $signature, $message, $hash_name) or die "ERROR";
235
236 =head2 dh_sign_hash
237
238 Generate DH signature as implemented by libtomcrypt. See method L</sign_hash> below.
239
240 my $sig = dh_sign_hash($priv_key_filename, $message_hash);
241 #or
242 my $sig = dh_sign_hash(\$buffer_containing_priv_key, $message_hash);
243
244 =head2 dh_verify_hash
245
246 Verify DH signature as implemented by libtomcrypt. See method L</verify_hash> below.
247
248 dh_verify_hash($pub_key_filename, $signature, $message_hash) or die "ERROR";
249 #or
250 dh_verify_hash(\$buffer_containing_pub_key, $signature, $message_hash) or die "ERROR";
251
252 =head2 dh_shared_secret
253
254 DH based shared secret generation. See method L</shared_secret> below.
255
256 #on Alice side
257 my $shared_secret = dh_shared_secret('Alice_priv_dh1.key', 'Bob_pub_dh1.key');
258
259 #on Bob side
260 my $shared_secret = dh_shared_secret('Bob_priv_dh1.key', 'Alice_pub_dh1.key');
261183
262184 =head1 METHODS
263185
344266
345267 =head2 shared_secret
346268
347 # Alice having her priv key $pk and Bob's public key $pkb
348 my $pk = Crypt::PK::DH->new($priv_key_filename);
349 my $pkb = Crypt::PK::DH->new($pub_key_filename);
350 my $shared_secret = $pk->shared_secret($pkb);
351
352 # Bob having his priv key $pk and Alice's public key $pka
353 my $pk = Crypt::PK::DH->new($priv_key_filename);
354 my $pka = Crypt::PK::DH->new($pub_key_filename);
355 my $shared_secret = $pk->shared_secret($pka); # same value as computed by Alice
269 # Alice having her priv key $pk and Bob's public key $pkb
270 my $pk = Crypt::PK::DH->new($priv_key_filename);
271 my $pkb = Crypt::PK::DH->new($pub_key_filename);
272 my $shared_secret = $pk->shared_secret($pkb);
273
274 # Bob having his priv key $pk and Alice's public key $pka
275 my $pk = Crypt::PK::DH->new($priv_key_filename);
276 my $pka = Crypt::PK::DH->new($pub_key_filename);
277 my $shared_secret = $pk->shared_secret($pka); # same value as computed by Alice
356278
357279 =head2 is_private
358280
379301 y => "AB9AAA40774D3CD476B52F82E7EE2D8A8D40CD88BF4...", #public key
380302 }
381303
304 =head1 FUNCTIONS
305
306 =head2 dh_encrypt
307
308 DH based encryption as implemented by libtomcrypt. See method L</encrypt> below.
309
310 my $ct = dh_encrypt($pub_key_filename, $message);
311 #or
312 my $ct = dh_encrypt(\$buffer_containing_pub_key, $message);
313 #or
314 my $ct = dh_encrypt($pub_key_filename, $message, $hash_name);
315
316 #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
317
318 Encryption works similar to the L<Crypt::PK::ECC> encryption whereas shared DH key is computed, and
319 the hash of the shared key XOR'ed against the plaintext forms the ciphertext.
320
321 =head2 dh_decrypt
322
323 DH based decryption as implemented by libtomcrypt. See method L</decrypt> below.
324
325 my $pt = dh_decrypt($priv_key_filename, $ciphertext);
326 #or
327 my $pt = dh_decrypt(\$buffer_containing_priv_key, $ciphertext);
328
329 =head2 dh_sign_message
330
331 Generate DH signature as implemented by libtomcrypt. See method L</sign_message> below.
332
333 my $sig = dh_sign_message($priv_key_filename, $message);
334 #or
335 my $sig = dh_sign_message(\$buffer_containing_priv_key, $message);
336 #or
337 my $sig = dh_sign_message($priv_key, $message, $hash_name);
338
339 =head2 dh_verify_message
340
341 Verify DH signature as implemented by libtomcrypt. See method L</verify_message> below.
342
343 dh_verify_message($pub_key_filename, $signature, $message) or die "ERROR";
344 #or
345 dh_verify_message(\$buffer_containing_pub_key, $signature, $message) or die "ERROR";
346 #or
347 dh_verify_message($pub_key, $signature, $message, $hash_name) or die "ERROR";
348
349 =head2 dh_sign_hash
350
351 Generate DH signature as implemented by libtomcrypt. See method L</sign_hash> below.
352
353 my $sig = dh_sign_hash($priv_key_filename, $message_hash);
354 #or
355 my $sig = dh_sign_hash(\$buffer_containing_priv_key, $message_hash);
356
357 =head2 dh_verify_hash
358
359 Verify DH signature as implemented by libtomcrypt. See method L</verify_hash> below.
360
361 dh_verify_hash($pub_key_filename, $signature, $message_hash) or die "ERROR";
362 #or
363 dh_verify_hash(\$buffer_containing_pub_key, $signature, $message_hash) or die "ERROR";
364
365 =head2 dh_shared_secret
366
367 DH based shared secret generation. See method L</shared_secret> below.
368
369 #on Alice side
370 my $shared_secret = dh_shared_secret('Alice_priv_dh1.key', 'Bob_pub_dh1.key');
371
372 #on Bob side
373 my $shared_secret = dh_shared_secret('Bob_priv_dh1.key', 'Alice_pub_dh1.key');
374
382375 =head1 SEE ALSO
383376
384377 =over
2323 sub export_key_pem {
2424 my ($self, $type, $password, $cipher) = @_;
2525 my $key = $self->export_key_der($type||'');
26 return undef unless $key;
26 return unless $key;
2727 return Crypt::PK::_asn1_to_pem($key, "DSA PRIVATE KEY", $password, $cipher) if $type eq 'private';
2828 return Crypt::PK::_asn1_to_pem($key, "DSA PUBLIC KEY") if $type eq 'public';
29 }
30
31 sub generate_key {
32 my $self = shift;
33 $self->_generate_key(@_);
34 return $self;
29 return Crypt::PK::_asn1_to_pem($key, "PUBLIC KEY") if $type eq 'public_x509';
3530 }
3631
3732 sub import_key {
5146 $data = Crypt::PK::_pem_to_asn1($data, $password);
5247 }
5348 croak "FATAL: invalid key format" unless $data;
54 $self->_import($data);
55 return $self;
49 return $self->_import($data);
5650 }
5751
5852 sub encrypt {
194188 #Signature: Bob (received $message + $sig)
195189 dsa_verify_message('Alice_pub_dsa1.der', $sig, $message) or die "ERROR";
196190
197 =head1 FUNCTIONS
198
199 =head2 dsa_encrypt
200
201 DSA based encryption as implemented by libtomcrypt. See method L</encrypt> below.
202
203 my $ct = dsa_encrypt($pub_key_filename, $message);
204 #or
205 my $ct = dsa_encrypt(\$buffer_containing_pub_key, $message);
206 #or
207 my $ct = dsa_encrypt($pub_key_filename, $message, $hash_name);
208
209 #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
210
211 Encryption works similar to the L<Crypt::PK::ECC> encryption whereas shared DSA key is computed, and
212 the hash of the shared key XOR'ed against the plaintext forms the ciphertext.
213
214 =head2 dsa_decrypt
215
216 DSA based decryption as implemented by libtomcrypt. See method L</decrypt> below.
217
218 my $pt = dsa_decrypt($priv_key_filename, $ciphertext);
219 #or
220 my $pt = dsa_decrypt(\$buffer_containing_priv_key, $ciphertext);
221
222 =head2 dsa_sign_message
223
224 Generate DSA signature. See method L</sign_message> below.
225
226 my $sig = dsa_sign_message($priv_key_filename, $message);
227 #or
228 my $sig = dsa_sign_message(\$buffer_containing_priv_key, $message);
229 #or
230 my $sig = dsa_sign_message($priv_key, $message, $hash_name);
231
232 =head2 dsa_verify_message
233
234 Verify DSA signature. See method L</verify_message> below.
235
236 dsa_verify_message($pub_key_filename, $signature, $message) or die "ERROR";
237 #or
238 dsa_verify_message(\$buffer_containing_pub_key, $signature, $message) or die "ERROR";
239 #or
240 dsa_verify_message($pub_key, $signature, $message, $hash_name) or die "ERROR";
241
242 =head2 dsa_sign_hash
243
244 Generate DSA signature. See method L</sign_hash> below.
245
246 my $sig = dsa_sign_hash($priv_key_filename, $message_hash);
247 #or
248 my $sig = dsa_sign_hash(\$buffer_containing_priv_key, $message_hash);
249
250 =head2 dsa_verify_hash
251
252 Verify DSA signature. See method L</verify_hash> below.
253
254 dsa_verify_hash($pub_key_filename, $signature, $message_hash) or die "ERROR";
255 #or
256 dsa_verify_hash(\$buffer_containing_pub_key, $signature, $message_hash) or die "ERROR";
257
258191 =head1 METHODS
259192
260193 =head2 new
318251 my $private_pem = $pk->export_key_pem('private');
319252 #or
320253 my $public_pem = $pk->export_key_pem('public');
254 #or
255 my $public_pem = $pk->export_key_pem('public_x509');
256
257 With parameter C<'public'> uses header and footer lines:
258
259 -----BEGIN DSA PUBLIC KEY------
260 -----END DSA PUBLIC KEY------
261
262 With parameter C<'public_x509'> uses header and footer lines:
263
264 -----BEGIN PUBLIC KEY------
265 -----END PUBLIC KEY------
321266
322267 Support for password protected PEM keys
323268
324269 my $private_pem = $pk->export_key_pem('private', $password);
325270 #or
326271 my $private_pem = $pk->export_key_pem('private', $password, $cipher);
327
272
328273 # supported ciphers: 'DES-CBC'
329274 # 'DES-EDE3-CBC'
330275 # 'SEED-CBC'
276 # 'CAMELLIA-128-CBC'
277 # 'CAMELLIA-192-CBC'
278 # 'CAMELLIA-256-CBC'
331279 # 'AES-128-CBC'
332280 # 'AES-192-CBC'
333281 # 'AES-256-CBC' (DEFAULT)
402350 y => "8F7604D77FA62C7539562458A63C7611B7...", #public key, where y = g^x mod p
403351 }
404352
353 =head1 FUNCTIONS
354
355 =head2 dsa_encrypt
356
357 DSA based encryption as implemented by libtomcrypt. See method L</encrypt> below.
358
359 my $ct = dsa_encrypt($pub_key_filename, $message);
360 #or
361 my $ct = dsa_encrypt(\$buffer_containing_pub_key, $message);
362 #or
363 my $ct = dsa_encrypt($pub_key_filename, $message, $hash_name);
364
365 #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
366
367 Encryption works similar to the L<Crypt::PK::ECC> encryption whereas shared DSA key is computed, and
368 the hash of the shared key XOR'ed against the plaintext forms the ciphertext.
369
370 =head2 dsa_decrypt
371
372 DSA based decryption as implemented by libtomcrypt. See method L</decrypt> below.
373
374 my $pt = dsa_decrypt($priv_key_filename, $ciphertext);
375 #or
376 my $pt = dsa_decrypt(\$buffer_containing_priv_key, $ciphertext);
377
378 =head2 dsa_sign_message
379
380 Generate DSA signature. See method L</sign_message> below.
381
382 my $sig = dsa_sign_message($priv_key_filename, $message);
383 #or
384 my $sig = dsa_sign_message(\$buffer_containing_priv_key, $message);
385 #or
386 my $sig = dsa_sign_message($priv_key, $message, $hash_name);
387
388 =head2 dsa_verify_message
389
390 Verify DSA signature. See method L</verify_message> below.
391
392 dsa_verify_message($pub_key_filename, $signature, $message) or die "ERROR";
393 #or
394 dsa_verify_message(\$buffer_containing_pub_key, $signature, $message) or die "ERROR";
395 #or
396 dsa_verify_message($pub_key, $signature, $message, $hash_name) or die "ERROR";
397
398 =head2 dsa_sign_hash
399
400 Generate DSA signature. See method L</sign_hash> below.
401
402 my $sig = dsa_sign_hash($priv_key_filename, $message_hash);
403 #or
404 my $sig = dsa_sign_hash(\$buffer_containing_priv_key, $message_hash);
405
406 =head2 dsa_verify_hash
407
408 Verify DSA signature. See method L</verify_hash> below.
409
410 dsa_verify_hash($pub_key_filename, $signature, $message_hash) or die "ERROR";
411 #or
412 dsa_verify_hash(\$buffer_containing_pub_key, $signature, $message_hash) or die "ERROR";
413
414 =head1 OpenSSL interoperability
415
416 ### let's have:
417 # DSA private key in PEM format - dsakey.priv.pem
418 # DSA public key in PEM format - dsakey.pub.pem
419 # data file to be signed - input.data
420
421 =head2 Sign by OpenSSL, verify by Crypt::PK::DSA
422
423 Create signature (from commandline):
424
425 openssl dgst -sha1 -sign dsakey.priv.pem -out input.sha1-dsa.sig input.data
426
427 Verify signature (Perl code):
428
429 use Crypt::PK::DSA;
430 use Crypt::Digest 'digest_file';
431 use File::Slurp 'read_file';
432
433 my $pkdsa = Crypt::PK::DSA->new("dsakey.pub.pem");
434 my $signature = read_file("input.sha1-dsa.sig", binmode=>':raw');
435 my $valid = $pkdsa->verify_hash($signature, digest_file("SHA1", "input.data"), "SHA1", "v1.5");
436 print $valid ? "SUCCESS" : "FAILURE";
437
438 =head2 Sign by Crypt::PK::DSA, verify by OpenSSL
439
440 Create signature (Perl code):
441
442 use Crypt::PK::DSA;
443 use Crypt::Digest 'digest_file';
444 use File::Slurp 'write_file';
445
446 my $pkdsa = Crypt::PK::DSA->new("dsakey.priv.pem");
447 my $signature = $pkdsa->sign_hash(digest_file("SHA1", "input.data"), "SHA1", "v1.5");
448 write_file("input.sha1-dsa.sig", {binmode=>':raw'}, $signature);
449
450 Verify signature (from commandline):
451
452 openssl dgst -sha1 -verify dsakey.pub.pem -signature input.sha1-dsa.sig input.data
453
454 =head2 Keys generated by Crypt::PK::DSA
455
456 Generate keys (Perl code):
457
458 use Crypt::PK::DSA;
459 use File::Slurp 'write_file';
460
461 my $pkdsa = Crypt::PK::DSA->new;
462 $pkdsa->generate_key(20, 128);
463 write_file("dsakey.pub.der", {binmode=>':raw'}, $pkdsa->export_key_der('public'));
464 write_file("dsakey.priv.der", {binmode=>':raw'}, $pkdsa->export_key_der('private'));
465 write_file("dsakey.pub.pem", $pkdsa->export_key_pem('public_x509'));
466 write_file("dsakey.priv.pem", $pkdsa->export_key_pem('private'));
467 write_file("dsakey-passwd.priv.pem", $pkdsa->export_key_pem('private', 'secret'));
468
469 Use keys by OpenSSL:
470
471 openssl dsa -in dsakey.priv.der -text -inform der
472 openssl dsa -in dsakey.priv.pem -text
473 openssl dsa -in dsakey-passwd.priv.pem -text -inform pem -passin pass:secret
474 openssl dsa -in dsakey.pub.der -pubin -text -inform der
475 openssl dsa -in dsakey.pub.pem -pubin -text
476
477 =head2 Keys generated by OpenSSL
478
479 Generate keys:
480
481 openssl dsaparam -genkey -out dsakey.priv.pem 1024
482 openssl dsa -in dsakey.priv.pem -out dsakey.priv.der -outform der
483 openssl dsa -in dsakey.priv.pem -out dsakey.pub.pem -pubout
484 openssl dsa -in dsakey.priv.pem -out dsakey.pub.der -outform der -pubout
485 openssl dsa -in dsakey.priv.pem -passout pass:secret -des3 -out dsakey-passwd.priv.pem
486
487 Load keys (Perl code):
488
489 use Crypt::PK::DSA;
490 use File::Slurp 'write_file';
491
492 my $pkdsa = Crypt::PK::DSA->new;
493 $pkdsa->import_key("dsakey.pub.der");
494 $pkdsa->import_key("dsakey.priv.der");
495 $pkdsa->import_key("dsakey.pub.pem");
496 $pkdsa->import_key("dsakey.priv.pem");
497 $pkdsa->import_key("dsakey-passwd.priv.pem", "secret");
498
405499 =head1 SEE ALSO
406500
407501 =over
1313 use Carp;
1414 use MIME::Base64 qw(encode_base64 decode_base64);
1515
16 our %curve = (
17 ### http://www.ecc-brainpool.org/download/Domain-parameters.pdf (v1.0 19.10.2005)
18 brainpoolP160r1 => {
19 prime => "E95E4A5F737059DC60DFC7AD95B3D8139515620F",
20 A => "340E7BE2A280EB74E2BE61BADA745D97E8F7C300",
21 B => "1E589A8595423412134FAA2DBDEC95C8D8675E58",
22 Gx => "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3",
23 Gy => "1667CB477A1A8EC338F94741669C976316DA6321",
24 order => "E95E4A5F737059DC60DF5991D45029409E60FC09",
25 cofactor => 1,
26 },
27 brainpoolP192r1 => {
28 prime => "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297",
29 A => "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF",
30 B => "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9",
31 Gx => "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6",
32 Gy => "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F",
33 order => "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1",
34 cofactor => 1,
35 },
36 brainpoolP224r1 => {
37 prime => "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF",
38 A => "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43",
39 B => "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B",
40 Gx => "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D",
41 Gy => "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD",
42 order => "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F",
43 cofactor => 1,
44 },
45 brainpoolP256r1 => {
46 prime => "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377",
47 A => "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9",
48 B => "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6",
49 Gx => "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262",
50 Gy => "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997",
51 order => "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7",
52 cofactor => 1,
53 },
54 brainpoolP320r1 => {
55 prime => "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27",
56 A => "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4",
57 B => "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6",
58 Gx => "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611",
59 Gy => "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1",
60 order => "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311",
61 cofactor => 1,
62 },
63 brainpoolP384r1 => {
64 prime => "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53",
65 A => "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826",
66 B => "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11",
67 Gx => "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E",
68 Gy => "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315",
69 order => "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565",
70 cofactor => 1,
71 },
72 brainpoolP512r1 => {
73 prime => "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3",
74 A => "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA",
75 B => "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723",
76 Gx => "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822",
77 Gy => "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892",
78 order => "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069",
79 cofactor => 1,
80 },
81 ### http://www.secg.org/collateral/sec2_final.pdf (September 20, 2000 - Version 1.0)
82 secp112r1 => {
83 prime => "DB7C2ABF62E35E668076BEAD208B",
84 A => "DB7C2ABF62E35E668076BEAD2088",
85 B => "659EF8BA043916EEDE8911702B22",
86 Gx => "09487239995A5EE76B55F9C2F098",
87 Gy => "A89CE5AF8724C0A23E0E0FF77500",
88 order => "DB7C2ABF62E35E7628DFAC6561C5",
89 cofactor => 1,
90 },
91 secp112r2 => {
92 prime => "DB7C2ABF62E35E668076BEAD208B",
93 A => "6127C24C05F38A0AAAF65C0EF02C",
94 B => "51DEF1815DB5ED74FCC34C85D709",
95 Gx => "4BA30AB5E892B4E1649DD0928643",
96 Gy => "ADCD46F5882E3747DEF36E956E97",
97 order => "36DF0AAFD8B8D7597CA10520D04B",
98 cofactor => 4,
99 },
100 secp128r1 => {
101 prime => "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
102 A => "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC",
103 B => "E87579C11079F43DD824993C2CEE5ED3",
104 Gx => "161FF7528B899B2D0C28607CA52C5B86",
105 Gy => "CF5AC8395BAFEB13C02DA292DDED7A83",
106 order => "FFFFFFFE0000000075A30D1B9038A115",
107 cofactor => 1,
108 },
109 secp128r2 => {
110 prime => "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
111 A => "D6031998D1B3BBFEBF59CC9BBFF9AEE1",
112 B => "5EEEFCA380D02919DC2C6558BB6D8A5D",
113 Gx => "7B6AA5D85E572983E6FB32A7CDEBC140",
114 Gy => "27B6916A894D3AEE7106FE805FC34B44",
115 order => "3FFFFFFF7FFFFFFFBE0024720613B5A3",
116 cofactor => 4,
117 },
118 secp160k1 => {
119 prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
120 A => "0000000000000000000000000000000000000000",
121 B => "0000000000000000000000000000000000000007",
122 Gx => "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB",
123 Gy => "938CF935318FDCED6BC28286531733C3F03C4FEE",
124 order => "0100000000000000000001B8FA16DFAB9ACA16B6B3",
125 cofactor => 1,
126 },
127 secp160r1 => {
128 prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF",
129 A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC",
130 B => "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45",
131 Gx => "4A96B5688EF573284664698968C38BB913CBFC82",
132 Gy => "23A628553168947D59DCC912042351377AC5FB32",
133 order => "0100000000000000000001F4C8F927AED3CA752257",
134 cofactor => 1,
135 },
136 secp160r2 => {
137 prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
138 A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70",
139 B => "B4E134D3FB59EB8BAB57274904664D5AF50388BA",
140 Gx => "52DCB034293A117E1F4FF11B30F7199D3144CE6D",
141 Gy => "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E",
142 order => "0100000000000000000000351EE786A818F3A1A16B",
143 cofactor => 1,
144 },
145 secp192k1 => {
146 prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37",
147 A => "000000000000000000000000000000000000000000000000",
148 B => "000000000000000000000000000000000000000000000003",
149 Gx => "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D",
150 Gy => "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D",
151 order => "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D",
152 cofactor => 1,
153 },
154 secp192r1 => {
155 prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
156 A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
157 B => "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1",
158 Gx => "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
159 Gy => "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811",
160 order => "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",
161 cofactor => 1,
162 },
163 secp224k1 => {
164 prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D",
165 A => "00000000000000000000000000000000000000000000000000000000",
166 B => "00000000000000000000000000000000000000000000000000000005",
167 Gx => "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C",
168 Gy => "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5",
169 order => "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",
170 cofactor => 1,
171 },
172 secp224r1 => {
173 prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
174 A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
175 B => "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
176 Gx => "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
177 Gy => "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
178 order => "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
179 cofactor => 1,
180 },
181 secp256k1 => {
182 prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F",
183 A => "0000000000000000000000000000000000000000000000000000000000000000",
184 B => "0000000000000000000000000000000000000000000000000000000000000007",
185 Gx => "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",
186 Gy => "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8",
187 order => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",
188 cofactor => 1,
189 },
190 secp256r1 => {
191 prime => "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
192 A => "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
193 B => "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
194 Gx => "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
195 Gy => "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
196 order => "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
197 cofactor => 1,
198 },
199 secp384r1 => {
200 prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
201 A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
202 B => "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
203 Gx => "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
204 Gy => "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
205 order => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
206 cofactor => 1,
207 },
208 secp521r1 => {
209 prime => "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
210 A => "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
211 B => "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
212 Gx => "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
213 Gy => "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
214 order => "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
215 cofactor => 1
216 },
217 ### http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf (July 2013)
218 nistp192 => {
219 prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF',
220 A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC',
221 B => '64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1',
222 Gx => '188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012',
223 Gy => '07192B95FFC8DA78631011ED6B24CDD573F977A11E794811',
224 order => 'FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831',
225 cofactor => 1,
226 },
227 nistp224 => {
228 prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001',
229 A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE',
230 B => 'B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4',
231 Gx => 'B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21',
232 Gy => 'BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34',
233 order => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D',
234 cofactor => 1,
235 },
236 nistp256 => {
237 prime => 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF',
238 A => 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC',
239 B => '5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B',
240 Gx => '6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296',
241 Gy => '4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5',
242 order => 'FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551',
243 cofactor => 1,
244 },
245 nistp384 => {
246 prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF',
247 A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC',
248 B => 'B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF',
249 Gx => 'AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7',
250 Gy => '3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F',
251 order => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973',
252 cofactor => 1,
253 },
254 nistp521 => {
255 prime => '1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF',
256 A => '1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC',
257 B => '051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00',
258 Gx => '0C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66',
259 Gy => '11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650',
260 order => '1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409',
261 cofactor => 1,
262 },
263 ### ANS X9.62 elliptic curves - http://www.flexiprovider.de/CurvesGfpX962.html
264 prime192v1 => {
265 prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF',
266 A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC',
267 B => '64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1',
268 Gx => '188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012',
269 Gy => '07192B95FFC8DA78631011ED6B24CDD573F977A11E794811',
270 order => 'FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831',
271 cofactor => 1,
272 },
273 prime192v2 => {
274 prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF',
275 A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC',
276 B => 'CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953',
277 Gx => 'EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A',
278 Gy => '6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15',
279 order => 'FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31',
280 cofactor => 1
281 },
282 prime192v3 => {
283 prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF',
284 A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC',
285 B => '22123DC2395A05CAA7423DAECCC94760A7D462256BD56916',
286 Gx => '7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896',
287 Gy => '38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0',
288 order => 'FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13',
289 cofactor => 1,
290 },
291 prime239v1 => {
292 prime => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF',
293 A => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC',
294 B => '6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A',
295 Gx => '0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF',
296 Gy => '7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE',
297 order => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B',
298 cofactor => 1,
299 },
300 prime239v2 => {
301 prime => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF',
302 A => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC',
303 B => '617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C',
304 Gx => '38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7',
305 Gy => '5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA',
306 order => '7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063',
307 cofactor => 1,
308 },
309 prime239v3 => {
310 prime => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF',
311 A => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC',
312 B => '255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E',
313 Gx => '6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A',
314 Gy => '1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3',
315 order => '7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551',
316 cofactor => 1,
317 },
318 prime256v1 => {
319 prime => 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF',
320 A => 'FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC',
321 B => '5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B',
322 Gx => '6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296',
323 Gy => '4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5',
324 order => 'FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551',
325 cofactor => 1,
326 },
327 );
328
16329 sub new {
17 my ($class, $f) = @_;
330 my ($class, $f, $p) = @_;
18331 my $self = _new();
19 $self->import_key($f) if $f;
332 $self->import_key($f, $p) if $f;
20333 return $self;
21334 }
22335
23 sub generate_key {
24 my $self = shift;
25 $self->_generate_key(@_);
26 return $self;
336 sub export_key_pem {
337 my ($self, $type, $password, $cipher) = @_;
338 my $key = $self->export_key_der($type||'');
339 return unless $key;
340 return Crypt::PK::_asn1_to_pem($key, "EC PRIVATE KEY", $password, $cipher) if $type eq 'private';
341 return Crypt::PK::_asn1_to_pem($key, "PUBLIC KEY") if $type eq 'public' || $type eq 'public_compressed';
27342 }
28343
29344 sub import_key {
30 my ($self, $key) = @_;
345 my ($self, $key, $password) = @_;
31346 croak "FATAL: undefined key" unless $key;
32347 my $data;
33348 if (ref($key) eq 'SCALAR') {
39354 else {
40355 croak "FATAL: non-existing file '$key'";
41356 }
42 ### no PEM support
43 #if ($data && $data =~ /-----BEGIN (EC PRIVATE|EC PUBLIC|PRIVATE|PUBLIC) KEY-----(.*?)-----END/sg) {
44 # $data = decode_base64($2);
45 #}
357 if ($data && $data =~ /-----BEGIN (EC PRIVATE|EC PUBLIC|PRIVATE|PUBLIC) KEY-----(.*?)-----END/sg) {
358 $data = Crypt::PK::_pem_to_asn1($data, $password);
359 }
46360 croak "FATAL: invalid key format" unless $data;
47 $self->_import($data);
48 return $self;
361 return $self->_import($data);
49362 }
50363
51364 sub encrypt {
173486
174487 #Key generation
175488 my $pk = Crypt::PK::ECC->new();
176 $pk->generate_key(24);
489 $pk->generate_key('secp160r1');
177490 my $private_der = $pk->export_key_der('private');
178491 my $public_der = $pk->export_key_der('public');
179 my $public_ansi_x963 = $pk->export_key_x963();
492 my $private_pem = $pk->export_key_pem('private');
493 my $public_pem = $pk->export_key_pem('public');
494 my $public_raw = $pk->export_key_raw('public');
180495
181496 ### Functional interface
182497
195510
196511 =head1 DESCRIPTION
197512
198 The module provides a set of core ECC functions as well that are designed to be the Elliptic Curve analogy of
199 all of the Diffie-Hellman routines (ECDH).
200
201 =head1 FUNCTIONS
202
203 =head2 ecc_encrypt
204
205 Elliptic Curve Diffie-Hellman (ECDH) encryption as implemented by libtomcrypt. See method L</encrypt> below.
206
207 my $ct = ecc_encrypt($pub_key_filename, $message);
208 #or
209 my $ct = ecc_encrypt(\$buffer_containing_pub_key, $message);
210 #or
211 my $ct = ecc_encrypt($pub_key_filename, $message, $hash_name);
212
213 #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
214
215 ECCDH Encryption is performed by producing a random key, hashing it, and XOR'ing the digest against the plaintext.
216
217 =head2 ecc_decrypt
218
219 Elliptic Curve Diffie-Hellman (ECDH) decryption as implemented by libtomcrypt. See method L</decrypt> below.
220
221 my $pt = ecc_decrypt($priv_key_filename, $ciphertext);
222 #or
223 my $pt = ecc_decrypt(\$buffer_containing_priv_key, $ciphertext);
224
225 =head2 ecc_sign_message
226
227 Elliptic Curve Digital Signature Algorithm (ECDSA) - signature generation. See method L</sign_message> below.
228
229 my $sig = ecc_sign_message($priv_key_filename, $message);
230 #or
231 my $sig = ecc_sign_message(\$buffer_containing_priv_key, $message);
232 #or
233 my $sig = ecc_sign_message($priv_key, $message, $hash_name);
234
235 =head2 ecc_verify_message
236
237 Elliptic Curve Digital Signature Algorithm (ECDSA) - signature verification. See method L</verify_message> below.
238
239 ecc_verify_message($pub_key_filename, $signature, $message) or die "ERROR";
240 #or
241 ecc_verify_message(\$buffer_containing_pub_key, $signature, $message) or die "ERROR";
242 #or
243 ecc_verify_message($pub_key, $signature, $message, $hash_name) or die "ERROR";
244
245 =head2 ecc_sign_hash
246
247 Elliptic Curve Digital Signature Algorithm (ECDSA) - signature generation. See method L</sign_hash> below.
248
249 my $sig = ecc_sign_hash($priv_key_filename, $message_hash);
250 #or
251 my $sig = ecc_sign_hash(\$buffer_containing_priv_key, $message_hash);
252
253 =head2 ecc_verify_hash
254
255 Elliptic Curve Digital Signature Algorithm (ECDSA) - signature verification. See method L</verify_hash> below.
256
257 ecc_verify_hash($pub_key_filename, $signature, $message_hash) or die "ERROR";
258 #or
259 ecc_verify_hash(\$buffer_containing_pub_key, $signature, $message_hash) or die "ERROR";
260
261 =head2 ecc_shared_secret
262
263 Elliptic curve Diffie-Hellman (ECDH) - construct a Diffie-Hellman shared secret with a private and public ECC key. See method L</shared_secret> below.
264
265 #on Alice side
266 my $shared_secret = ecc_shared_secret('Alice_priv_ecc1.der', 'Bob_pub_ecc1.der');
267
268 #on Bob side
269 my $shared_secret = ecc_shared_secret('Bob_priv_ecc1.der', 'Alice_pub_ecc1.der');
513 The module provides a set of core ECC functions as well as implementation of ECDSA and ECDH.
514
515 Supports elliptic curves C<y^2 = x^3 + a*x + b> over prime fields C<Fp = Z/pZ> (binary fields not supported).
270516
271517 =head1 METHODS
272518
278524 #or
279525 my $pk = Crypt::PK::ECC->new(\$buffer_containing_priv_or_pub_key);
280526
527 Support for password protected PEM keys
528
529 my $pk = Crypt::PK::ECC->new($priv_pem_key_filename, $password);
530 #or
531 my $pk = Crypt::PK::ECC->new(\$buffer_containing_priv_pem_key, $password);
532
281533 =head2 generate_key
282534
283535 Uses Yarrow-based cryptographically strong random number generator seeded with
284536 random data taken from C</dev/random> (UNIX) or C<CryptGenRandom> (Win32).
285537
286 $pk->generate_key($keysize);
287 # $keysize .. key size in bytes: 14, 16, 20, 24, 28, 32, 48 or 65
288 # 14 => use curve SECP112R1
289 # 16 => use curve SECP128R1
290 # 20 => use curve SECP160R1
291 # 24 => use curve P-192 recommended by FIPS 186-3
292 # 28 => use curve P-224 recommended by FIPS 186-3
293 # 32 => use curve P-256 recommended by FIPS 186-3
294 # 48 => use curve P-384 recommended by FIPS 186-3
295 # 65 => use curve P-521 recommended by FIPS 186-3
296
297 See L<http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf> and L<http://www.secg.org/collateral/sec2_final.pdf>
538 $pk->generate_key($curve_name);
539 #or
540 $pk->generate_key($hashref_with_curve_params);
541
542 The following pre-defined C<$curve_name> values are supported:
543
544 # curves from http://www.ecc-brainpool.org/download/Domain-parameters.pdf
545 'brainpoolP160r1'
546 'brainpoolP192r1'
547 'brainpoolP224r1'
548 'brainpoolP256r1'
549 'brainpoolP320r1'
550 'brainpoolP384r1'
551 'brainpoolP512r1'
552 # curves from http://www.secg.org/collateral/sec2_final.pdf
553 'secp112r1'
554 'secp112r2'
555 'secp128r1'
556 'secp128r2'
557 'secp160k1'
558 'secp160r1'
559 'secp160r2'
560 'secp192k1'
561 'secp192r1'
562 'secp224k1'
563 'secp224r1'
564 'secp256k1' ... used by Bitcoin
565 'secp256r1'
566 'secp384r1'
567 'secp521r1'
568 #curves from http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
569 'nistp192'
570 'nistp224'
571 'nistp256'
572 'nistp384'
573 'nistp521'
574 # curves from ANS X9.62
575 'prime192v1'
576 'prime192v2'
577 'prime192v3'
578 'prime239v1'
579 'prime239v2'
580 'prime239v3'
581 'prime256v1'
582
583 Using custom curve parameters:
584
585 $pk->generate_key({ prime => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF',
586 A => 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC',
587 B => '22123DC2395A05CAA7423DAECCC94760A7D462256BD56916',
588 Gx => '7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896',
589 Gy => '38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0',
590 order => 'FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13',
591 cofactor => 1 });
592
593 See L<http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf>, L<http://www.secg.org/collateral/sec2_final.pdf>, L<http://www.ecc-brainpool.org/download/Domain-parameters.pdf>
298594
299595 =head2 import_key
300596
301 Loads private or public key in DER format (exported by L</export_key_der>).
597 Loads private or public key in DER or PEM format.
302598
303599 $pk->import_key($filename);
304600 #or
305601 $pk->import_key(\$buffer_containing_key);
306602
307 =head2 import_key_x963
308
309 ANSI X9.63 Import (public key only) - can load data exported by L</export_key_x963>.
310
311 $pk->import_key(\$buffer_containing_pub_key_ansi_x963);
603 Support for password protected PEM keys
604
605 $pk->import_key($pem_filename, $password);
606 #or
607 $pk->import_key(\$buffer_containing_pem_key, $password);
608
609 =head2 import_key_raw
610
611 Import raw public/private key - can load data exported by L</export_key_raw>.
612
613 $pk->import_key_raw($key, $curve);
614 # $key .... data exported by export_key_raw()
615 # $curve .. curve name or hashref with curve parameters - same as by generate_key()
312616
313617 =head2 export_key_der
314618
316620 #or
317621 my $public_der = $pk->export_key_der('public');
318622
319 =head2 export_key_x963
320
321 ANSI X9.63 Export (public key only)
322
323 my $public_ansi_x963 = $pk->export_key_x963();
623 =head2 export_key_pem
624
625 my $private_pem = $pk->export_key_pem('private');
626 #or
627 my $public_pem = $pk->export_key_pem('public');
628
629 Support for password protected PEM keys
630
631 my $private_pem = $pk->export_key_pem('private', $password);
632 #or
633 my $private_pem = $pk->export_key_pem('private', $password, $cipher);
634
635 # supported ciphers: 'DES-CBC'
636 # 'DES-EDE3-CBC'
637 # 'SEED-CBC'
638 # 'CAMELLIA-128-CBC'
639 # 'CAMELLIA-192-CBC'
640 # 'CAMELLIA-256-CBC'
641 # 'AES-128-CBC'
642 # 'AES-192-CBC'
643 # 'AES-256-CBC' (DEFAULT)
644
645 =head2 export_key_raw
646
647 Export raw public/private key. Public key is exported in ANS X9.63 format (compressed or uncompressed),
648 private key is exported as raw bytes (padded with leading zeros to have the same size as the ECC curve).
649
650 my $pubkey_octets = $pk->export_key_raw('public');
651 #or
652 my $pubckey_octets = $pk->export_key_raw('public_compressed');
653 #or
654 my $privkey_octets = $pk->export_key_raw('private');
324655
325656 =head2 encrypt
326657
394725
395726 # returns hash like this (or undef if no key loaded):
396727 {
397 type => 1, # integer: 1 .. private, 0 .. public
398 size => 32, # integer: key (curve) size in bytes
728 size => 20, # integer: key (curve) size in bytes
729 type => 1, # integer: 1 .. private, 0 .. public
399730 #curve parameters
400 curve_name => "ECC-256",
401 curve_size => 32,
402 curve_B => "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
403 curve_Gx => "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
404 curve_Gy => "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
405 curve_order => "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
406 curve_prime => "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
731 curve_A => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC",
732 curve_B => "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45",
733 curve_bits => 160,
734 curve_bytes => 20,
735 curve_cofactor => 1,
736 curve_Gx => "4A96B5688EF573284664698968C38BB913CBFC82",
737 curve_Gy => "23A628553168947D59DCC912042351377AC5FB32",
738 curve_name => "secp160r1",
739 curve_order => "0100000000000000000001F4C8F927AED3CA752257",
740 curve_prime => "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF",
407741 #private key
408 k => "A7F43ACD4A05D69AE4597E6E723EB5F1E9B9B7EAA51B6DE83CF36F9687B57DEE",
742 k => "B0EE84A749FE95DF997E33B8F333E12101E824C3",
409743 #public key point coordinates
410 pub_x => "AB53ED5D16CE550BAAF16BA4F161332AAD56D63790629C27871ED515D4FC229C",
411 pub_y => "78FC34C6A320E22672A96EBB6DA48387A40541A3D7E5CFAE0D58A513E38C8888",
412 pub_z => "1",
744 pub_x => "5AE1ACE3ED0AEA9707CE5C0BCE014F6A2F15023A",
745 pub_y => "895D57E992D0A15F88D6680B27B701F615FCDC0F",
413746 }
414747
748 =head1 FUNCTIONS
749
750 =head2 ecc_encrypt
751
752 Elliptic Curve Diffie-Hellman (ECDH) encryption as implemented by libtomcrypt. See method L</encrypt> below.
753
754 my $ct = ecc_encrypt($pub_key_filename, $message);
755 #or
756 my $ct = ecc_encrypt(\$buffer_containing_pub_key, $message);
757 #or
758 my $ct = ecc_encrypt($pub_key_filename, $message, $hash_name);
759
760 #NOTE: $hash_name can be 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
761
762 ECCDH Encryption is performed by producing a random key, hashing it, and XOR'ing the digest against the plaintext.
763
764 =head2 ecc_decrypt
765
766 Elliptic Curve Diffie-Hellman (ECDH) decryption as implemented by libtomcrypt. See method L</decrypt> below.
767
768 my $pt = ecc_decrypt($priv_key_filename, $ciphertext);
769 #or
770 my $pt = ecc_decrypt(\$buffer_containing_priv_key, $ciphertext);
771
772 =head2 ecc_sign_message
773
774 Elliptic Curve Digital Signature Algorithm (ECDSA) - signature generation. See method L</sign_message> below.
775
776 my $sig = ecc_sign_message($priv_key_filename, $message);
777 #or
778 my $sig = ecc_sign_message(\$buffer_containing_priv_key, $message);
779 #or
780 my $sig = ecc_sign_message($priv_key, $message, $hash_name);
781
782 =head2 ecc_verify_message
783
784 Elliptic Curve Digital Signature Algorithm (ECDSA) - signature verification. See method L</verify_message> below.
785
786 ecc_verify_message($pub_key_filename, $signature, $message) or die "ERROR";
787 #or
788 ecc_verify_message(\$buffer_containing_pub_key, $signature, $message) or die "ERROR";
789 #or
790 ecc_verify_message($pub_key, $signature, $message, $hash_name) or die "ERROR";
791
792 =head2 ecc_sign_hash
793
794 Elliptic Curve Digital Signature Algorithm (ECDSA) - signature generation. See method L</sign_hash> below.
795
796 my $sig = ecc_sign_hash($priv_key_filename, $message_hash);
797 #or
798 my $sig = ecc_sign_hash(\$buffer_containing_priv_key, $message_hash);
799
800 =head2 ecc_verify_hash
801
802 Elliptic Curve Digital Signature Algorithm (ECDSA) - signature verification. See method L</verify_hash> below.
803
804 ecc_verify_hash($pub_key_filename, $signature, $message_hash) or die "ERROR";
805 #or
806 ecc_verify_hash(\$buffer_containing_pub_key, $signature, $message_hash) or die "ERROR";
807
808 =head2 ecc_shared_secret
809
810 Elliptic curve Diffie-Hellman (ECDH) - construct a Diffie-Hellman shared secret with a private and public ECC key. See method L</shared_secret> below.
811
812 #on Alice side
813 my $shared_secret = ecc_shared_secret('Alice_priv_ecc1.der', 'Bob_pub_ecc1.der');
814
815 #on Bob side
816 my $shared_secret = ecc_shared_secret('Bob_priv_ecc1.der', 'Alice_pub_ecc1.der');
817
818 =head1 OpenSSL interoperability
819
820 ### let's have:
821 # ECC private key in PEM format - eckey.priv.pem
822 # ECC public key in PEM format - eckey.pub.pem
823 # data file to be signed - input.data
824
825 =head2 Sign by OpenSSL, verify by Crypt::PK::ECC
826
827 Create signature (from commandline):
828
829 openssl dgst -sha1 -sign eckey.priv.pem -out input.sha1-ec.sig input.data
830
831 Verify signature (Perl code):
832
833 use Crypt::PK::ECC;
834 use Crypt::Digest 'digest_file';
835 use File::Slurp 'read_file';
836
837 my $pkec = Crypt::PK::ECC->new("eckey.pub.pem");
838 my $signature = read_file("input.sha1-ec.sig", binmode=>':raw');
839 my $valid = $pkec->verify_hash($signature, digest_file("SHA1", "input.data"), "SHA1", "v1.5");
840 print $valid ? "SUCCESS" : "FAILURE";
841
842 =head2 Sign by Crypt::PK::ECC, verify by OpenSSL
843
844 Create signature (Perl code):
845
846 use Crypt::PK::ECC;
847 use Crypt::Digest 'digest_file';
848 use File::Slurp 'write_file';
849
850 my $pkec = Crypt::PK::ECC->new("eckey.priv.pem");
851 my $signature = $pkec->sign_hash(digest_file("SHA1", "input.data"), "SHA1", "v1.5");
852 write_file("input.sha1-ec.sig", {binmode=>':raw'}, $signature);
853
854 Verify signature (from commandline):
855
856 openssl dgst -sha1 -verify eckey.pub.pem -signature input.sha1-ec.sig input.data
857
858 =head2 Keys generated by Crypt::PK::ECC
859
860 Generate keys (Perl code):
861
862 use Crypt::PK::ECC;
863 use File::Slurp 'write_file';
864
865 my $pkec = Crypt::PK::ECC->new;
866 $pkec->generate_key('secp160k1');
867 write_file("eckey.pub.der", {binmode=>':raw'}, $pkec->export_key_der('public'));
868 write_file("eckey.priv.der", {binmode=>':raw'}, $pkec->export_key_der('private'));
869 write_file("eckey.pub.pem", $pkec->export_key_pem('public'));
870 write_file("eckey.priv.pem", $pkec->export_key_pem('private'));
871 write_file("eckey-passwd.priv.pem", $pkec->export_key_pem('private', 'secret'));
872
873 Use keys by OpenSSL:
874
875 openssl ec -in eckey.priv.der -text -inform der
876 openssl ec -in eckey.priv.pem -text
877 openssl ec -in eckey-passwd.priv.pem -text -inform pem -passin pass:secret
878 openssl ec -in eckey.pub.der -pubin -text -inform der
879 openssl ec -in eckey.pub.pem -pubin -text
880
881 =head2 Keys generated by OpenSSL
882
883 Generate keys:
884
885 openssl ecparam -param_enc explicit -name prime192v3 -genkey -out eckey.priv.pem
886 openssl ec -param_enc explicit -in eckey.priv.pem -out eckey.pub.pem -pubout
887 openssl ec -param_enc explicit -in eckey.priv.pem -out eckey.priv.der -outform der
888 openssl ec -param_enc explicit -in eckey.priv.pem -out eckey.pub.der -outform der -pubout
889 openssl ec -param_enc explicit -in eckey.priv.pem -out eckey.privc.der -outform der -conv_form compressed
890 openssl ec -param_enc explicit -in eckey.priv.pem -out eckey.pubc.der -outform der -pubout -conv_form compressed
891 openssl ec -param_enc explicit -in eckey.priv.pem -passout pass:secret -des3 -out eckey-passwd.priv.pem
892
893 B<IMPORTANT:> it is necessary to use C<-param_enc explicit> option
894
895 Load keys (Perl code):
896
897 use Crypt::PK::ECC;
898 use File::Slurp 'write_file';
899
900 my $pkec = Crypt::PK::ECC->new;
901 $pkec->import_key("eckey.pub.der");
902 $pkec->import_key("eckey.pubc.der");
903 $pkec->import_key("eckey.priv.der");
904 $pkec->import_key("eckey.privc.der");
905 $pkec->import_key("eckey.pub.pem");
906 $pkec->import_key("eckey.priv.pem");
907 $pkec->import_key("eckey-passwd.priv.pem", "secret");
908
415909 =head1 SEE ALSO
416910
417911 =over
2323 sub export_key_pem {
2424 my ($self, $type, $password, $cipher) = @_;
2525 my $key = $self->export_key_der($type||'');
26 return undef unless $key;
27
26 return unless $key;
27
2828 # PKCS#1 RSAPrivateKey** (PEM header: BEGIN RSA PRIVATE KEY)
2929 # PKCS#8 PrivateKeyInfo* (PEM header: BEGIN PRIVATE KEY)
3030 # PKCS#8 EncryptedPrivateKeyInfo** (PEM header: BEGIN ENCRYPTED PRIVATE KEY)
3333 # PKCS#1 RSAPublicKey* (PEM header: BEGIN RSA PUBLIC KEY)
3434 return Crypt::PK::_asn1_to_pem($key, "RSA PUBLIC KEY") if $type eq 'public';
3535 # X.509 SubjectPublicKeyInfo** (PEM header: BEGIN PUBLIC KEY)
36 return Crypt::PK::_asn1_to_pem($key, "PUBLIC KEY") if $type eq 'public_x509';
37
38 }
39
40 sub generate_key {
41 my $self = shift;
42 $self->_generate_key(@_);
43 return $self;
36 return Crypt::PK::_asn1_to_pem($key, "PUBLIC KEY") if $type eq 'public_x509';
4437 }
4538
4639 sub import_key {
6053 $data = Crypt::PK::_pem_to_asn1($data, $password);
6154 }
6255 croak "FATAL: invalid key format" unless $data;
63 $self->_import($data);
64 return $self;
56 return $self->_import($data);
6557 }
6658
6759 sub encrypt {
212204 #Signature: Bob (received $message + $sig)
213205 rsa_verify_message('Alice_pub_rsa1.der', $sig, $message) or die "ERROR";
214206
215 =head1 FUNCTIONS
216
217 =head2 rsa_encrypt
218
219 RSA based encryption. See method L</encrypt> below.
220
221 my $ct = rsa_encrypt($pub_key_filename, $message);
222 #or
223 my $ct = rsa_encrypt(\$buffer_containing_pub_key, $message);
224 #or
225 my $ct = rsa_encrypt($pub_key, $message, $padding);
226 #or
227 my $ct = rsa_encrypt($pub_key, $message, 'oaep', $hash_name, $lparam);
228
229 =head2 rsa_decrypt
230
231 RSA based decryption. See method L</decrypt> below.
232
233 my $pt = rsa_decrypt($priv_key_filename, $ciphertext);
234 #or
235 my $pt = rsa_decrypt(\$buffer_containing_priv_key, $ciphertext);
236 #or
237 my $pt = rsa_decrypt($priv_key, $ciphertext, $padding);
238 #or
239 my $pt = rsa_decrypt($priv_key, $ciphertext, 'oaep', $hash_name, $lparam);
240
241 =head2 rsa_sign_message
242
243 Generate RSA signature. See method L</sign_message> below.
244
245 my $sig = rsa_sign_message($priv_key_filename, $message);
246 #or
247 my $sig = rsa_sign_message(\$buffer_containing_priv_key, $message);
248 #or
249 my $sig = rsa_sign_message($priv_key, $message, $hash_name);
250 #or
251 my $sig = rsa_sign_message($priv_key, $message, $hash_name, $padding);
252 #or
253 my $sig = rsa_sign_message($priv_key, $message, $hash_name, 'pss', $saltlen);
254
255 =head2 rsa_verify_message
256
257 Verify RSA signature. See method L</verify_message> below.
258
259 rsa_verify_message($pub_key_filename, $signature, $message) or die "ERROR";
260 #or
261 rsa_verify_message(\$buffer_containing_pub_key, $signature, $message) or die "ERROR";
262 #or
263 rsa_verify_message($pub_key, $signature, $message, $hash_name) or die "ERROR";
264 #or
265 rsa_verify_message($pub_key, $signature, $message, $hash_name, $padding) or die "ERROR";
266 #or
267 rsa_verify_message($pub_key, $signature, $message, $hash_name, 'pss', $saltlen) or die "ERROR";
268
269 =head2 rsa_sign_hash
270
271 Generate RSA signature. See method L</sign_hash> below.
272
273 my $sig = rsa_sign_hash($priv_key_filename, $message_hash);
274 #or
275 my $sig = rsa_sign_hash(\$buffer_containing_priv_key, $message_hash);
276 #or
277 my $sig = rsa_sign_hash($priv_key, $message_hash, $hash_name);
278 #or
279 my $sig = rsa_sign_hash($priv_key, $message_hash, $hash_name, $padding);
280 #or
281 my $sig = rsa_sign_hash($priv_key, $message_hash, $hash_name, 'pss', $saltlen);
282
283 =head2 rsa_verify_hash
284
285 Verify RSA signature. See method L</verify_hash> below.
286
287 rsa_verify_hash($pub_key_filename, $signature, $message_hash) or die "ERROR";
288 #or
289 rsa_verify_hash(\$buffer_containing_pub_key, $signature, $message_hash) or die "ERROR";
290 #or
291 rsa_verify_hash($pub_key, $signature, $message_hash, $hash_name) or die "ERROR";
292 #or
293 rsa_verify_hash($pub_key, $signature, $message_hash, $hash_name, $padding) or die "ERROR";
294 #or
295 rsa_verify_hash($pub_key, $signature, $message_hash, $hash_name, 'pss', $saltlen) or die "ERROR";
207 =head1 DESCRIPTION
208
209 The module provides a full featured RSA implementation.
296210
297211 =head1 METHODS
298212
362276 my $private_pem = $pk->export_key_pem('private', $password);
363277 #or
364278 my $private_pem = $pk->export_key_pem('private', $password, $cipher);
365
279
366280 # supported ciphers: 'DES-CBC'
367281 # 'DES-EDE3-CBC'
368282 # 'SEED-CBC'
283 # 'CAMELLIA-128-CBC'
284 # 'CAMELLIA-192-CBC'
285 # 'CAMELLIA-256-CBC'
369286 # 'AES-128-CBC'
370287 # 'AES-192-CBC'
371288 # 'AES-256-CBC' (DEFAULT)
392309 #or
393310 my $pt = $pk->decrypt($ciphertext, 'oaep', $hash_name, $lparam);
394311
395 #NOTE: $padding, $hash_name, $lparam - see encrypt method
312 # $padding .................... 'oaep' (DEFAULT), 'v1.5' or 'none'
313 # $hash_name (only for oaep) .. 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
314 # $lparam (only for oaep) ..... DEFAULT is empty string
396315
397316 =head2 sign_message
398317
414333 my $pk = Crypt::PK::RSA->new($pub_key_filename);
415334 my $valid = $pub->verify_message($signature, $message);
416335 #or
417 my $valid = $pub->verify_message($signature, $message, $padding);
418 #or
419 my $valid = $pub->verify_message($signature, $message, $padding, $hash_name);
420 #or
421 my $valid = $pub->verify_message($signature, $message, 'pss', $hash_name, $saltlen);
422
423 #NOTE: $hash_name, $padding, $saltlen - see sign_message method
336 my $valid = $pub->verify_message($signature, $message, $hash_name);
337 #or
338 my $valid = $pub->verify_message($signature, $message, $hash_name, $padding);
339 #or
340 my $valid = $pub->verify_message($signature, $message, $hash_name, 'pss', $saltlen);
341
342 # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
343 # $padding ................. 'pss' (DEFAULT) or 'v1.5'
344 # $saltlen (only for pss) .. DEFAULT is 12
424345
425346 =head2 sign_hash
426347
433354 #or
434355 my $signature = $priv->sign_hash($message_hash, $hash_name, 'pss', $saltlen);
435356
436 #NOTE: $hash_name, $padding, $saltlen - see sign_message method
357 # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
358 # $padding ................. 'pss' (DEFAULT) or 'v1.5'
359 # $saltlen (only for pss) .. DEFAULT is 12
437360
438361 =head2 verify_hash
439362
440363 my $pk = Crypt::PK::RSA->new($pub_key_filename);
441364 my $valid = $pub->verify_hash($signature, $message_hash);
442365 #or
443 my $valid = $pub->verify_hash($signature, $message_hash, $padding);
444 #or
445 my $valid = $pub->verify_hash($signature, $message_hash, $padding, $hash_name);
446 #or
447 my $valid = $pub->verify_hash($signature, $message_hash, 'pss', $hash_name, $saltlen);
448
449 #NOTE: $hash_name, $padding, $saltlen - see sign_message method
366 my $valid = $pub->verify_hash($signature, $message_hash, $hash_name);
367 #or
368 my $valid = $pub->verify_hash($signature, $message_hash, $hash_name, $padding);
369 #or
370 my $valid = $pub->verify_hash($signature, $message_hash, $hash_name, 'pss', $saltlen);
371
372 # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
373 # $padding ................. 'pss' (DEFAULT) or 'v1.5'
374 # $saltlen (only for pss) .. DEFAULT is 12
450375
451376 =head2 is_private
452377
479404 dQ => "4597284B2968B72C4212DB7E8F24360B987B80514DA9...", #d mod (q - 1) CRT param
480405 }
481406
407 =head1 FUNCTIONS
408
409 =head2 rsa_encrypt
410
411 RSA based encryption. See method L</encrypt> below.
412
413 my $ct = rsa_encrypt($pub_key_filename, $message);
414 #or
415 my $ct = rsa_encrypt(\$buffer_containing_pub_key, $message);
416 #or
417 my $ct = rsa_encrypt($pub_key, $message, $padding);
418 #or
419 my $ct = rsa_encrypt($pub_key, $message, 'oaep', $hash_name, $lparam);
420
421 # $padding .................... 'oaep' (DEFAULT), 'v1.5' or 'none'
422 # $hash_name (only for oaep) .. 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
423 # $lparam (only for oaep) ..... DEFAULT is empty string
424
425 =head2 rsa_decrypt
426
427 RSA based decryption. See method L</decrypt> below.
428
429 my $pt = rsa_decrypt($priv_key_filename, $ciphertext);
430 #or
431 my $pt = rsa_decrypt(\$buffer_containing_priv_key, $ciphertext);
432 #or
433 my $pt = rsa_decrypt($priv_key, $ciphertext, $padding);
434 #or
435 my $pt = rsa_decrypt($priv_key, $ciphertext, 'oaep', $hash_name, $lparam);
436
437 # $padding .................... 'oaep' (DEFAULT), 'v1.5' or 'none'
438 # $hash_name (only for oaep) .. 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
439 # $lparam (only for oaep) ..... DEFAULT is empty string
440
441 =head2 rsa_sign_message
442
443 Generate RSA signature. See method L</sign_message> below.
444
445 my $sig = rsa_sign_message($priv_key_filename, $message);
446 #or
447 my $sig = rsa_sign_message(\$buffer_containing_priv_key, $message);
448 #or
449 my $sig = rsa_sign_message($priv_key, $message, $hash_name);
450 #or
451 my $sig = rsa_sign_message($priv_key, $message, $hash_name, $padding);
452 #or
453 my $sig = rsa_sign_message($priv_key, $message, $hash_name, 'pss', $saltlen);
454
455 # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
456 # $padding ................. 'pss' (DEFAULT) or 'v1.5'
457 # $saltlen (only for pss) .. DEFAULT is 12
458
459 =head2 rsa_verify_message
460
461 Verify RSA signature. See method L</verify_message> below.
462
463 rsa_verify_message($pub_key_filename, $signature, $message) or die "ERROR";
464 #or
465 rsa_verify_message(\$buffer_containing_pub_key, $signature, $message) or die "ERROR";
466 #or
467 rsa_verify_message($pub_key, $signature, $message, $hash_name) or die "ERROR";
468 #or
469 rsa_verify_message($pub_key, $signature, $message, $hash_name, $padding) or die "ERROR";
470 #or
471 rsa_verify_message($pub_key, $signature, $message, $hash_name, 'pss', $saltlen) or die "ERROR";
472
473 # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
474 # $padding ................. 'pss' (DEFAULT) or 'v1.5'
475 # $saltlen (only for pss) .. DEFAULT is 12
476
477 =head2 rsa_sign_hash
478
479 Generate RSA signature. See method L</sign_hash> below.
480
481 my $sig = rsa_sign_hash($priv_key_filename, $message_hash);
482 #or
483 my $sig = rsa_sign_hash(\$buffer_containing_priv_key, $message_hash);
484 #or
485 my $sig = rsa_sign_hash($priv_key, $message_hash, $hash_name);
486 #or
487 my $sig = rsa_sign_hash($priv_key, $message_hash, $hash_name, $padding);
488 #or
489 my $sig = rsa_sign_hash($priv_key, $message_hash, $hash_name, 'pss', $saltlen);
490
491 # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
492 # $padding ................. 'pss' (DEFAULT) or 'v1.5'
493 # $saltlen (only for pss) .. DEFAULT is 12
494
495 =head2 rsa_verify_hash
496
497 Verify RSA signature. See method L</verify_hash> below.
498
499 rsa_verify_hash($pub_key_filename, $signature, $message_hash) or die "ERROR";
500 #or
501 rsa_verify_hash(\$buffer_containing_pub_key, $signature, $message_hash) or die "ERROR";
502 #or
503 rsa_verify_hash($pub_key, $signature, $message_hash, $hash_name) or die "ERROR";
504 #or
505 rsa_verify_hash($pub_key, $signature, $message_hash, $hash_name, $padding) or die "ERROR";
506 #or
507 rsa_verify_hash($pub_key, $signature, $message_hash, $hash_name, 'pss', $saltlen) or die "ERROR";
508
509 # $hash_name ............... 'SHA1' (DEFAULT), 'SHA256' or any other hash supported by Crypt::Digest
510 # $padding ................. 'pss' (DEFAULT) or 'v1.5'
511 # $saltlen (only for pss) .. DEFAULT is 12
512
513 =head1 OpenSSL interoperability
514
515 ### let's have:
516 # RSA private key in PEM format - rsakey.priv.pem
517 # RSA public key in PEM format - rsakey.pub.pem
518 # data file to be signed or encrypted - input.data
519
520 =head2 Encrypt by OpenSSL, decrypt by Crypt::PK::RSA
521
522 Create encrypted file (from commandline):
523
524 openssl rsautl -encrypt -inkey rsakey.pub.pem -pubin -out input.encrypted.rsa -in input.data
525
526 Decrypt file (Perl code):
527
528 use Crypt::PK::RSA;
529 use File::Slurp 'read_file';
530
531 my $pkrsa = Crypt::PK::RSA->new("rsakey.priv.pem");
532 my $encfile = read_file("input.encrypted.rsa", binmode=>':raw');
533 my $plaintext = $pkrsa->decrypt($encfile, 'v1.5');
534 print $plaintext;
535
536 =head2 Encrypt by Crypt::PK::RSA, decrypt by OpenSSL
537
538 Create encrypted file (Perl code):
539
540 use Crypt::PK::RSA;
541 use File::Slurp 'write_file';
542
543 my $plaintext = 'secret message';
544 my $pkrsa = Crypt::PK::RSA->new("rsakey.pub.pem");
545 my $encrypted = $pkrsa->encrypt($plaintext, 'v1.5');
546 write_file("input.encrypted.rsa", {binmode=>':raw'}, $encrypted);
547
548 Decrypt file (from commandline):
549
550 openssl rsautl -decrypt -inkey rsakey.priv.pem -in input.encrypted.rsa
551
552 =head2 Sign by OpenSSL, verify by Crypt::PK::RSA
553
554 Create signature (from commandline):
555
556 openssl dgst -sha1 -sign rsakey.priv.pem -out input.sha1-rsa.sig input.data
557
558 Verify signature (Perl code):
559
560 use Crypt::PK::RSA;
561 use Crypt::Digest 'digest_file';
562 use File::Slurp 'read_file';
563
564 my $pkrsa = Crypt::PK::RSA->new("rsakey.pub.pem");
565 my $signature = read_file("input.sha1-rsa.sig", binmode=>':raw');
566 my $valid = $pkrsa->verify_hash($signature, digest_file("SHA1", "input.data"), "SHA1", "v1.5");
567 print $valid ? "SUCCESS" : "FAILURE";
568
569 =head2 Sign by Crypt::PK::RSA, verify by OpenSSL
570
571 Create signature (Perl code):
572
573 use Crypt::PK::RSA;
574 use Crypt::Digest 'digest_file';
575 use File::Slurp 'write_file';
576
577 my $pkrsa = Crypt::PK::RSA->new("rsakey.priv.pem");
578 my $signature = $pkrsa->sign_hash(digest_file("SHA1", "input.data"), "SHA1", "v1.5");
579 write_file("input.sha1-rsa.sig", {binmode=>':raw'}, $signature);
580
581 Verify signature (from commandline):
582
583 openssl dgst -sha1 -verify rsakey.pub.pem -signature input.sha1-rsa.sig input.data
584
585 =head2 Keys generated by Crypt::PK::RSA
586
587 Generate keys (Perl code):
588
589 use Crypt::PK::RSA;
590 use File::Slurp 'write_file';
591
592 my $pkrsa = Crypt::PK::RSA->new;
593 $pkrsa->generate_key(256, 65537);
594 write_file("rsakey.pub.der", {binmode=>':raw'}, $pkrsa->export_key_der('public'));
595 write_file("rsakey.priv.der", {binmode=>':raw'}, $pkrsa->export_key_der('private'));
596 write_file("rsakey.pub.pem", $pkrsa->export_key_pem('public_x509'));
597 write_file("rsakey.priv.pem", $pkrsa->export_key_pem('private'));
598 write_file("rsakey-passwd.priv.pem", $pkrsa->export_key_pem('private', 'secret'));
599
600 Use keys by OpenSSL:
601
602 openssl rsa -in rsakey.priv.der -text -inform der
603 openssl rsa -in rsakey.priv.pem -text
604 openssl rsa -in rsakey-passwd.priv.pem -text -inform pem -passin pass:secret
605 openssl rsa -in rsakey.pub.der -pubin -text -inform der
606 openssl rsa -in rsakey.pub.pem -pubin -text
607
608 =head2 Keys generated by OpenSSL
609
610 Generate keys:
611
612 openssl genrsa -out rsakey.priv.pem 1024
613 openssl rsa -in rsakey.priv.pem -out rsakey.priv.der -outform der
614 openssl rsa -in rsakey.priv.pem -out rsakey.pub.pem -pubout
615 openssl rsa -in rsakey.priv.pem -out rsakey.pub.der -outform der -pubout
616 openssl rsa -in rsakey.priv.pem -passout pass:secret -des3 -out rsakey-passwd.priv.pem
617
618 Load keys (Perl code):
619
620 use Crypt::PK::RSA;
621 use File::Slurp 'write_file';
622
623 my $pkrsa = Crypt::PK::RSA->new;
624 $pkrsa->import_key("rsakey.pub.der");
625 $pkrsa->import_key("rsakey.priv.der");
626 $pkrsa->import_key("rsakey.pub.pem");
627 $pkrsa->import_key("rsakey.priv.pem");
628 $pkrsa->import_key("rsakey-passwd.priv.pem", "secret");
629
482630 =head1 SEE ALSO
483631
484632 =over
1616 my $f = shift;
1717 croak "FATAL: non-existing file '$f'" unless -f $f;
1818 local $/ = undef;
19 open FILE, "<", $f or croak "FATAL: couldn't open file: $!";
20 binmode FILE;
21 my $string = <FILE>;
22 close FILE;
19 open my $fh, "<", $f or croak "FATAL: couldn't open file: $!";
20 binmode $fh;
21 my $string = readline($fh);
22 close $fh;
2323 return $string;
2424 }
2525
2727 my $cipher_name = uc(shift);
2828 my %trans = ( 'DES-EDE3' => 'DES_EDE' );
2929
30 #my ($cipher, undef, $klen, $mode) = $cipher_name =~ /^(AES|CAMELLIA|DES|DES-EDE3|SEED)(-(\d+))?-(CBC|CFB|ECB|OFB)$/i;
31 my ($cipher, undef, $klen, $mode) = $cipher_name =~ /^(AES|DES|DES-EDE3|SEED)(-(\d+))?-(CBC|CFB|ECB|OFB)$/i;
30 my ($cipher, undef, $klen, $mode) = $cipher_name =~ /^(AES|CAMELLIA|DES|DES-EDE3|SEED)(-(\d+))?-(CBC|CFB|ECB|OFB)$/i;
3231 croak "FATAL: unsupported cipher '$cipher_name'" unless $cipher && $mode;
3332 $cipher = $trans{$cipher} || $cipher;
3433 $klen = $klen ? int($klen/8) : Crypt::Cipher::min_keysize($cipher);
5453 sub _pem_to_asn1 {
5554 my ($data, $password) = @_;
5655
57 my ($begin, $object, $headers, $content, $end) = $data =~ m/(-----BEGIN ([^\n\-]+)-----)\n(.*?\n\n)?(.+)(-----END .*?-----)/s;
56 my ($begin, $object, $headers, $content, $end) = $data =~ m/(-----BEGIN ([^\r\n\-]+KEY)-----)\r?\n(.*?\r?\n\r?\n)?(.+)(-----END [^\r\n\-]*-----)/s;
57
5858 return $content unless $content;
5959 $content = decode_base64($content);
6060
103103 1;
104104
105105 __END__
106
106
107107 =head1 NAME
108
108
109109 Crypt::PK - [internal only]
110
110
111111 =cut
111111
112112 =head1 METHODS
113113
114 =head1 new
114 =head2 new
115115
116116 See L<Crypt::PRNG/new>.
117117
110110
111111 =head1 METHODS
112112
113 =head1 new
113 =head2 new
114114
115115 See L<Crypt::PRNG/new>.
116116
110110
111111 =head1 METHODS
112112
113 =head1 new
113 =head2 new
114114
115115 See L<Crypt::PRNG/new>.
116116
110110
111111 =head1 METHODS
112112
113 =head1 new
113 =head2 new
114114
115115 See L<Crypt::PRNG/new>.
116116
4545 my ($self, $chars, $len) = @_;
4646
4747 $len = 20 unless defined $len;
48 return unless $len>0;
48 return unless $len > 0;
49 return unless length($chars) > 0;
4950
5051 my @ch = split(//, $chars);
51 my $max_index = scalar(@ch)-1;
52
52 my $max_index = $#ch;
53 return if $max_index > 65535;
54
5355 my $mask;
5456 for my $n (1..31) {
5557 $mask = (1<<$n) - 1;
5658 last if $mask >= $max_index;
5759 }
5860
61 my $upck = ($max_index > 255) ? "n*" : "C*";
62 my $l = $len * 2;
63
5964 my $rv = '';
65 my @r;
6066 while (length $rv < $len) {
61 my $i = $self->int32 & $mask;
67 @r = unpack($upck, $self->bytes($l)) if scalar @r == 0;
68 my $i = (shift @r) & $mask;
6269 next if $i > $max_index;
6370 $rv .= $ch[$i];
6471 }
204211
205212 =head1 METHODS
206213
207 =head1 new
214 =head2 new
208215
209216 $prng = Crypt::PRNG->new;
210217 #or
22 use strict;
33 use warnings ;
44
5 our $VERSION = '0.017';
5 our $VERSION = '0.021';
66
77 require XSLoader;
88 XSLoader::load('CryptX', $VERSION);
00 #include "EXTERN.h"
11 #include "perl.h"
22 #include "XSUB.h"
3
4 #define NEED_sv_2pvbyte_GLOBAL
5 #define NEED_sv_2pv_flags_GLOBAL
6 #define NEED_newRV_noinc_GLOBAL
7 #include "ppport.h"
38
49 #undef LTC_SOURCE
510 #include "tomcrypt.h"
161166 prng_state yarrow_prng_state;
162167 int yarrow_prng_index;
163168 ecc_key key;
169 ltc_ecc_set_type dp;
164170 int id;
165171 } *Crypt__PK__ECC;
172
173 ltc_ecc_set_type* _ecc_set_dp_from_SV(ltc_ecc_set_type *dp, SV *curve)
174 {
175 HV *h;
176 SV *param, **pref;
177 SV **sv_cofactor, **sv_prime, **sv_A, **sv_B, **sv_order, **sv_Gx, **sv_Gy;
178 int err;
179 char *ch_name;
180 STRLEN l_name;
181
182 if (SvPOK(curve)) {
183 ch_name = SvPV(curve, l_name);
184 if ((h = get_hv("Crypt::PK::ECC::curve", 0)) == NULL) croak("FATAL: generate_key_ex: no curve register");
185 if ((pref = hv_fetch(h, ch_name, l_name, 0)) == NULL) croak("FATAL: generate_key_ex: unknown curve/1 '%s'", ch_name);
186 if (!SvOK(*pref)) croak("FATAL: generate_key_ex: unknown curve/2 '%s'", ch_name);
187 param = *pref;
188 }
189 else if (SvROK(curve)) {
190 param = curve;
191 ch_name = "custom";
192 }
193 else {
194 croak("FATAL: curve has to be a string or a hashref");
195 }
196
197 if ((h = (HV*)(SvRV(param))) == NULL) croak("FATAL: ecparams: param is not valid hashref");
198
199 if ((sv_prime = hv_fetchs(h, "prime", 0)) == NULL) croak("FATAL: ecparams: missing param prime");
200 if ((sv_A = hv_fetchs(h, "A", 0)) == NULL) croak("FATAL: ecparams: missing param A");
201 if ((sv_B = hv_fetchs(h, "B", 0)) == NULL) croak("FATAL: ecparams: missing param B");
202 if ((sv_order = hv_fetchs(h, "order", 0)) == NULL) croak("FATAL: ecparams: missing param order");
203 if ((sv_Gx = hv_fetchs(h, "Gx", 0)) == NULL) croak("FATAL: ecparams: missing param Gx");
204 if ((sv_Gy = hv_fetchs(h, "Gy", 0)) == NULL) croak("FATAL: ecparams: missing param Gy");
205 if ((sv_cofactor = hv_fetchs(h, "cofactor", 0)) == NULL) croak("FATAL: ecparams: missing param cofactor");
206
207 if (!SvOK(*sv_prime )) croak("FATAL: ecparams: undefined param prime");
208 if (!SvOK(*sv_A )) croak("FATAL: ecparams: undefined param A");
209 if (!SvOK(*sv_B )) croak("FATAL: ecparams: undefined param B");
210 if (!SvOK(*sv_order )) croak("FATAL: ecparams: undefined param order");
211 if (!SvOK(*sv_Gx )) croak("FATAL: ecparams: undefined param Gx");
212 if (!SvOK(*sv_Gy )) croak("FATAL: ecparams: undefined param Gy");
213 if (!SvOK(*sv_cofactor)) croak("FATAL: ecparams: undefined param cofactor");
214
215 err = ecc_dp_set( dp,
216 SvPV_nolen(*sv_prime),
217 SvPV_nolen(*sv_A),
218 SvPV_nolen(*sv_B),
219 SvPV_nolen(*sv_order),
220 SvPV_nolen(*sv_Gx),
221 SvPV_nolen(*sv_Gy),
222 (unsigned long)SvUV(*sv_cofactor),
223 ch_name );
224 return err == CRYPT_OK ? dp : NULL;
225 }
226
227 void _ecc_free_key(ecc_key *key, ltc_ecc_set_type *dp)
228 {
229 if(dp) {
230 ecc_dp_clear(dp);
231 }
232 if (key->type != -1) {
233 ecc_free(key);
234 key->type = -1;
235 key->dp = NULL;
236 }
237 }
166238
167239 MODULE = CryptX PACKAGE = CryptX PREFIX = CryptX_
168240
221293 #endif
222294
223295 int
224 CryptX_test(s)
225 int s
296 CryptX_test(int s)
226297 CODE:
227298 RETVAL = s+1; /*xxx*/
228299 OUTPUT:
6666 STRLEN in_data_len, in_data_start;
6767 unsigned char *in_data, *out_data, tmp_block[MAXBLOCKSIZE];
6868
69 if (self->direction != 1) croak("FATAL: encrypt error, call start('enc') first (%d)", self->direction);
69 if (self->direction != 1) croak("FATAL: encrypt error, call start_encrypt first (%d)", self->direction);
7070
7171 blen = (&self->state)->blocklen;
7272 in_data_start = 0;
154154 blen = 0;
155155 }
156156
157 self->direction = 0;
157158 RETVAL = newSVpvn((char*)tmp_block, blen);
158159 }
159160 OUTPUT:
168169 STRLEN in_data_len, in_data_start;
169170 unsigned char *in_data, *out_data, tmp_block[MAXBLOCKSIZE];
170171
171 if (self->direction != -1) croak("FATAL: decrypt error, call start('dec') first (%d)", self->direction);
172 if (self->direction != -1) croak("FATAL: decrypt error, call start_decryt first (%d)", self->direction);
172173
173174 blen = (&self->state)->blocklen;
174175 in_data_start = 0;
280281 if (rv_len<0) rv_len = 0;
281282 }
282283 }
284
285 self->direction = 0;
283286 RETVAL = newSVpvn((char*)tmp_block, rv_len);
284287 }
285288 OUTPUT:
8181 if (rv != CRYPT_OK) croak("FATAL: cfb_decrypt failed: %s", error_to_string(rv));
8282 }
8383 else {
84 croak("FATAL: cfb_crypt failed: call start() first");
84 croak("FATAL: cfb_crypt failed: call start_encrypt or start_decrypt first");
8585 }
8686 }
8787 }
8686 if (rv != CRYPT_OK) croak("FATAL: ctr_decrypt failed: %s", error_to_string(rv));
8787 }
8888 else {
89 croak("FATAL: ctr_crypt failed: call start() first");
89 croak("FATAL: ctr_crypt failed: call start_encrypt or start_decrypt first");
9090 }
9191 }
9292 }
5959 STRLEN in_data_len, in_data_start;
6060 unsigned char *in_data, *out_data, tmp_block[MAXBLOCKSIZE];
6161
62 if (self->direction != 1) croak("FATAL: encrypt error, call start('enc') first (%d)", self->direction);
62 if (self->direction != 1) croak("FATAL: encrypt error, call start_encrypt first (%d)", self->direction);
6363
6464 blen = (&self->state)->blocklen;
6565 in_data_start = 0;
147147 blen = 0;
148148 }
149149
150 self->direction = 0;
150151 RETVAL = newSVpvn((char*)tmp_block, blen);
151152 }
152153 OUTPUT:
161162 STRLEN in_data_len, in_data_start;
162163 unsigned char *in_data, *out_data, tmp_block[MAXBLOCKSIZE];
163164
164 if (self->direction != -1) croak("FATAL: decrypt error, call start('dec') first (%d)", self->direction);
165 if (self->direction != -1) croak("FATAL: decrypt error, call start_decryt first (%d)", self->direction);
165166
166167 blen = (&self->state)->blocklen;
167168 in_data_start = 0;
273274 if (rv_len<0) rv_len = 0;
274275 }
275276 }
277
278 self->direction = 0;
276279 RETVAL = newSVpvn((char*)tmp_block, rv_len);
277280 }
278281 OUTPUT:
8181 if (rv != CRYPT_OK) croak("FATAL: ofb_decrypt failed: %s", error_to_string(rv));
8282 }
8383 else {
84 croak("FATAL: ofb_crypt failed: call start() first");
84 croak("FATAL: ofb_crypt failed: call start_encrypt or start_decrypt first");
8585 }
8686 }
8787 }
99 RETVAL->key.type = -1;
1010 RETVAL->yarrow_prng_index = find_prng("yarrow");
1111 if(RETVAL->yarrow_prng_index==-1) croak("FATAL: find_prng('yarrow') failed");
12 rv = rng_make_prng(128, RETVAL->yarrow_prng_index, &RETVAL->yarrow_prng_state, NULL);
12 rv = rng_make_prng(256, RETVAL->yarrow_prng_index, &RETVAL->yarrow_prng_state, NULL);
1313 if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
1414 }
1515 OUTPUT:
1616 RETVAL
1717
18 int
19 _generate_key(Crypt::PK::DH self, int key_size=256)
20 CODE:
21 {
22 int rv;
18 void
19 generate_key(Crypt::PK::DH self, int key_size=256)
20 PPCODE:
21 {
22 int rv;
23 /* add a small random entropy before generating key - not necessary as we have initialized prng with 256bit entropy in _new() */
24 rv = rng_make_prng(64, self->yarrow_prng_index, &self->yarrow_prng_state, NULL);
25 if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
26 /* gen the key */
2327 rv = dh_make_key(&self->yarrow_prng_state, self->yarrow_prng_index, key_size, &self->key);
2428 if (rv != CRYPT_OK) croak("FATAL: dh_make_key failed: %s", error_to_string(rv));
25 RETVAL = 1; /* xxx */
26 }
27 OUTPUT:
28 RETVAL
29
30 int
29 XPUSHs(ST(0)); /* return self */
30 }
31
32 void
3133 _import(Crypt::PK::DH self, SV * key_data)
32 CODE:
34 PPCODE:
3335 {
3436 int rv;
3537 unsigned char *data=NULL;
3941 if (self->key.type != -1) { dh_free(&self->key); self->key.type = -1; }
4042 rv = dh_import(data, (unsigned long)data_len, &self->key);
4143 if (rv != CRYPT_OK) croak("FATAL: dh_import failed: %s", error_to_string(rv));
42 RETVAL = 1; /* xxx */
43 }
44 OUTPUT:
45 RETVAL
44 XPUSHs(ST(0)); /* return self */
45 }
4646
4747 int
4848 is_private(Crypt::PK::DH self)
99 RETVAL->key.type = -1;
1010 RETVAL->yarrow_prng_index = find_prng("yarrow");
1111 if(RETVAL->yarrow_prng_index==-1) croak("FATAL: find_prng('yarrow') failed");
12 rv = rng_make_prng(128, RETVAL->yarrow_prng_index, &RETVAL->yarrow_prng_state, NULL);
12 rv = rng_make_prng(256, RETVAL->yarrow_prng_index, &RETVAL->yarrow_prng_state, NULL);
1313 if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
1414 }
1515 OUTPUT:
1616 RETVAL
1717
18 int
19 _generate_key(Crypt::PK::DSA self, int group_size=30, int modulus_size=256)
20 CODE:
21 {
22 int rv;
18 void
19 generate_key(Crypt::PK::DSA self, int group_size=30, int modulus_size=256)
20 PPCODE:
21 {
22 int rv;
23 /* add a small random entropy before generating key - not necessary as we have initialized prng with 256bit entropy in _new() */
24 rv = rng_make_prng(64, self->yarrow_prng_index, &self->yarrow_prng_state, NULL);
25 if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
26 /* gen the key */
2327 rv = dsa_make_key(&self->yarrow_prng_state, self->yarrow_prng_index, group_size, modulus_size, &self->key);
2428 if (rv != CRYPT_OK) croak("FATAL: dsa_make_key failed: %s", error_to_string(rv));
25 RETVAL = 1; /* xxx */
26 }
27 OUTPUT:
28 RETVAL
29
30 int
29 XPUSHs(ST(0)); /* return self */
30 }
31
32 void
3133 _import(Crypt::PK::DSA self, SV * key_data)
32 CODE:
34 PPCODE:
3335 {
3436 int rv;
3537 unsigned char *data=NULL;
3941 if (self->key.type != -1) { dsa_free(&self->key); self->key.type = -1; }
4042 rv = dsa_import(data, (unsigned long)data_len, &self->key);
4143 if (rv != CRYPT_OK) croak("FATAL: dsa_import failed: %s", error_to_string(rv));
42 RETVAL = 1; /* xxx */
43 }
44 OUTPUT:
45 RETVAL
44 XPUSHs(ST(0)); /* return self */
45 }
4646
4747 int
4848 is_private(Crypt::PK::DSA self)
66 int rv;
77 Newz(0, RETVAL, 1, struct ecc_struct);
88 if (!RETVAL) croak("FATAL: Newz failed");
9 RETVAL->yarrow_prng_index = find_prng("yarrow");
910 RETVAL->key.type = -1;
10 RETVAL->yarrow_prng_index = find_prng("yarrow");
11 ecc_dp_init(&RETVAL->dp);
1112 if(RETVAL->yarrow_prng_index==-1) croak("FATAL: find_prng('yarrow') failed");
12 rv = rng_make_prng(128, RETVAL->yarrow_prng_index, &RETVAL->yarrow_prng_state, NULL);
13 rv = rng_make_prng(256, RETVAL->yarrow_prng_index, &RETVAL->yarrow_prng_state, NULL);
1314 if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
1415 }
1516 OUTPUT:
1617 RETVAL
1718
18 int
19 _generate_key(Crypt::PK::ECC self, int key_size=32)
20 CODE:
21 {
22 int rv;
23 rv = ecc_make_key(&self->yarrow_prng_state, self->yarrow_prng_index, key_size, &self->key);
24 if (rv != CRYPT_OK) croak("FATAL: ecc_make_key failed: %s", error_to_string(rv));
25 RETVAL = 1; /* xxx */
26 }
27 OUTPUT:
28 RETVAL
29
30 int
19 void
20 generate_key(Crypt::PK::ECC self, SV *curve)
21 PPCODE:
22 {
23 int rv;
24 /* add a small random entropy before generating key - not necessary as we have initialized prng with 256bit entropy in _new() */
25 rv = rng_make_prng(64, self->yarrow_prng_index, &self->yarrow_prng_state, NULL);
26 if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
27 /* setup dp structure */
28 _ecc_set_dp_from_SV(&self->dp, curve); /* croaks on error */
29 /* gen the key */
30 rv = ecc_make_key_ex(&self->yarrow_prng_state, self->yarrow_prng_index, &self->key, &self->dp);
31 if (rv != CRYPT_OK) croak("FATAL: ecc_make_key_ex failed: %s", error_to_string(rv));
32 XPUSHs(ST(0)); /* return self */
33 }
34
35 void
3136 _import(Crypt::PK::ECC self, SV * key_data)
32 CODE:
37 PPCODE:
3338 {
3439 int rv;
3540 unsigned char *data=NULL;
3641 STRLEN data_len=0;
3742
3843 data = (unsigned char *)SvPVbyte(key_data, data_len);
39 if (self->key.type != -1) { ecc_free(&self->key); self->key.type = -1; }
40 rv = ecc_import(data, (unsigned long)data_len, &self->key);
41 if (rv != CRYPT_OK) croak("FATAL: ecc_import failed: %s", error_to_string(rv));
42 RETVAL = 1; /* xxx */
43 }
44 OUTPUT:
45 RETVAL
46
47 int
48 import_key_x963(Crypt::PK::ECC self, SV * key_data)
49 CODE:
44 _ecc_free_key(&self->key, &self->dp);
45 rv = ecc_import_full(data, (unsigned long)data_len, &self->key, &self->dp);
46 if (rv != CRYPT_OK) croak("FATAL: ecc_import_full failed: %s", error_to_string(rv));
47 XPUSHs(ST(0)); /* return self */
48 }
49
50 void
51 import_key_raw(Crypt::PK::ECC self, SV * key_data, SV * curve)
52 PPCODE:
5053 {
5154 int rv;
5255 unsigned char *data=NULL;
5356 STRLEN data_len=0;
5457
5558 data = (unsigned char *)SvPVbyte(key_data, data_len);
56 if (self->key.type != -1) { ecc_free(&self->key); self->key.type = -1; }
57 rv = ecc_ansi_x963_import(data, (unsigned long)data_len, &self->key);
58 if (rv != CRYPT_OK) croak("FATAL: ecc_ansi_x963_import failed: %s", error_to_string(rv));
59 RETVAL = 1; /* xxx */
60 }
61 OUTPUT:
62 RETVAL
59 _ecc_free_key(&self->key, &self->dp);
60
61 _ecc_set_dp_from_SV(&self->dp, curve); /* croaks on error */
62
63 rv = ecc_import_raw(data, (unsigned long)data_len, &self->key, &self->dp);
64 if (rv != CRYPT_OK) croak("FATAL: ecc_import_raw failed: %s", error_to_string(rv));
65 XPUSHs(ST(0)); /* return self */
66 }
6367
6468 int
6569 is_private(Crypt::PK::ECC self)
123127 else{
124128 not_used = hv_store(rv_hash, "pub_y", 5, newSVpv("", 0), 0);
125129 }
126 /* =====> pub_z */
127 siz = (self->key.pubkey.z) ? mp_unsigned_bin_size(self->key.pubkey.z) : 0;
128 if (siz>10000) {
129 croak("FATAL: key2hash failed - 'pub_z' too big number");
130 }
131 if (siz>0) {
132 mp_tohex(self->key.pubkey.z, buf);
133 not_used = hv_store(rv_hash, "pub_z", 5, newSVpv(buf, strlen(buf)), 0);
134 }
135 else{
136 not_used = hv_store(rv_hash, "pub_z", 5, newSVpv("", 0), 0);
137 }
138130 /* =====> curve_... */
139 if (self->key.idx>=0) {
131 if (self->key.dp) {
140132 not_used = hv_store(rv_hash, "curve_name", 10, newSVpv(self->key.dp->name, strlen(self->key.dp->name)), 0);
141133 not_used = hv_store(rv_hash, "curve_prime", 11, newSVpv(self->key.dp->prime, strlen(self->key.dp->prime)), 0);
134 not_used = hv_store(rv_hash, "curve_A", 7, newSVpv(self->key.dp->A, strlen(self->key.dp->A)), 0);
142135 not_used = hv_store(rv_hash, "curve_B", 7, newSVpv(self->key.dp->B, strlen(self->key.dp->B)), 0);
143136 not_used = hv_store(rv_hash, "curve_order", 11, newSVpv(self->key.dp->order, strlen(self->key.dp->order)), 0);
144137 not_used = hv_store(rv_hash, "curve_Gx", 8, newSVpv(self->key.dp->Gx, strlen(self->key.dp->Gx)), 0);
145138 not_used = hv_store(rv_hash, "curve_Gy", 8, newSVpv(self->key.dp->Gy, strlen(self->key.dp->Gy)), 0);
146 not_used = hv_store(rv_hash, "curve_size", 10, newSViv(self->key.dp->size), 0);
139 not_used = hv_store(rv_hash, "curve_cofactor", 14, newSViv(self->key.dp->cofactor), 0);
140 {
141 mp_int p_num;
142 mp_init(&p_num);
143 mp_read_radix(&p_num, self->key.dp->prime, 16);
144 not_used = hv_store(rv_hash, "curve_bytes", 11, newSViv(mp_unsigned_bin_size(&p_num)), 0);
145 not_used = hv_store(rv_hash, "curve_bits", 10, newSViv(mp_count_bits(&p_num)), 0);
146 mp_clear(&p_num);
147 }
147148 }
148149 /* =====> size */
149150 not_used = hv_store(rv_hash, "size", 4, newSViv(ecc_get_size(&self->key)), 0);
164165
165166 RETVAL = newSVpvn(NULL, 0); /* undef */
166167 if (strnEQ(type, "private", 7)) {
167 rv = ecc_export(out, &out_len, PK_PRIVATE, &self->key);
168 rv = ecc_export_full(out, &out_len, PK_PRIVATE, &self->key);
168169 if (rv != CRYPT_OK) croak("FATAL: ecc_export(PK_PRIVATE) failed: %s", error_to_string(rv));
169170 RETVAL = newSVpvn((char*)out, out_len);
170171 }
171172 else if (strnEQ(type, "public", 6)) {
172 rv = ecc_export(out, &out_len, PK_PUBLIC, &self->key);
173 rv = ecc_export_full(out, &out_len, PK_PUBLIC, &self->key);
173174 if (rv != CRYPT_OK) croak("FATAL: ecc_export(PK_PUBLIC) failed: %s", error_to_string(rv));
174175 RETVAL = newSVpvn((char*)out, out_len);
175176 }
181182 RETVAL
182183
183184 SV *
184 export_key_x963(Crypt::PK::ECC self)
185 export_key_raw(Crypt::PK::ECC self, char * type)
185186 CODE:
186187 {
187188 int rv;
188189 unsigned char out[4096];
189 unsigned long int out_len = 4096;
190
191 rv = ecc_ansi_x963_export(&self->key, out, &out_len);
192 if (rv != CRYPT_OK) croak("FATAL: ecc_ansi_x963_export failed: %s", error_to_string(rv));
193 RETVAL = newSVpvn((char*)out, out_len);
190 unsigned long int out_len = sizeof(out);
191
192 RETVAL = newSVpvn(NULL, 0); /* undef */
193 if (strnEQ(type, "private", 7)) {
194 rv = ecc_export_raw(out, &out_len, PK_PRIVATE, &self->key);
195 if (rv != CRYPT_OK) croak("FATAL: ecc_export_raw(private) failed: %s", error_to_string(rv));
196 RETVAL = newSVpvn((char*)out, out_len);
197 }
198 else if (strnEQ(type, "public_compressed", 17)) {
199 rv = ecc_export_raw(out, &out_len, PK_PUBLIC_COMPRESSED, &self->key);
200 if (rv != CRYPT_OK) croak("FATAL: ecc_export_raw(public_compressed) failed: %s", error_to_string(rv));
201 RETVAL = newSVpvn((char*)out, out_len);
202 }
203 else if (strnEQ(type, "public", 6)) {
204 rv = ecc_export_raw(out, &out_len, PK_PUBLIC, &self->key);
205 if (rv != CRYPT_OK) croak("FATAL: ecc_export_raw(public) failed: %s", error_to_string(rv));
206 RETVAL = newSVpvn((char*)out, out_len);
207 }
208 else {
209 croak("FATAL: export_key_raw invalid type '%s'", type);
210 }
194211 }
195212 OUTPUT:
196213 RETVAL
296313 void
297314 DESTROY(Crypt::PK::ECC self)
298315 CODE:
299 if (self->key.type != -1) { ecc_free(&self->key); self->key.type = -1; }
316 _ecc_free_key(&self->key, &self->dp);
300317 Safefree(self);
301318
99 RETVAL->key.type = -1;
1010 RETVAL->yarrow_prng_index = find_prng("yarrow");
1111 if(RETVAL->yarrow_prng_index==-1) croak("FATAL: find_prng('yarrow') failed");
12 rv = rng_make_prng(128, RETVAL->yarrow_prng_index, &RETVAL->yarrow_prng_state, NULL);
12 rv = rng_make_prng(256, RETVAL->yarrow_prng_index, &RETVAL->yarrow_prng_state, NULL);
1313 if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
1414 }
1515 OUTPUT:
1616 RETVAL
1717
18 int
19 _generate_key(Crypt::PK::RSA self, int key_size=256, long key_e=65537)
20 CODE:
21 {
18 void
19 generate_key(Crypt::PK::RSA self, int key_size=256, long key_e=65537)
20 PPCODE:
21 {
22 /* key_size is in octets */
2223 int rv;
23 /* key_size is in octets */
24 /* add a small random entropy before generating key - not necessary as we have initialized prng with 256bit entropy in _new() */
25 rv = rng_make_prng(64, self->yarrow_prng_index, &self->yarrow_prng_state, NULL);
26 if (rv != CRYPT_OK) croak("FATAL: rng_make_prng failed: %s", error_to_string(rv));
27 /* gen the key */
2428 rv = rsa_make_key(&self->yarrow_prng_state, self->yarrow_prng_index, key_size, key_e, &self->key);
2529 if (rv != CRYPT_OK) croak("FATAL: rsa_make_key failed: %s", error_to_string(rv));
26 RETVAL = 1; /* xxx */
27 }
28 OUTPUT:
29 RETVAL
30
31 int
30 XPUSHs(ST(0)); /* return self */
31 }
32
33 void
3234 _import(Crypt::PK::RSA self, SV * key_data)
33 CODE:
35 PPCODE:
3436 {
3537 int rv;
3638 unsigned char *data=NULL;
4042 if (self->key.type != -1) { rsa_free(&self->key); self->key.type = -1; }
4143 rv = rsa_import(data, (unsigned long)data_len, &self->key);
4244 if (rv != CRYPT_OK) croak("FATAL: rsa_import failed: %s", error_to_string(rv));
43 RETVAL = 1; /* xxx */
44 }
45 OUTPUT:
46 RETVAL
45 XPUSHs(ST(0)); /* return self */
46 }
4747
4848 int
4949 is_private(Crypt::PK::RSA self)
33 /*
44 ----------------------------------------------------------------------
55
6 ppport.h -- Perl/Pollution/Portability Version 3.20
6 ppport.h -- Perl/Pollution/Portability Version 3.21
77
88 Automatically created by Devel::PPPort running under perl 5.014002.
99
2020
2121 =head1 NAME
2222
23 ppport.h - Perl/Pollution/Portability version 3.20
23 ppport.h - Perl/Pollution/Portability version 3.21
2424
2525 =head1 SYNOPSIS
2626
357357
358358 =head1 COPYRIGHT
359359
360 Version 3.x, Copyright (c) 2004-2010, Marcus Holland-Moritz.
360 Version 3.x, Copyright (c) 2004-2013, Marcus Holland-Moritz.
361361
362362 Version 2.x, Copyright (C) 2001, Paul Marquess.
363363
377377 # Disable broken TRIE-optimization
378378 BEGIN { eval '${^RE_TRIE_MAXBUF} = -1' if $] >= 5.009004 && $] <= 5.009005 }
379379
380 my $VERSION = 3.20;
380 my $VERSION = 3.21;
381381
382382 my %opt = (
383383 quiet => 0,
446446 : die "invalid spec: $_" } qw(
447447 AvFILLp|5.004050||p
448448 AvFILL|||
449 BhkDISABLE||5.014000|
450 BhkENABLE||5.014000|
451 BhkENTRY_set||5.014000|
449 BhkDISABLE||5.019003|
450 BhkENABLE||5.019003|
451 BhkENTRY_set||5.019003|
452452 BhkENTRY|||
453453 BhkFLAGS|||
454454 CALL_BLOCK_HOOKS|||
467467 CopSTASH_eq|5.006000||p
468468 CopSTASH_set|5.006000||p
469469 CopSTASH|5.006000||p
470 CopyD|5.009002||p
471 Copy|||
472 CvPADLIST|||
470 CopyD|5.009002|5.004050|p
471 Copy||5.004050|
472 CvPADLIST||5.008001|
473473 CvSTASH|||
474474 CvWEAKOUTSIDE|||
475475 DEFSV_set|5.010001||p
492492 G_SCALAR|||
493493 G_VOID||5.004000|
494494 GetVars|||
495 GvAV|||
496 GvCV|||
497 GvHV|||
495498 GvSVn|5.009003||p
496499 GvSV|||
497500 Gv_AMupdate||5.011000|
505508 HeSVKEY||5.004000|
506509 HeUTF8||5.010001|
507510 HeVAL||5.004000|
511 HvENAMELEN||5.015004|
512 HvENAMEUTF8||5.015004|
508513 HvENAME||5.013007|
509514 HvNAMELEN_get|5.009003||p
515 HvNAMELEN||5.015004|
516 HvNAMEUTF8||5.015004|
510517 HvNAME_get|5.009003||p
511518 HvNAME|||
512519 INT2PTR|5.006000||p
527534 LINKLIST||5.013006|
528535 LVRET|||
529536 MARK|||
530 MULTICALL||5.014000|
537 MULTICALL||5.019003|
531538 MY_CXT_CLONE|5.009002||p
532539 MY_CXT_INIT|5.007003||p
533540 MY_CXT|5.007003||p
534 MoveD|5.009002||p
535 Move|||
541 MoveD|5.009002|5.004050|p
542 Move||5.004050|
536543 NOOP|5.005000||p
537544 NUM2PTR|5.006000||p
538545 NVTYPE|5.006000||p
559566 PAD_COMPNAME_OURSTASH|||
560567 PAD_COMPNAME_PV|||
561568 PAD_COMPNAME_TYPE|||
562 PAD_DUP|||
563569 PAD_RESTORE_LOCAL|||
564570 PAD_SAVE_LOCAL|||
565571 PAD_SAVE_SETNULLPAD|||
571577 PERLIO_FUNCS_CAST|5.009003||p
572578 PERLIO_FUNCS_DECL|5.009003||p
573579 PERL_ABS|5.008001||p
574 PERL_BCDVERSION|5.014000||p
580 PERL_BCDVERSION|5.019002||p
575581 PERL_GCC_BRACE_GROUPS_FORBIDDEN|5.008001||p
576582 PERL_HASH|5.004000||p
577583 PERL_INT_MAX|5.004000||p
589595 PERL_MAGIC_env|5.007002||p
590596 PERL_MAGIC_ext|5.007002||p
591597 PERL_MAGIC_fm|5.007002||p
592 PERL_MAGIC_glob|5.014000||p
598 PERL_MAGIC_glob|5.019002||p
593599 PERL_MAGIC_isaelem|5.007002||p
594600 PERL_MAGIC_isa|5.007002||p
595 PERL_MAGIC_mutex|5.014000||p
601 PERL_MAGIC_mutex|5.019002||p
596602 PERL_MAGIC_nkeys|5.007002||p
597 PERL_MAGIC_overload_elem|5.007002||p
603 PERL_MAGIC_overload_elem|5.019002||p
598604 PERL_MAGIC_overload_table|5.007002||p
599 PERL_MAGIC_overload|5.007002||p
605 PERL_MAGIC_overload|5.019002||p
600606 PERL_MAGIC_pos|5.007002||p
601607 PERL_MAGIC_qr|5.007002||p
602608 PERL_MAGIC_regdata|5.007002||p
642648 PERL_SHORT_MIN|5.004000||p
643649 PERL_SIGNALS_UNSAFE_FLAG|5.008001||p
644650 PERL_SUBVERSION|5.006000||p
645 PERL_SYS_INIT3||5.006000|
646 PERL_SYS_INIT|||
647 PERL_SYS_TERM||5.014000|
651 PERL_SYS_INIT3||5.010000|
652 PERL_SYS_INIT||5.010000|
653 PERL_SYS_TERM||5.019003|
648654 PERL_UCHAR_MAX|5.004000||p
649655 PERL_UCHAR_MIN|5.004000||p
650656 PERL_UINT_MAX|5.004000||p
666672 PL_DBsub|||pn
667673 PL_DBtrace|||pn
668674 PL_Sv|5.005000||p
669 PL_bufend|5.014000||p
670 PL_bufptr|5.014000||p
675 PL_bufend|5.019002||p
676 PL_bufptr|5.019002||p
677 PL_check||5.006000|
671678 PL_compiling|5.004050||p
672 PL_copline|5.014000||p
679 PL_comppad_name||5.017004|
680 PL_comppad||5.008001|
681 PL_copline|5.019002||p
673682 PL_curcop|5.004050||p
683 PL_curpad||5.005000|
674684 PL_curstash|5.004050||p
675685 PL_debstash|5.004050||p
676686 PL_defgv|5.004050||p
678688 PL_dirty|5.004050||p
679689 PL_dowarn|||pn
680690 PL_errgv|5.004050||p
681 PL_error_count|5.014000||p
682 PL_expect|5.014000||p
691 PL_error_count|5.019002||p
692 PL_expect|5.019002||p
683693 PL_hexdigit|5.005000||p
684694 PL_hints|5.005000||p
685 PL_in_my_stash|5.014000||p
686 PL_in_my|5.014000||p
695 PL_in_my_stash|5.019002||p
696 PL_in_my|5.019002||p
687697 PL_keyword_plugin||5.011002|
688698 PL_last_in_gv|||n
689699 PL_laststatval|5.005000||p
690 PL_lex_state|5.014000||p
691 PL_lex_stuff|5.014000||p
692 PL_linestr|5.014000||p
700 PL_lex_state|5.019002||p
701 PL_lex_stuff|5.019002||p
702 PL_linestr|5.019002||p
693703 PL_modglobal||5.005000|n
694704 PL_na|5.004050||pn
695705 PL_no_modify|5.006000||p
701711 PL_perldb|5.004050||p
702712 PL_ppaddr|5.006000||p
703713 PL_rpeepp||5.013005|n
704 PL_rsfp_filters|5.014000||p
705 PL_rsfp|5.014000||p
714 PL_rsfp_filters|5.019002||p
715 PL_rsfp|5.019002||p
706716 PL_rs|||n
707717 PL_signals|5.008001||p
708718 PL_stack_base|5.004050||p
715725 PL_sv_yes|5.004050||pn
716726 PL_tainted|5.004050||p
717727 PL_tainting|5.004050||p
718 PL_tokenbuf|5.014000||p
719 POP_MULTICALL||5.014000|
728 PL_tokenbuf|5.019002||p
729 POP_MULTICALL||5.019003|
720730 POPi|||n
721731 POPl|||n
722732 POPn|||n
731741 PTR2ul|5.007001||p
732742 PTRV|5.006000||p
733743 PUSHMARK|||
734 PUSH_MULTICALL||5.014000|
744 PUSH_MULTICALL||5.019003|
735745 PUSHi|||
736746 PUSHmortal|5.009002||p
737747 PUSHn|||
739749 PUSHs|||
740750 PUSHu|5.004000||p
741751 PUTBACK|||
752 PadARRAY||5.019003|
753 PadMAX||5.019003|
754 PadlistARRAY||5.019003|
755 PadlistMAX||5.019003|
756 PadlistNAMESARRAY||5.019003|
757 PadlistNAMESMAX||5.019003|
758 PadlistNAMES||5.019003|
759 PadlistREFCNT||5.017004|
760 PadnameIsOUR|||
761 PadnameIsSTATE|||
762 PadnameLEN||5.019003|
763 PadnameOURSTASH|||
764 PadnameOUTER|||
765 PadnamePV||5.019003|
766 PadnameSV||5.019003|
767 PadnameTYPE|||
768 PadnameUTF8||5.019003|
769 PadnamelistARRAY||5.019003|
770 PadnamelistMAX||5.019003|
742771 PerlIO_clearerr||5.007003|
743772 PerlIO_close||5.007003|
744773 PerlIO_context_layers||5.009004|
767796 PoisonNew|5.009004||p
768797 PoisonWith|5.009004||p
769798 Poison|5.008000||p
799 READ_XDIGIT||5.017006|
770800 RETVAL|||n
771801 Renewc|||
772802 Renew|||
796826 SVfARG|5.009005||p
797827 SVf_UTF8|5.006000||p
798828 SVf|5.006000||p
829 SVt_INVLIST||5.019002|
799830 SVt_IV|||
831 SVt_NULL|||
800832 SVt_NV|||
801833 SVt_PVAV|||
802834 SVt_PVCV|||
835 SVt_PVFM|||
836 SVt_PVGV|||
803837 SVt_PVHV|||
838 SVt_PVIO|||
839 SVt_PVIV|||
840 SVt_PVLV|||
804841 SVt_PVMG|||
842 SVt_PVNV|||
805843 SVt_PV|||
844 SVt_REGEXP||5.011000|
806845 Safefree|||
807846 Slab_Alloc|||
808847 Slab_Free|||
848 Slab_to_ro|||
809849 Slab_to_rw|||
810850 StructCopy|||
811851 SvCUR_set|||
876916 SvPV_nolen|5.006000||p
877917 SvPV_nomg_const_nolen|5.009003||p
878918 SvPV_nomg_const|5.009003||p
879 SvPV_nomg_nolen||5.013007|
919 SvPV_nomg_nolen|5.013007||p
880920 SvPV_nomg|5.007002||p
881921 SvPV_renew|5.009003||p
882922 SvPV_set|||
892932 SvPVutf8||5.006000|
893933 SvPVx|||
894934 SvPV|||
935 SvREFCNT_dec_NN||5.017007|
895936 SvREFCNT_dec|||
896937 SvREFCNT_inc_NN|5.009004||p
897938 SvREFCNT_inc_simple_NN|5.009004||p
922963 SvTAINTED_on||5.004000|
923964 SvTAINTED||5.004000|
924965 SvTAINT|||
966 SvTHINKFIRST|||
925967 SvTRUE_nomg||5.013006|
926968 SvTRUE|||
927969 SvTYPE|||
950992 UVxf|5.006000||p
951993 WARN_ALL|5.006000||p
952994 WARN_AMBIGUOUS|5.006000||p
953 WARN_ASSERTIONS|5.014000||p
995 WARN_ASSERTIONS|5.019002||p
954996 WARN_BAREWORD|5.006000||p
955997 WARN_CLOSED|5.006000||p
956998 WARN_CLOSURE|5.006000||p
9951037 WARN_UNTIE|5.006000||p
9961038 WARN_UTF8|5.006000||p
9971039 WARN_VOID|5.006000||p
1040 WIDEST_UTYPE|5.015004||p
9981041 XCPT_CATCH|5.009002||p
999 XCPT_RETHROW|5.009002||p
1000 XCPT_TRY_END|5.009002||p
1001 XCPT_TRY_START|5.009002||p
1042 XCPT_RETHROW|5.009002|5.007001|p
1043 XCPT_TRY_END|5.009002|5.004000|p
1044 XCPT_TRY_START|5.009002|5.004000|p
10021045 XPUSHi|||
10031046 XPUSHmortal|5.009002||p
10041047 XPUSHn|||
10231066 XST_mUV|5.008001||p
10241067 XST_mYES|||
10251068 XS_APIVERSION_BOOTCHECK||5.013004|
1069 XS_EXTERNAL||5.019003|
1070 XS_INTERNAL||5.019003|
10261071 XS_VERSION_BOOTCHECK|||
10271072 XS_VERSION|||
10281073 XSprePUSH|5.006000||p
10291074 XS|||
1030 XopDISABLE||5.014000|
1031 XopENABLE||5.014000|
1032 XopENTRY_set||5.014000|
1033 XopENTRY||5.014000|
1075 XopDISABLE||5.019003|
1076 XopENABLE||5.019003|
1077 XopENTRY_set||5.019003|
1078 XopENTRY||5.019003|
10341079 XopFLAGS||5.013007|
10351080 ZeroD|5.009002||p
10361081 Zero|||
10371082 _aMY_CXT|5.007003||p
1083 _add_range_to_invlist|||
10381084 _append_range_to_invlist|||
1085 _core_swash_init|||
1086 _get_swash_invlist|||
1087 _invlist_array_init|||
1088 _invlist_contains_cp|||
1089 _invlist_contents|||
1090 _invlist_dump|||
1091 _invlist_intersection_maybe_complement_2nd|||
1092 _invlist_intersection|||
1093 _invlist_invert_prop|||
1094 _invlist_invert|||
1095 _invlist_len|||
1096 _invlist_populate_swatch|||
1097 _invlist_search|||
1098 _invlist_subtract|||
1099 _invlist_union_maybe_complement_2nd|||
1100 _invlist_union|||
1101 _is_uni_FOO||5.017008|
1102 _is_uni_perl_idcont||5.017008|
1103 _is_uni_perl_idstart||5.017007|
1104 _is_utf8_FOO||5.017008|
1105 _is_utf8_mark||5.017008|
1106 _is_utf8_perl_idcont||5.017008|
1107 _is_utf8_perl_idstart||5.017007|
1108 _new_invlist_C_array|||
10391109 _new_invlist|||
10401110 _pMY_CXT|5.007003||p
10411111 _swash_inversion_hash|||
10421112 _swash_to_invlist|||
1113 _to_fold_latin1|||
1114 _to_uni_fold_flags||5.013011|
1115 _to_upper_title_latin1|||
1116 _to_utf8_fold_flags||5.015006|
1117 _to_utf8_lower_flags||5.015006|
1118 _to_utf8_title_flags||5.015006|
1119 _to_utf8_upper_flags||5.015006|
10431120 aMY_CXT_|5.007003||p
10441121 aMY_CXT|5.007003||p
1045 aTHXR_|5.014000||p
1046 aTHXR|5.014000||p
1122 aTHXR_|5.019002||p
1123 aTHXR|5.019002||p
10471124 aTHX_|5.006000||p
10481125 aTHX|5.006000||p
1049 add_alternate|||
1126 aassign_common_vars|||
10501127 add_cp_to_invlist|||
10511128 add_data|||n
1052 add_range_to_invlist|||
10531129 add_utf16_textfilter|||
10541130 addmad|||
1131 adjust_size_and_find_bucket|||n
1132 adjust_stack_on_leave|||
1133 alloc_maybe_populate_EXACT|||
1134 alloccopstash|||
10551135 allocmy|||
10561136 amagic_call|||
10571137 amagic_cmp_locale|||
10581138 amagic_cmp|||
10591139 amagic_deref_call||5.013007|
10601140 amagic_i_ncmp|||
1141 amagic_is_enabled|||
10611142 amagic_ncmp|||
10621143 anonymise_cv_maybe|||
10631144 any_dup|||
10761157 av_create_and_unshift_one||5.009005|
10771158 av_delete||5.006000|
10781159 av_exists||5.006000|
1160 av_extend_guts|||
10791161 av_extend|||
10801162 av_fetch|||
10811163 av_fill|||
10871169 av_reify|||
10881170 av_shift|||
10891171 av_store|||
1172 av_tindex||5.017009|
1173 av_top_index||5.017009|
10901174 av_undef|||
10911175 av_unshift|||
10921176 ax|||n
1093 bad_type|||
1177 bad_type_gv|||
1178 bad_type_pv|||
10941179 bind_match|||
10951180 block_end|||
10961181 block_gimme||5.004000|
11171202 cast_iv||5.006000|
11181203 cast_ulong||5.006000|
11191204 cast_uv||5.006000|
1205 check_locale_boundary_crossing|||
11201206 check_type_and_open|||
11211207 check_uni|||
11221208 check_utf8_print|||
11231209 checkcomma|||
1124 checkposixcc|||
11251210 ckWARN|5.006000||p
1211 ck_entersub_args_core|||
11261212 ck_entersub_args_list||5.013006|
11271213 ck_entersub_args_proto_or_list||5.013006|
11281214 ck_entersub_args_proto||5.013006|
11401226 clone_params_del|||n
11411227 clone_params_new|||n
11421228 closest_cop|||
1229 compute_EXACTish|||
11431230 convert|||
1231 cop_fetch_label||5.015001|
11441232 cop_free|||
11451233 cop_hints_2hv||5.013007|
11461234 cop_hints_fetch_pvn||5.013007|
11471235 cop_hints_fetch_pvs||5.013007|
11481236 cop_hints_fetch_pv||5.013007|
11491237 cop_hints_fetch_sv||5.013007|
1238 cop_store_label||5.015001|
11501239 cophh_2hv||5.013007|
11511240 cophh_copy||5.013007|
11521241 cophh_delete_pvn||5.013007|
11581247 cophh_fetch_pv||5.013007|
11591248 cophh_fetch_sv||5.013007|
11601249 cophh_free||5.013007|
1161 cophh_new_empty||5.014000|
1250 cophh_new_empty||5.019003|
11621251 cophh_store_pvn||5.013007|
11631252 cophh_store_pvs||5.013007|
11641253 cophh_store_pv||5.013007|
11651254 cophh_store_sv||5.013007|
1255 core_prototype|||
1256 core_regclass_swash|||
1257 coresub_op|||
1258 could_it_be_a_POSIX_class|||
11661259 cr_textfilter|||
11671260 create_eval_scope|||
1168 croak_no_modify||5.013003|
1261 croak_memory_wrap||5.019003|n
1262 croak_no_mem|||n
1263 croak_no_modify||5.013003|n
11691264 croak_nocontext|||vn
1265 croak_popstack|||n
11701266 croak_sv||5.013001|
1171 croak_xs_usage||5.010001|
1267 croak_xs_usage||5.010001|n
11721268 croak|||v
11731269 csighandler||5.009003|n
11741270 curmad|||
1271 current_re_engine|||
11751272 curse|||
11761273 custom_op_desc||5.007003|
11771274 custom_op_name||5.007003|
11781275 custom_op_register||5.013007|
11791276 custom_op_xop||5.013007|
1180 cv_ckproto_len|||
1277 cv_ckproto_len_flags|||
1278 cv_clone_into|||
11811279 cv_clone|||
1280 cv_const_sv_or_av|||
11821281 cv_const_sv||5.004000|
11831282 cv_dump|||
1283 cv_forget_slab|||
11841284 cv_get_call_checker||5.013006|
11851285 cv_set_call_checker||5.013006|
11861286 cv_undef|||
12001300 dORIGMARK|||
12011301 dSP|||
12021302 dTHR|5.004050||p
1203 dTHXR|5.014000||p
1303 dTHXR|5.019002||p
12041304 dTHXa|5.006000||p
12051305 dTHXoa|5.006000||p
12061306 dTHX|5.006000||p
12211321 debstack||5.007003|
12221322 debug_start_match|||
12231323 deb||5.007003|v
1324 defelem_target|||
12241325 del_sv|||
12251326 delete_eval_scope|||
12261327 delimcpy||5.004000|n
12551356 do_magic_dump||5.006000|
12561357 do_msgrcv|||
12571358 do_msgsnd|||
1359 do_ncmp|||
12581360 do_oddball|||
12591361 do_op_dump||5.006000|
12601362 do_op_xmldump|||
13301432 fbm_compile||5.005000|
13311433 fbm_instr||5.005000|
13321434 feature_is_enabled|||
1333 fetch_cop_label||5.011000|
13341435 filter_add|||
13351436 filter_del|||
13361437 filter_gets|||
13371438 filter_read|||
1439 finalize_optree|||
1440 finalize_op|||
13381441 find_and_forget_pmops|||
13391442 find_array_subscript|||
13401443 find_beginning|||
13411444 find_byclass|||
13421445 find_hash_subscript|||
13431446 find_in_my_stash|||
1447 find_lexical_cv|||
1448 find_runcv_where|||
13441449 find_runcv||5.008001|
1450 find_rundefsv2|||
13451451 find_rundefsvoffset||5.009002|
13461452 find_rundefsv||5.013002|
13471453 find_script|||
13541460 foldEQ||5.013002|n
13551461 fold_constants|||
13561462 forbid_setid|||
1463 force_ident_maybe_lex|||
13571464 force_ident|||
13581465 force_list|||
13591466 force_next|||
13621469 force_word|||
13631470 forget_pmop|||
13641471 form_nocontext|||vn
1472 form_short_octal_warning|||
13651473 form||5.004000|v
13661474 fp_dup|||
13671475 fprintf_nocontext|||vn
13691477 free_tied_hv_pool|||
13701478 free_tmps|||
13711479 gen_constant_list|||
1480 get_and_check_backslash_N_name|||
13721481 get_aux_mg|||
13731482 get_av|5.006000||p
13741483 get_context||5.006000|n
13791488 get_debug_opts|||
13801489 get_hash_seed|||
13811490 get_hv|5.006000||p
1491 get_invlist_iter_addr|||
1492 get_invlist_offset_addr|||
1493 get_invlist_previous_index_addr|||
13821494 get_mstats|||
13831495 get_no_modify|||
13841496 get_num|||
13981510 gp_free|||
13991511 gp_ref|||
14001512 grok_bin|5.007003||p
1513 grok_bslash_N|||
14011514 grok_bslash_c|||
14021515 grok_bslash_o|||
1516 grok_bslash_x|||
14031517 grok_hex|5.007003||p
14041518 grok_number|5.007002||p
14051519 grok_numeric_radix|5.007002||p
14111525 gv_SVadd|||
14121526 gv_add_by_type||5.011000|
14131527 gv_autoload4||5.004000|
1528 gv_autoload_pvn||5.015004|
1529 gv_autoload_pv||5.015004|
1530 gv_autoload_sv||5.015004|
14141531 gv_check|||
14151532 gv_const_sv||5.009003|
14161533 gv_dump||5.006000|
14211538 gv_fetchfile_flags||5.009005|
14221539 gv_fetchfile|||
14231540 gv_fetchmeth_autoload||5.007003|
1541 gv_fetchmeth_pv_autoload||5.015004|
1542 gv_fetchmeth_pvn_autoload||5.015004|
1543 gv_fetchmeth_pvn||5.015004|
1544 gv_fetchmeth_pv||5.015004|
1545 gv_fetchmeth_sv_autoload||5.015004|
1546 gv_fetchmeth_sv||5.015004|
14241547 gv_fetchmethod_autoload||5.004000|
1425 gv_fetchmethod_flags||5.011000|
1548 gv_fetchmethod_pv_flags||5.015004|
1549 gv_fetchmethod_pvn_flags||5.015004|
1550 gv_fetchmethod_sv_flags||5.015004|
14261551 gv_fetchmethod|||
14271552 gv_fetchmeth|||
14281553 gv_fetchpvn_flags|5.009002||p
14321557 gv_fullname3||5.004000|
14331558 gv_fullname4||5.006001|
14341559 gv_fullname|||
1435 gv_get_super_pkg|||
14361560 gv_handler||5.007001|
1437 gv_init_sv|||
1561 gv_init_pvn||5.015004|
1562 gv_init_pv||5.015004|
1563 gv_init_svtype|||
1564 gv_init_sv||5.015004|
14381565 gv_init|||
14391566 gv_magicalize_isa|||
1440 gv_magicalize_overload|||
14411567 gv_name_set||5.009004|
14421568 gv_stashpvn|5.004000||p
14431569 gv_stashpvs|5.009003||p
14441570 gv_stashpv|||
14451571 gv_stashsv|||
14461572 gv_try_downgrade|||
1573 handle_regex_sets|||
14471574 he_dup|||
14481575 hek_dup|||
1576 hfree_next_entry|||
14491577 hfreeentries|||
14501578 hsplit|||
14511579 hv_assert|||
1452 hv_auxinit|||n
1580 hv_auxinit|||
14531581 hv_backreferences_p|||
14541582 hv_clear_placeholders||5.009001|
14551583 hv_clear|||
14701598 hv_fetchs|5.009003||p
14711599 hv_fetch|||
14721600 hv_fill||5.013002|
1601 hv_free_ent_ret|||
14731602 hv_free_ent||5.004000|
14741603 hv_iterinit|||
14751604 hv_iterkeysv||5.004000|
14851614 hv_name_set||5.009003|
14861615 hv_notallowed|||
14871616 hv_placeholders_get||5.009003|
1488 hv_placeholders_p||5.009003|
1617 hv_placeholders_p|||
14891618 hv_placeholders_set||5.009003|
1619 hv_rand_set||5.017011|
14901620 hv_riter_p||5.009003|
14911621 hv_riter_set||5.009003|
14921622 hv_scalar||5.009001|
15051635 incpush|||
15061636 ingroup|||
15071637 init_argv_symbols|||
1638 init_constants|||
15081639 init_dbargs|||
15091640 init_debugger|||
15101641 init_global_struct|||
15181649 init_predump_symbols|||
15191650 init_stacks||5.005000|
15201651 init_tm||5.007002|
1652 inplace_aassign|||
15211653 instr|||n
15221654 intro_my|||
15231655 intuit_method|||
15241656 intuit_more|||
15251657 invert|||
15261658 invlist_array|||
1527 invlist_destroy|||
1659 invlist_clone|||
15281660 invlist_extend|||
1529 invlist_intersection|||
1530 invlist_len|||
1661 invlist_highest|||
1662 invlist_is_iterating|||
1663 invlist_iterfinish|||
1664 invlist_iterinit|||
1665 invlist_iternext|||
15311666 invlist_max|||
1532 invlist_set_array|||
1667 invlist_previous_index|||
15331668 invlist_set_len|||
1534 invlist_set_max|||
1669 invlist_set_previous_index|||
15351670 invlist_trim|||
1536 invlist_union|||
15371671 invoke_exception_hook|||
15381672 io_close|||
15391673 isALNUMC|5.006000||p
1674 isALNUM_lazy|||
1675 isALPHANUMERIC||5.017008|
15401676 isALPHA|||
1541 isASCII|5.006000||p
1677 isASCII|5.006000|5.006000|p
15421678 isBLANK|5.006001||p
1543 isCNTRL|5.006000||p
1679 isCNTRL|5.006000|5.006000|p
15441680 isDIGIT|||
1681 isFOO_lc|||
1682 isFOO_utf8_lc|||
15451683 isGRAPH|5.006000||p
15461684 isGV_with_GP|5.009004||p
1685 isIDCONT||5.017008|
1686 isIDFIRST_lazy|||
1687 isIDFIRST|||
15471688 isLOWER|||
15481689 isOCTAL||5.013005|
15491690 isPRINT|5.004000||p
15551696 isXDIGIT|5.006000||p
15561697 is_an_int|||
15571698 is_ascii_string||5.011000|n
1558 is_gv_magical_sv|||
1699 is_cur_LC_category_utf8|||
15591700 is_handle_constructor|||n
1560 is_inplace_av|||
15611701 is_list_assignment|||
15621702 is_lvalue_sub||5.007001|
15631703 is_uni_alnum_lc||5.006000|
1704 is_uni_alnumc_lc||5.017007|
1705 is_uni_alnumc||5.017007|
15641706 is_uni_alnum||5.006000|
15651707 is_uni_alpha_lc||5.006000|
15661708 is_uni_alpha||5.006000|
15671709 is_uni_ascii_lc||5.006000|
15681710 is_uni_ascii||5.006000|
1711 is_uni_blank_lc||5.017002|
1712 is_uni_blank||5.017002|
15691713 is_uni_cntrl_lc||5.006000|
15701714 is_uni_cntrl||5.006000|
15711715 is_uni_digit_lc||5.006000|
15861730 is_uni_upper||5.006000|
15871731 is_uni_xdigit_lc||5.006000|
15881732 is_uni_xdigit||5.006000|
1589 is_utf8_X_LVT|||
1590 is_utf8_X_LV_LVT_V|||
1591 is_utf8_X_LV|||
1592 is_utf8_X_L|||
1593 is_utf8_X_T|||
1594 is_utf8_X_V|||
1595 is_utf8_X_begin|||
1596 is_utf8_X_extend|||
1597 is_utf8_X_non_hangul|||
1598 is_utf8_X_prepend|||
1733 is_utf8_alnumc||5.017007|
15991734 is_utf8_alnum||5.006000|
16001735 is_utf8_alpha||5.006000|
16011736 is_utf8_ascii||5.006000|
1737 is_utf8_blank||5.017002|
1738 is_utf8_char_buf||5.015008|n
16021739 is_utf8_char_slow|||n
16031740 is_utf8_char||5.006000|n
16041741 is_utf8_cntrl||5.006000|
16661803 madlex|||
16671804 madparse|||
16681805 magic_clear_all_env|||
1806 magic_cleararylen_p|||
16691807 magic_clearenv|||
16701808 magic_clearhints|||
16711809 magic_clearhint|||
16721810 magic_clearisa|||
16731811 magic_clearpack|||
16741812 magic_clearsig|||
1813 magic_copycallchecker|||
16751814 magic_dump||5.006000|
16761815 magic_existspack|||
16771816 magic_freearylen_p|||
16881827 magic_getvec|||
16891828 magic_get|||
16901829 magic_killbackrefs|||
1691 magic_len|||
16921830 magic_methcall1|||
16931831 magic_methcall|||v
16941832 magic_methpack|||
16981836 magic_regdatum_set|||
16991837 magic_scalarpack|||
17001838 magic_set_all_env|||
1701 magic_setamagic|||
17021839 magic_setarylen|||
17031840 magic_setcollxfrm|||
17041841 magic_setdbline|||
17281865 malloc||5.007002|n
17291866 markstack_grow|||
17301867 matcher_matches_sv|||
1868 mayberelocate|||
17311869 measure_struct|||
17321870 memEQs|5.009005||p
17331871 memEQ|5.004000||p
17441882 mg_clear|||
17451883 mg_copy|||
17461884 mg_dup|||
1885 mg_find_mglob|||
17471886 mg_findext||5.013008|
17481887 mg_find|||
17491888 mg_free_type||5.013006|
17551894 mg_set|||
17561895 mg_size||5.005000|
17571896 mini_mktime||5.007002|
1897 minus_v|||
17581898 missingterm|||
17591899 mode_from_discipline|||
17601900 modkids|||
1761 mod|||
17621901 more_bodies|||
17631902 more_sv|||
17641903 moreswitches|||
17781917 mro_set_private_data||5.010001|
17791918 mul128|||
17801919 mulexp10|||n
1781 munge_qwlist_to_paren_list|||
17821920 my_atof2||5.007002|
17831921 my_atof||5.006000|
17841922 my_attrs|||
17851923 my_bcopy|||n
1786 my_betoh16|||n
1787 my_betoh32|||n
1788 my_betoh64|||n
1789 my_betohi|||n
1790 my_betohl|||n
1791 my_betohs|||n
17921924 my_bzero|||n
17931925 my_chsize|||
17941926 my_clearenv|||
18001932 my_failure_exit||5.004000|
18011933 my_fflush_all||5.006000|
18021934 my_fork||5.007003|n
1803 my_htobe16|||n
1804 my_htobe32|||n
1805 my_htobe64|||n
1806 my_htobei|||n
1807 my_htobel|||n
1808 my_htobes|||n
1809 my_htole16|||n
1810 my_htole32|||n
1811 my_htole64|||n
1812 my_htolei|||n
1813 my_htolel|||n
1814 my_htoles|||n
1815 my_htonl|||
18161935 my_kid|||
1817 my_letoh16|||n
1818 my_letoh32|||n
1819 my_letoh64|||n
1820 my_letohi|||n
1821 my_letohl|||n
1822 my_letohs|||n
18231936 my_lstat_flags|||
1824 my_lstat||5.014000|
1825 my_memcmp||5.004000|n
1826 my_memset|||n
1827 my_ntohl|||
1937 my_lstat||5.019003|
1938 my_memcmp|||n
1939 my_memset||5.004000|n
18281940 my_pclose||5.004000|
18291941 my_popen_list||5.007001|
18301942 my_popen||5.004000|
18331945 my_socketpair||5.007003|n
18341946 my_sprintf|5.009003||pvn
18351947 my_stat_flags|||
1836 my_stat||5.014000|
1948 my_stat||5.019003|
18371949 my_strftime||5.007002|
18381950 my_strlcat|5.009004||pn
18391951 my_strlcpy|5.009004||pn
1840 my_swabn|||n
1841 my_swap|||
18421952 my_unexec|||
18431953 my_vsnprintf||5.009004|n
18441954 need_utf8|||n
18471957 newANONLIST|||
18481958 newANONSUB|||
18491959 newASSIGNOP|||
1960 newATTRSUB_flags|||
18501961 newATTRSUB||5.006000|
18511962 newAVREF|||
18521963 newAV|||
18531964 newBINOP|||
18541965 newCONDOP|||
1966 newCONSTSUB_flags||5.015006|
18551967 newCONSTSUB|5.004050||p
18561968 newCVREF|||
18571969 newDEFSVOP|||
18621974 newGP|||
18631975 newGVOP|||
18641976 newGVREF|||
1977 newGVgen_flags||5.015004|
18651978 newGVgen|||
18661979 newHVREF|||
18671980 newHVhv||5.005000|
18731986 newLOOPOP|||
18741987 newMADPROP|||
18751988 newMADsv|||
1876 newMYSUB|||
1989 newMYSUB||5.017004|
18771990 newNULLLIST|||
18781991 newOP|||
18791992 newPADOP|||
18861999 newRV|||
18872000 newSLICEOP|||
18882001 newSTATEOP|||
2002 newSTUB|||
18892003 newSUB|||
18902004 newSVOP|||
18912005 newSVREF|||
18932007 newSVhek||5.009003|
18942008 newSViv|||
18952009 newSVnv|||
2010 newSVpadname||5.017004|
18962011 newSVpv_share||5.013006|
18972012 newSVpvf_nocontext|||vn
18982013 newSVpvf||5.004000|v
19132028 newWHENOP||5.009003|
19142029 newWHILEOP||5.013007|
19152030 newXS_flags||5.009004|
2031 newXS_len_flags|||
19162032 newXSproto||5.006000|
19172033 newXS||5.006000|
19182034 new_collate||5.006000|
19322048 no_fh_allowed|||
19332049 no_op|||
19342050 not_a_number|||
2051 not_incrementable|||
19352052 nothreadhook||5.008000|
19362053 nuke_stacks|||
19372054 num_overflow|||n
19462063 op_free|||
19472064 op_getmad_weak|||
19482065 op_getmad|||
2066 op_integerize|||
19492067 op_linklist||5.013006|
2068 op_lvalue_flags|||
19502069 op_lvalue||5.013007|
19512070 op_null||5.007002|
19522071 op_prepend_elem||5.013006|
19552074 op_refcnt_lock||5.009002|
19562075 op_refcnt_unlock||5.009002|
19572076 op_scope||5.013007|
2077 op_std_init|||
2078 op_unscope|||
19582079 op_xmldump|||
19592080 open_script|||
1960 opt_scalarhv|||
2081 opslab_force_free|||
2082 opslab_free_nopad|||
2083 opslab_free|||
19612084 pMY_CXT_|5.007003||p
19622085 pMY_CXT|5.007003||p
19632086 pTHX_|5.006000||p
19682091 package_version|||
19692092 package|||
19702093 packlist||5.008001|
1971 pad_add_anon|||
1972 pad_add_name_sv|||
1973 pad_add_name|||
2094 pad_add_anon||5.008001|
2095 pad_add_name_pvn||5.015001|
2096 pad_add_name_pvs||5.015001|
2097 pad_add_name_pv||5.015001|
2098 pad_add_name_sv||5.015001|
2099 pad_alloc_name|||
19742100 pad_alloc|||
19752101 pad_block_start|||
19762102 pad_check_dup|||
1977 pad_compname_type|||
2103 pad_compname_type||5.009003|
19782104 pad_findlex|||
1979 pad_findmy||5.011002|
2105 pad_findmy_pvn||5.015001|
2106 pad_findmy_pvs||5.015001|
2107 pad_findmy_pv||5.015001|
2108 pad_findmy_sv||5.015001|
19802109 pad_fixup_inner_anons|||
19812110 pad_free|||
19822111 pad_leavemy|||
1983 pad_new|||
2112 pad_new||5.008001|
19842113 pad_peg|||n
19852114 pad_push|||
19862115 pad_reset|||
19872116 pad_setsv|||
19882117 pad_sv|||
19892118 pad_swipe|||
1990 pad_tidy|||
2119 pad_tidy||5.008001|
19912120 padlist_dup|||
2121 padlist_store|||
19922122 parse_arithexpr||5.013008|
19932123 parse_barestmt||5.013007|
19942124 parse_block||5.013007|
19952125 parse_body|||
19962126 parse_fullexpr||5.013008|
19972127 parse_fullstmt||5.013005|
2128 parse_ident|||
19982129 parse_label||5.013007|
19992130 parse_listexpr||5.013008|
2131 parse_lparen_question_flags|||
20002132 parse_stmtseq||5.013006|
20012133 parse_termexpr||5.013008|
20022134 parse_unicode_opts|||
20032135 parser_dup|||
2136 parser_free_nexttoke_ops|||
20042137 parser_free|||
2005 path_is_absolute|||n
2138 path_is_searchable|||n
20062139 peep|||
2007 pending_Slabs_to_ro|||
2140 pending_ident|||
20082141 perl_alloc_using|||n
20092142 perl_alloc|||n
20102143 perl_clone_using|||n
20312164 printbuf|||
20322165 printf_nocontext|||vn
20332166 process_special_blocks|||
2167 ptr_hash|||n
20342168 ptr_table_clear||5.009005|
20352169 ptr_table_fetch||5.009005|
20362170 ptr_table_find|||n
20402174 ptr_table_store||5.009005|
20412175 push_scope|||
20422176 put_byte|||
2177 put_latin1_charclass_innards|||
20432178 pv_display|5.006000||p
20442179 pv_escape|5.009004||p
20452180 pv_pretty|5.009004||p
20492184 re_compile||5.009005|
20502185 re_croak2|||
20512186 re_dup_guts|||
2052 re_intuit_start||5.009005|
2187 re_intuit_start||5.019001|
20532188 re_intuit_string||5.006000|
2189 re_op_compile|||
20542190 readpipe_override|||
20552191 realloc||5.007002|n
2056 reentrant_free|||
2057 reentrant_init|||
2058 reentrant_retry|||vn
2059 reentrant_size|||
2192 reentrant_free||5.019003|
2193 reentrant_init||5.019003|
2194 reentrant_retry||5.019003|vn
2195 reentrant_size||5.019003|
20602196 ref_array_or_hash|||
20612197 refcounted_he_chain_2hv|||
20622198 refcounted_he_fetch_pvn|||
20722208 refcounted_he_value|||
20732209 refkids|||
20742210 refto|||
2075 ref||5.014000|
2211 ref||5.019003|
20762212 reg_check_named_buff_matched|||
20772213 reg_named_buff_all||5.009005|
20782214 reg_named_buff_exists||5.009005|
20822218 reg_named_buff_nextkey||5.009005|
20832219 reg_named_buff_scalar||5.009005|
20842220 reg_named_buff|||
2085 reg_namedseq|||
20862221 reg_node|||
20872222 reg_numbered_buff_fetch|||
20882223 reg_numbered_buff_length|||
21012236 regcppush|||
21022237 regcurly|||
21032238 regdump_extflags|||
2239 regdump_intflags|||
21042240 regdump||5.005000|
21052241 regdupe_internal|||
21062242 regexec_flags||5.005000|
21132249 reginsert|||
21142250 regmatch|||
21152251 regnext||5.005000|
2252 regpatws|||n
21162253 regpiece|||
21172254 regpposixcc|||
21182255 regprop|||
21252262 reg|||
21262263 repeatcpy|||n
21272264 report_evil_fh|||
2265 report_redefined_cv|||
21282266 report_uninit|||
21292267 report_wrongway_fh|||
21302268 require_pv||5.006000|
21832321 save_lines|||
21842322 save_list|||
21852323 save_long|||
2186 save_magic|||
2324 save_magic_flags|||
21872325 save_mortalizesv||5.007001|
21882326 save_nogv|||
21892327 save_op||5.005000|
22392377 search_const|||
22402378 seed||5.008001|
22412379 sequence_num|||
2242 sequence_tail|||
2243 sequence|||
22442380 set_context||5.006000|n
22452381 set_numeric_local||5.006000|
22462382 set_numeric_radix||5.006000|
22472383 set_numeric_standard||5.006000|
2248 set_regclass_bit_fold|||
2249 set_regclass_bit|||
22502384 setdefout|||
22512385 share_hek_flags|||
22522386 share_hek||5.004000|
22562390 skipspace0|||
22572391 skipspace1|||
22582392 skipspace2|||
2259 skipspace|||
2393 skipspace_flags|||
22602394 softref2xv|||
22612395 sortcv_stacked|||
22622396 sortcv_xsub|||
22692403 start_force|||
22702404 start_glob|||
22712405 start_subparse||5.004000|
2272 stashpv_hvname_match||5.014000|
22732406 stdize_locale|||
2274 store_cop_label|||
22752407 strEQ|||
22762408 strGE|||
22772409 strGT|||
23452477 sv_cmp|||
23462478 sv_collxfrm_flags||5.013006|
23472479 sv_collxfrm|||
2348 sv_compile_2op_is_broken|||
2349 sv_compile_2op||5.008001|
2350 sv_copypv||5.007003|
2480 sv_copypv_flags||5.017002|
2481 sv_copypv_nomg||5.017002|
2482 sv_copypv|||
23512483 sv_dec_nomg||5.013002|
23522484 sv_dec|||
23532485 sv_del_backref|||
2486 sv_derived_from_pvn||5.015004|
2487 sv_derived_from_pv||5.015004|
2488 sv_derived_from_sv||5.015004|
23542489 sv_derived_from||5.004000|
23552490 sv_destroyable||5.010000|
2491 sv_display|||
2492 sv_does_pvn||5.015004|
2493 sv_does_pv||5.015004|
2494 sv_does_sv||5.015004|
23562495 sv_does||5.009004|
23572496 sv_dump|||
23582497 sv_dup_common|||
23782517 sv_isobject|||
23792518 sv_iv||5.005000|
23802519 sv_kill_backrefs|||
2520 sv_len_utf8_nomg|||
23812521 sv_len_utf8||5.006000|
23822522 sv_len|||
2383 sv_magic_portable|5.014000|5.004000|p
2523 sv_magic_portable|5.019003|5.004000|p
2524 sv_magicext_mglob|||
23842525 sv_magicext||5.007003|
23852526 sv_magic|||
2527 sv_mortalcopy_flags|||
23862528 sv_mortalcopy|||
23872529 sv_ncmp|||
23882530 sv_newmortal|||
23922534 sv_nounlocking|||
23932535 sv_nv||5.005000|
23942536 sv_peek||5.005000|
2537 sv_pos_b2u_flags||5.019003|
23952538 sv_pos_b2u_midway|||
23962539 sv_pos_b2u||5.006000|
23972540 sv_pos_u2b_cached|||
24122555 sv_pv||5.006000|
24132556 sv_recode_to_utf8||5.007003|
24142557 sv_reftype|||
2558 sv_ref|||
24152559 sv_release_COW|||
24162560 sv_replace|||
24172561 sv_report_used|||
2562 sv_resetpvn|||
24182563 sv_reset|||
24192564 sv_rvweaken||5.006000|
2565 sv_sethek|||
24202566 sv_setiv_mg|5.004050||p
24212567 sv_setiv|||
24222568 sv_setnv_mg|5.006000||p
24362582 sv_setref_iv|||
24372583 sv_setref_nv|||
24382584 sv_setref_pvn|||
2439 sv_setref_pvs||5.013006|
2585 sv_setref_pvs||5.019003|
24402586 sv_setref_pv|||
24412587 sv_setref_uv||5.007001|
24422588 sv_setsv_cow|||
24692615 sv_utf8_upgrade||5.007001|
24702616 sv_uv|5.005000||p
24712617 sv_vcatpvf_mg|5.006000|5.004000|p
2618 sv_vcatpvfn_flags||5.017002|
24722619 sv_vcatpvfn||5.004000|
24732620 sv_vcatpvf|5.006000|5.004000|p
24742621 sv_vsetpvf_mg|5.006000|5.004000|p
24782625 svtype|||
24792626 swallow_bom|||
24802627 swash_fetch||5.007002|
2481 swash_get|||
24822628 swash_init||5.006000|
2629 swatch_get|||
24832630 sys_init3||5.010000|n
24842631 sys_init||5.010000|n
24852632 sys_intern_clear|||
24902637 taint_proper|||
24912638 tied_method|||v
24922639 tmps_grow||5.006000|
2640 toFOLD_uni||5.007003|
2641 toFOLD_utf8||5.019001|
2642 toFOLD||5.019001|
2643 toLOWER_L1||5.019001|
2644 toLOWER_LC||5.004000|
2645 toLOWER_uni||5.007003|
2646 toLOWER_utf8||5.015007|
24932647 toLOWER|||
2494 toUPPER|||
2648 toTITLE_uni||5.007003|
2649 toTITLE_utf8||5.015007|
2650 toTITLE||5.019001|
2651 toUPPER_uni||5.007003|
2652 toUPPER_utf8||5.015007|
2653 toUPPER||5.004000|
24952654 to_byte_substr|||
2655 to_lower_latin1|||
24962656 to_uni_fold||5.007003|
24972657 to_uni_lower_lc||5.006000|
24982658 to_uni_lower||5.007003|
25012661 to_uni_upper_lc||5.006000|
25022662 to_uni_upper||5.007003|
25032663 to_utf8_case||5.007003|
2504 to_utf8_fold||5.007003|
2505 to_utf8_lower||5.007003|
2664 to_utf8_fold||5.015007|
2665 to_utf8_lower||5.015007|
25062666 to_utf8_substr|||
2507 to_utf8_title||5.007003|
2508 to_utf8_upper||5.007003|
2667 to_utf8_title||5.015007|
2668 to_utf8_upper||5.015007|
25092669 token_free|||
25102670 token_getmad|||
25112671 tokenize_use|||
25122672 tokeq|||
25132673 tokereport|||
2514 too_few_arguments|||
2515 too_many_arguments|||
2674 too_few_arguments_pv|||
2675 too_few_arguments_sv|||
2676 too_many_arguments_pv|||
2677 too_many_arguments_sv|||
2678 translate_substr_offsets|||
25162679 try_amagic_bin|||
25172680 try_amagic_un|||
25182681 uiv_2buf|||n
25372700 utf8_mg_len_cache_update|||
25382701 utf8_mg_pos_cache_update|||
25392702 utf8_to_bytes||5.006001|
2703 utf8_to_uvchr_buf||5.015009|
25402704 utf8_to_uvchr||5.007001|
2705 utf8_to_uvuni_buf||5.015009|
25412706 utf8_to_uvuni||5.007001|
25422707 utf8n_to_uvchr|||
25432708 utf8n_to_uvuni||5.007001|
25462711 uvchr_to_utf8|||
25472712 uvuni_to_utf8_flags||5.007003|
25482713 uvuni_to_utf8||5.007001|
2714 valid_utf8_to_uvchr|||
2715 valid_utf8_to_uvuni||5.015009|
2716 validate_proto|||
25492717 validate_suid|||
25502718 varname|||
25512719 vcmp||5.009000|
25702738 warner_nocontext|||vn
25712739 warner|5.006000|5.004000|pv
25722740 warn|||v
2741 was_lvalue_sub|||
25732742 watch|||
2743 whichsig_pvn||5.015004|
2744 whichsig_pv||5.015004|
2745 whichsig_sv||5.015004|
25742746 whichsig|||
2747 win32_croak_not_implemented|||n
25752748 with_queued_errors|||
2576 write_no_mem|||
2749 wrap_op_checker||5.015008|
25772750 write_to_stderr|||
25782751 xmldump_all_perl|||
25792752 xmldump_all|||
25882761 xmldump_vindent|||
25892762 xs_apiversion_bootcheck|||
25902763 xs_version_bootcheck|||
2764 yyerror_pvn|||
2765 yyerror_pv|||
25912766 yyerror|||
25922767 yylex|||
25932768 yyparse|||
36953870 # define IVSIZE 8
36963871 #endif
36973872
3873 #ifndef LONGSIZE
3874 # define LONGSIZE 8
3875 #endif
3876
36983877 #ifndef PERL_QUAD_MIN
36993878 # define PERL_QUAD_MIN IV_MIN
37003879 #endif
37143893 #else
37153894 #ifndef IVTYPE
37163895 # define IVTYPE long
3896 #endif
3897
3898 #ifndef LONGSIZE
3899 # define LONGSIZE 4
37173900 #endif
37183901
37193902 #ifndef IV_MIN
39974180 #undef STMT_START
39984181 #undef STMT_END
39994182 #ifdef PERL_USE_GCC_BRACE_GROUPS
4000 # define STMT_START (void)( /* gcc supports ``({ STATEMENTS; })'' */
4001 # define STMT_END )
4183 # define STMT_START (void)( /* gcc supports ``({ STATEMENTS; })'' */
4184 # define STMT_END )
40024185 #else
40034186 # if defined(VOIDFLAGS) && (VOIDFLAGS) && (defined(sun) || defined(__sun__)) && !defined(__GNUC__)
4004 # define STMT_START if (1)
4005 # define STMT_END else (void)0
4187 # define STMT_START if (1)
4188 # define STMT_END else (void)0
40064189 # else
4007 # define STMT_START do
4008 # define STMT_END while (0)
4190 # define STMT_START do
4191 # define STMT_END while (0)
40094192 # endif
40104193 #endif
40114194 #ifndef boolSV
41184301 #endif
41194302 #ifndef PERL_HASH
41204303 # define PERL_HASH(hash,str,len) \
4121 STMT_START { \
4122 const char *s_PeRlHaSh = str; \
4123 I32 i_PeRlHaSh = len; \
4124 U32 hash_PeRlHaSh = 0; \
4125 while (i_PeRlHaSh--) \
4126 hash_PeRlHaSh = hash_PeRlHaSh * 33 + *s_PeRlHaSh++; \
4127 (hash) = hash_PeRlHaSh; \
4304 STMT_START { \
4305 const char *s_PeRlHaSh = str; \
4306 I32 i_PeRlHaSh = len; \
4307 U32 hash_PeRlHaSh = 0; \
4308 while (i_PeRlHaSh--) \
4309 hash_PeRlHaSh = hash_PeRlHaSh * 33 + *s_PeRlHaSh++; \
4310 (hash) = hash_PeRlHaSh; \
41284311 } STMT_END
41294312 #endif
41304313
41964379 */
41974380 # undef isPRINT
41984381 # endif
4382
4383 #ifdef HAS_QUAD
4384 # define WIDEST_UTYPE U64TYPE
4385 #else
4386 # define WIDEST_UTYPE U32
4387 #endif
41994388 #ifndef isALNUMC
42004389 # define isALNUMC(c) (isALPHA(c) || isDIGIT(c))
42014390 #endif
42024391
42034392 #ifndef isASCII
4204 # define isASCII(c) ((U8) (c) <= 127)
4393 # define isASCII(c) ((WIDEST_UTYPE) (c) <= 127)
42054394 #endif
42064395
42074396 #ifndef isCNTRL
4208 # define isCNTRL(c) ((U8) (c) < ' ' || (c) == 127)
4397 # define isCNTRL(c) ((WIDEST_UTYPE) (c) < ' ' || (c) == 127)
42094398 #endif
42104399
42114400 #ifndef isGRAPH
44594648 #endif
44604649
44614650 #ifndef G_METHOD
4462 # define G_METHOD 64
4651 # define G_METHOD 64
44634652 # ifdef call_sv
44644653 # undef call_sv
44654654 # endif
44664655 # if (PERL_BCDVERSION < 0x5006000)
44674656 # define call_sv(sv, flags) ((flags) & G_METHOD ? perl_call_method((char *) SvPV_nolen_const(sv), \
4468 (flags) & ~G_METHOD) : perl_call_sv(sv, flags))
4657 (flags) & ~G_METHOD) : perl_call_sv(sv, flags))
44694658 # else
44704659 # define call_sv(sv, flags) ((flags) & G_METHOD ? Perl_call_method(aTHX_ (char *) SvPV_nolen_const(sv), \
4471 (flags) & ~G_METHOD) : Perl_call_sv(aTHX_ sv, flags))
4660 (flags) & ~G_METHOD) : Perl_call_sv(aTHX_ sv, flags))
44724661 # endif
44734662 #endif
44744663
45054694 PUTBACK;
45064695
45074696 if (croak_on_error && SvTRUE(GvSV(errgv)))
4508 croak(SvPVx(GvSV(errgv), na));
4697 croak(SvPVx(GvSV(errgv), na));
45094698
45104699 return sv;
45114700 }
45454734 SvREADONLY_off(((SVOP*)modname)->op_sv);
45464735 modname->op_private |= OPpCONST_BARE;
45474736 if (ver) {
4548 veop = newSVOP(OP_CONST, 0, ver);
4737 veop = newSVOP(OP_CONST, 0, ver);
45494738 }
45504739 else
4551 veop = NULL;
4740 veop = NULL;
45524741 if (flags & PERL_LOADMOD_NOIMPORT) {
4553 imop = sawparens(newNULLLIST());
4742 imop = sawparens(newNULLLIST());
45544743 }
45554744 else if (flags & PERL_LOADMOD_IMPORT_OPS) {
4556 imop = va_arg(*args, OP*);
4745 imop = va_arg(*args, OP*);
45574746 }
45584747 else {
4559 SV *sv;
4560 imop = NULL;
4561 sv = va_arg(*args, SV*);
4562 while (sv) {
4563 imop = append_elem(OP_LIST, imop, newSVOP(OP_CONST, 0, sv));
4564 sv = va_arg(*args, SV*);
4565 }
4748 SV *sv;
4749 imop = NULL;
4750 sv = va_arg(*args, SV*);
4751 while (sv) {
4752 imop = append_elem(OP_LIST, imop, newSVOP(OP_CONST, 0, sv));
4753 sv = va_arg(*args, SV*);
4754 }
45664755 }
45674756 {
4568 const line_t ocopline = PL_copline;
4569 COP * const ocurcop = PL_curcop;
4570 const int oexpect = PL_expect;
4757 const line_t ocopline = PL_copline;
4758 COP * const ocurcop = PL_curcop;
4759 const int oexpect = PL_expect;
45714760
45724761 #if (PERL_BCDVERSION >= 0x5004000)
4573 utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(FALSE, 0),
4574 veop, modname, imop);
4762 utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(FALSE, 0),
4763 veop, modname, imop);
45754764 #else
4576 utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(),
4577 modname, imop);
4578 #endif
4579 PL_expect = oexpect;
4580 PL_copline = ocopline;
4581 PL_curcop = ocurcop;
4765 utilize(!(flags & PERL_LOADMOD_DENY), start_subparse(),
4766 modname, imop);
4767 #endif
4768 PL_expect = oexpect;
4769 PL_copline = ocopline;
4770 PL_curcop = ocurcop;
45824771 }
45834772 }
45844773
46704859 void
46714860 DPPP_(my_newCONSTSUB)(HV *stash, const char *name, SV *sv)
46724861 {
4673 U32 oldhints = PL_hints;
4674 HV *old_cop_stash = PL_curcop->cop_stash;
4675 HV *old_curstash = PL_curstash;
4676 line_t oldline = PL_curcop->cop_line;
4677 PL_curcop->cop_line = D_PPP_PL_copline;
4678
4679 PL_hints &= ~HINT_BLOCK_SCOPE;
4680 if (stash)
4681 PL_curstash = PL_curcop->cop_stash = stash;
4682
4683 newSUB(
4862 U32 oldhints = PL_hints;
4863 HV *old_cop_stash = PL_curcop->cop_stash;
4864 HV *old_curstash = PL_curstash;
4865 line_t oldline = PL_curcop->cop_line;
4866 PL_curcop->cop_line = D_PPP_PL_copline;
4867
4868 PL_hints &= ~HINT_BLOCK_SCOPE;
4869 if (stash)
4870 PL_curstash = PL_curcop->cop_stash = stash;
4871
4872 newSUB(
46844873
46854874 #if (PERL_BCDVERSION < 0x5003022)
4686 start_subparse(),
4875 start_subparse(),
46874876 #elif (PERL_BCDVERSION == 0x5003022)
4688 start_subparse(0),
4877 start_subparse(0),
46894878 #else /* 5.003_23 onwards */
4690 start_subparse(FALSE, 0),
4691 #endif
4692
4693 newSVOP(OP_CONST, 0, newSVpv((char *) name, 0)),
4694 newSVOP(OP_CONST, 0, &PL_sv_no), /* SvPV(&PL_sv_no) == "" -- GMB */
4695 newSTATEOP(0, Nullch, newSVOP(OP_CONST, 0, sv))
4696 );
4697
4698 PL_hints = oldhints;
4699 PL_curcop->cop_stash = old_cop_stash;
4700 PL_curstash = old_curstash;
4701 PL_curcop->cop_line = oldline;
4879 start_subparse(FALSE, 0),
4880 #endif
4881
4882 newSVOP(OP_CONST, 0, newSVpv((char *) name, 0)),
4883 newSVOP(OP_CONST, 0, &PL_sv_no), /* SvPV(&PL_sv_no) == "" -- GMB */
4884 newSTATEOP(0, Nullch, newSVOP(OP_CONST, 0, sv))
4885 );
4886
4887 PL_hints = oldhints;
4888 PL_curcop->cop_stash = old_cop_stash;
4889 PL_curstash = old_curstash;
4890 PL_curcop->cop_line = oldline;
47024891 }
47034892 #endif
47044893 #endif
47354924 #if (PERL_BCDVERSION < 0x5004068)
47364925 /* Fetches the SV that keeps the per-interpreter data. */
47374926 #define dMY_CXT_SV \
4738 SV *my_cxt_sv = get_sv(MY_CXT_KEY, FALSE)
4927 SV *my_cxt_sv = get_sv(MY_CXT_KEY, FALSE)
47394928 #else /* >= perl5.004_68 */
47404929 #define dMY_CXT_SV \
4741 SV *my_cxt_sv = *hv_fetch(PL_modglobal, MY_CXT_KEY, \
4742 sizeof(MY_CXT_KEY)-1, TRUE)
4930 SV *my_cxt_sv = *hv_fetch(PL_modglobal, MY_CXT_KEY, \
4931 sizeof(MY_CXT_KEY)-1, TRUE)
47434932 #endif /* < perl5.004_68 */
47444933
47454934 /* This declaration should be used within all functions that use the
47464935 * interpreter-local data. */
4747 #define dMY_CXT \
4748 dMY_CXT_SV; \
4749 my_cxt_t *my_cxtp = INT2PTR(my_cxt_t*,SvUV(my_cxt_sv))
4936 #define dMY_CXT \
4937 dMY_CXT_SV; \
4938 my_cxt_t *my_cxtp = INT2PTR(my_cxt_t*,SvUV(my_cxt_sv))
47504939
47514940 /* Creates and zeroes the per-interpreter data.
47524941 * (We allocate my_cxtp in a Perl SV so that it will be released when
47534942 * the interpreter goes away.) */
47544943 #define MY_CXT_INIT \
4755 dMY_CXT_SV; \
4756 /* newSV() allocates one more than needed */ \
4757 my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\
4758 Zero(my_cxtp, 1, my_cxt_t); \
4759 sv_setuv(my_cxt_sv, PTR2UV(my_cxtp))
4944 dMY_CXT_SV; \
4945 /* newSV() allocates one more than needed */ \
4946 my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\
4947 Zero(my_cxtp, 1, my_cxt_t); \
4948 sv_setuv(my_cxt_sv, PTR2UV(my_cxtp))
47604949
47614950 /* This macro must be used to access members of the my_cxt_t structure.
47624951 * e.g. MYCXT.some_data */
4763 #define MY_CXT (*my_cxtp)
4952 #define MY_CXT (*my_cxtp)
47644953
47654954 /* Judicious use of these macros can reduce the number of times dMY_CXT
47664955 * is used. Use is similar to pTHX, aTHX etc. */
4767 #define pMY_CXT my_cxt_t *my_cxtp
4768 #define pMY_CXT_ pMY_CXT,
4769 #define _pMY_CXT ,pMY_CXT
4770 #define aMY_CXT my_cxtp
4771 #define aMY_CXT_ aMY_CXT,
4772 #define _aMY_CXT ,aMY_CXT
4956 #define pMY_CXT my_cxt_t *my_cxtp
4957 #define pMY_CXT_ pMY_CXT,
4958 #define _pMY_CXT ,pMY_CXT
4959 #define aMY_CXT my_cxtp
4960 #define aMY_CXT_ aMY_CXT,
4961 #define _aMY_CXT ,aMY_CXT
47734962
47744963 #endif /* START_MY_CXT */
47754964
47764965 #ifndef MY_CXT_CLONE
47774966 /* Clones the per-interpreter data. */
47784967 #define MY_CXT_CLONE \
4779 dMY_CXT_SV; \
4780 my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\
4781 Copy(INT2PTR(my_cxt_t*, SvUV(my_cxt_sv)), my_cxtp, 1, my_cxt_t);\
4782 sv_setuv(my_cxt_sv, PTR2UV(my_cxtp))
4968 dMY_CXT_SV; \
4969 my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\
4970 Copy(INT2PTR(my_cxt_t*, SvUV(my_cxt_sv)), my_cxtp, 1, my_cxt_t);\
4971 sv_setuv(my_cxt_sv, PTR2UV(my_cxtp))
47834972 #endif
47844973
47854974 #else /* single interpreter */
47864975
47874976 #ifndef START_MY_CXT
47884977
4789 #define START_MY_CXT static my_cxt_t my_cxt;
4790 #define dMY_CXT_SV dNOOP
4791 #define dMY_CXT dNOOP
4792 #define MY_CXT_INIT NOOP
4793 #define MY_CXT my_cxt
4794
4795 #define pMY_CXT void
4978 #define START_MY_CXT static my_cxt_t my_cxt;
4979 #define dMY_CXT_SV dNOOP
4980 #define dMY_CXT dNOOP
4981 #define MY_CXT_INIT NOOP
4982 #define MY_CXT my_cxt
4983
4984 #define pMY_CXT void
47964985 #define pMY_CXT_
47974986 #define _pMY_CXT
47984987 #define aMY_CXT
48024991 #endif /* START_MY_CXT */
48034992
48044993 #ifndef MY_CXT_CLONE
4805 #define MY_CXT_CLONE NOOP
4994 #define MY_CXT_CLONE NOOP
48064995 #endif
48074996
48084997 #endif
48094998
48104999 #ifndef IVdf
48115000 # if IVSIZE == LONGSIZE
4812 # define IVdf "ld"
4813 # define UVuf "lu"
4814 # define UVof "lo"
4815 # define UVxf "lx"
4816 # define UVXf "lX"
5001 # define IVdf "ld"
5002 # define UVuf "lu"
5003 # define UVof "lo"
5004 # define UVxf "lx"
5005 # define UVXf "lX"
5006 # elif IVSIZE == INTSIZE
5007 # define IVdf "d"
5008 # define UVuf "u"
5009 # define UVof "o"
5010 # define UVxf "x"
5011 # define UVXf "X"
48175012 # else
4818 # if IVSIZE == INTSIZE
4819 # define IVdf "d"
4820 # define UVuf "u"
4821 # define UVof "o"
4822 # define UVxf "x"
4823 # define UVXf "X"
4824 # endif
5013 # error "cannot define IV/UV formats"
48255014 # endif
48265015 #endif
48275016
48415030
48425031 #ifndef SvREFCNT_inc
48435032 # ifdef PERL_USE_GCC_BRACE_GROUPS
4844 # define SvREFCNT_inc(sv) \
4845 ({ \
4846 SV * const _sv = (SV*)(sv); \
4847 if (_sv) \
4848 (SvREFCNT(_sv))++; \
4849 _sv; \
5033 # define SvREFCNT_inc(sv) \
5034 ({ \
5035 SV * const _sv = (SV*)(sv); \
5036 if (_sv) \
5037 (SvREFCNT(_sv))++; \
5038 _sv; \
48505039 })
48515040 # else
4852 # define SvREFCNT_inc(sv) \
5041 # define SvREFCNT_inc(sv) \
48535042 ((PL_Sv=(SV*)(sv)) ? (++(SvREFCNT(PL_Sv)),PL_Sv) : NULL)
48545043 # endif
48555044 #endif
48565045
48575046 #ifndef SvREFCNT_inc_simple
48585047 # ifdef PERL_USE_GCC_BRACE_GROUPS
4859 # define SvREFCNT_inc_simple(sv) \
4860 ({ \
4861 if (sv) \
4862 (SvREFCNT(sv))++; \
4863 (SV *)(sv); \
5048 # define SvREFCNT_inc_simple(sv) \
5049 ({ \
5050 if (sv) \
5051 (SvREFCNT(sv))++; \
5052 (SV *)(sv); \
48645053 })
48655054 # else
48665055 # define SvREFCNT_inc_simple(sv) \
48705059
48715060 #ifndef SvREFCNT_inc_NN
48725061 # ifdef PERL_USE_GCC_BRACE_GROUPS
4873 # define SvREFCNT_inc_NN(sv) \
4874 ({ \
4875 SV * const _sv = (SV*)(sv); \
4876 SvREFCNT(_sv)++; \
4877 _sv; \
5062 # define SvREFCNT_inc_NN(sv) \
5063 ({ \
5064 SV * const _sv = (SV*)(sv); \
5065 SvREFCNT(_sv)++; \
5066 _sv; \
48785067 })
48795068 # else
48805069 # define SvREFCNT_inc_NN(sv) \
48845073
48855074 #ifndef SvREFCNT_inc_void
48865075 # ifdef PERL_USE_GCC_BRACE_GROUPS
4887 # define SvREFCNT_inc_void(sv) \
4888 ({ \
4889 SV * const _sv = (SV*)(sv); \
4890 if (_sv) \
4891 (void)(SvREFCNT(_sv)++); \
5076 # define SvREFCNT_inc_void(sv) \
5077 ({ \
5078 SV * const _sv = (SV*)(sv); \
5079 if (_sv) \
5080 (void)(SvREFCNT(_sv)++); \
48925081 })
48935082 # else
48945083 # define SvREFCNT_inc_void(sv) \
52475436
52485437 #ifndef SvPV_nomg_const_nolen
52495438 # define SvPV_nomg_const_nolen(sv) SvPV_flags_const_nolen(sv, 0)
5439 #endif
5440
5441 #ifndef SvPV_nomg_nolen
5442 # define SvPV_nomg_nolen(sv) ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \
5443 ? SvPVX(sv) : sv_2pv_flags(sv, DPPP_SVPV_NOLEN_LP_ARG, 0))
52505444 #endif
52515445 #ifndef SvPV_renew
52525446 # define SvPV_renew(sv,n) STMT_START { SvLEN_set(sv, n); \
61916385
61926386 #ifndef CopSTASH_eq
61936387 # define CopSTASH_eq(c,hv) ((hv) && (CopSTASHPV(c) == HvNAME(hv) \
6194 || (CopSTASHPV(c) && HvNAME(hv) \
6195 && strEQ(CopSTASHPV(c), HvNAME(hv)))))
6388 || (CopSTASHPV(c) && HvNAME(hv) \
6389 && strEQ(CopSTASHPV(c), HvNAME(hv)))))
61966390 #endif
61976391
61986392 #else
64166610 digit = *s - '0';
64176611 if (digit >= 0 && digit <= 9) {
64186612 value = value * 10 + digit;
6419 if (++s < send) {
6613 if (++s < send) {
64206614 digit = *s - '0';
64216615 if (digit >= 0 && digit <= 9) {
64226616 value = value * 10 + digit;
64646658 }
64656659 }
64666660 }
6467 }
6661 }
64686662 }
64696663 }
64706664 }
64766670 }
64776671 }
64786672 }
6479 }
6673 }
64806674 }
64816675 }
64826676 numtype |= IS_NUMBER_IN_UV;
66296823 value_nv = (NV) value;
66306824 }
66316825 value_nv *= 2.0;
6632 /* If an NV has not enough bits in its mantissa to
6633 * represent a UV this summing of small low-order numbers
6634 * is a waste of time (because the NV cannot preserve
6635 * the low-order bits anyway): we could just remember when
6636 * did we overflow and in the end just multiply value_nv by the
6637 * right amount. */
6826 /* If an NV has not enough bits in its mantissa to
6827 * represent a UV this summing of small low-order numbers
6828 * is a waste of time (because the NV cannot preserve
6829 * the low-order bits anyway): we could just remember when
6830 * did we overflow and in the end just multiply value_nv by the
6831 * right amount. */
66386832 value_nv += (NV)(bit - '0');
66396833 continue;
66406834 }
66416835 if (bit == '_' && len && allow_underscores && (bit = s[1])
66426836 && (bit == '0' || bit == '1'))
6643 {
6644 --len;
6645 ++s;
6837 {
6838 --len;
6839 ++s;
66466840 goto redo;
6647 }
6841 }
66486842 if (!(*flags & PERL_SCAN_SILENT_ILLDIGIT))
66496843 warn("Illegal binary digit '%c' ignored", *s);
66506844 break;
66526846
66536847 if ( ( overflowed && value_nv > 4294967295.0)
66546848 #if UVSIZE > 4
6655 || (!overflowed && value > 0xffffffff )
6656 #endif
6657 ) {
6658 warn("Binary number > 0b11111111111111111111111111111111 non-portable");
6849 || (!overflowed && value > 0xffffffff )
6850 #endif
6851 ) {
6852 warn("Binary number > 0b11111111111111111111111111111111 non-portable");
66596853 }
66606854 *len_p = s - start;
66616855 if (!overflowed) {
67156909 }
67166910
67176911 for (; len-- && *s; s++) {
6718 xdigit = strchr((char *) PL_hexdigit, *s);
6912 xdigit = strchr((char *) PL_hexdigit, *s);
67196913 if (xdigit) {
67206914 /* Write it in this wonky order with a goto to attempt to get the
67216915 compiler to make the common case integer-only loop pretty tight.
67316925 value_nv = (NV) value;
67326926 }
67336927 value_nv *= 16.0;
6734 /* If an NV has not enough bits in its mantissa to
6735 * represent a UV this summing of small low-order numbers
6736 * is a waste of time (because the NV cannot preserve
6737 * the low-order bits anyway): we could just remember when
6738 * did we overflow and in the end just multiply value_nv by the
6739 * right amount of 16-tuples. */
6928 /* If an NV has not enough bits in its mantissa to
6929 * represent a UV this summing of small low-order numbers
6930 * is a waste of time (because the NV cannot preserve
6931 * the low-order bits anyway): we could just remember when
6932 * did we overflow and in the end just multiply value_nv by the
6933 * right amount of 16-tuples. */
67406934 value_nv += (NV)((xdigit - PL_hexdigit) & 15);
67416935 continue;
67426936 }
67436937 if (*s == '_' && len && allow_underscores && s[1]
6744 && (xdigit = strchr((char *) PL_hexdigit, s[1])))
6745 {
6746 --len;
6747 ++s;
6938 && (xdigit = strchr((char *) PL_hexdigit, s[1])))
6939 {
6940 --len;
6941 ++s;
67486942 goto redo;
6749 }
6943 }
67506944 if (!(*flags & PERL_SCAN_SILENT_ILLDIGIT))
67516945 warn("Illegal hexadecimal digit '%c' ignored", *s);
67526946 break;
67546948
67556949 if ( ( overflowed && value_nv > 4294967295.0)
67566950 #if UVSIZE > 4
6757 || (!overflowed && value > 0xffffffff )
6758 #endif
6759 ) {
6760 warn("Hexadecimal number > 0xffffffff non-portable");
6951 || (!overflowed && value > 0xffffffff )
6952 #endif
6953 ) {
6954 warn("Hexadecimal number > 0xffffffff non-portable");
67616955 }
67626956 *len_p = s - start;
67636957 if (!overflowed) {
68197013 value_nv = (NV) value;
68207014 }
68217015 value_nv *= 8.0;
6822 /* If an NV has not enough bits in its mantissa to
6823 * represent a UV this summing of small low-order numbers
6824 * is a waste of time (because the NV cannot preserve
6825 * the low-order bits anyway): we could just remember when
6826 * did we overflow and in the end just multiply value_nv by the
6827 * right amount of 8-tuples. */
7016 /* If an NV has not enough bits in its mantissa to
7017 * represent a UV this summing of small low-order numbers
7018 * is a waste of time (because the NV cannot preserve
7019 * the low-order bits anyway): we could just remember when
7020 * did we overflow and in the end just multiply value_nv by the
7021 * right amount of 8-tuples. */
68287022 value_nv += (NV)digit;
68297023 continue;
68307024 }
68317025 if (digit == ('_' - '0') && len && allow_underscores
68327026 && (digit = s[1] - '0') && (digit >= 0 && digit <= 7))
6833 {
6834 --len;
6835 ++s;
7027 {
7028 --len;
7029 ++s;
68367030 goto redo;
6837 }
7031 }
68387032 /* Allow \octal to work the DWIM way (that is, stop scanning
68397033 * as soon as non-octal characters are seen, complain only iff
68407034 * someone seems to want to use the digits eight and nine). */
68477041
68487042 if ( ( overflowed && value_nv > 4294967295.0)
68497043 #if UVSIZE > 4
6850 || (!overflowed && value > 0xffffffff )
6851 #endif
6852 ) {
6853 warn("Octal number > 037777777777 non-portable");
7044 || (!overflowed && value > 0xffffffff )
7045 #endif
7046 ) {
7047 warn("Octal number > 037777777777 non-portable");
68547048 }
68557049 *len_p = s - start;
68567050 if (!overflowed) {
68927086 #endif
68937087 va_end(ap);
68947088 if (retval < 0 || (len > 0 && (Size_t)retval >= len))
6895 Perl_croak(aTHX_ "panic: my_snprintf buffer overflow");
7089 Perl_croak(aTHX_ "panic: my_snprintf buffer overflow");
68967090 return retval;
68977091 }
68987092
70967290 octbuf[0] = esc;
70977291
70987292 if (!(flags & PERL_PV_ESCAPE_NOCLEAR))
7099 sv_setpvs(dsv, "");
7293 sv_setpvs(dsv, "");
71007294
71017295 #if defined(is_utf8_string) && defined(utf8_to_uvchr)
71027296 if ((flags & PERL_PV_ESCAPE_UNI_DETECT) && is_utf8_string((U8*)pv, count))
71067300 for (; pv < end && (!max || wrote < max) ; pv += readsize) {
71077301 const UV u =
71087302 #if defined(is_utf8_string) && defined(utf8_to_uvchr)
7109 isuni ? utf8_to_uvchr((U8*)pv, &readsize) :
7110 #endif
7111 (U8)*pv;
7303 isuni ? utf8_to_uvchr((U8*)pv, &readsize) :
7304 #endif
7305 (U8)*pv;
71127306 const U8 c = (U8)u & 0xFF;
71137307
71147308 if (u > 255 || (flags & PERL_PV_ESCAPE_ALL)) {
71227316 chsize = 1;
71237317 } else {
71247318 if (c == dq || c == esc || !isPRINT(c)) {
7125 chsize = 2;
7319 chsize = 2;
71267320 switch (c) {
7127 case '\\' : /* fallthrough */
7128 case '%' : if (c == esc)
7129 octbuf[1] = esc;
7130 else
7131 chsize = 1;
7132 break;
7133 case '\v' : octbuf[1] = 'v'; break;
7134 case '\t' : octbuf[1] = 't'; break;
7135 case '\r' : octbuf[1] = 'r'; break;
7136 case '\n' : octbuf[1] = 'n'; break;
7137 case '\f' : octbuf[1] = 'f'; break;
7321 case '\\' : /* fallthrough */
7322 case '%' : if (c == esc)
7323 octbuf[1] = esc;
7324 else
7325 chsize = 1;
7326 break;
7327 case '\v' : octbuf[1] = 'v'; break;
7328 case '\t' : octbuf[1] = 't'; break;
7329 case '\r' : octbuf[1] = 'r'; break;
7330 case '\n' : octbuf[1] = 'n'; break;
7331 case '\f' : octbuf[1] = 'f'; break;
71387332 case '"' : if (dq == '"')
7139 octbuf[1] = '"';
7140 else
7141 chsize = 1;
7142 break;
7143 default: chsize = my_snprintf(octbuf, sizeof octbuf,
7144 pv < end && isDIGIT((U8)*(pv+readsize))
7145 ? "%c%03o" : "%c%o", esc, c);
7333 octbuf[1] = '"';
7334 else
7335 chsize = 1;
7336 break;
7337 default: chsize = my_snprintf(octbuf, sizeof octbuf,
7338 pv < end && isDIGIT((U8)*(pv+readsize))
7339 ? "%c%03o" : "%c%o", esc, c);
71467340 }
71477341 } else {
71487342 chsize = 1;
71497343 }
7150 }
7151 if (max && wrote + chsize > max) {
7152 break;
7344 }
7345 if (max && wrote + chsize > max) {
7346 break;
71537347 } else if (chsize > 1) {
71547348 sv_catpvn(dsv, octbuf, chsize);
71557349 wrote += chsize;
7156 } else {
7157 char tmp[2];
7158 my_snprintf(tmp, sizeof tmp, "%c", c);
7350 } else {
7351 char tmp[2];
7352 my_snprintf(tmp, sizeof tmp, "%c", c);
71597353 sv_catpvn(dsv, tmp, 1);
7160 wrote++;
7161 }
7354 wrote++;
7355 }
71627356 if (flags & PERL_PV_ESCAPE_FIRSTCHAR)
71637357 break;
71647358 }
71957389 STRLEN escaped;
71967390
71977391 if (!(flags & PERL_PV_PRETTY_NOCLEAR))
7198 sv_setpvs(dsv, "");
7392 sv_setpvs(dsv, "");
71997393
72007394 if (dq == '"')
72017395 sv_catpvs(dsv, "\"");
72117405 sv_catpv(dsv, D_PPP_CONSTPV_ARG(end_color));
72127406
72137407 if (dq == '"')
7214 sv_catpvs(dsv, "\"");
7408 sv_catpvs(dsv, "\"");
72157409 else if (flags & PERL_PV_PRETTY_LTGT)
72167410 sv_catpvs(dsv, ">");
72177411
72187412 if ((flags & PERL_PV_PRETTY_ELLIPSES) && escaped < count)
7219 sv_catpvs(dsv, "...");
7413 sv_catpvs(dsv, "...");
72207414
72217415 return SvPVX(dsv);
72227416 }
72457439 {
72467440 pv_pretty(dsv, pv, cur, pvlim, NULL, NULL, PERL_PV_PRETTY_DUMP);
72477441 if (len > cur && pv[cur] == '\0')
7248 sv_catpvs(dsv, "\\0");
7442 sv_catpvs(dsv, "\\0");
72497443 return SvPVX(dsv);
72507444 }
72517445
212212 int x;
213213 ulong64 A, B;
214214
215 // LTC_ARGCHK(key != NULL);
216 // LTC_ARGCHK(skey != NULL);
215 /*
216 LTC_ARGCHK(key != NULL);
217 LTC_ARGCHK(skey != NULL);
218 */
217219
218220 /* Valid sizes (in bytes) are 16, 24, 32 */
219221 if (keylen != 16 && keylen != 24 && keylen != 32) {
618620 L ^= F(R ^ skey->camellia.k[1]);
619621 R ^= F(L ^ skey->camellia.k[0]);
620622
621 L ^= skey->camellia.kw[1];
622 R ^= skey->camellia.kw[0];
623
624 STORE64H(R, pt+0); STORE64H(L, pt+8);
623 R ^= skey->camellia.kw[1];
624 L ^= skey->camellia.kw[0];
625
626 STORE64H(R, pt+8); STORE64H(L, pt+0);
625627
626628 return CRYPT_OK;
627629 }
3232
3333 int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
3434 {
35 unsigned long x, sum, K[4];
35 ulong32 x, sum, K[4];
3636
3737 LTC_ARGCHK(key != NULL);
3838 LTC_ARGCHK(skey != NULL);
7474 */
7575 int xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
7676 {
77 unsigned long y, z;
77 ulong32 y, z;
7878 int r;
7979
8080 LTC_ARGCHK(pt != NULL);
110110 */
111111 int xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
112112 {
113 unsigned long y, z;
113 ulong32 y, z;
114114 int r;
115115
116116 LTC_ARGCHK(pt != NULL);
171171 }
172172
173173 } else {
174 // B_0 != NULL
174 /* B_0 != NULL */
175175 XMEMCPY(PAD, B_0, 16);
176176 }
177177
5555 */
5656
5757 /* detect x86-32 machines somewhat */
58 #if !defined(__STRICT_ANSI__) && !defined(_WIN64) && (defined(INTEL_CC) || (defined(_MSC_VER) && defined(WIN32)) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__))))
58 #if !defined(__STRICT_ANSI__) && !defined(__x86_64__) && !defined(_WIN64) && (defined(INTEL_CC) || (defined(_MSC_VER) && defined(WIN32)) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__))))
5959 #define ENDIAN_LITTLE
6060 #define ENDIAN_32BITWORD
6161 #define LTC_FAST
349349 /* #define LTC_MECC_FP */
350350
351351 /* Timing Resistant? */
352 /* #define LTC_ECC_TIMING_RESISTANT */
352 #define LTC_ECC_TIMING_RESISTANT
353353
354354 #endif /* LTC_NO_PK */
355355
262262
263263 #elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && !defined(INTEL_CC) && !defined(LTC_NO_ASM)
264264
265 static inline unsigned ROL(unsigned word, int i)
265 static inline ulong32 ROL(ulong32 word, int i)
266266 {
267267 asm ("roll %%cl,%0"
268268 :"=r" (word)
270270 return word;
271271 }
272272
273 static inline unsigned ROR(unsigned word, int i)
273 static inline ulong32 ROR(ulong32 word, int i)
274274 {
275275 asm ("rorl %%cl,%0"
276276 :"=r" (word)
280280
281281 #ifndef LTC_NO_ROLC
282282
283 static inline unsigned ROLc(unsigned word, const int i)
283 static inline ulong32 ROLc(ulong32 word, const int i)
284284 {
285285 asm ("roll %2,%0"
286286 :"=r" (word)
288288 return word;
289289 }
290290
291 static inline unsigned RORc(unsigned word, const int i)
291 static inline ulong32 RORc(ulong32 word, const int i)
292292 {
293293 asm ("rorl %2,%0"
294294 :"=r" (word)
305305
306306 #elif !defined(__STRICT_ANSI__) && defined(LTC_PPC32)
307307
308 static inline unsigned ROL(unsigned word, int i)
308 static inline ulong32 ROL(ulong32 word, int i)
309309 {
310310 asm ("rotlw %0,%0,%2"
311311 :"=r" (word)
313313 return word;
314314 }
315315
316 static inline unsigned ROR(unsigned word, int i)
316 static inline ulong32 ROR(ulong32 word, int i)
317317 {
318318 asm ("rotlw %0,%0,%2"
319319 :"=r" (word)
323323
324324 #ifndef LTC_NO_ROLC
325325
326 static inline unsigned ROLc(unsigned word, const int i)
326 static inline ulong32 ROLc(ulong32 word, const int i)
327327 {
328328 asm ("rotlwi %0,%0,%2"
329329 :"=r" (word)
331331 return word;
332332 }
333333
334 static inline unsigned RORc(unsigned word, const int i)
334 static inline ulong32 RORc(ulong32 word, const int i)
335335 {
336336 asm ("rotrwi %0,%0,%2"
337337 :"=r" (word)
361361 /* 64-bit Rotates */
362362 #if !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__x86_64__) && !defined(LTC_NO_ASM)
363363
364 static inline unsigned long ROL64(unsigned long word, int i)
364 static inline ulong64 ROL64(ulong64 word, int i)
365365 {
366366 asm("rolq %%cl,%0"
367367 :"=r" (word)
369369 return word;
370370 }
371371
372 static inline unsigned long ROR64(unsigned long word, int i)
372 static inline ulong64 ROR64(ulong64 word, int i)
373373 {
374374 asm("rorq %%cl,%0"
375375 :"=r" (word)
379379
380380 #ifndef LTC_NO_ROLC
381381
382 static inline unsigned long ROL64c(unsigned long word, const int i)
382 static inline ulong64 ROL64c(ulong64 word, const int i)
383383 {
384384 asm("rolq %2,%0"
385385 :"=r" (word)
387387 return word;
388388 }
389389
390 static inline unsigned long ROR64c(unsigned long word, const int i)
390 static inline ulong64 ROR64c(ulong64 word, const int i)
391391 {
392392 asm("rorq %2,%0"
393393 :"=r" (word)
216216 @return CRYPT_OK on success
217217 */
218218 int (*sqr)(void *a, void *b);
219
220 /** Square root (mod prime)
221 @param a The integer to compute square root mod prime from
222 @param b The prime
223 @param c The destination
224 @return CRYPT_OK on success
225 */
226 int (*sqrtmod_prime)(void *a, void *b, void *c);
219227
220228 /** Divide an integer
221229 @param a The dividend
350358 @param map Boolean indicated whether to map back to affine or not (can be ignored if you work in affine only)
351359 @return CRYPT_OK on success
352360 */
353 int (*ecc_ptmul)(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
361 int (*ecc_ptmul)(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map);
354362
355363 /** ECC GF(p) point addition
356364 @param P The first point
357365 @param Q The second point
358366 @param R The destination of P + Q
367 @param a ECC curve parameter a (if NULL we assume a == -3)
359368 @param modulus The modulus
360369 @param mp The "b" value from montgomery_setup()
361370 @return CRYPT_OK on success
362371 */
363 int (*ecc_ptadd)(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp);
372 int (*ecc_ptadd)(ecc_point *P, ecc_point *Q, ecc_point *R, void *a, void *modulus, void *mp);
364373
365374 /** ECC GF(p) point double
366375 @param P The first point
367376 @param R The destination of 2P
368 @param modulus The modulus
377 @param a ECC curve parameter a (if NULL we assume a == -3)
378 @param modulus The modulus of the field the ECC curve is in
369379 @param mp The "b" value from montgomery_setup()
370380 @return CRYPT_OK on success
371381 */
372 int (*ecc_ptdbl)(ecc_point *P, ecc_point *R, void *modulus, void *mp);
382 int (*ecc_ptdbl)(ecc_point *P, ecc_point *R, void *a, void *modulus, void *mp);
373383
374384 /** ECC mapping from projective to affine, currently uses (x,y,z) => (x/z^2, y/z^3, 1)
375385 @param P The point to map
393403 int (*ecc_mul2add)(ecc_point *A, void *kA,
394404 ecc_point *B, void *kB,
395405 ecc_point *C,
406 void *a,
396407 void *modulus);
397408
398409 /* ---- (optional) rsa optimized math (for internal CRT) ---- */
506517 #define mp_mul(a, b, c) ltc_mp.mul(a, b, c)
507518 #define mp_mul_d(a, b, c) ltc_mp.muli(a, b, c)
508519 #define mp_sqr(a, b) ltc_mp.sqr(a, b)
520 #define mp_sqrtmod_prime(a, b, c) ltc_mp.sqrtmod_prime(a, b, c)
509521 #define mp_div(a, b, c, d) ltc_mp.mpdiv(a, b, c, d)
510522 #define mp_div_2(a, b) ltc_mp.div_2(a, b)
511523 #define mp_mod(a, b, c) ltc_mp.mpdiv(a, b, NULL, c)
11
22 enum {
33 PK_PUBLIC=0,
4 PK_PRIVATE=1
4 PK_PRIVATE=1,
5 PK_PUBLIC_COMPRESSED=2 /* used only when exporting public ECC key */
56 };
67
78 int rand_prime(void *N, long len, prng_state *prng, int wprng);
9 int rand_bn_bits(void *N, int bits, prng_state *prng, int wprng);
10 int rand_bn_range(void *N, void *limit, prng_state *prng, int wprng);
811
912 enum {
1013 PKA_RSA,
11 PKA_DSA
14 PKA_DSA,
15 PKA_EC,
16 EC_PRIME_FIELD
1217 };
1318
1419 typedef struct Oid {
218223 /** The prime that defines the field the curve is in (encoded in hex) */
219224 char *prime;
220225
226 /** The fields A param (hex) */
227 char *A;
228
221229 /** The fields B param (hex) */
222230 char *B;
223231
229237
230238 /** The y co-ordinate of the base point on the curve (hex) */
231239 char *Gy;
240
241 /** The co-factor */
242 unsigned long cofactor;
232243 } ltc_ecc_set_type;
233244
234245 /** A point on a ECC curve, stored in Jacbobian format such that (x,y,z) => (x/z^2, y/z^3, 1) when interpretted as affine */
268279 void ecc_sizes(int *low, int *high);
269280 int ecc_get_size(ecc_key *key);
270281
282 int ecc_dp_init(ltc_ecc_set_type *dp);
283 int ecc_dp_set(ltc_ecc_set_type *dp, char *ch_prime, char *ch_A, char *ch_B, char *ch_order, char *ch_Gx, char *ch_Gy, unsigned long cofactor, char *ch_name);
284 int ecc_dp_clear(ltc_ecc_set_type *dp);
285
271286 int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key);
272287 int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp);
273288 void ecc_free(ecc_key *key);
279294 int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen);
280295 int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key);
281296 int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp);
297
298 int ecc_export_full(unsigned char *out, unsigned long *outlen, int type, ecc_key *key);
299 int ecc_import_full(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp);
300
301 int ecc_export_point(unsigned char *out, unsigned long *outlen, void *x, void *y, unsigned long size, int compressed);
302 int ecc_import_point(const unsigned char *in, unsigned long inlen, void *prime, void *a, void *b, void *x, void *y);
303 int ecc_export_raw(unsigned char *out, unsigned long *outlen, int type, ecc_key *key);
304 int ecc_import_raw(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp);
282305
283306 int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
284307 unsigned char *out, unsigned long *outlen);
300323 const unsigned char *hash, unsigned long hashlen,
301324 int *stat, ecc_key *key);
302325
326 int ecc_verify_key(ecc_key *key);
327
303328 /* low level functions */
304329 ecc_point *ltc_ecc_new_point(void);
305330 void ltc_ecc_del_point(ecc_point *p);
306331 int ltc_ecc_is_valid_idx(int n);
332 int ltc_ecc_is_point(const ltc_ecc_set_type *dp, void *x, void *y);
307333
308334 /* point ops (mp == montgomery digit) */
309335 #if !defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC) || defined(GMP_LTC_DESC)
310336 /* R = 2P */
311 int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp);
337 int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *a, void *modulus, void *mp);
312338
313339 /* R = P + Q */
314 int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp);
340 int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *a, void *modulus, void *mp);
315341 #endif
316342
317343 #if defined(LTC_MECC_FP)
318344 /* optimized point multiplication using fixed point cache (HAC algorithm 14.117) */
319 int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
345 int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map);
320346
321347 /* functions for saving/loading/freeing/adding to fixed point cache */
322348 int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen);
329355 #endif
330356
331357 /* R = kG */
332 int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
358 int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map);
333359
334360 #ifdef LTC_ECC_SHAMIR
335361 /* kA*A + kB*B = C */
336362 int ltc_ecc_mul2add(ecc_point *A, void *kA,
337363 ecc_point *B, void *kB,
338 ecc_point *C,
339 void *modulus);
364 ecc_point *C, void *a, void *modulus);
340365
341366 #ifdef LTC_MECC_FP
342367 /* Shamir's trick with optimized point multiplication using fixed point cache */
343368 int ltc_ecc_fp_mul2add(ecc_point *A, void *kA,
344369 ecc_point *B, void *kB,
345 ecc_point *C, void *modulus);
370 ecc_point *C, void *a, void *modulus);
346371 #endif
347372
348373 #endif
457482 unsigned long size;
458483 /** The used flag, this is used by the CHOICE ASN.1 type to indicate which choice was made */
459484 int used;
485 /** Flag used to indicate optional items in ASN.1 sequences */
486 int optional;
487 /** Flag used to indicate context specific tags on ASN.1 sequence items */
488 unsigned char tag;
460489 /** prev/next entry in the list */
461490 struct ltc_asn1_list_ *prev, *next, *child, *parent;
462491 } ltc_asn1_list;
469498 LTC_MACRO_list[LTC_MACRO_temp].data = (void*)(Data); \
470499 LTC_MACRO_list[LTC_MACRO_temp].size = (Size); \
471500 LTC_MACRO_list[LTC_MACRO_temp].used = 0; \
501 LTC_MACRO_list[LTC_MACRO_temp].tag = 0; \
502 LTC_MACRO_list[LTC_MACRO_temp].optional = 0; \
472503 } while (0);
473504
474505 /* SEQUENCE */
482513
483514 #define der_decode_sequence(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 1)
484515
485 int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
486 unsigned long *outlen);
516 int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, unsigned long *outlen);
517 int der_length_sequence_ex(ltc_asn1_list *list, unsigned long inlen, unsigned long *outlen, unsigned long *payloadlen);
487518
488519 /* SUBJECT PUBLIC KEY INFO */
489520 int der_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen,
669669 * The algorithm builds patterns in increasing bit order by first making all
670670 * single bit input patterns, then all two bit input patterns and so on
671671 */
672 static int build_lut(int idx, void *modulus, void *mp, void *mu)
672 static int build_lut(int idx, void *a, void *modulus, void *mp, void *mu)
673673 {
674674 unsigned x, y, err, bitlen, lut_gap;
675675 void *tmp;
708708
709709 /* now double it bitlen/FP_LUT times */
710710 for (y = 0; y < lut_gap; y++) {
711 if ((err = ltc_mp.ecc_ptdbl(fp_cache[idx].LUT[1<<x], fp_cache[idx].LUT[1<<x], modulus, mp)) != CRYPT_OK) {
711 if ((err = ltc_mp.ecc_ptdbl(fp_cache[idx].LUT[1<<x], fp_cache[idx].LUT[1<<x], a, modulus, mp)) != CRYPT_OK) {
712712 goto ERR;
713713 }
714714 }
721721
722722 /* perform the add */
723723 if ((err = ltc_mp.ecc_ptadd(fp_cache[idx].LUT[lut_orders[y].terma], fp_cache[idx].LUT[lut_orders[y].termb],
724 fp_cache[idx].LUT[y], modulus, mp)) != CRYPT_OK) {
724 fp_cache[idx].LUT[y], a, modulus, mp)) != CRYPT_OK) {
725725 goto ERR;
726726 }
727727 }
776776 }
777777
778778 /* perform a fixed point ECC mulmod */
779 static int accel_fp_mul(int idx, void *k, ecc_point *R, void *modulus, void *mp, int map)
779 static int accel_fp_mul(int idx, void *k, ecc_point *R, void *a, void *modulus, void *mp, int map)
780780 {
781781 unsigned char kb[128];
782782 int x;
869869
870870 /* double if not first */
871871 if (!first) {
872 if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) {
872 if ((err = ltc_mp.ecc_ptdbl(R, R, a, modulus, mp)) != CRYPT_OK) {
873873 return err;
874874 }
875875 }
876876
877877 /* add if not first, otherwise copy */
878878 if (!first && z) {
879 if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx].LUT[z], R, modulus, mp)) != CRYPT_OK) {
879 if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx].LUT[z], R, a, modulus, mp)) != CRYPT_OK) {
880880 return err;
881881 }
882882 } else if (z) {
901901 /* perform a fixed point ECC mulmod */
902902 static int accel_fp_mul2add(int idx1, int idx2,
903903 void *kA, void *kB,
904 ecc_point *R, void *modulus, void *mp)
904 ecc_point *R, void *a, void *modulus, void *mp)
905905 {
906906 unsigned char kb[2][128];
907907 int x;
10571057
10581058 /* double if not first */
10591059 if (!first) {
1060 if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) {
1060 if ((err = ltc_mp.ecc_ptdbl(R, R, a, modulus, mp)) != CRYPT_OK) {
10611061 return err;
10621062 }
10631063 }
10651065 /* add if not first, otherwise copy */
10661066 if (!first) {
10671067 if (zA) {
1068 if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx1].LUT[zA], R, modulus, mp)) != CRYPT_OK) {
1068 if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx1].LUT[zA], R, a, modulus, mp)) != CRYPT_OK) {
10691069 return err;
10701070 }
10711071 }
10721072 if (zB) {
1073 if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx2].LUT[zB], R, modulus, mp)) != CRYPT_OK) {
1073 if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx2].LUT[zB], R, a, modulus, mp)) != CRYPT_OK) {
10741074 return err;
10751075 }
10761076 }
10831083 }
10841084 if (zB && first == 0) {
10851085 if (zB) {
1086 if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx2].LUT[zB], R, modulus, mp)) != CRYPT_OK) {
1086 if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx2].LUT[zB], R, a, modulus, mp)) != CRYPT_OK) {
10871087 return err;
10881088 }
10891089 }
11111111 */
11121112 int ltc_ecc_fp_mul2add(ecc_point *A, void *kA,
11131113 ecc_point *B, void *kB,
1114 ecc_point *C, void *modulus)
1114 ecc_point *C, void *a, void *modulus)
11151115 {
11161116 int idx1, idx2, err;
11171117 void *mp, *mu;
11671167 }
11681168
11691169 /* build the LUT */
1170 if ((err = build_lut(idx1, modulus, mp, mu)) != CRYPT_OK) {
1170 if ((err = build_lut(idx1, a, modulus, mp, mu)) != CRYPT_OK) {
11711171 goto LBL_ERR;;
11721172 }
11731173 }
11881188 }
11891189
11901190 /* build the LUT */
1191 if ((err = build_lut(idx2, modulus, mp, mu)) != CRYPT_OK) {
1191 if ((err = build_lut(idx2, a, modulus, mp, mu)) != CRYPT_OK) {
11921192 goto LBL_ERR;;
11931193 }
11941194 }
11991199 /* compute mp */
12001200 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; }
12011201 }
1202 err = accel_fp_mul2add(idx1, idx2, kA, kB, C, modulus, mp);
1202 err = accel_fp_mul2add(idx1, idx2, kA, kB, C, a, modulus, mp);
12031203 } else {
1204 err = ltc_ecc_mul2add(A, kA, B, kB, C, modulus);
1204 err = ltc_ecc_mul2add(A, kA, B, kB, C, a, modulus);
12051205 }
12061206 LBL_ERR:
12071207 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
12191219 @param k The multiplicand
12201220 @param G Base point to multiply
12211221 @param R [out] Destination of product
1222 @param a ECC curve parameter a
12221223 @param modulus The modulus for the curve
12231224 @param map [boolean] If non-zero maps the point back to affine co-ordinates, otherwise it's left in jacobian-montgomery form
12241225 @return CRYPT_OK if successful
1225 */
1226 int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map)
1226 */
1227 int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map)
12271228 {
12281229 int idx, err;
12291230 void *mp, *mu;
12651266 }
12661267
12671268 /* build the LUT */
1268 if ((err = build_lut(idx, modulus, mp, mu)) != CRYPT_OK) {
1269 if ((err = build_lut(idx, a, modulus, mp, mu)) != CRYPT_OK) {
12691270 goto LBL_ERR;;
12701271 }
12711272 }
12751276 /* compute mp */
12761277 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; }
12771278 }
1278 err = accel_fp_mul(idx, k, R, modulus, mp, map);
1279 err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
12791280 } else {
1280 err = ltc_ecc_mulmod(k, G, R, modulus, map);
1281 err = ltc_ecc_mulmod(k, G, R, a, modulus, map);
12811282 }
12821283 LBL_ERR:
12831284 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
13641365 }
13651366
13661367 /* build the LUT */
1367 if ((err = build_lut(idx, modulus, mp, mu)) != CRYPT_OK) {
1368 if ((err = build_lut(idx, a, modulus, mp, mu)) != CRYPT_OK) {
13681369 goto LBL_ERR;
13691370 }
13701371 fp_cache[idx].lru_count = 2;
258258 return mpi_to_ltc_error(mp_sqr(a, b));
259259 }
260260
261 /* sqrtmod_prime */
262 static int sqrtmod_prime(void *a, void *b, void *c)
263 {
264 LTC_ARGCHK(a != NULL);
265 LTC_ARGCHK(b != NULL);
266 LTC_ARGCHK(c != NULL);
267 return mpi_to_ltc_error(mp_sqrtmod_prime(a, b, c));
268 }
269
261270 /* div */
262271 static int divide(void *a, void *b, void *c, void *d)
263272 {
456465 &mul,
457466 &muli,
458467 &sqr,
468 &sqrtmod_prime,
459469 &divide,
460470 &div_2,
461471 &modi,
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9 #include "tomcrypt.h"
10
11 /**
12 Generate a random number N with given bitlength (note: MSB can be 0)
13 */
14
15 int rand_bn_bits(void *N, int bits, prng_state *prng, int wprng)
16 {
17 int res, bytes;
18 unsigned char *buf, mask;
19
20 LTC_ARGCHK(N != NULL);
21 LTC_ARGCHK(bits > 1);
22
23 /* check PRNG */
24 if ((res = prng_is_valid(wprng)) != CRYPT_OK) return res;
25
26 bytes = (bits+7) >> 3;
27 mask = 0xff << (8 - bits % 8);
28
29 /* allocate buffer */
30 if ((buf = XCALLOC(1, bytes)) == NULL) return CRYPT_MEM;
31
32 /* generate random bytes */
33 if (prng_descriptor[wprng].read(buf, bytes, prng) != (unsigned long)bytes) {
34 res = CRYPT_ERROR_READPRNG;
35 goto cleanup;
36 }
37 /* mask bits */
38 buf[0] &= ~mask;
39 /* load value */
40 if ((res = mp_read_unsigned_bin(N, buf, bytes)) != CRYPT_OK) goto cleanup;
41
42 res = CRYPT_OK;
43
44 cleanup:
45 #ifdef LTC_CLEAN_STACK
46 zeromem(buf, len);
47 #endif
48 XFREE(buf);
49 return res;
50 }
51
52 /**
53 Generate a random number N in a range: 0 <= N < limit
54 */
55 int rand_bn_range(void *N, void *limit, prng_state *prng, int wprng)
56 {
57 int res;
58
59 LTC_ARGCHK(N != NULL);
60 LTC_ARGCHK(limit != NULL);
61
62 do {
63 res = rand_bn_bits(N, mp_count_bits(limit), prng, wprng);
64 if (res != CRYPT_OK) return res;
65 } while (mp_cmp(N, limit) != LTC_MP_LT);
66
67 return CRYPT_OK;
68 }
1818 6,
1919 };
2020
21 static const oid_st ec_oid = {
22 { 1, 2, 840, 10045, 2, 1 },
23 6,
24 };
25
26 static const oid_st ec_primef = {
27 { 1, 2, 840, 10045, 1, 1 },
28 6,
29 };
30
2131 /*
2232 Returns the OID of the public key algorithm.
2333 @return CRYPT_OK if valid
3141 case PKA_DSA:
3242 memcpy(st, &dsa_oid, sizeof(*st));
3343 break;
44 case PKA_EC:
45 memcpy(st, &ec_oid, sizeof(*st));
46 break;
47 case EC_PRIME_FIELD:
48 memcpy(st, &ec_primef, sizeof(*st));
49 break;
3450 default:
3551 return CRYPT_INVALID_ARG;
3652 }
9292 break;
9393 }
9494
95 /* handle context specific tags - just skip the tag + len bytes */
96 z = 0;
97 if (list[i].tag > 0 && list[i].tag == in[x + z++]) {
98 if (in[x+z] & 0x80) {
99 y = in[x + z++] & 0x7F;
100 if (y == 0 || y > 2) { return CRYPT_INVALID_PACKET; }
101 z += y;
102 } else {
103 z++;
104 }
105 x += z;
106 inlen -= z;
107 }
108
95109 switch (type) {
96110 case LTC_ASN1_BOOLEAN:
97111 z = inlen;
98112 if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) {
113 if (!ordered || list[i].optional) { continue; }
99114 goto LBL_ERR;
100115 }
101116 if ((err = der_length_boolean(&z)) != CRYPT_OK) {
106121 case LTC_ASN1_INTEGER:
107122 z = inlen;
108123 if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) {
109 if (!ordered) { continue; }
124 if (!ordered || list[i].optional) { continue; }
110125 goto LBL_ERR;
111126 }
112127 if ((err = der_length_integer(data, &z)) != CRYPT_OK) {
117132 case LTC_ASN1_SHORT_INTEGER:
118133 z = inlen;
119134 if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) {
120 if (!ordered) { continue; }
135 if (!ordered || list[i].optional) { continue; }
121136 goto LBL_ERR;
122137 }
123138 if ((err = der_length_short_integer(((unsigned long*)data)[0], &z)) != CRYPT_OK) {
129144 case LTC_ASN1_BIT_STRING:
130145 z = inlen;
131146 if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) {
132 if (!ordered) { continue; }
147 if (!ordered || list[i].optional) { continue; }
133148 goto LBL_ERR;
134149 }
135150 list[i].size = size;
141156 case LTC_ASN1_RAW_BIT_STRING:
142157 z = inlen;
143158 if ((err = der_decode_raw_bit_string(in + x, z, data, &size)) != CRYPT_OK) {
144 if (!ordered) { continue; }
159 if (!ordered || list[i].optional) { continue; }
145160 goto LBL_ERR;
146161 }
147162 list[i].size = size;
153168 case LTC_ASN1_OCTET_STRING:
154169 z = inlen;
155170 if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) {
156 if (!ordered) { continue; }
171 if (!ordered || list[i].optional) { continue; }
157172 goto LBL_ERR;
158173 }
159174 list[i].size = size;
164179
165180 case LTC_ASN1_NULL:
166181 if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) {
167 if (!ordered) { continue; }
182 if (!ordered || list[i].optional) { continue; }
168183 err = CRYPT_INVALID_PACKET;
169184 goto LBL_ERR;
170185 }
174189 case LTC_ASN1_OBJECT_IDENTIFIER:
175190 z = inlen;
176191 if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) {
177 if (!ordered) { continue; }
192 if (!ordered || list[i].optional) { continue; }
178193 goto LBL_ERR;
179194 }
180195 list[i].size = size;
186201 case LTC_ASN1_IA5_STRING:
187202 z = inlen;
188203 if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) {
189 if (!ordered) { continue; }
204 if (!ordered || list[i].optional) { continue; }
190205 goto LBL_ERR;
191206 }
192207 list[i].size = size;
199214 case LTC_ASN1_PRINTABLE_STRING:
200215 z = inlen;
201216 if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) {
202 if (!ordered) { continue; }
217 if (!ordered || list[i].optional) { continue; }
203218 goto LBL_ERR;
204219 }
205220 list[i].size = size;
211226 case LTC_ASN1_UTF8_STRING:
212227 z = inlen;
213228 if ((err = der_decode_utf8_string(in + x, z, data, &size)) != CRYPT_OK) {
214 if (!ordered) { continue; }
229 if (!ordered || list[i].optional) { continue; }
215230 goto LBL_ERR;
216231 }
217232 list[i].size = size;
223238 case LTC_ASN1_UTCTIME:
224239 z = inlen;
225240 if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) {
226 if (!ordered) { continue; }
241 if (!ordered || list[i].optional) { continue; }
227242 goto LBL_ERR;
228243 }
229244 break;
231246 case LTC_ASN1_SET:
232247 z = inlen;
233248 if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) {
234 if (!ordered) { continue; }
249 if (!ordered || list[i].optional) { continue; }
235250 goto LBL_ERR;
236251 }
237252 if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
249264
250265 z = inlen;
251266 if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) {
252 if (!ordered) { continue; }
267 if (!ordered || list[i].optional) { continue; }
253268 goto LBL_ERR;
254269 }
255270 if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
261276 case LTC_ASN1_CHOICE:
262277 z = inlen;
263278 if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) {
264 if (!ordered) { continue; }
279 if (!ordered || list[i].optional) { continue; }
265280 goto LBL_ERR;
266281 }
267282 break;
276291 if (!ordered) {
277292 /* restart the decoder */
278293 i = -1;
279 }
294 }
280295 }
281296
282297 for (i = 0; i < (int)outlen; i++) {
283 if (list[i].used == 0) {
298 if (list[i].used == 0 && list[i].optional == 0) {
284299 err = CRYPT_INVALID_PACKET;
285300 goto LBL_ERR;
286301 }
110110 case LTC_ASN1_SEQUENCE:
111111 case LTC_ASN1_SET:
112112 case LTC_ASN1_SETOF:
113 case LTC_ASN1_RAW_BIT_STRING:
113114 case LTC_ASN1_CHOICE:
114 list[x].type = type;
115 list[x].size = size;
116 list[x++].data = data;
115 LTC_SET_ASN1(list, x++, type, data, size);
117116 break;
118117
119118 default:
3232 {
3333 int err, type;
3434 unsigned long size, x, y, z, i;
35 unsigned char tmptag[6];
3536 void *data;
3637
3738 LTC_ARGCHK(list != NULL);
3940 LTC_ARGCHK(outlen != NULL);
4041
4142 /* get size of output that will be required */
42 y = 0;
43 for (i = 0; i < inlen; i++) {
44 type = list[i].type;
45 size = list[i].size;
46 data = list[i].data;
47
48 if (type == LTC_ASN1_EOL) {
49 break;
50 }
51
52 switch (type) {
53 case LTC_ASN1_BOOLEAN:
54 if ((err = der_length_boolean(&x)) != CRYPT_OK) {
55 goto LBL_ERR;
56 }
57 y += x;
58 break;
59
60 case LTC_ASN1_INTEGER:
61 if ((err = der_length_integer(data, &x)) != CRYPT_OK) {
62 goto LBL_ERR;
63 }
64 y += x;
65 break;
66
67 case LTC_ASN1_SHORT_INTEGER:
68 if ((err = der_length_short_integer(*((unsigned long*)data), &x)) != CRYPT_OK) {
69 goto LBL_ERR;
70 }
71 y += x;
72 break;
73
74 case LTC_ASN1_BIT_STRING:
75 case LTC_ASN1_RAW_BIT_STRING:
76 if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) {
77 goto LBL_ERR;
78 }
79 y += x;
80 break;
81
82 case LTC_ASN1_OCTET_STRING:
83 if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) {
84 goto LBL_ERR;
85 }
86 y += x;
87 break;
88
89 case LTC_ASN1_NULL:
90 y += 2;
91 break;
92
93 case LTC_ASN1_OBJECT_IDENTIFIER:
94 if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) {
95 goto LBL_ERR;
96 }
97 y += x;
98 break;
99
100 case LTC_ASN1_IA5_STRING:
101 if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) {
102 goto LBL_ERR;
103 }
104 y += x;
105 break;
106
107 case LTC_ASN1_PRINTABLE_STRING:
108 if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) {
109 goto LBL_ERR;
110 }
111 y += x;
112 break;
113
114 case LTC_ASN1_UTF8_STRING:
115 if ((err = der_length_utf8_string(data, size, &x)) != CRYPT_OK) {
116 goto LBL_ERR;
117 }
118 y += x;
119 break;
120
121 case LTC_ASN1_UTCTIME:
122 if ((err = der_length_utctime(data, &x)) != CRYPT_OK) {
123 goto LBL_ERR;
124 }
125 y += x;
126 break;
127
128 case LTC_ASN1_SET:
129 case LTC_ASN1_SETOF:
130 case LTC_ASN1_SEQUENCE:
131 if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) {
132 goto LBL_ERR;
133 }
134 y += x;
135 break;
136
137 default:
138 err = CRYPT_INVALID_ARG;
139 goto LBL_ERR;
140 }
141 }
142
143 /* calc header size */
144 z = y;
145 if (y < 128) {
146 y += 2;
147 } else if (y < 256) {
148 /* 0x30 0x81 LL */
149 y += 3;
150 } else if (y < 65536UL) {
151 /* 0x30 0x82 LL LL */
152 y += 4;
153 } else if (y < 16777216UL) {
154 /* 0x30 0x83 LL LL LL */
155 y += 5;
156 } else {
157 err = CRYPT_INVALID_ARG;
158 goto LBL_ERR;
159 }
43 y = 0; z = 0;
44 if ((err = der_length_sequence_ex(list, inlen, &y, &z)) != CRYPT_OK) return CRYPT_INVALID_ARG;
16045
16146 /* too big ? */
16247 if (*outlen < y) {
20287 if ((err = der_encode_boolean(*((int *)data), out + x, &z)) != CRYPT_OK) {
20388 goto LBL_ERR;
20489 }
205 x += z;
206 *outlen -= z;
20790 break;
20891
20992 case LTC_ASN1_INTEGER:
21194 if ((err = der_encode_integer(data, out + x, &z)) != CRYPT_OK) {
21295 goto LBL_ERR;
21396 }
214 x += z;
215 *outlen -= z;
21697 break;
21798
21899 case LTC_ASN1_SHORT_INTEGER:
220101 if ((err = der_encode_short_integer(*((unsigned long*)data), out + x, &z)) != CRYPT_OK) {
221102 goto LBL_ERR;
222103 }
223 x += z;
224 *outlen -= z;
225104 break;
226105
227106 case LTC_ASN1_BIT_STRING:
229108 if ((err = der_encode_bit_string(data, size, out + x, &z)) != CRYPT_OK) {
230109 goto LBL_ERR;
231110 }
232 x += z;
233 *outlen -= z;
234111 break;
235112
236113 case LTC_ASN1_RAW_BIT_STRING:
238115 if ((err = der_encode_raw_bit_string(data, size, out + x, &z)) != CRYPT_OK) {
239116 goto LBL_ERR;
240117 }
241 x += z;
242 *outlen -= z;
243118 break;
244119
245120 case LTC_ASN1_OCTET_STRING:
247122 if ((err = der_encode_octet_string(data, size, out + x, &z)) != CRYPT_OK) {
248123 goto LBL_ERR;
249124 }
250 x += z;
251 *outlen -= z;
252125 break;
253126
254127 case LTC_ASN1_NULL:
255 out[x++] = 0x05;
256 out[x++] = 0x00;
257 *outlen -= 2;
128 out[x] = 0x05;
129 out[x+1] = 0x00;
130 z = 2;
258131 break;
259132
260133 case LTC_ASN1_OBJECT_IDENTIFIER:
262135 if ((err = der_encode_object_identifier(data, size, out + x, &z)) != CRYPT_OK) {
263136 goto LBL_ERR;
264137 }
265 x += z;
266 *outlen -= z;
267138 break;
268139
269140 case LTC_ASN1_IA5_STRING:
271142 if ((err = der_encode_ia5_string(data, size, out + x, &z)) != CRYPT_OK) {
272143 goto LBL_ERR;
273144 }
274 x += z;
275 *outlen -= z;
276145 break;
277146
278147 case LTC_ASN1_PRINTABLE_STRING:
280149 if ((err = der_encode_printable_string(data, size, out + x, &z)) != CRYPT_OK) {
281150 goto LBL_ERR;
282151 }
283 x += z;
284 *outlen -= z;
285152 break;
286153
287154 case LTC_ASN1_UTF8_STRING:
289156 if ((err = der_encode_utf8_string(data, size, out + x, &z)) != CRYPT_OK) {
290157 goto LBL_ERR;
291158 }
292 x += z;
293 *outlen -= z;
294159 break;
295160
296161 case LTC_ASN1_UTCTIME:
298163 if ((err = der_encode_utctime(data, out + x, &z)) != CRYPT_OK) {
299164 goto LBL_ERR;
300165 }
301 x += z;
302 *outlen -= z;
303166 break;
304167
305168 case LTC_ASN1_SET:
307170 if ((err = der_encode_set(data, size, out + x, &z)) != CRYPT_OK) {
308171 goto LBL_ERR;
309172 }
310 x += z;
311 *outlen -= z;
312173 break;
313174
314175 case LTC_ASN1_SETOF:
316177 if ((err = der_encode_setof(data, size, out + x, &z)) != CRYPT_OK) {
317178 goto LBL_ERR;
318179 }
319 x += z;
320 *outlen -= z;
321180 break;
322181
323182 case LTC_ASN1_SEQUENCE:
325184 if ((err = der_encode_sequence_ex(data, size, out + x, &z, type)) != CRYPT_OK) {
326185 goto LBL_ERR;
327186 }
328 x += z;
329 *outlen -= z;
330187 break;
331188
332189 default:
333190 err = CRYPT_INVALID_ARG;
334191 goto LBL_ERR;
335192 }
193
194 if (list[i].tag > 0) {
195 tmptag[0] = list[i].tag;
196 y = 0;
197 if (z < 128) {
198 tmptag[1] = (unsigned char)z;
199 y = 2;
200 } else if (z < 256) {
201 tmptag[1] = 0x81;
202 tmptag[2] = (unsigned char)z;
203 y = 3;
204 } else if (z < 65536UL) {
205 tmptag[1] = 0x82;
206 tmptag[2] = (unsigned char)((z>>8UL)&255);
207 tmptag[3] = (unsigned char)(z&255);
208 y = 4;
209 } else if (z < 16777216UL) {
210 tmptag[1] = 0x83;
211 tmptag[2] = (unsigned char)((z>>16UL)&255);
212 tmptag[3] = (unsigned char)((z>>8UL)&255);
213 tmptag[4] = (unsigned char)(z&255);
214 y = 5;
215 }
216
217 memmove(out + x + y, out + x, z);
218 memcpy(out + x, tmptag, y);
219
220 z += y;
221 }
222
223 x += z;
224 *outlen -= z;
336225 }
226
337227 *outlen = x;
338 err = CRYPT_OK;
339
228 err = CRYPT_OK;
340229 LBL_ERR:
341230 return err;
342231 }
112112 case LTC_ASN1_SET:
113113 case LTC_ASN1_SETOF:
114114 case LTC_ASN1_RAW_BIT_STRING:
115 list[x].type = type;
116 list[x].size = size;
117 list[x++].data = data;
115 LTC_SET_ASN1(list, x++, type, data, size);
118116 break;
119117
120118 default:
4848 return err;
4949 }
5050
51 alg_id[0].data = oid.OID;
52 alg_id[0].size = oid.OIDlen;
53 alg_id[0].type = LTC_ASN1_OBJECT_IDENTIFIER;
54
55 alg_id[1].data = parameters;
56 alg_id[1].size = parameters_len;
57 alg_id[1].type = parameters_type;
51 LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid.OID, oid.OIDlen);
52 LTC_SET_ASN1(alg_id, 1, parameters_type, parameters, parameters_len);
5853
5954 return der_encode_sequence_multi(out, outlen,
6055 LTC_ASN1_SEQUENCE, (unsigned long)sizeof(alg_id)/sizeof(alg_id[0]), alg_id,
2323 @param outlen [out] The length required in octets to store it
2424 @return CRYPT_OK on success
2525 */
26 int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
27 unsigned long *outlen)
26
27 int der_length_sequence(ltc_asn1_list *list, unsigned long inlen, unsigned long *outlen)
28 {
29 return der_length_sequence_ex(list, inlen, outlen, NULL);
30 }
31
32 int der_length_sequence_ex(ltc_asn1_list *list, unsigned long inlen, unsigned long *outlen, unsigned long *payloadlen)
2833 {
2934 int err, type;
30 unsigned long size, x, y, i;
35 unsigned long size, x, y, z, i;
3136 void *data;
3237
3338 LTC_ARGCHK(list != NULL);
4449 break;
4550 }
4651
52 if (!list[i].used && list[i].optional) continue; /* some items may be optional during import */
53
4754 switch (type) {
4855 case LTC_ASN1_BOOLEAN:
49 if ((err = der_length_boolean(&x)) != CRYPT_OK) {
50 goto LBL_ERR;
51 }
52 y += x;
53 break;
54
56 if ((err = der_length_boolean(&x)) != CRYPT_OK) {
57 goto LBL_ERR;
58 }
59 break;
60
5561 case LTC_ASN1_INTEGER:
5662 if ((err = der_length_integer(data, &x)) != CRYPT_OK) {
5763 goto LBL_ERR;
5864 }
59 y += x;
6065 break;
6166
6267 case LTC_ASN1_SHORT_INTEGER:
6368 if ((err = der_length_short_integer(*((unsigned long *)data), &x)) != CRYPT_OK) {
6469 goto LBL_ERR;
6570 }
66 y += x;
6771 break;
6872
73 case LTC_ASN1_RAW_BIT_STRING:
6974 case LTC_ASN1_BIT_STRING:
7075 if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) {
7176 goto LBL_ERR;
7277 }
73 y += x;
7478 break;
7579
7680 case LTC_ASN1_OCTET_STRING:
7781 if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) {
7882 goto LBL_ERR;
7983 }
80 y += x;
8184 break;
8285
8386 case LTC_ASN1_NULL:
84 y += 2;
87 x = 2;
8588 break;
8689
8790 case LTC_ASN1_OBJECT_IDENTIFIER:
8891 if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) {
8992 goto LBL_ERR;
9093 }
91 y += x;
9294 break;
9395
9496 case LTC_ASN1_IA5_STRING:
9597 if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) {
9698 goto LBL_ERR;
9799 }
98 y += x;
99100 break;
100101
101102 case LTC_ASN1_PRINTABLE_STRING:
102103 if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) {
103104 goto LBL_ERR;
104105 }
105 y += x;
106106 break;
107107
108108 case LTC_ASN1_UTCTIME:
109109 if ((err = der_length_utctime(data, &x)) != CRYPT_OK) {
110110 goto LBL_ERR;
111111 }
112 y += x;
113112 break;
114113
115114 case LTC_ASN1_UTF8_STRING:
116115 if ((err = der_length_utf8_string(data, size, &x)) != CRYPT_OK) {
117116 goto LBL_ERR;
118117 }
119 y += x;
120118 break;
121119
122120 case LTC_ASN1_SET:
125123 if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) {
126124 goto LBL_ERR;
127125 }
128 y += x;
129126 break;
130127
131
132128 default:
133129 err = CRYPT_INVALID_ARG;
134130 goto LBL_ERR;
135131 }
132
133 /* handle context specific tags */
134 if (list[i].tag > 0) {
135 z = x;
136 /* calc tag size */
137 if (x < 128) {
138 x += 2;
139 } else if (x < 256) {
140 /* 0x30 0x81 LL */
141 x += 3;
142 } else if (x < 65536UL) {
143 /* 0x30 0x82 LL LL */
144 x += 4;
145 } else if (x < 16777216UL) {
146 /* 0x30 0x83 LL LL LL */
147 x += 5;
148 } else {
149 err = CRYPT_INVALID_ARG;
150 goto LBL_ERR;
151 }
152 }
153
154 y += x;
136155 }
137
156
138157 /* calc header size */
158 z = y;
139159 if (y < 128) {
140160 y += 2;
141161 } else if (y < 256) {
151171 err = CRYPT_INVALID_ARG;
152172 goto LBL_ERR;
153173 }
154
155174 /* store size */
175 if (payloadlen) *payloadlen = z;
156176 *outlen = y;
157177 err = CRYPT_OK;
158178
3636 unsigned char *expt, *skey;
3737 void *g_pub, *g_priv;
3838 unsigned long x, y;
39 int err;
39 int err, qbits;
4040
4141 LTC_ARGCHK(in != NULL);
4242 LTC_ARGCHK(out != NULL);
7474 return CRYPT_MEM;
7575 }
7676
77 /* make a random x, g^x pair */
78 x = mp_unsigned_bin_size(key->q);
79 if (prng_descriptor[wprng].read(expt, x, prng) != x) {
80 err = CRYPT_ERROR_READPRNG;
81 goto LBL_ERR;
82 }
83
84 /* load x */
85 if ((err = mp_read_unsigned_bin(g_priv, expt, x)) != CRYPT_OK) {
86 goto LBL_ERR;
87 }
88
77 /* make a random g_priv, g_pub = g^x pair */
78 qbits = mp_count_bits(key->q);
79 do {
80 if ((err = rand_bn_bits(g_priv, qbits, prng, wprng)) != CRYPT_OK) {
81 goto LBL_ERR;
82 }
83 /* private key x should be from range: 1 <= x <= q-1 (see FIPS 186-4 B.1.2) */
84 } while (mp_cmp_d(g_priv, 0) != LTC_MP_GT || mp_cmp(g_priv, key->q) != LTC_MP_LT);
85
8986 /* compute y */
9087 if ((err = mp_exptmod(key->g, g_priv, key->p, g_pub)) != CRYPT_OK) {
9188 goto LBL_ERR;
7070 goto error;
7171 }
7272
73 int_list[0].data = key->p;
74 int_list[0].size = 1UL;
75 int_list[0].type = LTC_ASN1_INTEGER;
76 int_list[1].data = key->q;
77 int_list[1].size = 1UL;
78 int_list[1].type = LTC_ASN1_INTEGER;
79 int_list[2].data = key->g;
80 int_list[2].size = 1UL;
81 int_list[2].type = LTC_ASN1_INTEGER;
73 LTC_SET_ASN1(int_list, 0, LTC_ASN1_INTEGER, key->p, 1UL);
74 LTC_SET_ASN1(int_list, 1, LTC_ASN1_INTEGER, key->q, 1UL);
75 LTC_SET_ASN1(int_list, 2, LTC_ASN1_INTEGER, key->g, 1UL);
8276
8377 err = der_encode_subject_public_key_info(out, outlen,
8478 PKA_DSA, tmp, tmplen,
1717 #ifdef LTC_MDSA
1818
1919 struct rng_data {
20 prng_state *prng;
21 int wprng;
20 prng_state *prng;
21 int wprng;
2222 };
2323
24 static int rand_prime_helper(unsigned char *dst, int len, void *dat)
25 {
26 return (int)prng_descriptor[((struct rng_data *)dat)->wprng].read(dst, len, ((struct rng_data *)dat)->prng);
24 static int rng_helper(unsigned char *dst, int len, void *dat)
25 {
26 return (int)prng_descriptor[((struct rng_data *)dat)->wprng].read(dst, len, ((struct rng_data *)dat)->prng);
27 }
28
29 /**
30 Create DSA parameters
31 @param prng An active PRNG state
32 @param wprng The index of the PRNG desired
33 @param group_size Size of the multiplicative group (octets)
34 @param modulus_size Size of the modulus (octets)
35 @param p [out] bignum where generated 'p' is stored (must be initialized by caller)
36 @param q [out] bignum where generated 'q' is stored (must be initialized by caller)
37 @param g [out] bignum where generated 'g' is stored (must be initialized by caller)
38 @return CRYPT_OK if successful, upon error this function will free all allocated memory
39 */
40 int dsa_make_params(prng_state *prng, int wprng, int group_size, int modulus_size, void *p, void *q, void *g)
41 {
42 unsigned long L, N, n, outbytes, seedbytes, counter, j, i;
43 int err, res, mr_tests_q, mr_tests_p, found_p, found_q, hash;
44 unsigned char *wbuf, *sbuf, digest[MAXBLOCKSIZE];
45 void *t2L1, *t2N1, *t2q, *t2seedlen, *U, *W, *X, *c, *h, *e, *seedinc;
46 struct rng_data rng;
47
48 /* check prng */
49 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
50 return err;
51 }
52
53 /* setup rng struct - used later for callback */
54 rng.prng = prng;
55 rng.wprng = wprng;
56
57 /* check size */
58 if (group_size >= LTC_MDSA_MAX_GROUP || group_size < 1 || group_size >= modulus_size) {
59 return CRYPT_INVALID_ARG;
60 }
61
62 /* FIPS-186-4 A.1.1.2 Generation of the Probable Primes p and q Using an Approved Hash Function
63 *
64 * L = The desired length of the prime p (in bits e.g. L = 1024)
65 * N = The desired length of the prime q (in bits e.g. N = 160)
66 * seedlen = The desired bit length of the domain parameter seed; seedlen shallbe equal to or greater than N
67 * outlen = The bit length of Hash function
68 *
69 * 1. Check that the (L, N)
70 * 2. If (seedlen <N), then return INVALID.
71 * 3. n = ceil(L / outlen) - 1
72 * 4. b = L- 1 - (n * outlen)
73 * 5. domain_parameter_seed = an arbitrary sequence of seedlen bits
74 * 6. U = Hash (domain_parameter_seed) mod 2^(N-1)
75 * 7. q = 2^(N-1) + U + 1 - (U mod 2)
76 * 8. Test whether or not q is prime as specified in Appendix C.3
77 * 9. If qis not a prime, then go to step 5.
78 * 10. offset = 1
79 * 11. For counter = 0 to (4L- 1) do {
80 * For j=0 to n do {
81 * Vj = Hash ((domain_parameter_seed+ offset + j) mod 2^seedlen
82 * }
83 * W = V0 + (V1 *2^outlen) + ... + (Vn-1 * 2^((n-1) * outlen)) + ((Vn mod 2^b) * 2^(n * outlen))
84 * X = W + 2^(L-1) Comment: 0 <= W < 2^(L-1); hence 2^(L-1) <= X < 2^L
85 * c = X mod 2*q
86 * p = X - (c - 1) Comment: p ~ 1 (mod 2*q)
87 * If (p >= 2^(L-1)) {
88 * Test whether or not p is prime as specified in Appendix C.3.
89 * If p is determined to be prime, then return VALID and the values of p, qand (optionally) the values of domain_parameter_seed and counter
90 * }
91 * offset = offset + n + 1 Comment: Increment offset
92 * }
93 */
94
95 seedbytes = group_size;
96 L = modulus_size * 8;
97 N = group_size * 8;
98
99 /* M-R tests (when followed by one Lucas test) according FIPS-186-4 - Appendix C.3 - table C.1 */
100 mr_tests_p = (L <= 2048) ? 3 : 2;
101 if (N <= 160) { mr_tests_q = 19; }
102 else if (N <= 224) { mr_tests_q = 24; }
103 else { mr_tests_q = 27; }
104
105 if (N <= 256) {
106 hash = register_hash(&sha256_desc);
107 }
108 else if (N <= 384) {
109 hash = register_hash(&sha384_desc);
110 }
111 else if (N <= 512) {
112 hash = register_hash(&sha512_desc);
113 }
114 else {
115 return CRYPT_INVALID_ARG; /* group_size too big */
116 }
117
118 if ((err = hash_is_valid(hash)) != CRYPT_OK) { return err; }
119 outbytes = hash_descriptor[hash].hashsize;
120
121 n = ((L + outbytes*8 - 1) / (outbytes*8)) - 1;
122
123 if ((wbuf = XMALLOC((n+1)*outbytes)) == NULL) { err = CRYPT_MEM; goto cleanup3; }
124 if ((sbuf = XMALLOC(seedbytes)) == NULL) { err = CRYPT_MEM; goto cleanup2; }
125
126 err = mp_init_multi(&t2L1, &t2N1, &t2q, &t2seedlen, &U, &W, &X, &c, &h, &e, &seedinc, NULL);
127 if (err != CRYPT_OK) { goto cleanup1; };
128
129 if ((err = mp_2expt(t2L1, L-1)) != CRYPT_OK) { goto cleanup; }
130 /* t2L1 = 2^(L-1) */
131 if ((err = mp_2expt(t2N1, N-1)) != CRYPT_OK) { goto cleanup; }
132 /* t2N1 = 2^(N-1) */
133 if ((err = mp_2expt(t2seedlen, seedbytes*8)) != CRYPT_OK) { goto cleanup; }
134 /* t2seedlen = 2^seedlen */
135
136 for(found_p=0; !found_p;) {
137 /* q */
138 for(found_q=0; !found_q;) {
139 if (prng_descriptor[wprng].read(sbuf, seedbytes, prng) != seedbytes) { err = CRYPT_ERROR_READPRNG; goto cleanup; }
140 i = outbytes;
141 if ((err = hash_memory(hash, sbuf, seedbytes, digest, &i)) != CRYPT_OK) { goto cleanup; }
142 if ((err = mp_read_unsigned_bin(U, digest, outbytes)) != CRYPT_OK) { goto cleanup; }
143 if ((err = mp_mod(U, t2N1, U)) != CRYPT_OK) { goto cleanup; }
144 if ((err = mp_add(t2N1, U, q)) != CRYPT_OK) { goto cleanup; }
145 if (!mp_isodd(q)) mp_add_d(q, 1, q);
146 err = mp_prime_is_prime_ex(q, mr_tests_q, &res, rng_helper, &rng);
147 if (err != CRYPT_OK) { goto cleanup; }
148 if (res == LTC_MP_YES) found_q = 1;
149 }
150
151 /* p */
152 if ((err = mp_read_unsigned_bin(seedinc, sbuf, seedbytes)) != CRYPT_OK) { goto cleanup; }
153 /* printf("seed="); mp_fwrite(seedinc, 16, stdout); printf("\n"); //XXX-DEBUG */
154 if ((err = mp_add(q, q, t2q)) != CRYPT_OK) { goto cleanup; }
155 for(counter=0; counter < 4*L && !found_p; counter++) {
156 for(j=0; j<=n; j++) {
157 if ((err = mp_add_d(seedinc, 1, seedinc)) != CRYPT_OK) { goto cleanup; }
158 if ((err = mp_mod(seedinc, t2seedlen, seedinc)) != CRYPT_OK) { goto cleanup; }
159 /* seedinc = (seedinc+1) % 2^seed_bitlen */
160 if ((i = mp_unsigned_bin_size(seedinc)) > seedbytes) { err = CRYPT_INVALID_ARG; goto cleanup; }
161 zeromem(sbuf, seedbytes);
162 if ((err = mp_to_unsigned_bin(seedinc, sbuf + seedbytes-i)) != CRYPT_OK) { goto cleanup; }
163 i = outbytes;
164 err = hash_memory(hash, sbuf, seedbytes, wbuf+(n-j)*outbytes, &i);
165 if (err != CRYPT_OK) { goto cleanup; }
166 }
167 if ((err = mp_read_unsigned_bin(W, wbuf, (n+1)*outbytes)) != CRYPT_OK) { goto cleanup; }
168 if ((err = mp_mod(W, t2L1, W)) != CRYPT_OK) { goto cleanup; }
169 if ((err = mp_add(W, t2L1, X)) != CRYPT_OK) { goto cleanup; }
170 if ((err = mp_mod(X, t2q, c)) != CRYPT_OK) { goto cleanup; }
171 if ((err = mp_sub_d(c, 1, p)) != CRYPT_OK) { goto cleanup; }
172 if ((err = mp_sub(X, p, p)) != CRYPT_OK) { goto cleanup; }
173 if (mp_cmp(p, t2L1) != LTC_MP_LT) {
174 /* p >= 2^(L-1) */
175 err = mp_prime_is_prime_ex(p, mr_tests_p, &res, rng_helper, &rng);
176 if (err != CRYPT_OK) { goto cleanup; }
177 if (res == LTC_MP_YES) found_p = 1;
178 }
179 }
180 }
181
182 /* FIPS-186-4 A.2.1 Unverifiable Generation of the Generator g
183 * 1. e = (p - 1)/q
184 * 2. h = any integer satisfying: 1 < h < (p - 1)
185 * h could be obtained from a random number generator or from a counter that changes after each use
186 * 3. g = h^e mod p
187 * 4. if (g == 1), then go to step 2.
188 *
189 */
190
191 if ((err = mp_sub_d(p, 1, e)) != CRYPT_OK) { goto cleanup; }
192 if ((err = mp_div(e, q, e, c)) != CRYPT_OK) { goto cleanup; }
193 /* e = (p - 1)/q */
194 i = mp_count_bits(p);
195 do {
196 do {
197 if ((err = rand_bn_bits(h, i, prng, wprng)) != CRYPT_OK) { goto cleanup; }
198 } while (mp_cmp(h, p) != LTC_MP_LT || mp_cmp_d(h, 2) != LTC_MP_GT);
199 if ((err = mp_sub_d(h, 1, h)) != CRYPT_OK) { goto cleanup; }
200 /* h is randon and 1 < h < (p-1) */
201 if ((err = mp_exptmod(h, e, p, g)) != CRYPT_OK) { goto cleanup; }
202 } while (mp_cmp_d(g, 1) == LTC_MP_EQ);
203
204 err = CRYPT_OK;
205 cleanup:
206 mp_clear_multi(t2L1, t2N1, t2q, t2seedlen, U, W, X, c, h, e, seedinc, NULL);
207 cleanup1:
208 XFREE(wbuf);
209 cleanup2:
210 XFREE(wbuf);
211 cleanup3:
212 return err;
213 }
214
215 /**
216 Create a DSA key (with given params)
217 @param prng An active PRNG state
218 @param wprng The index of the PRNG desired
219 @param group_size Size of the multiplicative group (octets)
220 @param modulus_size Size of the modulus (octets)
221 @param key [out] Where to store the created key
222 @param p_hex Hexadecimal string 'p'
223 @param q_hex Hexadecimal string 'q'
224 @param g_hex Hexadecimal string 'g'
225 @return CRYPT_OK if successful, upon error this function will free all allocated memory
226 */
227 int dsa_make_key_ex(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key, char* p_hex, char* q_hex, char* g_hex)
228 {
229 int err, qbits;
230
231 LTC_ARGCHK(key != NULL);
232
233 /* init mp_ints */
234 if ((err = mp_init_multi(&key->g, &key->q, &key->p, &key->x, &key->y, NULL)) != CRYPT_OK) {
235 return err;
236 }
237
238 if (p_hex == NULL || q_hex == NULL || g_hex == NULL) {
239 /* generate params */
240 err = dsa_make_params(prng, wprng, group_size, modulus_size, key->p, key->q, key->g);
241 if (err != CRYPT_OK) { goto cleanup; }
242 }
243 else {
244 /* read params */
245 if ((err = mp_read_radix(key->p, p_hex, 16)) != CRYPT_OK) { goto cleanup; }
246 if ((err = mp_read_radix(key->q, q_hex, 16)) != CRYPT_OK) { goto cleanup; }
247 if ((err = mp_read_radix(key->g, g_hex, 16)) != CRYPT_OK) { goto cleanup; }
248 /* XXX-TODO maybe do some validity check for p, q, g */
249 }
250
251 /* so now we have our DH structure, generator g, order q, modulus p
252 Now we need a random exponent [mod q] and it's power g^x mod p
253 */
254 qbits = mp_count_bits(key->q);
255 do {
256 if ((err = rand_bn_bits(key->x, qbits, prng, wprng)) != CRYPT_OK) { goto cleanup; }
257 /* private key x should be from range: 1 <= x <= q-1 (see FIPS 186-4 B.1.2) */
258 } while (mp_cmp_d(key->x, 0) != LTC_MP_GT || mp_cmp(key->x, key->q) != LTC_MP_LT);
259 if ((err = mp_exptmod(key->g, key->x, key->p, key->y)) != CRYPT_OK) { goto cleanup; }
260 key->type = PK_PRIVATE;
261 key->qord = group_size;
262
263 return CRYPT_OK;
264
265 cleanup:
266 mp_clear_multi(key->g, key->q, key->p, key->x, key->y, NULL);
267 return err;
27268 }
28269
29270 /**
37278 */
38279 int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key)
39280 {
40 void *tmp, *tmp2;
41 int err, res, q_size;
42 unsigned char *buf;
43 struct rng_data rng;
44
45 LTC_ARGCHK(key != NULL);
46 LTC_ARGCHK(ltc_mp.name != NULL);
47
48 /* check prng */
49 if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
50 return err;
51 }
52
53 /* setup rng struct - used later for callback */
54 rng.prng = prng;
55 rng.wprng = wprng;
56
57 /* check size */
58 if (group_size >= LTC_MDSA_MAX_GROUP || group_size <= 15 ||
59 group_size >= modulus_size || (modulus_size - group_size) >= LTC_MDSA_DELTA) {
60 return CRYPT_INVALID_ARG;
61 }
62
63 /* allocate ram */
64 buf = XMALLOC(LTC_MDSA_DELTA);
65 if (buf == NULL) {
66 return CRYPT_MEM;
67 }
68
69 /* init mp_ints */
70 if ((err = mp_init_multi(&tmp, &tmp2, &key->g, &key->q, &key->p, &key->x, &key->y, NULL)) != CRYPT_OK) {
71 XFREE(buf);
72 return err;
73 }
74
75 /* make our prime q */
76 if ((err = rand_prime(key->q, group_size, prng, wprng)) != CRYPT_OK) { goto error; }
77
78 /* double q */
79 if ((err = mp_add(key->q, key->q, tmp)) != CRYPT_OK) { goto error; }
80
81 /* now make a random string and multply it against q */
82 if (prng_descriptor[wprng].read(buf+1, modulus_size - group_size, prng) != (unsigned long)(modulus_size - group_size)) {
83 err = CRYPT_ERROR_READPRNG;
84 goto error;
85 }
86
87 /* force magnitude */
88 buf[0] |= 0xC0;
89
90 /* force even */
91 buf[modulus_size - group_size - 1] &= ~1;
92
93 if ((err = mp_read_unsigned_bin(tmp2, buf, modulus_size - group_size)) != CRYPT_OK) { goto error; }
94 if ((err = mp_mul(key->q, tmp2, key->p)) != CRYPT_OK) { goto error; }
95 if ((err = mp_add_d(key->p, 1, key->p)) != CRYPT_OK) { goto error; }
96
97 /* now loop until p is prime */
98 for (;;) {
99 if ((err = mp_prime_is_prime_ex(key->p, 0, &res, rand_prime_helper, &rng)) != CRYPT_OK) { goto error; }
100 if (res == LTC_MP_YES) break;
101
102 /* add 2q to p and 2 to tmp2 */
103 if ((err = mp_add(tmp, key->p, key->p)) != CRYPT_OK) { goto error; }
104 if ((err = mp_add_d(tmp2, 2, tmp2)) != CRYPT_OK) { goto error; }
105 }
106
107 /* now p = (q * tmp2) + 1 is prime, find a value g for which g^tmp2 != 1 */
108 mp_set(key->g, 1);
109
110 do {
111 if ((err = mp_add_d(key->g, 1, key->g)) != CRYPT_OK) { goto error; }
112 if ((err = mp_exptmod(key->g, tmp2, key->p, tmp)) != CRYPT_OK) { goto error; }
113 } while (mp_cmp_d(tmp, 1) == LTC_MP_EQ);
114
115 /* at this point tmp generates a group of order q mod p */
116 mp_exch(tmp, key->g);
117
118 /* so now we have our DH structure, generator g, order q, modulus p
119 Now we need a random exponent [mod q] and it's power g^x mod p
120 */
121 q_size = mp_unsigned_bin_size(key->q);
122 do {
123 if (prng_descriptor[wprng].read(buf, q_size, prng) != (unsigned long)q_size) {
124 err = CRYPT_ERROR_READPRNG;
125 goto error;
126 }
127 if ((err = mp_read_unsigned_bin(key->x, buf, q_size)) != CRYPT_OK) { goto error; }
128 } while (mp_cmp_d(key->x, 1) != LTC_MP_GT || mp_cmp(key->x, key->q) != LTC_MP_LT);
129 if ((err = mp_exptmod(key->g, key->x, key->p, key->y)) != CRYPT_OK) { goto error; }
130
131 key->type = PK_PRIVATE;
132 key->qord = group_size;
133
134 #ifdef LTC_CLEAN_STACK
135 zeromem(buf, LTC_MDSA_DELTA);
136 #endif
137
138 err = CRYPT_OK;
139 goto done;
140 error:
141 mp_clear_multi(key->g, key->q, key->p, key->x, key->y, NULL);
142 done:
143 mp_clear_multi(tmp, tmp2, NULL);
144 XFREE(buf);
145 return err;
281 return dsa_make_key_ex(prng, wprng, group_size, modulus_size, key, NULL, NULL, NULL);
146282 }
147283
148284 #endif
3333 {
3434 void *k, *kinv, *tmp;
3535 unsigned char *buf;
36 int err;
36 int err, qbits;
3737
3838 LTC_ARGCHK(in != NULL);
3939 LTC_ARGCHK(r != NULL);
6060 /* Init our temps */
6161 if ((err = mp_init_multi(&k, &kinv, &tmp, NULL)) != CRYPT_OK) { goto ERRBUF; }
6262
63 qbits = mp_count_bits(key->q);
6364 retry:
6465
6566 do {
6667 /* gen random k */
67 if (prng_descriptor[wprng].read(buf, key->qord, prng) != (unsigned long)key->qord) {
68 err = CRYPT_ERROR_READPRNG;
69 goto error;
70 }
68 if ((err = rand_bn_bits(k, qbits, prng, wprng)) != CRYPT_OK) { goto error; }
7169
72 /* read k */
73 if ((err = mp_read_unsigned_bin(k, buf, key->qord)) != CRYPT_OK) { goto error; }
74
75 /* k > 1 and k < q ? */
76 if (mp_cmp_d(k, 1) != LTC_MP_GT || mp_cmp(k, key->q) != LTC_MP_LT) { goto retry; }
70 /* k should be from range: 1 <= k <= q-1 (see FIPS 186-4 B.2.2) */
71 if (mp_cmp_d(k, 0) != LTC_MP_GT || mp_cmp(k, key->q) != LTC_MP_LT) { goto retry; }
7772
7873 /* test gcd */
7974 if ((err = mp_gcd(k, key->q, tmp)) != CRYPT_OK) { goto error; }
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
2927 14,
3028 "SECP112R1",
3129 "DB7C2ABF62E35E668076BEAD208B",
30 "DB7C2ABF62E35E668076BEAD2088",
3231 "659EF8BA043916EEDE8911702B22",
3332 "DB7C2ABF62E35E7628DFAC6561C5",
3433 "09487239995A5EE76B55F9C2F098",
35 "A89CE5AF8724C0A23E0E0FF77500"
34 "A89CE5AF8724C0A23E0E0FF77500",
35 1
3636 },
3737 #endif
3838 #ifdef ECC128
4040 16,
4141 "SECP128R1",
4242 "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
43 "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC",
4344 "E87579C11079F43DD824993C2CEE5ED3",
4445 "FFFFFFFE0000000075A30D1B9038A115",
4546 "161FF7528B899B2D0C28607CA52C5B86",
4647 "CF5AC8395BAFEB13C02DA292DDED7A83",
48 1
4749 },
4850 #endif
4951 #ifdef ECC160
5153 20,
5254 "SECP160R1",
5355 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF",
56 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC",
5457 "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45",
5558 "0100000000000000000001F4C8F927AED3CA752257",
5659 "4A96B5688EF573284664698968C38BB913CBFC82",
5760 "23A628553168947D59DCC912042351377AC5FB32",
61 1
5862 },
5963 #endif
6064 #ifdef ECC192
6266 24,
6367 "ECC-192",
6468 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
69 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
6570 "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1",
6671 "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",
6772 "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
6873 "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811",
74 1
6975 },
7076 #endif
7177 #ifdef ECC224
7379 28,
7480 "ECC-224",
7581 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
82 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
7683 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
7784 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
7885 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
7986 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
87 1
8088 },
8189 #endif
8290 #ifdef ECC256
8492 32,
8593 "ECC-256",
8694 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
95 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
8796 "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
8897 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
8998 "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
9099 "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
100 1
91101 },
92102 #endif
93103 #ifdef ECC384
95105 48,
96106 "ECC-384",
97107 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
108 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
98109 "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
99110 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
100111 "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
101112 "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
113 1,
102114 },
103115 #endif
104116 #ifdef ECC521
106118 66,
107119 "ECC-521",
108120 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
121 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
109122 "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
110123 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
111124 "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
112125 "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
126 1,
113127 },
114128 #endif
115129 {
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
9088 }
9189
9290 /* import ECC key from packet */
93 if ((err = ecc_import(decode[1].data, decode[1].size, &pubkey)) != CRYPT_OK) {
91 if ((err = ecc_import_raw(decode[1].data, decode[1].size, &pubkey, (ltc_ecc_set_type *)key->dp)) != CRYPT_OK) {
9492 goto LBL_ERR;
9593 }
9694
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9
10 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
11 *
12 */
13
14 #include "tomcrypt.h"
15
16 #ifdef LTC_MECC
17
18 int ecc_dp_clear(ltc_ecc_set_type *dp)
19 {
20 if (dp == NULL) return CRYPT_INVALID_ARG;
21
22 if (dp->name != NULL) { XFREE(dp->name ); dp->name = NULL; }
23 if (dp->prime != NULL) { XFREE(dp->prime); dp->prime = NULL; }
24 if (dp->A != NULL) { XFREE(dp->A ); dp->A = NULL; }
25 if (dp->B != NULL) { XFREE(dp->B ); dp->B = NULL; }
26 if (dp->order != NULL) { XFREE(dp->order); dp->order = NULL; }
27 if (dp->Gx != NULL) { XFREE(dp->Gx ); dp->Gx = NULL; }
28 if (dp->Gy != NULL) { XFREE(dp->Gy ); dp->Gy = NULL; }
29 dp->cofactor = 0;
30
31 return CRYPT_OK;
32 }
33
34 #endif
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9
10 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
11 *
12 */
13
14 #include "tomcrypt.h"
15
16 #ifdef LTC_MECC
17
18 int ecc_dp_init(ltc_ecc_set_type *dp)
19 {
20 if (dp == NULL) return CRYPT_INVALID_ARG;
21
22 dp->name = NULL;
23 dp->prime = NULL;
24 dp->A = NULL;
25 dp->B = NULL;
26 dp->order = NULL;
27 dp->Gx = NULL;
28 dp->Gy = NULL;
29 dp->cofactor = 0;
30
31 return CRYPT_OK;
32 }
33
34 #endif
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9
10 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
11 *
12 */
13
14 #include "tomcrypt.h"
15
16 #ifdef LTC_MECC
17
18 int ecc_dp_set(ltc_ecc_set_type *dp, char *ch_prime, char *ch_A, char *ch_B, char *ch_order, char *ch_Gx, char *ch_Gy, unsigned long cofactor, char *ch_name)
19 {
20 unsigned long l_name, l_prime, l_A, l_B, l_order, l_Gx, l_Gy;
21
22 if (!dp || !ch_prime || !ch_A || !ch_B || !ch_order || !ch_Gx || !ch_Gy || cofactor==0) return CRYPT_INVALID_ARG;
23
24 l_name = (unsigned long)strlen(ch_name);
25 l_prime = (unsigned long)strlen(ch_prime);
26 l_A = (unsigned long)strlen(ch_A);
27 l_B = (unsigned long)strlen(ch_B);
28 l_order = (unsigned long)strlen(ch_order);
29 l_Gx = (unsigned long)strlen(ch_Gx);
30 l_Gy = (unsigned long)strlen(ch_Gy);
31
32 dp->cofactor = cofactor;
33
34 { /* calculate size */
35 void *p_num;
36 mp_init(&p_num);
37 mp_read_radix(p_num, ch_prime, 16);
38 dp->size = mp_unsigned_bin_size(p_num);
39 mp_clear(p_num);
40 }
41
42 if (dp->name != NULL) { XFREE(dp->name ); dp->name = NULL; }
43 if (dp->prime != NULL) { XFREE(dp->prime); dp->prime = NULL; }
44 if (dp->A != NULL) { XFREE(dp->A ); dp->A = NULL; }
45 if (dp->B != NULL) { XFREE(dp->B ); dp->B = NULL; }
46 if (dp->order != NULL) { XFREE(dp->order); dp->order = NULL; }
47 if (dp->Gx != NULL) { XFREE(dp->Gx ); dp->Gx = NULL; }
48 if (dp->Gy != NULL) { XFREE(dp->Gy ); dp->Gy = NULL; }
49
50 dp->name = XMALLOC(1+l_name); strncpy(dp->name, ch_name, 1+l_name);
51 dp->prime = XMALLOC(1+l_prime); strncpy(dp->prime, ch_prime, 1+l_prime);
52 dp->A = XMALLOC(1+l_A); strncpy(dp->A, ch_A, 1+l_A);
53 dp->B = XMALLOC(1+l_B); strncpy(dp->B, ch_B, 1+l_B);
54 dp->order = XMALLOC(1+l_order); strncpy(dp->order, ch_order, 1+l_order);
55 dp->Gx = XMALLOC(1+l_Gx); strncpy(dp->Gx, ch_Gx, 1+l_Gx);
56 dp->Gy = XMALLOC(1+l_Gy); strncpy(dp->Gy, ch_Gy, 1+l_Gy);
57
58 return CRYPT_OK;
59 }
60
61 #endif
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
8583 }
8684
8785 pubkeysize = ECC_BUF_SIZE;
88 if ((err = ecc_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) {
86 if ((err = ecc_export_raw(pub_expt, &pubkeysize, PK_PUBLIC_COMPRESSED, &pubkey)) != CRYPT_OK) {
8987 ecc_free(&pubkey);
9088 goto LBL_ERR;
9189 }
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9
10 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
11 *
12 */
13
14 #include "tomcrypt.h"
15
16 #ifdef LTC_MECC
17
18 /**
19 Export an ECC key as a binary packet
20 @param out [out] Destination for the key
21 @param outlen [in/out] Max size and resulting size of the exported key
22 @param type The type of key you want to export (PK_PRIVATE or PK_PUBLIC)
23 @param key The key to export
24 @return CRYPT_OK if successful
25 */
26
27 int ecc_export_full(unsigned char *out, unsigned long *outlen, int type, ecc_key *key)
28 {
29 int err;
30 void *prime, *order, *a, *b, *gx, *gy;
31 unsigned char bin_a[256], bin_b[256], bin_k[256], bin_g[512], bin_xy[512];
32 unsigned long len_a, len_b, len_k, len_g, len_xy;
33 unsigned long cofactor, one = 1;
34 oid_st oid;
35 ltc_asn1_list seq_fieldid[2], seq_curve[2], seq_ecparams[6], seq_priv[4];
36
37 LTC_ARGCHK(out != NULL);
38 LTC_ARGCHK(outlen != NULL);
39 LTC_ARGCHK(key != NULL);
40
41 if (key->type != PK_PRIVATE && type == PK_PRIVATE) return CRYPT_PK_TYPE_MISMATCH;
42 if (ltc_ecc_is_valid_idx(key->idx) == 0) return CRYPT_INVALID_ARG;
43
44 if ((err = mp_init_multi(&prime, &order, &a, &b, &gx, &gy, NULL)) != CRYPT_OK) return err;
45
46 if ((err = mp_read_radix(prime, key->dp->prime, 16)) != CRYPT_OK) goto error;
47 if ((err = mp_read_radix(order, key->dp->order, 16)) != CRYPT_OK) goto error;
48 if ((err = mp_read_radix(b, key->dp->B, 16)) != CRYPT_OK) goto error;
49 if ((err = mp_read_radix(a, key->dp->A, 16)) != CRYPT_OK) goto error;
50 if ((err = mp_read_radix(gx, key->dp->Gx, 16)) != CRYPT_OK) goto error;
51 if ((err = mp_read_radix(gy, key->dp->Gy, 16)) != CRYPT_OK) goto error;
52
53 /* curve param a */
54 len_a = mp_unsigned_bin_size(a);
55 if (len_a > sizeof(bin_a)) { err = CRYPT_BUFFER_OVERFLOW; goto error; }
56 if ((err = mp_to_unsigned_bin(a, bin_a)) != CRYPT_OK) goto error;
57 if (len_a == 0) { len_a = 1; bin_a[0] = 0; } /* XXX-TODO hack to handle case a == 0 */
58
59 /* curve param b */
60 len_b = mp_unsigned_bin_size(b);
61 if (len_b > sizeof(bin_b)) { err = CRYPT_BUFFER_OVERFLOW; goto error; }
62 if ((err = mp_to_unsigned_bin(b, bin_b)) != CRYPT_OK) goto error;
63 if (len_b == 0) { len_b = 1; bin_b[0] = 0; } /* XXX-TODO hack to handle case b == 0 */
64
65 /* base point - we export uncompressed form */
66 len_g = sizeof(bin_g);
67 if ((err = ecc_export_point(bin_g, &len_g, gx, gy, key->dp->size, 0)) != CRYPT_OK) goto error;
68
69 /* public key */
70 len_xy = sizeof(bin_xy);
71 if ((err = ecc_export_point(bin_xy, &len_xy, key->pubkey.x, key->pubkey.y, key->dp->size, 0)) != CRYPT_OK) goto error;
72
73 /* co-factor */
74 cofactor = key->dp->cofactor;
75
76 /* we support only prime-field EC */
77 if ((err = pk_get_oid(EC_PRIME_FIELD, &oid)) != CRYPT_OK) goto error;
78
79 /* FieldID SEQUENCE */
80 LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid.OID, oid.OIDlen);
81 LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL);
82
83 /* Curve SEQUENCE */
84 LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, len_a);
85 LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, len_b);
86
87 /* ECParameters SEQUENCE */
88 LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &one, 1UL);
89 LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL);
90 LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 2UL);
91 LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, len_g);
92 LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL);
93 LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL);
94
95 if (type == PK_PRIVATE) {
96 /* private key format: http://tools.ietf.org/html/rfc5915
97
98 ECPrivateKey ::= SEQUENCE { # SEQUENCE
99 version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), # INTEGER :01
100 privateKey OCTET STRING, # OCTET STRING
101 [0] ECParameters ::= SEQUENCE { # SEQUENCE
102 version INTEGER { ecpVer1(1) } (ecpVer1), # INTEGER :01
103 FieldID ::= SEQUENCE { # SEQUENCE
104 fieldType FIELD-ID.&id({IOSet}), # OBJECT :prime-field
105 parameters FIELD-ID.&Type({IOSet}{@fieldType}) # INTEGER
106 }
107 Curve ::= SEQUENCE { # SEQUENCE
108 a FieldElement ::= OCTET STRING # OCTET STRING
109 b FieldElement ::= OCTET STRING # OCTET STRING
110 seed BIT STRING OPTIONAL
111 }
112 base ECPoint ::= OCTET STRING # OCTET STRING
113 order INTEGER, # INTEGER
114 cofactor INTEGER OPTIONAL # INTEGER
115 }
116 [1] publicKey # BIT STRING
117 }
118 */
119
120 /* private key */
121 len_k = mp_unsigned_bin_size(key->k);
122 if (len_k > sizeof(bin_k)) { err = CRYPT_BUFFER_OVERFLOW; goto error; }
123 if ((err = mp_to_unsigned_bin(key->k, bin_k)) != CRYPT_OK) goto error;
124
125 LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &one, 1UL);
126 LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, len_k);
127 LTC_SET_ASN1(seq_priv, 2, LTC_ASN1_SEQUENCE, seq_ecparams, 6UL);
128 LTC_SET_ASN1(seq_priv, 3, LTC_ASN1_RAW_BIT_STRING, bin_xy, 8*len_xy);
129 seq_priv[2].tag = 0xA0;
130 seq_priv[3].tag = 0xA1;
131
132 err = der_encode_sequence(seq_priv, 4, out, outlen);
133 }
134 else {
135 /* public key format: http://tools.ietf.org/html/rfc5480
136
137 SubjectPublicKeyInfo ::= SEQUENCE { # SEQUENCE
138 AlgorithmIdentifier ::= SEQUENCE { # SEQUENCE
139 algorithm OBJECT IDENTIFIER # OBJECT :id-ecPublicKey
140 ECParameters ::= SEQUENCE { # SEQUENCE
141 version INTEGER { ecpVer1(1) } (ecpVer1), # INTEGER :01
142 FieldID ::= SEQUENCE { # SEQUENCE
143 fieldType FIELD-ID.&id({IOSet}), # OBJECT :prime-field
144 parameters FIELD-ID.&Type({IOSet}{@fieldType}) # INTEGER
145 }
146 Curve ::= SEQUENCE { # SEQUENCE
147 a FieldElement ::= OCTET STRING # OCTET STRING
148 b FieldElement ::= OCTET STRING # OCTET STRING
149 seed BIT STRING OPTIONAL
150 }
151 base ECPoint ::= OCTET STRING # OCTET STRING
152 order INTEGER, # INTEGER
153 cofactor INTEGER OPTIONAL # INTEGER
154 }
155 }
156 subjectPublicKey BIT STRING # BIT STRING
157 }
158 */
159
160 err = der_encode_subject_public_key_info( out, outlen,
161 PKA_EC, bin_xy, len_xy,
162 LTC_ASN1_SEQUENCE, seq_ecparams, 6 );
163 }
164
165 error:
166 mp_clear_multi(prime, order, a, b, gx, gy, NULL);
167 return err;
168 }
169
170 #endif
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9
10 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
11 *
12 */
13
14 #include "tomcrypt.h"
15
16 #ifdef LTC_MECC
17
18 int ecc_export_point(unsigned char *out, unsigned long *outlen, void *x, void *y, unsigned long size, int compressed)
19 {
20 int err;
21 unsigned char buf[ECC_BUF_SIZE];
22 unsigned long xsize, ysize;
23
24 if (size > sizeof(buf)) return CRYPT_BUFFER_OVERFLOW;
25 if ((xsize = mp_unsigned_bin_size(x)) > size) return CRYPT_BUFFER_OVERFLOW;
26 if ((ysize = mp_unsigned_bin_size(y)) > size) return CRYPT_BUFFER_OVERFLOW;
27
28 if(compressed) {
29 if (*outlen < (1 + size)) {
30 *outlen = 1 + size;
31 return CRYPT_BUFFER_OVERFLOW;
32 }
33 /* store first byte */
34 out[0] = mp_isodd(y) ? 0x03 : 0x02;
35 /* pad and store x */
36 zeromem(buf, sizeof(buf));
37 if ((err = mp_to_unsigned_bin(x, buf + (size - xsize))) != CRYPT_OK) return err;
38 XMEMCPY(out+1, buf, size);
39 /* adjust outlen */
40 *outlen = 1 + size;
41 }
42 else {
43 if (*outlen < (1 + 2*size)) {
44 *outlen = 1 + 2*size;
45 return CRYPT_BUFFER_OVERFLOW;
46 }
47 /* store byte 0x04 */
48 out[0] = 0x04;
49 /* pad and store x */
50 zeromem(buf, sizeof(buf));
51 if ((err = mp_to_unsigned_bin(x, buf + (size - xsize))) != CRYPT_OK) return err;
52 XMEMCPY(out+1, buf, size);
53 /* pad and store y */
54 zeromem(buf, sizeof(buf));
55 if ((err = mp_to_unsigned_bin(y, buf + (size - ysize))) != CRYPT_OK) return err;
56 XMEMCPY(out+1+size, buf, size);
57 /* adjust outlen */
58 *outlen = 1 + 2*size;
59 }
60 return CRYPT_OK;
61 }
62
63 /** Export raw public or private key (public keys = ANS X9.63 compressed or uncompressed; private keys = raw bytes)
64 @param out [out] destination of export
65 @param outlen [in/out] Length of destination and final output size
66 @param type PK_PRIVATE, PK_PUBLIC or PK_PUBLIC_COMPRESSED
67 @param key Key to export
68 Return CRYPT_OK on success
69 */
70
71 int ecc_export_raw(unsigned char *out, unsigned long *outlen, int type, ecc_key *key)
72 {
73 unsigned long size, ksize;
74 int err;
75
76 LTC_ARGCHK(key != NULL);
77 LTC_ARGCHK(out != NULL);
78 LTC_ARGCHK(outlen != NULL);
79
80 if (ltc_ecc_is_valid_idx(key->idx) == 0) {
81 return CRYPT_INVALID_ARG;
82 }
83 size = key->dp->size;
84
85 if (type == PK_PUBLIC_COMPRESSED) {
86 if ((err = ecc_export_point(out, outlen, key->pubkey.x, key->pubkey.y, size, 1)) != CRYPT_OK) return err;
87 }
88 else if (type == PK_PUBLIC) {
89 if ((err = ecc_export_point(out, outlen, key->pubkey.x, key->pubkey.y, size, 0)) != CRYPT_OK) return err;
90 }
91 else if (type == PK_PRIVATE) {
92 if (key->type != PK_PRIVATE) return CRYPT_PK_TYPE_MISMATCH;
93 *outlen = size;
94 if (size > *outlen) return CRYPT_BUFFER_OVERFLOW;
95 if ((ksize = mp_unsigned_bin_size(key->k)) > size) return CRYPT_BUFFER_OVERFLOW;
96 /* pad and store k */
97 if ((err = mp_to_unsigned_bin(key->k, out + (size - ksize))) != CRYPT_OK) return err;
98 zeromem(out, size - ksize);
99 }
100 else {
101 return CRYPT_INVALID_ARG;
102 }
103
104 return CRYPT_OK;
105 }
106
107 #endif
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
1816 /**
1917 @file ecc_import.c
2018 ECC Crypto, Tom St Denis
21 */
19 */
2220
2321 #ifdef LTC_MECC
2422
2523 static int is_point(ecc_key *key)
2624 {
27 void *prime, *b, *t1, *t2;
25 void *prime, *a, *b, *t1, *t2;
2826 int err;
29
30 if ((err = mp_init_multi(&prime, &b, &t1, &t2, NULL)) != CRYPT_OK) {
27
28 if ((err = mp_init_multi(&prime, &a, &b, &t1, &t2, NULL)) != CRYPT_OK) {
3129 return err;
3230 }
33
34 /* load prime and b */
31
32 /* load prime, a and b */
3533 if ((err = mp_read_radix(prime, key->dp->prime, 16)) != CRYPT_OK) { goto error; }
3634 if ((err = mp_read_radix(b, key->dp->B, 16)) != CRYPT_OK) { goto error; }
37
35 if ((err = mp_read_radix(a, key->dp->A, 16)) != CRYPT_OK) { goto error; }
36
3837 /* compute y^2 */
3938 if ((err = mp_sqr(key->pubkey.y, t1)) != CRYPT_OK) { goto error; }
40
39
4140 /* compute x^3 */
4241 if ((err = mp_sqr(key->pubkey.x, t2)) != CRYPT_OK) { goto error; }
4342 if ((err = mp_mod(t2, prime, t2)) != CRYPT_OK) { goto error; }
4443 if ((err = mp_mul(key->pubkey.x, t2, t2)) != CRYPT_OK) { goto error; }
45
44
4645 /* compute y^2 - x^3 */
4746 if ((err = mp_sub(t1, t2, t1)) != CRYPT_OK) { goto error; }
48
49 /* compute y^2 - x^3 + 3x */
50 if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; }
51 if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; }
52 if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; }
53 if ((err = mp_mod(t1, prime, t1)) != CRYPT_OK) { goto error; }
47
48 /* compute y^2 - x^3 - a*x */
49 if ((err = mp_submod(prime, a, prime, t2)) != CRYPT_OK) { goto error; }
50 if ((err = mp_mulmod(t2, key->pubkey.x, prime, t2)) != CRYPT_OK) { goto error; }
51 if ((err = mp_addmod(t1, t2, prime, t1)) != CRYPT_OK) { goto error; }
52
53 /* adjust range (0, prime) */
5454 while (mp_cmp_d(t1, 0) == LTC_MP_LT) {
5555 if ((err = mp_add(t1, prime, t1)) != CRYPT_OK) { goto error; }
5656 }
5757 while (mp_cmp(t1, prime) != LTC_MP_LT) {
5858 if ((err = mp_sub(t1, prime, t1)) != CRYPT_OK) { goto error; }
5959 }
60
60
6161 /* compare to b */
6262 if (mp_cmp(t1, b) != LTC_MP_EQ) {
6363 err = CRYPT_INVALID_PACKET;
6464 } else {
6565 err = CRYPT_OK;
6666 }
67
67
6868 error:
6969 mp_clear_multi(prime, b, t1, t2, NULL);
7070 return err;
106106 }
107107
108108 /* find out what type of key it is */
109 if ((err = der_decode_sequence_multi(in, inlen,
109 if ((err = der_decode_sequence_multi(in, inlen,
110110 LTC_ASN1_BIT_STRING, 1UL, &flags,
111111 LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
112112 goto done;
152152 }
153153 /* set z */
154154 if ((err = mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto done; }
155
155
156156 /* is it a point on the curve? */
157157 if ((err = is_point(key)) != CRYPT_OK) {
158158 goto done;
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
12 *
13 */
14
15 #include "tomcrypt.h"
16
17 #ifdef LTC_MECC
18
19 static int _populate_dp(void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor, ltc_ecc_set_type *dp)
20 {
21 unsigned char buf[ECC_BUF_SIZE];
22 unsigned long len;
23
24 /* a */
25 mp_tohex(a, (char *)buf);
26 len = (unsigned long)strlen((char *)buf);
27 if ((dp->A = XMALLOC(1+len)) == NULL) goto cleanup1;
28 strncpy(dp->A, (char*)buf, 1+len);
29 /* b */
30 mp_tohex(b, (char *)buf);
31 len = (unsigned long)strlen((char *)buf);
32 if ((dp->B = XMALLOC(1+len)) == NULL) goto cleanup2;
33 strncpy(dp->B, (char*)buf, 1+len);
34 /* order */
35 mp_tohex(order, (char *)buf);
36 len = (unsigned long)strlen((char *)buf);
37 if ((dp->order = XMALLOC(1+len)) == NULL) goto cleanup3;
38 strncpy(dp->order, (char*)buf, 1+len);
39 /* prime */
40 mp_tohex(prime, (char *)buf);
41 len = (unsigned long)strlen((char *)buf);
42 if ((dp->prime = XMALLOC(1+len)) == NULL) goto cleanup4;
43 strncpy(dp->prime, (char*)buf, 1+len);
44 /* gx */
45 mp_tohex(gx, (char *)buf);
46 len = (unsigned long)strlen((char *)buf);
47 if ((dp->Gx = XMALLOC(1+len)) == NULL) goto cleanup5;
48 strncpy(dp->Gx, (char*)buf, 1+len);
49 /* gy */
50 mp_tohex(gy, (char *)buf);
51 len = (unsigned long)strlen((char *)buf);
52 if ((dp->Gy = XMALLOC(1+len)) == NULL) goto cleanup6;
53 strncpy(dp->Gy, (char*)buf, 1+len);
54 /* cofactor & size */
55 dp->cofactor = cofactor;
56 dp->size = mp_unsigned_bin_size(prime);
57 /* name */
58 if ((dp->name = XMALLOC(7)) == NULL) goto cleanup7;
59 strcpy(dp->name, "custom"); /* XXX-TODO check this */
60 /* done - success */
61 return CRYPT_OK;
62
63 /* XFREE(dp->name); **** warning: statement not reached *** */
64 cleanup7:
65 XFREE(dp->Gy);
66 cleanup6:
67 XFREE(dp->Gx);
68 cleanup5:
69 XFREE(dp->prime);
70 cleanup4:
71 XFREE(dp->order);
72 cleanup3:
73 XFREE(dp->B);
74 cleanup2:
75 XFREE(dp->A);
76 cleanup1:
77 return CRYPT_MEM;
78 }
79
80 int ecc_import_full(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp)
81 {
82 void *prime, *order, *a, *b, *gx, *gy;
83 ltc_asn1_list seq_fieldid[2], seq_curve[3], seq_ecparams[6], seq_priv[4];
84 unsigned char bin_a[ECC_MAXSIZE], bin_b[ECC_MAXSIZE], bin_k[ECC_MAXSIZE], bin_g[2*ECC_MAXSIZE+1], bin_xy[2*ECC_MAXSIZE+2], bin_seed[128];
85 unsigned long len_a, len_b, len_k, len_g, len_xy;
86 unsigned long cofactor = 0, ecver = 0, pkver = 0, tmpoid[16];
87 /*oid_st oid;*/
88 int err;
89
90 if ((err = mp_init_multi(&prime, &order, &a, &b, &gx, &gy, NULL)) != CRYPT_OK) return err;
91
92 /* ### 1. try to load public key */
93
94 /* ECParameters SEQUENCE */
95 LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &ecver, 1UL);
96 LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL);
97 LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 3UL);
98 LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, (unsigned long)2*ECC_MAXSIZE+1);
99 LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL);
100 LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL);
101 seq_ecparams[5].optional = 1;
102 /* FieldID SEQUENCE */
103 LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, 16UL);
104 LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL);
105 /* Curve SEQUENCE */
106 LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, (unsigned long)ECC_MAXSIZE);
107 LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, (unsigned long)ECC_MAXSIZE);
108 LTC_SET_ASN1(seq_curve, 2, LTC_ASN1_RAW_BIT_STRING, bin_seed, (unsigned long)8*128);
109 seq_curve[2].optional = 1;
110
111 /* try to load public key */
112 len_xy = sizeof(bin_xy);
113 err = der_decode_subject_public_key_info(in, inlen, PKA_EC, bin_xy, &len_xy, LTC_ASN1_SEQUENCE, seq_ecparams, 6);
114 if (err == CRYPT_OK) {
115 len_a = seq_curve[0].size;
116 len_b = seq_curve[1].size;
117 len_g = seq_ecparams[3].size;
118 /* create bignums */
119 if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto error; }
120 if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; }
121 if ((err = ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; }
122 /* load curve parameters */
123 if ((err = _populate_dp(a, b, prime, order, gx, gy, cofactor, dp)) != CRYPT_OK) { goto error; }
124 /* load public key */
125 if ((err = ecc_import_raw(bin_xy, len_xy, key, dp)) != CRYPT_OK) { goto error; }
126 goto success;
127 }
128
129 /* ### 2. try to load private key */
130
131 /* ECPrivateKey SEQUENCE */
132 LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &pkver, 1UL);
133 LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, (unsigned long)ECC_MAXSIZE);
134 LTC_SET_ASN1(seq_priv, 2, LTC_ASN1_SEQUENCE, seq_ecparams, 6UL);
135 LTC_SET_ASN1(seq_priv, 3, LTC_ASN1_RAW_BIT_STRING, bin_xy, (unsigned long)8*(2*ECC_MAXSIZE+2));
136 seq_priv[2].tag = 0xA0;
137 seq_priv[3].tag = 0xA1;
138 /* ECParameters SEQUENCE */
139 LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &ecver, 1UL);
140 LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL);
141 LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 3UL);
142 LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, (unsigned long)2*ECC_MAXSIZE+1);
143 LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL);
144 LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL);
145 seq_ecparams[5].optional = 1;
146 /* FieldID SEQUENCE */
147 LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, 16UL);
148 LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL);
149 /* Curve SEQUENCE */
150 LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, (unsigned long)ECC_MAXSIZE);
151 LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, (unsigned long)ECC_MAXSIZE);
152 LTC_SET_ASN1(seq_curve, 2, LTC_ASN1_RAW_BIT_STRING, bin_seed, (unsigned long)8*128);
153 seq_curve[2].optional = 1;
154
155 /* try to load private key */
156 err = der_decode_sequence(in, inlen, seq_priv, 3);
157 if (err == CRYPT_OK) {
158 len_k = seq_priv[1].size;
159 len_xy = seq_priv[3].size;
160 len_a = seq_curve[0].size;
161 len_b = seq_curve[1].size;
162 len_g = seq_ecparams[3].size;
163 /* create bignums */
164 if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto error; }
165 if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; }
166 if ((err = ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; }
167 /* load curve parameters */
168 if ((err = _populate_dp(a, b, prime, order, gx, gy, cofactor, dp)) != CRYPT_OK) { goto error; }
169 /* load private+public key */
170 if ((err = ecc_import_raw(bin_k, len_k, key, dp)) != CRYPT_OK) { goto error; }
171 goto success;
172 }
173
174 /* ### 3. backward compatibility - try to load old-DER format */
175 if ((err = ecc_import(in, inlen, key)) != CRYPT_OK) { goto error; }
176
177 success:
178 err = CRYPT_OK;
179 error:
180 mp_clear_multi(prime, order, a, b, gx, gy, NULL);
181 return err;
182 }
183
184 #endif
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9
10 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
11 *
12 */
13
14 #include "tomcrypt.h"
15
16 #ifdef LTC_MECC
17
18 int ecc_import_point(const unsigned char *in, unsigned long inlen, void *prime, void *a, void *b, void *x, void *y)
19 {
20 int err;
21 unsigned long size;
22 void *t1, *t2;
23
24 /* init key + temporary numbers */
25 if (mp_init_multi(&t1, &t2, NULL) != CRYPT_OK) {
26 return CRYPT_MEM;
27 }
28
29 size = mp_unsigned_bin_size(prime);
30
31 if (in[0] == 0x04 && (inlen&1) && ((inlen-1)>>1) == size) {
32 /* read uncompressed point */
33 /* load x */
34 if ((err = mp_read_unsigned_bin(x, (unsigned char *)in+1, size)) != CRYPT_OK) {
35 goto cleanup;
36 }
37 /* load y */
38 if ((err = mp_read_unsigned_bin(y, (unsigned char *)in+1+size, size)) != CRYPT_OK) {
39 goto cleanup;
40 }
41 }
42 else if ((in[0] == 0x02 || in[0] == 0x03) && (inlen-1) == size) {
43 /* read compressed point */
44 /* load x */
45 if ((err = mp_read_unsigned_bin(x, (unsigned char *)in+1, size)) != CRYPT_OK) {
46 goto cleanup;
47 }
48 /* compute x^3 */
49 if ((err = mp_sqr(x, t1)) != CRYPT_OK) { goto cleanup; }
50 if ((err = mp_mulmod(t1, x, prime, t1)) != CRYPT_OK) { goto cleanup; }
51 /* compute x^3 + a*x */
52 if ((err = mp_mulmod(a, x, prime, t2)) != CRYPT_OK) { goto cleanup; }
53 if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto cleanup; }
54 /* compute x^3 + a*x + b */
55 if ((err = mp_add(t1, b, t1)) != CRYPT_OK) { goto cleanup; }
56 /* compute sqrt(x^3 + a*x + b) */
57 if ((err = mp_sqrtmod_prime(t1, prime, t2)) != CRYPT_OK) { goto cleanup; }
58 /* adjust y */
59 if ((mp_isodd(t2) && in[0] == 0x03) || (!mp_isodd(t2) && in[0] == 0x02)) {
60 if ((err = mp_mod(t2, prime, y)) != CRYPT_OK) { goto cleanup; }
61 }
62 else {
63 if ((err = mp_submod(prime, t2, prime, y)) != CRYPT_OK) { goto cleanup; }
64 }
65 }
66 else {
67 err = CRYPT_INVALID_PACKET;
68 goto cleanup;
69 }
70
71 err = CRYPT_OK;
72 cleanup:
73 mp_clear_multi(t1, t2, NULL);
74 return err;
75 }
76
77 /** Import raw public or private key (public keys = ANSI X9.63 compressed or uncompressed; private keys = raw bytes)
78 @param in The input data to read
79 @param inlen The length of the input data
80 @param key [out] destination to store imported key
81 @param dp Curve parameters
82 Return CRYPT_OK on success
83 */
84
85 int ecc_import_raw(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp)
86 {
87 int err, type = -1;
88 unsigned long size = 0;
89 void *prime, *a, *b;
90 ecc_point *base;
91
92 LTC_ARGCHK(in != NULL);
93 LTC_ARGCHK(key != NULL);
94 LTC_ARGCHK(dp != NULL);
95
96 /* init key + temporary numbers */
97 if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, &prime, &a, &b, NULL) != CRYPT_OK) {
98 return CRYPT_MEM;
99 }
100
101 if (inlen == (unsigned long)dp->size) {
102 /* read PRIVATE key */
103 type = PK_PRIVATE;
104 size = inlen;
105 /* load private k */
106 if ((err = mp_read_unsigned_bin(key->k, (unsigned char *)in, size)) != CRYPT_OK) {
107 goto cleanup;
108 }
109 if (mp_iszero(key->k)) {
110 err = CRYPT_INVALID_PACKET;
111 goto cleanup;
112 }
113 /* init base point */
114 if ((base = ltc_ecc_new_point()) == NULL) {
115 err = CRYPT_MEM;
116 goto cleanup;
117 }
118 /* load prime + base point */
119 if ((err = mp_read_radix(prime, dp->prime, 16)) != CRYPT_OK) { goto cleanup; }
120 if ((err = mp_read_radix(base->x, dp->Gx, 16)) != CRYPT_OK) { goto cleanup; }
121 if ((err = mp_read_radix(base->y, dp->Gy, 16)) != CRYPT_OK) { goto cleanup; }
122 if ((err = mp_set(base->z, 1)) != CRYPT_OK) { goto cleanup; }
123 /* make the public key */
124 if ((err = mp_read_radix(a, dp->A, 16)) != CRYPT_OK) { goto cleanup; }
125 if ((err = ltc_mp.ecc_ptmul(key->k, base, &key->pubkey, a, prime, 1)) != CRYPT_OK) {
126 goto cleanup;
127 }
128 /* cleanup */
129 ltc_ecc_del_point(base);
130 }
131 else {
132 /* read PUBLIC key */
133 type = PK_PUBLIC;
134 /* load prime + A + B */
135 if ((err = mp_read_radix(prime, dp->prime, 16)) != CRYPT_OK) { goto cleanup; }
136 if ((err = mp_read_radix(b, dp->B, 16)) != CRYPT_OK) { goto cleanup; }
137 if ((err = mp_read_radix(a, dp->A, 16)) != CRYPT_OK) { goto cleanup; }
138 err = ecc_import_point(in, inlen, prime, a, b, key->pubkey.x, key->pubkey.y);
139 if (err != CRYPT_OK) { goto cleanup; }
140 if ((err = mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto cleanup; }
141 }
142
143 if ((err = ltc_ecc_is_point(dp, key->pubkey.x, key->pubkey.y)) != CRYPT_OK) {
144 err = CRYPT_INVALID_PACKET;
145 goto cleanup;
146 }
147
148 key->type = type;
149 key->idx = -1;
150 key->dp = dp;
151
152 /* we're done */
153 mp_clear_multi(prime, a, b, NULL);
154 return CRYPT_OK;
155 cleanup:
156 mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, prime, a, b, NULL);
157 return err;
158 }
159
160 #endif
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
5048 {
5149 int err;
5250 ecc_point *base;
53 void *prime, *order;
51 void *prime, *order, *a;
5452 unsigned char *buf;
55 int keysize;
53 int keysize, orderbits;
5654
5755 LTC_ARGCHK(key != NULL);
5856 LTC_ARGCHK(ltc_mp.name != NULL);
8179 }
8280
8381 /* setup the key variables */
84 if ((err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, &prime, &order, NULL)) != CRYPT_OK) {
82 if ((err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, &prime, &order, &a, NULL)) != CRYPT_OK) {
8583 goto ERR_BUF;
8684 }
8785 base = ltc_ecc_new_point();
9896 if ((err = mp_set(base->z, 1)) != CRYPT_OK) { goto errkey; }
9997 if ((err = mp_read_unsigned_bin(key->k, (unsigned char *)buf, keysize)) != CRYPT_OK) { goto errkey; }
10098
101 /* the key should be smaller than the order of base point */
102 if (mp_cmp(key->k, order) != LTC_MP_LT) {
103 if((err = mp_mod(key->k, order, key->k)) != CRYPT_OK) { goto errkey; }
104 }
99 /* ECC key pair generation according to FIPS-186-4 (B.4.2 Key Pair Generation by Testing Candidates):
100 * the generated private key k should be the range [1, order–1]
101 * a/ N = bitlen(order)
102 * b/ generate N random bits and convert them into big integer k
103 * c/ if k not in [1, order-1] go to b/
104 * e/ Q = k*G
105 */
106 orderbits = mp_count_bits(order);
107 do {
108 if ((err = rand_bn_bits(key->k, orderbits, prng, wprng)) != CRYPT_OK) { goto errkey; }
109 } while (mp_iszero(key->k) || mp_cmp(key->k, order) != LTC_MP_LT);
110
105111 /* make the public key */
106 if ((err = ltc_mp.ecc_ptmul(key->k, base, &key->pubkey, prime, 1)) != CRYPT_OK) { goto errkey; }
112 if ((err = mp_read_radix(a, (char *)key->dp->A, 16)) != CRYPT_OK) { goto errkey; }
113 if ((err = ltc_mp.ecc_ptmul(key->k, base, &key->pubkey, a, prime, 1)) != CRYPT_OK) { goto errkey; }
107114 key->type = PK_PRIVATE;
108115
109116 /* free up ram */
113120 mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL);
114121 cleanup:
115122 ltc_ecc_del_point(base);
116 mp_clear_multi(prime, order, NULL);
123 mp_clear_multi(prime, order, a, NULL);
117124 ERR_BUF:
118125 #ifdef LTC_CLEAN_STACK
119126 zeromem(buf, ECC_MAXSIZE);
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
3533 {
3634 unsigned long x;
3735 ecc_point *result;
38 void *prime;
36 void *prime, *a;
3937 int err;
4038
4139 LTC_ARGCHK(private_key != NULL);
6260 return CRYPT_MEM;
6361 }
6462
65 if ((err = mp_init(&prime)) != CRYPT_OK) {
63 if ((err = mp_init_multi(&prime, &a, NULL)) != CRYPT_OK) {
6664 ltc_ecc_del_point(result);
6765 return err;
6866 }
6967
7068 if ((err = mp_read_radix(prime, (char *)private_key->dp->prime, 16)) != CRYPT_OK) { goto done; }
71 if ((err = ltc_mp.ecc_ptmul(private_key->k, &public_key->pubkey, result, prime, 1)) != CRYPT_OK) { goto done; }
69 if ((err = mp_read_radix(a, (char *)private_key->dp->A, 16)) != CRYPT_OK) { goto done; }
70 if ((err = ltc_mp.ecc_ptmul(private_key->k, &public_key->pubkey, result, a, prime, 1)) != CRYPT_OK) { goto done; }
7271
7372 x = (unsigned long)mp_unsigned_bin_size(prime);
7473 if (*outlen < x) {
8281 err = CRYPT_OK;
8382 *outlen = x;
8483 done:
85 mp_clear(prime);
84 mp_clear_multi(prime, a, NULL);
8685 ltc_ecc_del_point(result);
8786 return err;
8887 }
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
4038 ecc_key pubkey;
4139 void *r, *s, *e, *p;
4240 int err;
41 unsigned long pbits, pbytes, i, shift_right;
42 unsigned char ch, buf[MAXBLOCKSIZE];
4343
4444 LTC_ARGCHK(in != NULL);
4545 LTC_ARGCHK(out != NULL);
6060 return err;
6161 }
6262
63 /* get the hash and load it as a bignum into 'e' */
6463 /* init the bignums */
6564 if ((err = mp_init_multi(&r, &s, &p, &e, NULL)) != CRYPT_OK) {
6665 return err;
6766 }
6867 if ((err = mp_read_radix(p, (char *)key->dp->order, 16)) != CRYPT_OK) { goto errnokey; }
69 if ((err = mp_read_unsigned_bin(e, (unsigned char *)in, (int)inlen)) != CRYPT_OK) { goto errnokey; }
68
69 /* get the hash and load it as a bignum into 'e' */
70 pbits = mp_count_bits(p);
71 pbytes = (pbits+7) >> 3;
72 if (pbits > inlen*8) {
73 if ((err = mp_read_unsigned_bin(e, (unsigned char *)in, inlen)) != CRYPT_OK) { goto errnokey; }
74 }
75 else if (pbits % 8 == 0) {
76 if ((err = mp_read_unsigned_bin(e, (unsigned char *)in, pbytes)) != CRYPT_OK) { goto errnokey; }
77 }
78 else {
79 shift_right = 8 - pbits % 8;
80 for (i=0, ch=0; i<pbytes; i++) {
81 buf[i] = ch;
82 ch = (in[i] << (8-shift_right));
83 buf[i] = buf[i] ^ (in[i] >> shift_right);
84 }
85 if ((err = mp_read_unsigned_bin(e, (unsigned char *)buf, pbytes)) != CRYPT_OK) { goto errnokey; }
86 }
7087
7188 /* make up a key and export the public copy */
7289 for (;;) {
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
1816 /**
1917 @file ecc_verify_hash.c
2018 ECC Crypto, Tom St Denis
21 */
19 */
2220
2321 #ifdef LTC_MECC
2422
25 /* verify
23 /* verify
2624 *
2725 * w = s^-1 mod n
28 * u1 = xw
26 * u1 = xw
2927 * u2 = rw
3028 * X = u1*G + u2*Q
3129 * v = X_x1 mod n
4341 @return CRYPT_OK if successful (even if the signature is not valid)
4442 */
4543 int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
46 const unsigned char *hash, unsigned long hashlen,
44 const unsigned char *hash, unsigned long hashlen,
4745 int *stat, ecc_key *key)
4846 {
4947 ecc_point *mG, *mQ;
50 void *r, *s, *v, *w, *u1, *u2, *e, *p, *m;
48 void *r, *s, *v, *w, *u1, *u2, *e, *p, *m, *a;
5149 void *mp;
5250 int err;
51 unsigned long pbits, pbytes, i, shift_right;
52 unsigned char ch, buf[MAXBLOCKSIZE];
5353
5454 LTC_ARGCHK(sig != NULL);
5555 LTC_ARGCHK(hash != NULL);
6666 }
6767
6868 /* allocate ints */
69 if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, NULL)) != CRYPT_OK) {
69 if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, &a, NULL)) != CRYPT_OK) {
7070 return CRYPT_MEM;
7171 }
7272
9292 /* get the modulus */
9393 if ((err = mp_read_radix(m, (char *)key->dp->prime, 16)) != CRYPT_OK) { goto error; }
9494
95 /* get the a */
96 if ((err = mp_read_radix(a, (char *)key->dp->A, 16)) != CRYPT_OK) { goto error; }
97
9598 /* check for zero */
9699 if (mp_iszero(r) || mp_iszero(s) || mp_cmp(r, p) != LTC_MP_LT || mp_cmp(s, p) != LTC_MP_LT) {
97100 err = CRYPT_INVALID_PACKET;
98101 goto error;
99102 }
100103
101 /* read hash */
102 if ((err = mp_read_unsigned_bin(e, (unsigned char *)hash, (int)hashlen)) != CRYPT_OK) { goto error; }
104 /* read hash - truncate if needed */
105 pbits = mp_count_bits(p);
106 pbytes = (pbits+7) >> 3;
107 if (pbits > hashlen*8) {
108 if ((err = mp_read_unsigned_bin(e, (unsigned char *)hash, hashlen)) != CRYPT_OK) { goto error; }
109 }
110 else if (pbits % 8 == 0) {
111 if ((err = mp_read_unsigned_bin(e, (unsigned char *)hash, pbytes)) != CRYPT_OK) { goto error; }
112 }
113 else {
114 shift_right = 8 - pbits % 8;
115 for (i=0, ch=0; i<pbytes; i++) {
116 buf[i] = ch;
117 ch = (hash[i] << (8-shift_right));
118 buf[i] = buf[i] ^ (hash[i] >> shift_right);
119 }
120 if ((err = mp_read_unsigned_bin(e, (unsigned char *)buf, pbytes)) != CRYPT_OK) { goto error; }
121 }
103122
104123 /* w = s^-1 mod n */
105124 if ((err = mp_invmod(s, p, w)) != CRYPT_OK) { goto error; }
121140
122141 /* compute u1*mG + u2*mQ = mG */
123142 if (ltc_mp.ecc_mul2add == NULL) {
124 if ((err = ltc_mp.ecc_ptmul(u1, mG, mG, m, 0)) != CRYPT_OK) { goto error; }
125 if ((err = ltc_mp.ecc_ptmul(u2, mQ, mQ, m, 0)) != CRYPT_OK) { goto error; }
126
143 if ((err = ltc_mp.ecc_ptmul(u1, mG, mG, a, m, 0)) != CRYPT_OK) { goto error; }
144 if ((err = ltc_mp.ecc_ptmul(u2, mQ, mQ, a, m, 0)) != CRYPT_OK) { goto error; }
145
127146 /* find the montgomery mp */
128147 if ((err = mp_montgomery_setup(m, &mp)) != CRYPT_OK) { goto error; }
129148
130149 /* add them */
131 if ((err = ltc_mp.ecc_ptadd(mQ, mG, mG, m, mp)) != CRYPT_OK) { goto error; }
132
150 if ((err = ltc_mp.ecc_ptadd(mQ, mG, mG, a, m, mp)) != CRYPT_OK) { goto error; }
151
133152 /* reduce */
134153 if ((err = ltc_mp.ecc_map(mG, m, mp)) != CRYPT_OK) { goto error; }
135154 } else {
136155 /* use Shamir's trick to compute u1*mG + u2*mQ using half of the doubles */
137 if ((err = ltc_mp.ecc_mul2add(mG, u1, mQ, u2, mG, m)) != CRYPT_OK) { goto error; }
156 if ((err = ltc_mp.ecc_mul2add(mG, u1, mQ, u2, mG, a, m)) != CRYPT_OK) { goto error; }
138157 }
139158
140159 /* v = X_x1 mod n */
150169 error:
151170 ltc_ecc_del_point(mG);
152171 ltc_ecc_del_point(mQ);
153 mp_clear_multi(r, s, v, w, u1, u2, p, e, m, NULL);
154 if (mp != NULL) {
172 mp_clear_multi(r, s, v, w, u1, u2, p, e, m, a, NULL);
173 if (mp != NULL) {
155174 mp_montgomery_free(mp);
156175 }
157176 return err;
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9
10 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
11 *
12 */
13
14 #include "tomcrypt.h"
15
16 /* origin of this code - OLPC */
17
18 #ifdef LTC_MECC
19
20 /**
21 Verify a key according to ANSI spec
22 @param key The key to validate
23 @return CRYPT_OK if successful
24 */
25
26 int ecc_verify_key(ecc_key *key)
27 {
28 int err;
29 void *prime = NULL;
30 void *order = NULL;
31 void *a = NULL;
32 ecc_point *test_output = NULL;
33 test_output = malloc(sizeof(ecc_point));
34
35 /* XXX test_output->infinity = 0; */
36 if (mp_init_multi(&(test_output->x), &(test_output->y), &(test_output->z), &order, &prime, NULL) != CRYPT_OK) {
37 return CRYPT_MEM;
38 }
39
40 /* Test 1: Are the x amd y points of the public key in the field? */
41 if((err = ltc_mp.read_radix(prime, key->dp->prime, 16)) != CRYPT_OK) { goto error;}
42
43 if(ltc_mp.compare_d(key->pubkey.z, 1) == LTC_MP_EQ) {
44 if(
45 (ltc_mp.compare(key->pubkey.x, prime) != LTC_MP_LT)
46 || (ltc_mp.compare(key->pubkey.y, prime) != LTC_MP_LT)
47 || (ltc_mp.compare_d(key->pubkey.x, 0) != LTC_MP_GT)
48 || (ltc_mp.compare_d(key->pubkey.y, 0) != LTC_MP_GT) )
49 {
50 err = CRYPT_INVALID_PACKET;
51 goto error;
52 }
53 }
54
55 /* Test 2: is the public key on the curve? */
56 if((err = ltc_ecc_is_point(key->dp, key->pubkey.x, key->pubkey.y)) != CRYPT_OK) { goto error;}
57
58 /* Test 3: does nG = O? (n = order, 0 = point at infinity, G = public key) */
59 if((err = ltc_mp.read_radix(order, key->dp->order, 16)) != CRYPT_OK) { goto error;}
60 if((err = ltc_mp.read_radix(a, key->dp->A, 16)) != CRYPT_OK) { goto error;}
61 if((err = ltc_ecc_mulmod(order, &(key->pubkey), test_output, a, prime, 1)) != CRYPT_OK) {
62 goto error;
63 }
64
65 /* XXX
66 if(!test_output->infinity){
67 err = CRYPT_INVALID_PACKET;
68 goto error;
69 }
70 */
71
72 err = CRYPT_OK;
73 error:
74 mp_clear_multi(prime, order, test_output->z, test_output->y, test_output->x, NULL);
75 return err;
76 }
77
78 #endif
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9
10 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
11 */
12
13 #include "tomcrypt.h"
14
15 #ifdef LTC_MECC
16
17 /** Returns whether [x,y] is a point on curve defined by dp
18 @param dp curve parameters
19 @param x x point coordinate
20 @param y y point coordinate
21 @return CRYPT_OK if valid
22 */
23
24 int ltc_ecc_is_point(const ltc_ecc_set_type *dp, void *x, void *y)
25 {
26 void *prime, *a, *b, *t1, *t2;
27 int err;
28
29 if ((err = mp_init_multi(&prime, &a, &b, &t1, &t2, NULL)) != CRYPT_OK) {
30 return err;
31 }
32
33 /* load prime, a and b */
34 if ((err = mp_read_radix(prime, dp->prime, 16)) != CRYPT_OK) goto cleanup;
35 if ((err = mp_read_radix(b, dp->B, 16)) != CRYPT_OK) goto cleanup;
36 if ((err = mp_read_radix(a, dp->A, 16)) != CRYPT_OK) goto cleanup;
37
38 /* compute y^2 */
39 if ((err = mp_sqr(y, t1)) != CRYPT_OK) goto cleanup;
40
41 /* compute x^3 */
42 if ((err = mp_sqr(x, t2)) != CRYPT_OK) goto cleanup;
43 if ((err = mp_mod(t2, prime, t2)) != CRYPT_OK) goto cleanup;
44 if ((err = mp_mul(x, t2, t2)) != CRYPT_OK) goto cleanup;
45
46 /* compute y^2 - x^3 */
47 if ((err = mp_sub(t1, t2, t1)) != CRYPT_OK) goto cleanup;
48
49 /* compute y^2 - x^3 - a*x */
50 if ((err = mp_submod(prime, a, prime, t2)) != CRYPT_OK) goto cleanup;
51 if ((err = mp_mulmod(t2, x, prime, t2)) != CRYPT_OK) goto cleanup;
52 if ((err = mp_addmod(t1, t2, prime, t1)) != CRYPT_OK) goto cleanup;
53
54 /* adjust range (0, prime) */
55 while (mp_cmp_d(t1, 0) == LTC_MP_LT) {
56 if ((err = mp_add(t1, prime, t1)) != CRYPT_OK) goto cleanup;
57 }
58 while (mp_cmp(t1, prime) != LTC_MP_LT) {
59 if ((err = mp_sub(t1, prime, t1)) != CRYPT_OK) goto cleanup;
60 }
61
62 /* compare to b */
63 if (mp_cmp(t1, b) != LTC_MP_EQ) {
64 err = CRYPT_INVALID_PACKET;
65 } else {
66 err = CRYPT_OK;
67 }
68
69 cleanup:
70 mp_clear_multi(prime, b, t1, t2, NULL);
71 return err;
72 }
73
74 #endif
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
12 *
1513 */
1614 #include "tomcrypt.h"
1715
3634 int ltc_ecc_mul2add(ecc_point *A, void *kA,
3735 ecc_point *B, void *kB,
3836 ecc_point *C,
37 void *a,
3938 void *modulus)
4039 {
4140 ecc_point *precomp[16];
113112 if ((err = mp_mulmod(B->z, mu, modulus, precomp[1<<2]->z)) != CRYPT_OK) { goto ERR_MU; }
114113
115114 /* precomp [i,0](A + B) table */
116 if ((err = ltc_mp.ecc_ptdbl(precomp[1], precomp[2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
117 if ((err = ltc_mp.ecc_ptadd(precomp[1], precomp[2], precomp[3], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
115 if ((err = ltc_mp.ecc_ptdbl(precomp[1], precomp[2], a, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
116 if ((err = ltc_mp.ecc_ptadd(precomp[1], precomp[2], precomp[3], a, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
118117
119118 /* precomp [0,i](A + B) table */
120 if ((err = ltc_mp.ecc_ptdbl(precomp[1<<2], precomp[2<<2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
121 if ((err = ltc_mp.ecc_ptadd(precomp[1<<2], precomp[2<<2], precomp[3<<2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
119 if ((err = ltc_mp.ecc_ptdbl(precomp[1<<2], precomp[2<<2], a, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
120 if ((err = ltc_mp.ecc_ptadd(precomp[1<<2], precomp[2<<2], precomp[3<<2], a, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
122121
123122 /* precomp [i,j](A + B) table (i != 0, j != 0) */
124123 for (x = 1; x < 4; x++) {
125124 for (y = 1; y < 4; y++) {
126 if ((err = ltc_mp.ecc_ptadd(precomp[x], precomp[(y<<2)], precomp[x+(y<<2)], modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
125 if ((err = ltc_mp.ecc_ptadd(precomp[x], precomp[(y<<2)], precomp[x+(y<<2)], a, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
127126 }
128127 }
129128
156155 /* double twice, only if this isn't the first */
157156 if (first == 0) {
158157 /* double twice */
159 if ((err = ltc_mp.ecc_ptdbl(C, C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
160 if ((err = ltc_mp.ecc_ptdbl(C, C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
158 if ((err = ltc_mp.ecc_ptdbl(C, C, a, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
159 if ((err = ltc_mp.ecc_ptdbl(C, C, a, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
161160 }
162161
163162 /* if not both zero */
170169 if ((err = mp_copy(precomp[nA + (nB<<2)]->z, C->z)) != CRYPT_OK) { goto ERR_MU; }
171170 } else {
172171 /* if not first, add from table */
173 if ((err = ltc_mp.ecc_ptadd(C, precomp[nA + (nB<<2)], C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
172 if ((err = ltc_mp.ecc_ptadd(C, precomp[nA + (nB<<2)], C, a, modulus, mp)) != CRYPT_OK) { goto ERR_MU; }
174173 }
175174 }
176175 }
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
12 *
1513 */
1614 #include "tomcrypt.h"
1715
3533 @param map Boolean whether to map back to affine or not (1==map, 0 == leave in projective)
3634 @return CRYPT_OK on success
3735 */
38 int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map)
36 int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map)
3937 {
4038 ecc_point *tG, *M[8];
4139 int i, j, err;
9492
9593 /* calc the M tab, which holds kG for k==8..15 */
9694 /* M[0] == 8G */
97 if ((err = ltc_mp.ecc_ptdbl(tG, M[0], modulus, mp)) != CRYPT_OK) { goto done; }
98 if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], modulus, mp)) != CRYPT_OK) { goto done; }
99 if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], modulus, mp)) != CRYPT_OK) { goto done; }
95 if ((err = ltc_mp.ecc_ptdbl(tG, M[0], a, modulus, mp)) != CRYPT_OK) { goto done; }
96 if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], a, modulus, mp)) != CRYPT_OK) { goto done; }
97 if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], a, modulus, mp)) != CRYPT_OK) { goto done; }
10098
10199 /* now find (8+k)G for k=1..7 */
102100 for (j = 9; j < 16; j++) {
103 if ((err = ltc_mp.ecc_ptadd(M[j-9], tG, M[j-8], modulus, mp)) != CRYPT_OK) { goto done; }
101 if ((err = ltc_mp.ecc_ptadd(M[j-9], tG, M[j-8], a, modulus, mp)) != CRYPT_OK) { goto done; }
104102 }
105103
106104 /* setup sliding window */
134132
135133 /* if the bit is zero and mode == 1 then we double */
136134 if (mode == 1 && i == 0) {
137 if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; }
135 if ((err = ltc_mp.ecc_ptdbl(R, R, a, modulus, mp)) != CRYPT_OK) { goto done; }
138136 continue;
139137 }
140138
155153 /* ok window is filled so double as required and add */
156154 /* double first */
157155 for (j = 0; j < WINSIZE; j++) {
158 if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; }
156 if ((err = ltc_mp.ecc_ptdbl(R, R, a, modulus, mp)) != CRYPT_OK) { goto done; }
159157 }
160158
161159 /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
162 if ((err = ltc_mp.ecc_ptadd(R, M[bitbuf-8], R, modulus, mp)) != CRYPT_OK) { goto done; }
160 if ((err = ltc_mp.ecc_ptadd(R, M[bitbuf-8], R, a, modulus, mp)) != CRYPT_OK) { goto done; }
163161 }
164162 /* empty window and reset */
165163 bitcpy = bitbuf = 0;
173171 for (j = 0; j < bitcpy; j++) {
174172 /* only double if we have had at least one add first */
175173 if (first == 0) {
176 if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; }
174 if ((err = ltc_mp.ecc_ptdbl(R, R, a, modulus, mp)) != CRYPT_OK) { goto done; }
177175 }
178176
179177 bitbuf <<= 1;
186184 first = 0;
187185 } else {
188186 /* then add */
189 if ((err = ltc_mp.ecc_ptadd(R, tG, R, modulus, mp)) != CRYPT_OK) { goto done; }
187 if ((err = ltc_mp.ecc_ptadd(R, tG, R, a, modulus, mp)) != CRYPT_OK) { goto done; }
190188 }
191189 }
192190 }
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
2927 @param k The scalar to multiply by
3028 @param G The base point
3129 @param R [out] Destination for kG
30 @param a ECC curve parameter a
3231 @param modulus The modulus of the field the ECC curve is in
3332 @param map Boolean whether to map back to affine or not (1==map, 0 == leave in projective)
3433 @return CRYPT_OK on success
3534 */
36 int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map)
35 int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map)
3736 {
3837 ecc_point *tG, *M[3];
3938 int i, j, err;
9089 if ((err = mp_copy(tG->y, M[0]->y)) != CRYPT_OK) { goto done; }
9190 if ((err = mp_copy(tG->z, M[0]->z)) != CRYPT_OK) { goto done; }
9291 /* M[1] == 2G */
93 if ((err = ltc_mp.ecc_ptdbl(tG, M[1], modulus, mp)) != CRYPT_OK) { goto done; }
92 if ((err = ltc_mp.ecc_ptdbl(tG, M[1], a, modulus, mp)) != CRYPT_OK) { goto done; }
9493
9594 /* setup sliding window */
9695 mode = 0;
118117
119118 if (mode == 0 && i == 0) {
120119 /* dummy operations */
121 if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; }
122 if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; }
120 if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], a, modulus, mp)) != CRYPT_OK) { goto done; }
121 if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], a, modulus, mp)) != CRYPT_OK) { goto done; }
123122 continue;
124123 }
125124
126125 if (mode == 0 && i == 1) {
127126 mode = 1;
128127 /* dummy operations */
129 if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; }
130 if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; }
128 if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], a, modulus, mp)) != CRYPT_OK) { goto done; }
129 if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], a, modulus, mp)) != CRYPT_OK) { goto done; }
131130 continue;
132131 }
133132
134 if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[i^1], modulus, mp)) != CRYPT_OK) { goto done; }
135 if ((err = ltc_mp.ecc_ptdbl(M[i], M[i], modulus, mp)) != CRYPT_OK) { goto done; }
133 if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[i^1], a, modulus, mp)) != CRYPT_OK) { goto done; }
134 if ((err = ltc_mp.ecc_ptdbl(M[i], M[i], a, modulus, mp)) != CRYPT_OK) { goto done; }
136135 }
137136
138137 /* copy result out */
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
14
1615 #include "tomcrypt.h"
1716
1817 /**
3130 @param mp The "b" value from montgomery_setup()
3231 @return CRYPT_OK on success
3332 */
34 int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp)
33 int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *a, void *modulus, void *mp)
3534 {
3635 void *t1, *t2, *x, *y, *z;
3736 int err;
5352 (Q->z != NULL && mp_cmp(P->z, Q->z) == LTC_MP_EQ) &&
5453 (mp_cmp(P->y, Q->y) == LTC_MP_EQ || mp_cmp(P->y, t1) == LTC_MP_EQ)) {
5554 mp_clear_multi(t1, t2, x, y, z, NULL);
56 return ltc_ecc_projective_dbl_point(P, R, modulus, mp);
55 return ltc_ecc_projective_dbl_point(P, R, a, modulus, mp);
5756 }
5857
5958 if ((err = mp_copy(P->x, x)) != CRYPT_OK) { goto done; }
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
14
1615 #include "tomcrypt.h"
16
17 /* ### Point doubling in Jacobian coordinate system ###
18 *
19 * let us have a curve: y^2 = x^3 + a*x + b
20 * in Jacobian coordinates it becomes: y^2 = x^3 + a*x*z^4 + b*z^6
21 *
22 * The doubling of P = (Xp, Yp, Zp) is given by R = (Xr, Yr, Zr) where:
23 * Xr = M^2 - 2*S
24 * Yr = M * (S - Xr) - 8*T
25 * Zr = 2 * Yp * Zp
26 *
27 * M = 3 * Xp^2 + a*Zp^4
28 * T = Yp^4
29 * S = 4 * Xp * Yp^2
30 *
31 * SPECIAL CASE - when a == -3 we can compute M as:
32 * M = 3 * (Xp^2 - Zp^4) = 3 * (Xp + Zp^2) * (Xp - Zp^2)
33 */
1734
1835 /**
1936 @file ltc_ecc_projective_dbl_point.c
2037 ECC Crypto, Tom St Denis
21 */
38 */
2239
2340 #if defined(LTC_MECC) && (!defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC))
2441
2643 Double an ECC point
2744 @param P The point to double
2845 @param R [out] The destination of the double
46 @param a ECC curve parameter a (if NULL we assume a == -3)
2947 @param modulus The modulus of the field the ECC curve is in
3048 @param mp The "b" value from montgomery_setup()
3149 @return CRYPT_OK on success
3250 */
33 int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp)
51 int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *a, void *modulus, void *mp)
3452 {
3553 void *t1, *t2;
3654 int err;
6179 if (mp_cmp(R->z, modulus) != LTC_MP_LT) {
6280 if ((err = mp_sub(R->z, modulus, R->z)) != CRYPT_OK) { goto done; }
6381 }
64
65 /* T2 = X - T1 */
66 if ((err = mp_sub(R->x, t1, t2)) != CRYPT_OK) { goto done; }
67 if (mp_cmp_d(t2, 0) == LTC_MP_LT) {
68 if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; }
82
83 if (a == NULL) { /* special case for a == -3 (slightly faster than general case) */
84 /* T2 = X - T1 */
85 if ((err = mp_sub(R->x, t1, t2)) != CRYPT_OK) { goto done; }
86 if (mp_cmp_d(t2, 0) == LTC_MP_LT) {
87 if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; }
88 }
89 /* T1 = X + T1 */
90 if ((err = mp_add(t1, R->x, t1)) != CRYPT_OK) { goto done; }
91 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
92 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
93 }
94 /* T2 = T1 * T2 */
95 if ((err = mp_mul(t1, t2, t2)) != CRYPT_OK) { goto done; }
96 if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; }
97 /* T1 = 2T2 */
98 if ((err = mp_add(t2, t2, t1)) != CRYPT_OK) { goto done; }
99 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
100 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
101 }
102 /* T1 = T1 + T2 */
103 if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; }
104 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
105 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
106 }
69107 }
70 /* T1 = X + T1 */
71 if ((err = mp_add(t1, R->x, t1)) != CRYPT_OK) { goto done; }
72 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
73 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
74 }
75 /* T2 = T1 * T2 */
76 if ((err = mp_mul(t1, t2, t2)) != CRYPT_OK) { goto done; }
77 if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; }
78 /* T1 = 2T2 */
79 if ((err = mp_add(t2, t2, t1)) != CRYPT_OK) { goto done; }
80 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
81 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
82 }
83 /* T1 = T1 + T2 */
84 if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; }
85 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
86 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
108 else {
109 /* T2 = T1 * T1 */
110 if ((err = mp_sqr(t1, t2)) != CRYPT_OK) { goto done; }
111 if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; }
112 /* T1 = T2 * a */
113 if ((err = mp_mulmod(t2, a, modulus, t1)) != CRYPT_OK) { goto done; }
114 /* T2 = X * X */
115 if ((err = mp_sqr(R->x, t2)) != CRYPT_OK) { goto done; }
116 if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; }
117 /* T1 = T2 + T1 */
118 if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; }
119 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
120 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
121 }
122 /* T1 = T2 + T1 */
123 if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; }
124 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
125 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
126 }
127 /* T1 = T2 + T1 */
128 if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; }
129 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
130 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
131 }
87132 }
88133
89134 /* Y = 2Y */
120165 if ((err = mp_add(R->x, modulus, R->x)) != CRYPT_OK) { goto done; }
121166 }
122167
123 /* Y = Y - X */
168 /* Y = Y - X */
124169 if ((err = mp_sub(R->y, R->x, R->y)) != CRYPT_OK) { goto done; }
125170 if (mp_cmp_d(R->y, 0) == LTC_MP_LT) {
126171 if ((err = mp_add(R->y, modulus, R->y)) != CRYPT_OK) { goto done; }
133178 if (mp_cmp_d(R->y, 0) == LTC_MP_LT) {
134179 if ((err = mp_add(R->y, modulus, R->y)) != CRYPT_OK) { goto done; }
135180 }
136
181
137182 err = CRYPT_OK;
138183 done:
139184 mp_clear_multi(t1, t2, NULL);
3131
3232 #ifdef BN_MP_INVMOD_SLOW_C
3333 return mp_invmod_slow(a, b, c);
34 #else
35 return MP_VAL;
3436 #endif
35
36 return MP_VAL;
3737 }
3838 #endif
3939
0 #include <tommath.h>
1 #ifdef BN_MP_SQRTMOD_PRIME_C
2 /* LibTomMath, multiple-precision integer library -- Tom St Denis
3 *
4 * LibTomMath is a library that provides multiple-precision
5 * integer arithmetic as well as number theoretic functionality.
6 *
7 * The library is free for all purposes without any express
8 * guarantee it works.
9 */
10
11 /* Tonelli–Shanks algorithm
12 * https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm
13 * https://gmplib.org/list-archives/gmp-discuss/2013-April/005300.html
14 *
15 */
16
17 int mp_sqrtmod_prime(mp_int *n, mp_int *prime, mp_int *ret)
18 {
19 int res, legendre;
20 mp_int t1, C, Q, S, Z, M, T, R, two;
21 unsigned long i;
22
23 /* first handle the simple cases */
24 if (mp_cmp_d(n, 0) == MP_EQ) {
25 mp_zero(ret);
26 return MP_OKAY;
27 }
28 if (mp_cmp_d(prime, 2) == MP_EQ) return MP_VAL; /* prime must be odd */
29 if ((res = mp_jacobi(n, prime, &legendre)) != MP_OKAY) return res;
30 if (legendre == -1) return MP_VAL; /* quadratic non-residue mod prime */
31
32 mp_init_multi(&t1, &C, &Q, &S, &Z, &M, &T, &R, &two, NULL);
33
34 /* SPECIAL CASE: if prime mod 4 == 3
35 * compute directly: res = n^(prime+1)/4 mod prime
36 * Handbook of Applied Cryptography algorithm 3.36
37 */
38 if ((res = mp_mod_d(prime, 4, &i)) != MP_OKAY) goto cleanup;
39 if (i == 3) {
40 if ((res = mp_add_d(prime, 1, &t1)) != MP_OKAY) goto cleanup;
41 if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup;
42 if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup;
43 if ((res = mp_exptmod(n, &t1, prime, ret)) != MP_OKAY) goto cleanup;
44 res = MP_OKAY;
45 goto cleanup;
46 }
47
48 /* NOW: Tonelli–Shanks algorithm */
49
50 /* factor out powers of 2 from prime-1, defining Q and S as: prime-1 = Q*2^S */
51 if ((res = mp_copy(prime, &Q)) != MP_OKAY) goto cleanup;
52 if ((res = mp_sub_d(&Q, 1, &Q)) != MP_OKAY) goto cleanup;
53 /* Q = prime - 1 */
54 mp_zero(&S);
55 /* S = 0 */
56 while (mp_iseven(&Q)) {
57 if ((res = mp_div_2(&Q, &Q)) != MP_OKAY) goto cleanup;
58 /* Q = Q / 2 */
59 if ((res = mp_add_d(&S, 1, &S)) != MP_OKAY) goto cleanup;
60 /* S = S + 1 */
61 }
62
63 /* find a Z such that the Legendre symbol (Z|prime) == -1 */
64 mp_set_int(&Z, 2);
65 /* Z = 2 */
66 while(1) {
67 if ((res = mp_jacobi(&Z, prime, &legendre)) != MP_OKAY) goto cleanup;
68 if (legendre == -1) break;
69 if ((res = mp_add_d(&Z, 1, &Z)) != MP_OKAY) goto cleanup;
70 /* Z = Z + 1 */
71 }
72
73 if ((res = mp_exptmod(&Z, &Q, prime, &C)) != MP_OKAY) goto cleanup;
74 /* C = Z ^ Q mod prime */
75 if ((res = mp_add_d(&Q, 1, &t1)) != MP_OKAY) goto cleanup;
76 if ((res = mp_div_2(&t1, &t1)) != MP_OKAY) goto cleanup;
77 /* t1 = (Q + 1) / 2 */
78 if ((res = mp_exptmod(n, &t1, prime, &R)) != MP_OKAY) goto cleanup;
79 /* R = n ^ ((Q + 1) / 2) mod prime */
80 if ((res = mp_exptmod(n, &Q, prime, &T)) != MP_OKAY) goto cleanup;
81 /* T = n ^ Q mod prime */
82 if ((res = mp_copy(&S, &M)) != MP_OKAY) goto cleanup;
83 /* M = S */
84 if ((res = mp_set_int(&two, 2)) != MP_OKAY) goto cleanup;
85
86 res = MP_VAL;
87 while (1) {
88 if ((res = mp_copy(&T, &t1)) != MP_OKAY) goto cleanup;
89 i = 0;
90 while (1) {
91 if (mp_cmp_d(&t1, 1) == MP_EQ) break;
92 if ((res = mp_exptmod(&t1, &two, prime, &t1)) != MP_OKAY) goto cleanup;
93 i++;
94 }
95 if (i == 0) {
96 mp_copy(&R, ret);
97 res = MP_OKAY;
98 goto cleanup;
99 }
100 if ((res = mp_sub_d(&M, i, &t1)) != MP_OKAY) goto cleanup;
101 if ((res = mp_sub_d(&t1, 1, &t1)) != MP_OKAY) goto cleanup;
102 if ((res = mp_exptmod(&two, &t1, prime, &t1)) != MP_OKAY) goto cleanup;
103 /* t1 = 2 ^ (M - i - 1) */
104 if ((res = mp_exptmod(&C, &t1, prime, &t1)) != MP_OKAY) goto cleanup;
105 /* t1 = C ^ (2 ^ (M - i - 1)) mod prime */
106 if ((res = mp_sqrmod(&t1, prime, &C)) != MP_OKAY) goto cleanup;
107 /* C = (t1 * t1) mod prime */
108 if ((res = mp_mulmod(&R, &t1, prime, &R)) != MP_OKAY) goto cleanup;
109 /* R = (R * t1) mod prime */
110 if ((res = mp_mulmod(&T, &C, prime, &T)) != MP_OKAY) goto cleanup;
111 /* T = (T * C) mod prime */
112 mp_set(&M, i);
113 /* M = i */
114 }
115
116 cleanup:
117 mp_clear_multi(&t1, &C, &Q, &S, &Z, &M, &T, &R, &two, NULL);
118 return res;
119 }
120
121 #endif
392392
393393 /* special sqrt algo */
394394 int mp_sqrt(mp_int *arg, mp_int *ret);
395
396 /* special sqrt (mod prime) */
397 int mp_sqrtmod_prime(mp_int *arg, mp_int *prime, mp_int *ret);
395398
396399 /* is number a square? */
397400 int mp_is_square(mp_int *arg, int *ret);
105105 #define BN_MP_SQR_C
106106 #define BN_MP_SQRMOD_C
107107 #define BN_MP_SQRT_C
108 #define BN_MP_SQRTMOD_PRIME_C
108109 #define BN_MP_SUB_C
109110 #define BN_MP_SUB_D_C
110111 #define BN_MP_SUBMOD_C
824825 #define BN_MP_CLEAR_C
825826 #endif
826827
828 #if defined(BN_MP_SQRTMOD_PRIME_C)
829 #define BN_MP_JACOBI_C
830 #define BN_MP_ZERO_C
831 #define BN_MP_SET_INT_C
832 #define BN_MP_COPY_C
833 #define BN_MP_SUB_C
834 #define BN_MP_SUB_D_C
835 #define BN_MP_DIV_2_C
836 #define BN_MP_ADD_D_C
837 #define BN_MP_EXPTMOD_C
838 #endif
839
827840 #if defined(BN_MP_SUB_C)
828841 #define BN_S_MP_ADD_C
829842 #define BN_MP_CMP_MAG_C
1919 $flag = ($flag && $flag eq ':1') ? 1 : 0;
2020 $cipher_name = uc($cipher_name);
2121 next if $cipher_name =~ /^(DESX-CBC|RC4)$/;
22 next if $cipher_name =~ /CAMELLIA/; #XXX-FIXME
2322 die "UNEXPECTED '$l'" unless $cipher_name;
2423 my ($cipher, undef, $klen, $mode) = $cipher_name =~ /^(AES|DES|DES-EDE3|SEED|CAMELLIA)(-(\d+))?-(CBC|CFB|ECB|OFB|CTR)$/i;
2524 die "UNKNOWN CIPHER '$cipher_name'" unless $cipher;
00 -----BEGIN EC PRIVATE KEY-----
1 MG8DAgeAAgEgAiEAq1PtXRbOVQuq8Wuk8WEzKq1W1jeQYpwnhx7VFdT8IpwCIHj8NMajIOImcqlu
2 u22kg4ekBUGj1+XPrg1YpRPjjIiIAiEAp/Q6zUoF1prkWX5ucj618em5t+qlG23oPPNvloe1fe4=
1 MIIBEwIBAQQg722QX6XVTBoXlyXCtQxpRtQK76sEA+rP7f9SF8zyg02ggaUwgaIC
2 AQEwLAYHKoZIzj0BAQIhAP////////////////////////////////////7///wv
3 MAYEAQAEAQcEQQR5vmZ++dy7rFWgYpXOhwsHApv82y3OKNlZ8oFbFvgXmEg62ncm
4 o8RlXaT7/A4RCKj9F7RIpoVUGZxH0I/7ENS4AiEA/////////////////////rqu
5 3OavSKA7v9JejNA2QUECAQGhRANCAATAaLdUh3pKsyilabrG1GSoGxflJ9LWUlcq
6 uxG9o1ctUL+M52NFkNKSOgMRLKau405TyHFrQ0Q+EjQCRkNvO4yK
37 -----END EC PRIVATE KEY-----
4
0 -----BEGIN EC PRIVATE KEY-----
1 MG8DAgeAAgEgAiEAq1PtXRbOVQuq8Wuk8WEzKq1W1jeQYpwnhx7VFdT8IpwCIHj8NMajIOImcqlu
2 u22kg4ekBUGj1+XPrg1YpRPjjIiIAiEAp/Q6zUoF1prkWX5ucj618em5t+qlG23oPPNvloe1fe4=
3 -----END EC PRIVATE KEY-----
4
00 -----BEGIN EC PRIVATE KEY-----
1 MG8DAgeAAgEgAiEAwlhDYQrUrJwbA37CWwk6Yr4SUEls2ZljuK0Lre1m5xcCIEy8lSEMcDIOi+ON
2 RXG95gi61HJaNi2fuiqXEMg0EOzCAiEA7Tu/FCpxSTkBWWDnbyEI0Mrfa0FeHARIYvdYyaZhkeY=
1 MIIBEwIBAQQgDoQBZ4/WvEv60n7lQ2MO9CCmm2+D1TAVROsCG2FTAJ2ggaUwgaIC
2 AQEwLAYHKoZIzj0BAQIhAP////////////////////////////////////7///wv
3 MAYEAQAEAQcEQQR5vmZ++dy7rFWgYpXOhwsHApv82y3OKNlZ8oFbFvgXmEg62ncm
4 o8RlXaT7/A4RCKj9F7RIpoVUGZxH0I/7ENS4AiEA/////////////////////rqu
5 3OavSKA7v9JejNA2QUECAQGhRANCAASE4xf5yit44KY5gUVylgL+3pEdSqPzW+RR
6 Tx14x9LA66Uu6kcRQC8CR7+8pRp3pIHylN783HsDbJb46QWLdGIO
37 -----END EC PRIVATE KEY-----
4
0 -----BEGIN EC PRIVATE KEY-----
1 MG8DAgeAAgEgAiEAwlhDYQrUrJwbA37CWwk6Yr4SUEls2ZljuK0Lre1m5xcCIEy8lSEMcDIOi+ON
2 RXG95gi61HJaNi2fuiqXEMg0EOzCAiEA7Tu/FCpxSTkBWWDnbyEI0Mrfa0FeHARIYvdYyaZhkeY=
3 -----END EC PRIVATE KEY-----
4
Binary diff not shown
00 -----BEGIN PUBLIC KEY-----
1 MEwDAgcAAgEgAiEAq1PtXRbOVQuq8Wuk8WEzKq1W1jeQYpwnhx7VFdT8IpwCIHj8NMajIOImcqlu
2 u22kg4ekBUGj1+XPrg1YpRPjjIiI
1 MIH1MIGuBgcqhkjOPQIBMIGiAgEBMCwGByqGSM49AQECIQD/////////////////
2 ///////////////////+///8LzAGBAEABAEHBEEEeb5mfvncu6xVoGKVzocLBwKb
3 /NstzijZWfKBWxb4F5hIOtp3JqPEZV2k+/wOEQio/Re0SKaFVBmcR9CP+xDUuAIh
4 AP////////////////////66rtzmr0igO7/SXozQNkFBAgEBA0IABMBot1SHekqz
5 KKVpusbUZKgbF+Un0tZSVyq7Eb2jVy1Qv4znY0WQ0pI6AxEspq7jTlPIcWtDRD4S
6 NAJGQ287jIo=
37 -----END PUBLIC KEY-----
4
0 -----BEGIN PUBLIC KEY-----
1 MEwDAgcAAgEgAiEAq1PtXRbOVQuq8Wuk8WEzKq1W1jeQYpwnhx7VFdT8IpwCIHj8NMajIOImcqlu
2 u22kg4ekBUGj1+XPrg1YpRPjjIiI
3 -----END PUBLIC KEY-----
4
Binary diff not shown
00 -----BEGIN PUBLIC KEY-----
1 MEwDAgcAAgEgAiEAwlhDYQrUrJwbA37CWwk6Yr4SUEls2ZljuK0Lre1m5xcCIEy8lSEMcDIOi+ON
2 RXG95gi61HJaNi2fuiqXEMg0EOzC
1 MIH1MIGuBgcqhkjOPQIBMIGiAgEBMCwGByqGSM49AQECIQD/////////////////
2 ///////////////////+///8LzAGBAEABAEHBEEEeb5mfvncu6xVoGKVzocLBwKb
3 /NstzijZWfKBWxb4F5hIOtp3JqPEZV2k+/wOEQio/Re0SKaFVBmcR9CP+xDUuAIh
4 AP////////////////////66rtzmr0igO7/SXozQNkFBAgEBA0IABITjF/nKK3jg
5 pjmBRXKWAv7ekR1Ko/Nb5FFPHXjH0sDrpS7qRxFALwJHv7ylGnekgfKU3vzcewNs
6 lvjpBYt0Yg4=
37 -----END PUBLIC KEY-----
4
0 -----BEGIN PUBLIC KEY-----
1 MEwDAgcAAgEgAiEAwlhDYQrUrJwbA37CWwk6Yr4SUEls2ZljuK0Lre1m5xcCIEy8lSEMcDIOi+ON
2 RXG95gi61HJaNi2fuiqXEMg0EOzC
3 -----END PUBLIC KEY-----
4
0 -----BEGIN EC PRIVATE KEY-----
1 Proc-Type: 4,ENCRYPTED
2 DEK-Info: AES-128-CBC,98245C830C9282F7937E13D1D5BA11EC
3
4 0Y85oZ2+BKXYwrkBjsZdj6gnhOAfS5yDVmEsxFCDug+R3+Kw3QvyIfO4MVo9iWoA
5 D7wtoRfbt2OlBaLVl553+6QrUoa2DyKf8kLHQs1x1/J7tJOMM4SCXjlrOaToQ0dT
6 o7fOnjQjHne16pjgBVqGilY/I79Ab85AnE4uw7vgEucBEiU0d3nrhwuS2Opnhzyx
7 009q9VLDPwY2+q7tXjTqnk9mCmQgsiaDJqY09wlauSukYPgVuOJFmi1VdkRSDKYZ
8 rUUsQvz6Q6Q+QirSlfHna+NhUgQ2eyhGszwcP6NU8iqIxI+NCwfFVuAzw539yYwS
9 8SICczoC/YRlaclayXuomQ==
10 -----END EC PRIVATE KEY-----
0 -----BEGIN EC PRIVATE KEY-----
1 Proc-Type: 4,ENCRYPTED
2 DEK-Info: AES-192-CBC,CF0DF9FBAECBEF5FCE53EF2264D61B50
3
4 dXLk+Rgos3L2WJRAtmJ690eHwjLhNeHppsdBS83T/xcJQtW//8Fkxa9XyJp4PG43
5 MxYt5x9bJysmRVZ5Z+lxrkwxh1P82Fj8lq8wJ0ijnxrdQUG8dj3M5b6TvXZ9Wwml
6 D5t28yduo4f+72UOAyfKLIbh/fbYg0sejdRaK6s1aFDpbhg1oKqhjldgPZsLB+M2
7 awzwlYtfQaCPxlGMSyfvanS4X7TL1KHcaX7g1ygvwBcqli85cIynZsaGKTj26Itb
8 pvOECs6IE81hsFbHBe4KeLakqVcqdo4wBwbwbrZANxk=
9 -----END EC PRIVATE KEY-----
0 -----BEGIN EC PRIVATE KEY-----
1 Proc-Type: 4,ENCRYPTED
2 DEK-Info: AES-256-CBC,5112DF71CEEE534741673D8F36CFF9FF
3
4 lqxba1ld8+3CaMQJWNWVPmHqaipNSSKeEPDShvdvTgUEGn6gaCxcS2volX0FPTRp
5 CS38ie3jOhbY6d8D62QCyMLFeY43nlzJnxJ2KdA8b7/RM+XXw9M/QK0xI7sMdDRp
6 JorqKquZWHa4YmhdEi7rUwMTycivBzO7dhadgpH5V0R3XvHYiZjGdGwNnFGb4VzU
7 fIeZWgMA86Vd8yP4vrMxzufcvY6Whjtnoj3ruHOdYU/Y93BdgmYojGWWdEanDp1k
8 WiBAEDQBtsfOZS2OTQ0dVMJX1HooTSn1U8yM/iKf1VcdXCvfZrOyHMkN1pEM2RYK
9 5/Bq5dfLXqiwbxWOKoelsQ==
10 -----END EC PRIVATE KEY-----
0 -----BEGIN EC PRIVATE KEY-----
1 Proc-Type: 4,ENCRYPTED
2 DEK-Info: CAMELLIA-128-CBC,118544E97AC088140AC1C0C06ABC759E
3
4 f/moV4xfY8b+3foS4l8MFfkdVYW1x3mausivtv3O7aMpJCS46bEvYvQ0xTPZwvDc
5 3jnxmkHGem6yaofmxcLDEpOV4Hr2sBGK4OAxtdv+w5BzN9U0iOTehG83nlcp280u
6 wkd8r2h4Yz7wyZZClGccPw7CGBcBwhkvhfAVK9p/qISDo2HKPSSAx5STZ1QhsIro
7 ALd+UGup+LLfckn2no1A1EAnq721XpYPJUyO0KacvZXGkGEX8FGpKcBfPHIZY01M
8 KaxsuEbxPldHFUDOWkT+ID3jPiSlUlurQtUKbagzPJS2opQXRcW5WiZZ/fgJMETV
9 mXrESk3A1j3eHEgqJlsWSQyNyxcvmc1EN8WFgzjwWBA3yaG/dyYyjjAOzaIOAwO8
10 QhOwQFD9t7JU0C2CKvgv/JAx/4maOyNUcncNY+4JlYrsV/U5Hp1kvGmjAZP7CVuD
11 -----END EC PRIVATE KEY-----
0 -----BEGIN EC PRIVATE KEY-----
1 Proc-Type: 4,ENCRYPTED
2 DEK-Info: CAMELLIA-192-CBC,3D2679B0FA9626F66AC2855E10732713
3
4 1xhoIqCYu1HBKVW0G8o3TKQQFkrD/KrOWTRNTCuP4WDVjCL7YLTBeJQbEuAxpuci
5 tICDjO0FSy5L4RjKOveoL+akG52LflnsWpYkwcxmsp+FIPHTR0sFZvkD5HDID0ZB
6 y2XpDhMNInVELjAcHGg8NfzrgLFb7xzgWBUTIONzqw4Komfkes31mIalbh+/V1Z4
7 ZE0r7BiOnd+NO2Rydw2u4zWRsgZBXdVTGm+97ZIWoiNLN6unAU1Q65gYRABg94nq
8 APFIJZz800WXIcCFFyrM7QsX2WCP5Q/121j8k0l5Quw+ylkziZSFxivcZXyM2a24
9 43gZt/1Hu5zVK0e4dDfUlQIDw5ugPO/B/ShkuaY1B12BMTf6EeNtAyBjFjX+TP+4
10 -----END EC PRIVATE KEY-----
0 -----BEGIN EC PRIVATE KEY-----
1 Proc-Type: 4,ENCRYPTED
2 DEK-Info: CAMELLIA-256-CBC,E1CB2335163192A57FD06C3279CFD052
3
4 z3zB6/uGCQL2Drl2lr3Hl/85yHdt/WFW/5XHka2SVO8v9scr77AJdshZyypPbFLi
5 ieS1lEedDbsADjwbyFrHQmO1Tz6vNfAfAnUCEVJnFcAxtkdeYabN25srhJ1pQYte
6 6vzi+7uOmNjLQRmSvN1NaA20JKuyFFEhSPKiVhK84tl6GOKhyu0ETzjjAP89RtDm
7 5+sHmGxedPonEDilAYcWo3Y55v0nbctwDhBQXio2VGgjw9QiCoa9pApjcNo9sr9S
8 uj/OWTTlaiiBTZQ7PJ93zeNkpomV4eZxrSVDPRTkAyR9emKScVLVZN8/rACgwZzi
9 t80ALww0VVnoyNuMqVh008fEE96X3MjixzdyXpOXfGeiXjFHCka+8M/SQ92C4G45
10 XFR0C2ql1yDeo4zoNihrsm0VXoz5M/beOGZtELoase0mNsqmOPmKQQKnb3Lkm0aE
11 +iuasKk3fQ5J30FLegrNr4xcLKO5ztkiykjMp/9G4dsm30iWEcdfJETMvYsfPXox
12 WptJWdMP6RtCyz9v+6KBjvHi05GHph+STgRm8QGUDVDaQdP27p2za9xJokWbzbxa
13 Hk0/WUBdboa0a7MTCUFJqVqT+IIHK4Y34DKqw1no7aki3UJJNiR4Dnlta7bR4m4q
14 yKCvFVaxKE+Y/WippfyKEZciiZxHprrQUCv+yy6rRGo=
15 -----END EC PRIVATE KEY-----
0 -----BEGIN EC PRIVATE KEY-----
1 Proc-Type: 4,ENCRYPTED
2 DEK-Info: DES-CBC,25CCB799403FC4A8
3
4 cVh3cIHbAHumbPxqkNyUTijnJxs5gAYx/R6XazSzfOv5AVniXWcBYXUz8xxu5ihG
5 njKhB/A7NnMrRBT3MU//Q16sKnnsC1YwRVFn5Ynzs0ZE+Z2XKHbV/pgRtlYWbgUA
6 fiXZttximkYqHr4BB0lfcm89jV8Ks50wGMmpADd/b09R5BhrYEt30poLqArKokZ+
7 YIxR/nf1pcd6frbvnQmR/6TiX6SNf+9GZohIkBhkcT24OTSEtLdJnQg4wCzwuKW/
8 oLKMPxKtHtQ=
9 -----END EC PRIVATE KEY-----
0 -----BEGIN EC PRIVATE KEY-----
1 Proc-Type: 4,ENCRYPTED
2 DEK-Info: DES-EDE3-CBC,BCC03F44667493FB
3
4 OcnqVLNcxYQyDJKMkWEFv1sLOFnui9hN8wPidDYS3rP1HTeFZRQeWznTtqAs6MAH
5 vFnHHLTYMJXlGJ/qSb9sJmRJw2XAkRUtsT6vxXvf0IhPTd5632aXSjewUllOfl+N
6 1tmztrOGWtHIms9Kz4noG1ApXhv66eUtLMDkiKR85D2Wai4yzyftFQyFT0BzFTxu
7 IHcZ7oDYYX50+iru0x9aP990jyXzzrlURLCpgtr940YkoLquudvyn9s/6wtKqeyG
8 SIEU6SHQhYrsiVTpQWMIUQc2T0HVoCoHBUGFAtj4wYA=
9 -----END EC PRIVATE KEY-----
0 -----BEGIN EC PRIVATE KEY-----
1 Proc-Type: 4,ENCRYPTED
2 DEK-Info: SEED-CBC,94487C737A60F0E41D5AF5A3BA0B155E
3
4 3MjBEjo9vDpSKd0UbyCngNl7dVJfxdEwqTOQw0rjl8qYBlvbdx+zSMQTixKXJR70
5 +Z+z1UvW415QTEyTArnuwwfDMkgGB5w3tr2+YuF8908vvtyX2GKvkdaEvFHdYb0X
6 8PSABZgiAPdjgzDDm3WZHj72wcgiJeXs+UCId2Aqueqxfd+qRT9UmpBUJ7VGlT6w
7 u3YV+1SbCqNZr/vV6XoJ5z8VuaXQiv2HuROzbqZ5gKSag4Mk9UlmMhLs6SeN40du
8 xQDZj3NStwbZUlPlJwkSMzmzjoyHMY5xFbKdtFB8LiYTYlDu7qQr2E/T2TviquBw
9 HobzhyW1rPKfJ/4uUpflww==
10 -----END EC PRIVATE KEY-----
+0
-20
t/data/info.txt less more
0 openssl genrsa -passout pass:secret -des3 -out rsa-des3.pem 1024
1 openssl genrsa -passout pass:secret -des -out rsa-des.pem 1024
2 openssl genrsa -passout pass:secret -seed -out rsa-seed.pem 1024
3 openssl genrsa -passout pass:secret -aes128 -out rsa-aes128.pem 1024
4 openssl genrsa -passout pass:secret -aes192 -out rsa-aes192.pem 1024
5 openssl genrsa -passout pass:secret -aes256 -out rsa-aes256.pem 1024
6 openssl genrsa -passout pass:secret -camellia128 -out rsa-camellia128.pem 1024
7 openssl genrsa -passout pass:secret -camellia192 -out rsa-camellia192.pem 1024
8 openssl genrsa -passout pass:secret -camellia256 -out rsa-camellia256.pem 1024
9
10 openssl dsaparam -out dsa-param.pem -outform pem 1024
11 openssl gendsa -passout pass:secret -des3 -out dsa-des3.pem dsa-param.pem
12 openssl gendsa -passout pass:secret -des -out dsa-des.pem dsa-param.pem
13 openssl gendsa -passout pass:secret -seed -out dsa-seed.pem dsa-param.pem
14 openssl gendsa -passout pass:secret -aes128 -out dsa-aes128.pem dsa-param.pem
15 openssl gendsa -passout pass:secret -aes192 -out dsa-aes192.pem dsa-param.pem
16 openssl gendsa -passout pass:secret -aes256 -out dsa-aes256.pem dsa-param.pem
17 openssl gendsa -passout pass:secret -camellia128 -out dsa-camellia128.pem dsa-param.pem
18 openssl gendsa -passout pass:secret -camellia192 -out dsa-camellia192.pem dsa-param.pem
19 openssl gendsa -passout pass:secret -camellia256 -out dsa-camellia256.pem dsa-param.pem
0 -----BEGIN EC PARAMETERS-----
1 MIIBVwIBATA8BgcqhkjOPQEBAjEA////////////////////////////////////
2 //////7/////AAAAAAAAAAD/////MHsEMP//////////////////////////////
3 ///////////+/////wAAAAAAAAAA/////AQwszEvp+I+5+SYjgVr4/gtGRgdnG7+
4 gUESAxQIj1ATh1rGVjmNii7RnSqFyO3T7CrvAxUAozWSaqMZonodAIlqZ3OkgnrN
5 rHMEYQSqh8oivosFN46xxx7zIK10bh07Younm5hZ90HgglQqOFUC8l2/VSlsOlRe
6 OHJ2Crc2F95KliYsb12emL+Sktwp+PQdvSiaFHzp2jETtfC4wApgsc4dfoGdekMd
7 fJDqDl8CMQD////////////////////////////////HY02B9Dct31gaDbJIsKd6
8 7OwZaszFKXMCAQE=
9 -----END EC PARAMETERS-----
10 -----BEGIN EC PRIVATE KEY-----
11 MIIB+gIBAQQwCKEAcA6cIt6CGfyLKm57LyXWv2PgTjydrHSbvhDJTOl+7bzUW8DS
12 rgSdtSPONPq1oIIBWzCCAVcCAQEwPAYHKoZIzj0BAQIxAP//////////////////
13 ///////////////////////+/////wAAAAAAAAAA/////zB7BDD/////////////
14 /////////////////////////////v////8AAAAAAAAAAP////wEMLMxL6fiPufk
15 mI4Fa+P4LRkYHZxu/oFBEgMUCI9QE4daxlY5jYou0Z0qhcjt0+wq7wMVAKM1kmqj
16 GaJ6HQCJamdzpIJ6zaxzBGEEqofKIr6LBTeOscce8yCtdG4dO2KLp5uYWfdB4IJU
17 KjhVAvJdv1UpbDpUXjhydgq3NhfeSpYmLG9dnpi/kpLcKfj0Hb0omhR86doxE7Xw
18 uMAKYLHOHX6BnXpDHXyQ6g5fAjEA////////////////////////////////x2NN
19 gfQ3Ld9YGg2ySLCneuzsGWrMxSlzAgEBoWQDYgAEeGyHPLmHcszPQ9MIIYnznpzi
20 QbvuJtYSjCqtIGxDfzgcLcc3nCc5tBxo+qX6OJEzcWdDAC0bwplY+9Z9jHR3ylNy
21 ovlHoK4ItdWkVO8NH89SLSRyVuOF8N5t3CHIo93B
22 -----END EC PRIVATE KEY-----
Binary diff not shown
0 -----BEGIN EC PRIVATE KEY-----
1 MIIB+gIBAQQwCKEAcA6cIt6CGfyLKm57LyXWv2PgTjydrHSbvhDJTOl+7bzUW8DS
2 rgSdtSPONPq1oIIBWzCCAVcCAQEwPAYHKoZIzj0BAQIxAP//////////////////
3 ///////////////////////+/////wAAAAAAAAAA/////zB7BDD/////////////
4 /////////////////////////////v////8AAAAAAAAAAP////wEMLMxL6fiPufk
5 mI4Fa+P4LRkYHZxu/oFBEgMUCI9QE4daxlY5jYou0Z0qhcjt0+wq7wMVAKM1kmqj
6 GaJ6HQCJamdzpIJ6zaxzBGEEqofKIr6LBTeOscce8yCtdG4dO2KLp5uYWfdB4IJU
7 KjhVAvJdv1UpbDpUXjhydgq3NhfeSpYmLG9dnpi/kpLcKfj0Hb0omhR86doxE7Xw
8 uMAKYLHOHX6BnXpDHXyQ6g5fAjEA////////////////////////////////x2NN
9 gfQ3Ld9YGg2ySLCneuzsGWrMxSlzAgEBoWQDYgAEeGyHPLmHcszPQ9MIIYnznpzi
10 QbvuJtYSjCqtIGxDfzgcLcc3nCc5tBxo+qX6OJEzcWdDAC0bwplY+9Z9jHR3ylNy
11 ovlHoK4ItdWkVO8NH89SLSRyVuOF8N5t3CHIo93B
12 -----END EC PRIVATE KEY-----
0 -----BEGIN EC PRIVATE KEY-----
1 MIIBmgIBAQQwCKEAcA6cIt6CGfyLKm57LyXWv2PgTjydrHSbvhDJTOl+7bzUW8DS
2 rgSdtSPONPq1oIIBKzCCAScCAQEwPAYHKoZIzj0BAQIxAP//////////////////
3 ///////////////////////+/////wAAAAAAAAAA/////zB7BDD/////////////
4 /////////////////////////////v////8AAAAAAAAAAP////wEMLMxL6fiPufk
5 mI4Fa+P4LRkYHZxu/oFBEgMUCI9QE4daxlY5jYou0Z0qhcjt0+wq7wMVAKM1kmqj
6 GaJ6HQCJamdzpIJ6zaxzBDEDqofKIr6LBTeOscce8yCtdG4dO2KLp5uYWfdB4IJU
7 KjhVAvJdv1UpbDpUXjhydgq3AjEA////////////////////////////////x2NN
8 gfQ3Ld9YGg2ySLCneuzsGWrMxSlzAgEBoTQDMgADeGyHPLmHcszPQ9MIIYnznpzi
9 QbvuJtYSjCqtIGxDfzgcLcc3nCc5tBxo+qX6OJEz
10 -----END EC PRIVATE KEY-----
Binary diff not shown
0 -----BEGIN PUBLIC KEY-----
1 MIIBzDCCAWQGByqGSM49AgEwggFXAgEBMDwGByqGSM49AQECMQD/////////////
2 /////////////////////////////v////8AAAAAAAAAAP////8wewQw////////
3 //////////////////////////////////7/////AAAAAAAAAAD////8BDCzMS+n
4 4j7n5JiOBWvj+C0ZGB2cbv6BQRIDFAiPUBOHWsZWOY2KLtGdKoXI7dPsKu8DFQCj
5 NZJqoxmieh0AiWpnc6SCes2scwRhBKqHyiK+iwU3jrHHHvMgrXRuHTtii6ebmFn3
6 QeCCVCo4VQLyXb9VKWw6VF44cnYKtzYX3kqWJixvXZ6Yv5KS3Cn49B29KJoUfOna
7 MRO18LjACmCxzh1+gZ16Qx18kOoOXwIxAP//////////////////////////////
8 /8djTYH0Ny3fWBoNskiwp3rs7BlqzMUpcwIBAQNiAAR4bIc8uYdyzM9D0wghifOe
9 nOJBu+4m1hKMKq0gbEN/OBwtxzecJzm0HGj6pfo4kTNxZ0MALRvCmVj71n2MdHfK
10 U3Ki+Uegrgi11aRU7w0fz1ItJHJW44Xw3m3cIcij3cE=
11 -----END PUBLIC KEY-----
0 -----BEGIN PUBLIC KEY-----
1 MIIBbDCCATQGByqGSM49AgEwggEnAgEBMDwGByqGSM49AQECMQD/////////////
2 /////////////////////////////v////8AAAAAAAAAAP////8wewQw////////
3 //////////////////////////////////7/////AAAAAAAAAAD////8BDCzMS+n
4 4j7n5JiOBWvj+C0ZGB2cbv6BQRIDFAiPUBOHWsZWOY2KLtGdKoXI7dPsKu8DFQCj
5 NZJqoxmieh0AiWpnc6SCes2scwQxA6qHyiK+iwU3jrHHHvMgrXRuHTtii6ebmFn3
6 QeCCVCo4VQLyXb9VKWw6VF44cnYKtwIxAP//////////////////////////////
7 /8djTYH0Ny3fWBoNskiwp3rs7BlqzMUpcwIBAQMyAAN4bIc8uYdyzM9D0wghifOe
8 nOJBu+4m1hKMKq0gbEN/OBwtxzecJzm0HGj6pfo4kTM=
9 -----END PUBLIC KEY-----
0 use strict;
1 use warnings;
2
3 sub runcmds {
4 my $cmds = shift;
5 for (split /\n/, $cmds) {
6 s/^\s*(.*?)\s*$/$1/;
7 warn "#### >$_<\n";
8 my $rv = system($_);
9 die "ERROR (rv = $rv)\n" if $rv;
10 }
11 }
12
13 sub doit {
14
15 ### sign openssl > cryptx
16 runcmds <<'MARKER';
17 openssl dgst -sha1 -sign dsakey.priv.pem -out input.sha1-dsa.sig input.data
18 MARKER
19
20 {
21 use Crypt::PK::DSA;
22 use Crypt::Digest 'digest_file';
23 use File::Slurp 'read_file';
24
25 my $pkdsa = Crypt::PK::DSA->new("dsakey.pub.pem");
26 my $signature = read_file("input.sha1-dsa.sig", binmode=>':raw');
27 my $valid = $pkdsa->verify_hash($signature, digest_file("SHA1", "input.data"), "SHA1", "v1.5");
28 print $valid ? "SUCCESS" : "FAILURE";
29 }
30
31 ### sign cryptx > openssl
32 {
33 use Crypt::PK::DSA;
34 use Crypt::Digest 'digest_file';
35 use File::Slurp 'write_file';
36
37 my $pkdsa = Crypt::PK::DSA->new("dsakey.priv.pem");
38 my $signature = $pkdsa->sign_hash(digest_file("SHA1", "input.data"), "SHA1", "v1.5");
39 write_file("input.sha1-dsa.sig", {binmode=>':raw'}, $signature);
40 }
41
42 runcmds <<'MARKER';
43 openssl dgst -sha1 -verify dsakey.pub.pem -signature input.sha1-dsa.sig input.data
44 MARKER
45
46 }
47
48 ### MAIN ###
49
50 write_file("input.data", "test-file-content");
51
52 ### keys generated by cryptx
53 {
54 use Crypt::PK::DSA;
55 use File::Slurp 'write_file';
56
57 my $pkdsa = Crypt::PK::DSA->new;
58 $pkdsa->generate_key(20, 128);
59 write_file("dsakey.pub.der", {binmode=>':raw'}, $pkdsa->export_key_der('public'));
60 write_file("dsakey.priv.der", {binmode=>':raw'}, $pkdsa->export_key_der('private'));
61 write_file("dsakey.pub.pem", $pkdsa->export_key_pem('public_x509'));
62 write_file("dsakey.priv.pem", $pkdsa->export_key_pem('private'));
63 write_file("dsakey-passwd.priv.pem", $pkdsa->export_key_pem('private', 'secret'));
64 }
65
66 runcmds <<'MARKER';
67 openssl dsa -in dsakey.priv.der -text -inform der
68 openssl dsa -in dsakey.priv.pem -text
69 openssl dsa -in dsakey-passwd.priv.pem -text -inform pem -passin pass:secret
70 openssl dsa -in dsakey.pub.der -pubin -text -inform der
71 openssl dsa -in dsakey.pub.pem -pubin -text
72 MARKER
73
74 doit();
75
76 ### keys generated by openssl
77
78 runcmds <<'MARKER';
79 openssl dsaparam -genkey -out dsakey.priv.pem 1024
80 openssl dsa -in dsakey.priv.pem -out dsakey.priv.der -outform der
81 openssl dsa -in dsakey.priv.pem -out dsakey.pub.pem -pubout
82 openssl dsa -in dsakey.priv.pem -out dsakey.pub.der -outform der -pubout
83 openssl dsa -in dsakey.priv.pem -passout pass:secret -des3 -out dsakey-passwd.priv.pem
84 MARKER
85
86 {
87 use Crypt::PK::DSA;
88 use File::Slurp 'write_file';
89
90 my $pkdsa = Crypt::PK::DSA->new;
91 $pkdsa->import_key("dsakey.pub.der");
92 $pkdsa->import_key("dsakey.priv.der");
93 $pkdsa->import_key("dsakey.pub.pem");
94 $pkdsa->import_key("dsakey.priv.pem");
95 $pkdsa->import_key("dsakey-passwd.priv.pem", "secret");
96 }
97
98 doit();
99
100 warn "\nSUCCESS\n";
0 use strict;
1 use warnings;
2
3 sub runcmds {
4 my $cmds = shift;
5 for (split /\n/, $cmds) {
6 s/^\s*(.*?)\s*$/$1/;
7 warn "#### >$_<\n";
8 my $rv = system($_);
9 die "ERROR (rv = $rv)\n" if $rv;
10 }
11 }
12
13 sub doit {
14
15 ### sign openssl > cryptx
16 runcmds <<'MARKER';
17 openssl dgst -sha1 -sign eckey.priv.pem -out input.sha1-ec.sig input.data
18 MARKER
19
20 {
21 use Crypt::PK::ECC;
22 use Crypt::Digest 'digest_file';
23 use File::Slurp 'read_file';
24
25 my $pkec = Crypt::PK::ECC->new("eckey.pub.pem");
26 my $signature = read_file("input.sha1-ec.sig", binmode=>':raw');
27 my $valid = $pkec->verify_hash($signature, digest_file("SHA1", "input.data"), "SHA1", "v1.5");
28 print $valid ? "SUCCESS" : "FAILURE";
29 }
30
31 ### sign cryptx > openssl
32 {
33 use Crypt::PK::ECC;
34 use Crypt::Digest 'digest_file';
35 use File::Slurp 'write_file';
36
37 my $pkec = Crypt::PK::ECC->new("eckey.priv.pem");
38 my $signature = $pkec->sign_hash(digest_file("SHA1", "input.data"), "SHA1", "v1.5");
39 write_file("input.sha1-ec.sig", {binmode=>':raw'}, $signature);
40 }
41
42 runcmds <<'MARKER';
43 openssl dgst -sha1 -verify eckey.pub.pem -signature input.sha1-ec.sig input.data
44 MARKER
45
46 }
47
48 ### MAIN ###
49
50 write_file("input.data", "test-file-content");
51
52 ### keys generated by cryptx
53 {
54 use Crypt::PK::ECC;
55 use File::Slurp 'write_file';
56
57 my $pkec = Crypt::PK::ECC->new;
58 $pkec->generate_key('secp160k1');
59 write_file("eckey.pub.der", {binmode=>':raw'}, $pkec->export_key_der('public'));
60 write_file("eckey.priv.der", {binmode=>':raw'}, $pkec->export_key_der('private'));
61 write_file("eckey.pub.pem", $pkec->export_key_pem('public'));
62 write_file("eckey.priv.pem", $pkec->export_key_pem('private'));
63 write_file("eckey-passwd.priv.pem", $pkec->export_key_pem('private', 'secret'));
64 }
65
66 runcmds <<'MARKER';
67 openssl ec -in eckey.priv.der -text -inform der
68 openssl ec -in eckey.priv.pem -text
69 openssl ec -in eckey-passwd.priv.pem -text -inform pem -passin pass:secret
70 openssl ec -in eckey.pub.der -pubin -text -inform der
71 openssl ec -in eckey.pub.pem -pubin -text
72 MARKER
73
74 doit();
75
76 ### keys generated by openssl
77
78 runcmds <<'MARKER';
79 openssl ecparam -param_enc explicit -name prime192v3 -genkey -out eckey.priv.pem
80 openssl ec -param_enc explicit -in eckey.priv.pem -out eckey.pub.pem -pubout
81 openssl ec -param_enc explicit -in eckey.priv.pem -out eckey.priv.der -outform der
82 openssl ec -param_enc explicit -in eckey.priv.pem -out eckey.pub.der -outform der -pubout
83 openssl ec -param_enc explicit -in eckey.priv.pem -out eckey.privc.der -outform der -conv_form compressed
84 openssl ec -param_enc explicit -in eckey.priv.pem -out eckey.pubc.der -outform der -pubout -conv_form compressed
85 openssl ec -param_enc explicit -in eckey.priv.pem -passout pass:secret -des3 -out eckey-passwd.priv.pem
86 MARKER
87
88 {
89 use Crypt::PK::ECC;
90 use File::Slurp 'write_file';
91
92 my $pkec = Crypt::PK::ECC->new;
93 $pkec->import_key("eckey.pub.der");
94 $pkec->import_key("eckey.pubc.der");
95 $pkec->import_key("eckey.priv.der");
96 $pkec->import_key("eckey.privc.der");
97 $pkec->import_key("eckey.pub.pem");
98 $pkec->import_key("eckey.priv.pem");
99 $pkec->import_key("eckey-passwd.priv.pem", "secret");
100 }
101
102 doit();
103
104 warn "\nSUCCESS\n";
0 for I in 1 2 3
1 do
2 for C in 512 1024 1536 2048 3072 4096
3 # for C in 512
4 do
5
6 echo "processing $C"
7 PREF="key_$C-$I"
8 openssl dsaparam -genkey -out "$PREF.key.pem" $C
9 openssl dsa -in "$PREF.key.pem" -out "$PREF.pri.pem"
10 openssl dsa -in "$PREF.key.pem" -pubout -out "$PREF.pub.pem"
11 openssl dsa -in "$PREF.key.pem" -out "$PREF.pri.der" -outform der
12 openssl dsa -in "$PREF.key.pem" -pubout -out "$PREF.pub.der" -outform der
13 echo -n 'test-data' | openssl dgst -sha1 -sign "$PREF.pri.pem" -out "$PREF.dsa-sha1.sig"
14 echo -n 'test-data' | openssl dgst -sha256 -sign "$PREF.pri.pem" -out "$PREF.dsa-sha256.sig"
15 HEX_DSA_SHA1=`perl -00 -pe '$_ = unpack("H*", $_)' < "$PREF.dsa-sha1.sig"`
16 HEX_DSA_SHA256=`perl -00 -pe '$_ = unpack("H*", $_)' < "$PREF.dsa-sha256.sig"`
17 HEX_PRI=`openssl dsa -in "$PREF.pri.pem" -inform PEM -text | perl -00 -pe 's/[\n\r] +//sg' | grep "^priv:" | perl -00 -pe 's/[\n\r\s:priv]//sg'`
18 HEX_PUB=`openssl dsa -in "$PREF.pri.pem" -inform PEM -text | perl -00 -pe 's/[\n\r] +//sg' | grep "^pub:" | perl -pe 's/^pub://'| perl -00 -pe 's/[\n\r\s:]//sg'`
19 HEX_PRI_DER=`perl -00 -pe '$_ = unpack("H*", $_)' < "$PREF.pri.der"`
20 HEX_PUB_DER=`perl -00 -pe '$_ = unpack("H*", $_)' < "$PREF.pub.der"`
21 echo " {SIZE=>$C,PRI_FILE=>'$PREF.pri.pem',PUB_FILE=>'$PREF.pub.pem',PRI=>'$HEX_PRI',PUB=>'$HEX_PUB',DSA_SHA1=>'$HEX_DSA_SHA1',DSA_SHA256=>'$HEX_DSA_SHA256',PRI_DER=>'$HEX_PRI_DER',PUB_DER=>'$HEX_PUB_DER'}," >> tmp.txt
22 rm "$PREF.key.pem"
23
24 done
25 done
26
27
0 for I in 1 2 3
1 do
2 for C in secp112r1 secp112r2 secp128r1 secp128r2 secp160k1 secp160r1 secp160r2 secp192k1 secp224k1 secp224r1 secp256k1 secp384r1 secp521r1 prime192v1 prime192v2 prime192v3 prime239v1 prime239v2 prime239v3 prime256v1
3 do
4
5 echo "processing $C"
6 PREF="key_$C-$I"
7 openssl ecparam -param_enc explicit -name "$C" -genkey -out "$PREF.key.pem"
8 openssl ec -in "$PREF.key.pem" -param_enc explicit -out "$PREF.pri.pem"
9 openssl ec -in "$PREF.key.pem" -param_enc explicit -conv_form compressed -out "$PREF.pric.pem"
10 openssl ec -in "$PREF.key.pem" -pubout -param_enc explicit -out "$PREF.pub.pem"
11 openssl ec -in "$PREF.key.pem" -pubout -param_enc explicit -conv_form compressed -out "$PREF.pubc.pem"
12 echo -n 'test-data' | openssl dgst -sha1 -sign "$PREF.pri.pem" -out "$PREF.ecdsa-sha1.sig"
13 echo -n 'test-data' | openssl dgst -sha256 -sign "$PREF.pri.pem" -out "$PREF.ecdsa-sha256.sig"
14 HEX_ECDSA_SHA1=`cat "$PREF.ecdsa-sha1.sig" | perl -00pe '$_ = unpack("H*", $_)'`
15 HEX_ECDSA_SHA256=`cat "$PREF.ecdsa-sha256.sig" | perl -00pe '$_ = unpack("H*", $_)'`
16 HEX_PRI=`openssl ec -in "$PREF.pri.pem" -inform PEM -text | perl -00pe 's/[\n\r] +//sg' | grep "^priv:" | perl -00pe 's/[\n\r\s:priv]//sg'`
17 HEX_PUB=`openssl ec -in "$PREF.pri.pem" -inform PEM -text | perl -00pe 's/[\n\r] +//sg' | grep "^pub:" | perl -pe 's/^pub://'| perl -00pe 's/[\n\r\s:]//sg'`
18 HEX_PUBC=`openssl ec -in "$PREF.pric.pem" -inform PEM -text | perl -00pe 's/[\n\r] +//sg' | grep "^pub:" | perl -pe 's/^pub://'| perl -00pe 's/[\n\r\s:]//sg'`
19 echo " {CURVE=>'$C',PRI_FILE=>'$PREF.pri.pem',PUB_FILE=>'$PREF.pub.pem',PRI=>'$HEX_PRI',PUB=>'$HEX_PUB',PUBC=>'$HEX_PUBC',ECDSA_SHA1=>'$HEX_ECDSA_SHA1',ECDSA_SHA256=>'$HEX_ECDSA_SHA256'}," >> tmp.txt
20 rm "$PREF.key.pem" "$PREF.pric.pem" "$PREF.pubc.pem"
21
22 done
23 done
0 use strict;
1 use warnings;
2
3 use File::Slurp qw(append_file read_file write_file);
4 use MIME::Base64 qw(encode_base64 decode_base64);
5 use Crypt::PK::RSA;
6 use Test::More;
7
8 sub test_rsa { # copy from pk_rsa_test_vectors_openssl.t
9 my $h = shift;
10 my $rsa_pri = Crypt::PK::RSA->new->import_key(\decode_base64($h->{PRIDER}));
11 my $rsa_pub = Crypt::PK::RSA->new->import_key(\decode_base64($h->{PUBDER}));
12 my $rsa_pri_h = $rsa_pri->key2hash;
13 my $rsa_pub_h = $rsa_pub->key2hash;
14 is($rsa_pri_h->{d}, $h->{PRI}, "$h->{ID}/PRI");
15 is($rsa_pri_h->{N}, $h->{PUB}, "$h->{ID}/PUB");
16 is($rsa_pub_h->{N}, $h->{PUB}, "$h->{ID}/PUB");
17 is( $rsa_pri->decrypt(decode_base64($h->{ENC}), 'v1.5'), 'test-data', "$h->{ID}/ENC") || return 0;
18 ok( $rsa_pub->verify_message(decode_base64($h->{SIGSHA1}), 'test-data', 'SHA1', 'v1.5'), "$h->{ID}/SIGSHA1") || return 0;
19 ok( $rsa_pub->verify_message(decode_base64($h->{SIGSHA256}), 'test-data', 'SHA256', 'v1.5'), "$h->{ID}/SIGSHA256") || return 0;
20 return 1 if !$h->{SIGSHA512}; #SHA512 might be too big for short RSA keys
21 ok( $rsa_pub->verify_message(decode_base64($h->{SIGSHA512}), 'test-data', 'SHA512', 'v1.5'), "$h->{ID}/SIGSHA512") || return 0;
22 return 1;
23 }
24
25 write_file("input.data", {binmode=>':raw'}, "test-data");
26 my $outfile = "rsa_tmp.$$.txt";
27 my $ver = `openssl version` =~ s/[\r\n]*$//r;
28 append_file($outfile, "my \$data = [ #test vectors generated by: $ver\n");
29 for my $I (1..10000) {
30 for my $C (qw(512 1024 1536 2048 3072 4096)) {
31 my $ID="key-$C-$I";
32 my $PREF="$ID-$$";
33 warn "######## processing $PREF\n";
34 system("openssl genrsa -out $PREF.key.pem $C");
35 system("openssl rsa -in $PREF.key.pem -out $PREF.priv.pem");
36 system("openssl rsa -in $PREF.key.pem -pubout -out $PREF.pub.pem");
37 system("openssl rsa -in $PREF.key.pem -out $PREF.priv.der -outform der");
38 system("openssl rsa -in $PREF.key.pem -pubout -out $PREF.pub.der -outform der");
39 system("openssl dgst -sha1 -sign $PREF.priv.pem -out $PREF.sha1.sig input.data");
40 system("openssl dgst -sha256 -sign $PREF.priv.pem -out $PREF.sha256.sig input.data");
41 system("openssl dgst -sha512 -sign $PREF.priv.pem -out $PREF.sha512.sig input.data");
42 system("openssl rsautl -encrypt -inkey $PREF.pub.pem -pubin -out $PREF.enc -in input.data");
43 my $PRI_DER = encode_base64(read_file("$PREF.priv.der", binmode=>':raw'), "");
44 my $PUB_DER = encode_base64(read_file("$PREF.pub.der", binmode=>':raw'), "");
45 my $SIG_SHA1 = encode_base64(read_file("$PREF.sha1.sig", binmode=>':raw'), "");
46 my $SIG_SHA256 = encode_base64(read_file("$PREF.sha256.sig", binmode=>':raw'), "");
47 my $SIG_SHA512 = encode_base64(read_file("$PREF.sha512.sig", binmode=>':raw'), "");
48 my $ENCRYPTED = encode_base64(read_file("$PREF.enc", binmode=>':raw'), "");
49 my @key_dump = split /[\r\n]+/, `openssl rsa -in "$PREF.priv.pem" -inform PEM -text` =~ s/:[\r\n]+ +/:/sgr;
50 my %h = map { my ($k, $v) = /^([a-zA-Z0-9]+):(.*)/; ($k||0)=>($v||0) =~ s/[: ]//sgr } @key_dump; # ugly, I know
51 my $PRI = uc $h{privateExponent} =~ s/^0+//r;
52 my $PUB = uc $h{modulus} =~ s/^0+//r;
53 append_file($outfile, " {ID=>'$ID',SIZE=>$C,PRI=>'$PRI',PUB=>'$PUB',SIGSHA1=>'$SIG_SHA1',SIGSHA256=>'$SIG_SHA256',SIGSHA512=>'$SIG_SHA512',ENC=>'$ENCRYPTED',PRIDER=>'$PRI_DER',PUBDER=>'$PUB_DER'},\n");
54 test_rsa({ID=>$ID,SIZE=>$C,PRI=>$PRI,PUB=>$PUB,SIGSHA1=>$SIG_SHA1,SIGSHA256=>$SIG_SHA256,SIGSHA512=>$SIG_SHA512,ENC=>$ENCRYPTED,PRIDER=>$PRI_DER,PUBDER=>$PUB_DER}) || die;
55 unlink "$PREF.key.pem";
56 unlink "$PREF.priv.pem";
57 unlink "$PREF.pub.pem";
58 unlink "$PREF.priv.der";
59 unlink "$PREF.pub.der";
60 unlink "$PREF.sha1.sig";
61 unlink "$PREF.sha256.sig";
62 unlink "$PREF.sha512.sig";
63 }
64 }
65 append_file($outfile, "];\n");
0 openssl genrsa -passout pass:secret -des3 -out rsa-des3.pem 1024
1 openssl genrsa -passout pass:secret -des -out rsa-des.pem 1024
2 openssl genrsa -passout pass:secret -seed -out rsa-seed.pem 1024
3 openssl genrsa -passout pass:secret -aes128 -out rsa-aes128.pem 1024
4 openssl genrsa -passout pass:secret -aes192 -out rsa-aes192.pem 1024
5 openssl genrsa -passout pass:secret -aes256 -out rsa-aes256.pem 1024
6 openssl genrsa -passout pass:secret -camellia128 -out rsa-camellia128.pem 1024
7 openssl genrsa -passout pass:secret -camellia192 -out rsa-camellia192.pem 1024
8 openssl genrsa -passout pass:secret -camellia256 -out rsa-camellia256.pem 1024
9
10 openssl dsaparam -out dsa-param.pem -outform pem 1024
11 openssl gendsa -passout pass:secret -des3 -out dsa-des3.pem dsa-param.pem
12 openssl gendsa -passout pass:secret -des -out dsa-des.pem dsa-param.pem
13 openssl gendsa -passout pass:secret -seed -out dsa-seed.pem dsa-param.pem
14 openssl gendsa -passout pass:secret -aes128 -out dsa-aes128.pem dsa-param.pem
15 openssl gendsa -passout pass:secret -aes192 -out dsa-aes192.pem dsa-param.pem
16 openssl gendsa -passout pass:secret -aes256 -out dsa-aes256.pem dsa-param.pem
17 openssl gendsa -passout pass:secret -camellia128 -out dsa-camellia128.pem dsa-param.pem
18 openssl gendsa -passout pass:secret -camellia192 -out dsa-camellia192.pem dsa-param.pem
19 openssl gendsa -passout pass:secret -camellia256 -out dsa-camellia256.pem dsa-param.pem
20
21 openssl ecparam -out tmp.pem -name secp128r2 -genkey -param_enc explicit && openssl ec -param_enc explicit -passout pass:secret -des3 -out ec-des3.pem -in tmp.pem
22 openssl ecparam -out tmp.pem -name secp160k1 -genkey -param_enc explicit && openssl ec -param_enc explicit -passout pass:secret -des -out ec-des.pem -in tmp.pem
23 openssl ecparam -out tmp.pem -name secp160r1 -genkey -param_enc explicit && openssl ec -param_enc explicit -passout pass:secret -seed -out ec-seed.pem -in tmp.pem
24 openssl ecparam -out tmp.pem -name secp160r2 -genkey -param_enc explicit && openssl ec -param_enc explicit -passout pass:secret -aes128 -out ec-aes128.pem -in tmp.pem
25 openssl ecparam -out tmp.pem -name secp192k1 -genkey -param_enc explicit && openssl ec -param_enc explicit -passout pass:secret -aes192 -out ec-aes192.pem -in tmp.pem
26 openssl ecparam -out tmp.pem -name secp224k1 -genkey -param_enc explicit && openssl ec -param_enc explicit -passout pass:secret -aes256 -out ec-aes256.pem -in tmp.pem
27 openssl ecparam -out tmp.pem -name secp224r1 -genkey -param_enc explicit && openssl ec -param_enc explicit -passout pass:secret -camellia128 -out ec-camellia128.pem -in tmp.pem
28 openssl ecparam -out tmp.pem -name secp256k1 -genkey -param_enc explicit && openssl ec -param_enc explicit -passout pass:secret -camellia192 -out ec-camellia192.pem -in tmp.pem
29 openssl ecparam -out tmp.pem -name secp384r1 -genkey -param_enc explicit && openssl ec -param_enc explicit -passout pass:secret -camellia256 -out ec-camellia256.pem -in tmp.pem
30
31 openssl ecparam -list_curves
32 openssl ecparam -out openssl_ec_secp112r1.pem -name secp112r1 -genkey -param_enc explicit
33 openssl ecparam -out openssl_ec_secp112r2.pem -name secp112r2 -genkey -param_enc explicit
34 openssl ecparam -out openssl_ec_secp128r1.pem -name secp128r1 -genkey -param_enc explicit
35 openssl ecparam -out openssl_ec_secp128r2.pem -name secp128r2 -genkey -param_enc explicit
36 openssl ecparam -out openssl_ec_secp160k1.pem -name secp160k1 -genkey -param_enc explicit
37 openssl ecparam -out openssl_ec_secp160r1.pem -name secp160r1 -genkey -param_enc explicit
38 openssl ecparam -out openssl_ec_secp160r2.pem -name secp160r2 -genkey -param_enc explicit
39 openssl ecparam -out openssl_ec_secp192k1.pem -name secp192k1 -genkey -param_enc explicit
40 openssl ecparam -out openssl_ec_secp224k1.pem -name secp224k1 -genkey -param_enc explicit
41 openssl ecparam -out openssl_ec_secp224r1.pem -name secp224r1 -genkey -param_enc explicit
42 openssl ecparam -out openssl_ec_secp256k1.pem -name secp256k1 -genkey -param_enc explicit
43 openssl ecparam -out openssl_ec_secp384r1.pem -name secp384r1 -genkey -param_enc explicit
44 openssl ecparam -out openssl_ec_secp521r1.pem -name secp521r1 -genkey -param_enc explicit
45 openssl ecparam -out openssl_ec_prime192v1.pem -name prime192v1 -genkey -param_enc explicit
46 openssl ecparam -out openssl_ec_prime192v2.pem -name prime192v2 -genkey -param_enc explicit
47 openssl ecparam -out openssl_ec_prime192v3.pem -name prime192v3 -genkey -param_enc explicit
48 openssl ecparam -out openssl_ec_prime239v1.pem -name prime239v1 -genkey -param_enc explicit
49 openssl ecparam -out openssl_ec_prime239v2.pem -name prime239v2 -genkey -param_enc explicit
50 openssl ecparam -out openssl_ec_prime239v3.pem -name prime239v3 -genkey -param_enc explicit
51 openssl ecparam -out openssl_ec_prime256v1.pem -name prime256v1 -genkey -param_enc explicit
52 openssl ecparam -out openssl_ec_wap-wsg-idm-ecid-wtls6.pem -name wap-wsg-idm-ecid-wtls6 -genkey -param_enc explicit
53 openssl ecparam -out openssl_ec_wap-wsg-idm-ecid-wtls7.pem -name wap-wsg-idm-ecid-wtls7 -genkey -param_enc explicit
54 openssl ecparam -out openssl_ec_wap-wsg-idm-ecid-wtls8.pem -name wap-wsg-idm-ecid-wtls8 -genkey -param_enc explicit
55 openssl ecparam -out openssl_ec_wap-wsg-idm-ecid-wtls9.pem -name wap-wsg-idm-ecid-wtls9 -genkey -param_enc explicit
56 openssl ecparam -out openssl_ec_wap-wsg-idm-ecid-wtls12.pem -name wap-wsg-idm-ecid-wtls12 -genkey -param_enc explicit
57
58
59 openssl ecparam -out openssl_ec1.key.pem -name secp384r1 -genkey -param_enc explicit
60 openssl ec -in openssl_ec1.key.pem -param_enc explicit -out openssl_ec1.pri.pem
61 openssl ec -in openssl_ec1.key.pem -param_enc explicit -conv_form compressed -out openssl_ec1.pric.pem
62 openssl ec -in openssl_ec1.key.pem -param_enc explicit -pubout -out openssl_ec1.pub.pem
63 openssl ec -in openssl_ec1.key.pem -param_enc explicit -pubout -conv_form compressed -out openssl_ec1.pubc.pem
64 openssl ec -in openssl_ec1.key.pem -param_enc explicit -outform der -out openssl_ec1.pri.der
65 openssl ec -in openssl_ec1.key.pem -param_enc explicit -outform der -conv_form compressed -out openssl_ec1.pric.der
66 openssl ec -in openssl_ec1.key.pem -param_enc explicit -outform der -pubout -out openssl_ec1.pub.der
67 openssl ec -in openssl_ec1.key.pem -param_enc explicit -outform der -pubout -conv_form compressed -out openssl_ec1.pubc.der
0 use strict;
1 use warnings;
2
3 sub runcmds {
4 my $cmds = shift;
5 for (split /\n/, $cmds) {
6 s/^\s*(.*?)\s*$/$1/;
7 warn "#### >$_<\n";
8 my $rv = system($_);
9 die "ERROR (rv = $rv)\n" if $rv;
10 }
11 }
12
13 sub doit {
14
15 ### enc openssl > cryptx
16 runcmds <<'MARKER';
17 openssl rsautl -encrypt -inkey rsakey.pub.pem -pubin -out input.encrypted.rsa -in input.data
18 MARKER
19
20 {
21 use Crypt::PK::RSA;
22 use File::Slurp 'read_file';
23
24 my $pkrsa = Crypt::PK::RSA->new("rsakey.priv.pem");
25 my $encfile = read_file("input.encrypted.rsa", binmode=>':raw');
26 my $plaintext = $pkrsa->decrypt($encfile, 'v1.5');
27 print $plaintext;
28 }
29
30 ### enc cryptx > openssl
31 {
32 use Crypt::PK::RSA;
33 use File::Slurp 'write_file';
34
35 my $plaintext = 'secret message';
36 my $pkrsa = Crypt::PK::RSA->new("rsakey.pub.pem");
37 my $encrypted = $pkrsa->encrypt($plaintext, 'v1.5');
38 write_file("input.encrypted.rsa", {binmode=>':raw'}, $encrypted);
39 }
40
41 runcmds <<'MARKER';
42 openssl rsautl -decrypt -inkey rsakey.priv.pem -in input.encrypted.rsa
43 MARKER
44
45 ### sign openssl > cryptx
46 runcmds <<'MARKER';
47 openssl dgst -sha1 -sign rsakey.priv.pem -out input.sha1-rsa.sig input.data
48 MARKER
49
50 {
51 use Crypt::PK::RSA;
52 use Crypt::Digest 'digest_file';
53 use File::Slurp 'read_file';
54
55 my $pkrsa = Crypt::PK::RSA->new("rsakey.pub.pem");
56 my $signature = read_file("input.sha1-rsa.sig", binmode=>':raw');
57 my $valid = $pkrsa->verify_hash($signature, digest_file("SHA1", "input.data"), "SHA1", "v1.5");
58 print $valid ? "SUCCESS" : "FAILURE";
59 }
60
61 ### sign cryptx > openssl
62 {
63 use Crypt::PK::RSA;
64 use Crypt::Digest 'digest_file';
65 use File::Slurp 'write_file';
66
67 my $pkrsa = Crypt::PK::RSA->new("rsakey.priv.pem");
68 my $signature = $pkrsa->sign_hash(digest_file("SHA1", "input.data"), "SHA1", "v1.5");
69 write_file("input.sha1-rsa.sig", {binmode=>':raw'}, $signature);
70 }
71
72 runcmds <<'MARKER';
73 openssl dgst -sha1 -verify rsakey.pub.pem -signature input.sha1-rsa.sig input.data
74 MARKER
75
76 }
77
78 ### MAIN ###
79
80 write_file("input.data", "test-file-content");
81
82 ### keys generated by cryptx
83 {
84 use Crypt::PK::RSA;
85 use File::Slurp 'write_file';
86
87 my $pkrsa = Crypt::PK::RSA->new;
88 $pkrsa->generate_key(256, 65537);
89 write_file("rsakey.pub.der", {binmode=>':raw'}, $pkrsa->export_key_der('public'));
90 write_file("rsakey.priv.der", {binmode=>':raw'}, $pkrsa->export_key_der('private'));
91 write_file("rsakey.pub.pem", $pkrsa->export_key_pem('public_x509'));
92 write_file("rsakey.priv.pem", $pkrsa->export_key_pem('private'));
93 write_file("rsakey-passwd.priv.pem", $pkrsa->export_key_pem('private', 'secret'));
94 }
95
96 runcmds <<'MARKER';
97 openssl rsa -in rsakey.priv.der -text -inform der
98 openssl rsa -in rsakey.priv.pem -text
99 openssl rsa -in rsakey-passwd.priv.pem -text -inform pem -passin pass:secret
100 openssl rsa -in rsakey.pub.der -pubin -text -inform der
101 openssl rsa -in rsakey.pub.pem -pubin -text
102 MARKER
103
104 doit();
105
106 ### keys generated by openssl
107
108 runcmds <<'MARKER';
109 openssl genrsa -out rsakey.priv.pem 1024
110 openssl rsa -in rsakey.priv.pem -out rsakey.priv.der -outform der
111 openssl rsa -in rsakey.priv.pem -out rsakey.pub.pem -pubout
112 openssl rsa -in rsakey.priv.pem -out rsakey.pub.der -outform der -pubout
113 openssl rsa -in rsakey.priv.pem -passout pass:secret -des3 -out rsakey-passwd.priv.pem
114 MARKER
115
116 {
117 use Crypt::PK::RSA;
118 use File::Slurp 'write_file';
119
120 my $pkrsa = Crypt::PK::RSA->new;
121 $pkrsa->import_key("rsakey.pub.der");
122 $pkrsa->import_key("rsakey.priv.der");
123 $pkrsa->import_key("rsakey.pub.pem");
124 $pkrsa->import_key("rsakey.priv.pem");
125 $pkrsa->import_key("rsakey-passwd.priv.pem", "secret");
126 }
127
128 doit();
129
130 warn "\nSUCCESS\n";
0 use strict;
1 use warnings;
2
3 use Test::More;
4 use Crypt::PK::DSA;
5
6 my $data = [
7 {SIZE=>512,PRI_FILE=>'key_512-1.pri.pem',PUB_FILE=>'key_512-1.pub.pem',PRI=>'53faaa79adc02e31ce2865e09393d321978b0b84',PUB=>'2b7cd87cef58954dab4368d51cb96d063317e018def42fd4bb0703a3c7c7cc31b81683197e49bb0c9076f0f6bf2d210380c54f5a1f166c0b0f25b933d4f6fcfd',DSA_SHA1=>'302c02141b9ee2d783233c759384d029875e6cc8b69038d9021475e1ddede6d839c6dca249b0415eaf426a793f21',DSA_SHA256=>'302c02140363f4b1dfaf90d8d6acaf158b205ca0d3948bc702143155b536047e44b7554355fe926f7409c29d2d07',PRI_DER=>'3081f7020100024100dd47e95c66ccd30418c25aff403bdd09ef907699f7168fb34893e2722d76ab62ac31503a1d32e6ec6f8dc209ad35c90a055520d87b0496c27c22c4a75e90994f0215009043e406a88f6cc9af5d620512424fc501c418e102405057ac1eaab6313f35c23aad24f11f85c4adf5d2d81cfac94cae2a0fe9641825a8eeedda170d596b0f9ac857b59d3fd803f4eff9eb16cde387b8b48ca969778702402b7cd87cef58954dab4368d51cb96d063317e018def42fd4bb0703a3c7c7cc31b81683197e49bb0c9076f0f6bf2d210380c54f5a1f166c0b0f25b933d4f6fcfd021453faaa79adc02e31ce2865e09393d321978b0b84',PUB_DER=>'3081f03081a806072a8648ce38040130819c024100dd47e95c66ccd30418c25aff403bdd09ef907699f7168fb34893e2722d76ab62ac31503a1d32e6ec6f8dc209ad35c90a055520d87b0496c27c22c4a75e90994f0215009043e406a88f6cc9af5d620512424fc501c418e102405057ac1eaab6313f35c23aad24f11f85c4adf5d2d81cfac94cae2a0fe9641825a8eeedda170d596b0f9ac857b59d3fd803f4eff9eb16cde387b8b48ca969778703430002402b7cd87cef58954dab4368d51cb96d063317e018def42fd4bb0703a3c7c7cc31b81683197e49bb0c9076f0f6bf2d210380c54f5a1f166c0b0f25b933d4f6fcfd'},
8 {SIZE=>1024,PRI_FILE=>'key_1024-1.pri.pem',PUB_FILE=>'key_1024-1.pub.pem',PRI=>'1c59ff18088e085ff6ad546f902536b7d92d4664',PUB=>'4e2f8de47faa96295eec8c12f4e69bdadcc911cb013c23ba84621abe72a6497c1ee64524ca19c4adb64e438ba72f2d0b879e362fce0208ee67136da3bf7acb2f64fb9695062c4d7d67f4f848d60ce25e03415b041c3218e22ad145a2f4e203dbdbd0ddcf92ee131d3201c179538eff896438dd7cf98c54f20218516a0192ca80',DSA_SHA1=>'302c02142596d20c3c1922aa08794d13180d5b1ef9ccf76102141df0e2d0241d50da26c812fc464afd2aff2f9be3',DSA_SHA256=>'302c02141bbb545956785ab5b34bb4606ed82ef2bde6f2c0021425dd6c191efb0c709c7266f4fb8819154b5924ab',PRI_DER=>'308201bb020100028181009de4a90812fd9998704cac7d43c789c3fa13aed3e3ad426ba063c06e722b52f217c7dc4717fc03798220d84e880ad9200b45b0ca1add4b423242bbaee134d8a91467a79423ca499857897606dffb5f53565490a8040038431959eebc9d04a319136eff5c5e353eaf8740c25286ef0dee9ea8b602ea7e948702f9087ace8249b5021500876df298aebc94a3a4ac0831743cd7be00873627028181009d5eea2e5644112c0eb3ca36d8b3578755914d076d2ced54246f67a1ecb149524c4c183143854d7b75e7b5111227c95412fd312ac22ac5c28dba33ca4aae3cb35a0f8d4a131a2aa2317ecae04e5fbea9dbee056a7dc8794f4be31c2496ac15cec6eaff1df6a6859c82476a6c172ade0112ed6ac8cbb282db0e381a87e62bb3c20281804e2f8de47faa96295eec8c12f4e69bdadcc911cb013c23ba84621abe72a6497c1ee64524ca19c4adb64e438ba72f2d0b879e362fce0208ee67136da3bf7acb2f64fb9695062c4d7d67f4f848d60ce25e03415b041c3218e22ad145a2f4e203dbdbd0ddcf92ee131d3201c179538eff896438dd7cf98c54f20218516a0192ca8002141c59ff18088e085ff6ad546f902536b7d92d4664',PUB_DER=>'308201b73082012c06072a8648ce3804013082011f028181009de4a90812fd9998704cac7d43c789c3fa13aed3e3ad426ba063c06e722b52f217c7dc4717fc03798220d84e880ad9200b45b0ca1add4b423242bbaee134d8a91467a79423ca499857897606dffb5f53565490a8040038431959eebc9d04a319136eff5c5e353eaf8740c25286ef0dee9ea8b602ea7e948702f9087ace8249b5021500876df298aebc94a3a4ac0831743cd7be00873627028181009d5eea2e5644112c0eb3ca36d8b3578755914d076d2ced54246f67a1ecb149524c4c183143854d7b75e7b5111227c95412fd312ac22ac5c28dba33ca4aae3cb35a0f8d4a131a2aa2317ecae04e5fbea9dbee056a7dc8794f4be31c2496ac15cec6eaff1df6a6859c82476a6c172ade0112ed6ac8cbb282db0e381a87e62bb3c2038184000281804e2f8de47faa96295eec8c12f4e69bdadcc911cb013c23ba84621abe72a6497c1ee64524ca19c4adb64e438ba72f2d0b879e362fce0208ee67136da3bf7acb2f64fb9695062c4d7d67f4f848d60ce25e03415b041c3218e22ad145a2f4e203dbdbd0ddcf92ee131d3201c179538eff896438dd7cf98c54f20218516a0192ca80'},
9 {SIZE=>1536,PRI_FILE=>'key_1536-1.pri.pem',PUB_FILE=>'key_1536-1.pub.pem',PRI=>'630c5e35d645b884c0de84055feceed4d5cd55a1',PUB=>'67b3a9dcdbdfe145df560b5b3226827489cda4987b7103bd4b4857b4826ea1e39fb6bc56ff6eec5775963baf2ce673268e5b3b8519e6d2e1d6a7355c4be977086f288a0dc68c5823426580287bb347505c2eed5ed6b0c377b261a3941a97e2e0da0feb0cb7e7ba65c7e2e3d1704a1ce977c543c2f8c1c5e4634049ecbab3271f15d0d59a7305b6ae312677a32836ae4e2b1e4f37372df0760c152472104953955501f8e37a70e6e8ca8cd7e90bd4a79c070a79dbe20eb48cd17704c2b803e3ca',DSA_SHA1=>'302c0214534053ef9a874980e394edf7158c5a3f0effc2f4021406e384a6bb00df3dbed75ad1cfe044efd4227c72',DSA_SHA256=>'302c02141ecbfc3e5bddc6f06e25925622b9770e5c9eaf74021446f42b32a5ee8647f77419b3e114733946d442fa',PRI_DER=>'3082027b0201000281c100a4ca1614ae22c8e03cc012db3f07b5d08f82fe0b51f895d57359fb928c04a2654ca8a184776341fea9d3e18b74d562bc506d477eb9b35fa5eecda63a11fd62f95872b1dff55858b41273ae2cde311e0b7e945128b5f796a71136fbb02fab0fb17008ae2b91818ac6c5d8f5729f8d843efc042f686da1bd530dd15a88bd253024a66f94710b1444dc190a439ab8888169ea847751d767290ff00991c022a46cd10a7fef1c7263ac6793a1a2c1a26932aee4cf138e7690d7117e5eb4a2d92ff27d02150087bd7144a9eb4b7a915fa3aaf3ce33827545deff0281c100860ab0c50678098f84b43f3b64a25fe9a4c4f5830b08986ba0853b80196eb4e8bdafc262b00c26bb54175e229dd0fec2ec4be42c0511ef4959b1ea7efd2f9fd196b3e41345798fc733ddeded1e390f0cde596b31f3ac4e541c942112d6da33ce1657f238f8ae44eb88562471951af02f25e97162465ddb25113b5d3557d55cdea1fccd7a047e07dad60e1ed4131a166dd502e4c022af28e489bbcef8245ff8cefa26395b24c111a3e0616072dafb3f9c6c6d17d4404c6fd33a1827f3a99b548f0281c067b3a9dcdbdfe145df560b5b3226827489cda4987b7103bd4b4857b4826ea1e39fb6bc56ff6eec5775963baf2ce673268e5b3b8519e6d2e1d6a7355c4be977086f288a0dc68c5823426580287bb347505c2eed5ed6b0c377b261a3941a97e2e0da0feb0cb7e7ba65c7e2e3d1704a1ce977c543c2f8c1c5e4634049ecbab3271f15d0d59a7305b6ae312677a32836ae4e2b1e4f37372df0760c152472104953955501f8e37a70e6e8ca8cd7e90bd4a79c070a79dbe20eb48cd17704c2b803e3ca0214630c5e35d645b884c0de84055feceed4d5cd55a1',PUB_DER=>'30820277308201ac06072a8648ce3804013082019f0281c100a4ca1614ae22c8e03cc012db3f07b5d08f82fe0b51f895d57359fb928c04a2654ca8a184776341fea9d3e18b74d562bc506d477eb9b35fa5eecda63a11fd62f95872b1dff55858b41273ae2cde311e0b7e945128b5f796a71136fbb02fab0fb17008ae2b91818ac6c5d8f5729f8d843efc042f686da1bd530dd15a88bd253024a66f94710b1444dc190a439ab8888169ea847751d767290ff00991c022a46cd10a7fef1c7263ac6793a1a2c1a26932aee4cf138e7690d7117e5eb4a2d92ff27d02150087bd7144a9eb4b7a915fa3aaf3ce33827545deff0281c100860ab0c50678098f84b43f3b64a25fe9a4c4f5830b08986ba0853b80196eb4e8bdafc262b00c26bb54175e229dd0fec2ec4be42c0511ef4959b1ea7efd2f9fd196b3e41345798fc733ddeded1e390f0cde596b31f3ac4e541c942112d6da33ce1657f238f8ae44eb88562471951af02f25e97162465ddb25113b5d3557d55cdea1fccd7a047e07dad60e1ed4131a166dd502e4c022af28e489bbcef8245ff8cefa26395b24c111a3e0616072dafb3f9c6c6d17d4404c6fd33a1827f3a99b548f0381c4000281c067b3a9dcdbdfe145df560b5b3226827489cda4987b7103bd4b4857b4826ea1e39fb6bc56ff6eec5775963baf2ce673268e5b3b8519e6d2e1d6a7355c4be977086f288a0dc68c5823426580287bb347505c2eed5ed6b0c377b261a3941a97e2e0da0feb0cb7e7ba65c7e2e3d1704a1ce977c543c2f8c1c5e4634049ecbab3271f15d0d59a7305b6ae312677a32836ae4e2b1e4f37372df0760c152472104953955501f8e37a70e6e8ca8cd7e90bd4a79c070a79dbe20eb48cd17704c2b803e3ca'},
10 {SIZE=>2048,PRI_FILE=>'key_2048-1.pri.pem',PUB_FILE=>'key_2048-1.pub.pem',PRI=>'5ca7ce7397dd512ab599883efc620734fcd0742eeb6adb07a663508cb74adf4e',PUB=>'49f560fa511efc8614fda1be58146bc92e5799788bebd7d317fb97bbbe2df363d2188b29344a33300e76da04f3bfe5ca048413991b3491f9acdd06f8347fed58a28a2f7d95a431190fa4a0fa56221562204dd97fb2db1304e936dce96d85f768e9a7bef22bfc4f81cf535a625b7b8b643a89e9416a0c2c27806e4fa20000ff617d124a168f35f9ab47855429c5c5d95582a798826a333273f024b0e2bea5d2c56535bdbb47e5312844ce71512f941b4c14db30a3a3d0face56e90dae0d02b2f5136b27dbb85fe9da160a9f76e69cbf0a5732bc1bc0ead82632250d046bdd986bfd177c58f39bc38a3ed79387ff0912cfd09198d15abfc9743c493cc62300e034',DSA_SHA1=>'304402206933c92131ae35fc927a3048cc034d201d32dfb416da1bd64908c80360db70240220530dae54a59c2e01f6c20a463fcf6943698810694ce1f8b7133a77af07cfb95e',DSA_SHA256=>'304502204b6316c274f294cbb520f80bbc4d87dc7afcaa87d8a05a677341e12fd89ee7c902210083e1b36acc4b31fb6d306a56684c81fa2b671c82b0a2564612abe14c7ced1bd2',PRI_DER=>'308203550201000282010100bae9f4e5dd259b1060ea6ff3b82c3b97e1f02b0c425b20e5d4c5d047a94d1f82509cff932ffba7c5e9b52da023903c325ae61061084dc3151ee3706523c7de8f9fea845a33415f7b53990be646a8b628d5ccbfc89b0fc7013b42ad5297281f3c0e04475544ce23f75429a5c5590d7547349ab1bae2e1167366ecccdbfe845890131692601ab0ebe62ea26dc4c01f62c501bcb34ff91d4023938a09e23d783c06092850a7dcec9a87fbb86ff497336129f67cab5c28e467f2ea39043f14233da6ef42a98d8e4c3f125b124577dbd6dd6a41293c80b542e40e309cfff667c981b678474d87fc386e6bff62f267b1e2a51a6e80788c7d598d48006e64756656465f022100b264d85ef485a50705816616ae53043812eb180375c6a1d68924ba9e741c8aaf02820100127400355ca7e838353e051904a3ab2fd02a6efc82605d435cdacfb588c30fabdc0d65ba66d7004ec30f557812bc112269f2cdcfa2354860851d991aa2155a2f06a1c5d96c738c113571f77849c5e31baf01ca9b8d95485a3665e329887d33524cec864375ee9f262464a062943b6fb9cddddfc6fc8b14639dcf52be4d3761318c9aa3a7260e3c3914a4b4561caa20a68df5acc856ea5a134d658f071364e58e79229a829c3d7d9fe499daa11fad49ec7a441d24f71e4d20517a4d5eb4bdf21348317b6bdd7b85e9871a02c32ee3b1af0231638ee4da86d04912123d90c8aed6310fff61f6aa060423a7f6abf2f05613cda96d1eadb343d43ff9bdacaab56eba0282010049f560fa511efc8614fda1be58146bc92e5799788bebd7d317fb97bbbe2df363d2188b29344a33300e76da04f3bfe5ca048413991b3491f9acdd06f8347fed58a28a2f7d95a431190fa4a0fa56221562204dd97fb2db1304e936dce96d85f768e9a7bef22bfc4f81cf535a625b7b8b643a89e9416a0c2c27806e4fa20000ff617d124a168f35f9ab47855429c5c5d95582a798826a333273f024b0e2bea5d2c56535bdbb47e5312844ce71512f941b4c14db30a3a3d0face56e90dae0d02b2f5136b27dbb85fe9da160a9f76e69cbf0a5732bc1bc0ead82632250d046bdd986bfd177c58f39bc38a3ed79387ff0912cfd09198d15abfc9743c493cc62300e03402205ca7ce7397dd512ab599883efc620734fcd0742eeb6adb07a663508cb74adf4e',PUB_DER=>'308203463082023906072a8648ce3804013082022c0282010100bae9f4e5dd259b1060ea6ff3b82c3b97e1f02b0c425b20e5d4c5d047a94d1f82509cff932ffba7c5e9b52da023903c325ae61061084dc3151ee3706523c7de8f9fea845a33415f7b53990be646a8b628d5ccbfc89b0fc7013b42ad5297281f3c0e04475544ce23f75429a5c5590d7547349ab1bae2e1167366ecccdbfe845890131692601ab0ebe62ea26dc4c01f62c501bcb34ff91d4023938a09e23d783c06092850a7dcec9a87fbb86ff497336129f67cab5c28e467f2ea39043f14233da6ef42a98d8e4c3f125b124577dbd6dd6a41293c80b542e40e309cfff667c981b678474d87fc386e6bff62f267b1e2a51a6e80788c7d598d48006e64756656465f022100b264d85ef485a50705816616ae53043812eb180375c6a1d68924ba9e741c8aaf02820100127400355ca7e838353e051904a3ab2fd02a6efc82605d435cdacfb588c30fabdc0d65ba66d7004ec30f557812bc112269f2cdcfa2354860851d991aa2155a2f06a1c5d96c738c113571f77849c5e31baf01ca9b8d95485a3665e329887d33524cec864375ee9f262464a062943b6fb9cddddfc6fc8b14639dcf52be4d3761318c9aa3a7260e3c3914a4b4561caa20a68df5acc856ea5a134d658f071364e58e79229a829c3d7d9fe499daa11fad49ec7a441d24f71e4d20517a4d5eb4bdf21348317b6bdd7b85e9871a02c32ee3b1af0231638ee4da86d04912123d90c8aed6310fff61f6aa060423a7f6abf2f05613cda96d1eadb343d43ff9bdacaab56eba03820105000282010049f560fa511efc8614fda1be58146bc92e5799788bebd7d317fb97bbbe2df363d2188b29344a33300e76da04f3bfe5ca048413991b3491f9acdd06f8347fed58a28a2f7d95a431190fa4a0fa56221562204dd97fb2db1304e936dce96d85f768e9a7bef22bfc4f81cf535a625b7b8b643a89e9416a0c2c27806e4fa20000ff617d124a168f35f9ab47855429c5c5d95582a798826a333273f024b0e2bea5d2c56535bdbb47e5312844ce71512f941b4c14db30a3a3d0face56e90dae0d02b2f5136b27dbb85fe9da160a9f76e69cbf0a5732bc1bc0ead82632250d046bdd986bfd177c58f39bc38a3ed79387ff0912cfd09198d15abfc9743c493cc62300e034'},
11 {SIZE=>3072,PRI_FILE=>'key_3072-1.pri.pem',PUB_FILE=>'key_3072-1.pub.pem',PRI=>'43062c67f9f5a90a268040fdad17d1990bf88731849baa38997dce9b145285a7',PUB=>'0384463ae72b8cf36be819c9e27d1303cbcaf779976c21492876133dafb6ece83c2402f9a7260dba4b5df25512da0a332b84079c438b9a5ea42142941d8a7170a2385d79cb904748292892ccce0c24e643658e326a1a191edddcb97fc23764d1e5fb937116b0798cc10c915e16b6694b651965969723d460693fd0e1d87882ddea7bf22a4f3c66b26ee24aff8da7b54fa37369e0a240b253c805f80f975ebbc3323e3dfbe683670dd9d4c518205756692a2fb986e101a21d4dc2b29fe2561ce48a014a33db0bfd5da99dd60d5dc111b5657266320a9295be0fef3fc483a49b8826b9f2c433a2452e5898a95d93e0cd5fd00734cab519c0131db95eb9be9d564ff3b03fe1160ea619220b3dfb21e5746798ed68aca608bc261e1832d4af45ddf62e08e1934272f8a8b063e7cb74b100b9c89cf5b6c2837abb825f8595fdb648a8f5a90a270c403c01137852b2579583c5ba7632ef2d8636c4a08856a0584252892edb6b142585aa5f370d45ccb11aece796f5b18202a309a4d3f1c124683c2209',DSA_SHA1=>'304502210080df69ae68f75c230b58f1ca262c1d164eea62b128206122799c7b08b3635a7a022026603ee5655ac7ae2c351ed73f3a952420c5625404082761e2e1fc6ca698b0e8',DSA_SHA256=>'304402203ea77e1adde22694d030e1b068166241b7c3912653c1db106afb2165c94e57cc02203cf8ab667ec48a64b8a2be2219d1252853435706d2916d08b362204e57183705',PRI_DER=>'308204d50201000282018100feb941727d8c2ab11c0dc6f712b9c7a7887a4ff691a3eb0378ea2ea223cdce8f7b6f8904465a5c25a0ba1894f82a141b2c98703a2e9fba5f70e64d88a68658e7456c398b25c5a87177fc8bff41f25ea7528f67548a7e61ff7125e7439ff5f4cb4f37a1347a0901b0fa68cad66960386fed67e82a1b0a1657209758d218e97fc44552557806d2efac2858c61332a744bf00f2cf9552828ade2ad0177b79559ade4d25b551701fab8d876068ad50598ebd9bb5e90d12cd5be1468b1a52e99ee7abad1c00f731b3369bbbef6075678ccb073709893a10315e44d21a8707dd0b6337fa36bbb127bc635abaf4358cfc997adc46d435f4a381daf5682470742e45e50877a02f5ff101b74a043a41086464ea7fd38f8e48beb29ddd421d051e232437d44f6552a1bf9546b8fa5f6a61af84df2fa2f825bb3a6dc851bbc813d44d2830074a05479bfa7743c3c9c756427fb4f6a05970b21f0c923e09a297949964707fc8af4c92ff3a86f734e872132dd4fa6bea942c16396f27c224a6d72f023e2b9a0f022100860af3885a0d2a1f8b804a2f9808e396c023767a1eeb1afa98c0afe45456af91028201806c67ad7e0e74bfe7cc0a8ef15de9a05aa181ec7b764670deba67845903615c82e92e9048678e354698ec0603b114cd53f219b3ad8067b2fd3e95d5f66804768c3aaa278189be38c0461395fbf39bfaada63e23145916328dd0d244e4143a0c37cd8f16dfcbc7d65af513e62a01ead870469798938181495847c0ff61e3b119c48aa6822cc574e995ef40e10118fc35f145ccbf36c8fe8d54d05d6b46dacdb14c43d064a12ca66887f8b2cd85e8df03d83a1e9db69a9fecf5d5fd44608e8705b6c6e553c4ef075c078b2eca1dcf6949433da60c3fd92023764141bc11f8a0fd75b046c85d11da12c271fa6c186e94c31b0919dbfc7b2e8007c2169895d3882807762a6e70e00c5d6a714a09a58f40d6a2b3d70985a2d8a362c21b286ee503253872933634fd51493be04b9204b4f9f9d2401c6cb1aa53ee5699f171ef4e53e8cde8dde4d5fff8dc76156f37c5a733ee523d8ee8cfb1bf5bd552ee32b56c62e18263843a6ba53983eb06c1996fe33fff33fd87fc88774ba60f423bf5c2ef3d6ae5028201800384463ae72b8cf36be819c9e27d1303cbcaf779976c21492876133dafb6ece83c2402f9a7260dba4b5df25512da0a332b84079c438b9a5ea42142941d8a7170a2385d79cb904748292892ccce0c24e643658e326a1a191edddcb97fc23764d1e5fb937116b0798cc10c915e16b6694b651965969723d460693fd0e1d87882ddea7bf22a4f3c66b26ee24aff8da7b54fa37369e0a240b253c805f80f975ebbc3323e3dfbe683670dd9d4c518205756692a2fb986e101a21d4dc2b29fe2561ce48a014a33db0bfd5da99dd60d5dc111b5657266320a9295be0fef3fc483a49b8826b9f2c433a2452e5898a95d93e0cd5fd00734cab519c0131db95eb9be9d564ff3b03fe1160ea619220b3dfb21e5746798ed68aca608bc261e1832d4af45ddf62e08e1934272f8a8b063e7cb74b100b9c89cf5b6c2837abb825f8595fdb648a8f5a90a270c403c01137852b2579583c5ba7632ef2d8636c4a08856a0584252892edb6b142585aa5f370d45ccb11aece796f5b18202a309a4d3f1c124683c2209022043062c67f9f5a90a268040fdad17d1990bf88731849baa38997dce9b145285a7',PUB_DER=>'308204c63082033906072a8648ce3804013082032c0282018100feb941727d8c2ab11c0dc6f712b9c7a7887a4ff691a3eb0378ea2ea223cdce8f7b6f8904465a5c25a0ba1894f82a141b2c98703a2e9fba5f70e64d88a68658e7456c398b25c5a87177fc8bff41f25ea7528f67548a7e61ff7125e7439ff5f4cb4f37a1347a0901b0fa68cad66960386fed67e82a1b0a1657209758d218e97fc44552557806d2efac2858c61332a744bf00f2cf9552828ade2ad0177b79559ade4d25b551701fab8d876068ad50598ebd9bb5e90d12cd5be1468b1a52e99ee7abad1c00f731b3369bbbef6075678ccb073709893a10315e44d21a8707dd0b6337fa36bbb127bc635abaf4358cfc997adc46d435f4a381daf5682470742e45e50877a02f5ff101b74a043a41086464ea7fd38f8e48beb29ddd421d051e232437d44f6552a1bf9546b8fa5f6a61af84df2fa2f825bb3a6dc851bbc813d44d2830074a05479bfa7743c3c9c756427fb4f6a05970b21f0c923e09a297949964707fc8af4c92ff3a86f734e872132dd4fa6bea942c16396f27c224a6d72f023e2b9a0f022100860af3885a0d2a1f8b804a2f9808e396c023767a1eeb1afa98c0afe45456af91028201806c67ad7e0e74bfe7cc0a8ef15de9a05aa181ec7b764670deba67845903615c82e92e9048678e354698ec0603b114cd53f219b3ad8067b2fd3e95d5f66804768c3aaa278189be38c0461395fbf39bfaada63e23145916328dd0d244e4143a0c37cd8f16dfcbc7d65af513e62a01ead870469798938181495847c0ff61e3b119c48aa6822cc574e995ef40e10118fc35f145ccbf36c8fe8d54d05d6b46dacdb14c43d064a12ca66887f8b2cd85e8df03d83a1e9db69a9fecf5d5fd44608e8705b6c6e553c4ef075c078b2eca1dcf6949433da60c3fd92023764141bc11f8a0fd75b046c85d11da12c271fa6c186e94c31b0919dbfc7b2e8007c2169895d3882807762a6e70e00c5d6a714a09a58f40d6a2b3d70985a2d8a362c21b286ee503253872933634fd51493be04b9204b4f9f9d2401c6cb1aa53ee5699f171ef4e53e8cde8dde4d5fff8dc76156f37c5a733ee523d8ee8cfb1bf5bd552ee32b56c62e18263843a6ba53983eb06c1996fe33fff33fd87fc88774ba60f423bf5c2ef3d6ae50382018500028201800384463ae72b8cf36be819c9e27d1303cbcaf779976c21492876133dafb6ece83c2402f9a7260dba4b5df25512da0a332b84079c438b9a5ea42142941d8a7170a2385d79cb904748292892ccce0c24e643658e326a1a191edddcb97fc23764d1e5fb937116b0798cc10c915e16b6694b651965969723d460693fd0e1d87882ddea7bf22a4f3c66b26ee24aff8da7b54fa37369e0a240b253c805f80f975ebbc3323e3dfbe683670dd9d4c518205756692a2fb986e101a21d4dc2b29fe2561ce48a014a33db0bfd5da99dd60d5dc111b5657266320a9295be0fef3fc483a49b8826b9f2c433a2452e5898a95d93e0cd5fd00734cab519c0131db95eb9be9d564ff3b03fe1160ea619220b3dfb21e5746798ed68aca608bc261e1832d4af45ddf62e08e1934272f8a8b063e7cb74b100b9c89cf5b6c2837abb825f8595fdb648a8f5a90a270c403c01137852b2579583c5ba7632ef2d8636c4a08856a0584252892edb6b142585aa5f370d45ccb11aece796f5b18202a309a4d3f1c124683c2209'},
12 {SIZE=>4096,PRI_FILE=>'key_4096-1.pri.pem',PUB_FILE=>'key_4096-1.pub.pem',PRI=>'00b14ee1226c4aeb4d7a9ff494214918c0489d479c4d0a0107928400abe41035e5',PUB=>'2a6218a818996260e331afc85e2696b02e3b6e14c25c2b7a3a742c9600c67d371be48ce4aabb814294bd7977ea3a5cec0398330c5501784dc45df1e2fa2487a02e9c4c5ba1b7c04d172db32ee6955cc5b3ea368fd044dd068d677f28d650a281f8a3bdf67efa1b1e47b885784d7281d5a5a096b39f23f52e5482b6e2c51806c69614f2f02c441542f62f0fbb8da887998bd181cc6db9d570bb8d5a14e8e6033414bf30170bdc33569685678321a4537e52fac8fe1a45c8f940c2eda85b03a257673a4f589b0956bac61bb01afd44242d10763060169eb09459d39eb9da034a8897473c5db16e3adb56216e5b81b454fe6bc622ddf3eabe3851ecf1fb9bdd2b7cf0c43184192cc9564db5e472b8d52c0b1cb7b7be3cde77424524d9f99bee280590def04b6856fdf2d5765fdb64429bd02c0083caa2d0c57a12b16d659196e6b195f02104ab02e9083c7e5158d4440bcb7a263476c10b8a389677f94274840a0436a492651f12e959bb1338757f111e80db13c6cbff4bdfc2ecd0ef0c80c16fb4bbbb6eb2a72a1a000160a65c5e79c766b09d60bbaed6e2f4a63e50d63a949a101c2d31010d212a7481e7fbdff57c5bc1dea8230882262ce661ba10c7081993657935419621a2aecae0476d487f1e09ee241bfb12e723edc95c395a4d692ab2bb6ff5bbaa5b61334600066b1e1e1e6577757089f110f4742667df74367293278b',DSA_SHA1=>'304502203085c025a9f5fc220ec42c3d3b7c14925f7fa94ee90926ad6fb00bebad056c7102210096b0e77cbc0ccfe16d3781566a9efc8c95ffc68e042a8fbc97725935bac43588',DSA_SHA256=>'304502203e0ae9a870323e30469fd854775dd1509802801eff9620b2115b7ac84bc5ea6702210085725f39bf186a24bf98d8b03aa07a90f7dca1a092a4015d428012a92cf1ed4c',PRI_DER=>'308206560201000282020100f28559890368a4d099f36f59a9e75ac562f5d0092662332924b10987f354dc97a8aa0cd77db048d52a8bee696d781d97e6df71e02b8aa35a25d891d62d7fb34ced5ee522069b6282fa9fb7b48450f24df6585b35cacd5eb2a311a1e239d4acfed79009b287f6e4265b8b369e3aba8c901ce3c421aa46d6e526f61fefd899edfcea94f416ddad7e48fd87b4b820be28e7f8a34d86e73d984eaa9c939d2e5e7ef4549ec9506f080ae18a633657e0caab2005a174a7161232158c9f76def948def72be4120da4dff7fe535c8968c3b35eba307d5c9f0142c8343469fcbafadbd4d2274ad50266bdb783e367a8703967e53836bbd0028e09c7dd37f5d5a670ab7e0af487de28a968cf8712f2aab20637d8e0a2f05f1c2075775170d4a56124090f159c9776cfda62ce66e582834023d4ba08f7de63456cfc94cd5e0b7e7d230638aa768f32d7f89262454810c0e40e303bff463e12b7691866fb004a336edf4d4c6be131c6b4690f0e4b328289bfebe98cfdf1babf8b17607d7b0ba236bb1abd56ec1698319141d8c6c4ca154a2d7d9a323a5b6005c3a9639adee5b756d42156f8ff405decb098072454af97496d017e4a2de551ad286f5f6c89925a32e042f2fab1be11e25be5848fed6986f309d55671687403d23272fb96e2017277e39b917bd34254e4275049d5a75a00e94f01077b51de470c4867b239ec739fabdf8b0bd65d022100ef8decba0475990b9cdb3d28ea579028e587cc78c4304903e98f2358692bcad9028202000c794a5b82ddf4e62bccb6e939cbf48627c8d4fb45b05d3ee175249c5feea6f6c9bc6a080e5fdd3ba86da51b7529bb7c07da35e39859f44f13fc62d8878936d0738dd00cb322edf5e6ee5503777257ab18060cccabb15a532f9ac291d508e27b939812c9b288a06aaaa3911141fd1756094dc8e843d60eed4ee974c4b8e06bea58dab388dfc7b36d088b8b9d2a6070d3bd49f20befa0734ebfaf7312c73ffad54f69609bd3e94da4296760818afc409f3f955631284f5c416a415d150bb149728fdc75443e16677c62a0193f9ece50cdf55c5877f62164d5e95d8e8da9502927036743fb292e2c5260b7561e09f26702ca4f8d1aacc68fb4f73dee9a3febded8f217725a9a18347776778c69046b55910ca984e4ce7acfec24e3435c7e966b41415b8d3c9865535a5cc149f8518a9ec6fd7ad9c8ef8074347c16a51642b2a2326be4cffcfa7611dde0633131f0f9471702d23d2271657d3e59e334c082a1205e1387b063c84d9459af72290ec0afaaf1fef3852811faf8981f5ab803aa24ec600448b65ef2bdca0d014209fa3e7db677fd1964bba279abd9785e7604ab91810002c31fac482843313019924c850c007abb6b9fe1bbdb8b90b419b636c0f90fe02f020a6a60de8e20fe5c9bfa4efe8e6a5c3bdc3adbc2a49ed1f2203ce76d5f08bf91b354104c57bd2be1cc210e6b357e247622a2ae72c710d3910bd5f64639d4028202002a6218a818996260e331afc85e2696b02e3b6e14c25c2b7a3a742c9600c67d371be48ce4aabb814294bd7977ea3a5cec0398330c5501784dc45df1e2fa2487a02e9c4c5ba1b7c04d172db32ee6955cc5b3ea368fd044dd068d677f28d650a281f8a3bdf67efa1b1e47b885784d7281d5a5a096b39f23f52e5482b6e2c51806c69614f2f02c441542f62f0fbb8da887998bd181cc6db9d570bb8d5a14e8e6033414bf30170bdc33569685678321a4537e52fac8fe1a45c8f940c2eda85b03a257673a4f589b0956bac61bb01afd44242d10763060169eb09459d39eb9da034a8897473c5db16e3adb56216e5b81b454fe6bc622ddf3eabe3851ecf1fb9bdd2b7cf0c43184192cc9564db5e472b8d52c0b1cb7b7be3cde77424524d9f99bee280590def04b6856fdf2d5765fdb64429bd02c0083caa2d0c57a12b16d659196e6b195f02104ab02e9083c7e5158d4440bcb7a263476c10b8a389677f94274840a0436a492651f12e959bb1338757f111e80db13c6cbff4bdfc2ecd0ef0c80c16fb4bbbb6eb2a72a1a000160a65c5e79c766b09d60bbaed6e2f4a63e50d63a949a101c2d31010d212a7481e7fbdff57c5bc1dea8230882262ce661ba10c7081993657935419621a2aecae0476d487f1e09ee241bfb12e723edc95c395a4d692ab2bb6ff5bbaa5b61334600066b1e1e1e6577757089f110f4742667df74367293278b022100b14ee1226c4aeb4d7a9ff494214918c0489d479c4d0a0107928400abe41035e5',PUB_DER=>'308206463082043906072a8648ce3804013082042c0282020100f28559890368a4d099f36f59a9e75ac562f5d0092662332924b10987f354dc97a8aa0cd77db048d52a8bee696d781d97e6df71e02b8aa35a25d891d62d7fb34ced5ee522069b6282fa9fb7b48450f24df6585b35cacd5eb2a311a1e239d4acfed79009b287f6e4265b8b369e3aba8c901ce3c421aa46d6e526f61fefd899edfcea94f416ddad7e48fd87b4b820be28e7f8a34d86e73d984eaa9c939d2e5e7ef4549ec9506f080ae18a633657e0caab2005a174a7161232158c9f76def948def72be4120da4dff7fe535c8968c3b35eba307d5c9f0142c8343469fcbafadbd4d2274ad50266bdb783e367a8703967e53836bbd0028e09c7dd37f5d5a670ab7e0af487de28a968cf8712f2aab20637d8e0a2f05f1c2075775170d4a56124090f159c9776cfda62ce66e582834023d4ba08f7de63456cfc94cd5e0b7e7d230638aa768f32d7f89262454810c0e40e303bff463e12b7691866fb004a336edf4d4c6be131c6b4690f0e4b328289bfebe98cfdf1babf8b17607d7b0ba236bb1abd56ec1698319141d8c6c4ca154a2d7d9a323a5b6005c3a9639adee5b756d42156f8ff405decb098072454af97496d017e4a2de551ad286f5f6c89925a32e042f2fab1be11e25be5848fed6986f309d55671687403d23272fb96e2017277e39b917bd34254e4275049d5a75a00e94f01077b51de470c4867b239ec739fabdf8b0bd65d022100ef8decba0475990b9cdb3d28ea579028e587cc78c4304903e98f2358692bcad9028202000c794a5b82ddf4e62bccb6e939cbf48627c8d4fb45b05d3ee175249c5feea6f6c9bc6a080e5fdd3ba86da51b7529bb7c07da35e39859f44f13fc62d8878936d0738dd00cb322edf5e6ee5503777257ab18060cccabb15a532f9ac291d508e27b939812c9b288a06aaaa3911141fd1756094dc8e843d60eed4ee974c4b8e06bea58dab388dfc7b36d088b8b9d2a6070d3bd49f20befa0734ebfaf7312c73ffad54f69609bd3e94da4296760818afc409f3f955631284f5c416a415d150bb149728fdc75443e16677c62a0193f9ece50cdf55c5877f62164d5e95d8e8da9502927036743fb292e2c5260b7561e09f26702ca4f8d1aacc68fb4f73dee9a3febded8f217725a9a18347776778c69046b55910ca984e4ce7acfec24e3435c7e966b41415b8d3c9865535a5cc149f8518a9ec6fd7ad9c8ef8074347c16a51642b2a2326be4cffcfa7611dde0633131f0f9471702d23d2271657d3e59e334c082a1205e1387b063c84d9459af72290ec0afaaf1fef3852811faf8981f5ab803aa24ec600448b65ef2bdca0d014209fa3e7db677fd1964bba279abd9785e7604ab91810002c31fac482843313019924c850c007abb6b9fe1bbdb8b90b419b636c0f90fe02f020a6a60de8e20fe5c9bfa4efe8e6a5c3bdc3adbc2a49ed1f2203ce76d5f08bf91b354104c57bd2be1cc210e6b357e247622a2ae72c710d3910bd5f64639d40382020500028202002a6218a818996260e331afc85e2696b02e3b6e14c25c2b7a3a742c9600c67d371be48ce4aabb814294bd7977ea3a5cec0398330c5501784dc45df1e2fa2487a02e9c4c5ba1b7c04d172db32ee6955cc5b3ea368fd044dd068d677f28d650a281f8a3bdf67efa1b1e47b885784d7281d5a5a096b39f23f52e5482b6e2c51806c69614f2f02c441542f62f0fbb8da887998bd181cc6db9d570bb8d5a14e8e6033414bf30170bdc33569685678321a4537e52fac8fe1a45c8f940c2eda85b03a257673a4f589b0956bac61bb01afd44242d10763060169eb09459d39eb9da034a8897473c5db16e3adb56216e5b81b454fe6bc622ddf3eabe3851ecf1fb9bdd2b7cf0c43184192cc9564db5e472b8d52c0b1cb7b7be3cde77424524d9f99bee280590def04b6856fdf2d5765fdb64429bd02c0083caa2d0c57a12b16d659196e6b195f02104ab02e9083c7e5158d4440bcb7a263476c10b8a389677f94274840a0436a492651f12e959bb1338757f111e80db13c6cbff4bdfc2ecd0ef0c80c16fb4bbbb6eb2a72a1a000160a65c5e79c766b09d60bbaed6e2f4a63e50d63a949a101c2d31010d212a7481e7fbdff57c5bc1dea8230882262ce661ba10c7081993657935419621a2aecae0476d487f1e09ee241bfb12e723edc95c395a4d692ab2bb6ff5bbaa5b61334600066b1e1e1e6577757089f110f4742667df74367293278b'},
13 {SIZE=>512,PRI_FILE=>'key_512-2.pri.pem',PUB_FILE=>'key_512-2.pub.pem',PRI=>'3a56c667cd9c95dec92aeafc3987274da82a57cf',PUB=>'6d00de86363f590dbaaeb289617d5b099e0bae1e483aa464411519831106a09571f13b51353f897b18865c8f6f2d3c95d9071db89333f0ec968e8f793a5069f5',DSA_SHA1=>'302c0214141fd4af5c16d4610eb37b52d54a306d3ebd37c3021463b294e41521763d0c9ec19b96e92b4dd15d0ded',DSA_SHA256=>'302c02140aaf646c5f39a84b6bc698ac8a22700cd4c8b6280214471cc080922947385772a00c9ce379b1e27b38c5',PRI_DER=>'3081f8020100024100ec6b341b598e6a69ab7aa592b071dd86345198bd5ef70a1b08285d364691439f8b0eb1516d9d8ad140c8e8aed9923eaaef1f70e16d7ad8e730812536249db869021500d4efc32035cfac6994ba06600ae587c452c4649102410093bf6ce6f9743760a2436eaae725811ca3bfec69c974413ae185860f277b58182065ee72a83a91d6d2fd66c5d0a4e8f8cec977b29a9bcfe66c080f441a3e5dfa02406d00de86363f590dbaaeb289617d5b099e0bae1e483aa464411519831106a09571f13b51353f897b18865c8f6f2d3c95d9071db89333f0ec968e8f793a5069f502143a56c667cd9c95dec92aeafc3987274da82a57cf',PUB_DER=>'3081f13081a906072a8648ce38040130819d024100ec6b341b598e6a69ab7aa592b071dd86345198bd5ef70a1b08285d364691439f8b0eb1516d9d8ad140c8e8aed9923eaaef1f70e16d7ad8e730812536249db869021500d4efc32035cfac6994ba06600ae587c452c4649102410093bf6ce6f9743760a2436eaae725811ca3bfec69c974413ae185860f277b58182065ee72a83a91d6d2fd66c5d0a4e8f8cec977b29a9bcfe66c080f441a3e5dfa03430002406d00de86363f590dbaaeb289617d5b099e0bae1e483aa464411519831106a09571f13b51353f897b18865c8f6f2d3c95d9071db89333f0ec968e8f793a5069f5'},
14 {SIZE=>1024,PRI_FILE=>'key_1024-2.pri.pem',PUB_FILE=>'key_1024-2.pub.pem',PRI=>'3e07cddee79c1312d6812e42b824fe41c800a0d1',PUB=>'11f4a38220a7ee8f0e842fe058776e655aa8490e52399d6f190e83289a3c8044e1def4f84e12ca1bce210ca33101c20e28d82db43dfe198c94158a66de392e94410e3b536d67fe1e428b2ae75d1626dcfda48b1d2469b18deade9e7b4d3ae46d20b2d89f17245bdf1a7e33ea4fc2b8fdd88ac07a3a268e0170bb2a4150060a11',DSA_SHA1=>'302d0215008ffd4c5d43bdc2d7ed52459158d686181494940b02142d40e961290fbed9a4686c276c3a18e9e4238120',DSA_SHA256=>'302d0215008f82e99fd73dc62a889ae881a14e5b644d350470021409049520599783e9659e207ebc794c8040ca06f2',PRI_DER=>'308201ba02010002818100a44cca1539a619f46a0bfddc566aad42c081ad64f17e3080a02c40f833a0eb1eabc6deeb9ad2f3efe2fb82f8714ae1d4105a29fd1db950f50a5dd6cf93e98139f5afab6cff916c66d5192e27e1bfe169927c820615796ba8542875e52b7830430462af4fc1f90d324faa12e57ee817343330bffa6a1fddb351b78592d4e801670215009c1446d67299bef01c9fa08f7fa03f96306fb4890281804b3876507dfd6f3e1fcaeaf346f59062c6f5cfc147305d5ed83525f8e51bebd29377c96b36d5d373ec90f343243e6c40770dbb35083061b0244c5fb53c25bb6aa6724a2458336520380895d8631260c5441d51b396ce1ebe9a3aeecc342fc62d50ceab15c742cf6b290b1ff4d5f7de7ec6e3ec5aff2da5d9d2b1851d3810ef0302818011f4a38220a7ee8f0e842fe058776e655aa8490e52399d6f190e83289a3c8044e1def4f84e12ca1bce210ca33101c20e28d82db43dfe198c94158a66de392e94410e3b536d67fe1e428b2ae75d1626dcfda48b1d2469b18deade9e7b4d3ae46d20b2d89f17245bdf1a7e33ea4fc2b8fdd88ac07a3a268e0170bb2a4150060a1102143e07cddee79c1312d6812e42b824fe41c800a0d1',PUB_DER=>'308201b63082012b06072a8648ce3804013082011e02818100a44cca1539a619f46a0bfddc566aad42c081ad64f17e3080a02c40f833a0eb1eabc6deeb9ad2f3efe2fb82f8714ae1d4105a29fd1db950f50a5dd6cf93e98139f5afab6cff916c66d5192e27e1bfe169927c820615796ba8542875e52b7830430462af4fc1f90d324faa12e57ee817343330bffa6a1fddb351b78592d4e801670215009c1446d67299bef01c9fa08f7fa03f96306fb4890281804b3876507dfd6f3e1fcaeaf346f59062c6f5cfc147305d5ed83525f8e51bebd29377c96b36d5d373ec90f343243e6c40770dbb35083061b0244c5fb53c25bb6aa6724a2458336520380895d8631260c5441d51b396ce1ebe9a3aeecc342fc62d50ceab15c742cf6b290b1ff4d5f7de7ec6e3ec5aff2da5d9d2b1851d3810ef030381840002818011f4a38220a7ee8f0e842fe058776e655aa8490e52399d6f190e83289a3c8044e1def4f84e12ca1bce210ca33101c20e28d82db43dfe198c94158a66de392e94410e3b536d67fe1e428b2ae75d1626dcfda48b1d2469b18deade9e7b4d3ae46d20b2d89f17245bdf1a7e33ea4fc2b8fdd88ac07a3a268e0170bb2a4150060a11'},
15 {SIZE=>1536,PRI_FILE=>'key_1536-2.pri.pem',PUB_FILE=>'key_1536-2.pub.pem',PRI=>'09d7c38692f017316b0ee0ea0ed40805c5c1afbb',PUB=>'009e39f3add36d29c6cdb19daaf75ef21c16594df511789489116f2b7f9b6e1f36a638bbcc7cd4993778d04892775bcabede3a24a907edefe0411a62f63b1f150e38b2f2a66932e37fffa5e3f83ecdc1b1107ea93f71199f2cd4f3db105ec39e01aa49877a54af76644fdbd3e2f87725cd94f34c991ba6dd1b0710c675b13dad03752b3f5caed2129873286687cc9f67c3b0c8143df89965173a0961ae173bd6a0ee16bee1b86ea7c6a634f5d9fcb46959e8524f6f2e8652046b1c32ddbcc12a6d',DSA_SHA1=>'302d021500a16ed40a1ee247e2af1d638bc0e49f8a0a0ff2ab02146761128987b8965fd52ea563f5a521af928c5438',DSA_SHA256=>'302d021500a21a000884f97aced098f6ac793824e16e1d0c7f02145d44972b36d27dfba5ef643789ff1551425ce037',PRI_DER=>'3082027c0201000281c100fba98712cd16a01b0fede62bf7785b259b7c3994b3caf492fdc4b9a596550b02e2771cf5b15a12994c59212772d83f512820391d76d4dafae6dce317fda9c3b4ffe493737e86d27c9f1ab8c7295bd16f8b69155ef43cd4196430d747a350b2dce22c8d531a60d53414c95b83fd6e4a0d14baeffc3c67b2f5eff8b4d2a8591eddea82849afc5553f44a4527cb78a03aca62deaf6996209e6e46df32eb2c910e8446e9c9d421585ae62410b082a669b2a950784b37d1e542361eab0e00dc7b3c11021500a4ff288631f6560028464eeba69f3922a661761b0281c1008df52bdcf90e37df6d8e6d52db5ebba47f9605ac345919ec8b985afe7d614b2bad9371aa7c1109b5b86bb90f79c72ff7f767f3306ccad681cb372a514de86d356a960f8798ad9d91b62e87d00a962dcef16be237ff413aadd7be1601a50df3344a99b5579e2c557a6f0d6dcc54b79d3f10e6e0a7faf8e2de861f076d4030375532451835bc0c056239bf4c904ab9567ae3c0c93b028c8c0db506945ecf3737be47d5bbcd81d8881249ab57cd7c573f7bec538b999b4590c5d4eefbd64bd6a8d10281c1009e39f3add36d29c6cdb19daaf75ef21c16594df511789489116f2b7f9b6e1f36a638bbcc7cd4993778d04892775bcabede3a24a907edefe0411a62f63b1f150e38b2f2a66932e37fffa5e3f83ecdc1b1107ea93f71199f2cd4f3db105ec39e01aa49877a54af76644fdbd3e2f87725cd94f34c991ba6dd1b0710c675b13dad03752b3f5caed2129873286687cc9f67c3b0c8143df89965173a0961ae173bd6a0ee16bee1b86ea7c6a634f5d9fcb46959e8524f6f2e8652046b1c32ddbcc12a6d021409d7c38692f017316b0ee0ea0ed40805c5c1afbb',PUB_DER=>'30820278308201ac06072a8648ce3804013082019f0281c100fba98712cd16a01b0fede62bf7785b259b7c3994b3caf492fdc4b9a596550b02e2771cf5b15a12994c59212772d83f512820391d76d4dafae6dce317fda9c3b4ffe493737e86d27c9f1ab8c7295bd16f8b69155ef43cd4196430d747a350b2dce22c8d531a60d53414c95b83fd6e4a0d14baeffc3c67b2f5eff8b4d2a8591eddea82849afc5553f44a4527cb78a03aca62deaf6996209e6e46df32eb2c910e8446e9c9d421585ae62410b082a669b2a950784b37d1e542361eab0e00dc7b3c11021500a4ff288631f6560028464eeba69f3922a661761b0281c1008df52bdcf90e37df6d8e6d52db5ebba47f9605ac345919ec8b985afe7d614b2bad9371aa7c1109b5b86bb90f79c72ff7f767f3306ccad681cb372a514de86d356a960f8798ad9d91b62e87d00a962dcef16be237ff413aadd7be1601a50df3344a99b5579e2c557a6f0d6dcc54b79d3f10e6e0a7faf8e2de861f076d4030375532451835bc0c056239bf4c904ab9567ae3c0c93b028c8c0db506945ecf3737be47d5bbcd81d8881249ab57cd7c573f7bec538b999b4590c5d4eefbd64bd6a8d10381c5000281c1009e39f3add36d29c6cdb19daaf75ef21c16594df511789489116f2b7f9b6e1f36a638bbcc7cd4993778d04892775bcabede3a24a907edefe0411a62f63b1f150e38b2f2a66932e37fffa5e3f83ecdc1b1107ea93f71199f2cd4f3db105ec39e01aa49877a54af76644fdbd3e2f87725cd94f34c991ba6dd1b0710c675b13dad03752b3f5caed2129873286687cc9f67c3b0c8143df89965173a0961ae173bd6a0ee16bee1b86ea7c6a634f5d9fcb46959e8524f6f2e8652046b1c32ddbcc12a6d'},
16 {SIZE=>2048,PRI_FILE=>'key_2048-2.pri.pem',PUB_FILE=>'key_2048-2.pub.pem',PRI=>'1c590fa44b9e739c76249737db6174cd9769fe79d03fc03ba516b8ef74ad586a',PUB=>'00cb10c09a261164c1aaad42837226eecc283064a3d25e402bd6585a3f32386e8625d082ba587417a54f3d4f78e0f439cb7dd7a0533c6b7be576313080efd2ade6877df67e0f3ac2199970601fcdebd6f764151e98d3ac2e3a29c98787b1b43562681388c607da5bc54e7607fa393bcba944d7a92eb9b590d01080e24c235f2c9d4b96a0ace845a1447816e54910dd52bfa92e6a0cf26453d7a93158cc6f41afdabf9642ca0f7507cba2d7149f194aa0e89a765fff0af4e1da6a62e37e61b6b7fc8a6f5fc4034da9f4929c128a8753cc05d02b2ea98b73e7523e461b888736e82738e67af73db59e3d834d4cc7b61989883b90f9cfdc4c9e421681498bef22ce32',DSA_SHA1=>'304502210080cbd2427d64f09496a3955467112d83cd03de839a21a54eb1a4fe17464d08bb0220507dde54e2a736a3cb6695b037a7f861b0cec2879b88b2d04d84a5df1b4a283f',DSA_SHA256=>'3044022072e70831aa0d612f0ee132e382665d2329c9f33f97735a3a1e798d03dbb3acc60220089021568f94ce8bb2a8f723cf108a98f8a2ec9d23d896dc5931ad2b3de09e7b',PRI_DER=>'308203570201000282010100ee7508d90986f6fb4dc0477fb20012661bf17040120df3349812e4081306ca8dba7036e7db55163259f52c5daaa55d86b8b04950386eeefb37e7abadcf8424685c04c207a47bc73e85cd72a0d5dfd32db9150ca5bc5c310ab990d24ce778b99ee424449e202b253ba83b038fcf184236910115c98fafabfd51a835d28a34c3ccc4c40a7bcc0eb1aeb06084c23a156e36d55b5cd208b032f741e7225aad202f556d5175e649417ffdb86a05ced41c3728387708d5048b90687e09516ce1b934f94d8226e9791ce62827cfaced6e53a9befd1aa08baa3888996d7f076442f07a33b83ae9a8e3f0bc7abe41eb4505f32d711fca1a19cee56d733d8b1f25a7734c49022100a6220ae5da12fbfb2cb7d8b1e07c7d12e55c11db8316594b575b6bdc215931f9028201010081ae4099eec0b8a4bb8e4b4a54f445fad55d49e7561130f51e1c2eda1f1bfde83f482d15ef890587b106eed4aaf102eb57141be1824f124c0f1a4c8e34aa74de6597d411b3fb49cbdb5b163886f5b8954cb80404065575873feef35b676d70922d43cb471ab0e199bd1da380e39d9b80ffd52e72cdeef88333d8f83d6aca2f2e6332363fc002c63df5e1af6ef215ea78a44b26627fa09c3dfdd74704eddfdeac13fc34ba96355f3d48483b970e52371606ac345ddf911ce35018364d5dcb3d8f0b6845c8ca049d168d8245836a627cfaf03c0751c9faa4fd3870f596a190efca507a546fead9d63a792d8b04beda3f543a5ab19890033174484fb3081d8c8f100282010100cb10c09a261164c1aaad42837226eecc283064a3d25e402bd6585a3f32386e8625d082ba587417a54f3d4f78e0f439cb7dd7a0533c6b7be576313080efd2ade6877df67e0f3ac2199970601fcdebd6f764151e98d3ac2e3a29c98787b1b43562681388c607da5bc54e7607fa393bcba944d7a92eb9b590d01080e24c235f2c9d4b96a0ace845a1447816e54910dd52bfa92e6a0cf26453d7a93158cc6f41afdabf9642ca0f7507cba2d7149f194aa0e89a765fff0af4e1da6a62e37e61b6b7fc8a6f5fc4034da9f4929c128a8753cc05d02b2ea98b73e7523e461b888736e82738e67af73db59e3d834d4cc7b61989883b90f9cfdc4c9e421681498bef22ce3202201c590fa44b9e739c76249737db6174cd9769fe79d03fc03ba516b8ef74ad586a',PUB_DER=>'308203483082023a06072a8648ce3804013082022d0282010100ee7508d90986f6fb4dc0477fb20012661bf17040120df3349812e4081306ca8dba7036e7db55163259f52c5daaa55d86b8b04950386eeefb37e7abadcf8424685c04c207a47bc73e85cd72a0d5dfd32db9150ca5bc5c310ab990d24ce778b99ee424449e202b253ba83b038fcf184236910115c98fafabfd51a835d28a34c3ccc4c40a7bcc0eb1aeb06084c23a156e36d55b5cd208b032f741e7225aad202f556d5175e649417ffdb86a05ced41c3728387708d5048b90687e09516ce1b934f94d8226e9791ce62827cfaced6e53a9befd1aa08baa3888996d7f076442f07a33b83ae9a8e3f0bc7abe41eb4505f32d711fca1a19cee56d733d8b1f25a7734c49022100a6220ae5da12fbfb2cb7d8b1e07c7d12e55c11db8316594b575b6bdc215931f9028201010081ae4099eec0b8a4bb8e4b4a54f445fad55d49e7561130f51e1c2eda1f1bfde83f482d15ef890587b106eed4aaf102eb57141be1824f124c0f1a4c8e34aa74de6597d411b3fb49cbdb5b163886f5b8954cb80404065575873feef35b676d70922d43cb471ab0e199bd1da380e39d9b80ffd52e72cdeef88333d8f83d6aca2f2e6332363fc002c63df5e1af6ef215ea78a44b26627fa09c3dfdd74704eddfdeac13fc34ba96355f3d48483b970e52371606ac345ddf911ce35018364d5dcb3d8f0b6845c8ca049d168d8245836a627cfaf03c0751c9faa4fd3870f596a190efca507a546fead9d63a792d8b04beda3f543a5ab19890033174484fb3081d8c8f1003820106000282010100cb10c09a261164c1aaad42837226eecc283064a3d25e402bd6585a3f32386e8625d082ba587417a54f3d4f78e0f439cb7dd7a0533c6b7be576313080efd2ade6877df67e0f3ac2199970601fcdebd6f764151e98d3ac2e3a29c98787b1b43562681388c607da5bc54e7607fa393bcba944d7a92eb9b590d01080e24c235f2c9d4b96a0ace845a1447816e54910dd52bfa92e6a0cf26453d7a93158cc6f41afdabf9642ca0f7507cba2d7149f194aa0e89a765fff0af4e1da6a62e37e61b6b7fc8a6f5fc4034da9f4929c128a8753cc05d02b2ea98b73e7523e461b888736e82738e67af73db59e3d834d4cc7b61989883b90f9cfdc4c9e421681498bef22ce32'},
17 {SIZE=>3072,PRI_FILE=>'key_3072-2.pri.pem',PUB_FILE=>'key_3072-2.pub.pem',PRI=>'00c2db365bb0b2788a9d1667d78d9103e43ae3d1417c3b475dbf5a1dd72c847dde',PUB=>'0b5601ed1907996bae158b1702daaae656884f08470597e74fa894fff8f5af2ee6c576c182b58abdf7b3e24833890e4e80ca6df45a26d8e504bbcb9c4ed0977dd04ac31cb3fd1834fd488527ccc8710de82b3421ebc367c9b18ebf43b4e218973d5fd63e01448e0633a7be225cc2974306fd908067920500a275a2ff37183c14c7951c72a7186c4a8b755bea148d29ffabc9895a2c7b798f80c39038ece615051ccb077eef7ac1a08a38c4dcf7cd1132202e7672848d2317b021d3779778f4d8d5a05308ba8d36f262cd661ea53a421f22bd94b521e2e9cb7e7a2831421cbe5cff7bee38ec95b1fc1a3bb09aab2395be4e5ebba2e8fe8122dde881d284ec5677f8ffdb33224c763d9fc88651df6defc321626e1c28309d80eb978392e41daf5575e9455c74db761f03367c3faf234d28d1cec619f43aaa88d5c4705f221ab9387740d30fe600399971a26c59d1a85dc075bf4515b8e41abd925c68dd49d19282119297308cf3883bc99a61c1a7bb85c28c5f3f5d863045eac5ce1b00e33a2afa',DSA_SHA1=>'3046022100cfce16904b96e5590b17bec1f739bc7aed862e9aa08d94e3d4bd465fcde977db022100dfccf04c741c4ea5e98030f1936f0928d1550f1b5ed3fe92324fc9b3715193ce',DSA_SHA256=>'3044022069f3380c6dbe99b2bc350d5d982ba2ada5605f260d15b9fa468eff1f13a6e490022030ee9d88348dc113ee3fa819e158593081fd1df15d6a803479ff68acd8509128',PRI_DER=>'308204d60201000282018100b237ef71b02ce1e42a2b3d0f5e64ee2e3c1424b1aba696d83f9ee26d0ff58fc9b506eaca7d9d1ffbab6c0aa750f87afe7661a00bb2abbc28c8f44d9d782bc955262dc4200159cf3ddf9ef7b31ce3606838af4edbfd4395f14177788059e34830b9598facf541d82306626ff5b3f6a846534e60d5d7cbdc97917c720771b1e4a9498d9a37ee997e6bac19612f7320db729f6b8c47899d6c0a80083cfaa1a534d81e0fd019d6bf145ee448e26b1597baa7140207d73924f1be96d77adc029a980019b22fa3b2a9d9c6421e0017c7c40e4b236808ad341b91403f75a1a8e57a96bd0e477458bedf13239da92176fe7b7beabe25f9edaa52c50871cb25d44faad5a0e8835bcaaf727bc9a49e77712a4006f6ac7159d954d5f5ebd4927b868e74f9409671d8b702f3e4adccd075bd3cc801de48bf3143f7e8c189f05bb7b4ef8a331ed8d806815903dd5b3e01b31928377b12ee7ee198fbd65e9c06faed56ebb170c1452c4097eb31f71c6dce49a06c9c9d74fda29ee65e74514736c78401372cabd7022100ed52f447dd0081a130d018d365c4267ec6bad820b5adf15133fd400a941d9929028201804815c0ad70253b9f0dc57a1970b7fa902f52ae06314587823043661de3f2a066a360de3a500138fbb4cfc499853550b9604d23f05b3537efc65dbf7f7149ab7e84646fad8e181fa8efcd559bcb66c29d65f71165d2564a0def5c53af84e878f1d0193f74d27c2229b6ccda82f696db41716688776c33aa9926031ef801f2519fb195d1f35236bf28e424fecf10bdc68681e30e6866810d9db7e8da5b3798a75243c9f50c18ec7bf57f266005b2e346f0038c104e7da5e8d64e8b80a41d7efba79f632493eeb06a830ee451016241a2e55820caa55c00bdd77728d6490d9b2ed2649e8ea3c92d28f8349aeef2e4fb11d76d5604dd7ce23f7fbb63adf6bbef219f6846660221f9cae8587dfba7ef1dd06a174f23ca5d2df23b4e35100d706d8af09b93c1cde387f5f814a1014cc1c0bf9662dd3eca365a6376d79058e6f5c73a04bb0064519d6b89de953ffc15044ecb7b7f16483c80084ea24dc0c1b3ae3b35d9f15519610534b18b9a66abb139bab1f1924b9d20e0d7dae504cef39cd71237f1028201800b5601ed1907996bae158b1702daaae656884f08470597e74fa894fff8f5af2ee6c576c182b58abdf7b3e24833890e4e80ca6df45a26d8e504bbcb9c4ed0977dd04ac31cb3fd1834fd488527ccc8710de82b3421ebc367c9b18ebf43b4e218973d5fd63e01448e0633a7be225cc2974306fd908067920500a275a2ff37183c14c7951c72a7186c4a8b755bea148d29ffabc9895a2c7b798f80c39038ece615051ccb077eef7ac1a08a38c4dcf7cd1132202e7672848d2317b021d3779778f4d8d5a05308ba8d36f262cd661ea53a421f22bd94b521e2e9cb7e7a2831421cbe5cff7bee38ec95b1fc1a3bb09aab2395be4e5ebba2e8fe8122dde881d284ec5677f8ffdb33224c763d9fc88651df6defc321626e1c28309d80eb978392e41daf5575e9455c74db761f03367c3faf234d28d1cec619f43aaa88d5c4705f221ab9387740d30fe600399971a26c59d1a85dc075bf4515b8e41abd925c68dd49d19282119297308cf3883bc99a61c1a7bb85c28c5f3f5d863045eac5ce1b00e33a2afa022100c2db365bb0b2788a9d1667d78d9103e43ae3d1417c3b475dbf5a1dd72c847dde',PUB_DER=>'308204c63082033906072a8648ce3804013082032c0282018100b237ef71b02ce1e42a2b3d0f5e64ee2e3c1424b1aba696d83f9ee26d0ff58fc9b506eaca7d9d1ffbab6c0aa750f87afe7661a00bb2abbc28c8f44d9d782bc955262dc4200159cf3ddf9ef7b31ce3606838af4edbfd4395f14177788059e34830b9598facf541d82306626ff5b3f6a846534e60d5d7cbdc97917c720771b1e4a9498d9a37ee997e6bac19612f7320db729f6b8c47899d6c0a80083cfaa1a534d81e0fd019d6bf145ee448e26b1597baa7140207d73924f1be96d77adc029a980019b22fa3b2a9d9c6421e0017c7c40e4b236808ad341b91403f75a1a8e57a96bd0e477458bedf13239da92176fe7b7beabe25f9edaa52c50871cb25d44faad5a0e8835bcaaf727bc9a49e77712a4006f6ac7159d954d5f5ebd4927b868e74f9409671d8b702f3e4adccd075bd3cc801de48bf3143f7e8c189f05bb7b4ef8a331ed8d806815903dd5b3e01b31928377b12ee7ee198fbd65e9c06faed56ebb170c1452c4097eb31f71c6dce49a06c9c9d74fda29ee65e74514736c78401372cabd7022100ed52f447dd0081a130d018d365c4267ec6bad820b5adf15133fd400a941d9929028201804815c0ad70253b9f0dc57a1970b7fa902f52ae06314587823043661de3f2a066a360de3a500138fbb4cfc499853550b9604d23f05b3537efc65dbf7f7149ab7e84646fad8e181fa8efcd559bcb66c29d65f71165d2564a0def5c53af84e878f1d0193f74d27c2229b6ccda82f696db41716688776c33aa9926031ef801f2519fb195d1f35236bf28e424fecf10bdc68681e30e6866810d9db7e8da5b3798a75243c9f50c18ec7bf57f266005b2e346f0038c104e7da5e8d64e8b80a41d7efba79f632493eeb06a830ee451016241a2e55820caa55c00bdd77728d6490d9b2ed2649e8ea3c92d28f8349aeef2e4fb11d76d5604dd7ce23f7fbb63adf6bbef219f6846660221f9cae8587dfba7ef1dd06a174f23ca5d2df23b4e35100d706d8af09b93c1cde387f5f814a1014cc1c0bf9662dd3eca365a6376d79058e6f5c73a04bb0064519d6b89de953ffc15044ecb7b7f16483c80084ea24dc0c1b3ae3b35d9f15519610534b18b9a66abb139bab1f1924b9d20e0d7dae504cef39cd71237f10382018500028201800b5601ed1907996bae158b1702daaae656884f08470597e74fa894fff8f5af2ee6c576c182b58abdf7b3e24833890e4e80ca6df45a26d8e504bbcb9c4ed0977dd04ac31cb3fd1834fd488527ccc8710de82b3421ebc367c9b18ebf43b4e218973d5fd63e01448e0633a7be225cc2974306fd908067920500a275a2ff37183c14c7951c72a7186c4a8b755bea148d29ffabc9895a2c7b798f80c39038ece615051ccb077eef7ac1a08a38c4dcf7cd1132202e7672848d2317b021d3779778f4d8d5a05308ba8d36f262cd661ea53a421f22bd94b521e2e9cb7e7a2831421cbe5cff7bee38ec95b1fc1a3bb09aab2395be4e5ebba2e8fe8122dde881d284ec5677f8ffdb33224c763d9fc88651df6defc321626e1c28309d80eb978392e41daf5575e9455c74db761f03367c3faf234d28d1cec619f43aaa88d5c4705f221ab9387740d30fe600399971a26c59d1a85dc075bf4515b8e41abd925c68dd49d19282119297308cf3883bc99a61c1a7bb85c28c5f3f5d863045eac5ce1b00e33a2afa'},
18 {SIZE=>4096,PRI_FILE=>'key_4096-2.pri.pem',PUB_FILE=>'key_4096-2.pub.pem',PRI=>'38d41fa4f9f1b5c0f500db4333315efaa712e71cde8d789c6752166d48961287',PUB=>'0b368f4ad35f6e0b56d933d65446716d93869555a8ea5b2d8c3739ff84b6c5e330f340b667d6614249544f60896d6a8826b2cdba78c294a8a89680dc3b21885739578b1c81bc7832aadc9ca88a892cfa0b1a7fad0c4c45f2e021b1667403063855e022d1c689fb1c18239e0c8c615ca7c73d55ebd83050fc7378dfe6e4f4f30bff7b96c5def16d27fcccf40c27acae8dc2c2816b5eabbc85ad760b988ec24c33f3e2bb9757324c72b86d9baeb1899ca05a39faab9791d880927a1c6c6ec2ca695b5bc5666c94f681f958770018801323d597003153967b4c9ef3b44c65d367c86df422f9414b206db83e4264ab1e07a2be26f16cf890ae17a7335700223d46942f560834b9b368c8182f53a94aee019160544211e221caefd9697b98952543e596ffb35c1b781d181c6a1ee46c7e046b9a7281b463a7598eb04fda97e50f50f0fc191cbc0f0099432283870afce578fdfe0571f5aee8d26e0665985106ac779ae14134a0701d8864be3a7b75512cb202e2b607e90747df8177dd527d91055f6ff655ccd42fcd1b9acb71112a57c4485c23863fce3fac5dd9669cadeec0388083a087d10265ef3b215f3f0bdb7e8b6365a48583f1db8e957c39388e1655355d55890399c09c79a3d4b210c376522b95c364a804736b38ade020968febdf79fd4caa32b8ad1a3b6b4ecc57253738f3fd91fc4f6b76dfec5a3e7016b91bc0c366e2',DSA_SHA1=>'3044022026c960994107c0fa57498d136e915430577342513bfbc13b2c366ee83e0963fd0220290cf102aece997ab5811b0b19fcfecf8f8d131cf66efa23bdfe77e77eff7863',DSA_SHA256=>'304402203d265b947a4ece7bc09fac28b44e4957f07f6797ab7fab37d0618badc7d6cdae022041a9b074d9a0f8f10c79bd585192d85a2cb3670f39d8e661ee171474a2878f89',PRI_DER=>'30820655020100028202010090b1ddb54da806089760fafeb78ddbe711f28029e7759b9617f8f08708a28b9e3ece970e1faeaac05f6df297f417f45a7037f19fcab47d2d9ba6eae1d46a5f84ecb01511b796ac40dd26b794262410042e18c023806986fb8a1fe796e254f0b19f4c948c09f5980e9ed6789c9fed5e262eeefef61661c45479b0580fd81a380ddf18f6e7839f362515bdbcb67abda613bf9308f7667d6828b02b30bd33bbf32455bc7e5c112c80a7acb0e4917eb05f6e59f794887b909a061ac92dc579d9913ce454e51d856c07632a4a37af749d834b3b994a15193187eca0a20a325c42ef46386e0b01b17102f38ef0ab8e4cca6e52b158c5448957123df4b95f9d11a965a099dd986dd065f482432c023dd2c47231d300e03bc385e1721ff20b7b73c93f9c9e8f0125eb5f8e562eb8bfc187f69a942e1cc395ec531afd04e5b4867a7fcdc31bde4cfce070510d1c6b6dc27d3603c3eebcd7a0853b1b473838629c9b2356c1b340920a94ada02c59e49eae8ecdfbe6826a9b357dee648ab2723ea0bf9f2fa73c1ef86b2dbb2ade24d9d9ba1e9302a8e01a9fedf4b7fadba98fcc825397c49d341933df3b20a4f6baea78ee298df10e3482f1742d86bbd35e3426ae674a1d8059fa0d6ff1761f7df80fa628c17944ddd7e04798e64c2dcf689320bc3827b034c5b9a5e0de71a9a176a354671c2f178b89e294a04253b4b45cc4dd93c14fdb2702210081ec0285d408ba6cd1510844c6688e043ca153c251f8b013e81387e2dce34567028202000c517a3ce47e34e7fe8e40d1868e5c5b20f7c5d34f5c50abf776c4a229331aa66006d55824be2941ec88d664536641884e1a50ae02c789b323d7148073df13dded991591d84f29b38c37da71a4930160c1ce6bd3c0d2501f461db4e0e750b543631a7809e991a932527ee7de40b2709ad777e36f443d208de3898d2694af863494a1d13524d4d68bf23d40d2856c3f5b496053f6a7f0ed649a6165ab8ff6a3d6e733e0a7e55972e32d53afd0f8d62e4596ea0e95be45ac7939003f02d31904389cef190ea07456b2198e27c1fc1be7f1d40a9d57d5826f81e1430fbf7f73036e6069cb06438632add8c594619ccb28018b4e25a28940fc99e85aa909864bcbd6ac77d1021e2ecd7900c313179b9ec0b3fc0a619800389995e3be5f89d0bbb55e6e7b963aeee3bff45dbf76d8cb1be3b7ccc511b1a056df14b71927fbb64df02773a160c2dfb534f62b56f4fee6dd864ae46b366d96aee8fd714d4f8e87c27f53293475344b0117430c6033b41a19ac48d1472691f5123540477e23383848c308211a6c7d87885ec4db1edc424da2102006f4506f3e077c118a3f080ec0bdd03151bef1a2d860f9a6df2cf7b9ea7a6597f6bcd21bf8960e6a36ef032ed49ef11e5bdaf2b4b8b30178dae663f7f2dffb1d3e25ee4d039c2302164255353ce52535901fc9b9a054c1fb8fd0b9a2d8bc661ed0603f2e00f3d3532051082bb251c157028202000b368f4ad35f6e0b56d933d65446716d93869555a8ea5b2d8c3739ff84b6c5e330f340b667d6614249544f60896d6a8826b2cdba78c294a8a89680dc3b21885739578b1c81bc7832aadc9ca88a892cfa0b1a7fad0c4c45f2e021b1667403063855e022d1c689fb1c18239e0c8c615ca7c73d55ebd83050fc7378dfe6e4f4f30bff7b96c5def16d27fcccf40c27acae8dc2c2816b5eabbc85ad760b988ec24c33f3e2bb9757324c72b86d9baeb1899ca05a39faab9791d880927a1c6c6ec2ca695b5bc5666c94f681f958770018801323d597003153967b4c9ef3b44c65d367c86df422f9414b206db83e4264ab1e07a2be26f16cf890ae17a7335700223d46942f560834b9b368c8182f53a94aee019160544211e221caefd9697b98952543e596ffb35c1b781d181c6a1ee46c7e046b9a7281b463a7598eb04fda97e50f50f0fc191cbc0f0099432283870afce578fdfe0571f5aee8d26e0665985106ac779ae14134a0701d8864be3a7b75512cb202e2b607e90747df8177dd527d91055f6ff655ccd42fcd1b9acb71112a57c4485c23863fce3fac5dd9669cadeec0388083a087d10265ef3b215f3f0bdb7e8b6365a48583f1db8e957c39388e1655355d55890399c09c79a3d4b210c376522b95c364a804736b38ade020968febdf79fd4caa32b8ad1a3b6b4ecc57253738f3fd91fc4f6b76dfec5a3e7016b91bc0c366e2022038d41fa4f9f1b5c0f500db4333315efaa712e71cde8d789c6752166d48961287',PUB_DER=>'308206463082043906072a8648ce3804013082042c028202010090b1ddb54da806089760fafeb78ddbe711f28029e7759b9617f8f08708a28b9e3ece970e1faeaac05f6df297f417f45a7037f19fcab47d2d9ba6eae1d46a5f84ecb01511b796ac40dd26b794262410042e18c023806986fb8a1fe796e254f0b19f4c948c09f5980e9ed6789c9fed5e262eeefef61661c45479b0580fd81a380ddf18f6e7839f362515bdbcb67abda613bf9308f7667d6828b02b30bd33bbf32455bc7e5c112c80a7acb0e4917eb05f6e59f794887b909a061ac92dc579d9913ce454e51d856c07632a4a37af749d834b3b994a15193187eca0a20a325c42ef46386e0b01b17102f38ef0ab8e4cca6e52b158c5448957123df4b95f9d11a965a099dd986dd065f482432c023dd2c47231d300e03bc385e1721ff20b7b73c93f9c9e8f0125eb5f8e562eb8bfc187f69a942e1cc395ec531afd04e5b4867a7fcdc31bde4cfce070510d1c6b6dc27d3603c3eebcd7a0853b1b473838629c9b2356c1b340920a94ada02c59e49eae8ecdfbe6826a9b357dee648ab2723ea0bf9f2fa73c1ef86b2dbb2ade24d9d9ba1e9302a8e01a9fedf4b7fadba98fcc825397c49d341933df3b20a4f6baea78ee298df10e3482f1742d86bbd35e3426ae674a1d8059fa0d6ff1761f7df80fa628c17944ddd7e04798e64c2dcf689320bc3827b034c5b9a5e0de71a9a176a354671c2f178b89e294a04253b4b45cc4dd93c14fdb2702210081ec0285d408ba6cd1510844c6688e043ca153c251f8b013e81387e2dce34567028202000c517a3ce47e34e7fe8e40d1868e5c5b20f7c5d34f5c50abf776c4a229331aa66006d55824be2941ec88d664536641884e1a50ae02c789b323d7148073df13dded991591d84f29b38c37da71a4930160c1ce6bd3c0d2501f461db4e0e750b543631a7809e991a932527ee7de40b2709ad777e36f443d208de3898d2694af863494a1d13524d4d68bf23d40d2856c3f5b496053f6a7f0ed649a6165ab8ff6a3d6e733e0a7e55972e32d53afd0f8d62e4596ea0e95be45ac7939003f02d31904389cef190ea07456b2198e27c1fc1be7f1d40a9d57d5826f81e1430fbf7f73036e6069cb06438632add8c594619ccb28018b4e25a28940fc99e85aa909864bcbd6ac77d1021e2ecd7900c313179b9ec0b3fc0a619800389995e3be5f89d0bbb55e6e7b963aeee3bff45dbf76d8cb1be3b7ccc511b1a056df14b71927fbb64df02773a160c2dfb534f62b56f4fee6dd864ae46b366d96aee8fd714d4f8e87c27f53293475344b0117430c6033b41a19ac48d1472691f5123540477e23383848c308211a6c7d87885ec4db1edc424da2102006f4506f3e077c118a3f080ec0bdd03151bef1a2d860f9a6df2cf7b9ea7a6597f6bcd21bf8960e6a36ef032ed49ef11e5bdaf2b4b8b30178dae663f7f2dffb1d3e25ee4d039c2302164255353ce52535901fc9b9a054c1fb8fd0b9a2d8bc661ed0603f2e00f3d3532051082bb251c1570382020500028202000b368f4ad35f6e0b56d933d65446716d93869555a8ea5b2d8c3739ff84b6c5e330f340b667d6614249544f60896d6a8826b2cdba78c294a8a89680dc3b21885739578b1c81bc7832aadc9ca88a892cfa0b1a7fad0c4c45f2e021b1667403063855e022d1c689fb1c18239e0c8c615ca7c73d55ebd83050fc7378dfe6e4f4f30bff7b96c5def16d27fcccf40c27acae8dc2c2816b5eabbc85ad760b988ec24c33f3e2bb9757324c72b86d9baeb1899ca05a39faab9791d880927a1c6c6ec2ca695b5bc5666c94f681f958770018801323d597003153967b4c9ef3b44c65d367c86df422f9414b206db83e4264ab1e07a2be26f16cf890ae17a7335700223d46942f560834b9b368c8182f53a94aee019160544211e221caefd9697b98952543e596ffb35c1b781d181c6a1ee46c7e046b9a7281b463a7598eb04fda97e50f50f0fc191cbc0f0099432283870afce578fdfe0571f5aee8d26e0665985106ac779ae14134a0701d8864be3a7b75512cb202e2b607e90747df8177dd527d91055f6ff655ccd42fcd1b9acb71112a57c4485c23863fce3fac5dd9669cadeec0388083a087d10265ef3b215f3f0bdb7e8b6365a48583f1db8e957c39388e1655355d55890399c09c79a3d4b210c376522b95c364a804736b38ade020968febdf79fd4caa32b8ad1a3b6b4ecc57253738f3fd91fc4f6b76dfec5a3e7016b91bc0c366e2'},
19 {SIZE=>512,PRI_FILE=>'key_512-3.pri.pem',PUB_FILE=>'key_512-3.pub.pem',PRI=>'44ad88412b165ab43a59205dee392b71a7166462',PUB=>'7354177bb79b818530f0afc8f1a8379273b3f6c22febce156e9ac187c97d99ed94e0465e96d688cd9e0896cd7fd2e755a9bd81206c5fcf28a28dde23d773270b',DSA_SHA1=>'302e021500a1a36ecd213faf706340004f766e8473d7d84a24021500b0431f94dbf71cb29424525ffcf3f46552ffd392',DSA_SHA256=>'302d02143a67062aa24c257431c3ac8ad1cd33a453ff545c0215008dfc43a31aade0136548451a4a2ca4d54f3b8715',PRI_DER=>'3081f70201000241009b328b2ee18d24b0c9f030c68038cab21d547a422f2bcced33b28b89c01f8ecc36f00d5a30d0cede004806ed3e1b1ec5231724d85756f8afabac16914c595a65021500b1e2ea9e46f4bf1f8bd158a0463e4c6fe50b1d8d024027f89024380018f5c3e2adc5d85763d82e4c54a9cacb6a1c25f7c12b29eeb0eddc7593e112a07576ad6dd4c4b78cf624d5df25a6a4cd69c7132e7a693990519302407354177bb79b818530f0afc8f1a8379273b3f6c22febce156e9ac187c97d99ed94e0465e96d688cd9e0896cd7fd2e755a9bd81206c5fcf28a28dde23d773270b021444ad88412b165ab43a59205dee392b71a7166462',PUB_DER=>'3081f03081a806072a8648ce38040130819c0241009b328b2ee18d24b0c9f030c68038cab21d547a422f2bcced33b28b89c01f8ecc36f00d5a30d0cede004806ed3e1b1ec5231724d85756f8afabac16914c595a65021500b1e2ea9e46f4bf1f8bd158a0463e4c6fe50b1d8d024027f89024380018f5c3e2adc5d85763d82e4c54a9cacb6a1c25f7c12b29eeb0eddc7593e112a07576ad6dd4c4b78cf624d5df25a6a4cd69c7132e7a693990519303430002407354177bb79b818530f0afc8f1a8379273b3f6c22febce156e9ac187c97d99ed94e0465e96d688cd9e0896cd7fd2e755a9bd81206c5fcf28a28dde23d773270b'},
20 {SIZE=>1024,PRI_FILE=>'key_1024-3.pri.pem',PUB_FILE=>'key_1024-3.pub.pem',PRI=>'4589befc1e879af92d5aa5ebfb816d5cacb77297',PUB=>'0082af54957f228f659e65c974db10e4f7811f9f7a13b8e9b1dc7331284ad54f588f2b891745a36c9a5eb1e5bba4f28c4e357c494fad8f4b446421e5d823904816ce6233694c7114be15a0002ab92956b7787b1986dd6bb578b83933ab878593202ff74e94196e7fceb13fa55f5a1c4588d6c6b3c2941edda4fcd7ca66f7e2585a',DSA_SHA1=>'302c02140f83819f9e2acb17223aa75427240311a775e13402146d17093744308954cfe894790ed903a8811852b9',DSA_SHA256=>'302c0214236c3dece1c1cfda8fd6a581052aeea7a6a328e002140d790d58d2d8cc85383618eba360e414999c48e2',PRI_DER=>'308201bb0201000281810088d428e174d87c18265d9da55b384d1228c1fa6bf036401e8a41022bb32e5fbcb5ad3a75ef3ab7d90ece0b1ffbe611ed89beb2d59e2c40d570e8af8a6821936b29725074885a3a6ace615dce8fbceef93a3d3f671fd2ac4742ec0a18fc9369d003c127c603eb3b4d5d45cc9bbfdcd556e6a8418db55c453dc08f56e158e9aa03021500d452d5c4fd4bc831e0dc8c5d2d36ceda165fba9502818031bef6d3315713597c8f8e0306f9872e66ace4c54c30a76afbbfcacc2e2c4a719d947ed2b2f180ffb241ff62d7e5e000556e56ca5aa1e9e59b9a375d4b6779558787f9f931801b94cbe3a663dd9554077f597e719f276686b921a5477997d97b6953cdc8e05ad73ffeb9ebe7cff684a29021fe77d3ea432a5bb417fd422cad6a0281810082af54957f228f659e65c974db10e4f7811f9f7a13b8e9b1dc7331284ad54f588f2b891745a36c9a5eb1e5bba4f28c4e357c494fad8f4b446421e5d823904816ce6233694c7114be15a0002ab92956b7787b1986dd6bb578b83933ab878593202ff74e94196e7fceb13fa55f5a1c4588d6c6b3c2941edda4fcd7ca66f7e2585a02144589befc1e879af92d5aa5ebfb816d5cacb77297',PUB_DER=>'308201b73082012b06072a8648ce3804013082011e0281810088d428e174d87c18265d9da55b384d1228c1fa6bf036401e8a41022bb32e5fbcb5ad3a75ef3ab7d90ece0b1ffbe611ed89beb2d59e2c40d570e8af8a6821936b29725074885a3a6ace615dce8fbceef93a3d3f671fd2ac4742ec0a18fc9369d003c127c603eb3b4d5d45cc9bbfdcd556e6a8418db55c453dc08f56e158e9aa03021500d452d5c4fd4bc831e0dc8c5d2d36ceda165fba9502818031bef6d3315713597c8f8e0306f9872e66ace4c54c30a76afbbfcacc2e2c4a719d947ed2b2f180ffb241ff62d7e5e000556e56ca5aa1e9e59b9a375d4b6779558787f9f931801b94cbe3a663dd9554077f597e719f276686b921a5477997d97b6953cdc8e05ad73ffeb9ebe7cff684a29021fe77d3ea432a5bb417fd422cad6a038185000281810082af54957f228f659e65c974db10e4f7811f9f7a13b8e9b1dc7331284ad54f588f2b891745a36c9a5eb1e5bba4f28c4e357c494fad8f4b446421e5d823904816ce6233694c7114be15a0002ab92956b7787b1986dd6bb578b83933ab878593202ff74e94196e7fceb13fa55f5a1c4588d6c6b3c2941edda4fcd7ca66f7e2585a'},
21 {SIZE=>1536,PRI_FILE=>'key_1536-3.pri.pem',PUB_FILE=>'key_1536-3.pub.pem',PRI=>'00f71141cf80f653272aaa38288b45424bf5145f3d',PUB=>'53f6a23eef20ee0032caa4a4ceea6eca6a4448246be18b935ddbb4982d737dd5bc216cf50b4343beca56d913175b8c984d7aa381fe55e60ff5cd5cdd12e7e1f16f29a25bc1911a2a14911dbf31c4004246e6930ed5b884ecc73332a9120c27aaa731a3249163ad91764a3883a3ea477744c9c5349abcf6291ef5ba5102aee912b475e4186eb400594474ecb6c53f996b17e2e9d1238fa2b9d44a6df4e536cff96cde614d5e146446303beba02b520ddf6fe42414391f73daacc5365e4b881d16',DSA_SHA1=>'302d0215008d3cddc5e8d7e19ced7d7859f8ec38e3a0c352be02143657b7417c64cf715eac4a1666c9e964e0ae5ac8',DSA_SHA256=>'302d02147d8330a66f4415e548a72c9bc95a172d1ce423ff021500df28aa0a60965fa6f096b95c216d419c219f8435',PRI_DER=>'3082027c0201000281c100b8dce58c5b30fa449a4d8a8c97bd8bd8279f47a15b0f4cc5ef9b566c19d3259ee57292f5d8a84fa11df9c9a3ea3183ad2cc62b7261da4815acf620387c265235c89c0ef4e7de13ce081b47dab3046a68a6858b183028567dae91fbbca6ce263af5bdc106018cf47686aea352df286af5c48d14c4fe528731c5684c5efb79e99bffd87e7c6ee52e4bb5ea536dfb85ea33a241f99adb30c5489f9c4b5b6f4a0231f74cae0986f70a0ef259e9ca18937abe8ce387c51644e0bb58950037098cc8bf021500facd6fa6fab1a552398b3fdd07fb704354ad305f0281c100b665a4de3c066541735a9a5c60707512e2e37af0ef3f36c7d73c7f419b98d1956aadac1551fb9196a1ed1f6318a0d100ec3f2e6b9dba345a9362db38b07d2e5f42ca91d4dc0168fd61a09c60c95596f7b1eda3a238db6931aced78116f4ec0cf901afd18d7143ee442a1037c3ee0efe80f120eb8bfdebf3b5c9f0e0d71f68a00393f5ce5b774cb1e44cfec7a794e34e6d7907a6c233d41a375779812f4c8283b24d8d18cfd13fbd717076004ed5cf59f2b5884e2310c069df1c5e75081a7202a0281c053f6a23eef20ee0032caa4a4ceea6eca6a4448246be18b935ddbb4982d737dd5bc216cf50b4343beca56d913175b8c984d7aa381fe55e60ff5cd5cdd12e7e1f16f29a25bc1911a2a14911dbf31c4004246e6930ed5b884ecc73332a9120c27aaa731a3249163ad91764a3883a3ea477744c9c5349abcf6291ef5ba5102aee912b475e4186eb400594474ecb6c53f996b17e2e9d1238fa2b9d44a6df4e536cff96cde614d5e146446303beba02b520ddf6fe42414391f73daacc5365e4b881d16021500f71141cf80f653272aaa38288b45424bf5145f3d',PUB_DER=>'30820277308201ac06072a8648ce3804013082019f0281c100b8dce58c5b30fa449a4d8a8c97bd8bd8279f47a15b0f4cc5ef9b566c19d3259ee57292f5d8a84fa11df9c9a3ea3183ad2cc62b7261da4815acf620387c265235c89c0ef4e7de13ce081b47dab3046a68a6858b183028567dae91fbbca6ce263af5bdc106018cf47686aea352df286af5c48d14c4fe528731c5684c5efb79e99bffd87e7c6ee52e4bb5ea536dfb85ea33a241f99adb30c5489f9c4b5b6f4a0231f74cae0986f70a0ef259e9ca18937abe8ce387c51644e0bb58950037098cc8bf021500facd6fa6fab1a552398b3fdd07fb704354ad305f0281c100b665a4de3c066541735a9a5c60707512e2e37af0ef3f36c7d73c7f419b98d1956aadac1551fb9196a1ed1f6318a0d100ec3f2e6b9dba345a9362db38b07d2e5f42ca91d4dc0168fd61a09c60c95596f7b1eda3a238db6931aced78116f4ec0cf901afd18d7143ee442a1037c3ee0efe80f120eb8bfdebf3b5c9f0e0d71f68a00393f5ce5b774cb1e44cfec7a794e34e6d7907a6c233d41a375779812f4c8283b24d8d18cfd13fbd717076004ed5cf59f2b5884e2310c069df1c5e75081a7202a0381c4000281c053f6a23eef20ee0032caa4a4ceea6eca6a4448246be18b935ddbb4982d737dd5bc216cf50b4343beca56d913175b8c984d7aa381fe55e60ff5cd5cdd12e7e1f16f29a25bc1911a2a14911dbf31c4004246e6930ed5b884ecc73332a9120c27aaa731a3249163ad91764a3883a3ea477744c9c5349abcf6291ef5ba5102aee912b475e4186eb400594474ecb6c53f996b17e2e9d1238fa2b9d44a6df4e536cff96cde614d5e146446303beba02b520ddf6fe42414391f73daacc5365e4b881d16'},
22 {SIZE=>2048,PRI_FILE=>'key_2048-3.pri.pem',PUB_FILE=>'key_2048-3.pub.pem',PRI=>'193475eb231fd607055354f80d9ff3e57ec231e8dbbff55f95482fd519b74fe0',PUB=>'661321784a1ea8dc4790d824e1f816f29245e01801336a3c171019815c7a948e4c39304b4f242a8353a4f7c1b51d1a1318145769f5cdf4ede0728f383b896d4ece262706e4612711427f96651c1440f1b7ef669a9811771c777e851cc6f81fb205ea8e8e1585a0dadca1b6f5e276590716616345d8a3fba6fb3a3b7c34ed16a3214fd9d51936c39348c64af6ba30dee50e5a10c8e19a53ec88217ac3f6b8ab237fcfcf25d08a202bfff256cf68cf5d0e6d9b03296c15a3be0598d349234128ce76ac6e207702bdbfe99b545a900880400130249fbbd67ea2135ebc15150eb1814da820d81a01185b7dce2c4f6bae3a20f0a9cefa03b0cb660934022c07070ac3',DSA_SHA1=>'304502200b25566c0237e7dca7ac792b10a314ee0360337c3a5a089ba0e2e84fcae3786802210088af5f3c1fb63a286d47985b19499f727bbea199af01d36684db1d003689e4de',DSA_SHA256=>'304402201e4355145e0efe9d86a9c2c2a104e2ccc3fbe7af3f6282f3b011e0f2a3f6a056022057e94dda0220995348167aa23f80d7a91138a7b076d47416b6994b8b63cf8bae',PRI_DER=>'308203560201000282010100f25d3273dcd60ae415dfcaffa157a2781adf86a6227fcd411be3d09becde1ea2ed6ad1e3de90f41f441af965f21c739af4aa0f89d881f13e995e075d1279124deb25adcbbd43a0281e2272807fd402f74a9e07a151c1b6f95ed80a5e5fab67afb6b0d2b799d1c12e3e154a4caf48322352eb218c085fa91309f4b94b4a448651adbb7cfc6511883881ae241143b456f28844fdbfd22294dec457c9d9915c823dc68d336211832786500b775900816cdc9abdd8e97bdc3838d2f88cb172511770cc59ee067d9c8cac1776c7818a4b6d432eefdeed2429d2662f6e7885d79bfa17df116648634f4a133e95c6250cf7c9e3cbd8f74d49ad804f5c0ca1377f9efa590221009cc0f23bd00116a00b0fa28ee420c58a34d4809fa661f0755b3ea2ed51e55b0d0282010100c8c793880b0c8fbdfc0ecc7320e7fee017c5796382d00575875d4a9df8c313310054e33b46f2f3ec20cb78bc2ac5de6c86416f7359cb10e5a20b9822db9e323e416a43669fdc6bcf6ad57aadeceffb101c7a4683c3b77ab5a7e13126f1332880a70536669d35783d0c2d58b27234aeee67940e96cc8b3cb228d4e2c1dd347b324d8ac5a80ec208db47cd121e260cac787c0f7500e220a2db1f0f940d5fac2a7756b050f45bf8726610f7ab61bfb9353d3c6cf00df77110f32d038bc58597275e3942e303befdbf37b440c4f5c419551d8943f852a3f641bc454b22e5ecf6687aefb258971aa4b414c14298bab8948859985c57ce1a52ed1d21e4bb1255773dce02820100661321784a1ea8dc4790d824e1f816f29245e01801336a3c171019815c7a948e4c39304b4f242a8353a4f7c1b51d1a1318145769f5cdf4ede0728f383b896d4ece262706e4612711427f96651c1440f1b7ef669a9811771c777e851cc6f81fb205ea8e8e1585a0dadca1b6f5e276590716616345d8a3fba6fb3a3b7c34ed16a3214fd9d51936c39348c64af6ba30dee50e5a10c8e19a53ec88217ac3f6b8ab237fcfcf25d08a202bfff256cf68cf5d0e6d9b03296c15a3be0598d349234128ce76ac6e207702bdbfe99b545a900880400130249fbbd67ea2135ebc15150eb1814da820d81a01185b7dce2c4f6bae3a20f0a9cefa03b0cb660934022c07070ac30220193475eb231fd607055354f80d9ff3e57ec231e8dbbff55f95482fd519b74fe0',PUB_DER=>'308203473082023a06072a8648ce3804013082022d0282010100f25d3273dcd60ae415dfcaffa157a2781adf86a6227fcd411be3d09becde1ea2ed6ad1e3de90f41f441af965f21c739af4aa0f89d881f13e995e075d1279124deb25adcbbd43a0281e2272807fd402f74a9e07a151c1b6f95ed80a5e5fab67afb6b0d2b799d1c12e3e154a4caf48322352eb218c085fa91309f4b94b4a448651adbb7cfc6511883881ae241143b456f28844fdbfd22294dec457c9d9915c823dc68d336211832786500b775900816cdc9abdd8e97bdc3838d2f88cb172511770cc59ee067d9c8cac1776c7818a4b6d432eefdeed2429d2662f6e7885d79bfa17df116648634f4a133e95c6250cf7c9e3cbd8f74d49ad804f5c0ca1377f9efa590221009cc0f23bd00116a00b0fa28ee420c58a34d4809fa661f0755b3ea2ed51e55b0d0282010100c8c793880b0c8fbdfc0ecc7320e7fee017c5796382d00575875d4a9df8c313310054e33b46f2f3ec20cb78bc2ac5de6c86416f7359cb10e5a20b9822db9e323e416a43669fdc6bcf6ad57aadeceffb101c7a4683c3b77ab5a7e13126f1332880a70536669d35783d0c2d58b27234aeee67940e96cc8b3cb228d4e2c1dd347b324d8ac5a80ec208db47cd121e260cac787c0f7500e220a2db1f0f940d5fac2a7756b050f45bf8726610f7ab61bfb9353d3c6cf00df77110f32d038bc58597275e3942e303befdbf37b440c4f5c419551d8943f852a3f641bc454b22e5ecf6687aefb258971aa4b414c14298bab8948859985c57ce1a52ed1d21e4bb1255773dce038201050002820100661321784a1ea8dc4790d824e1f816f29245e01801336a3c171019815c7a948e4c39304b4f242a8353a4f7c1b51d1a1318145769f5cdf4ede0728f383b896d4ece262706e4612711427f96651c1440f1b7ef669a9811771c777e851cc6f81fb205ea8e8e1585a0dadca1b6f5e276590716616345d8a3fba6fb3a3b7c34ed16a3214fd9d51936c39348c64af6ba30dee50e5a10c8e19a53ec88217ac3f6b8ab237fcfcf25d08a202bfff256cf68cf5d0e6d9b03296c15a3be0598d349234128ce76ac6e207702bdbfe99b545a900880400130249fbbd67ea2135ebc15150eb1814da820d81a01185b7dce2c4f6bae3a20f0a9cefa03b0cb660934022c07070ac3'},
23 {SIZE=>3072,PRI_FILE=>'key_3072-3.pri.pem',PUB_FILE=>'key_3072-3.pub.pem',PRI=>'00b7f3580347bd0036d803d6ec8b91390cde0486e1bc78e79585b91c3da0a1f654',PUB=>'2eec741d2835ff4dffa7b41c533105346c21bf6140bdbc25aec290166b1c87f1bec4c9a3b6c41f3ca5e1a170b1656485fdc98a00bc294fb8e2b95f03f1b0b104768d69de74146dd0921545babc51e7f85c35276602c319dea058b3973614866af220d5bc7aed3353ac79a506b7b5b7e3f8e957ebb2c5d1bd5bcda844df0ea275d80eb28c40f501cca3cf1d64173e244daca9e3fb53925dee37ac0eda6ae08141003f48c5580688a40d5b2b11e2fa81ad4888514a2eaf59cd23f3bb5bab4f595aec5a8639001788280272af77caa3eb16c4544708b2540d89f52cf544138bd3ac1e44c50ef9f99169a090a4ee36f61964189a03eecba84bfeec150cbd99d2b410fc2e465d9c0131d373510e48503a9a71f808f96515ab908dd942ca71f745ce7d3f50da9a202490939ca4037ff67ca3542914b0becea148979b1a78bac983863a39ac04f4ca73a24573c4d8bee1031008e7b4497304cf660d5ee300d767f7ade2945005a0fb75c9817e8351fa57cf7aab3db012702cfbe90fcd1aac50faab11df',DSA_SHA1=>'304502210093daa231cb0aaaa606e081f9dc0f877ab6e7b0bd96ef7b80885f871b72805cd402202d4f30e5f05d41138719abdb1897053c9588743f218b78044c63b4fd2f4080b3',DSA_SHA256=>'304402201cbaf998e6da4d73c94eda876a0683a72f7b808cef4b74191f40ec04810e8f16022061a8182ebddb911be3b6ac9e45576fecc3ea115285562907743ce0220e34bef9',PRI_DER=>'308204d6020100028201810080ac23af0ddcf39c3e8755c8fc9ae0ca0d698af17474bcac63e591f71397dd38ce912a9ef9f429ac3b5bf49c29e3723e45f47202c8ae050ec978ebece60436748e3cda32cfd3b072fd2719dc38dd8ffa200aa1b221a5f2478947056e20a0aba6f2475be6e71213bda62b284a0a07a20524c8edcd494933a89da43a576ed98476f46ff0f03838fedf4a902ea4abcc6f0c98749b6e7c678922b5a19042c011102b853c90fb490a268830cbbd9a74e24d0328d63f0c2851b768560b010cac03ea9b79abdbd1c0c80306d6a7eea7763b713e27e1ac45f483f7a14d64308a9fa09521609263cac314492f50487bf6c3a63f53b4a98bf8053c63cbb65dce373e70637aca6f63afabdd9dbb3106609052c4d8946cc3c2f08abf8171b18d5de415d001b69e63a07a69ef8a85fa69ac6acce63728c93a435c22e6342ab6f9438aee6dfd9f39c482751a1d1200d17903b05785eb15c35af02866275b0f42277a46c7a9205765ef756bdb9db084c2ceb2bb0380ed86dd15a121929b6cbba611908231d086ad022100b956a289913fd513bf3d085e8837f60e6490be78eff0d98d93f4d08c5e74001d0282018029004ac99e2e5aba6d99ba74da246fbbaae7ba1540cb5d35dfdcd93dcf5bb0742bd8db503ae91bb0b3d8c6847e40c86e85f7770c62691ae204e52d73d824c3510a56f0c221125cd9281522be35e4b52c5c8bc8b4eb72669841e5d4171bd92db8771c546975078070fc6c18b49823df98cb2d2584ae483a73161b1eb9768d1948e3ce2bf8da0eb922278ca17453eb67157c92a0e143cd8b817323229a98ad818418a1ad994ec0cb1a726d2118b494efb763c866f49337c22b34dd0fa4fbb73c9d4f88ab28541ce78a52255cd7c95fc3d7fc228d79a99e83d54ea4168275aa3a72fbd950891c3d42c048b9ba03c553b5d0aed83637569f59686aa57488e4746ad89c90fea0e377959075abafaefd7ccff5bd1212e547dbcd70026b9cb04012d8c97d62ba8dc1b9c3ef7eb6ff0b9e25efc3eb593ce2e604b7b662e12390f3044591d80812d309382367d21ab77ead78ce7d1606dbe22e5a3ec722bb2a6d67e5d0f0d44c00b1e80cee0583f61df7bdb9b9ebf8225a5041b633dfaf11198d7c983f60028201802eec741d2835ff4dffa7b41c533105346c21bf6140bdbc25aec290166b1c87f1bec4c9a3b6c41f3ca5e1a170b1656485fdc98a00bc294fb8e2b95f03f1b0b104768d69de74146dd0921545babc51e7f85c35276602c319dea058b3973614866af220d5bc7aed3353ac79a506b7b5b7e3f8e957ebb2c5d1bd5bcda844df0ea275d80eb28c40f501cca3cf1d64173e244daca9e3fb53925dee37ac0eda6ae08141003f48c5580688a40d5b2b11e2fa81ad4888514a2eaf59cd23f3bb5bab4f595aec5a8639001788280272af77caa3eb16c4544708b2540d89f52cf544138bd3ac1e44c50ef9f99169a090a4ee36f61964189a03eecba84bfeec150cbd99d2b410fc2e465d9c0131d373510e48503a9a71f808f96515ab908dd942ca71f745ce7d3f50da9a202490939ca4037ff67ca3542914b0becea148979b1a78bac983863a39ac04f4ca73a24573c4d8bee1031008e7b4497304cf660d5ee300d767f7ade2945005a0fb75c9817e8351fa57cf7aab3db012702cfbe90fcd1aac50faab11df022100b7f3580347bd0036d803d6ec8b91390cde0486e1bc78e79585b91c3da0a1f654',PUB_DER=>'308204c63082033906072a8648ce3804013082032c028201810080ac23af0ddcf39c3e8755c8fc9ae0ca0d698af17474bcac63e591f71397dd38ce912a9ef9f429ac3b5bf49c29e3723e45f47202c8ae050ec978ebece60436748e3cda32cfd3b072fd2719dc38dd8ffa200aa1b221a5f2478947056e20a0aba6f2475be6e71213bda62b284a0a07a20524c8edcd494933a89da43a576ed98476f46ff0f03838fedf4a902ea4abcc6f0c98749b6e7c678922b5a19042c011102b853c90fb490a268830cbbd9a74e24d0328d63f0c2851b768560b010cac03ea9b79abdbd1c0c80306d6a7eea7763b713e27e1ac45f483f7a14d64308a9fa09521609263cac314492f50487bf6c3a63f53b4a98bf8053c63cbb65dce373e70637aca6f63afabdd9dbb3106609052c4d8946cc3c2f08abf8171b18d5de415d001b69e63a07a69ef8a85fa69ac6acce63728c93a435c22e6342ab6f9438aee6dfd9f39c482751a1d1200d17903b05785eb15c35af02866275b0f42277a46c7a9205765ef756bdb9db084c2ceb2bb0380ed86dd15a121929b6cbba611908231d086ad022100b956a289913fd513bf3d085e8837f60e6490be78eff0d98d93f4d08c5e74001d0282018029004ac99e2e5aba6d99ba74da246fbbaae7ba1540cb5d35dfdcd93dcf5bb0742bd8db503ae91bb0b3d8c6847e40c86e85f7770c62691ae204e52d73d824c3510a56f0c221125cd9281522be35e4b52c5c8bc8b4eb72669841e5d4171bd92db8771c546975078070fc6c18b49823df98cb2d2584ae483a73161b1eb9768d1948e3ce2bf8da0eb922278ca17453eb67157c92a0e143cd8b817323229a98ad818418a1ad994ec0cb1a726d2118b494efb763c866f49337c22b34dd0fa4fbb73c9d4f88ab28541ce78a52255cd7c95fc3d7fc228d79a99e83d54ea4168275aa3a72fbd950891c3d42c048b9ba03c553b5d0aed83637569f59686aa57488e4746ad89c90fea0e377959075abafaefd7ccff5bd1212e547dbcd70026b9cb04012d8c97d62ba8dc1b9c3ef7eb6ff0b9e25efc3eb593ce2e604b7b662e12390f3044591d80812d309382367d21ab77ead78ce7d1606dbe22e5a3ec722bb2a6d67e5d0f0d44c00b1e80cee0583f61df7bdb9b9ebf8225a5041b633dfaf11198d7c983f600382018500028201802eec741d2835ff4dffa7b41c533105346c21bf6140bdbc25aec290166b1c87f1bec4c9a3b6c41f3ca5e1a170b1656485fdc98a00bc294fb8e2b95f03f1b0b104768d69de74146dd0921545babc51e7f85c35276602c319dea058b3973614866af220d5bc7aed3353ac79a506b7b5b7e3f8e957ebb2c5d1bd5bcda844df0ea275d80eb28c40f501cca3cf1d64173e244daca9e3fb53925dee37ac0eda6ae08141003f48c5580688a40d5b2b11e2fa81ad4888514a2eaf59cd23f3bb5bab4f595aec5a8639001788280272af77caa3eb16c4544708b2540d89f52cf544138bd3ac1e44c50ef9f99169a090a4ee36f61964189a03eecba84bfeec150cbd99d2b410fc2e465d9c0131d373510e48503a9a71f808f96515ab908dd942ca71f745ce7d3f50da9a202490939ca4037ff67ca3542914b0becea148979b1a78bac983863a39ac04f4ca73a24573c4d8bee1031008e7b4497304cf660d5ee300d767f7ade2945005a0fb75c9817e8351fa57cf7aab3db012702cfbe90fcd1aac50faab11df'},
24 {SIZE=>4096,PRI_FILE=>'key_4096-3.pri.pem',PUB_FILE=>'key_4096-3.pub.pem',PRI=>'14ab4fb361bd3ea6bbf83488224966d224f6fe247fd1f7ae6ef40f098c3f4e15',PUB=>'59ee50c1c33bffc11b087f29ef0e2295ad0ce5534ba81d4edd93c6069f213695a594b6df516fd3cf29312cb11e01ada478df2371b980f6468e745925ffc623395445410b7d83ac4549e378edc757b7ab59c2ac38369b4180f207cd5f3674a968fc02e1ac243bab7af78356580474616342521ca2c1c81615418045f0239cf55f52b4c193514abd1fba7e02bd7d7db219206bc565c11f615efe768c28fff6930a961f88fa4984e775644522ea42b3fd698c79b7e6b06bb0d5f53a9ead504e80d299684485e926d37d8d111913e78e532e3816706b466a6888dfd136ce041c5d8f60b52f4bd0df145850c50640562a013a23f52d1fc4b35a0dffc55b628f7a651f621a11e4fc5176bb901791def06f003884bd3e2826b3532b72be884f52cce7a85f3b6c01093dfd8421a9a986310051e1d4a940ade05a0c40d794940921208ebe0a243fefcbcc6356cd28617218c403e0c972f8c3cc3ac0e41693a58651a01d0ac03e126cddd362aa2e73039c8d53f78b1e06e5abf67b91a5b2f1c4d2d2c593c1a397e4a5d4b486e53cd17354c1ad3a712030e23cebd6614c3e3c38c4ae31759fd8ea276ac95f19f0f644f7fde56c7c221a9911f1189e996476e5cd3d3d000d7c50e5289286e08a1afccd6e3dfea5e30ad76ef2482d16ac9321b8524e839c2522c217003dc247ff69a6eec5d8a0e87fe498b449beedc5cd44aff00e97f5a185a9',DSA_SHA1=>'304402201a99853cdf35cef247bc4d029dde5172c18f65e7ea9b69904319017d6e9bf0b5022069e8e1bba98f9ea859016ba4cbea0115ef452f9bce4f47d7216ef542bea71b3a',DSA_SHA256=>'30440220560704814ace4a241dcff64c95f89c71ad3cb2b23d5f15ce4bac5d5826afdb0802204f7deb328ba25f3b1d76f957bde23c28c08a68fe84070c4c05ea58996f42e399',PRI_DER=>'30820655020100028202010099043ca2b994c89a2999c839a41c2a79d12b626a0c8cbf73c6c65af93b28ac9ec69bab58d65bfb02f2da42f6743f63ee68e224517c04c4d0fb4286f981e84612ea19ddcd4217d0996c78c346c67e0930a882bd135761bf43f6e9fd9cb27c341cbbec64aa7b2d3193089f2e2975656555b0b274fb3348262bb52cd3e97cc0840b9f4caab0b0bd6a47b9f1ac73cb7e5a3c0c773f463605a16ef2dff07e429060d7fb9dda0839890a2d5dac70ac5d8a2ba4084e635541b9dd774db993d638ed70e405437d9bfb8a4d763dbc6d19364103bc2f2dad3e491091fb47998c754e2b098c7dfe00bab9c1d7e207744364fd2c91fc9694082598a688623f5fb4cfbccf0e9f97f700304bb6e955f5ac8a09c85b82b28a50b95ccf90728e8e13aaa82b3d08905f244bd9df07d2f0f98ff52dcd033587377b722975020fc33d725990cf40f35df744aa89efed8d94d9edc5deb807d0cbdd2652ccd2e358c0c4e5dac7235cd5d630b7a4cbb61cc8620985cd7ee67c4e3a7b8439cccb9f8bb06cee107f241219227b0f679f9dd6844e21ff7c1b52bbe3420838ccbb7d6a2bc3a73325d775ec5b4b277b9ea08f665502a90126152f8a9da01f2019dae3238d05d62615825eb8bb5a6476e12d8b5fabefa5b0f95ff57267f814fcdaf2d12fff188fc016d6e0aa0a6259c3e6532db32ace8a18e14451cadd9495099b3157afb249f6a593f5de1fcb910221008492598d9db34282ddd651a5a141ad2f2f3b928306c7b18f2245e3bb47baceb7028202000d820b8709730584eae360da462883ee99b7ca79aa9a8d13bd99ff040205a47d2db840748bb845fe20d538baa75b63ff35a57fe91c7eab39f3136a7e095404dacebe3606398df71a2e4a7ce9cc76db2a345e908048dfd58b91d296678e865862fadc8d0055d84bc2eddc422119fa6796c74408e76bb228adf4d18829771e0bb185480d64366aec6520a3c1398963e436e6176e8ea2ba75ed81251d39bbdff79b421f4b1976db9bbc71fdfb9bec22433c922c27f921b13c017b946549830318462cd80fc2c3383108d77a2add324b1cc180d57e99ea265d99aac0a00cafdccbbf9c1e259d45e410e04e14d4d434f526d03edec2ebc93a5d25a8bdf68771e94e8d3ac53dd9687c7c68edb90477cd8c06b7a159ac117518a24a28cc21da768761c0542f2898eb2cbe17e550a390f84d78dbd032acd9841e9ac4bbe9c1a64b9f7ca51ebb2ba855b6935c0dc109c064270de846e739ac63595db70914d3d747b43a51cf17056021721ef41e9fa813247ae0eb37e9227eb338fd1a194ba1392ef794de6aebb4e73bae2d7d6e10fffc7c24a19f3851b7962c40f86e36635816acaee929edb919444f5c7be739201a88cc0500885ed1736e5c723dbb97bc2e8ae66414498d416e809aa006fd2c91f3dbc0d103c79f34165fa4984ce18902d205a70ba9b46f65dde7b73bdb55830c9f1349f89a1ee47429593f4546b04483b1e0381d5daf0282020059ee50c1c33bffc11b087f29ef0e2295ad0ce5534ba81d4edd93c6069f213695a594b6df516fd3cf29312cb11e01ada478df2371b980f6468e745925ffc623395445410b7d83ac4549e378edc757b7ab59c2ac38369b4180f207cd5f3674a968fc02e1ac243bab7af78356580474616342521ca2c1c81615418045f0239cf55f52b4c193514abd1fba7e02bd7d7db219206bc565c11f615efe768c28fff6930a961f88fa4984e775644522ea42b3fd698c79b7e6b06bb0d5f53a9ead504e80d299684485e926d37d8d111913e78e532e3816706b466a6888dfd136ce041c5d8f60b52f4bd0df145850c50640562a013a23f52d1fc4b35a0dffc55b628f7a651f621a11e4fc5176bb901791def06f003884bd3e2826b3532b72be884f52cce7a85f3b6c01093dfd8421a9a986310051e1d4a940ade05a0c40d794940921208ebe0a243fefcbcc6356cd28617218c403e0c972f8c3cc3ac0e41693a58651a01d0ac03e126cddd362aa2e73039c8d53f78b1e06e5abf67b91a5b2f1c4d2d2c593c1a397e4a5d4b486e53cd17354c1ad3a712030e23cebd6614c3e3c38c4ae31759fd8ea276ac95f19f0f644f7fde56c7c221a9911f1189e996476e5cd3d3d000d7c50e5289286e08a1afccd6e3dfea5e30ad76ef2482d16ac9321b8524e839c2522c217003dc247ff69a6eec5d8a0e87fe498b449beedc5cd44aff00e97f5a185a9022014ab4fb361bd3ea6bbf83488224966d224f6fe247fd1f7ae6ef40f098c3f4e15',PUB_DER=>'308206463082043906072a8648ce3804013082042c028202010099043ca2b994c89a2999c839a41c2a79d12b626a0c8cbf73c6c65af93b28ac9ec69bab58d65bfb02f2da42f6743f63ee68e224517c04c4d0fb4286f981e84612ea19ddcd4217d0996c78c346c67e0930a882bd135761bf43f6e9fd9cb27c341cbbec64aa7b2d3193089f2e2975656555b0b274fb3348262bb52cd3e97cc0840b9f4caab0b0bd6a47b9f1ac73cb7e5a3c0c773f463605a16ef2dff07e429060d7fb9dda0839890a2d5dac70ac5d8a2ba4084e635541b9dd774db993d638ed70e405437d9bfb8a4d763dbc6d19364103bc2f2dad3e491091fb47998c754e2b098c7dfe00bab9c1d7e207744364fd2c91fc9694082598a688623f5fb4cfbccf0e9f97f700304bb6e955f5ac8a09c85b82b28a50b95ccf90728e8e13aaa82b3d08905f244bd9df07d2f0f98ff52dcd033587377b722975020fc33d725990cf40f35df744aa89efed8d94d9edc5deb807d0cbdd2652ccd2e358c0c4e5dac7235cd5d630b7a4cbb61cc8620985cd7ee67c4e3a7b8439cccb9f8bb06cee107f241219227b0f679f9dd6844e21ff7c1b52bbe3420838ccbb7d6a2bc3a73325d775ec5b4b277b9ea08f665502a90126152f8a9da01f2019dae3238d05d62615825eb8bb5a6476e12d8b5fabefa5b0f95ff57267f814fcdaf2d12fff188fc016d6e0aa0a6259c3e6532db32ace8a18e14451cadd9495099b3157afb249f6a593f5de1fcb910221008492598d9db34282ddd651a5a141ad2f2f3b928306c7b18f2245e3bb47baceb7028202000d820b8709730584eae360da462883ee99b7ca79aa9a8d13bd99ff040205a47d2db840748bb845fe20d538baa75b63ff35a57fe91c7eab39f3136a7e095404dacebe3606398df71a2e4a7ce9cc76db2a345e908048dfd58b91d296678e865862fadc8d0055d84bc2eddc422119fa6796c74408e76bb228adf4d18829771e0bb185480d64366aec6520a3c1398963e436e6176e8ea2ba75ed81251d39bbdff79b421f4b1976db9bbc71fdfb9bec22433c922c27f921b13c017b946549830318462cd80fc2c3383108d77a2add324b1cc180d57e99ea265d99aac0a00cafdccbbf9c1e259d45e410e04e14d4d434f526d03edec2ebc93a5d25a8bdf68771e94e8d3ac53dd9687c7c68edb90477cd8c06b7a159ac117518a24a28cc21da768761c0542f2898eb2cbe17e550a390f84d78dbd032acd9841e9ac4bbe9c1a64b9f7ca51ebb2ba855b6935c0dc109c064270de846e739ac63595db70914d3d747b43a51cf17056021721ef41e9fa813247ae0eb37e9227eb338fd1a194ba1392ef794de6aebb4e73bae2d7d6e10fffc7c24a19f3851b7962c40f86e36635816acaee929edb919444f5c7be739201a88cc0500885ed1736e5c723dbb97bc2e8ae66414498d416e809aa006fd2c91f3dbc0d103c79f34165fa4984ce18902d205a70ba9b46f65dde7b73bdb55830c9f1349f89a1ee47429593f4546b04483b1e0381d5daf03820205000282020059ee50c1c33bffc11b087f29ef0e2295ad0ce5534ba81d4edd93c6069f213695a594b6df516fd3cf29312cb11e01ada478df2371b980f6468e745925ffc623395445410b7d83ac4549e378edc757b7ab59c2ac38369b4180f207cd5f3674a968fc02e1ac243bab7af78356580474616342521ca2c1c81615418045f0239cf55f52b4c193514abd1fba7e02bd7d7db219206bc565c11f615efe768c28fff6930a961f88fa4984e775644522ea42b3fd698c79b7e6b06bb0d5f53a9ead504e80d299684485e926d37d8d111913e78e532e3816706b466a6888dfd136ce041c5d8f60b52f4bd0df145850c50640562a013a23f52d1fc4b35a0dffc55b628f7a651f621a11e4fc5176bb901791def06f003884bd3e2826b3532b72be884f52cce7a85f3b6c01093dfd8421a9a986310051e1d4a940ade05a0c40d794940921208ebe0a243fefcbcc6356cd28617218c403e0c972f8c3cc3ac0e41693a58651a01d0ac03e126cddd362aa2e73039c8d53f78b1e06e5abf67b91a5b2f1c4d2d2c593c1a397e4a5d4b486e53cd17354c1ad3a712030e23cebd6614c3e3c38c4ae31759fd8ea276ac95f19f0f644f7fde56c7c221a9911f1189e996476e5cd3d3d000d7c50e5289286e08a1afccd6e3dfea5e30ad76ef2482d16ac9321b8524e839c2522c217003dc247ff69a6eec5d8a0e87fe498b449beedc5cd44aff00e97f5a185a9'},
25 ];
26
27 #diag("samples_count=". @$data);
28
29 for my $h (@$data) {
30 my $dsa_pri = Crypt::PK::DSA->new->import_key(\pack("H*",$h->{PRI_DER}));
31 my $dsa_pub = Crypt::PK::DSA->new->import_key(\pack("H*",$h->{PUB_DER}));
32 my $dsa_pri_h = $dsa_pri->key2hash;
33 my $dsa_pub_h = $dsa_pub->key2hash;
34 $h->{PRI} =~ s/^0+//;
35 $h->{PUB} =~ s/^0+//;
36 is($dsa_pri_h->{x}, uc $h->{PRI}, "$h->{PRI_FILE}/PRI");
37 is($dsa_pri_h->{y}, uc $h->{PUB}, "$h->{PRI_FILE}/PUB");
38 is($dsa_pub_h->{y}, uc $h->{PUB}, "$h->{PUB_FILE}/PUB");
39 ok( $dsa_pub->verify_message(pack("H*", $h->{DSA_SHA1}), 'test-data', 'SHA1'), "$h->{PRI_FILE}/DSA_SHA1");
40 ok( $dsa_pub->verify_message(pack("H*", $h->{DSA_SHA256}), 'test-data', 'SHA256'), "$h->{PRI_FILE}/DSA_SHA256");
41 }
42
43 done_testing();
1010 ok($k, 'load cryptx_priv_ecc1.der');
1111 ok($k->is_private, 'is_private cryptx_priv_ecc1.der');
1212 is($k->size, 32, 'size');
13 is(uc($k->key2hash->{pub_x}), 'AB53ED5D16CE550BAAF16BA4F161332AAD56D63790629C27871ED515D4FC229C', 'key2hash');
13 is(uc($k->key2hash->{pub_x}), 'C068B754877A4AB328A569BAC6D464A81B17E527D2D652572ABB11BDA3572D50', 'key2hash');
1414
1515 $k = Crypt::PK::ECC->new('t/data/cryptx_priv_ecc2.der');
1616 ok($k, 'load cryptx_priv_ecc2.der');
2424 ok($k, 'load cryptx_pub_ecc2.der');
2525 ok(!$k->is_private, 'is_private cryptx_pub_ecc2.der');
2626
27 # $k = Crypt::PK::ECC->new('t/data/cryptx_priv_ecc1.pem');
28 # ok($k, 'load cryptx_priv_ecc1.pem');
29 # ok($k->is_private, 'is_private cryptx_priv_ecc1.pem');
27 ### XXX-TODO regenerate keys
28 $k = Crypt::PK::ECC->new('t/data/cryptx_priv_ecc1.pem');
29 ok($k, 'load cryptx_priv_ecc1.pem');
30 ok($k->is_private, 'is_private cryptx_priv_ecc1.pem');
3031
31 # $k = Crypt::PK::ECC->new('t/data/cryptx_priv_ecc2.pem');
32 # ok($k, 'load cryptx_priv_ecc2.pem');
33 # ok($k->is_private, 'is_private cryptx_priv_ecc2.pem');
32 $k = Crypt::PK::ECC->new('t/data/cryptx_priv_ecc2.pem');
33 ok($k, 'load cryptx_priv_ecc2.pem');
34 ok($k->is_private, 'is_private cryptx_priv_ecc2.pem');
3435
35 # $k = Crypt::PK::ECC->new('t/data/cryptx_pub_ecc1.pem');
36 # ok($k, 'load cryptx_pub_ecc1.pem');
37 # ok(!$k->is_private, 'is_private cryptx_pub_ecc1.pem');
36 $k = Crypt::PK::ECC->new('t/data/cryptx_pub_ecc1.pem');
37 ok($k, 'load cryptx_pub_ecc1.pem');
38 ok(!$k->is_private, 'is_private cryptx_pub_ecc1.pem');
3839
39 # $k = Crypt::PK::ECC->new('t/data/cryptx_pub_ecc2.pem');
40 # ok($k, 'load cryptx_pub_ecc2.pem');
41 # ok(!$k->is_private, 'is_private cryptx_pub_ecc2.pem');
40 $k = Crypt::PK::ECC->new('t/data/cryptx_pub_ecc2.pem');
41 ok($k, 'load cryptx_pub_ecc2.pem');
42 ok(!$k->is_private, 'is_private cryptx_pub_ecc2.pem');
43 $k = Crypt::PK::ECC->new('t/data/cryptx_pub_ecc2.pem');
44
45 for (qw( openssl_ec1.pub.pem openssl_ec1.pub.der openssl_ec1.pubc.der openssl_ec1.pubc.pem
46 cryptx_pub_ecc1_OLD.der cryptx_pub_ecc1_OLD.pem cryptx_pub_ecc2_OLD.der cryptx_pub_ecc2_OLD.pem )) {
47 $k = Crypt::PK::ECC->new("t/data/$_");
48 ok($k, "load $_");
49 ok(!$k->is_private, "is_private $_");
50 }
51 for (qw( openssl_ec1.pri.der openssl_ec1.pri.pem openssl_ec1.pric.der openssl_ec1.pric.pem openssl_ec1.key.pem
52 cryptx_priv_ecc1_OLD.der cryptx_priv_ecc1_OLD.pem cryptx_priv_ecc2_OLD.der cryptx_priv_ecc2_OLD.pem )) {
53 $k = Crypt::PK::ECC->new("t/data/$_");
54 ok($k, "load $_");
55 ok($k->is_private, "is_private $_");
56 }
4257 }
4358
4459 {
4964
5065 my $ct = $pu1->encrypt("secret message");
5166 my $pt = $pr1->decrypt($ct);
52 ok(length $ct > 100, 'encrypt ' . length($ct));
67 ok(length $ct > 30, 'encrypt ' . length($ct));
5368 is($pt, "secret message", 'decrypt');
5469
5570 my $sig = $pr1->sign_message("message");
7388
7489 {
7590 my $k = Crypt::PK::ECC->new;
76 $k->generate_key(32);
91 $k->generate_key('secp224r1');
7792 ok($k, 'generate_key');
7893 ok($k->is_private, 'is_private');
7994 #ok($k->export_key_pem('private'), 'export_key_pem pri');
0 use strict;
1 use warnings;
2
3 use Test::More;
4 use Crypt::PK::ECC;
5
6 my $data = [
7 {CURVE=>'secp112r1',PRI_FILE=>'key_secp112r1-1.pri.pem',PUB_FILE=>'key_secp112r1-1.pub.pem',PRI=>'9c8c2a0cd14052e0a802e965ea77',PUB=>'0411f09ba3f913b142b38585d19fc48c928f2b6026bc15b98157f2fb9d',PUBC=>'0311f09ba3f913b142b38585d19fc4',ECDSA_SHA1=>'3020020e194733eb7aea5031db4cf273e84e020e12bef575d5a9a78391f421d7c607',ECDSA_SHA256=>'3021020f00a81637ea3744d65335e2870aefd6020e514a4b4c7d7b25b257276ab476f9'},
8 {CURVE=>'secp112r2',PRI_FILE=>'key_secp112r2-1.pri.pem',PUB_FILE=>'key_secp112r2-1.pub.pem',PRI=>'2dad629912f1ef7acd7ff55a6072',PUB=>'047d8cb70beab422d22880c79fe117d0392c404dc974831c5f26c506a3',PUBC=>'037d8cb70beab422d22880c79fe117',ECDSA_SHA1=>'3020020e115b7759e0bc13dbbb77db756850020e09d74cc8e9d70f7def749bc59759',ECDSA_SHA256=>'3020020e10eb5ca8badd470e4794c1a108db020e02de4d6532d666f6f08b64e89b30'},
9 {CURVE=>'secp128r1',PRI_FILE=>'key_secp128r1-1.pri.pem',PUB_FILE=>'key_secp128r1-1.pub.pem',PRI=>'5c5e30ef79639baa2ddd0e41637384ae',PUB=>'04dedf05d521119c98a0b91f081401ac7c3e359793e5ff70f2ee31324d263e9f61',PUBC=>'03dedf05d521119c98a0b91f081401ac7c',ECDSA_SHA1=>'3026021100d366e9dac9a3bc43576b38962c9afba9021100acffead8c8440c5b4c288a2869919b2f',ECDSA_SHA256=>'30250210674badb9584429bacf8ad1ff6819f4c1021100c2621e5cb97206474177d50b3d1c0145'},
10 {CURVE=>'secp128r2',PRI_FILE=>'key_secp128r2-1.pri.pem',PUB_FILE=>'key_secp128r2-1.pub.pem',PRI=>'31739a3d53459d7df41e3134d8c3cf1b',PUB=>'042b294c16752327dd9be5311d70561fd1f0c75e6b6cb69fcc152670777eec89ab',PUBC=>'032b294c16752327dd9be5311d70561fd1',ECDSA_SHA1=>'302402102697263886c57d8de361afec554f29e7021011d091dab40603a4e7d8dffbcdc1ed0f',ECDSA_SHA256=>'302402101e3dd1147131625b9ad5bbf114d1bc0d02103d82b9a394054844e9d353565c50ff99'},
11 {CURVE=>'secp160k1',PRI_FILE=>'key_secp160k1-1.pri.pem',PUB_FILE=>'key_secp160k1-1.pub.pem',PRI=>'14b70aec3aa250e66c5eedbf4363a27b4b27231f',PUB=>'048d448a89c0290d646b4e0a4592c0eafe51bfae0174462140df8839784b02683088f3eae3dbd77ccb',PUBC=>'038d448a89c0290d646b4e0a4592c0eafe51bfae01',ECDSA_SHA1=>'302e021500ed2e2adac4a5145a6408211c1d47d98ffd6c5b89021500a6ebc3897cf5163bd3f842b50d7facb307fc0f3d',ECDSA_SHA256=>'302d021500bd3ed4ceca917b49ac2faec87a91378a81e6172c02146017099013c0adb4bceb08b8e6cbcfdbb494b6b6'},
12 {CURVE=>'secp160r1',PRI_FILE=>'key_secp160r1-1.pri.pem',PUB_FILE=>'key_secp160r1-1.pub.pem',PRI=>'4f3ff1d85f36dda2930ce4fd6e50fbe66830042d',PUB=>'04a497c25340df2b80aef1e26ed45ea179dd5f6f52d017a07f00b5a40ac2c76bb2aaec555d4bc08a1f',PUBC=>'03a497c25340df2b80aef1e26ed45ea179dd5f6f52',ECDSA_SHA1=>'302c021453e1ba4695646e93ac5db45933d59c4a2b64d3f902142a383226907d5952af829765645d5ae34a15ab5f',ECDSA_SHA256=>'302d021500a559a68611e26d4acfe0eaa59e9e4956ad080b9902147730150c0a79f7500f23953bdc84577111d9f4bf'},
13 {CURVE=>'secp160r2',PRI_FILE=>'key_secp160r2-1.pri.pem',PUB_FILE=>'key_secp160r2-1.pub.pem',PRI=>'999e25723cd7baf003b110e1d3e719396b0486e3',PUB=>'04fed95dd2b94579147d09c7cf1fff0a2156fad1b48e6dd96ca660ef55097589f4d75dbcae1553c9a1',PUBC=>'03fed95dd2b94579147d09c7cf1fff0a2156fad1b4',ECDSA_SHA1=>'302d021500f58ff53a28bd1e41bed2b214aeb2672852276f4c02141d088051ad977dcaa44a68994ff35ac447cc4848',ECDSA_SHA256=>'302c021478385546c27950308485c44a5ed2b3cabfd4d65602144fe588beecb3f1a42a3eefa1d74b9382fa066f96'},
14 {CURVE=>'secp192k1',PRI_FILE=>'key_secp192k1-1.pri.pem',PUB_FILE=>'key_secp192k1-1.pub.pem',PRI=>'a98043d5c9cff228846613d2557d83747249666420f66a28',PUB=>'04581e261bb2fce5f6c5306cf5b5952a548c72e591baf73d8621569c4311490499db5b6e2969bd5965aad628f99c996183',PUBC=>'03581e261bb2fce5f6c5306cf5b5952a548c72e591baf73d86',ECDSA_SHA1=>'3035021900d36a2d3a3702f954b4364aad125bf710f5f772cc2d06da200218389da6af997dfedb713858e4d415aedfc0235d59453a3a5e',ECDSA_SHA256=>'3036021900f3a48ae6f34dc434e7605ddd2edc3363116a076bafbbefc0021900f08e144406402eed1297d309e40caa7107f8ec2e0e7e8b75'},
15 {CURVE=>'secp224k1',PRI_FILE=>'key_secp224k1-1.pri.pem',PUB_FILE=>'key_secp224k1-1.pub.pem',PRI=>'230e41b86eec5b958d5f2959bc4b392aa27fa3f7e3fdf9915db47da7',PUB=>'046adc2b376d687aabb7b05bb00bbe03822f32711512e054510ee89be429eb839d41fa5ad6a6f70f274850d477e1049e08c9e6098d2d1208a7',PUBC=>'036adc2b376d687aabb7b05bb00bbe03822f32711512e054510ee89be4',ECDSA_SHA1=>'303d021c1f58bfc8684e3f333433cd0fa3c66892c06727ddd8b1a4913f2b152d021d00d518957f96b59789f8ecf3e3b963d2aa3466152571775e93462c10ea',ECDSA_SHA256=>'303c021c74a28d855453e3a8c93cf520e367e12659d254d64c2248fb3060d02a021c03340c2b4d88018ad203f01f6f6ff072d22a653d7379b139ca5b86c3'},
16 {CURVE=>'secp224r1',PRI_FILE=>'key_secp224r1-1.pri.pem',PUB_FILE=>'key_secp224r1-1.pub.pem',PRI=>'fe892ab148f432be15645766bc969487197bc84dd92e4e2ef00c1a86',PUB=>'0467ebe5a5aef2c7cf7752970ccca9c6bb29f5420dff40d003dbf3e5d57f910b1174d0b9507107c55c4e9b386b0358a07b24c49ee219b3a52f',PUBC=>'0367ebe5a5aef2c7cf7752970ccca9c6bb29f5420dff40d003dbf3e5d5',ECDSA_SHA1=>'303e021d00bb0d2991ed5c73c0b61685a6e81b578c31a3d72bb4ede6d8d0534d74021d00f24f418c3105ee6299dd6de2f3f866c9e71213c5a144c40440fdb3c9',ECDSA_SHA256=>'303e021d008467a633a2682253bd99285e40040cf7b0c7f528f1418aeade8318fe021d00dbd009aba53c06fc09293caf1a4ac0dc6dc38dc2c126c2ef306f67e7'},
17 {CURVE=>'secp256k1',PRI_FILE=>'key_secp256k1-1.pri.pem',PUB_FILE=>'key_secp256k1-1.pub.pem',PRI=>'4b03aa0b55fb2911a54a708d900a95ada33fd76306f03268fa388b63d0aefb43',PUB=>'0422af1a552f83cccce76d197c55d3c7d8ad8cb68dc3042c227984211b0a78aa7f153768dc1fd47239ba4fccb73e3c2d1285560eb809a2a84a12371c2915d59af9',PUBC=>'0322af1a552f83cccce76d197c55d3c7d8ad8cb68dc3042c227984211b0a78aa7f',ECDSA_SHA1=>'3045022100de6548db95f7c10e6dfd3241dbef8f0b5fb350932c0a2f209f4aab95aaddf08e022006caa0150bd1c1355574e3164c2a1287e8e77d7bd1b272f4d286f40f281004e3',ECDSA_SHA256=>'3044022060595de7d992adb52f68e1b6a5aa4fed88d8e31f73a4aafce3345997b7d72f560220408e8d7f9d5f7111cab83853a5f5e3667bd20c0a707d53f02c5b36052b750549'},
18 {CURVE=>'secp384r1',PRI_FILE=>'key_secp384r1-1.pri.pem',PUB_FILE=>'key_secp384r1-1.pub.pem',PRI=>'2705f8a76c216172157b6187a466852a8127e7670188448444452ae2e3404155fcfdcdfbd014753ae9e5156b1b57db69',PUB=>'04cd738a8ebc08734a0fcfaf68b9123075a05d0c4b2a387da1c8ca378402abac23a87fd5c4fdffab91127bc61fbc8d69f57ca9e3aafed7698ce75b9116235e749d7b6f29c91d2123112289426dbe174f42022924ed9752e94d5037ceddd007473c',PUBC=>'02cd738a8ebc08734a0fcfaf68b9123075a05d0c4b2a387da1c8ca378402abac23a87fd5c4fdffab91127bc61fbc8d69f5',ECDSA_SHA1=>'306602310092acb263c179af269bdea79361a1a6b71ac53a5496fb3a04955493882725b5210c9c2f59ba315f53e61c254986b1f844023100d9872b751d26660ae5dc43161b6f6527b254cf1fc2e59a07ed76b39d7698f06d40abcec14848dab97362cbf475184268',ECDSA_SHA256=>'30650231009eb92d03cf786e936c0dbe0d710d2b55e92415b4133ee9272acb1af4529b53bfa573f5c6683b9a89072c34c2a7fc98650230062d798914ee0fba4bebe73f6efdf694299aafac7680744187f3f9bfcbcfd56790b9cbcf7b0fb8a9968bebf2ac6970a7'},
19 {CURVE=>'secp521r1',PRI_FILE=>'key_secp521r1-1.pri.pem',PUB_FILE=>'key_secp521r1-1.pub.pem',PRI=>'013cc69064c1be4f387df1cbb9481e6182ef91c2db8b099ade5ac1241e634d8bd419f5766131b00bbc0c8b136cdbc01658cdbfefbf08ddb78030fdfe3b877c61ca0f',PUB=>'04006d71a3ba5519119aa9352a156ce8a55fe5f9c2a8380697132619802581e597cf7c05a363d0a0fdee4e4a2296350090cef05f6ee6fb3ad1d8d300108ddcd7d13410014599a7509db9ca78804c8ee96a36101020649ae13b3890f35a72a05229c4247fbfea322cdb939617aee52fe491f911ac11dca100e105d6b7b9043384b33100077b',PUBC=>'03006d71a3ba5519119aa9352a156ce8a55fe5f9c2a8380697132619802581e597cf7c05a363d0a0fdee4e4a2296350090cef05f6ee6fb3ad1d8d300108ddcd7d13410',ECDSA_SHA1=>'308187024133ac3eb5173908318f71aab17f39f3a9a608e9b8117b7896f76a875e671fbfc386f2de6b288f4314b41f1d97a1fcd43e380226d0908af28dfd7b0cad33ba689d20024201aa82692b8ab235faf3f0a801d25dd226d1e4ca06913415d9194ac457e5a6ed114725caa490fdba9d8b9e05513978dc29f5c6b59fe26e3019e9b3fe09d66b7d7517',ECDSA_SHA256=>'308188024201216ee0ed86caad32a443c592e64bd573f71f42d89cd41bdab291554331af9cf62f3619913fa1e3954d565f2bfbe8020f4ede97ea67f3915bf9984013cfbb83a159024200a59d3ffa95564849ec9b1382aef9165f9dbc473bc6ef41cdaaa5c2beda03e863ec298e84c16a25fc034d3975e0b91c2f882478ab0d4892ee70d4390d923852ddee'},
20 {CURVE=>'prime192v1',PRI_FILE=>'key_prime192v1-1.pri.pem',PUB_FILE=>'key_prime192v1-1.pub.pem',PRI=>'bcadb48540afbf1f994030949e8bf180e58f4f82f23e337f',PUB=>'04dc06d31d9ccc7e0d453727f870c2ef8ff751c04a1c225d729d16255ae82522536cdd979cec71c7af8ddbdbe8073bd18f',PUBC=>'03dc06d31d9ccc7e0d453727f870c2ef8ff751c04a1c225d72',ECDSA_SHA1=>'3035021862ab2dbb184e1bab8e4286fc53cd0e7d556e11dccd7f4f28021900dcfe136e14be8993c87aadf4b21225a0c1664bc71fad1916',ECDSA_SHA256=>'3034021873d9d19eb128b21bab27292f83f1c7a1afccbae9ddfc2c1d0218296f9823316f98449293c3fdde89f328fd49d4a5e92d9c25'},
21 {CURVE=>'prime192v2',PRI_FILE=>'key_prime192v2-1.pri.pem',PUB_FILE=>'key_prime192v2-1.pub.pem',PRI=>'e76be718c514a9bc3a293b1a5058a16ec61023e596118aad',PUB=>'047450c16d9975711cf80dc60743427321e3d218be9e59b1d546bbc49500904c8e19740611ff85670c163646e19c81943b',PUBC=>'037450c16d9975711cf80dc60743427321e3d218be9e59b1d5',ECDSA_SHA1=>'3035021818d6f73595b8e384a7149dc85296c8666f8d2474b8dbc436021900e9e2781a2c78747ef03c7ee91eee5017dd88b0a088a4cdd1',ECDSA_SHA256=>'3036021900a868c241a3b265b1a5f14a1159e65b2d7674d614a1261fb2021900f25c9af9b2a30188f5899e8af96a28d9fbc1d4424566f734'},
22 {CURVE=>'prime192v3',PRI_FILE=>'key_prime192v3-1.pri.pem',PUB_FILE=>'key_prime192v3-1.pub.pem',PRI=>'648e23d8d716b1df186359698827d52cc708c17f0a8b2a43',PUB=>'0428986b5a7a2b25f8f6ed245e1ceb5c7ab9809f666678a31f50f7ea09b7ddea56af39317425ba1ec600f06d2497dad527',PUBC=>'0328986b5a7a2b25f8f6ed245e1ceb5c7ab9809f666678a31f',ECDSA_SHA1=>'3036021900caf7c9f8015999e1b8c412f5740f12eb5f43a1c1f69f56550219009de8beb76045131000a8049abbea025cc6c2e8767c0adfca',ECDSA_SHA256=>'30340218364fd7612789f6ef38a431d7a68a16fe3b4ea5d6f231fe9e0218360da0b99234285196a18d707e8721b641239ac41195716e'},
23 {CURVE=>'prime239v1',PRI_FILE=>'key_prime239v1-1.pri.pem',PUB_FILE=>'key_prime239v1-1.pub.pem',PRI=>'3a8dc3010097c31c7badfb2bf9d609ec697f1811f2d744ad0557984fe8b9',PUB=>'046d4c619ce0f8550c1c480740f9e441ccaddc67a3a3b4d5585e11c8882d2e36df87f6b2f964c4def52105234eac2e3ff9753c4f8e6da5e331a68a2409',PUBC=>'036d4c619ce0f8550c1c480740f9e441ccaddc67a3a3b4d5585e11c8882d2e',ECDSA_SHA1=>'3040021e323f05efea814b067583c06ae373c7285293ccfabb4ce2e57ec14d66a677021e1f1defc99fecc9d684f3a388dee309311af73a1ec3f156bb6e3584f5def4',ECDSA_SHA256=>'3040021e6b9d25707ffdc1f80fda1e698a72cb2229591a4031bcb88719ab9321a65e021e2f72ac85bb20053173dc35338bf3a18aac47b3fd7a152154e2d77d3b945a'},
24 {CURVE=>'prime239v2',PRI_FILE=>'key_prime239v2-1.pri.pem',PUB_FILE=>'key_prime239v2-1.pub.pem',PRI=>'56d2b5b6929413702756f0eab763ed439dac7ff458298d9b2e4017fc9909',PUB=>'040c545af1fa000b4ae404e915efa2ae4e66f5f00c493f00f06d1449038657760786628e9d1b0be3d184caa45c53c9b2e9c940709409ef531e01d6f8a4',PUBC=>'020c545af1fa000b4ae404e915efa2ae4e66f5f00c493f00f06d1449038657',ECDSA_SHA1=>'3040021e63d489be144e5bf005179b4c72e82d9a5fcb91dddab247ee2829685cf075021e0c2bf212b80c86bd7e5d3224694ee968519e8bab17b18615b5dc41cd02d1',ECDSA_SHA256=>'3040021e58400e9b4b36380d8b053c7ea7a301dddf5fa5ce4fbdc3d8122ef7c3ebc6021e2f009f726bd9809e7ef9f9a3d89571c044143e19e5c1214d27a409ed346c'},
25 {CURVE=>'prime239v3',PRI_FILE=>'key_prime239v3-1.pri.pem',PUB_FILE=>'key_prime239v3-1.pub.pem',PRI=>'33810cfd9a7332f57c4a3c10269df7ef04313e101da1de843ebf10c5db45',PUB=>'0445ea95ec167f4f059915bc6edf8801315ad057ff4121729345ce1b5c60e208960be1c5ceeb08d7ad23cdc5dbe4d2a890df710ec845d0966a36dcdec6',PUBC=>'0245ea95ec167f4f059915bc6edf8801315ad057ff4121729345ce1b5c60e2',ECDSA_SHA1=>'3040021e12b35c822cbf04bd254f8e65437514987427ef1be09c092ebaac80020af2021e2507686d483701f43859c8e8d15523d85d5717b7b144a16b930feadf2e19',ECDSA_SHA256=>'3040021e29db586a8c429a3a13c914b6e424ed3261c19d05736d4bf131825de73dcd021e655362728f9d039c62f07a09e5817b48e59794fa5be03ecec3567cba3905'},
26 {CURVE=>'prime256v1',PRI_FILE=>'key_prime256v1-1.pri.pem',PUB_FILE=>'key_prime256v1-1.pub.pem',PRI=>'be1a6a95799d80c63e671c1c7df3c55ab17398acb4a1e86048a902d2a0177359',PUB=>'04c513e40a8a1acbb660e56aceb0c814a9e73750059c2ffc355c0117143d02e9557672ae5fe192f5ab270eab920daeba57b1281da53bfcba91070c894082d745d3',PUBC=>'03c513e40a8a1acbb660e56aceb0c814a9e73750059c2ffc355c0117143d02e955',ECDSA_SHA1=>'3046022100b5d61020541bdc9fb4f45edcc51d7d3e1398b394ada7ed94b227733b552442ce022100d76b73bd24d71b75cf4ecd11f9840c901d9e30b5a4a56bae7040a541d5c31082',ECDSA_SHA256=>'3043022037b324cba8f288a9c6befa49065dce22a6e60c28b04d7ed4cdca986033509b78021f44225fe81e5a4f6ac78b2b56c7187b8b31837ad30add379c780b125e3ff533'},
27 {CURVE=>'secp112r1',PRI_FILE=>'key_secp112r1-2.pri.pem',PUB_FILE=>'key_secp112r1-2.pub.pem',PRI=>'8e5fbe3aebddc8a13f4d438cd170',PUB=>'045bfd38feda320a73e8bfcd804d3351272055e00eb139c6d5635c784e',PUBC=>'025bfd38feda320a73e8bfcd804d33',ECDSA_SHA1=>'3020020e62608296f33ecbe6ab204c5363dc020e289acb64e5f41fc11dea1295dfe3',ECDSA_SHA256=>'3022020f00902b45f5c263486633ac52e6f651020f00b8aa90c885a11ca76843db7d8937'},
28 {CURVE=>'secp112r2',PRI_FILE=>'key_secp112r2-2.pri.pem',PUB_FILE=>'key_secp112r2-2.pub.pem',PRI=>'094a8840454dd75a9633026622ca',PUB=>'04147cfe973288ff633c7a57228fc179d08a91ba4703304f63b1a16d51',PUBC=>'03147cfe973288ff633c7a57228fc1',ECDSA_SHA1=>'3020020e135c91a6b875e35fab2ff1916f45020e05d85149bd8a5fc007091cc31ea9',ECDSA_SHA256=>'3020020e0f4f6ff485ffbc027c84d4793597020e037e1dfec72c665384c77ca8ebb9'},
29 {CURVE=>'secp128r1',PRI_FILE=>'key_secp128r1-2.pri.pem',PUB_FILE=>'key_secp128r1-2.pub.pem',PRI=>'d8108a2ba9817e63aa251a1c7e6b5f08',PUB=>'04c1bce4bd65cdb84c67a15f5a46445a68ae5d2dd02477ce42c2a0da5a80b94be9',PUBC=>'03c1bce4bd65cdb84c67a15f5a46445a68',ECDSA_SHA1=>'302502102693e1ee12b6575e6bcaa80ed3ef8d98021100bcbb082a9be6040e32c79cc64a50d5e8',ECDSA_SHA256=>'302502103c1a1e95c3ef7c8a8fac8c111f5e293b021100dba18950be1f5bed4a554cc0dfdf79c8'},
30 {CURVE=>'secp128r2',PRI_FILE=>'key_secp128r2-2.pri.pem',PUB_FILE=>'key_secp128r2-2.pub.pem',PRI=>'3ff23cebb55a74409042e2a9eb750d57',PUB=>'04cb2d66b60721e0f0d97b7c98af40247e54ec27097f08468a820eb9849aec2d3b',PUBC=>'03cb2d66b60721e0f0d97b7c98af40247e',ECDSA_SHA1=>'30240210296e7edd2551b28086d0870778d9690402101b3fdb29f6619c1545b97dcb4d861d61',ECDSA_SHA256=>'302402101cbf75997ef81010142794150cc19c5b021037504f952172552593ab384c8e1f36f6'},
31 {CURVE=>'secp160k1',PRI_FILE=>'key_secp160k1-2.pri.pem',PUB_FILE=>'key_secp160k1-2.pub.pem',PRI=>'f337ddafec2746fe7dc9da27447eb341df179d6a',PUB=>'045678d69216c722bc84753a0216a71316fcac81b3e2f074eb9269dcd09351ade008faea4c66e62d92',PUBC=>'025678d69216c722bc84753a0216a71316fcac81b3',ECDSA_SHA1=>'302e021500968ed51e956e8c7099d43188da98ac2cd7859520021500c91dece0f7e8dd3c5f303c9a7d3d17f025963a3a',ECDSA_SHA256=>'302d0214094116423bb12bb3b9ffa3f4abaf8de7f47055a102150094b9baf8434c6cb49a6125a634b0a9e8f2cfeabb'},
32 {CURVE=>'secp160r1',PRI_FILE=>'key_secp160r1-2.pri.pem',PUB_FILE=>'key_secp160r1-2.pub.pem',PRI=>'3d6ebb5fde1043333948b72ed440726160bbb13c',PUB=>'04a7b54fb28c8275d9667adbe63e4dfe84b387e9eea16d67505274d51ac808d4b436c93e9aeb02956d',PUBC=>'03a7b54fb28c8275d9667adbe63e4dfe84b387e9ee',ECDSA_SHA1=>'302c02145d57a2bbcf49841f80562285aad853d171a71c5f0214530e8338ba0754531f9c1a46df5c8a555beed5e4',ECDSA_SHA256=>'302e021500a6972031ba74c43385072d42b090730982b69129021500a11478df762c506c3832f42b26815d9f88e4dda4'},
33 {CURVE=>'secp160r2',PRI_FILE=>'key_secp160r2-2.pri.pem',PUB_FILE=>'key_secp160r2-2.pub.pem',PRI=>'6e21d1f56b4aa5a4acc70cf872668cb2f3e67d8c',PUB=>'04c39963ee5bc371c9c1fdbbae426517ddcbb42e362891dd49d52582a6e56b3572e87717fd1f80d4f5',PUBC=>'03c39963ee5bc371c9c1fdbbae426517ddcbb42e36',ECDSA_SHA1=>'302e0215009fcad076515550c9c0cdf7e22889d955279c3bca021500892a8436a33a99d5e36dcb38bb2a659ba92a2ee6',ECDSA_SHA256=>'302d021500fedf83d3d70c02c9e2f7fcf72b99c7855ecb8dfc02143ffe07b330c2a8a36a62156bf1a940b342f514cf'},
34 {CURVE=>'secp192k1',PRI_FILE=>'key_secp192k1-2.pri.pem',PUB_FILE=>'key_secp192k1-2.pub.pem',PRI=>'bb4412db119fab036e42eb8028ce4552188e5fd12cab1bc5',PUB=>'04f3ecb98a3c0c5715a5425a08e99b092caf166a457da770d2d56111a007faf45c6ec5f38849b94f5011b90151ada2df78',PUBC=>'02f3ecb98a3c0c5715a5425a08e99b092caf166a457da770d2',ECDSA_SHA1=>'303502182a806106c98d2e3131f4eedd35fae93421b4ea3362e56511021900c501bdedae0c3e2fc1bfc74727b17a1d8e8234ce5e8c0551',ECDSA_SHA256=>'3034021823f499904af5aa3cacf41b559202a89510bf4238399af7d1021854a24fe0050e810d4b12313e341c74d0c67b85997ab81abd'},
35 {CURVE=>'secp224k1',PRI_FILE=>'key_secp224k1-2.pri.pem',PUB_FILE=>'key_secp224k1-2.pub.pem',PRI=>'504e3418a6f2bec9b61b82818cfae14360e9c523224b010976494ae4',PUB=>'04a2c7ad145b9323d9cbbdb0989d1294338ae89808f805666ef09913282c47712e7a8ff702bfbfafc624d07e84d34d52ab4f5a025224bf7e53',PUBC=>'03a2c7ad145b9323d9cbbdb0989d1294338ae89808f805666ef0991328',ECDSA_SHA1=>'303d021d00a5c69f06a247cd5155e62244f9cb0b01645ed1872b86e977433ccb35021c1c7b36e14f36764906d64d78305cd131bce4ca4f576fbd55120bfcd5',ECDSA_SHA256=>'303d021d00eb13832d8736ba2305d8d52621ea3be465d56286f8d93f54d8b07388021c1a34e39ceb48e7caaf4b4554127ac5ca56361d5cb22e139c34f70f4a'},
36 {CURVE=>'secp224r1',PRI_FILE=>'key_secp224r1-2.pri.pem',PUB_FILE=>'key_secp224r1-2.pub.pem',PRI=>'5f037dbc728b0c912f33f79748ad9e13c531aabfb1a6f36c52871de3',PUB=>'04ed81d7d9b0185ad27a09c231e97253983af2435019cb5d20bf838e9ea78f4153eba00627a93dcbf26d16b765e43899f22416a0e9fb210fe0',PUBC=>'02ed81d7d9b0185ad27a09c231e97253983af2435019cb5d20bf838e9e',ECDSA_SHA1=>'303d021d00da725b75f0798ab2b35c981f539bf32e0be4b630094b0f602d246b3e021c419900df5a076f7eedfbb4fb6db996f9284ec3cfae2b563eeff24900',ECDSA_SHA256=>'303d021d00f1b6b3505010b9f9f285dd5304a593e217114644ffe789b71e16542d021c7f33a2703e633885738844c164189eefcb6fdfc41244efcd600cf425'},
37 {CURVE=>'secp256k1',PRI_FILE=>'key_secp256k1-2.pri.pem',PUB_FILE=>'key_secp256k1-2.pub.pem',PRI=>'91d44bd72c399f23f1423c750eec025e007d1d9fbb372a4a0cf5813a35a1ba42',PUB=>'04d5f31fd4a14bf567d93b1f9b1e17b1c10ab53127dfdcede6eaf4915f0f0f675e7f26378ad406fd4f9499c1453c655262733c26c0e7df31b6f414734e04c72c02',PUBC=>'02d5f31fd4a14bf567d93b1f9b1e17b1c10ab53127dfdcede6eaf4915f0f0f675e',ECDSA_SHA1=>'3046022100abd606d9332a56e50e7312c7f62575267966fb5d61feea9564c136222282eddf022100b415ee5c718bbec1db767e24f47427fe6d4fa778637fbc2af053ecf64e78a6d9',ECDSA_SHA256=>'30440220495590030cb410f2b15f25fb6508866b94c32fba01a08527d119468db80d0c9202204074b2f994b345742e55c52f5edc5543e97e975fad73934dae9fb5f42ba0a91a'},
38 {CURVE=>'secp384r1',PRI_FILE=>'key_secp384r1-2.pri.pem',PUB_FILE=>'key_secp384r1-2.pub.pem',PRI=>'56973b2fca72e7edf50efda16a3ed1191b9b04a8701849965afbef82639b3fc533af184e35097efc2947f34075963652',PUB=>'04e7175772defa198cf0fbbdf2fe4658551678d6b982c2a5e9a5c07652f5534dd5be12fbbfab701fbde3fc140d3f666f2b39f9a93f136c8c8b6857a70126e97cc893d6831c2f7a4356b2dd896fb9864d436989b4618191b14b4579a8961c3801fd',PUBC=>'03e7175772defa198cf0fbbdf2fe4658551678d6b982c2a5e9a5c07652f5534dd5be12fbbfab701fbde3fc140d3f666f2b',ECDSA_SHA1=>'3064023017f1d5e1987978315138ec211f10a93a9272d9ccdf5b40d25576e7256964af43f40b47d02b7f88a573241e46f88275af02305ce504f4c18601dda24f0b4fbc68d1f4ee28b09524882c37babea5c6091164642dcba21b8f7cb0f6f7ed63ebbea641f4',ECDSA_SHA256=>'3065023100f3571b35f8d5a37ff773bd48f1f366c5680b9331765078fa642f4a0e07fa6e60b7581b7175372092a914d7bbd4ff825a02305d42ac2c0e596900685d2d7a900d626cbd26128f8b8d225d2c2222214f9b2d98dcf12439f87bf647aeeaf1d991fc8269'},
39 {CURVE=>'secp521r1',PRI_FILE=>'key_secp521r1-2.pri.pem',PUB_FILE=>'key_secp521r1-2.pub.pem',PRI=>'0175ba2b79d6fd589da82df79c5d05fafd80e25ba28e0735d3563ea5eb2cba0be36799ea4b5db067cecd8129456d552d556049d404afbb3f1a07fdb7e77b22716c47',PUB=>'0401f0761f84de1a2a48986fff480f0186ae2c2283b429c2c9c89e124138bd580a9414a4438036d80d40156a14ecec290cd4321075dfb7a130c85e8a5f1a9f025245730152eea2a0bf7ce57a1374f6f5b3be85d42619654bd341c3b54834ece5f09e28e4b4f200059c8d305fb5bac6353d4abc4ce8b599d64c457154cc2d382ce958fa8f5e',PUBC=>'0201f0761f84de1a2a48986fff480f0186ae2c2283b429c2c9c89e124138bd580a9414a4438036d80d40156a14ecec290cd4321075dfb7a130c85e8a5f1a9f02524573',ECDSA_SHA1=>'30818702416065101e06016a4b6a9c33939a60a135029d75bbe63632dd211de90e612c8b6c70eb82fb3e3ff93a3f7bf99833f3d2ce1a09386219031524475998105e076804db024200875bafb63e370157cc05f01a5aeeb20e123c7f030ef603119341bd85d1faf10993bc96e3c23f10c284834acc38b288a72b886539774b71aa231697eadf761d0206',ECDSA_SHA256=>'3081880242019a8a0d0f32c72209e918ab6c64049a397127f40957321c051ed2865d9f103d271dc1a3489887fb4f7b6089d91cc2797b05c45795a92876d9639ee7c8a9ae6006db0242016f9fd8f5d799a6085b42aa8c7ff131afdbc12d017b5563384f9c83bffefcba72c38a151cadb337d9ea35bbbba9082ae0e3eebec6570eaed7d25268a12e607f6033'},
40 {CURVE=>'prime192v1',PRI_FILE=>'key_prime192v1-2.pri.pem',PUB_FILE=>'key_prime192v1-2.pub.pem',PRI=>'71ac6f0ae6aa7fe4c12073291e4a26242f7877732ea7ae42',PUB=>'04be75fe89acac6396e72fd9488f036a0f45574f0d5a528a9e1f3485f4477d328f082331fc529f26918510cacac28b6980',PUBC=>'02be75fe89acac6396e72fd9488f036a0f45574f0d5a528a9e',ECDSA_SHA1=>'3034021866a002530fb1feaf300e06a45d7c034e8fffc21b77594893021801c8b0a27cb0e901d151cae47c0c99df9560118a2565a814',ECDSA_SHA256=>'3035021900eac516c8c76282a6adaf7013e4984b04a6e4bea8b3fdba2f02180d76b408f2dd457015b923a7580c10655f855e9b36dc61f4'},
41 {CURVE=>'prime192v2',PRI_FILE=>'key_prime192v2-2.pri.pem',PUB_FILE=>'key_prime192v2-2.pub.pem',PRI=>'bc6532fb8adc6fa22da85e99d49024769c7c0c56869e238f',PUB=>'04acc0985af3bf8e31f0af0b3838ef7a0c626657c9b5ca3e436aa8dec02391bb465099ab50bc89f193d5759f8b4f242685',PUBC=>'03acc0985af3bf8e31f0af0b3838ef7a0c626657c9b5ca3e43',ECDSA_SHA1=>'3036021900809a8999cabd8cd4112524fff6fbb6daf8f459e91fbfd693021900f5608819d4cba9d5e574e65265d61a19649bea696838c148',ECDSA_SHA256=>'303502190084a289c87df7219ae5c0bd5a3cb6a622eeda328468ed76a3021816c5701f707db1c263670d670bbba401ca278aa93c3e536b'},
42 {CURVE=>'prime192v3',PRI_FILE=>'key_prime192v3-2.pri.pem',PUB_FILE=>'key_prime192v3-2.pub.pem',PRI=>'8494aebbe0d99d40240ddb354e3b7a52ade08cc692e3fd06',PUB=>'040ad7d2cff956a360c9cd80486f6cc6da080eb6bba14f637cc21db492d38007fc894f685edaf2d6d8361a376e0b359c74',PUBC=>'020ad7d2cff956a360c9cd80486f6cc6da080eb6bba14f637c',ECDSA_SHA1=>'3036021900bc3384edd8302ac6c3535fcdce339952aa37e2dad1b2ae78021900d5b0a106b65c384185147f5a13b172426dc30d3f84e7e4af',ECDSA_SHA256=>'30360219008e507ad0476d149bad832f1b06301e90ae881838a83fd392021900b9986def1c09c5a35bb0f922658891dd13719ae0844c3105'},
43 {CURVE=>'prime239v1',PRI_FILE=>'key_prime239v1-2.pri.pem',PUB_FILE=>'key_prime239v1-2.pub.pem',PRI=>'5193b61d599160d1272ecfe4f7a5ad010dbe3b77a15c56bedcc1232bc7bc',PUB=>'0473003b786b391df8bfee506d3c8ef06ba6abe797dfbd83d56c1c77fa4fa35bcb925515f3b443d85993fc40f71e82ce6a528b2083637e1cc43a0e541b',PUBC=>'0373003b786b391df8bfee506d3c8ef06ba6abe797dfbd83d56c1c77fa4fa3',ECDSA_SHA1=>'3040021e34a760575935aad189d1fd58d0b84740f25cb91e829a605e02d3d78da526021e6669d3b4d56edff4d95310bc59ec443e306aba3443efbe6356153f3d2d3a',ECDSA_SHA256=>'3040021e42392d20a54b930870df319b4ff2b401d73d028e1a0aff73eee6f9bb1f04021e6a688a6eee784c86cb7a80a74e2ac7936c54f203bc5b7e38a3e8339ce02e'},
44 {CURVE=>'prime239v2',PRI_FILE=>'key_prime239v2-2.pri.pem',PUB_FILE=>'key_prime239v2-2.pub.pem',PRI=>'420d695063758fd46b007badcefa22031d1544c81e6179ba211cab1f4870',PUB=>'04706eaf62b820e6982b6b77604d58640c14f2e6d9d500a25c5af132bde7342ea7caa1edc98513c48fffe799615ecc5ca27316b748a7cf1d61a36093d5',PUBC=>'03706eaf62b820e6982b6b77604d58640c14f2e6d9d500a25c5af132bde734',ECDSA_SHA1=>'3040021e3dc9786d2909e492b79e0829dec995094bce0fa72aa2f5792ed1e49c94f6021e033ec9cd8d9b53d6365e54fad6ff92c029636f4f1d05d8309c5908940cdf',ECDSA_SHA256=>'3040021e371a500289437979ac9e9ba3544589bbdddfca5cc4f11d8b9d2220b81929021e710f645cee7d7939d5bd35dfef8fcfc8f46e4bfc2ca7875e1fae52a258e7'},
45 {CURVE=>'prime239v3',PRI_FILE=>'key_prime239v3-2.pri.pem',PUB_FILE=>'key_prime239v3-2.pub.pem',PRI=>'659e95f77dade42c7d9110ea4e4515bb8f02d8f5e3626aacf6d105121747',PUB=>'0429bc5929ae9da6f71a4f3616f90a4f4ef0268db5f11699d35da37218f1a32cf63dc7c17e2e2bc5d14298e168b745bdc142eeb5fcb94c47f646fcfbb7',PUBC=>'0329bc5929ae9da6f71a4f3616f90a4f4ef0268db5f11699d35da37218f1a3',ECDSA_SHA1=>'3040021e291cb5e727a422ae3594d8a39795355107dd3100935e7084589666179085021e7a5ee8a8e84cee4f818f4893b87003f02f5f1f7bd8d8db7d382ee24255d7',ECDSA_SHA256=>'3040021e478e0c7becb16f197b8491c16cd01a26a5623ea2b29a7f1b13ab240fdcd0021e60996413db68c035ff740476ef5eef859243a6daae5e94485dc486efdc0a'},
46 {CURVE=>'prime256v1',PRI_FILE=>'key_prime256v1-2.pri.pem',PUB_FILE=>'key_prime256v1-2.pub.pem',PRI=>'40c961ba75e7e7bb72cf3a70164bd91697e99ab0436668031e17ec9306f4a418',PUB=>'04c4e24a83f54c2dd5b3c826b9bdcf1771d2e0ad164a4e91b6658f746cf8949a5938d8e727e08f54b8403acc4c5882fda0b1001692215a098e35df5aa22d4dccb4',PUBC=>'02c4e24a83f54c2dd5b3c826b9bdcf1771d2e0ad164a4e91b6658f746cf8949a59',ECDSA_SHA1=>'3045022063b6370e207f3611b2f4a2f56b7f31cf9aa0049b91d347bbfa48da1a07c600060221008784387f01b1cfa7951caa20bca1fa81e49b812661a8512513615a44dabd2772',ECDSA_SHA256=>'3046022100d21eb03d217c9545c82eb0cece3d5c9b0a5540f8350e5b200bec17509bacad86022100de403a528f8c4fcd2b6bcc6ec5131ffa830ae75827d1b7b828fc44fee7fefdf9'},
47 {CURVE=>'secp112r1',PRI_FILE=>'key_secp112r1-3.pri.pem',PUB_FILE=>'key_secp112r1-3.pub.pem',PRI=>'99dac1a9d673f1495db2b80ee5f6',PUB=>'041d02fae808bccb57ca565c312cae0abaadaadf6a46d12ccaf7d12c95',PUBC=>'031d02fae808bccb57ca565c312cae',ECDSA_SHA1=>'3020020e1d29a37d02f2a35edd287f9bf894020e7b646f073a8f260095427ed24456',ECDSA_SHA256=>'3020020e603f37bb2c02c86716537630572a020e2af1fbd9760dcdbde41374307638'},
48 {CURVE=>'secp112r2',PRI_FILE=>'key_secp112r2-3.pri.pem',PUB_FILE=>'key_secp112r2-3.pub.pem',PRI=>'013e4250b66bef1fe4bebfb2ae4d',PUB=>'04246c25c0a706d4b66062b75522e53922c012d5fc6b6c1b4a5e303e13',PUBC=>'03246c25c0a706d4b66062b75522e5',ECDSA_SHA1=>'3020020e16185a3bdbb6f1b0580ce4a9ffab020e182b89aaea76c1a7ac67a170174d',ECDSA_SHA256=>'3020020e26232f75db40434bfc8750402edb020e2cb40a523f9b157238696f11e49f'},
49 {CURVE=>'secp128r1',PRI_FILE=>'key_secp128r1-3.pri.pem',PUB_FILE=>'key_secp128r1-3.pub.pem',PRI=>'16de36667a6aed4dfd0b6c589333862a',PUB=>'0415f6582df158fd71655e4b30d79a34a63635d644d8fc95efb53df1f9ef26ceba',PUBC=>'0215f6582df158fd71655e4b30d79a34a6',ECDSA_SHA1=>'30260211008da8921c9f3622e1b0e0b1c9b62348d7021100e1bc3b9a759fe65d52edcaa1faf35d08',ECDSA_SHA256=>'302402101a84782f46201fb5f8f48929670d173802104e4eea5f3010a169dbac27bbe86d6b1d'},
50 {CURVE=>'secp128r2',PRI_FILE=>'key_secp128r2-3.pri.pem',PUB_FILE=>'key_secp128r2-3.pub.pem',PRI=>'0e8511b4ca37715cce554c75d93a0717',PUB=>'048127262ecb6d260ad2b531700e53873cd3e36bad4a35ae9a8cf0f46fa7153257',PUBC=>'038127262ecb6d260ad2b531700e53873c',ECDSA_SHA1=>'3024021000eb393148856af9d9c8a85dbc1c2b960210279019c29f1b9affebab711b73fbbed7',ECDSA_SHA256=>'3024021030f8c03c69cd3681152bfcb47baedd3602100146958b926d985bbe0f2f326f8b2c40'},
51 {CURVE=>'secp160k1',PRI_FILE=>'key_secp160k1-3.pri.pem',PUB_FILE=>'key_secp160k1-3.pub.pem',PRI=>'de18c665d4ead6391e6d865a1f437ad41a63fe99',PUB=>'04a9cb746bbcd7fcf9df839e516816d11867322a0a3f589dcc639e3e37575c20e19f1d78e1734451b7',PUBC=>'03a9cb746bbcd7fcf9df839e516816d11867322a0a',ECDSA_SHA1=>'302e021500897668859cb3a0afc961c6622b8362bd1db9cd45021500ac8ecb94e4c2fc0b36064c75aecdceda4be95243',ECDSA_SHA256=>'302e021500e26e12f798ff67d292986f42c1700f867dfaed46021500ebaac751bf8953ea7b18bf7765b8d40320d78409'},
52 {CURVE=>'secp160r1',PRI_FILE=>'key_secp160r1-3.pri.pem',PUB_FILE=>'key_secp160r1-3.pub.pem',PRI=>'4c3c347ce986c9c9af2d978a4f520d309f53a32c',PUB=>'044ef02c65cc01e27355e82839dd939c1d907569ff9b24bcb72962f24a5434989a8a494cdc982e272c',PUBC=>'024ef02c65cc01e27355e82839dd939c1d907569ff',ECDSA_SHA1=>'302e021500d83981a07ee6bfaafab87746d8ada8774bfce737021500d88aa07b13f7c8ca9110f83217da200cdf84e40a',ECDSA_SHA256=>'302e02150095e2b46af8171a27b5005096be62d86f09212240021500b6899293eca3af7ac8f2651ee9b294fdbb4915c7'},
53 {CURVE=>'secp160r2',PRI_FILE=>'key_secp160r2-3.pri.pem',PUB_FILE=>'key_secp160r2-3.pub.pem',PRI=>'c7b1c191ccee2c0e1d691719350e7c6761c02e4f',PUB=>'04c6810cc1ed89788e9581fa85edfff774ddee38d9f01a87c51b748750f7a9b15ee83e620cdc4c3f46',PUBC=>'02c6810cc1ed89788e9581fa85edfff774ddee38d9',ECDSA_SHA1=>'302e021500b349b13cc377b37ca63a91fb2fe0219dd9e4b886021500a10e071c02762443ab4e8b2315a8acf456c9b911',ECDSA_SHA256=>'302d0214374915221f383798358bee6fde43a6a7cf431438021500ba3b6f5e9af136addb05d8acd0134462151a72d5'},
54 {CURVE=>'secp192k1',PRI_FILE=>'key_secp192k1-3.pri.pem',PUB_FILE=>'key_secp192k1-3.pub.pem',PRI=>'1476eb7512b0f85d3e4824da18912335f5abc74e50ca3deb',PUB=>'04b20094e3df79dfcdef5ea044e9ee85457910379d939683a6c372ca525b543270c712d10260a58f21ad583383e9887568',PUBC=>'02b20094e3df79dfcdef5ea044e9ee85457910379d939683a6',ECDSA_SHA1=>'3035021900c5c2ae75f2106d5f4dfccf2f76a41f6f0bd587ebe8344e5d021852d7aa70f1f6cc73f50e9459252b68707995c90005844c9f',ECDSA_SHA256=>'303402181d7a041cdaa6ad34ba834fd7b53c6e260a1c6ccfe2638f7402183d7ef9e11953bf1fbdc7bb5cf7fd2701d28a64402f5925b5'},
55 {CURVE=>'secp224k1',PRI_FILE=>'key_secp224k1-3.pri.pem',PUB_FILE=>'key_secp224k1-3.pub.pem',PRI=>'1709f944da01983d28b96777782e5a78e40e08c54212b19840f84006',PUB=>'04b56fdf57979beb9267a57e2ff9f5752dbf77c41c9ee12b8aa1e769802866f41bbfb4159b19659c42a95e40ff1c667eee4ab250b66cfe775d',PUBC=>'03b56fdf57979beb9267a57e2ff9f5752dbf77c41c9ee12b8aa1e76980',ECDSA_SHA1=>'303d021d0093e0b6edf75e3c2109caa6fa2dd79f2099081238c01cb0ad0ec09f2d021c404ea31d975290d58f03906293630913fea5a0a0839030f30828db75',ECDSA_SHA256=>'303c021c2118c6c3e8926ce2d1239e111da1a2979d14176c8ab144367121dd48021c376d49e2f4a212d274963c44bc72bea6249fb733f3445fb913bc85f5'},
56 {CURVE=>'secp224r1',PRI_FILE=>'key_secp224r1-3.pri.pem',PUB_FILE=>'key_secp224r1-3.pub.pem',PRI=>'53dfaeffd502ac4d6c7942a2f7ff2367a016b20b1b350635f8c820eb',PUB=>'04b1fb44ffa8e4f655c060074e380900675b84cace46fd1fcada9b3d9b44cef8598e4caa8861bd10d81052606a3fe4a2cbfd1344287952837b',PUBC=>'03b1fb44ffa8e4f655c060074e380900675b84cace46fd1fcada9b3d9b',ECDSA_SHA1=>'303d021c2cbf83ae5138d0a4ea7aa0284a7195aefec5e12e2e3fe2dcd72926da021d00cd74475d258fe3070ba43a7b4e8653d1daaa18252a56a563d0c8062a',ECDSA_SHA256=>'303c021c094487a847116fdc95d77b981dfa8eb4363dbb33c42c1e9ce145b932021c5dcd1325cfa137f0d1b9076b49b2c29a91fbb3d9ca5fa32a8d3a350c'},
57 {CURVE=>'secp256k1',PRI_FILE=>'key_secp256k1-3.pri.pem',PUB_FILE=>'key_secp256k1-3.pub.pem',PRI=>'20a12fab9d4a13fb06e1146ef6c715f6b663037336a5d59c2027b613d016eaeb',PUB=>'04275b2c4783e4ee1c22d0862b804ce97aa7c74631ad8f599fa94884ab366e44bc8f7bec169298abf6af998195cf47965e6c7426baac71653941b02942f50a4dc9',PUBC=>'03275b2c4783e4ee1c22d0862b804ce97aa7c74631ad8f599fa94884ab366e44bc',ECDSA_SHA1=>'3045022100a366fdf8d18bd322966a38834b5594080f19558af75e2216c637f048903e81f302201435b36c9ec5a864435af3c492216162357157a3b18a7c5811e4183b6263d662',ECDSA_SHA256=>'3046022100d0abdee98a71dd2a931266ce68b8937bfc6dbc74bde97919fbeeddc201e0fbf1022100e1db50da1e9e5c4adcb3fe1271d4dd32f3946659ea9a2d93eae6ac18eb02c26a'},
58 {CURVE=>'secp384r1',PRI_FILE=>'key_secp384r1-3.pri.pem',PUB_FILE=>'key_secp384r1-3.pub.pem',PRI=>'1730392b33dac04f9f5e689308ea7c17cfe764a5f2208f598ba897c82317e469db16fe42457a68139b3e56c0a30fb983',PUB=>'0408353a2bb4dba518ad6a2c2cec3dfa9a17fc3440628cb03635749100bc46accd0ee6477ef0b018cae45f660f2134298e8a1b68fb2b8a9f9be8e6bfd09175923f4cd1efc459a7a6f233f5bae751333c4b318a32cd8834a9654bd72975a2fc82a7',PUBC=>'0308353a2bb4dba518ad6a2c2cec3dfa9a17fc3440628cb03635749100bc46accd0ee6477ef0b018cae45f660f2134298e',ECDSA_SHA1=>'3066023100d5a1649ebb113acc2f640316fb6798ff1d4532dd5fbd8744d821bcea8e15223e7d15b3fa2dcbe89e776f2f477a681791023100d0a60af9620eaa62a68830e0b717442e9c12e677da652705326da9c0e9766d1b654d94a2c3c11bdd98fa620764b3e143',ECDSA_SHA256=>'306502303b7a750e8b7e9007d4bd6f4a25a75cdf706cd75c6acb8c7543b06a72ba56ec5df629e51141c173459edb9c7e96212e71023100e5a98ee967460796fcf90c27009f485dd2dc066eb31bfe99ed0a2647a56a1206cdd28c7c9911896a74466b98363c668a'},
59 {CURVE=>'secp521r1',PRI_FILE=>'key_secp521r1-3.pri.pem',PUB_FILE=>'key_secp521r1-3.pub.pem',PRI=>'01f2baec33a3d20b041c4ee883d457306e03f4e54b1285e0180e97d246461826a56dc49f8c6261e44c5e37de393fc467f505ec254d5380e6d82ace0335af5b4f8d15',PUB=>'0400b7f08eee478a92ba8e682286add2ca686409213662795632703c0ee39964af94188d133b793b4a9e6e354e6755f24d9d77018d77bb20238732147c9459b75eb50b000f099e980ee1cbb8ca4e1029b12a57083c300e8bb7240a23e0e8e5914010eb4c65b032e499570c59ee6d506501dfab6a4e3a957950437cba1495314af2c2863d98',PUBC=>'0200b7f08eee478a92ba8e682286add2ca686409213662795632703c0ee39964af94188d133b793b4a9e6e354e6755f24d9d77018d77bb20238732147c9459b75eb50b',ECDSA_SHA1=>'30818702412b146ccf45b99f845473b001765e875f69fa17cecdbe4f50189f75cce4d4910f24932e31cc5784fd56b817e6763afe78f3c793cb5796f121c044ab6dfc1ed01a8a024201cedad9d70fcbbb3c7c0677dc9a16b4b0bc8522fd3eac63cb7dd94452e375f66e56ff32a94c036e388367b5935482c50d4660e27b08d16f99b004855e4690929ce2',ECDSA_SHA256=>'308188024201c4f42125a4b3a51fba577722541d618139b01052d7ac866f411e22ff710cd3df0e3df9dbf89f70775911e6067024dc4b300dfa1146b0f13418946fd2e90d3646ff0242017275db4bad078310dd163a60c48cc805bb43b022be881b58d0a66d46762e380eee32735cd7fe1f0caed6eb57ed1af12cf5bff8f8bc66bb4a47313dd0e9bab2895f'},
60 {CURVE=>'prime192v1',PRI_FILE=>'key_prime192v1-3.pri.pem',PUB_FILE=>'key_prime192v1-3.pub.pem',PRI=>'eb566f88950fd765e3d1f757e7293bd040b5a038812fc7bb',PUB=>'0404aef826969cfb139810d6bfe286917ec14e378730ea0707912480112d723d1eb50f129edb9367fda59fdd4867a0e0d8',PUBC=>'0204aef826969cfb139810d6bfe286917ec14e378730ea0707',ECDSA_SHA1=>'3036021900d88f65003cc149dbd2b7b30a86ad378f0298621a981b8b2f021900e618e0cae3b3d79886ba6a12deeb7fcb81dc74bbea7c3838',ECDSA_SHA256=>'3035021900fea28b7e0140628e06ed3946cbcc4cde7af87b3452e15b62021846ef2b4e550b954ac08798e5707770c78b8c4b71800ba486'},
61 {CURVE=>'prime192v2',PRI_FILE=>'key_prime192v2-3.pri.pem',PUB_FILE=>'key_prime192v2-3.pub.pem',PRI=>'ec2af2777a78eacff5e4057925c8f4c3f1f4134492ce6e97',PUB=>'0423abfde9a835f43a1bbbb8ee413a24070b358af447b958997b8f2000089556a0128dd5252c5fb6ffb9532059f559846e',PUBC=>'0223abfde9a835f43a1bbbb8ee413a24070b358af447b95899',ECDSA_SHA1=>'303502184c83e052e376a1aa8ad731b197a51cb064b8cc426508653c0219008dfafacf06139e4982b7bedfd106c19ff320409809c17f23',ECDSA_SHA256=>'3035021814308b29608456cf4531f9cc107f077f5140f1e96865b0ff021900b372c4d61e8d24ccf76ed94dd8830aefdfaf0135cb582e37'},
62 {CURVE=>'prime192v3',PRI_FILE=>'key_prime192v3-3.pri.pem',PUB_FILE=>'key_prime192v3-3.pub.pem',PRI=>'f721088da7d09e79a0f44e6bd6e92c27c68c6bf97242d3f5',PUB=>'04d93470443f8713e656a4509468c3706ef40b6a2ef86043fb181e6ca5eaffc54f7874b86b9ffad5f5b1a8f2703c121096',PUBC=>'02d93470443f8713e656a4509468c3706ef40b6a2ef86043fb',ECDSA_SHA1=>'3036021900c9cbf98af8853554b6c5012943d2f08c77b759bff7c719ee021900bc9534db2e4f40b8ffc7284a1f0c5bc0fa35bee52b56c699',ECDSA_SHA256=>'3034021810b340e088be8c6f50be9697e054780438f7e95f62f5302b021818cb8f834fdf26d23ead0f612171b5e0a66393633f647c46'},
63 {CURVE=>'prime239v1',PRI_FILE=>'key_prime239v1-3.pri.pem',PUB_FILE=>'key_prime239v1-3.pub.pem',PRI=>'7b4521bca9b02ef8b57d9e2d6193a732d138b39d8abc741e96e146b01e3c',PUB=>'042c30f53413f4ea8a794724d02f1824ed9412a2b7cb02792f7e6ef06a93b130d45b9b4cde3e4b178921e0aa0c310e550a39f4d67800932466583f3690',PUBC=>'022c30f53413f4ea8a794724d02f1824ed9412a2b7cb02792f7e6ef06a93b1',ECDSA_SHA1=>'3040021e4165b85d1f2709847a739c3009adca605b7957eee86002461c92c8895b01021e7bcc9b21701e6b290b7032cba2ba87c8e0565c965db2190e9baa1152c372',ECDSA_SHA256=>'3040021e601b96746a533f378fafc2c12ee980a04857c6e56c36fcadb290ba0d0370021e312662f498a75da7506da87567a68e169d79f335cf743ce90516da562aff'},
64 {CURVE=>'prime239v2',PRI_FILE=>'key_prime239v2-3.pri.pem',PUB_FILE=>'key_prime239v2-3.pub.pem',PRI=>'1da296ea5305b60c16824671f792118e585b65d564ed627371f3031765bc',PUB=>'04333d12e0faf83df27d7af2767f3196bfa2c7b758c8f7e394298b5d892aac7832609b6fb037ac1059cd471e3bece6784a39263a13979af094c00baf37',PUBC=>'03333d12e0faf83df27d7af2767f3196bfa2c7b758c8f7e394298b5d892aac',ECDSA_SHA1=>'3040021e6ba7fb1fe0ced3a2e221800817906de9e95035bf6970745792a3e46badcc021e5c4f8bc42973ad07509813c020d076972992a8294bd3b084a779e2a18cff',ECDSA_SHA256=>'3040021e6610ea72b2f451e5f801d6c81ecc416ccc0c6614adae2c51f5cf8d01d332021e2694f4086968d8552cbf9508a248967ece6a2e75e1a91caea584bd460656'},
65 {CURVE=>'prime239v3',PRI_FILE=>'key_prime239v3-3.pri.pem',PUB_FILE=>'key_prime239v3-3.pub.pem',PRI=>'2c33bab3e10be173c9a98c8bda253f929569c4c53b8c26ebdea5202fbc3f',PUB=>'040bc536b07d27c9c138875e9d03f3cc1ce4d4bcd9a5fcfc0dcb6e9b539b9e126747a584397c8c9e29fc7c60205be6d018e16cc6a0ee4e9e014d87aa3a',PUBC=>'020bc536b07d27c9c138875e9d03f3cc1ce4d4bcd9a5fcfc0dcb6e9b539b9e',ECDSA_SHA1=>'3040021e04e94698eb31a90baaa8f9b578ec307f8d1f83edc85fd90c14652b520408021e3fbcf91f4dfa164ece8765bdbc70f72ced1e0c6aa919483fdefe3e75cbfe',ECDSA_SHA256=>'3040021e4c1e0fa1474a4bdfe5ad4ebdaf76e8eccb4d3288997ccda97cb8ac5e1771021e2a821fd377761401de5302f4dc99bc25705273967bf78e46068450a07328'},
66 {CURVE=>'prime256v1',PRI_FILE=>'key_prime256v1-3.pri.pem',PUB_FILE=>'key_prime256v1-3.pub.pem',PRI=>'e6e3680400f2d4ee67577cec2819bf920fcfdf69fce549e5b603778b5b8f2894',PUB=>'0407ff8b133730ccdc19eb24bddd7931459488829e458e77ad5d5620f90ba61224ad599d9d436ec8fbcbc883e8342e14847f97fb37ff71e898d800574ab6a9e03f',PUBC=>'0307ff8b133730ccdc19eb24bddd7931459488829e458e77ad5d5620f90ba61224',ECDSA_SHA1=>'3045022100def3eba30349fe165c36da726f22579ad3ccfb853f6edf26ef8707b7e09332c40220076bcf2b5855b8485a460a5b96f211c7ea538b18fe3a4c54711bb53f9dfe18a4',ECDSA_SHA256=>'3045022100b4197fb9426cebae0204d63f250b1ba82d96a246369e56eef9196bcfd2f4b006022057131c64a5bd9c32f0c7cecaa1562f68f04c8390cdee81bd59d62551b87f9142'},
67 ];
68
69 #diag("samples_count=". @$data);
70
71 for my $h (@$data) {
72 ok( length($h->{PUB}) == 2 * length($h->{PRI})+2, "$h->{PRI_FILE}/length test PUB");
73 ok( length($h->{PUBC}) == length($h->{PRI})+2, "$h->{PRI_FILE}/length test PUBC");
74 }
75
76 for my $h (@$data) {
77 my $ec_pri = Crypt::PK::ECC->new->import_key_raw(pack("H*",$h->{PRI}), $h->{CURVE});
78 my $ec_pub = Crypt::PK::ECC->new->import_key_raw(pack("H*",$h->{PUB}), $h->{CURVE});
79 my $ec_pubc = Crypt::PK::ECC->new->import_key_raw(pack("H*",$h->{PUBC}), $h->{CURVE});
80 is( unpack("H*", $ec_pub ->export_key_raw('public_compressed')), $h->{PUBC}, "$h->{PRI_FILE}/ec_pub public compressed");
81 is( unpack("H*", $ec_pub ->export_key_raw('public')) , $h->{PUB}, "$h->{PRI_FILE}/ec_pub public uncompressed");
82 is( unpack("H*", $ec_pubc->export_key_raw('public_compressed')), $h->{PUBC}, "$h->{PRI_FILE}/ec_pubc public compressed");
83 is( unpack("H*", $ec_pubc->export_key_raw('public')) , $h->{PUB}, "$h->{PRI_FILE}/ec_pubc public uncompressed");
84 is( unpack("H*", $ec_pri ->export_key_raw('public_compressed')), $h->{PUBC}, "$h->{PRI_FILE}/ec_pri public compressed");
85 is( unpack("H*", $ec_pri ->export_key_raw('public')) , $h->{PUB}, "$h->{PRI_FILE}/ec_pri public uncompressed");
86 is( unpack("H*", $ec_pri ->export_key_raw('private')) , $h->{PRI}, "$h->{PRI_FILE}/ec_pri private");
87 ok( $ec_pub->verify_message(pack("H*", $h->{ECDSA_SHA1}), 'test-data', 'SHA1'), "$h->{PRI_FILE}/ECDSA_SHA1");
88 ok( $ec_pub->verify_message(pack("H*", $h->{ECDSA_SHA256}), 'test-data', 'SHA256'), "$h->{PRI_FILE}/ECDSA_SHA256");
89 }
90
91 done_testing();
33
44 use Crypt::PK::RSA;
55 use Crypt::PK::DSA;
6 use Crypt::PK::ECC;
67
7 for my $f (qw/rsa-aes128.pem rsa-aes192.pem rsa-aes256.pem rsa-des.pem rsa-des3.pem rsa-seed.pem/) {
8 for my $f (qw/rsa-aes128.pem rsa-aes192.pem rsa-aes256.pem rsa-des.pem rsa-des3.pem rsa-seed.pem rsa-camellia128.pem rsa-camellia192.pem rsa-camellia256.pem/) {
89 my $pk = Crypt::PK::RSA->new("t/data/$f", 'secret');
910 is($pk->is_private, 1, $f);
1011 }
1112
12 for my $f (qw/dsa-aes128.pem dsa-aes192.pem dsa-aes256.pem dsa-des.pem dsa-des3.pem dsa-seed.pem/) {
13 for my $f (qw/dsa-aes128.pem dsa-aes192.pem dsa-aes256.pem dsa-des.pem dsa-des3.pem dsa-seed.pem dsa-camellia128.pem dsa-camellia192.pem dsa-camellia256.pem/) {
1314 my $pk = Crypt::PK::DSA->new("t/data/$f", 'secret');
1415 is($pk->is_private, 1, $f);
1516 }
1617
18 for my $f (qw/ec-aes128.pem ec-aes192.pem ec-aes256.pem ec-camellia128.pem ec-camellia192.pem ec-camellia256.pem ec-des.pem ec-des3.pem ec-seed.pem/) {
19 my $pk = Crypt::PK::ECC->new("t/data/$f", 'secret');
20 is($pk->is_private, 1, $f);
21 }
22
1723 done_testing;
0 use strict;
1 use warnings;
2
3 use Test::More;
4 use Crypt::PK::RSA;
5 use MIME::Base64 qw(decode_base64);
6
7 my $data = [ #test vectors generated by: OpenSSL 1.0.1e 11 Feb 2013
8 {ID=>'key-512-1',SIZE=>512,PRI=>'632B6C7F984EA022C2B3D507A3A0886678F8794B151E16EA696883B0305B2A984EB6CBE3CC56025852CCE742A51655A8CADE5BE73EBE75CEEF70CAA72F82A801',PUB=>'C5920D48C0DB954D7834FA7C74DB7C91714C97EF2DA4B35DA302D75A0E08AD3B7C05296533C71DF5045F66DDD2E1F9A0D487CDAFE4137214F7764D2BE25D0D29',SIGSHA1=>'v/ZzE0JT8xakMsHhh2qVcEm1r/odXZAfSr+JK/B2trzq3UrzUwYfWgM7NtO2L6kU0wyNCVTy+gMpGECfaAEiqA==',SIGSHA256=>'pjOjBMaGXx7XZ+uNgfszCD1yy9WeLwgdM/1eP987j+s6hGaIjHKOm2PAxXZ6cEqYi1QQsMybe3F9UhL2b5ws9A==',SIGSHA512=>'',ENC=>'mQw7zaZdwthCgpBdV/BxdzMp9yUMOSFHogB7DvwCYztRlqlc8bXnJUsa6yasLARaN2rbb3dyIN+apNW+wZkvrg==',PRIDER=>'MIIBOgIBAAJBAMWSDUjA25VNeDT6fHTbfJFxTJfvLaSzXaMC11oOCK07fAUpZTPHHfUEX2bd0uH5oNSHza/kE3IU93ZNK+JdDSkCAwEAAQJAYytsf5hOoCLCs9UHo6CIZnj4eUsVHhbqaWiDsDBbKphOtsvjzFYCWFLM50KlFlWoyt5b5z6+dc7vcMqnL4KoAQIhAPLj363QXovzYxztngqfImgsXOSBwgTpmnKylb6oSbfVAiEA0Dv50hhAHRneuo0M4nat47wIvc5MmJVS4ecf1N4bngUCIEbwgRLd6c9MPaVkTSVjBwSP+G2Q7F7M75wSRqQRuL4lAiEAqDzcsQ6gtiJRnh0ZnNpP0Z/43AkSP3DdfuByClTMsVUCIH3TYvzcDPJO1K9KTLNXGOSAhkh3QE3wJBLZCI7jm3LY',PUBDER=>'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMWSDUjA25VNeDT6fHTbfJFxTJfvLaSzXaMC11oOCK07fAUpZTPHHfUEX2bd0uH5oNSHza/kE3IU93ZNK+JdDSkCAwEAAQ=='},
9 {ID=>'key-1024-1',SIZE=>1024,PRI=>'56293EFF57BC5C6A708CB55AE74403F6B21ACACC2642E50E020D2D3429BF815A53DC13858DD1F2E79FD5377EF1DA04740FEA5D3F1C862252F1A88F750ACCA71C5B6C60C43FD4AC2A102D7F48968E38EBB792CE643FF511E7892853532E7A98DF9DD9773627CC29EFE17C8B41AAEA31BC57078B5BE466CA0D64390E997727D631',PUB=>'ABCF9F5B2BA9FA2A11B8BA608756387234B2A10A96033C27BFC789BD3907AC53BA5227DCBDADC865B7991D6DCAA2C7FB0C8742C3D59AF3100FAB034CADCE51DCFDA813E4064D476A683ED8BB4E6C7CBC3A0485DD6A852AD087FAA99567436E165E73210068B7544BD6DC3D66A61A3D1C9953D28CFC0E2CE4EFFD6C01645B766B',SIGSHA1=>'nJVnjobpUG6jIjIXTLgM6Oo4SXegZD3MYMC/ejjypCn0aDVoCpCatouypILdBiWm3QoBlcwAZoDfwV2xPhRi9Y4Uy4Fwn2h2ItkJSaoV1j16jVnR/GHl8qXS1lX3Euj1AWScYy0uXP5ddSNjxjjPwWPHh/R8hjHg/+JSi1v/XRw=',SIGSHA256=>'fIziZBxGd1VR+b7DdjqlpBUn7dlShTkmCSBtx31Ryl3Ku/UCFKU02NURE5l5nH3AE366LU7FX8H55VsoTdxySNGHW1vzAe+BqgTzYnTYZTlgBAJxtdgBaLF2JewOZB3iX90TKeCcLclUlcNtcFNpf2r7/qdxdNQwzsuy80gOAls=',SIGSHA512=>'BTIfuv37aZkHPWVhj3RQRQREun0iUdj5FEJppjVtBfFIe3ZCAYnEO8XA0vaNbIyKHTzz66tCHAON/x1lsoGDZztzKnalUJVGkdsXu8NaBdH0Wrxo6tiaKkOSoHOrFrtiWC998HB/POZCOIXJq9PgamCp4sQ1u/pQu+6vG3+SfDk=',ENC=>'LIefk1+idC96eS6yPAMAzuO6nH3FyCutvBCfoGIh0BSmpYvfyLHsdg5hog9Zgva9vs/LXJHOGzQ4c82O05SEG7+IiwL78l/jmIUXUusCGo0BRDn2J2oPl5ZpF+ku5W2w+wFy70AnVzB97kUjsM104ZugbO+9W4PYoLVLMWh+R2I=',PRIDER=>'MIICXQIBAAKBgQCrz59bK6n6KhG4umCHVjhyNLKhCpYDPCe/x4m9OQesU7pSJ9y9rchlt5kdbcqix/sMh0LD1ZrzEA+rA0ytzlHc/agT5AZNR2poPti7Tmx8vDoEhd1qhSrQh/qplWdDbhZecyEAaLdUS9bcPWamGj0cmVPSjPwOLOTv/WwBZFt2awIDAQABAoGAVik+/1e8XGpwjLVa50QD9rIayswmQuUOAg0tNCm/gVpT3BOFjdHy55/VN37x2gR0D+pdPxyGIlLxqI91CsynHFtsYMQ/1KwqEC1/SJaOOOu3ks5kP/UR54koU1Muepjfndl3NifMKe/hfItBquoxvFcHi1vkZsoNZDkOmXcn1jECQQDhVP7yFj7RFGmwWzGgobh9K2YQlvkbTJzL4WAR7TtcwrNhpNxKNooI3ryG5XqejZDEY7VKA5jiLoPtHYR6S3x1AkEAwzHaAc62JfYPUoiFGZ6XHbslUhdE1VwuEk+O/0OmJZe5hEIlR5iwfpudsJFKy/zDpK1LpJYzKHBNMwpAHRpLXwJBANbc0W3OQH/l0xHTI3NkQiM46s4O5+JcH3dZpN3zNJOzJJGLPnOVpfHnUiXfVBk0LELYQNoeq/2hFTNY3iYvLLECQExxf5FppQgk30dRU97+ruvj2O/XUQvF9/0Pz07E7ZKXYv4a8YKil6xdwVne7M4KhYw+mfsxH4Pcxz8P6p/7Jj0CQQCrDRP2Rhqre0Oq3fyRd44uIaN+hWArLFBwB8VDoTnbymG0qPuvfROAHroRLmXmF9PFeGrKcPGjej2G1C+AuSdm',PUBDER=>'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCrz59bK6n6KhG4umCHVjhyNLKhCpYDPCe/x4m9OQesU7pSJ9y9rchlt5kdbcqix/sMh0LD1ZrzEA+rA0ytzlHc/agT5AZNR2poPti7Tmx8vDoEhd1qhSrQh/qplWdDbhZecyEAaLdUS9bcPWamGj0cmVPSjPwOLOTv/WwBZFt2awIDAQAB'},
10 {ID=>'key-1536-1',SIZE=>1536,PRI=>'B97EC809C3728D720E2C5674E2FBCA68C904C0C981C0A3B95C0138A0B91FB295DC168BF7EC002795BC8F24CBF82314FCE8FD7D69BF0FA022AEE48DC3163A4195E3197ABF65FEAC42069914B57D153591E1D08C7D5F4CAFA2B6922280BEEA31CD505E34970AB1B785F64A0BBD7F92534D0C6E1356C86A358F2BA9CEF16BF27D4AC7DF712337ADC46B3186584F551E5933CE4A85A140A5382E7A7D2797DF8E1EA862338D47E7AF3DC86994CF2E17D2CCA6784294AFFB8D9CC6B34C655987A53255',PUB=>'DA464976929528C9868B7CB656CFD969269119A9CA8D91931714DDC2BCB937BD40D5C11140191843A467DE2F310B63FEFABF82462744F04B9920ADE448851CDA47ACA0EF75F33DCB205049AF15399EA2301E251EE450D67326CB1F64AECECC560C43E3C3EC683D716B4C6814AD8FE26E6442B1A462C23CB0F41CC2B159C940837687C8A3C3818B5E9D5E2E4DDEE6507B17F06AEE9257C6A8EF33E8E7C06C5D52DE858110BE260FF5CCBE1BEAE7FEE1BF576045819676732BC3991D7F8CC13E15',SIGSHA1=>'NUrmQizMnT/GScFhWdIMq0zJ0mmhfFj8pF5Ux8K/Awf/nFViJSuTb7yDHp3k7QmGgo6UmWZNCNrTy2jZo6F9XAwNo+IVsnPXVtoCVLMRxNYYpOV8H0Ph8xaym0jmowj+TivyGx7k/6UoJMer1lTow1nZ/d7rroDrrKTnRoK8cBTfXaq9xiGztXTd0+kXkLSai64JQ8i2H66dDY6P713fPhWZxD3w9uTJ5pPlhBVX76ccz/4o5UPKXQUHDKvhG6lO',SIGSHA256=>'KnD9d6valiHNzj1zX4yYU7W9IffPdScpAKbKhUDv0D/y+EkH0jUJJ/F7dV0JBxGshf1Kmi5B7BnXbND9/fHPDIFPlgJ1rxFeIntG9+m7c2xg8Dh0S1rh6slMAJgj8dKaw/mRwBVwmMi1luBrW17r1LKlDUDYfNnjKTeXzbwny8Je5COlDfDP/Lk3NtX5DuY9Et+3+MQCRn95CedNokteW3jO9q7a+1UcQ9F7EYPiISyDje2Eh5rbc+eNHjZ3iBJq',SIGSHA512=>'c+lX10eLEZx0bregmdnBuY5usXmWrGQ2HNd++2mkyXK3UqGmJSdmpfxoHmK7rFaQaCf/QOlhSzYPx5MG7GS9sxxbJsYTBa0S78RslfBNQVUYiS9BZNae6kLCDyKPfoAOIvZdqg35SQFasDqdS2cv4s/2TrP1ziAriEP/Uv6MIPIODZq0qdVswyWIJIOOmG5CN4eoi70y2VLtcN1+PgcYpJG+dmgFE6EVItGqUss1XoMuhx4xn8xhbYLISsR0fylK',ENC=>'so1DFioxlbOOm7e0A4HOcznRjGS/dgji5ThBJMMVmvzCMv2lBaKy6kfemk+NhjG9dUIRuf9aPY+sASHJwGfBI72puf6H0VkFFzYPzIkTndW57fVJItTIuh8yre74fPadi6hcW2JBWoDCU7EO6hJynM1Zlol/Qt2gXiy5LrDp0QGV6tkl5z/Vho+I/PnPA8bbTs8/Iw+WKgtgnakK9gE2u2TjU8MpHM2SyShnRAMVW/qUeblQcrNORMGD1bY6tXk9',PRIDER=>'MIIDfwIBAAKBwQDaRkl2kpUoyYaLfLZWz9lpJpEZqcqNkZMXFN3CvLk3vUDVwRFAGRhDpGfeLzELY/76v4JGJ0TwS5kgreRIhRzaR6yg73XzPcsgUEmvFTmeojAeJR7kUNZzJssfZK7OzFYMQ+PD7Gg9cWtMaBStj+JuZEKxpGLCPLD0HMKxWclAg3aHyKPDgYtenV4uTd7mUHsX8GruklfGqO8z6OfAbF1S3oWBEL4mD/XMvhvq5/7hv1dgRYGWdnMrw5kdf4zBPhUCAwEAAQKBwQC5fsgJw3KNcg4sVnTi+8poyQTAyYHAo7lcATiguR+yldwWi/fsACeVvI8ky/gjFPzo/X1pvw+gIq7kjcMWOkGV4xl6v2X+rEIGmRS1fRU1keHQjH1fTK+itpIigL7qMc1QXjSXCrG3hfZKC71/klNNDG4TVshqNY8rqc7xa/J9SsffcSM3rcRrMYZYT1UeWTPOSoWhQKU4Lnp9J5ffjh6oYjONR+evPchplM8uF9LMpnhClK/7jZzGs0xlWYelMlUCYQD4ouyy0yEpXK7jQ8keFTo5/dWD4KS+hw+PdxpcDDXPxJ8WF8SaP7c0vlmXesf6pbpZszaIZoLnIUi6LePpmQ1QWQUXpC3Wwpfybz+hySxzEGPl0oN3Jqi2ESXMh77oJpsCYQDgvStQS1Db1Ln71ncg/9XmqCHhbV3cclYjivtC9FcytK2UGGr1da0pqiIV3iDWLCbddO2POJDwMFi6X/MiiwJa2jSdKhN27kbN7vAhBoMFjUcesw46KoRBrIjME0zXIQ8CYQD31QaUtShv3yef9thIeSZB2cdzHX95Poz/Ftwadj1JLRbZ4bUhf3MxSq9o84TUTU9zy9QGoA/JLP8ePVHZbaq8tQ8DYq4iTHNCvysxK6J3yxWYZn6OTOWMHYmM1p4vLxMCYQCWX5z6tdpdrSHgkyjUyLoMAtXgqzgRh+OBFr52l109DU3TeN8gbGO4LCFwdleMVrCOn21Q1m2MeRz1X7wkkdS6i6SGwJ+ThW2U31qHDn9emKBMt0w+uTITa2mA+y0ACRsCYQCFvIhdbvkrzk2BVa4sdL6u0zbcIWPdtujqV6eruK5es8p/98kBz2o0XQLbwtZoIe1yjgx9BrPXMRNq8fUx71XJ4Vx6WcxzvvHIGpTrJt7ylPm6TrowwMoMQ+C8bqo8V+4=',PUBDER=>'MIHfMA0GCSqGSIb3DQEBAQUAA4HNADCByQKBwQDaRkl2kpUoyYaLfLZWz9lpJpEZqcqNkZMXFN3CvLk3vUDVwRFAGRhDpGfeLzELY/76v4JGJ0TwS5kgreRIhRzaR6yg73XzPcsgUEmvFTmeojAeJR7kUNZzJssfZK7OzFYMQ+PD7Gg9cWtMaBStj+JuZEKxpGLCPLD0HMKxWclAg3aHyKPDgYtenV4uTd7mUHsX8GruklfGqO8z6OfAbF1S3oWBEL4mD/XMvhvq5/7hv1dgRYGWdnMrw5kdf4zBPhUCAwEAAQ=='},
11 {ID=>'key-2048-1',SIZE=>2048,PRI=>'35BAC35A8E3E44462A1F4BF6A61EF45E899456BB9F0ECBB24100AA500875E424EC269B877131B80D1DAFECFC2D740FA108790C9BBD0840B9839E7A32D1985D74E069EE3F9B13BED01CAF208D354DEBB4C71C5517B4642400CDE9DAB8B1E312D3C72FFAF4DC60D4A62F935A23DA8AF0C768410C02727E1830F5BDC50276AECA6FB67BC24AE0D96F3A38503959EB0A2E2F1C326829573697CD27DF9AB4603A7CE5A0579E4EF87F4FEC3D6378171EDB9D4A75C00B70D376B38C14DBE5B06781746ED0DC80220BFE4649EFC47C24F796EEADD723FD590D0E9696A945E5B4DD4944DF1DF57A40273E1821C2FBBAEC6B1D14F9899953E7D97DA6B0A2F6FF319806541',PUB=>'E76B4A62D1D9027F4CCFA5EBD885F6CE2A4FAF82EC863CDACBD381391D7100B8667C7EC17E229CA62FDDB9232B9CE38D31298A71C2B116E93120890A289113DFA94CF746F436460DEC112E821E113EC44981F47E2400691142AB59AEEAA9AB52009A034FCDC1D59602954B7E99262574FB07121833B19380198D3C925DF7F1722BEFBBAA4CDF0C5A44001B0A0FCC47790E55D1F8A08E5D12362A2B3E94224D47DA3886B76FB30A5505BA2B0E50906D7DEE236132D3D30B2357CD02B860C7E87F915B44F25ABB07FDF842F52EC5524ACA10F1B3E0A027D563636AFE3B5B9DF1ED996E3E2D44295EB0EDCE7FF9227DD92FDEC6A8592DB20F76AFCA9D2BAFA87C9B',SIGSHA1=>'t7hzGMLSKGA3Qnp6b5GdCayymGTJQST8Q9q16VF+8nUrSk3D9LeyWkw1WKdXUMpklS831aUPRW8p5ri6Iy5ZvRr1ukjDR4v4cSnn3aVfrP19z+gazVnWGnJlP6cgfu84yxvn0CjLu+8+cqN2Ky7mLrfMQCGTPc+JNnv80DG4mHEr3PqHpZl8zCgBuD3ysejFbdIVbAoo2hnSRmwKjvMXWbACAU78bRqkaMxdEv6aGPfJvtR9BzeHvM+NT9duELHBxKt2hc0XUYgGo6FhnA2ikGpKnw8vTXqTHap8qORfahPy4uhQ4+BVeIAUyt7eGMQpc/qPcFB+uY+3Ul/zrKN7zw==',SIGSHA256=>'xdwP2TFfCitIB8eol5XNbuc+eeWLXumVSAIooBktCQjb3EdzK0WOyd6GJHk8DLT48itK75nJhOh1IYFMlsUoNAKItzSnvSXt2bJVmavA8+MnkIXn9uZXmPAD6vXadocHtZFex7wq0t2xcObnyVI5i9FsW84icOJzwPm4jTELVrmkecZ+mQcFmgTxE7S7iT8a/FUqDa2vIfaD7PVpC5HctmWmMDVwpbBTmwZDwBbrzQm5MS3PbVhhpHDmwH/nBRgWCeCnL+jcZAxV+sWy209I3ZKiO0OuvSlhyl5sF9kk1B0A9Oiyje7xvPqwV6yybf9cWibihdIOBi7gSlHRTX2oiw==',SIGSHA512=>'mAJ6B3krtvDorBPLwTdCjiZgrtzkuqqM0VGWASX1a9BzwQ2WgfaJupbTNru8CSuu7Bef9gR1Gtv+6a5MrjrgE9EaTjF1yJfWr5+azsjyCGcJGtZlhj0GbsMqLUdHagkDpNhAVtnYG+Kug/Qgn4WgMj7Jyiqy0aqEcntbbsT4KtNzFdQyO9CIQss9QCSZYGJ0cKdFr46i0sIe4bIpzzAHG58Q1Ipwq3wtxtwKIoIZlSpAwSsLvm570civoQ3+cJdLOvLpJqLz90kgR3GNioh0XH1KsvXfaWrEJnEXQApoYc/Xeaw7+F6SBZmGwUHC3+EjNDyqg27084ef4rr+Qkh/BQ==',ENC=>'NeTQwFritWcP2UbW8bnMLfIezi2vcjQuMkv/TvRfDS8GvIoYkSDNT6aa2Husiy461c4xmpXlnRMGIYppf6cPOO1P3tXm+3Wvb/6tt2aMi1g5kAOct6Tg348uxpy3H0dXaIhXRyC8YRVaDcV/tVYR4AvZONDD1Xj89jtEopfPySCfpKUTw8WL9hblvCCSaiEDDsB6xVeqjPLsH0NaKFMm7FnriBXwE7OoIl1GXh3XAWz+GrFjXThO0rai5rcIpRrB1uO9r7H1EQI6Bg2fZ0XqbFs+XwtJXQ5MxVMuFFmGEnEaDjUKhmH3tvSu9tY2WIHs25JkeIHjdLaijjqfthPwdA==',PRIDER=>'MIIEpAIBAAKCAQEA52tKYtHZAn9Mz6Xr2IX2zipPr4Lshjzay9OBOR1xALhmfH7BfiKcpi/duSMrnOONMSmKccKxFukxIIkKKJET36lM90b0NkYN7BEugh4RPsRJgfR+JABpEUKrWa7qqatSAJoDT83B1ZYClUt+mSYldPsHEhgzsZOAGY08kl338XIr77uqTN8MWkQAGwoPzEd5DlXR+KCOXRI2Kis+lCJNR9o4hrdvswpVBborDlCQbX3uI2Ey09MLI1fNArhgx+h/kVtE8lq7B/34QvUuxVJKyhDxs+CgJ9VjY2r+O1ud8e2Zbj4tRClesO3Of/kifdkv3saoWS2yD3avyp0rr6h8mwIDAQABAoIBAANbrDWo4+REYqH0v2ph70XomUVrufDsuyQQCqUAh15CTsJpuHcTG4DR2v7PwtdA+hCHkMm70IQLmDnnoy0ZhddOBp7j+bE77QHK8gjTVN67THHFUXtGQkAM3p2rix4xLTxy/69Nxg1KYvk1oj2orwx2hBDAJyfhgw9b3FAnauym+2e8JK4NlvOjhQOVnrCi4vHDJoKVc2l80n35q0YDp85aBXnk74f0/sPWN4Fx7bnUp1wAtw03azjBTb5bBngXRu0NyAIgv+RknvxHwk95burdcj/VkNDpaWqUXltN1JRN8d9XpAJz4YIcL7uuxrHRT5iZlT59l9prCi9v8xmAZUECgYEA/3gLqu2XOb+MmeytV4DDUlLXGykHmEvqDm6sWiojEdWF3dGUTxSAiwNWd7SjNmR3dbfUQvOodYnfFAyny3wLViBrMdN9ymBHnPblxBmu3W5YF5JUC7MOp9Zh+Ae8ZUaDjjU/Dno7UDvcLx1YGHSjAsYorb2FQkHBPrtYfq8MqeECgYEA5+ZyPcWAFQhrT89vwi+iadr2+AbKwzTlZscHCRvzb6rn6r9BbnG2AtqN3wzXTKP6CVZDs91ZCU309EZYgRNm+5b48PU0Jv5A40PIutOMK91fuCM2zWVfAYrwi4n7UNxEClZ4KUMYVHL/XB92rLx9q17T2+aJYyYIMJg/9HxNjfsCgYEA9OK4HINf4SVyu+IaT7TIhtOOCyULeLvcgzUn1c5qi5/okLdjuWJnzdnHOzxW777inF85A2zZ4MHmqytudSpVG5w75SlcfXBJdXdezNnpu60YmI/WLNjZhZ2Fj+Kqf1JWrSzxYwlcbg7Tg/5XAipcUD5vpAv1/4tUmLOxos5eD0ECgYAvJmbB8n8ZR63x+z5A4EiId1HRmiftyrp9zCe9DWbQpJIk46AdIZedOuyvlj/MQGbdMSHw1yd8QdJ1PDxQei5tJwQUkfZ5myZ8TtLoUYzlekw090v0NRE9Eg/Yf0SO60oWRACIezDeMseC5o7NjkGK72vqARScCSaPItWWExP9swKBgQDiwDNbc8hYyMdCtUquETEHULXi4UNaJEGAbd6c2rKmJF4Spc1jul38RGQvuJ6AkYXF18ICYgkod414TNr6Gdj/OU6kJ4EK8hOaSm3xBTWNu8ScG527Tiado9B2YIhHj2CKmPzNcMuChUFPFWy4ju5hurT7vU4gyWOOqdSth0d2sA==',PUBDER=>'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA52tKYtHZAn9Mz6Xr2IX2zipPr4Lshjzay9OBOR1xALhmfH7BfiKcpi/duSMrnOONMSmKccKxFukxIIkKKJET36lM90b0NkYN7BEugh4RPsRJgfR+JABpEUKrWa7qqatSAJoDT83B1ZYClUt+mSYldPsHEhgzsZOAGY08kl338XIr77uqTN8MWkQAGwoPzEd5DlXR+KCOXRI2Kis+lCJNR9o4hrdvswpVBborDlCQbX3uI2Ey09MLI1fNArhgx+h/kVtE8lq7B/34QvUuxVJKyhDxs+CgJ9VjY2r+O1ud8e2Zbj4tRClesO3Of/kifdkv3saoWS2yD3avyp0rr6h8mwIDAQAB'},
12 {ID=>'key-3072-1',SIZE=>3072,PRI=>'466B5E488E856F7999E3967AAF101A0E42F5BC5316758D3441CABBA36AEDF240BF7C17DF094B589439DFA688AB3B925D18CDBB18565A70EB85A5DB409DE3496081D14E883B6E96EB012916A2A2F42E67AF6884751384D09790E1C2D7CDE5AE24B16616D66517A71AB641838F5477D8B0D042DD35BA6E7A871A99303B2F0148E7D2C6CF0EAAFC144424A33874235E64F3231D2CC72E0E7C66F0F0525DCC001ACA7F4B3FDF3A93876CCC147E60B89BBB7AFE6E6138519109E1B2A0717D9A478EEC2182E93135A80DFB15AB3FA7DA6312B2AF2884F099E0190A3BE57B70DD604F82C581A36557AC062C5850DA0CC7C4EC32E576D04EF5B52FB1CC1557CA6C889BC6DA3F09F64BA12C856C891C850940BFA6CBF397830D6A3A23FBD5C0A16ECC270E341C3F2682CAC83A1AF059DB8336C68FE589E014D82F66705A247D31B07D3B19FDD46F6AF6CADD9B2BC99A044D7580CD1EDA0E8FFAEBE1FF49954CD17FA49DCF9E7A4BBCC9F3CF7E02A6686B7F42EA2CBC91557E265C2ACB52794129C68FA469',PUB=>'C1303847E4A1735F0E8DFE75B3C0717D1F73BD02CE2A694630F65C29437928DE50EAA2BA323DE544E644DDEA43D61860390A6784FE42F7F92052FF022A8ADA5F840DD95FAF50CB1C6E55D5B5F7C758DE46268E38B047E2BA3316780F5A83B3F0B13BBED9BB49BD903391A46D9B1BCCB2A0D8DE8F9D74AD88BD8D426F1384EF11CBD7156A87CDD70B821952CC246B6149A1C3CB8982460BD3178920CDBBEDF0E008CE57BFE67B6879DC12546481E2B3E96E40A871F6FDD195CEBFEDCDE8EDFFB98F3670F03063D37385C703EA7B3A708480237E39072561CA43B62541CCF52C03E964AF3E4D47CE894A0CB5390241689257700F9C7E7E6ECE66C7187217A762668E0606C2D8C59920BDC33AC8B72D59C77BA2AA325CA6598E70F9BED4EE07238FB67A34B7D64A6AD917F073A13C0724DFDFBD97881C0C646F018A3D1D8BBCFCB0B133FC4EECB15953DCCD62CD79817134C1D2212DE38736ED10C79BAB9AED2858EADA6705D6D1BD87A0D4976B75FAC33EEDCFBA2DB166D30BA8E8641D2BA8E19F',SIGSHA1=>'Y0wFAn1lm1ULtbLwJkWenpKDeyoawgxBL/KkBteZugp67v2+zAQJ1HnO2GGum0vG23pj6BU0evECZMddiH26robWkli2WtTIZFUnfemCSyVcMrjsp9R7xP7uvX36UuZOX3iPgFyRPen8vypQTDcD0HWva04ohcPq/LgD8Wsiy5NF/ksOxyCuLnn3G68jsgyIH1q4V3FOng4MDyw7O4YQF2VqjaOrskmjqooZU4G4JyrW04Lm+8h1kWyJOzuHzizxjMl08kV8zXxRMbKU3rk5zVDk6bf+12Ek5Op7CMaZ4Ca894nYSxm+5JLvzBJAdbpbV1Q0LI/rIYciSrXS2FipamTPzUw1uNuHWDii2aJ/OC8+ONzPgEnPTUDYofwplBXJxhyU1Vinzo4DJDFwEoPUMyNMCvxulyPM3QwXHj0/mzaOBGoBx7YyIJ17VOe0VXvG+WdYuHoq+p/cm9uU7XEsS1KSM6XNfBxCO1gmceJfHh0Y5ELDZzMTUvEjk5ozoMxm',SIGSHA256=>'BRcb9ZwKXtN+TkUnEDD+MEEJjY4iLS6eP5CLXbye0m59xOLlssKRswrm7Y020ySAHgpD4YxCLM7lkrNSmkVj/FFjo2M/ztUcz9nfp5FUPut9nhB3HToUJZX38eDaCTZAyYh5v3lL2UGpleiRAD59lEcSqnz1DrDUUyQXFRtDzGxNbmsz8wpAJAkLjfCtW872ZsiRFoB2WZk9GwHBuTyCIIe1Nbx9yF4qqLVU7hIwTsHfQcRkhcrRLlRz6z1+4i0CR9NyYZ/Hi9SZUGENg7z/eo+AQWP20G4ASlb7jlMfMAi723fKi0NK+NWYdqkVaLUyrBZcCU9qnztGbw+qv0botWrFemqY5ou6lVm1BNTTnhgBMseFFgN0SgG92t4rt/ZQY1JRGAEe7Mbiu8nqrSdF5hofF12EG7UADoxSFrfVpsN+wXcWswP3J9uMMSGPWKsIL+SThVx/RZAigs4YNFuDAKjW5hGlWmhn47uMm1W730S+CfEhataLdx+oIMMdwtmE',SIGSHA512=>'JE2fRi/inFlPZkc1dOQ/B4sE4S+wUKaTZhGW7QZ3LSC9mWk066l+1a9tXYPoIaHprHU+MRbbmlUZrJNs2Rc8BcG6XUjEoxayroturrqMkxpkb9/gKp2A3NBf27nW2bo0MPd9okyQhZ5FosY0VHX1oRJMUBWmvTScIsw9GbQN/8+xNmSaHiioHWFzbnITdW8S0aCwXZnCtoc+A7awMNV5gfNFP1jKk8NfYNfWH4S5pXulX33fQM2sDYN71Yfl511Wtn+YUfudUNnfGLAG2ExWsrkKlOoKF+8zyqTbUmGS7XqTtz/5zsoiWkwOcBvoSptWBkFklcyKk3sursTWPSATyXLBwa3R03DrAnlhgzaz6KlrXtVlC2Ww6TIosMawbEyMGk8/lPDaqlA4p20PREZcSGorOw+D0V+tXjIil7RZz8+V8s6TvTtSHh2JPpoZMH/azeFrad4iqMQ6MkiE8/ej0oM14VX5mIKn/98M2UfXBT3tVLhTgLnVPJyJlaWauwtF',ENC=>'vFJ5b7Bxh/Zpi59tSghhJyoYH0yO5IiKwDhNeGVDWPw/567mRYF4Jv3xhEnO16gUQQeuDGnmkoh6yuKPxIHrRsGbYtaV6PBp+4v6b/HnI+UPf55Agvv/5U4Tw/+SPFM8ax11diMTcNlTIm7WZ2gStm7EnLZQXFdW5L7mIqrF8Wxl2Xy6XYNRtRU4c7PiBpSM2D1GeXUwcjNTh1dwZB3fbTjwhgL6rc499mFy+ysbt3TI1JqyGpLG3mfRy/yjSS+KBv70nV5LuShctBy21MbEOjl62CcmrzptFCYfxZsobb/liMgO/o/NstcwczbnY96wmYhP32+7JD6AFUPT5ScNPMT+3AmIpXPE+IJ9ps062Ygq6ONeuJn4tGifwQq4euBn9aJBqTio+qMcYbt1TS1JwtjqtWNqHX1GgPzAZCtwSfXrAgWRfOxFO/OAQAq41wb3qneevY85JKqCPSKAu/tZUBPm9WQh8GkES46gNGoZ2bjh/9bjufT+gOpae0K8zsTW',PRIDER=>'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',PUBDER=>'MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAwTA4R+Shc18Ojf51s8BxfR9zvQLOKmlGMPZcKUN5KN5Q6qK6Mj3lROZE3epD1hhgOQpnhP5C9/kgUv8CKoraX4QN2V+vUMscblXVtffHWN5GJo44sEfiujMWeA9ag7PwsTu+2btJvZAzkaRtmxvMsqDY3o+ddK2IvY1CbxOE7xHL1xVqh83XC4IZUswka2FJocPLiYJGC9MXiSDNu+3w4AjOV7/me2h53BJUZIHis+luQKhx9v3Rlc6/7c3o7f+5jzZw8DBj03OFxwPqezpwhIAjfjkHJWHKQ7YlQcz1LAPpZK8+TUfOiUoMtTkCQWiSV3APnH5+bs5mxxhyF6diZo4GBsLYxZkgvcM6yLctWcd7oqoyXKZZjnD5vtTuByOPtno0t9ZKatkX8HOhPAck39+9l4gcDGRvAYo9HYu8/LCxM/xO7LFZU9zNYs15gXE0wdIhLeOHNu0Qx5urmu0oWOraZwXW0b2HoNSXa3X6wz7tz7otsWbTC6joZB0rqOGfAgMBAAE='},
13 {ID=>'key-4096-1',SIZE=>4096,PRI=>'EEC3B4C4E7B954BE456C4D61D9F5B161991EDAA62ED6D101F903DC834F3FF6702C6AE015BD67B8EC423B69DD2DEA2CC57CAD50ED37AD756BE2235704F5FD5954687C00F85DB70A77FDE4966C82AAB569A8E646925AA2E3FE0C5370016D98EFEE0D6355B0E63D7FBD37F353D8CEC11193FE96D5F1CB35182DBFD2BBEE8C820382AFAF0D72912F1B8CDA6CCD3FC04E02304CAF8A007C9997F8819F020EFE3AB536534900905D0CD3CA3E0ED84241377D390390BCCC4CA25E1A18B8B6C2665183C388D08D05F60A7AB91481E4E8CA48C22BAEC25534FA2B2AA380F49CCE1B389688D5E2C7FB747EEEBDFADFBA9D1CE9BABD96EC07056DCCF72D4569649DC442BD7B31B964A612F5C64926D1834A428DF1613738CFA552411B06FDB5515C4D0491CB95CA60558E37F0C6F7FFB9B1712F9557DFEF310C78A5E1838514A138A0B25BB3EB52E833F4D38CF69991BC06C3F64AC6C077213C3D7BEFD8F8A3483466FA340FCA5CE0523C155583A62CB80AE41227D072F6B6BE575C342681C35222A9C6186ED047316193ADAFDEBF9BA0960399B4A8DC67B76AF0CA428DB00586F9DCED8C59A4FE6C103575B98CFE86E2ED172F2BA03E177DAA606228B02C08291C03DEFBB7EBC80479D996BF2761C35FFAE68FFE6207E4E7C33017B25E9A63DCCB40BFD9A4757ADA2B4A648BB29E2E7F2248B83BFB94B2B738626C4C7EAA0C89289C8A061',PUB=>'D2F4DB95A2573C457257888D7FBFFBE237A9D087361AF26417E00BF3C820EE465C33498E20AE763D634FE3CFEE22541952C8D3B1D6910D8FA7423D8B3308012A6A4CC9D820697F9C30E9C2E00F199841B4BC21FD76CBDE19204F0FF9B257597B055C72ED6E99A4899460C9437CE2F496411628ABF5882F2AEEFE706EB0A6994E96CFD697300C14F83C0EB70ADEB1D12AE6EDF7549EAE90F5B4FB5FCCC1BECC0AA1AE90527D8F850CA6D9DD617EFC04CE4E011B0C2E5332CA4B6290E165E4FA1BDFD221DF5200D4B8443C0E81282679E2CAB4B18EBDD8CF74FEFA94A96332C0D54D7563F1305A762901A610C6A7024A59F58A985B67E08AB15ADC243FC1294F844C37E10A5411AE8A2556778D93F3458F625B9642FA758DC7C44FFA1B412DB8CB19CF7803CF751DE47B4E7445F2A1386C4826AADAF6B34789995059D62B11B3303FD0928E80542BCB567CA88F838C22E77E1103D684E40F4E413A09BA85BACE459476B493DBF0879F626460FF6C465D9F192F3747C8BB96AE30980EB6F118FC2F106BD5666F85944097202C003DEC82F4D198EB3236134FE0D7F063EAF94F2F539585F4313318E5C340167E44C7A76FFAA0ED5BB737D6F86AD29E883E3134996DA5798452279685CD58288C52143150C802811FF6647889122E95A10D4E90976D8888C59C23BB88B18EB1225A2D09E61B13E7BF736B26A22EA794EB9FC4A1142F',SIGSHA1=>'W8K38ZGrWFFlBB6Btk/hIuDwaUKGGgNuHxClV+mJuElAErXPyCfav/ypw5jzjMgZn2X/6pAepJEN4PmEP4Jv3V/p0TmtGp5edgY9krTk5TbRxKSN1lMYV5qGO5W4wRDUTfKDdh40BALPBIPTR/MPR6CZpKAN0tIIzERb1qkMcPUUw3R5JpgE7SXqf576TD0YfGCShy8QQ5Mj6QtZMSCp3uYsc71Xt2qXXwWeRpKyMvyE3XtAUgJIFJuGTOqknsQx/l99cHtwEC+S57YiNBxuzkjSJqCDKytfdVJzgfk4CCd8Io12KaNNQ1wS8UafLsbg5TWm/inpQa+pPKhJdPdSQyxrhbcXJtPGv0jaZq/6KTm9AN245IrJ2sCPLRII2m8ryB2BcSdIb0bSAtHsLdUvr2NIPUQpM+ZDmOZ69FHR8W6N5VAuNkvNHK5bt1cXV9RIIlATIiV8oicTnzrzx7+yaWRzxJUUbjLO1/EaQN8Jcu1gPVf2T+PdpUJTuSR9XXbbE9tQ29D5WUDoZuDkRbume9jB6tdokR3jmkYkHOziJYlj35EyLjhO/HFRwblwJd9rtQxgcMos150W7PTLgPqzQn0KabBGocFxxrhA+Rg8iD8UJf5dIplbP7kx3VK7hhGcD90yWOP71zsRkgnJAeuHEplU2uE2/uf31jklHAmxT2I=',SIGSHA256=>'e7DiidRieshIZnUF/NL9cVVGA1TxdzXGrhyC6GTKTUuRaNUctdyKn+WwY3PJRmhGiqzxPUNuPSGbX9/gSt7IQ64huFOhANgYaDkq3vDrtHLhsSPXHJ7O91gv5HZSOkxbcEQR9ojLDMe0wZlHUcMi26q/Aiw9sJpsh2yj300zFHg6KlGo1PJXBbYt7g+gJCUr8kWjSUL7ogD1+r8OCRsCQuHIVKJTRWVtYBR8bi3h7+LMOyzxpFgBWkbJuxQx2JLXG3Exvh+Jhe+0oAITbvIwRDsFDgU3TXRV9ZQGefT8AyY4PcIn9hO48ifzP0kai/ycLoj03XADCrbKGmOx55/0j09N8nZ9KkqsaTUqNB9mL9MR4Phn/UfBDXBXapoS3NbI111JZQXvQTm51DlKQ0FcNDj3f67BJg0RHGMPsvM2Nsmze9NMPdu+YGw2X6R91VFgi9PxEtENz4pB1pL5nrGuh3MnEo2XtKMxcvOhVK/3VVNolM4KbC0PEO7zjjbLURvIaFermqN1E2LOYy9jEBFTuBRymq6uwTAPCrwa/BkaZrA8lgaLCqzqDfMu9oZ//6q3FRxLL4G+0OOqSZL1sehQCsf4CyBf8XJRE9+4K1bETUlQLE0UNDQfxER6ba9k6aNap/o7cmQEgNgLKjU1KF8vtV8jSEVvQ8v/S3bGtHHhh1M=',SIGSHA512=>'gZbJf94FaaOwF1ww2p8FOxe/ki+WY0AEzZND91IHWZW4nw++y0EfkNCGvdi5V8xeFeCYGGglU099S8Y7vISVsHBM5x6ZdltNicYgZchALus+IY3N5VptEUlqjI1R6h8niSPcSzS8cycAZGcQ7cCdamx3qTuO2BxPvY8zgbJpXRdwyNbBA+5VbYvaTgKfMRppjZ9zvTiru20eJezdR9FOwueoSLfihj7NCdWmVY+hzHjDkJpeQSw1cNL9Z7wkDMDd7TlGPYIiCzZsjefvMdbv1/o2ymCpvkixAdljxSnVskqKMYYXGFj9Uw3LJdr9IrCjJ6eUiQ9CQeBfJFPUmlWAEXFicirWv7BRih1j0STq4Kxar7hICmlSLX17gP90grU+cVTy7avWq7Pq2+iF/kgxwR8MLHFM8sGuPgMycwE4ydjPIRax91afDZHzXhHHEMJ+270KbohPS9aux8NVucYNdeWx4EzqvUnARXgIH7IkbkrZkN5s6DJsJFOIVx4SsF/Z1MAmfp1o3iEO4d4G2XIy0cVAQ3YcR1cyOaeTxEcwQ+GV4+sR80PAz67IazlPikq5k7Mbx2D0mEmM4X5msizGGEDXTZfgGiap2TOAieA3N/CiWykqi3fYqnKm+DfUH1Zt8YOFYYH2gHSUsSEd5exK5HDT2GyidifdARB+E5JsiYc=',ENC=>'P22VZFyf3iviOmd1fUiwaCZMxKK008+clrRw05t3qTNEOdY1jBO3NTDjxNXxgUTx4Ov+hVj+0M0nslOdchR9VmQKJjJ73gMz89RAy4Ns0aS5lncik3+CHm+xzredcxFe7Gj7uxy1Ta4+EUM4vCzCRzDriXiWClgvCvM/vZRBMBM/2HslhLuuQ4jxqb0vJBugMawXsaV3ATNsstVKLiJsemIfRsXYbJkrsm7kC9XNMwRYxK3OUAteX62XPtprOjnNBx5F03cqgyJJ53OwOSqj8d6wJQBTgWWysiOHtn9NApdw6tFZwb7RKOYK0KEPA3yNn/qZnYG+X6m9mtnbgRQQPXeu3knJmzkoYtETPv+41t7WekX6vv/tAVYE+b1hGXow/+YLg0lp01T3rObHvFxNsRFCuzWr0pxM3S467KshF3UubrGCKAJXvzoTwC8/jsf+5lvU/6O+vrJ5+uBRS/V/MewrvUPJr8hABKGtbQFY5ynqIaZ62vho6cSx3LFGsEXNklghvzAp4SyXzjnzZzRi40wrvQJ8hp2zxbR7HIG888I9QnZd7bKoDkMQGMcSZdfxwdz8LKmiw6gBf9WjB5btbY8jeIdsJl3alt/wz9XZ+YtJ6khOytF6aWwy1rduKCqOdvum40YbBbvfzxMETVhBfzjp2b7yjEEwjRtClXJiV/Y=',PRIDER=>'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',PUBDER=>'MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0vTblaJXPEVyV4iNf7/74jep0Ic2GvJkF+AL88gg7kZcM0mOIK52PWNP48/uIlQZUsjTsdaRDY+nQj2LMwgBKmpMydggaX+cMOnC4A8ZmEG0vCH9dsveGSBPD/myV1l7BVxy7W6ZpImUYMlDfOL0lkEWKKv1iC8q7v5wbrCmmU6Wz9aXMAwU+DwOtwresdEq5u33VJ6ukPW0+1/Mwb7MCqGukFJ9j4UMptndYX78BM5OARsMLlMyyktikOFl5Pob39Ih31IA1LhEPA6BKCZ54sq0sY692M90/vqUqWMywNVNdWPxMFp2KQGmEManAkpZ9YqYW2fgirFa3CQ/wSlPhEw34QpUEa6KJVZ3jZPzRY9iW5ZC+nWNx8RP+htBLbjLGc94A891HeR7TnRF8qE4bEgmqtr2s0eJmVBZ1isRszA/0JKOgFQry1Z8qI+DjCLnfhED1oTkD05BOgm6hbrORZR2tJPb8IefYmRg/2xGXZ8ZLzdHyLuWrjCYDrbxGPwvEGvVZm+FlECXICwAPeyC9NGY6zI2E0/g1/Bj6vlPL1OVhfQxMxjlw0AWfkTHp2/6oO1btzfW+GrSnog+MTSZbaV5hFInloXNWCiMUhQxUMgCgR/2ZHiJEi6VoQ1OkJdtiIjFnCO7iLGOsSJaLQnmGxPnv3NrJqIup5Trn8ShFC8CAwEAAQ=='},
14 {ID=>'key-512-2',SIZE=>512,PRI=>'789F2924364C2D28482AD386B9061370FAD795C0E446796E5BF321BE61D668019D13900FC8355D8C61965A5267DA4F50D3FB790F64038C002C1DB1501FCD6E81',PUB=>'AA1000B937AB6D662256A382269F1318117E842D58D6FDC1F3A0BBC8C551A0C0B1D256F68DE56F54BCC623B875CE0E3E0EF35CD6E13E83B93B0605D0379DA303',SIGSHA1=>'ibYmYqh21vATqib8SSBsHJR6sMBn5Cl4n07PMVK74ahVuIvql2bQK4DuGIgoccdlKjdmCoAYNcozOwMP1bx0Xg==',SIGSHA256=>'BtACjhTzcNBa8BNg+jCajWXJ/knWvgyR86dNft8UOVh1OUNrKCaNewHiLG9j3xOWy9HI6V7RNTxDsFXbEbVeJw==',SIGSHA512=>'',ENC=>'K+5L09f3pg+I9SlOJjuXAtaBu9qjhy66ycPWwT0lc68kOOVXu/NfIW2iyQYz4VNz5QSmVwSHGOGMKeTYH3KFqg==',PRIDER=>'MIIBPAIBAAJBAKoQALk3q21mIlajgiafExgRfoQtWNb9wfOgu8jFUaDAsdJW9o3lb1S8xiO4dc4OPg7zXNbhPoO5OwYF0DedowMCAwEAAQJAeJ8pJDZMLShIKtOGuQYTcPrXlcDkRnluW/MhvmHWaAGdE5APyDVdjGGWWlJn2k9Q0/t5D2QDjAAsHbFQH81ugQIhANSrAlK+4beidJa6qQC6TZInhqL9RpDnCejH/gF5P0MRAiEAzLalRRqn9O16mD9Po1s4NMCm4IRvEQHYDWnFu3vrnNMCIQDPd1y22Fxexu8yNDq26QjPshuYWblDlwCFxMS5L01V4QIhALWwbWK109fIZgR2PIJp1arMSc/++myHzG+rLvnFdEpNAiEAoMhrIdV2AMHbElFURodgoryK4oM6rCL3v72BRaoBSpc=',PUBDER=>'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoQALk3q21mIlajgiafExgRfoQtWNb9wfOgu8jFUaDAsdJW9o3lb1S8xiO4dc4OPg7zXNbhPoO5OwYF0DedowMCAwEAAQ=='},
15 {ID=>'key-1024-2',SIZE=>1024,PRI=>'18CC62F2E1C55DCF866B1562C7095A74254C57641BE1A96189BED388DC590DFAC537F974A853168ACBB027CF23B944B0BE9AA79393E46F6EE8646C4BC9A48A215E65DA88DDEFAF62AAFED173BAFB83FE3B3781A235F43E68279B5F3727A5C554390915C1CD43D4E560C476C50BCC08D6666DCBC603ED6823DB3CE09A319AB371',PUB=>'A9A9FDE558F97E9EE9EA223456CE84A66FFDC604BCD5683BBBEA034089BD32288C1CEF429EAFDFDF8FD5555082A4B0F9614A4622089B1838DDCCF930D33E8108683CDD02436ECE7D3E99404E14187F3DC2D751503F9D90FE2F15BCC4AF43C34F48626AEAB25D66A2D771344E8FD6D3FBFD035BA8D2DEF9D145B753611FDA5339',SIGSHA1=>'bH2k4H+NffHp0STfAQJO3c/Awr7mrE5mz7yiw4PYEvu6A270aA8OJbSxq8t0Im5ZyclN6k4xD8+T5+tO522WEbHvDhW+1AfrLKf47YiPJb8pvjnFmiE6VE6mFP0iv4u3JB6Eive4hhIMdoZ10UcY0mJU9jRa44Ajv0XbQWaDg0E=',SIGSHA256=>'VfLiyb3unwX5mBlrAPmeR9V9kGFx7Ft6JwKX6HwnpxbGYb6C0CPTHbZOao9LxSuO4lkyAhtxUIGQ8hhL28xW+dWIuhy2Wx+vPFiogerY4YFzkPPytsjoArnCzVywO+7Djav9a+pmMZqTWNr/i4/NHq7F1svq32tuwOrRbzLOHnM=',SIGSHA512=>'FIivdhZjOVyTXJTODj1Ie1I3Oli86KUR7zxsPcR8VedTWvLbsNiO4kvOShMT753vJ6x0h1MAwTjZ7eyrc/EmQJkG6qDtiryJHEgoXxC5+qXyK4OUDPlQ6nBN6iSxAkTR2E2BSMgrfgpXQvtGCskpaI1Zru6qOZIwIwdRq8aOEx4=',ENC=>'K1dLGpiOcq5eJqNOqDvkwpaVnwzyqjIJIBLr9897vaEkVtMdw/upZvhGFuuWyWNtop3lSTNHYuvZDmntTCjjlEXnnFYUQUnMY5nE50yNqXlb7kmnmjYwaItf61cRQE5hbs0/jyJ13PiUZiqiCyXTuIy6BuJZaoJq55L3XHteS1c=',PRIDER=>'MIICXQIBAAKBgQCpqf3lWPl+nunqIjRWzoSmb/3GBLzVaDu76gNAib0yKIwc70Ker9/fj9VVUIKksPlhSkYiCJsYON3M+TDTPoEIaDzdAkNuzn0+mUBOFBh/PcLXUVA/nZD+LxW8xK9Dw09IYmrqsl1motdxNE6P1tP7/QNbqNLe+dFFt1NhH9pTOQIDAQABAoGAGMxi8uHFXc+GaxVixwladCVMV2Qb4alhib7TiNxZDfrFN/l0qFMWisuwJ88juUSwvpqnk5Pkb27oZGxLyaSKIV5l2ojd769iqv7Rc7r7g/47N4GiNfQ+aCebXzcnpcVUOQkVwc1D1OVgxHbFC8wI1mZty8YD7Wgj2zzgmjGas3ECQQDeWf5NYH0zlMFUIaQr6Q5FC478PpEwt7VNWecWYCwXjWHF7W5D58G0919ww+2vNCvyzzAULkGOCM4/roneCkYdAkEAw1bb2r5Qyppjae9fTjccr/AUmLDyiQ+UWmkLhJg9umcoxkRgowLNVP1kHcdWd5GjADrmSZSD3riHRN7VHRGGzQJBALhj0OvB9JHt7lUigM6ZOmgvqaetCyJndkZrI6P+pRHzAP3uY96UNqMn8VHGaTk9/qQhBTH3Gg37Z26QA2zLAFECQBOtilRM28KtLtqbHJS6hI9MtiZznNsl0KIS9vASjhVbEwZ2GO4S+DBZnl5JmHJPH4aEaHJ9HZOwLyBG+l0FSPkCQQCdcD3XJzzYFxZ8C5NVmOAa6wnzI+ma73m0fkAxR1/0sCCHGSUb8f9flK77cCwQOgha94pxqVijw8Y4M1sEVY+9',PUBDER=>'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCpqf3lWPl+nunqIjRWzoSmb/3GBLzVaDu76gNAib0yKIwc70Ker9/fj9VVUIKksPlhSkYiCJsYON3M+TDTPoEIaDzdAkNuzn0+mUBOFBh/PcLXUVA/nZD+LxW8xK9Dw09IYmrqsl1motdxNE6P1tP7/QNbqNLe+dFFt1NhH9pTOQIDAQAB'},
16 {ID=>'key-1536-2',SIZE=>1536,PRI=>'A1011F8D52219AA702B569684D1EAB62F4100412D2FF4C548E65AEACEC31B0FD6E34B9083F0F065AE440139269198EE02A6F08138DD96E10F0F2DB1A2B5AF18165A16DFC5BD4881F4868A3A53C6616ACF9FD3C88202271CF3C7D97D97EADDFD30EC1668715AB1A98DE64641435EEC73CF91514D29505CF5C9A09FEA7EDA9698616941C04B58CFC01D5D84249DB23A5EB575D6BBCA51A89D3E1553923C5213C74029A56F75BF015AC198E2F34E0F61B7AAAD4162B4C5CA41487D0C548A05BE5E1',PUB=>'C0A60530AC3838B9BF7BB0F1A74D888ACB4F8CFF575FF638B2B42CE1BEBEDEA9577CB720F5FE91298908D79C396A0F7CF30A4691D10F4AECB85B70DA18BD55D0956DDAA2BC582FF41CADC6D1942DC80A194972CC40E2D33B503EE99DF3F4FFFE106799AAA54A0A0E64A9E12DBEB2F833A97B8F1577E9D09F30092CBA6AC69C8AFE3D36178907E7FCC58E1DCDD09F3E5E36EB34B71B59231915B8A56EFA0A186B80F05A837BF9994393DD1F29064A1534545CAD17D32100FE5F7056E69FE48997',SIGSHA1=>'gGCMUK24og7Yh1WZff6+2v6aNiqz+/4xLvrqoVlt+ClbXIvIaeIx7zSe1thiZHk6JpPQrt/iY7AaPkNLI5oe7bZJTAMPWXNJiItWxf5UHfPTnOjal736SUyt4lSbbEYZpWzLWfnWIl5ZoiX05r/vif9ax/tiZMo1NiSzfeFNVal4OhfJ5f1Cr402I0Pv7K7mEgQcv1+g1Ws5LzzkCrjA3dr+/X5xXo4fOQc1DC92m2L+TZj5P2qXSAQMM8dQPd3t',SIGSHA256=>'YtvZL6+shM4NMl3I0leTOyNe2PAHCesST8dEYbIEZOFEeBRsSaAl7q+skJTljC8VpTTOmdFQ8VFc+gbdgyAOjsK3K3hmKu48JCBjS5GVMVFfiSRnAXNvuV0yw4NAj0OHZGYAEOenQ0MrKdNMDsn8xpiNIDYo+CLzYxLqDlWe9cbdFGI/Ux5HDhNeakjx5pwAj4KGXTrD8Rvn0qsk86Kcv4looH+IwJBGYftx9CK5em5SV5KFuSem9RagMtpTxHzs',SIGSHA512=>'P/nGEs4oMvEJr0MDAKfqHXZw1UiDd+HBfeycr95WZBTv9k/egT236S8MopR1pgerC4Ymp0iXFCDF8yWGHDIN/KbDGxjO3uDeaorO20Xskl/TwRdm3GBNT9jsmVKf+QqOfQ9JUSvfi/FTPt1cmOkux/JakIwczr7EetIJ2ZdQGGG+WQhHAWI+yLHJf4ZVgBuYA6bIEjsTINlmD6ns6bOTuTlC5kGKgYtBa9dtdFeVlSGqD4obaRJWyA42ufrkM9uT',ENC=>'OZti7pHvJbHuCMk//MUuCFgfcJi7TwytEFw4SMHr+osnMeKGf2JFpHFHvVZMBcJyUrkRntSRsnl/AKWf0cF4txqZheWIJpP/ZAZ8LM3cLTRWNWDWr7VM7NSD1WDhI5+u9LQXm1OFMYrJgcyUI9bqeru2tsDeCGdf8ZEE+Y1pobP6Kdr4o3dClXOmcDe/o0x1r4dQwR1xmaV3JY85MeTzZr0z9zHn3kJ4Q6/Nku9k7D+RnJcHQjfqfvt4gEhuMcYO',PRIDER=>'MIIDfwIBAAKBwQDApgUwrDg4ub97sPGnTYiKy0+M/1df9jiytCzhvr7eqVd8tyD1/pEpiQjXnDlqD3zzCkaR0Q9K7LhbcNoYvVXQlW3aorxYL/QcrcbRlC3IChlJcsxA4tM7UD7pnfP0//4QZ5mqpUoKDmSp4S2+svgzqXuPFXfp0J8wCSy6asaciv49NheJB+f8xY4dzdCfPl426zS3G1kjGRW4pW76ChhrgPBag3v5mUOT3R8pBkoVNFRcrRfTIQD+X3BW5p/kiZcCAwEAAQKBwQChAR+NUiGapwK1aWhNHqti9BAEEtL/TFSOZa6s7DGw/W40uQg/DwZa5EATkmkZjuAqbwgTjdluEPDy2xorWvGBZaFt/FvUiB9IaKOlPGYWrPn9PIggInHPPH2X2X6t39MOwWaHFasamN5kZBQ17sc8+RUU0pUFz1yaCf6n7alphhaUHAS1jPwB1dhCSdsjpetXXWu8pRqJ0+FVOSPFITx0AppW91vwFawZji804PYbeqrUFitMXKQUh9DFSKBb5eECYQDgdVdXXLPlsuAFxJmRrZRlvflwg3GtNO33rDRRu9UBiwDyYGi95ir2AoGwXRovVYLEmv7LZzlH3xljKjGmRriD+vsiBv6R6QH96zI449JhB7sGKDPpAbw68BxmKMGTefMCYQDbuFpA557VkvI6sZ40v0HCvQo3EDYrr9D1egBiC3/1TW0s+/e8mOqEvlPTYMIwkEzsX7arEZaF2cgXz71J3lOPNZL8dxeI7AG5kX1ZDdURZ+2kg0kL3j4yHSK1o1mrFs0CYQCKtll8ptCSMmIZjm7tRV1BJw8hBkpZJS2u8t/+ZtrzMikqoIP6X2TLVa86A79r4yeGQtcVcrxGe0xgKTI3tNrQzWknlTT7jQjrF8+YsspPpoxg+LVj2OuvbLXQOH2wmxsCYQDJ5PApy6tLnKcv/53b4hJPGt2UEzVzly5vIhfP/7kocmjreOv/RJPaPflQtgw6C55jZN+4+YRSofcWyjCo+73UTeouSlA55IMBPQrtFaS/Rbw7+tbYLPMBoXwPY3Y1m9ECYQC4ooeHvm1nQik3Z9q6xYG4j0hUDKtBrjG0iw1PNRhedSxx6fWAo4Shqs4KSovgp4GNsRId53BmhCI5Y8te5MEPE7vjOC0gQoXb1AKg9rhhhDV24WvLeaRqmTh2C+KQmNY=',PUBDER=>'MIHfMA0GCSqGSIb3DQEBAQUAA4HNADCByQKBwQDApgUwrDg4ub97sPGnTYiKy0+M/1df9jiytCzhvr7eqVd8tyD1/pEpiQjXnDlqD3zzCkaR0Q9K7LhbcNoYvVXQlW3aorxYL/QcrcbRlC3IChlJcsxA4tM7UD7pnfP0//4QZ5mqpUoKDmSp4S2+svgzqXuPFXfp0J8wCSy6asaciv49NheJB+f8xY4dzdCfPl426zS3G1kjGRW4pW76ChhrgPBag3v5mUOT3R8pBkoVNFRcrRfTIQD+X3BW5p/kiZcCAwEAAQ=='},
17 {ID=>'key-2048-2',SIZE=>2048,PRI=>'B8BDB1741EEE884CA03C44930982108B007CBD28FAC7F6210DE0C90B51CF23AD817C7733C67D24832B83F646A88E19078F767977DB9191C933114E53B607E932CFB1A43F524E28201EEB5ADBFFDA3D80B63B31D97B5984644AC373BE6827EC011FC450000569492008C23B686B4B32F8A88F6765FF27A9E3E572BD7D78F72D3B604B608F89DCDC9F4D0563D59F85E1F09666544BF71461EC558A87011DCC656A5CB973C1E59E33EDD030BB77F4645CD3F83E06EEFC1D395F4F74703B71324565A81C6ECCE33DDF5BBADDF20866B1EC5C93C1DB13AECCDEEE694EBEB8C5E3D8557660415CEF73506579D6CDC390E25C1BF19034A373075B2C55DF460D5B5625E1',PUB=>'CBFA97A6C6712B31E9703E72DABDA41AA42AD7EA055A250FB2FEE8928CA5C780C5D16C4A72EF8995B1BDEEE5C14222145BFA72ECAEB2C08ADD1C3F4D26D9792BE0119D26B08B5EEDEEE6B30094BCDC983F0E185862E684969204B876F373618775DEE8F3F6DCB6B3E032880660A90F7DD53739133AC4549577910C822CFA74547354BB3F699DA2F7D5EB91799FFA35FB0A1018492A519B1099169C177CF496181DABB987605DBBF779EF90E4F1A9E115342AEC46B0CCB0B2ADCA1AADFC4193286B39EE1C9F6E7F17C2987DD69CAD602C7E2E48D2FA32EEB0E84F5EC51287553244411CF4CE94063F69945F4A0DA355E5AA6C7039181E8B743FED943AFC6BBDF7',SIGSHA1=>'esT5L4F3vT6O7VZLHRtUQ+OwNk4lSQp8OWODOFuBxD5B95d1A76qJAjhSFEo3J7e+YhXK4cJnyHRW+/KjioBxcYAQFfqbQtgVXUxAr+cEvK0reu5YG6hKEj2pYA/BqnWSjthcUZJNcgaB9SAg+Xd4r59Ndhi2WnhED7yurGiwpTKe1Vk6ZYizjhroA78eahZoQtwFOpP8DkEigF70gZCx/RP3le3vykAe9NPl0935UL7tzQKIQpaXNHwAATD6xMGEnb2shBaNBd7Ox2DrzburKExaSl/owaGVgAbzG+lYYbDqqdCl6EcWDSgcH+AWpDlnMkKds2AxoXkw7B25pTHKw==',SIGSHA256=>'PL/Omq1oZFNqOVzrxsrYKYyQgNwNtnZtGR32o+nnZxN5wvvIrHADRoQlMBgydqOnCr/gtukIZMAYQJp7ip49juCLRjNiS7jaP/B5ahoASlvXWyioueDtOih6N7PGGk68xiGic8cIOzeizIsEFqoVWHqCB79Xm5AqWv91DLD35ZuI4r5zkapc+2enXNo/820UTZvyOW6W3q+Db4Lvt+GfUVPaltlkpYApjsCElicB8QNKwKi9F005zdj49U7b9wVyzrKufFwa1aPlUlyGgFrOKjGlIkidH81CNovmBTvnEhDdypIkMd07ncTbQrPQgaZ2Nm2B7jFYfr92zMBejg/tlQ==',SIGSHA512=>'liR5dmgVey+thtyQWDv/SXGxwcCdRctd/4NaJrDORoSGxGRQqquUu5iWQCo/68/4Uk8PXIXIvObUUsfXIE5ZtpvPIUH8oCcp18/mz0EGJ7hZRXKPkzvmjavhYPEGwuF05+ETNO0YsWnKE5Z5geMk9QARBLJfD+f+gXXDJwo5jiMa/9YCVDMxeixd24PhM9645AOkaKFErdeCRN/tiY8rgX/5l+mNEttYtbgVhps/9E6kiX236Db3S8DHMNUwAZYYl6gWg5Bqi5Cll/1LVMSI+9vm4Dbs5m3SuS9pg0FhhlbLNr59n9y5cVcm3F4SW8aIh99viFLKT5WSvR3WWeBbWQ==',ENC=>'COyyr9NjdqgyfSe+vEj9jSwa02gwRT/X1jUO0xpwZ0RmGmXTO/EJgo6TsjrGIjtOjQhRm7xU8+SVTcL9Mho1eF50CYaoGiWd3We4WJaH8ERggZJokRnSoC681yJpEpmpR2f2SCufW0SmmYkzDiTO0jMJSrRqgwmR/J1dyjyLcHSWCqaQXfWjOK7EBzH42E7mzDQy2mbaxLBFVLzd0usCdKKAnxBX9Ao2mrdaImsEmh1r2WogBKEPwfwCH017cYVuZi066t/KkYxorKbM4mPqdi5rAeiuTLgt/IqSjF/bdhr4OjJy+tKqVQu2nol6lIkNFZtt2+sPefTmji4Y7+MTHg==',PRIDER=>'MIIEpAIBAAKCAQEAy/qXpsZxKzHpcD5y2r2kGqQq1+oFWiUPsv7okoylx4DF0WxKcu+JlbG97uXBQiIUW/py7K6ywIrdHD9NJtl5K+ARnSawi17t7uazAJS83Jg/DhhYYuaElpIEuHbzc2GHdd7o8/bctrPgMogGYKkPfdU3ORM6xFSVd5EMgiz6dFRzVLs/aZ2i99XrkXmf+jX7ChAYSSpRmxCZFpwXfPSWGB2ruYdgXbv3ee+Q5PGp4RU0KuxGsMywsq3KGq38QZMoaznuHJ9ufxfCmH3WnK1gLH4uSNL6Mu6w6E9exRKHVTJEQRz0zpQGP2mUX0oNo1XlqmxwORgei3Q/7ZQ6/Gu99wIDAQABAoIBAQC4vbF0Hu6ITKA8RJMJghCLAHy9KPrH9iEN4MkLUc8jrYF8dzPGfSSDK4P2RqiOGQePdnl325GRyTMRTlO2B+kyz7GkP1JOKCAe61rb/9o9gLY7Mdl7WYRkSsNzvmgn7AEfxFAABWlJIAjCO2hrSzL4qI9nZf8nqePlcr19ePctO2BLYI+J3NyfTQVj1Z+F4fCWZlRL9xRh7FWKhwEdzGVqXLlzweWeM+3QMLt39GRc0/g+Bu78HTlfT3RwO3EyRWWoHG7M4z3fW7rd8ghmsexck8HbE67M3u5pTr64xePYVXZgQVzvc1BledbNw5DiXBvxkDSjcwdbLFXfRg1bViXhAoGBAPZ6+DpTE1k0mAQV2EY1hgAYBlv+Iptx/Me2dRsiM4CwV71skVcmbClJaai+LGcUD45N9pu//SwzUOsVEX/0cJ/RXaZ+IWx/bLHY0ED5PvXJqxcKRdzY2miQRug1pAzoEVgQSYDixmxE2cea3pbVUqnyqV123wyXqIxwNtmd8Yl1AoGBANPbZaPuuKIS+QPBR7rqYFo1aT9Pllkmx6LVxeBwBOvVc3wx5VAjT2iXzIC5RhQ7n0VZBWoPhJqLBX3g0EliPW31KllZKmBSDlt+ZKsLd5SSv+ncGwmUMXVjLDne0mXwUrv25Tv8tXeBlQsQu0+4lOFuhv4twUu4H3i24fmpitA7AoGBAIts5B2aAMflSFiHQt/0RuimrnI7P7hOsn8GZxgCMMALAJbWYyC5S1XPgUVCzjtAzcvhri5MXBo0rQFN2ahXzZ2aAS+9CYsmSYYQ7zzRwRuoCG/wD7Ttth6P/ow8S6BBZg46qFmP7k4wZEDVCjSoVypragLEy0eEQoOutlhDT+5BAoGACNdcG4ZH4EOobravNqa3VKxr8v9wR9ItfKctNduW6PykcCdo6Xo/wx6qoyiYOxnt4KgBaNay8vwgQ4uRRa66347esJHfCdwCy2Cv9M9qsyGYrrrHyhOMKNj1rIiXATgRS9TW5jT6ob0fqjGNj5slY28IZS0lpvJNJe2D6rZfm6cCgYBfONBuQ+fITHAn71J5OLmp7uFQLTl1MmW0h9TYL3vyMyF26exjLBfBJTRYlo3Qy3lw+p37yOK2Ovu8k++ZyUdP/alhJdVwZ3xucITMoQOO+uoZzvF3yav8kBfWHDy7vGW1QaeVIaxrwpmyhpNBZojuV37Fbl5kitNnwRC9SfwJFQ==',PUBDER=>'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy/qXpsZxKzHpcD5y2r2kGqQq1+oFWiUPsv7okoylx4DF0WxKcu+JlbG97uXBQiIUW/py7K6ywIrdHD9NJtl5K+ARnSawi17t7uazAJS83Jg/DhhYYuaElpIEuHbzc2GHdd7o8/bctrPgMogGYKkPfdU3ORM6xFSVd5EMgiz6dFRzVLs/aZ2i99XrkXmf+jX7ChAYSSpRmxCZFpwXfPSWGB2ruYdgXbv3ee+Q5PGp4RU0KuxGsMywsq3KGq38QZMoaznuHJ9ufxfCmH3WnK1gLH4uSNL6Mu6w6E9exRKHVTJEQRz0zpQGP2mUX0oNo1XlqmxwORgei3Q/7ZQ6/Gu99wIDAQAB'},
18 {ID=>'key-3072-2',SIZE=>3072,PRI=>'20B38022266C2E3A07C79EEADD0989D435AE04D5EA05455B744856B6CC1694181BDDFCF73DD8517D5282FAFC4821AA90E68DAAA89216EB3C315B18E7EFD3EFA9F84067CA44C8D719E23D05BAC0A896FE86D7A23B91BC71B46D5FFE97AD64C48391137EE5017BD80CF169B783818F9F542951F3AAA9F780F56AAC48497A12F084CA9F404841A7536B5B14B624041538D2DBE26F393F381A4AE535846A740A286C28A016851DEA7D558ECA116AAC12621757475E0FD455AC13542E40FE0F0D491748BF81BCD3330CDB43758D9B1218B3C41A7307B6555CAB38294C900E8D7479BAC27E3DE28A14F9E839FEF0B96635713F5463933DC46607894F27DFC85BDA2A64A35E77672E692BDBADD949693B97683A8929332B77069D613C5F37ED8D01A39DC50396FF15EC2D4F5FB710B79F54ACD559DF604836F0D5D7588E390C5E54DE3C7F027AD82BA3EFE5F292A27D1A0A538D4FF4442D6CD96A0D91400E14E8C22A70416D00D6C0BA92A9921CF7EE939A97E0B168E50A7BDB2A48B3E0124FE15AA401',PUB=>'C4F61D5A91C8598CB775108105BA00D74F50D406A7A2D144B6F169BC127A4C86DB76E71D13422A9F77BCBF4E6542933326AB2A6CDACA99CCDD9C2811555491898FD4B5F9C15978B0341C537829ACC09ECE1A3C11E1461313DBDF3FD25B57DF42080635E3A291DBA53820C59045567BCB98B7D16E376F2416C4059F4012BCCBED88CFDC6A4B6B25124ADD83A6EE5C337AC221573540A93E58DFCD07F99C7E7E4D3DB7C05109C12A236F587DA72629999A58F31D75F390DDEEBCADC0B81407A04FB93062DCE5E67837AD22CB5D6726DF18DC1FD33206B2CD35782B5EE39FCC18BBF5D58DAF546257949358B2495A08CDEBB3465D62FD33F0E72F7187D6D3B1F1CED8029E36AC2197394EF53D4B5016E5CEB22961E94C43D0EF65C37E43D1C0B24AB1484553EBCF2E5733F3D63C20C31DF4D1F5D21398403EC0B96E7E59BFBF9E1E505A7B60D3E53D2F7547F2776DDF936B637578C6A9EEBF7B83E4DC7BCA2955332E6F56B9674880E586B829DD505F0163203CC107E614444C1937B483E07EEFF9',SIGSHA1=>'YcnZm/GkeNLB7Y3xJuvUKEYfP8fEqAv4zlFrSnNb+1NgL2tJScLwp8kZyZKWakxZw5KPRy4/d3NDFcUjTiErLk5ZO6xdoVwVOaDXL5Io828NV2pLGj4rPkgqY3Ccwxr7qnkZo9CFyEzVD8o0YSfwh2Y02BB5k1HH0IAQEVc2YYb+ZHptyJS8JqU2XqsdOlUX9lz3huZonrDai9THqC03FjXfZTlSqYfXwW/Fm4KYMScqMeZXh1/6V7ZYem1d069KSZhK58KdSYUYQG3d1imEBTXSIE5JM0DcYxnDmVMJrdnZd7T0mhbadJIvo6hKOn8CYRujky9uA7e+kZw3zPhT7HeIjFDIM7rT+KQdk4B1vSSfgplAy8s2DCi23kgtmkrNk205h+/mWxU486gdpPq3P3RCkMg2P1/+Rsi7qacJsxH9RpzHMGHLdl/0HeX8M5O42XYErXsFpLQkKdCkkVeNhrA7YVU/puT+qaRalAONbgwZz6mBd2bXwINW2VoFm9E6',SIGSHA256=>'wQQVc+RQlkhaSYYBDsElyDZX+jp/YSNU4No/tYyzCPTJ2eHDBS3xwo9N9oEV0i1ZMhiyOHJRppZj8VzUMJCm41vOQfiaJ3FjA3cXb0LbOuqfAHfwn2CNIKvhGI2pij0oDCUC9590Q1bp+6bg+QRJTIGztxqcG2R563u5f/uwp+tIGTjUjaSV1c76hspubl1/ZB6njN48Zt6LSMOCZgGirtU9zzOsuSIuo+r2InQasi/7ErbAuE5/3ZPbzbvf0B1qPYaKYg3x5uEKPbm85YKK3a7LopRYWRjacdGOYMeSsG+gfd+ZKo0TVcKLbTeyaCyXYzDq59FVa5F6lO12affvymA21qtUa98WnJ39Qi6vuTGtaTdNTueXpaNk+OFoiwv09b+eR0XlBgRtILyQWLs/WY8ACkocPvlElcWb9rLSWf6apgLv7rsMGrgHXrFG9GbYur7kKkmfdnpw/KNJCPyg44byDufKXslokFhSHZI5ZZocFWfEYCE5Gi/v6IkaOKoH',SIGSHA512=>'UsB5Rk1NUWRH7kUqt0HoJUgxW/wnoLWVqnyht3Icb4g6+Zx6Yzmq5Tg+i4gn58kXNlrdCb8uCN8Mfi3EbllBHlrU2NJYF7AZKvr2SZvP03tcV4td5y76bkahrsFcDMKpkcLXXiEH9IWeMASLmEBKcnSwjQN9pXrqWVMRP5CcN4Y03/k/vDr/q3lzvziQ7QjvwKSq6bOKexac3U3sI9zazbgpyKhhEO3O/3SRQV5xteHaNKHUkwvWnvLG5uEJ0EJky3UmvK1eDyPOOeOxSYhiILPXJKr6hbMiFDCLC6gOY3MwOzOE1R8sxwGUeYW1KvFnZKlx9Ip8Zr9BQyWnBLjS0wo1vdHmqn6H4Z5XRA1wGLhYCT7gmOgBCszmm3fsLeyiWTLBwTpK/1e637xAqZriXUPaRXrmPiGZX6fju8P91F/wGZFmiFDN3YGQjiw4z+QPkBvOuzz4CTkxP6jfbBOL7jpfqysA/PoiTVL/JKJKwmV3lPnYhpe9mr0Maqa0of+r',ENC=>'QRCsicZ8VrCdwT2i4L9v6LRoDUsFIVMYXUyul9A9yHDrcktst7NY/zkJb9h/o1Xat1kVO2x/4Ps2nMRDqlLiZcJeLD6M2luKL3PYD3gpMdC2+RrxJCAAFNoLmk/XQuiBO4c73OPqXFgarHz+Bs/At7D7jWZU+QqbEGqxFMPpj3QKas+BJ/dd56wHiCAuqkoPIDfRr84ZzvhjSmI4sIrXYWkNJ6VjLDsaLI/tReOWpvKThWgmCN9VEU57QiOvXzp4VjntI7TXtDF/hK+qjUF4FqtXR8YRLnPaLBanjQIvfuqebH7RkAzFf3Xp4eHQvkNS8zBy7s/SvC4/mHj8M4FzHlj7uJfah+qn0f7lDH/2gxJauhnjx/VaOiCNfFg5f3fU07zFtlny7rUHAlG1hHVQ1d0m4r3fptqMhuVne174tBu/8rnJI4cQEKfzjs4Bn9PXeqyIZkVlAlC+zoI8hlFuKjJ17qiiWsjWdSbycqql+g07JNke9van+NF4Ga/0MXLD',PRIDER=>'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',PUBDER=>'MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAxPYdWpHIWYy3dRCBBboA109Q1AanotFEtvFpvBJ6TIbbducdE0Iqn3e8v05lQpMzJqsqbNrKmczdnCgRVVSRiY/UtfnBWXiwNBxTeCmswJ7OGjwR4UYTE9vfP9JbV99CCAY146KR26U4IMWQRVZ7y5i30W43byQWxAWfQBK8y+2Iz9xqS2slEkrdg6buXDN6wiFXNUCpPljfzQf5nH5+TT23wFEJwSojb1h9pyYpmZpY8x1185Dd7rytwLgUB6BPuTBi3OXmeDetIstdZybfGNwf0zIGss01eCte45/MGLv11Y2vVGJXlJNYsklaCM3rs0ZdYv0z8OcvcYfW07HxztgCnjasIZc5TvU9S1AW5c6yKWHpTEPQ72XDfkPRwLJKsUhFU+vPLlcz89Y8IMMd9NH10hOYQD7AuW5+Wb+/nh5QWntg0+U9L3VH8ndt35NrY3V4xqnuv3uD5Nx7yilVMy5vVrlnSIDlhrgp3VBfAWMgPMEH5hRETBk3tIPgfu/5AgMBAAE='},
19 {ID=>'key-4096-2',SIZE=>4096,PRI=>'6B8990668B8843A5CAEEB0C0C688A180B8A3BEC24C44D97F122CCE9574132C311E18F9AC8046108F3A8A50F58799FED4EAADCA30EC2FA05697C453D72013B1567DB9E84788E79F837DABAC1B093DDDA367E4B516D5CEFEF1E3FF2CAD3462632DE6E7DED023CC6FD0BC49C2313E4DEA70B7FD99099B25FB1838627122258672EA0EFA09E3C5754D183E549EDF7FBA60EE40F6D2AFF2ADB60F47F0E6BE2D47B1CAD4F9669D83D8DA5F709B06EFFAE5640D48A334E6A1E29F8381DDB9349F272B8CF8D11B2B6199A6A8CE716B0F8D0DA4C01BD53869472F8D5694FEE719F794837E9B59A0FB1E1296E678EDB4684CFE368E93FA8099DA900A477850A1F8437CC66E50EF678DE000713411BE24EED970362E5481B87018A139EEA95BD33376971FDC8054DEE7A28E356A2F8218DCBD3388A127C0A81A6F984DEB6F4B1A71A727A932D0D93416A7ED6DF5E3EE9CAE60414EC1EC1EF3C815D71D0D2854B8BDCF3E75E2C974CD365B6506228F6C8D4DA85C9B87EE10987EA36FEE6F47368247F1472E6755610F0424D49715E3FFC1870CEB7A0A4B6B4F885F6D51797E59920B5C2CBEE7484DBDAD600419CB45DA706FAEF778FAE9FC0FE752108877C92133DC642E27E95BE78F27720F78A0D412762B987C4ABBBA1E18A2A6B93B393FFB5731823DC129C1CB9BE5277CCE91594F0CB5E08E35B0B2B411E131C207E25B430B9E718FA531',PUB=>'E00AA4E51A61D45904E9448AF5D4A824DDE17A2D73941219358A1E25471FB760C5BD7A349AAD5D4C2836FA15150CA4591BAEF3A0B4BC38DAC0B7B099ADD82F05FD7AFDB56A76BCF9C05E9C952A7AE472561E43F30901EB284CA30F70E88D036987003FFF801B3E420033079E057A6D69E78E45375518BFFAB091C82943F74FE5528BA3F4E4F316DF5A7A6C495440AFDA62874D150824B99F281D38A8756E7FE70E0A4455BAFDF15EBE566814008830C9043A480129794B1B86AFF44CDBEC1141007F3F42E8D6D907C7E5D712C25D1922F536293721DE8E83EFFF0E889865D94DE9AFF0AC851686A95A322865C5264510F8E77C1170F6C950F02C183196D0C1FAC1C05BF4E921D2035A0B2745A69B25C3E5AD4F81EBA422D0B6E01235DF54FC897D0918EFBDBD6EBD43E6577DBF184F0A8C565F1CB371AABF893C3C4FB65385777E05F1BD2F97BBCEFC44D232969937909A6E8751AB093FBC85364F518447B4A8E59D563B1B203DDC43126C2DC54315C7B152B6D4DC0DC705D03B5F2ACCB6B0510BC9240D7E339A61F1BADAC01EEEE1E3DD5336881C4567E89CAD867C83B55E6AF99D64D6FBCC7A66D9D3BA856BBDD49978638460CDBFF995A64A4877F1A08F81F9C4074CE81654BB1F64DB23B1E1531C14274AC813DE15CC3F92EAD1B07931B72582CE4ACADF493BE67E5DA881FD1175CB61C77AAFF3C870F9BEA7A16F0C6403',SIGSHA1=>'tFCXrbLB8DZLSP2561rZ/Y82NSqeMh7tNek1kBmvK0Fi2stAlRjxRzm7paoeOPEX24dG08a192ClUUfYdIGxFBKcV3t+Xyq+txmGMhNVjUD1wr2WGyi8YKipzq/9G1pVcHHdb25pE0tF+tqNYrxa4kClDYvQiwVwFfrQEllJxl12p8XvSvLvbuBWKqcY82qGx1Lvcfd/9CY1m4I48tvChSWQrMusM6N7gBqKdilDfZd/5k49QEo8xw/M4MjPqq4Vi421Kyi7HjhmAYDd5naMh2vz4508eVGIJ3n/2kN7pQM+0Ty5qpDYuPSdUHv1Ls9713/5gJ9FeFaxlxVFG32gY9cf7SX0NzjzSsiNgBBtxvpN+kWDxfS8ECLopFnubbs0hREBmH9s05UVqdtA9RMaPWi0n+3zNrueKEsetuxwoiL2YwTqUPo13G14j+D24Nbwl2yauo3Ppp2qjjHBwalLYwhmS/omnQcdNUP+vbvpb+uFOdzeWdhZVz8Y4D3SAq3v+H6fS+//8x+v0x6lsisj3mwLis7I0I96g3sPq1orJxwHTmRdcL74j+RQqqbcWbuoFn6M3Qn77ZzjgYFPp3xzPbggM29oJmRIG7YxS3nnJNMF7/HKxrum5p+uubEIzMWb7HorKwkVuiMvfK5oeqDephHOYxF/7yKCMcKigxdDQBQ=',SIGSHA256=>'ZPqUxZ693Fc88BZxSi0Lb/2n1BVg7GbWzlSkpWvRoT9svklkc72dvqyK1pM1y7DLF2wbxeIWkqGGupYVgeYwINpfq6tutV40H8oGP+Jul+vN4CI62m50wVfl4Jxj1YUm5vD4Fo3vEDi+KwJLq+e7tYEnBaZ/EChH3KEkimm+Vt6Zfsfv9rXG9bLmCNhlY6APQnS8aNQ6ebtsiXzHMacg73OuyTIE6YA66nMMV5ERhNX1Zb+FL2wxFIMrzskP9/UaENHCHviEiLp9jph1rXsjOQCPnMHaTlCgnF47iWZJIGu5TgwMlZYYX7TcBjAM1QjmFeTUTAHui1KKu6pholjgj1S3RAGlo9RnAO1Eez4axcqtMZhXetMYPhQGFPGboXZrjYj4a4Zqhf3PB+dL2kRgVgywv43EZjJRT211rqRPwdK6/9kPYt8jTZLXll7sU2fqm1BBa653wQJrMfvmGh6wChKPrK8N5mr3wY9dl3XjQ3AjrhdFSDye5y2dejlUzRx8r9iEI1YYr1JAyEr5DG7xvOwDUUrJ/0RnLUess97ATRr1eBadiG3fyJWw9q1VpmGhUIY9TqonYWTanXDO9EZd0knyycWFBoC0EjRb3mPAR8cuvWwcBudjbwq9OZtNwfOXvYxY24GIgDDG9HP56C5tBn4LvWPEw4llq1mg43NATCA=',SIGSHA512=>'N2zOjiz3GWXCynJXX1xCF3jdUeeahQ4/C2E2RzIZSWtB9iGm8KmkWIBAxya1yzRclUU6/Tpm2K4+6Nxz9iv/nOzXEZYN8Dge8gMk2OZnTAofsKWtonR6aLE3LQW9dOjqVg6ffv6+jDMyT6tT6i1aviCSbkkdsCxJ4UyheWAu8voPk4SLGkrmtRXK3Js2rXUaMmoHtMt5XfFKuOnzC1baMg1SgjiQ+QgYmRwjs210PjcgrBLMO6i0eTjx+Uwy2xwOM3Hsa5npTGIkZwUN0GXDGIZuE/8HappF67lWoM3N6rZNERzTeAlLyMIbTnegR/fcnju8+1Jop7JJ9L7J7vXp4l5RClcsiG8HSm1OOR7FHjXIIX5MIWX2c7k134KlsQbJCHf4GDUwlvtat294kDMsHhkS2dNWkUrvmf+Xbi7lh2nTD/EIM3ki8XK6f1cQSL7vJamwDAIYcXSc8UoO+CygY6lmWDfmxyVaqNTwnOmK0KCIy++MGNcNYed17+zy02NyV/RQ/9/lJho/buYbGwfbVTf9wXr57gotRFl9UIuOPBvB33MApndtm6/8fP4PS6zhYlFe7r6V34AZVwOQnDPdeEVg8tz8IyhHOvno69YuQUurGvz79165zJvKZOpdwKujq9QgIcVeoS1w4pJT+HV6vpN32c6/qfb6qk1CdnHQVrk=',ENC=>'znyPxBD+XM9r1DoTGrGnu76/WSiAQQglq/aI/EPmBzmUfGIFkJ8DdDLPYGvRzUVXCS20TGI9rJtXjanKt5mRlt7zTFM9jdpgOoEhn6ZHhVY/kX7/v8/34XKqUezLdRyyozRTwkniYAUuWzYkZ5/3SqMqq0oN0nnGpgTRJtvD5+BIjxjNK36oJnLHJnfObVT4XHILHLMrR3gnNotHmUza7IG+9tY7Ga7a6neqH+mA/CWPja8k1+M+FkPh8z832I03kmoLAS/bSuyBmfLmdEJWhWOI4u9W20Ihyf3evHBs8ByEglWFUzGa/n1VwmhOT9zkdhWhNmk/d+Eq1MihtYVjiwi11iy6m8+11mIQF21VWIebgKg5yCq/lxGV4iPx37kV6+JgqF0Vj815cDeeWyWJDafsJqd8YvZJs86mur3BIkls8GuPYU+USwoYcfc8F615zOLLICxbbVgNiZ2+Y9J6VfNWtprRw8dJnWJJrmbilvabPuBPsaJIR+CVSM/VRXGVTMHk8DMUAvP4Q19J8NMHWxeoGeqk0BtgWKPg1W3LOMgmJ+c1k7LbfRRnr/tNL+WM9BtryDf+2UhuZsw1XuhN62g4IARR9nsL8MSNwAXHT2C2ex6zrhOjHMcFkNzE/V2n84xQsGPPLHyFIHTNvVxekO7GRZBy+je6WXDrUAxjHtc=',PRIDER=>'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',PUBDER=>'MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4Aqk5Rph1FkE6USK9dSoJN3hei1zlBIZNYoeJUcft2DFvXo0mq1dTCg2+hUVDKRZG67zoLS8ONrAt7CZrdgvBf16/bVqdrz5wF6clSp65HJWHkPzCQHrKEyjD3DojQNphwA//4AbPkIAMweeBXptaeeORTdVGL/6sJHIKUP3T+VSi6P05PMW31p6bElUQK/aYodNFQgkuZ8oHTiodW5/5w4KRFW6/fFevlZoFACIMMkEOkgBKXlLG4av9Ezb7BFBAH8/QujW2QfH5dcSwl0ZIvU2KTch3o6D7/8OiJhl2U3pr/CshRaGqVoyKGXFJkUQ+Od8EXD2yVDwLBgxltDB+sHAW/TpIdIDWgsnRaabJcPlrU+B66Qi0LbgEjXfVPyJfQkY7729br1D5ld9vxhPCoxWXxyzcaq/iTw8T7ZThXd+BfG9L5e7zvxE0jKWmTeQmm6HUasJP7yFNk9RhEe0qOWdVjsbID3cQxJsLcVDFcexUrbU3A3HBdA7XyrMtrBRC8kkDX4zmmHxutrAHu7h491TNogcRWfonK2GfIO1Xmr5nWTW+8x6ZtnTuoVrvdSZeGOEYM2/+ZWmSkh38aCPgfnEB0zoFlS7H2TbI7HhUxwUJ0rIE94VzD+S6tGweTG3JYLOSsrfSTvmfl2ogf0Rdcthx3qv88hw+b6noW8MZAMCAwEAAQ=='},
20 {ID=>'key-512-3',SIZE=>512,PRI=>'987EFFFEA6ECAE6537F986A2F0FCA8F88EE705311A4BCFE4523D601A432325B46D67E809F5F63F20F66CD04E9B7C6765A628A02F35792EDA2E6606C756841741',PUB=>'CB3A550F2096DE1D9CA3438E7E4706B215F9E8EB2B5CE8274864D5FE51DF38109527DA48E4790427C261FFA0C7E985E9EC983F9BE5087F3956A3582F0441BAE3',SIGSHA1=>'RRRCdaNSPBrUNM+Wa8swDSNCPGl/9wnKv0lwjxAawky78v1jUlQw+Lg9ASJ2mJn0ZAO7nnLWaCs3tfhcuB8mkg==',SIGSHA256=>'jnVH8iSQkY3hOgNEqVkhCJX9QZN32N83ZL0WXJ51MW66RpNPxC/ioOPUJEQRpq3dTulvRYca9ufkzJOXPhQeew==',SIGSHA512=>'',ENC=>'ZHprbbXI4zqxSp9xpM6d/oAu1qb1JKSiFBSh3L5nXee2RajU91xzqYFZcM38jI3pmgUxvJq22dT/8DvKPJic4Q==',PRIDER=>'MIIBOwIBAAJBAMs6VQ8glt4dnKNDjn5HBrIV+ejrK1zoJ0hk1f5R3zgQlSfaSOR5BCfCYf+gx+mF6eyYP5vlCH85VqNYLwRBuuMCAwEAAQJBAJh+//6m7K5lN/mGovD8qPiO5wUxGkvP5FI9YBpDIyW0bWfoCfX2PyD2bNBOm3xnZaYooC81eS7aLmYGx1aEF0ECIQDoe9pUgy2swh3GTiKxS9BT6efhgTTwOfBnzUGhIl61AwIhAN/I5kPm8FR1vxs1PwnEs1TmbQPAAbEfnVotKvq8p0yhAiEAs08LVxGSAeP6OP/8zAgwVvhai1gvb3UQkc8C5nfu2ecCIA/4YV51K6+LW6EQcrg6vmWPsDX1TOmcDPmzgX61WechAiAGtqyZaNukznXSxJchSpRr7Ko3HDmS9J8cayZrro0F4w==',PUBDER=>'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMs6VQ8glt4dnKNDjn5HBrIV+ejrK1zoJ0hk1f5R3zgQlSfaSOR5BCfCYf+gx+mF6eyYP5vlCH85VqNYLwRBuuMCAwEAAQ=='},
21 {ID=>'key-1024-3',SIZE=>1024,PRI=>'5C6E2CE5768B7A181B65B00404F728550E0193AC11FC260F5C0F9FC75A5F5DFD559A64AAE7CF12083C10AD58F4CE08B89F5FC89E50B4F3FF3EA64A701AC024B807FD29F64CB3DA87F035156244CF11E09EF1423C7862B5E8D73F0C969334CF5638B0D889B947D79E31F849AA5F2C7D01EE9CBD3FA3C342C42B9903267D1BDD21',PUB=>'F8995152BFFF2A8E343BD609314BCB22CF5A71608EA1C5A4FA289291B2EF7A5430DF00E2B989324393609E1C93F4C0EB15624DFF679232D485BC9576725EFD64BECE61D4520F71FECB7E18EE8644F189B27009383CF89C9C02B75FA0BE513CEBE05F99B843BEE096A87237B3AEE719D40FC10F5C832CDC78A6DE6EF5360DDEAB',SIGSHA1=>'bWT1q9eZl65JhUgOE1BKCz5cFNMF6RdjKRyW7VImofkyd8F9XztefH9dfjbZ0H/BJ4Gw18PNRXUV5Ecza9ynOUhVytc5/FJgsEQ4Siv8oDihW7AaKgiaOCr/u9/7BgXrMkSiMMgJbHgFwJYLdNYlcuz6FZH++cB7zHM/iPJYY8k=',SIGSHA256=>'sUIIjHIMEEVH2p9VIducRTyjOqFUx1U3otIlo48TmbKOHcT+xMny2nLtWZlZ//TnMqN8WuO/DWqg0Up1yHOjKUok3kTDlIOrWpHVQywy9BbDqVutDO+jZQFIcoNrCj0aSUxXhDSg/NgTwnIO7rv89mvkELeDQKd9+qrk1r8cM/M=',SIGSHA512=>'vwIT/VmvaiqccuS3CzIpxPCJsG1T6K/VthutpTTVJIPRCUGT9hwSWliWZBHLXJaN31k9hKNmVyViWyH9dlFBbfiSXmRjrKS3alkSefnxiw0KDv8Fjf6zY09UCvs7dfZbrtaXmg2rDS5geDuKelf7JWOAsuFxQ9DdvIfE/H8SAh8=',ENC=>'Jj3DnngbwjZVLPIdP1gt9CfDcDz1G6fUMd2XRpzoNS67NQ/EwHT9PbSMswqyUHy1HXPgOH6SptUEZhF/QVVlCMeLDtuBqVkjeVmWRmxAAw9kHjYd5TglV0lkGLj2Mebi8BpVu5BvTfrw7sfKg11gyYiAoCc8EidoMq5Y1vgPO3U=',PRIDER=>'MIICXAIBAAKBgQD4mVFSv/8qjjQ71gkxS8siz1pxYI6hxaT6KJKRsu96VDDfAOK5iTJDk2CeHJP0wOsVYk3/Z5Iy1IW8lXZyXv1kvs5h1FIPcf7LfhjuhkTxibJwCTg8+JycArdfoL5RPOvgX5m4Q77glqhyN7Ou5xnUD8EPXIMs3Him3m71Ng3eqwIDAQABAoGAXG4s5XaLehgbZbAEBPcoVQ4Bk6wR/CYPXA+fx1pfXf1VmmSq588SCDwQrVj0zgi4n1/InlC08/8+pkpwGsAkuAf9KfZMs9qH8DUVYkTPEeCe8UI8eGK16Nc/DJaTNM9WOLDYiblH154x+EmqXyx9Ae6cvT+jw0LEK5kDJn0b3SECQQD8pbFcpyQCZX4jrOjIQ6eWUnxQBCvr8rmn4VWO0Lbis2eumauyQzlbmuvVQgtc2EgQ0XZvpmUph2lTo/Hxv0GbAkEA++XfIVqRbbBdmGQGDixAUeY4W3tquhVQGVe/kLo0F3m+uUl66jNJ9TlEU5o8Wfqged7HWOqo2QhZjJz7DGPwMQJBAJTP29phMJqgwV2uGSbsgqfOSh6vdldyDtzNoyGN2ktJtQZoyXMkmYJVjBd+4UZ8tmYBmqtE7U06z1VOudHU/4UCQAcx+b2qKJ1JfGLt+H5PJUcxnEqAq/vEwBT5PK+VogdJovkH8ErgTCyFBj6dGTw4vHy+sFMJ4OjSJDyv/zvLXwECQGQED2zrrPhaaACJNB0nkXS7r+FKGHOjZoloA7Mvb4UYTUGnfp3xnG8pa/dQFHgjNEZyGbYFiUYi/Ycy13RdrvM=',PUBDER=>'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD4mVFSv/8qjjQ71gkxS8siz1pxYI6hxaT6KJKRsu96VDDfAOK5iTJDk2CeHJP0wOsVYk3/Z5Iy1IW8lXZyXv1kvs5h1FIPcf7LfhjuhkTxibJwCTg8+JycArdfoL5RPOvgX5m4Q77glqhyN7Ou5xnUD8EPXIMs3Him3m71Ng3eqwIDAQAB'},
22 {ID=>'key-1536-3',SIZE=>1536,PRI=>'718578C4C5955E7B711EEE5E0FA0723F9CAD0DE78E0FAC7502CDD4D482EA507707866739E23C3E2764FC3BBFF5404BD91E055CFE21928791A980711CCA0200CCE6746E4F45D203F107FBE98B2A974EA99CE60E766EF5AEEEDFBB5F8A0B47AE9FB39FD4C01A6DA14A7424D7385F75758F41EAD10016EF55A86EF0ADD9798397F6F8B88CF5179F76906A6E15DE1C09E1051FE5781CAABCB61C6591AA5204C845F1AB336C95EE2D345F48D78DA5158D986E34101092E904430E5396D16FEC9BE601',PUB=>'C18DF7D61C47953B26F35B1394A12FB32985FA5B3757106001B9522264146DD1FDFC20FB8C27CD9EEAC07B28CE692816F9F4B2AC539A074CFBFA5EA2725BD90B69109D85AB28C21179BD39121A5D1DC001CF30D255AD0E00D1242F9D9C07CAAB37A1DA2D9FA65B94A05DC452450FDBB556989241C69BF007C5C965058824AF0183E5DCD95288949977DCE577052AED0DB02B0D886823324E7268F884342552A2FF73A0881F0631AB9035B5567E75418F5CFF9357C6D639D0E5B4F21DBF810C89',SIGSHA1=>'BVVhtXAQG+OUHTz1OsiRGuhiG75drci7qifEMMrdOMikNbRtvRRjCRjZ7ELixj1xjwLTEiqmxbcytSPIMXHeKy+FqHz6rioIUMiEgSFnnFhMa0e9zUgBd8L3JCuEJxPYi4fJrb/MYoSg7B7+tBV4m1BLGLwM7flPrJEikNRHpgtpyNypLqX7kqj7gdT8cqKyefrDuQUM7kFr5HZk6z8s/6TFyzRr9nWpwMUfEjr6HqdSp4XGwQihb1eHsttUCCbO',SIGSHA256=>'tmAA/bfDCRbn9sy30iE77KVJmgoljYla8g6etapmGeElT8zE8bGnFI2wNEm+VRXu5pFx7emqOQ6X5DGJG5Fi7BAA/XDLT71kzJoQdqr9yeJuAyPFOA0LC///LiEhdQ65tZiuZjcadJ9Uxl9MkjteuTCULIXmxcUxXN0FdYoZgoGjIT5jq2J/eqgRnbTliqfLyyumTbXkHj4kh9b1a1F0UGCOV5/6F+Ib+mMxZpakiAxAqpNcBLXEojzAJ+OG9Nnx',SIGSHA512=>'U9L1gTB8xZumj54CJJr1hOZ3UAhCPO7gWETT9s4nYyE6l+xqigNMg60uPK6YXuuo5htHMCtQDgq9Q9sMnhqQZg4+GqE7Tdc2nN/1M4GWlB8Rw2FMtI+pIPW32bneY5z3DCBkNkHMsyCZPpHGA0Jf3ZJ4lvRleuPpXsjBVfvEZrSRLysI8Au2GNQa0FmBFeAOcALGEfHP8Fdnw+gJMwnRXNxd/E9fve00uby6Li7CRbXo6dWH1zlcyB6WnoZyfNkg',ENC=>'LEv96RAFrnDt2yUSwY40o8AxfmmQrRcdeOACZjgp/FEuQ6+aLDTdVWHiZKArKkaO74N5WnlR9zl6zs0HLeUS0ehv5J9u022eFrqKxOmIIHuKVtC3e9MpLc+8bJPWdGNrgkytmIFxs3WyhixWglViC+QJKEkfg4YxjS3y1RCcm46A9h8EW3SgBWruljf1I2RobRUET41rdWB1XVhjsVpQhlILrmlXG9GzmnIegllulkKs3VY44cwbpV9DxZLMalSe',PRIDER=>'MIIDfQIBAAKBwQDBjffWHEeVOybzWxOUoS+zKYX6WzdXEGABuVIiZBRt0f38IPuMJ82e6sB7KM5pKBb59LKsU5oHTPv6XqJyW9kLaRCdhasowhF5vTkSGl0dwAHPMNJVrQ4A0SQvnZwHyqs3odotn6ZblKBdxFJFD9u1VpiSQcab8AfFyWUFiCSvAYPl3NlSiJSZd9zldwUq7Q2wKw2IaCMyTnJo+IQ0JVKi/3OgiB8GMauQNbVWfnVBj1z/k1fG1jnQ5bTyHb+BDIkCAwEAAQKBwHGFeMTFlV57cR7uXg+gcj+crQ3njg+sdQLN1NSC6lB3B4ZnOeI8Pidk/Du/9UBL2R4FXP4hkoeRqYBxHMoCAMzmdG5PRdID8Qf76Ysql06pnOYOdm71ru7fu1+KC0eun7Of1MAabaFKdCTXOF91dY9B6tEAFu9VqG7wrdl5g5f2+LiM9RefdpBqbhXeHAnhBR/leByqvLYcZZGqUgTIRfGrM2yV7i00X0jXjaUVjZhuNBAQkukEQw5TltFv7JvmAQJhAO7ZSmTu+lFa8PnTn+k49BfSx087/IXwHdwMYkm7jWMKunUz9tW0f1sfu7vQGFNdC0YMyQsZPdaoiL8gPJkP3VK/VrFx479f5iLybWJi/Fyaai8IChV88TTFOyIOSRM6oQJhAM90CvSxKqnGB65Zz69pRerNSngVhVuX8CtmNhhWqRv3vcnCpfT8YAzhQdXGFOVUGh5IW/IDggz1ZW8TusqHO/GoCvrTgX4wCN85dfvWnah4qw6jckk0Ofr9GmuYSXKw6QJhAMarFqY94RgqfKZQ0II9TUtDl2TgkHsX7r5JzrdluYTYN5+lSXsYV5aEHrNps9IjYm0x1UfWBwm1xYi0V7M47u8VGBcglD9qlRIcc7+SdjbQeeIE3d5hvoAWTclV+JJ2AQJgEW9rTE1njIU8OAcMUW3DloxSae1FHAGVCdC5UypVZChaJw7Y69IaMHruEY1oTC3ZVBo4wApTb8tgDwnVdRgQjarV4WbNR1G6LSijJdtPvM0Hc1+BR23AQbvr8IcIBT+hAmEA6HY4G8I29oyd7zv2Z0bmZspHR/yR66FOTqZ++hKwHF9FTGXiwhKDxOCLXsPdEfm5TW8kYFhaE/pn78r7ns3kQ5XXXvJB1RjIxGV4Cr3XqeBeevMKp8YJPD82zXzufudu',PUBDER=>'MIHfMA0GCSqGSIb3DQEBAQUAA4HNADCByQKBwQDBjffWHEeVOybzWxOUoS+zKYX6WzdXEGABuVIiZBRt0f38IPuMJ82e6sB7KM5pKBb59LKsU5oHTPv6XqJyW9kLaRCdhasowhF5vTkSGl0dwAHPMNJVrQ4A0SQvnZwHyqs3odotn6ZblKBdxFJFD9u1VpiSQcab8AfFyWUFiCSvAYPl3NlSiJSZd9zldwUq7Q2wKw2IaCMyTnJo+IQ0JVKi/3OgiB8GMauQNbVWfnVBj1z/k1fG1jnQ5bTyHb+BDIkCAwEAAQ=='},
23 {ID=>'key-2048-3',SIZE=>2048,PRI=>'6B4CD1833925E1FFB0EC80F61048B8CE6F3636F9E13708B0B21450CFB4AF45320674ECCD3849BCCF71291C3EFFEFAD8A20C683515DF51BCFC238F702D686D24705B87CA8307CC1919CD801AEA8F17C6EB8799DEDBA456982AE1EBB942C69A28C375E76382469E954F33477D18FD1506BC17701E2BABD290B0E268A70F7F6229268D7FD89AE705E8FD9FC2972210E9962DA4B1A67DEAEDE4A8ADC9CA526CCF22547A4A9946EC420E5582043C189F80670F2C798BA3B4562DDF8A111C5AF08AA90881A3F181E9C6536D412634BAEB2B9D082198E98A4E7F11B6B3F10607D1700B6BAC2034413801CE7D81D242A4C701EC46602A49D771C9D87791B7F86AAD1E079',PUB=>'982FFBBECB63D90CA7515617F963A5E907B2F533D76D91D8B669FAC24E5E01C4DC6E5BBF7908692395C8E1C741E4F5E34D958CA9627B3149205D64D67093A45A0A6C91CD4A62324375F79A954D97AF1CEB76CAA07578B1A4ED3E2D4D6A142C05B4BE983A6E6DE54CF3B6C62FF1911E37945B4188DAA4284FF3F4039C0B5D1B843D6E4FC688D0A80BDA6E2AA362957644B7D0D61AA5E90C072E7E932D1A08AC8D47246CBA71E4A78F32335D3246A26554BBCCF9F3179ABD834D2D1B2DF5BCA2ABFF34B72D53911E99739767861677C547AD7CB55C29A85F0C23DDE44770A61302C4F9996C568746DE8F54E4A7D5E879692B1E474649E70C01F7235055CF14BCB3',SIGSHA1=>'T+InLHHGlX4CRhN44n09zmbsTg+E9sA+FVR8cNkL4L/We6l4+Zpn3MrqNL87r07r4DRoneQ2DRH/eWjoRdzzaIyCMtFOSpZk4l/Pu1yY1npW0rqXTSTqle94olYdV0n6SEHnH2+F0Od96Xyu1CsMwyTPaITIwUXk3uMqXLFwrgH3NqYH/y+rq9uYRaQvUMcwBkWX59P6lsDYU8EQFXyLab9SL1fVEMeuCdXjA9E01CxF9GFkHv9FJLUw+4BY5F8NvFXPi8Yb4N5UM9fcTweVIEICLF8e5f4SB3WMVB+2JvcGDssA9HZ+/Nh7ZfMsbtha+fdTl6+7XD+4w61ABgfYdQ==',SIGSHA256=>'kaJA6EGVDN+IMZ6EOz7Lo0yJ1yiN1z6LslEL1t5BU7hGc5Wgv9uoJz1Q301xBl63K66vcJh/PBEUc9816Nc52m1ioNKhPLleTrOzvsgn9e3DEMgOgZGTkACfmRuqjyzfKD0roK9pnwqpCGuCH3UIcPJ2kGD8MlqamC28dnouhGA6flxkj3hcLpZfvuEAYJUOwvW/S4adNFaeNX0TB1nCzsL99/IP5zx1lMP34j98VHj9fGr6m2DgGWIDY3PoQhAqcXAq8eOTmB4aSavvQg6+dOTj/ZB22deXCxGGYd/G15vX5csZf7+ZFwRm86Ki4yQZdo0a82F+ENEUSG4egB+kXg==',SIGSHA512=>'Dg5HED0ShODMhXsZhymDXssEVH/HpEsVs4vlVQupBCaVxSzSp46uE6YrUFvvJU+eFeGZJQAVGkdc9hJPSCc73yjrjt8Z4IBhF4MyR7Oe2e+zK6ZHDnHx3hQk72pSok/sMyqrJPebNRGiHztBYaY2GaDlA0zdU9hiLemDluPIFJ+NvfqtzbE1GA1edX9jrE+hqsgEWAEUXHm9L3RYxOJNn3Wgjb0tQGu2QOJv/6irwvUzK5FPe2xsOcSL7VgljVj1YCJHd4LGpqlcd67JN3hoMkxDyX1TksCy7pFY2bqntU/UMSW2zdQdSMXXz+nEP81Xn9QDs2eXzYFuJImFtFJ5BQ==',ENC=>'Zvr2SWqDaHDtRRZjqwBK9zouTKN+OYpHzOXHdYVPAazGYp7ldtjFe9+m+NNorv9zs3T4MVXcYkEujXds8crkQ+qfQc5N2PHvVhLSdd0Q5XM5mM62LK1px+G9GdmLCGLgrFAHcrMBICprDPVTMT5ypQFbegrVNCp4iCVJ+lmm/zSdZUZ9IoxkGIOt3/BPX2h1giKzXR9c/zYUyqZGg2w/vB8lgzsXO6UMQ6BjHIi145mGXHLExWaFArdnMhp1ncO+bgjxZvmFJyI8xhy9omsyp543Hb2hxH89F96bHOBmAR04ZeEJ9OY6rZRHT1X5+JiyYfAuTwN0DNjBoCyG4AUT4Q==',PRIDER=>'MIIEpAIBAAKCAQEAmC/7vstj2QynUVYX+WOl6Qey9TPXbZHYtmn6wk5eAcTcblu/eQhpI5XI4cdB5PXjTZWMqWJ7MUkgXWTWcJOkWgpskc1KYjJDdfealU2XrxzrdsqgdXixpO0+LU1qFCwFtL6YOm5t5UzztsYv8ZEeN5RbQYjapChP8/QDnAtdG4Q9bk/GiNCoC9puKqNilXZEt9DWGqXpDAcufpMtGgisjUckbLpx5KePMjNdMkaiZVS7zPnzF5q9g00tGy31vKKr/zS3LVORHplzl2eGFnfFR618tVwpqF8MI93kR3CmEwLE+ZlsVodG3o9U5KfV6HlpKx5HRknnDAH3I1BVzxS8swIDAQABAoIBAGtM0YM5JeH/sOyA9hBIuM5vNjb54TcIsLIUUM+0r0UyBnTszThJvM9xKRw+/++tiiDGg1Fd9RvPwjj3AtaG0kcFuHyoMHzBkZzYAa6o8XxuuHmd7bpFaYKuHruULGmijDdedjgkaelU8zR30Y/RUGvBdwHiur0pCw4minD39iKSaNf9ia5wXo/Z/ClyIQ6ZYtpLGmfert5KitycpSbM8iVHpKmUbsQg5VggQ8GJ+AZw8seYujtFYt34oRHFrwiqkIgaPxgenGU21BJjS66yudCCGY6YpOfxG2s/EGB9FwC2usIDRBOAHOfYHSQqTHAexGYCpJ13HJ2HeRt/hqrR4HkCgYEAyQkF7m9q85ZTeKwaiEZ17VrCk9vPP9R1S9yMyCr9Xzmtkut3FuCLzqduMq2XXYLIRYpMpgj0r6fUel3hNzlnq2F1pABgRO1yEQ5XClvSmwD4EsYZPBM4YZSwUIyzhfS9t+clyAeGm2oHrWK6oYBxFuKunj/K5Zlh5KRWRl1c+x0CgYEAwcv5vSxtifPqKcrM8KpH13kq18APRenCgvOJUW3zDAcKMnoJvXxpfDmEvR7zLFmtEiOQwLuc6tzl608ghGSgz0J3QrhlPej9iZwe9a6QqcpGOEubFn0lGKo77x0ILU+NU7e6uo9Hq/tUmzCe1YKRwDnCfVbxTSK2MlYQVj9FPg8CgYBjqD1wfXsfVZ37bBWbCJLdHujmM0kB82hSOvrvH6CK3CTXeDKI/LdRsl5GcRdgG7z7/BsTE814ZlJGdtN2dNaXdrDCpA0VHkA1hE5RrEMy48AWTm2kAkMo3HSq+ZTlCvYhfEyWZGSuFlnH8fFirjFhju3RNP534xlMJss+BnpZYQKBgQCwUhA/oKts50I2kfBSSusgTXrAX1rGBj/V+xQFxV5rpAAQGt6/yvECeCagFweyY0jHBxrNcCT9vstlg1GXgyKYT+XIC5L5eAEtcaDtcMzn3kRzNb6+AFB/F2t+S1DEQOvZroEy+eeAvyOkKuFoauqHFUYx2aejwaA5PfqRLfGm2wKBgQCKW0iGocJgd23CGwV2w6q9d0N88Y8z94gqAp1eFYML2m/l/8ZF14U4oXhbf+DqHEzMoq5tKy2zBt7ASNYRKESNSN27VdBjqkCNHOtddypXIed5yTM3DoQ4HEC/726PoZ5MEtKzup6PegZqyPgfYblnplllDTkd2eD0KfQRejeRQw==',PUBDER=>'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmC/7vstj2QynUVYX+WOl6Qey9TPXbZHYtmn6wk5eAcTcblu/eQhpI5XI4cdB5PXjTZWMqWJ7MUkgXWTWcJOkWgpskc1KYjJDdfealU2XrxzrdsqgdXixpO0+LU1qFCwFtL6YOm5t5UzztsYv8ZEeN5RbQYjapChP8/QDnAtdG4Q9bk/GiNCoC9puKqNilXZEt9DWGqXpDAcufpMtGgisjUckbLpx5KePMjNdMkaiZVS7zPnzF5q9g00tGy31vKKr/zS3LVORHplzl2eGFnfFR618tVwpqF8MI93kR3CmEwLE+ZlsVodG3o9U5KfV6HlpKx5HRknnDAH3I1BVzxS8swIDAQAB'},
24 {ID=>'key-3072-3',SIZE=>3072,PRI=>'28B8D8BCA984FA61FCD1F8F03EB33C2BA156DBA955B2DA052089511A266A68B1E74B4D9393BED2E7149241DA37C1F2430D671334E12B91D0AC2265BFDC391719AD799F057ED6FF2B2E330E87E85A50CB542CF7E0DB1B0CEE6DCAEB51AB0B5A744FEF57D5D98A1B9861C44AFF6749586DF2215CDA1BF3B416BEAC2398F013AE0322CD9949796ABBF8DDED033B723AE295F1F937E56890B8DC7910008DF2590EDFBAB22F2EBB26FBE7DAA4D22C33B9EA61D55290109B4FAC61F222381959C00C23DABC1D3A993D57E1565BF963224A20826E08AB1D27E207F07BD06885832025B2506EBB73B86B82CC65536F5EBEEDB8FCFE1DD907EAC8E3C9A348B5D8C8C16EB475AB940E91099A2CD8F0DDE5925400151AC551E5F8F0A498AEC6B2EAE8AC1E0283261A4306EFFFA404AB88A9A916F1AB387CF3BAFE8682660E40B616C96697596DFC6FFEF049AF2402B3C449312E1BD9E6319181C8891DE7A3931310CF16478274F39999D5202D255712CA005FB0BB7BF8AA474617B228E08553634D929F6F1',PUB=>'C22DEC229CCA21821240C71E8A58B6F6B707FD9E928E2697E3A8B5DB7BC37C34BFDF9B3F80CA2E99EB03B2269FAAF3DFCEB7979E085A5B1FD99CCB4AD70A31D230A38C59F665E2D5A1CAE430B4A461428D1E531B7937E12EB0E68A37D933A8F8BE3498AEF6C2B40D105447980881EE8D756849D329AEA41B2BDCE034D1721B3F3214C9E4559C436B78CED91DE761D72FC4ADA1CCBFBDDDACE35307698DB0BFCA88D3C764A024C9BD113929255CCC683A681758923DFE5AED32717045792BEB37D22292454737416EB49E44C08661ACBA236F63588534BAADA012F4488F3D7D8E95C60FC3746728EEF27646CF086CA4D203441C1E81E3A596AEC396B58A43D2BE6DA065748451A4B50387C31FF260481878F7DCA1A9888590E10435881920E55A7D8DD1F1994041778D732A383A49E0BF4B7A3825F5D8E6F39661122278C2B0DBE35150B4A262675409BF84CE6C30F87B48E6AA61EB91D6F06A1B221545CEC5250E14A910DFD233936E6D4E1858AB16955364A3E5D4592B82B4D67FC931413149',SIGSHA1=>'Y4Kqi4zKizlEVCmiZUhFf6psQPeELXnF7C9Mha3b8tKCT8IRryMvbaxBbd6Gnc325bBkTwX44VtVjAe9qenO7b42fIFZcZgUHWByCTzZCtnSM2h4W8qAO4fJHI2ye0GV7Dk+w6doottLo6RFL3+ZHb6VSkOYeTHl0TeQC5YkktY67erTDfpq6xTIu3yPAw2RPtT/UsBeo7HRvHD2/5JrUgeWUzl41rySjleeax7pXxsMyrBskw8rLvQNSJtsAuhQqsFfIOz642sJSeibxXTrs+Xh1xsEiOUytyZHcHaGgIyPieBDYofE1CADag12GlrZ9l+1AvdbhMD3iX9LYAFLvXCa9EbyNRDiua+CvDnIKaFWOJ4uUOaKd+cZbo/0F9b2eP7OlIbkfse7mIqzDF8WocXYInxvScJNjHiYTmcj2CXm2xz00Yt4aIBfbwpKy8lhB9t0deX9U/PEE2m+zoTwJTCGxheBSXecYC7W4abnRi/LvX4vpws+oTp6GJ76t3Au',SIGSHA256=>'tJyBBJPCcGSi13J97ip8C4hCPoSDNX7+n/POkXmLrIMCQ5eSOgxx3W6AdAFQSWtg/NDR/NhVpCkYD63cu0gQxU+IYVgXaz3dUsj273lDM9QnY2lmTvh/pvPwZA9P+DHmZjmiBh9OH3ltS1o+QTNhJZQSUQX4n1wcfhU9w1zFCbiu0th9gldKG1yJcjsmpO91HAnuVxUKwurypIea4oB/0GbVxCUc3IDHtvK1TEGmeQ9JyIr0/q5R+W1oHLQLGRiNFggE3aXUujYGCrz/KurP8PSYPQFgucgcd2D8iG1KvdypnMWdKXAsiUJQWB8sr5eK0M4HozwthX5reaBadoLmRVXh/vSxa+0Jf8KuAUmCFcS9+KmEcaMEb/3DoYfX19S2ZofzxcnF0Ug1Tvkcg+KcJBOZlHjNmTU3KcZ2BOIK64KHTxMouaWeAFB9ctsReSlpk+y0jrXYlYI/0IN7pvBIA48jema8ilf9x8gRU1ykm5XCpw70XigG0HknyUYgimNn',SIGSHA512=>'MqM7BWBoqpz5gKfMJkLM2oyYkRQNgnlefu1knM67BLoDHIlSlBRIDPZdogBDdalhVEKMN/NmiL//Mu/sjoenTo1KH03+gKW+S9NlMxS9zUhWu2goDnyzVKgulmKi1RngcA/Z0WGd0WqMLorDna7S2c5hwTRDKn8vVCt/6ts27y/6LCrdqMXBQtyV/ochYrmdWfU7N7Bo/W8ZzbkuGFPJjG4S1LrrwQGDZyrj7SmmwhMPC6NSJLrNGETCPp31DsNqmzDrQUYbuv32HvalMSp4UXE77dkgTt4XxWkmlqgIEYb8wLiJbIQl66rZ5I9Rg2c9S57iIa+C4X9hG2qtgpfXts8vHPQZVyvV2plsQdSvUtqXVG6wWZ2TANJy73fgsqaTAj0stzwzMSMQyEzrCBicq3JVKXxH0r6ufFji+Hd5Vm6ajTx+tXy2blzVwXFVnFO9L5aQsGMt9HtghdFvAxsOJbooURYSvdJ42SjfKR95D4nuUlu4S9n2K9UTjrJRrL8H',ENC=>'Yz968huyr2owVhfL3v8whWwzh3VwzP6pAoFd3/lGAlHpOb9MBxxE3dlXoHG9P9HCfEJ7omP0QmYVjlFjxHKayNdKuB9TMPVkxky81kXqNbs1bLHWut5q+PxKhqK3V3Fv0TD4Dne5f3SgpvIYT3mlf+/iR9dw2ruh8CGBqliMeqCzsGwp2qQHzm2jd4AdyuoU6pYfYUh9wJzFNuCmLiM+9Gqecs/O547yy/jjAYUrHTsOQb3W7SZSZ9/xZPPXHV15mE69KZVjqGKQIbEAwdORFaAP4+eZ7+lPCJpScIkrNQfiOyg2w5h4o4ok/zuRb+6Kq/SnygMTUukGdArhu7wSTZSwmzdL9tOqaukycbYl4t6ZL6mZ90YHgri9lUZTsJPCTj6IukOkWS35YIzeAW7dAybLPvHTyS1jBVO+CwECgBhVzLxtMU0JIf8hVO6KMNhpesjZ58pTvpmoPIpeOl8MbOuku07nRB/gpMmoHpfH3+qX37qBbL3cax3ZbBUp/3oe',PRIDER=>'MIIG4wIBAAKCAYEAwi3sIpzKIYISQMceili29rcH/Z6SjiaX46i123vDfDS/35s/gMoumesDsiafqvPfzreXnghaWx/ZnMtK1wox0jCjjFn2ZeLVocrkMLSkYUKNHlMbeTfhLrDmijfZM6j4vjSYrvbCtA0QVEeYCIHujXVoSdMprqQbK9zgNNFyGz8yFMnkVZxDa3jO2R3nYdcvxK2hzL+93azjUwdpjbC/yojTx2SgJMm9ETkpJVzMaDpoF1iSPf5a7TJxcEV5K+s30iKSRUc3QW60nkTAhmGsuiNvY1iFNLqtoBL0SI89fY6Vxg/DdGco7vJ2Rs8IbKTSA0QcHoHjpZauw5a1ikPSvm2gZXSEUaS1A4fDH/JgSBh499yhqYiFkOEENYgZIOVafY3R8ZlAQXeNcyo4Okngv0t6OCX12ObzlmESInjCsNvjUVC0omJnVAm/hM5sMPh7SOaqYeuR1vBqGyIVRc7FJQ4UqRDf0jOTbm1OGFirFpVTZKPl1FkrgrTWf8kxQTFJAgMBAAECggGAAouNi8qYT6YfzR+PA+szwroVbbqVWy2gUgiVEaJmposedLTZOTvtLnFJJB2jfB8kMNZxM04SuR0KwiZb/cORcZrXmfBX7W/ysuMw6H6FpQy1Qs9+DbGwzubcrrUasLWnRP71fV2YobmGHESv9nSVht8iFc2hvztBa+rCOY8BOuAyLNmUl5arv43e0DO3I64pXx+TflaJC43HkQAI3yWQ7furIvLrsm++fapNIsM7nqYdVSkBCbT6xh8iI4GVnADCPavB06mT1X4VZb+WMiSiCCbgirHSfiB/B70GiFgyAlslBuu3O4a4LMZVNvXr7tuPz+HdkH6sjjyaNItdjIwW60dauUDpEJmizY8N3lklQAFRrFUeX48KSYrsay6uisHgKDJhpDBu//pASriKmpFvGrOHzzuv6GgmYOQLYWyWaXWW38b/7wSa8kArPESTEuG9nmMZGByIkd56OTExDPFkeCdPOZmdUgLSVXEsoAX7C7e/iqR0YXsijghVNjTZKfbxAoHBAPb/e2VZ0lLXWVl5xrhdEzl9hSyWGSFxQzBf4F09P6oanulmoPL7vboP9FMoj34hRwKpV8ikNl0eRSttXsOjgqTgaatHivaAfTrcVSvhYdnjHI3Giwvrb7DSJ6ezbg2XJIA1w6vwh/cXz/gAoAmL/NZ8zdAvuxNk3xFixYIZeY9SsKFiSKf7jxClx3/BQ7JbT0TB7QWGGFRM0IYaI4RnTyrSiJWxZVn49ymXp6+yvbyyJxK5AlUQpcpuTO2Wv/Mi1QKBwQDJQaMeF90Dei7p5rVXKJunHrRmVZa1HY9SLcgckycWKfDhzb7k+RFa4VGVu6nfdx/haJD36xKjBYrt0kn8rP0j5p6OLXmmoUQ+IeobsvBg7QmrHeyw3Jwb5b8Etg3jMx3UDn4obkBdExGIBu1kScJ9oOyNEQJq5H21cdm/rIWdgyNg/k2TIDl2BQ2lJTIxe1iuZdzjgsaT6QLhy/hFl+pXR/OEEpzaiJbTb2io1xR7U79tCeA8+AvHghGbHqmvxqUCgcEA9Vb18ckTghfH93lfazeAZgWI5628DpzbWUySpuq0tzk0CbBYRKLLZOp+DK/oQCe7yif9Ox3ppfrwR9+eVoOuvCjwrSImJQ2h1nqO20RHFs9hSG4jJVbZnXBR1WED+tnbdsJwtvP3ifeMKtIsJO942HAlWxpeHzh93l4Ww1Ccj0FakyL1+m2EQMv6aqrEnH/YL/rUfT0iI3IdWmbSSqz3VRjEdLQ9cO48S4MJHBtWHf1zlERSzb34gCepoAGybkZ1AoHAPNce3KYSJk71h7g68dJQ28CogJc3LCF3hjxY1mqV0llzfI+aOdYhrPuYkk9dFzUH6jiWOpxR0f6G9UYxH7WcARJitFCDCiCOZMoT37PEf0ipN5WgTAclGjnl+SKgKCL3zXdkJAzQYFK3ZgvSEBNMPHY9jJerx2yzo/p6/TrGWcufEl9OTD/dnxQAAACyn8rOEEqy8AREy8oRGPl0YHWAXkpeD3sg99962QhA92mtw2qZ3/iwVT4XMYTclaw7V+wRAoHAdK3FTrMTjbA2ndUf5A0Chuf4kM4viSEWomHe30HfP+63YiIK8+8fjg2G+5xNFIcXho0Qc8JIY/N5NGVxHCh2oPwPtAlNS3xnhSm4q7FKB9zbZhZv3KpTmwZHwiKfJLSBGNdxO+9seVfYGgcM36K2Lkb99kjOaYDbpooQQkebOecq2g8vmuLDHwuwdAMCFE4tD7Da2fopyRRKYR9SWal7sf+SWnzGXMui0DX2pvwrKy9Kxcg+zReUOoPZKBo5aWgo',PUBDER=>'MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAwi3sIpzKIYISQMceili29rcH/Z6SjiaX46i123vDfDS/35s/gMoumesDsiafqvPfzreXnghaWx/ZnMtK1wox0jCjjFn2ZeLVocrkMLSkYUKNHlMbeTfhLrDmijfZM6j4vjSYrvbCtA0QVEeYCIHujXVoSdMprqQbK9zgNNFyGz8yFMnkVZxDa3jO2R3nYdcvxK2hzL+93azjUwdpjbC/yojTx2SgJMm9ETkpJVzMaDpoF1iSPf5a7TJxcEV5K+s30iKSRUc3QW60nkTAhmGsuiNvY1iFNLqtoBL0SI89fY6Vxg/DdGco7vJ2Rs8IbKTSA0QcHoHjpZauw5a1ikPSvm2gZXSEUaS1A4fDH/JgSBh499yhqYiFkOEENYgZIOVafY3R8ZlAQXeNcyo4Okngv0t6OCX12ObzlmESInjCsNvjUVC0omJnVAm/hM5sMPh7SOaqYeuR1vBqGyIVRc7FJQ4UqRDf0jOTbm1OGFirFpVTZKPl1FkrgrTWf8kxQTFJAgMBAAE='},
25 {ID=>'key-4096-3',SIZE=>4096,PRI=>'CCEEBA3A5E569A0B551465A378927C200112F9B117C813877AEA1E01C6A9FA1EB71D3521ECF947C1E99AA5F89322A940BABDC5DFAC39B1D2346112B80DC70CC6199BC4D107908D707A428B93A770442E901BBB6FEACD65C2A43F142964722872BA0B2DB66A8F93A10A8EAEE4A940C8A51E0F96A39D70C7B32C941FF57754B0B8B4D5CE3FFB3FF11DDE245B91F6A9790CD0273B53A76287EA9F07272F9BB3DE915601392BC88299B81C2E93FD69192E30BD16F594AB240D72F7D45F04C62C7A2A48A90091ADBA629329EFAAD4CEFFAE840E00058266D2D392F252D1DCADD4E6227473D1DF1B99CDE8395B97E6C4F2B37E67767515B95BACCE0FD410B6334B1F2D8D3DD9D9D6E74E2C6638CB93B672F2F2CA06F96B7C9218B996AD6FA1EC58B43E55F9FAE2F3DF7E56CEF5B624B20728631070EBA15326F3780A631274571A2181741FDB721E51669F35A6AE8BEF601DE61CF880E6AE28DC06902B1E0124F2AF81760C73FE2FAF3BE6F0A0D98D24E6DA932150F5119F00BA5E4C52224530CAE4A7F6F2BC5B4E3FBF785D26B1B957B80BAE010EB3E0E7C441CD6E5F442D92EC6077960C2C646BC482F02FC5A7F03233615DD35310FA0A45D49C4C1EE18CF009F89B765DCBCA6254D485838DA088FAD8ABF77DC9972C7925B68029EFFFEEFDDAB0868EC67A4325F8F6C1CB2BF2197753FCC9C9928FC783C3A08F6A829E08F683C7E9',PUB=>'D73271F2080D423B6E9CFD1542BDA9EDD13E373C54F21AAF4C50275C5F4298BB14F2A2139B73D187F1D7BE27708C1AA49F8E3377B66F5B626EC57795E97A2ADA409862985A2607371B64666C7D5A186AE529B17F5E03F6F5AF13E6530C61B16FDD02CAD7B35628F275E90F6CA1311E7F2D26E042C30B4E24DC3BB133B36721FF685300483B3AF2F59F975C60FE3AD3D1FB76AB111A7E9AC46667D7D466ACD616964B33244BBF0502E218A71BE493D805EB8C06FCEE41194042B5AA72D0BF71489E4766D4F3D04E16C8A1F5D239069B27B861D5C91C4BA1A1D2415C07EC6A843751E0C2FF437BAE488263798D24CBA234214F7BCE7E1AC2D61C496CD7EBC23C874B088B833C999EBE495A13CE1EB8344E87C7011093C71EB82F5CCE162B1E7F7B4F26986C717673803C655E8958FABEDA9A41210E75EDBB61FD1AD2D0DA278D4E33ED85E3A44E78A6D9C46848643894124E212697118A76B907BFDD0BFD223C95CC37410A153F136F8493CDB9BC8A696DDC2A4F680258968BF653F057E2F699E5DEAD4521543E1A0A84B218981051C74F1049336DA1F6F42B551527D937E8BAADC7D2454F139C6F2F6FAB992ADB749B67EB1C3376C2A21183B4E2D00AF859DBFA0D8294AF0B0E893082128642A60AADAE35A67CAFD026FFFBDF2C22A78C5103DEA1B688FE6C6881E39F5A2D9FA76B3F966CD682A6001F8493C0F09C81501EC8CB',SIGSHA1=>'0z7pv3ZkLNZ7m2OCfeVsK/onLnHpPDrv0oVf5e15pMgVnCZKeGkwC9gMAp3iEmbYVdBxObKlRwFRitWeAqqbBWJICFIdxp144WEus/8gWWnM9jTTLSnuj/iWhylh539nQ+PaJ1GDJdLizmRFC/qSeLx8VLAz5vjlVZi1yg3ROjjJkkdJjysBx/e9PkfIeAnDn80WR64nLAgkneJcOvUla+Ld8RVjpzY6Lqr8W71Yi+pAczh2nE3zSKlE8Jjq7Oq17fmdkpluLqk9HcItooNfTCpJjBW+XMAuU4JWzHutmjQhGJmLQYnCRFVMmnC6qoEacVFeXO22bId3W5kquaiV6drJvisRwdenHIuNepbvP46bvYvArKCfBIFWm/ELvP8OmPJ3OIthNBVgyWaLFW1HmmuIOIXOr6SMmqzMxZhnLoP9wBPlgHz5guVPAGU15PTnpHSIqJSWkOqUoYbdIJosfZk43lvx+6f3KSjksddHoDQzvXKh7URZioLImIdZuThD2x6tTQrTdjl+foikq9OZJRDzSbF4ujDi+5plbcA6wDOJjMkIJSj6AJIXp35HlqeIVmddP8NPzhYGFuX5QBRKOSn7tI38pEPbWntLg21LndL6kkKUek2+yWoPkqqxdO+llXueK5uENnsfcasab7g6YGvxU9feFUEGtHNUlX6gM+I=',SIGSHA256=>'Ik1d9Z1GYsJYYrAKo5n212XICiiV8txKBH+0r+E4IdkIJYu0rbE/hQIstVoJ0jAFKu4P6Qsctad4Z/UfZFwlY3+LU9Aohimukb+ZHRoRPbxbncanE263OQJN72Pi4hny/L0w/7BNzhB6FizmkvTv04QBSoj6kLko1n2DZkYTGkjNcolEUgVBIecdWJY4y8TcXZ3O/85kn7clHNqC+g5wv7SAOiPpnaOHwkmISiLfFTQ5kE93mgvgSrI/GazXOFNbV2Kb2/KrQstyHgQMvgfWSDyOqyfJ/5UID85NeiTjoGNLTuk9X0fcCS0K210Nkbs8N+j6E/zF7CjTrgO81Xb8GA9p2bEMmKJUczKLy9egpcBKnDfsr2XFgPmBeej2RYnfsNjxs6vM5unVrIkC8207a5f0pKR4+EirXYmVIY6waq5L/oTvpvDdkn3uKYptPkjRWDxCDqjOLsL8kkFGS/fJ1TkSIQPhq6TkSRQfOcB7qMGGjeVnYoHN8GcVnAxOKb8wZcX7E5Zx1Vj6t+ibSooaYR7fDKU/l7gyhUEKDRxbzL79OUC7sZVE3NOSutdtgDqprM3A3unxCGSwe2x94hUto8RxR/hJTHIDgWiaGQZeucAzHmX+cw7QlmxiZQsVOghaZlXr4+1HS696bbmcjXDBng8LOPIBUWmGlaNPA14Cdz4=',SIGSHA512=>'Vu7cM0ta4RWQeXHIV+BkvhTrXM2gJP6NrqXAKN+eke0RSC39wxb8yuwuD17vzjOmv9JEfvzSKhANT9f2qcicxTJs7phwv/2FgSHCkAixRDQ71OneME79YIxw7C+Xq+jXNIVejYAxFBHL6kapDekptDn1EjEOKLdECVNeIDBQ1pFn1+InqPacKg5G7QxX47HyRJavTi85/HqOE1ZMZGuFXNVbSIsI4j15QkVhDtsv8hnkx47J//FLwpUCVtMwG1gfhh1jMFecppR/170wS+DoCOE5I1e+1HDfATaXDhlgYEOAGTNufCut9ag2nF0vEP5wPW1e093hOO1pEHQ7gWbrM/EpLqb5nh/85kVDrtwFrRYfGgxoPIakLhf4EonfKESamEsS1G6sgUo4iMTUuQR/zD77/H/pIpNghnuTh4hB/oP6u0Ztq+3DqX5ht6Bml7HnsFGwIqwJYZ2akq8+y61BNOSl0WoG/gYoqMljDKgWzfw4t9Qtm+qLTiAavMK2CxG6EoBrY/rjCgkHjReBVU7KChFSFiai/fHyxvClJyB/pygr31cjd4hUmOYIMWhfABt85Jm6rwhnx7kgK0h6PDN8nBuQJT8PBtwFtQ5EGwxQ3LescmhFV9502mF8aTxnlPyGfKhdOD3LNSnkaSQeLQvZzm6S8BjnuhkKpHfSdMegzqE=',ENC=>'uilkgenihQCM5wSfQflJbFiykXMbBrdidxfzDmwUDREvDPgsld4o/yRehSnGGVCbpNgXy7wB+9nlzd3wiSJu3URiqAX97greBaSV/UuBM4Ko3jMoQOg/UcTs5EfebQqoiPruje6SJa3T449S1RDdcm+71E2QvuCvHEOL1JzjznmXYVPIQjhpQ6JOuNR74eMrZecMaUoz5CTakhzhJY93y7oW0O2iz7GdbCNMK80NH5bJEyNvY3kC5zrB5KAJgJf6o3KRKXONtng5YT0HEIjyOS9uyPAwbsuNzHxvsMfxhZlyQM53OTy+AVwkrfTSptxHB77G2UChie/KCqx9ajwErGLT8DZhYUScozPh1KF7IYHqmn0YrnqTY1VEutODHaaOoxSkBd9IPiPjEKf28Hixq6QCqveV2Q5q8upzkSyTFLGD605nLCWjlGpiPUitl6Rlj6gJPMj0DuB+nl+rJtV9ggqpFhkwMR0Vm6Mj+3vGJUmON7dSbEol8Ede66eMbaCXSpjI3exkNqGO2MQw3JNuZNCU8tm68huqlqsRwUX13VRFEwRmzM/z4WaltP6/RhDHRDM5IXydTPcF+xbiZKMFIeK6dHvPHutQhjavIMBQibi0G5UQ4BMXVAbqETQfKR6RFWlBvsCgRs5RPmdOZaTAE80TqQv42ewjWjPqqQX0AcU=',PRIDER=>'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',PUBDER=>'MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1zJx8ggNQjtunP0VQr2p7dE+NzxU8hqvTFAnXF9CmLsU8qITm3PRh/HXvidwjBqkn44zd7ZvW2JuxXeV6Xoq2kCYYphaJgc3G2RmbH1aGGrlKbF/XgP29a8T5lMMYbFv3QLK17NWKPJ16Q9soTEefy0m4ELDC04k3DuxM7NnIf9oUwBIOzry9Z+XXGD+OtPR+3arERp+msRmZ9fUZqzWFpZLMyRLvwUC4hinG+ST2AXrjAb87kEZQEK1qnLQv3FInkdm1PPQThbIofXSOQabJ7hh1ckcS6Gh0kFcB+xqhDdR4ML/Q3uuSIJjeY0ky6I0IU97zn4awtYcSWzX68I8h0sIi4M8mZ6+SVoTzh64NE6HxwEQk8ceuC9czhYrHn97TyaYbHF2c4A8ZV6JWPq+2ppBIQ517bth/RrS0NonjU4z7YXjpE54ptnEaEhkOJQSTiEmlxGKdrkHv90L/SI8lcw3QQoVPxNvhJPNubyKaW3cKk9oAliWi/ZT8Ffi9pnl3q1FIVQ+GgqEshiYEFHHTxBJM22h9vQrVRUn2Tfouq3H0kVPE5xvL2+rmSrbdJtn6xwzdsKiEYO04tAK+Fnb+g2ClK8LDokwghKGQqYKra41pnyv0Cb/+98sIqeMUQPeobaI/mxogeOfWi2fp2s/lmzWgqYAH4STwPCcgVAeyMsCAwEAAQ=='},
26 {ID=>'key-512-4',SIZE=>512,PRI=>'EBEC266767F57B6546D65E283663987BA1240438E5A5BB1B6BCF2C107032285B32036A0E6DBA174BA1F358777A640DC7A97CB53BE03A6DA9DEEDCD44FEC74001',PUB=>'EFE10FCE3C6BCA1754A8CD1FF35663523C8F2130F05485539FB458B5DB787CDE0A9B3F029CF554FF7EE8DBBF9C366E353997E220C2F6FE445FACEC5748D96489',SIGSHA1=>'ZVcGrrM5ETnQ5PYONgyZw91dHWpUh/GPiHtxB96sN/9+aivi4hLTvX8bV4s4wXyVw75af9g6ITN2wEfmV5KWIA==',SIGSHA256=>'S3TE1TltPDVSTlV7VINZqgO/MNtBXGwD70Jc+hnAiu/1YRptX4/W66RYt+w3rklyaEzS0j94tjpkR9KOob4AAA==',SIGSHA512=>'',ENC=>'PVIb9rhsFtTY8xvZELeZfGPdusSKcpbPo0l1tTeR+AQmp5TPk2fG5lybdOAcgm6o4Fwn79ZnlMGH/XGyugXJbA==',PRIDER=>'MIIBOwIBAAJBAO/hD848a8oXVKjNH/NWY1I8jyEw8FSFU5+0WLXbeHzeCps/Apz1VP9+6Nu/nDZuNTmX4iDC9v5EX6zsV0jZZIkCAwEAAQJBAOvsJmdn9XtlRtZeKDZjmHuhJAQ45aW7G2vPLBBwMihbMgNqDm26F0uh81h3emQNx6l8tTvgOm2p3u3NRP7HQAECIQD7YqPn1wBWps2XLvMlfhom8Ye2mvmW0N5D6zNUKYX5AQIhAPRIWXP2cQSNJVw++lVgH8X/2y08bnJD0F93tI2DHCOJAiASW6fAnJDnwxKsgb8787OROH5CtZqYivRQXXLIKKgiAQIhAM+v31XHNclf0169MIp7oift4sNv+Jrvau5v0LLrwHW5AiBHRVVGyESfYAKa3AmIVlfIKw/81zaoIyLI6Cr82Jv4bw==',PUBDER=>'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAO/hD848a8oXVKjNH/NWY1I8jyEw8FSFU5+0WLXbeHzeCps/Apz1VP9+6Nu/nDZuNTmX4iDC9v5EX6zsV0jZZIkCAwEAAQ=='},
27 {ID=>'key-1024-4',SIZE=>1024,PRI=>'138CE7314CD3B9C5BE126A48FCEC3007E04E1AFF13AEE9BCA37C87DF0BB386D925091B52E150879D8BDF7CE472FCA79E9874E298DD8CAFC2C38B98636CA0B4D50679897C1C7609F2A490D9591FC5EEA9E9041D9049CF883EBC8B1862C7EA84149B0D8318C02C498C23CA782376B5288412124A6AF43BE62D3DF695230C17CA81',PUB=>'A874AEB0A2CD88A1D218A63FA7516A8FEE6E1AB2574EBD46853060C8FD31289D1C25707BBF390C1E8B3E28631582BF2670889E3FF456E17CD8B330E7BBBF284078C16039DFD348FCEB34B89AC6429C9B7248A40C8B3516E5880336E4D679EAB197006513809A172FF959BBDDEEBBE2243C33A21CDF8DBF1BE485D135011834D5',SIGSHA1=>'GFjo3b7o7RXAX7fqZn7BbAOOrRDV5ZhHbIFfjhiZZTBLBbci1VlgW1SJk5phkENuBnxU5QyCdqZy5AosPlKqTlc4ZUsaZQ1EtDRrB4A4+BEAkgEwSIvUfV94Qfr6eVLpYoCL2zXWLjQ1Ibk6wCbOPMSprFpoREA1RIiEIHYtBfc=',SIGSHA256=>'AtDMYj0itx61ffpcrEpEaHT20nTr99I+EyIzHzyeWpv6SZL59dErA6jomYFXnB0zDUYEhoY8JDYIiO4i7BKWdHij/ZFeFI8zoaYYPWxg6R/tSJjkL07Rwnw7OJdg0taNFGLeqBWPMx5FmI/UemiMk/zM8gYutdSKkKj1AabUA68=',SIGSHA512=>'iUgH8mE3ZuyELgNNClTZRAkkHg8hCLpZAqS6ajG78KNXsDW86jKH6KfKB3/MDcAACBBX2hraO+LtKOwfDXKQDb8WJgOlPk1m+NJpLWs6su532pVkO61IIf4erjGNgPwj4lpBg+EIm8ROrMu/NqfaUR6XhAZze0rfuOs+GFDsDk4=',ENC=>'M4ppg8LSgapManQogWY9YJfZoxJ6XkudUyrdU1lJg7DDpa8tWhF0Fip62DlikQuUZGdymy/B+OyMj+pyrx+J3l/a/9WZg6P8IbWQ7OKP3I6T/i52Sj235sjtEbi9OMp3pqTbZ0oN093Z534TdOM1PvTeF8/ev9p6sxTfATckf0Y=',PRIDER=>'MIICXAIBAAKBgQCodK6wos2IodIYpj+nUWqP7m4asldOvUaFMGDI/TEonRwlcHu/OQweiz4oYxWCvyZwiJ4/9FbhfNizMOe7vyhAeMFgOd/TSPzrNLiaxkKcm3JIpAyLNRbliAM25NZ56rGXAGUTgJoXL/lZu93uu+IkPDOiHN+NvxvkhdE1ARg01QIDAQABAoGAE4znMUzTucW+EmpI/OwwB+BOGv8Trum8o3yH3wuzhtklCRtS4VCHnYvffORy/KeemHTimN2Mr8LDi5hjbKC01QZ5iXwcdgnypJDZWR/F7qnpBB2QSc+IPryLGGLH6oQUmw2DGMAsSYwjyngjdrUohBISSmr0O+YtPfaVIwwXyoECQQDSxSxtScsdnADiCqd9btYFHD2wC078a1kWqBu5pSFLHiRB7QzIe6UT1alM49SoiHW8lFGU50UtqicTPzV6gf9xAkEAzJru4VIsTdIwjMaFdJ0rGCF3/ABy0fHzixNzjs8oKA240LTNl9cInM0Z6z5DhVdZ/4JaP/zmRiW8gtLV0PEhpQJARIi0n3zFPQWDC/0m5RRrJxI9xMaIkm9dco6LJVxabRCJ/Z3U8EO0M7Tf7g6PEZX9oqoftOlWhziyqAF/pCwtIQJBAMbrint9zJ0MUS9MgstRUmhvgZt7RCZhOQppqtuZA82NKbWfUpLg+PqZXS2cp0CoIFONg/jaA3cHkTMPj9lH1hECQGq/MEn5L4zFw7uFBJsuQyhyobenrVsmrN6S2kAqEpWAJq2DwGtmUcdyR4+zxa4EilsEcm++bDtoWKwXIKmLgRU=',PUBDER=>'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCodK6wos2IodIYpj+nUWqP7m4asldOvUaFMGDI/TEonRwlcHu/OQweiz4oYxWCvyZwiJ4/9FbhfNizMOe7vyhAeMFgOd/TSPzrNLiaxkKcm3JIpAyLNRbliAM25NZ56rGXAGUTgJoXL/lZu93uu+IkPDOiHN+NvxvkhdE1ARg01QIDAQAB'},
28 {ID=>'key-1536-4',SIZE=>1536,PRI=>'55B17891FE8D81B361F6EB4A32E996A954B21F79FCA5E9B018BE0864DFD172F80244DDC6F657D8B6AC9E388CF699776A10A043C70843A32ADD955793D2A5E0F5CBF12CCC4D0111CE1A0A63B49CE7DF67D459D4250B3D30DCC8D2D48058C17C7361D984F1166F84771E0A6E33F08C077B5877FFE177EB32638A3D3B522FFD351900B8E4E3867BC9E4A7800C4697076B686FB2C4887CADFB2E1EFDE634E3297873DF9E6EBA0E0CD2D01BD99CCB79E467125B1C684B6A0FC7549B0389396A93DE01',PUB=>'BDF6A20F8278E264AFA0CB65813170B2D2E5F465CC63F27975172E8AD368742F26BB3F1B4B768DA6C0B11B9052E81E3BDA442248C5A905B3BC878B2552B14D4E6CE391D557D9C03125EE744D2D082D4D6056CDCD379C7D552FB1014F1F040740D9FB7177561698A607B62697C6E1317EA5DB4F4004C2AD67373029C9F381BD01E3DC4DC9C4DF2F82E59C7E6C3477D22BDB5A98D3A85DFD4B0451D05334A2200FE145713CAE382DA4B28FAD8DFB6F11445DC221029A669941C6083973AA66E3B5',SIGSHA1=>'AliIydMDxlcEgZrUFEicveUH20lhn2CywgSkCHzQ3H9I51f2A8R4Ar89W6MuSARw5y42C8GfeZeeHAidxV3QugLsE5sdwlIMAG1D//js0g52CdyUBi9dKcIOtPW/WhagH+QkgjlmDy8AMFkX7pGx/VzDK94ZPQqvi7GwNb6EqnSWbjGFJeUHm/toB/9xj/Leg40ExIbfP7y4mXR26qZD7aZvGUQMIYGiO5MxWU4zJx4dhVeor7n9pbabu9/8qy2c',SIGSHA256=>'n/dvS6MCki66AQTUUc/X0RbypY8dNSDTKgD6rtKwIIpKEQwvlvoEmDIJ2pn9zNfYwrDeMR9rZjp4QCSF/Gv19F6fU03OtrhJK2Bl/gQOyOfd0lJEjIiWZTlSP4uv8iKw2AuMAFOjilDuch10JfhGtf++4p12TEctiDnOx65Ekt0GdpQ59gOiA+f2/3ydFk/g5nWX3wuCRWZmMeKLDiPnU477UcwheNXu/sezl+1phJijNuXOSjx6kCCufGJUZEXJ',SIGSHA512=>'ZR31PkjCEvSAE1r+6C/FZxM1/G8uJKU86QTjuEBVcjW0EDckbOf9oWI1JFc7Df8/xueCgXoChWAyF5GSB7Untza4hvCTnaT6pqW/GQXnXwDvshtFLnM5T0lQdThhINVOd1/N7ThKjXv60AA7Ml20bJQtOIc0HYkANjkYIZT4jg37lEyhgXqqCT2UQFt4AKpL6raDnJPTiSJBTWgSU36JFR9BQRHAd4oNyEaVfymjTVaGwYPgvl/NGcoP63GkZ89e',ENC=>'Iy/NxEEN65dGboxz9Zpa1GeyZZgOxsKkJfqvXrhMIWof02JEQlTWWu8AZmyM5clQD93l11Qc/6GXvki+R4pgNIrCuL4qb2nF//6zdSpNOWYIW7oKTRKUBh4PDwZU87QQOtFmLLxE36ZEeu+eG/MurQyC09QK0i6Ti72jxjuVD4+l5/n9zhTMXap4hwlRHRcoO4wjyfTNWZwQDUtkJTlWcQV1DBIJb4gskCvpdAGgCWC7ULZHJX8OOIbJ2Iur8fhS',PRIDER=>'MIIDfAIBAAKBwQC99qIPgnjiZK+gy2WBMXCy0uX0Zcxj8nl1Fy6K02h0Lya7PxtLdo2mwLEbkFLoHjvaRCJIxakFs7yHiyVSsU1ObOOR1VfZwDEl7nRNLQgtTWBWzc03nH1VL7EBTx8EB0DZ+3F3VhaYpge2JpfG4TF+pdtPQATCrWc3MCnJ84G9AePcTcnE3y+C5Zx+bDR30ivbWpjTqF39SwRR0FM0oiAP4UVxPK44LaSyj62N+28RRF3CIQKaZplBxgg5c6pm47UCAwEAAQKBwFWxeJH+jYGzYfbrSjLplqlUsh95/KXpsBi+CGTf0XL4AkTdxvZX2LasnjiM9pl3ahCgQ8cIQ6Mq3ZVXk9Kl4PXL8SzMTQERzhoKY7Sc599n1FnUJQs9MNzI0tSAWMF8c2HZhPEWb4R3HgpuM/CMB3tYd//hd+syY4o9O1Iv/TUZALjk44Z7yeSngAxGlwdraG+yxIh8rfsuHv3mNOMpeHPfnm66DgzS0BvZnMt55GcSWxxoS2oPx1SbA4k5apPeAQJhAOKQBDvCkng+K0QPqSD42TxYxQohMF7RsxeywyXH2WtCtYMMp9RqdCHwNuhYtMK/gVOQHZx1RQXcRTREsz6Bk5iexT0y5oZEPUZXBitU0CO7EzPtLvQFlK9ygPrmH3hzoQJhANalPu98GLFoJrGB3rD92po1pMMvdP6qFIL1tyRd9IubCghu2XM3LeJHsAXBukK3S7PszeZhsnpKDCW1lJa3mk8Uny7NyFQBDYRzvQ76273aLwettwUDc7et0zNbY/Q3lQJgR6Sq8grRLlzaaadaICcQ6thXVqCwHwvIylGpDCVqR1TM+SfjWnRfTOwdMNP8NSlByB7mfjdHIFdLOwAOflGTTsvGK1gRNZwWlEuok8M6HlJl/CGgm2G4ZtKanrxubzSBAmEAk7DkGxjCTN+jMCRyPEqPregXVI5E7C3PK0UzHPzhFWY6gw7y5IolMjutbGieZuWEW2snScwTaH2m2hOVCBeRP7SqyyOhIdwPlwGkJriJlpqYHapz8ikr6Ejct8u8fP/5AmBkbTPbfZID9SPHe2f0AnaqxkRWlpT/mhfFXraASJbxZotTZCmHPvr4wwGu5HtOTqitIROtqJA0wSg3fz98tNBhPdBXqUem1aqhXFvKY36s1uqWXh+aQ8mVnARUNqsVzvE=',PUBDER=>'MIHfMA0GCSqGSIb3DQEBAQUAA4HNADCByQKBwQC99qIPgnjiZK+gy2WBMXCy0uX0Zcxj8nl1Fy6K02h0Lya7PxtLdo2mwLEbkFLoHjvaRCJIxakFs7yHiyVSsU1ObOOR1VfZwDEl7nRNLQgtTWBWzc03nH1VL7EBTx8EB0DZ+3F3VhaYpge2JpfG4TF+pdtPQATCrWc3MCnJ84G9AePcTcnE3y+C5Zx+bDR30ivbWpjTqF39SwRR0FM0oiAP4UVxPK44LaSyj62N+28RRF3CIQKaZplBxgg5c6pm47UCAwEAAQ=='},
29 {ID=>'key-2048-4',SIZE=>2048,PRI=>'B92632A9156C7BC7BEF3CF78EF1DED9C189BDA23C28FF64AE8D09B76BD3425EBCBEB5EBC8EC6A310F012AA4B4A20A3A7A674DF2DD9E8060C88C818BA242AED224A7A8D32094981D3B3C1626BA0B25A05E52C10744A8BD05BFAB5AD4021D41999231AF5D7ACB81B804989F47157FE560EF30A39F4DE0DB1A85F01DCB6C3D237DFE838082BE9E6D5B519DD0DFB956F85BB9D71CC5A90EEEF06E800ABD2E1F70F662C255EA8754753B18DBD203EB2D5465B7FA1424F578CBD754E1FA4EAB375C96885B95AA50E69C379CD77D29601F4AA3FEF4EAA19014CFE3C7005E3CBEA8D0C30A234F48DD8D9197AE3AF18F50607371A890FAC2F9B522AE6D32DC3434D876EF1',PUB=>'C4B124670789C9B6E294B1BE5EDDB4A42C00DBA26B271B369A35AC6E2B5C21E946877B8A7403AD0DC2D2C1D75C05052F27565992075E8F313D63AB8127BF0998548A9D9DEB5B806D1C60484ACEB0596707A7F32769FADFED0E8D36EFF0E120BE02909F18286694F3936FAA2196EFABCCA18FC11EA98B04B3AF747C473A584BDF591C39F1A6E759E2E8056F17C736B5701AFC6D81B7DDBA185B633D9C412A8EFA35F4877CB169E03B2926C3A2BE17B40831563C40B89E3DC8CF48AEA5DDD751603A9D5CEFBD8BE271DF8D4F3C410747437C07AFAE8FD6C05E07DE2BD04EDCE2214F752F28434ADE844C4048772B406B1615581459B882CF619ABB0FC768628AAF',SIGSHA1=>'gOm25U+tNjkUR1HD0Y8mHfwsfD9I1vxVQf3euMk1TS6xXY90VoDHsUpzBOASdwOYoz8VXFUeBiIV8aPxpuYLSlcH1+lHSWFKuID+7ScwyTSt1qAKQAr7u/lZyKC7KjI6JTogqpHtMKD1SzslkHTmDzD7qKg6o3nf/wwbOkrOXY4g8amqBkF4OKozWCdedX2Ez2hqEPPIQQdcC1bDO8zID2UzqMrhD3JK/dzxOworV4P0aCAQU5TFgTe+DO5K6F/fY7ljA9yhhFf8aX4bZ2r5AWApLmOpY9oGTGmt21CBj4t0h/sH3HxSW5Cs6cG96MMNU4nKuFzQZvFhP6U7SFET2w==',SIGSHA256=>'OjtRR8XDn+WWenwNzdUAumtq+ZFBbrG2hgmGccSOkfQ4D4+hHRVO2FzRe/OXB1qnlv0QhEg6t+1hQsLYIZM6BPg5MAk09juHCMVqpXk3LkHrmbGzN63Pk/C//MPzUGuAp20+bI9EXJK5NORvxDx6gUK9AlyDytAULMzvNd9DgdffTiuabtKckiclTA1YHTcq8JPGVNg6tL2/hWRJme1Pn5Lee5aPlPD63oCwRjvgK7WAYZiBEvG6AwgrgPXgusIXR7l4cDcCMlPIV0YQ0oYxiutd7LVAwrU+t5vFAy/ZicccyJjVj/AuBqrsA+a1JIi/mUwTgqb4eZKlPuxcc8ZT4w==',SIGSHA512=>'RA40wsW4nU+cUBBs4fNmBWZgfy6NjXfAw8Mw97+x55QZXLRuSJODEh/kgKSzuCBzJdE8g+Vi2Ll4sL/VAzGr3iLv3s1eq4YH1mLHODoAC6593tPum58b4tcg7R5TwN88BIxDW2TwEQEyxi1bQy2lK8S1zfAXewQuj1KMQOkO1NIw++Ok78TG6dyNW58HFU+e7nXGxj+nxLt/1uFZk4aATIyLKvdJv8wx4YtCY1i82AAzS2cY+J55qx2IItTmbjuBW8uctbrASGXpz5DQC0KWD1GbqOWYzyteUjcTCHEkMr9FGLqV5Mli/x9SoTIow5dQ0NDyWHNiG9+4MywbP1MBJw==',ENC=>'YlUUrLX04jonBaZpHJsA1z7sf0hCdq3r15pyJwAOtIItEwAJgJBBdBIYij9P9vX6siIi10idXX2u26qqd7Y2nRlNApxcEq/lpsygnrS2xm5g2YRzlOPYjSt0Vj3tJ5XAaRMr+rZ5qXrZl+OABbLlKe6Pck45daXglPwC5tETrUquUUuTwFhhtHOpx1yIwpTSaT2HJdvXJJl937g7hP21SFBEnwFd9uizKZ4feG44jWQbxJ5AWtd7x4Ya24nJynEU7rpiJ1FBcSvT/cQA0OUCsXGlU+o7dAo5ZifN30zI3b8+U6SDVDewHQ/gtLX4eI4StrEwQ9S4oaYLQSDx6ZpBnA==',PRIDER=>'MIIEpQIBAAKCAQEAxLEkZweJybbilLG+Xt20pCwA26JrJxs2mjWsbitcIelGh3uKdAOtDcLSwddcBQUvJ1ZZkgdejzE9Y6uBJ78JmFSKnZ3rW4BtHGBISs6wWWcHp/Mnafrf7Q6NNu/w4SC+ApCfGChmlPOTb6ohlu+rzKGPwR6piwSzr3R8RzpYS99ZHDnxpudZ4ugFbxfHNrVwGvxtgbfduhhbYz2cQSqO+jX0h3yxaeA7KSbDor4XtAgxVjxAuJ49yM9IrqXd11FgOp1c772L4nHfjU88QQdHQ3wHr66P1sBeB94r0E7c4iFPdS8oQ0rehExASHcrQGsWFVgUWbiCz2Gauw/HaGKKrwIDAQABAoIBAQC5JjKpFWx7x77zz3jvHe2cGJvaI8KP9kro0Jt2vTQl68vrXryOxqMQ8BKqS0ogo6emdN8t2egGDIjIGLokKu0iSnqNMglJgdOzwWJroLJaBeUsEHRKi9Bb+rWtQCHUGZkjGvXXrLgbgEmJ9HFX/lYO8wo59N4NsahfAdy2w9I33+g4CCvp5tW1Gd0N+5VvhbudccxakO7vBugAq9Lh9w9mLCVeqHVHU7GNvSA+stVGW3+hQk9XjL11Th+k6rN1yWiFuVqlDmnDec130pYB9Ko/706qGQFM/jxwBePL6o0MMKI09I3Y2Rl6468Y9QYHNxqJD6wvm1Iq5tMtw0NNh27xAoGBAPAnxUlfLwyN1z7oywpao+QBjfeQV77szwqC83dtPSoRyp9Fq2ATqyiy3DzSIHescdQrysC4JF0DmQ63Zfg1LMzh30TPzJcrDOB/YcbYsypC6by0rr+1MXgC15keMyLVYjYH0YoT4ry1lfE0cYe8s88hKMh+oTpBa1+NnVyitg1nAoGBANGrRhw3/UneF0LGpp95nrpvLwEObjouj3zKR79G5CfIGVpqf31h+MxK8t0t8lVVgNoTzHJhAaLIIGyOCDw+gj/7hQ4NPPzbzC/+WF0/8vWXBFuU8DzLpgoojd3tPHOY1obnC2rDsE+SEDqmkZRgGB/M9OaH9jccxBb/dT4logN5AoGBAL0aQ/Irfiu/gM8rlb24c7b1NmnLAhz38WvQg4/1t6Tpz4gs3u5PboYkmOFXgHNbmWI9fXDVTuTjEWGSLjwM+xL1hM51Zh9eqcwY4dAnEKVlfRG3oKaaMbLTYhtSuWdjaOssquW0FOUNg10kM4VzpI6kCK4fcCskGj1qkI/CG+JfAoGASCVuV5Fwh7VzPZgLh76avr45Z1ym00BoQWF9dLUZFxNEnhcdTXCj4vA7R55iz7g/QUskw4rbvD6u4YuyC8DaoteSfjZR8RRU24LitxulJ5rSdgz26YSN2tr/jgjvDzvdPchM5mz1wzuYeAYO/AZg5rho4NaSA37TfrJijoL2j8kCgYEAhVKy1HTeKwvPPutcFfgRjn7sS61XpTkCAleDjIGOOQ+kz8zuTwONvotEoMd6HFiMeV3pM9zMyFk7rRrlJPmvecjwTznKbCVA+oidUFQ70h2fAhyg3m6ujZKuZjhMwkn3WnR8H+r89+wfRZMXVHfuO/x0Z6/uDe3c/zBZNpViQb0=',PUBDER=>'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxLEkZweJybbilLG+Xt20pCwA26JrJxs2mjWsbitcIelGh3uKdAOtDcLSwddcBQUvJ1ZZkgdejzE9Y6uBJ78JmFSKnZ3rW4BtHGBISs6wWWcHp/Mnafrf7Q6NNu/w4SC+ApCfGChmlPOTb6ohlu+rzKGPwR6piwSzr3R8RzpYS99ZHDnxpudZ4ugFbxfHNrVwGvxtgbfduhhbYz2cQSqO+jX0h3yxaeA7KSbDor4XtAgxVjxAuJ49yM9IrqXd11FgOp1c772L4nHfjU88QQdHQ3wHr66P1sBeB94r0E7c4iFPdS8oQ0rehExASHcrQGsWFVgUWbiCz2Gauw/HaGKKrwIDAQAB'},
30 {ID=>'key-3072-4',SIZE=>3072,PRI=>'19BD174C627D45201D3EA4572E9C4FE90F1A130F823941F31D5F720537EB20C688478772118334D717C9E6F85341EFD6F38CCA72CB6FD6F3484E930CB14E77152891EB66817F35AC80ACD2EF8B363D029EBCDCF653FDE00412501FC4F1DBA28411615384CD0E07A34CFB04C1FC21C2837D8053A2D8D303583F84A2EB981E75B9B4A4D2EB1369516E8A3D403CF8BCEF08420B932C11DDB81DBBE1C91CB96E477D5BC477F4AC8A6FA3BAECFF47AC2A14297BC8F4643910A4F69DB589928132ADCD21902C1C4A919098D3205560CDA13E6DB7BD932CBCFE04EC0B2E38F949E0D3C67546C39D23261BF19F93E28AB01771837450406E347D088ED134EFF599E40EF3000379F4B8EECE6B7026A052A457E0ABDF1900E545F3965F7B3BA6587CAC8E4EB96D0A7C4E896410AE0AFDE1A98D0C3C87C3C05550FC827604AD88B4EDA685CC5CED1A575D112E1F23F216216F4D867EEE40680CC77E00E3D9F28975039E458E4E33E8962387699F92E76488DC058352F9A589551DB859425A93C1B7DC17B521',PUB=>'C34D99317675E56CA42B158B0281207F111398C80C5A58FD75E5027AD37622BA590A46E302CB571EDFB13D54ECD4AB5856A8D435A51561C18E6A6363FC6B12287A53864076BAA5CC14C98A38CB61F76E0BA9ADFDF4173CE89087B1A9EA249634D0B4D485A23E7134645EC7DCB211AF3D169C1E16F47746AB58254CCDCA87FBBC9C197A33D202B14D42F34C72AD18265481765439E34D63A9B0411E656276C3CA6395C32749A0FAD164A62AE111B00A89F14FC42989FFE1DD29D393FE4DC03E99C824B3185EBD67DE0AAB771794E4750E4791C204568B6070225373E61227F61914E3FD5C978B78E7F52DB16C1FD8F99423620E691CE020F1C11B4B088476AB28A3CE24F90F6E9BB736A9EFEBA31E387C52317EE51632D17298B3166254F05A348223047372C34DD4023938FB189F5B4C8A2A2AB3CC8E0ACF6C360875BCE1DF7C6D33472894E76960EECFBA8E5DE31676E90D4761612642C5861B1EFA848C041626FCECFA0653880FCC744FF6027B4080A74FF537F6F83C4975F7B3F64E1F48E5',SIGSHA1=>'JE+V0sgCaRcvPPQ0Rrfa4HPH+S9PFYrlvUmLgqtcsZ57zucMSohFFzd403aKNNYsHUt+7Zfn1XUS9Xba1iizCiocpJkwW5DkGCEBYbxFte9jrbrA0vKSNbR5UPtLfLaFS0FEZ3WkLh2FK+9HlkHHxJ9Qjn9P+6AwFBcMiSAkSE9k3RbqAq10i3OJvse+/HQFVzr3XbZURMKenopzlOnksK1/xy1ECvA15scCsmZETmwFJikLap0ZhyIDHbwwMwRDzt4fM62yujHk/njYT3cmlXEup/44hY2ZFm1Y3X9+ztKCjO+auEFbLbYAr9cXmbqYvV+sKM6dUsAFMQ5GhHImefGNcoRA/Quy3HpiHj7aZkuA71JXESXrZbPeT0UhwuO5ElsJqbugtZfrxvjVWBoMwnoXGarxqbRj5d6xGJGD73UsbGEqggJRXoxkRWhfi84OO7fVWWLdvqinx3/QoXD60zbyu3hoKOzNLisoCnZZOBmNjxzdWEMVltemFSMH1C85',SIGSHA256=>'XlU5ni0u19ozXRFP7hkkohW3gQ/LN10vSDiYcBDsg6L6agVARqd7fdEZ2Ir6Co9aDz1vdJZcsuq1iKyzky7y2Hvf0A2NdXz/79GuH5IQMCRXU05yC/GqmlY6DZp4zuIWxDJlR0tIBHt8OeigITQa7xkJjv4rFRlO4fggDDIqmQkRltLylrwBb/XhwN24c8K/1lz1xxgmwU7Ju2IIfO5Mhw6RYkixRSNqUM00gpFUH1C3JgDOMKznoOusi7F5dKkEBFREO17EeT7zBkyYc/IVW7gnFMvQ7Spyp7l9d2jAs0CPV/p91RAC4d5y8XMRkEqVNqKI/qVFWC1ffWj5ki7xaw2Cvf+pygz59ssDpkKc5P4KIV1QsH+CZ//fuV2VBim3HXDAKYWtcbJFGzfR82j7pEeti7FyXcfLjWt2gqRQVNkgLjwQQ1gbyIVO5dqgekrvnVEwlcNoULE43laCVGaHj0JtJ7ZaQ071K2ssHcPMT/XHCCy3IsU4gwWM3HphSske',SIGSHA512=>'b8DMjUYBWvpEvw1IUzw/v7lyPUFGZsRxORcw9FQDrJJ+r11zp4sXwO2xUxWbFKif8vmGXEO2zKLhLwobCOKtptKgHHatSz2Q7w13NKiv/i00IXYCYf83lJr6y6BuYiksfdtM1hyP9nFMNooCDo2XLn+ugmJ6X3d6R89OXzH6uAXglrWBkl+sQ9mJT2IlCBvB8dRGWK9c9QxmEQxA0UuOlxNvCOSQy2z1V4+ef68hqRx5utoPOFeOn2Xx56zF/fiRucqp63OM3ZzN1tjEeOarI06gmnuJA112SR6Axais4EQ18StsmpIJqbWmvtZyf20AjyPmaSXOlVTH3IssF3X5mvjrdsK9gSkdZ9CnNkjvowBm/XgcZlLWfdMSuGEocd9FdL88E46GHtq83PGy4t4XpGZts90wk7EkD4nBM41QjDbk1JwDUMoqbGHGRfmEtd3mWTanNAtj1lrhNtZGlrqIgRS+EFfCrzMZgbqY7gC5vFJbjhwNuxb77pb1Y3XfDfw2',ENC=>'VwnZ1Qu0QJS0AfAmfQp0IrIKRaPTlpHZ/7VSpFbcq2rgc2ECn00l8fwq9Grfs29LvBv3V8abbcLtusGs5bWra/65/ZIVCziWXanJmbrsVYhp9EL0z839oC+UQySO7qBfIf/ShZvyECdxklccdmzWRAj/iGtOTe3vwREreAvaSain9lItg3Vgoh/52kbU7xkOT+0ezA5A2/aV327lVqZX05Irrev/uL9qSGg88orG5DhSkLbwasASW74h5qy8GwyInRQTqTWG4/t1yJRVHGGTY7Dzeaq+f1yetAfwxb+QbFiKpYOLwdRvAyw2xwP/Ike2mRqoArhaLWFhSOjTsnnDIw5zgwdHpK8scujvKQt3fpXfe+qjnj9Hd8yrU1ZEssyZAGrpkwl+udaEGUsJwWHqgb8DHqUyrqLfvt2O4/59UPyWBGfY6TPOFD/WQkgp3mD43GUs4aIu9o3I2UC/k/xxDkeViykQFFlw+x4+nalAPbmN3YxSJO8djMaT2m7FBk6i',PRIDER=>'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',PUBDER=>'MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAw02ZMXZ15WykKxWLAoEgfxETmMgMWlj9deUCetN2IrpZCkbjAstXHt+xPVTs1KtYVqjUNaUVYcGOamNj/GsSKHpThkB2uqXMFMmKOMth924Lqa399Bc86JCHsanqJJY00LTUhaI+cTRkXsfcshGvPRacHhb0d0arWCVMzcqH+7ycGXoz0gKxTULzTHKtGCZUgXZUOeNNY6mwQR5lYnbDymOVwydJoPrRZKYq4RGwConxT8Qpif/h3SnTk/5NwD6ZyCSzGF69Z94Kq3cXlOR1DkeRwgRWi2BwIlNz5hIn9hkU4/1cl4t45/UtsWwf2PmUI2IOaRzgIPHBG0sIhHarKKPOJPkPbpu3Nqnv66MeOHxSMX7lFjLRcpizFmJU8Fo0giMEc3LDTdQCOTj7GJ9bTIoqKrPMjgrPbDYIdbzh33xtM0colOdpYO7Puo5d4xZ26Q1HYWEmQsWGGx76hIwEFib87PoGU4gPzHRP9gJ7QICnT/U39vg8SXX3s/ZOH0jlAgMBAAE='},
31 {ID=>'key-4096-4',SIZE=>4096,PRI=>'55C0AF46546BD90CB30E805CEA97BD0647C5CBB00AE70B62A9132D3EE580C6479F0A5F10B29520331C6F18EBA28CE31B0A9A4F008FB41DFB21AEB556403D54DC07A2487AA94ABD712C869385A4CC8E45C68F37C14E8D620CA5F6B5C46046477ED733AE962A19D90641ADD05A5E50CD822D6B9E69912060A481DCA2D1D05FE518A544A2A87B97CA3290CBCAB1EEADED146C749ADDD875F16B223E7187B0FC3AE2BD2A4EE21CF84E30953FA28D4BFE701E28EA07B8B753855058F853830104174D99038E9C1595208C80309BB90E69C185EBA4167ED15C6AE2350143709C6B432EAA045BE8E96D6B4C8FD523EC9D59C26E1A1A413EF460E01F9C35B72D56FC61A21C897C4EE0BF996EE0338EE18D8C9477195135B577F90D65649F34001959DAC059AB9D35B957A3A7BCE4B736F52DA22166A8ECD6BBE0ACE8D380941351A58502EFCED78B32E4AE56D7A312F48541CBA2F33AD1749104609BF2A746FA8132080DF087444BB7E0C4EEC1CD40FF94AB6DC544B504FDAC6E382617E405D7C9C7B1DBF9E6C04CE0F8207250353E1B99FFA2D606365B3FFD7930B279F4318E3E9B38737E67A33D28247E20980DE16C753614F851051D829C6AC57BA7BB5B2D3024FD4AEE2B6940988FE612F660B93DEA964B5A0A86F21348E79B05637D0B27AFCE5E6394564E2B07D8A5E5EDFBA6297742604D2AEF4C3A604AECB26372CF092EDFE8A1',PUB=>'AD1BD1E8ECC4D4E104DFF0F335A2455C39E93D0A2B408F66DE6E3586DAB919BBB4FA64F115FDB420DF147D35DC70DE7E8AF7A978E9A269D50596E9461F24E3854E8C90F911215A6BDF4A116DB25080B556EDC375BD538CFBCC13CE58A1E48A8A3083E3C8E6F2B8D1B5D49140334FCE90F0F5FDF993DFEFA308F174EFB5D3D6669B9EF21B593DCBDD4BD63C1DC12F04D21C71630D605194E092EEF93E46729B08EF4072A8420114E133F9782442EDE762EE405DA3264D23E2AF2C03261D477FE41EA2D4B2C796E371A88727C374F47A9991DB495D7AFFA19DD36151421A31C0FAABC8B0ED5C8DC102DB05DF6A605CDB5F03FC25935E1866C43D3386BF14A652F7023089847CF541A8C5970CC8F6F0ECCE31DDF2B81319E6FDB364BB320C409A14332A8C6A4D818F3087B7B0AA88DD736132A984CA600F46EBB1544459D95FED495C9131C5672C32AF5A1182BE3399585D4B45792E02FF7D749F4CA0B8B68243EA3D918DE6370F06A3B477071EE24D25991843E4615626FBA6A17FDA36C1D4B5C3AF9468D526A8E76642DB1BC7EE13C2A92B45FF2D441E688B9E4143BD84FF41373F2BBF0C1AB31C603E82F5B222409D09B42F7AC23DDDFC87EFD1AF0A492C87215B00FA83A512A99BDB90F906E23EC25F8C5A1FFD54242465C3925F7979CF2B6584EB0C8791CF19D26FCDE437BBCBAE15C23BC37C63152ED76E67FF0FD922D94B',SIGSHA1=>'IS1AaCvHlIoGxIhsLAuC5+fBIBO+QLmIkkEHdaM2FZro6LsAu3PojEaYeJJpvB1kvwpqmQ9b9s9tvrgnG6vMuhyGxFhaM/ntLBtn+Aav3hFg4eljNmmkkHbJutcY79ZQ7pfGSSqorocXb7cArIi1mJjDL/9D6hN05o5z0qy3qXo8kX+qGy2g7/IT9AgSQTYc72ygbd56G3mXVqXJgA5JSH8im2/qGU+YgzbIi2nnZmZ3yftZCZbzLYMoR3Jf0owj80vXVl1k53+Yi7qSjGsRFvx3z9P9l8lnbgiyKBkPZ7BDZb4B7wVKEl5RGWPyfG+r9N4KvIiioCOHQlsuN4Nw9oykx4RuPtT4rKq8Tlc2ms+EJpud1BED/2e6VryF8Rqxh3vf/Fjgp6eDO5yHqxNe2bNevSJXByeF5HR5C8rFuOWzi5XYLp/Ul2yRk04+gksnAtMeKYQCKEi+vTB7qf2s0vCQ6pCTxcdj+x2EwPpNgbeRUqdkiL5eOn1w0FZcLI6ofwwRQ0wKl7fNVgDK1KdLD2gGxGm0ftHLseEJ3SSGd1ehhfxUNAS1RsX1u+9VMQwoaAIUvAX58ljnGFGpCgWDLmPBb4apCw6hKzw03BhWYpCWH2IRZhsWzoZmJC3qxcTmMaXT93oiHfEY80yuzvm65vhEhIrXvRJaTEQsKq/k+ho=',SIGSHA256=>'mp9/Hw2AgI0UBS5qg10uzz3hVaeVzCq7EvE/DLu7aCtftC7K1Ijrw2cqH4zI0kgZMqpEAIfNEzO86X4hUf/IoIRffljthP6fgwAzfYVEqS8AuWLOfKYWvbLbdciQD5nusMVcV1tQNEm2TIInHeEoxsTAuhBmyF5xDYc0EuzbArjBSzVH8stxODEWeGrbE0t5dFZUpeqJ4FV8encmJzbfi+pTBwra+Egm9Gr52okSZsUeCh6l1wsnMPjSdI4fokgaiVq/EKo6YKnk8EOUHu7MoDe2SoixL9X6HwAqewFyd66m00ua8pD+ASpCBx25Pdp6phBtTBfGeSF7L/7YNSNed5M1WknOxA/MUnAOviDJf9A8d4BnUp/RYTTWzjHALoR0b+SfevPWdqueg77khSqtdm8t8F/ldn2jPcIoSQAJ2Wufz3f9/ioXj5iU7S4n2s+DPgpxkVycejQ266JT4DcPI0MIm71D8VJ7Q2Y6My5B1NoruYkN59UD0SBcCKrbX8KdJbJDCfBfMCdxJXCikbB7iQMsb8VlQCZImxs/WY6Wkyr0NKxDxyFy8ugyk3xOkS4Sf0oYUKK+RVGuww/0RJsHq15GO5d/MzxC6x22r+ob0yFVCEb+nwZ8c0AdgteYecJcJmMhOkK4P0rnET7aSCwh4lXKWakYompSQjbCfRnBpQI=',SIGSHA512=>'F6/tpLHh96uO6opjzcM4GBYNOw+8vjfmy9oLKFJ7Up3ZP1SCI3iDnelUJGDCpb2JnZUJA4eXwdXP7pFml0gYtFnlkz91a1SWlDGxcpkgYkKjA1BjZrCat6Z5z5E9x/T374ulsnjtMW4EO1SvfOmyk8HdMePfD51+ciXmx2GygkTY0jIXtJRDi4+qf15M9u96mremlJtISvhlxur8BHPgkQUG3JNhXe7RUthXQZS5Ds4f/bDaoa7Hkb3618LQ+vN4+nkmPoEhxk3FcfN/Gkeg7j6j/XzvT3mPhcZpEnSLGpWlsU8zC4cQnN8hxHj/RHoWOEl8wBrPXbrulzGb5RWzPteAP6UeP2oTkkNkK7tk6RwUIrDFBGi6fI6prZwsZc0AjsqlO0Vo78WDfjVQ7Dzw0wUjXk3CtHLLF3Lsqv7zDXaEutskAg2NpqJUdOiHrSfodvR8PHCyAhfqDuYUdU2UYUR85JBPs+EGeO2johYS7zNWia0aPk4Kx75ofFddLWefQtbycsb+3Fq2CpTXPv7kBd1bOZbd0byS9pl9XXPdzbQz8gm1Ab8P9drP/qwb8tcCXsnAHGGcAdDM8Hshs3J3SGdj8Ae+r8mo1DSVDGw8oVgX0/pjFB+hwZ4SOoSbiMKLqs/ZrHg0jPo4BI3JDOyVB0w7N/J5q7Y8syQYfHgeo+s=',ENC=>'R8CRZVFaYglslNiGkVlDAl/D6ACtzyIlrphS1QBoOmLvotb/hdq6PNYWk8YcqYwj5r/gmsBFlQNUucXpAS3ArzrxbASvmmxTA0gZLoSKbvfbIKrkT8qGxfi3NpQPXG5nUMnry2SDcUXVBuPWJkbcf6gxHxufnJ9UXo7UDFmdCLh1G7nrVXEpvZVlBGyF+FrtbAIZRMhqCTqnVQTFcq8yUTFhYyuu7gL8rqLIpsS5fHDrDK1L2ht7CaiN3vFTxMKB5kq1SZTz/RKnSdSHVoTZX+5oW3BaJOfYs4u52gane751M2gCfk1rpledb7LsOjxSjb/8AvRvtpHfXC3l+KvLAgBUQaNUOaLAEG/KH4/7uUT8PJVI1o8FD2mMqGhYWNwIFAq1GFgr+OGMqD5CBJb1Oar+knVm7PkgOBa6B3Z9oAU06b6vUnMA7/Iug0s2shRbry0IKYXZ41EmKjzwTYHZ6uqwcPH2Y9QXmFP8OxGgFN6MgPEpzW4s3hZfhVuZVx4gw+dGOrWMLs6D+tbsjfMBQdlXUzSCjYeFwP3RxhvYAskSFfNdIAS+hD1QJAByco56HJ24hiDZLjSZNi8f/9HLcWI4lLkpQ6YvZavdDZ8sZjtNqUGbjdQM9TFTL+wz+ZzhN99RjQRR1fPIDqfiRyZfL3A7YZWohHuNHKC9snRagkc=',PRIDER=>'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',PUBDER=>'MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEArRvR6OzE1OEE3/DzNaJFXDnpPQorQI9m3m41htq5Gbu0+mTxFf20IN8UfTXccN5+ivepeOmiadUFlulGHyTjhU6MkPkRIVpr30oRbbJQgLVW7cN1vVOM+8wTzlih5IqKMIPjyObyuNG11JFAM0/OkPD1/fmT3++jCPF077XT1mabnvIbWT3L3UvWPB3BLwTSHHFjDWBRlOCS7vk+RnKbCO9AcqhCARThM/l4JELt52LuQF2jJk0j4q8sAyYdR3/kHqLUsseW43GohyfDdPR6mZHbSV16/6Gd02FRQhoxwPqryLDtXI3BAtsF32pgXNtfA/wlk14YZsQ9M4a/FKZS9wIwiYR89UGoxZcMyPbw7M4x3fK4Exnm/bNkuzIMQJoUMyqMak2BjzCHt7CqiN1zYTKphMpgD0brsVREWdlf7UlckTHFZywyr1oRgr4zmVhdS0V5LgL/fXSfTKC4toJD6j2RjeY3DwajtHcHHuJNJZkYQ+RhVib7pqF/2jbB1LXDr5Ro1Sao52ZC2xvH7hPCqStF/y1EHmiLnkFDvYT/QTc/K78MGrMcYD6C9bIiQJ0JtC96wj3d/Ifv0a8KSSyHIVsA+oOlEqmb25D5BuI+wl+MWh/9VCQkZcOSX3l5zytlhOsMh5HPGdJvzeQ3u8uuFcI7w3xjFS7Xbmf/D9ki2UsCAwEAAQ=='},
32 {ID=>'key-512-5',SIZE=>512,PRI=>'497BC8E89C6C3C234807BB86ADF92AC9C22B207A6322BC8039A26FD41377D8BBBB6B466436E5EDD2E0B3DBA29371623B0BC556F834F2B2FE15F352FE455035B1',PUB=>'C30BE0273495EDE466D781FD61CD19ABB783DBC4C5EB3D3BE0A201D48239217093F5A1286F5DC751C1A49423736C3724798BBADA4B45C62C3D13A13ABDC9B233',SIGSHA1=>'B7DyETogGrrAccHJGX9KfCEVSrBkYzZ5dy52sXKJNghEeyhoFdS61LrsCu7AM9HL8EOONotHrWm/AwVRYPZVJQ==',SIGSHA256=>'AYhisiP6kZNBRZrMMsMmaVVRJFsp11himCSPkozj0118VIhP+pMAcO0ZRmkjYG8T0K5AT852jLUGE4cN2NBVhw==',SIGSHA512=>'',ENC=>'WHYvUGeB9Suuxree7bAFKjqaVoxVYQMoAVdwdz9nLBgVbNkwXkClV5mxCx+70+M1uqN/VSVLEuQc2zlpS3VXjw==',PRIDER=>'MIIBPAIBAAJBAMML4Cc0le3kZteB/WHNGau3g9vExes9O+CiAdSCOSFwk/WhKG9dx1HBpJQjc2w3JHmLutpLRcYsPROhOr3JsjMCAwEAAQJASXvI6JxsPCNIB7uGrfkqycIrIHpjIryAOaJv1BN32Lu7a0ZkNuXt0uCz26KTcWI7C8VW+DTysv4V81L+RVA1sQIhAPHkqWRTJkqMJVlO+WB0Me9NrIIO1/UQPv1jYddLZmhpAiEAzmvQxtgrSXZB8t4po0iVkcJKAZF7pFHtnL0FkcoOUjsCIQDany/53Kze84tODHKXGm2HO0yOv5uvgd9sZEYpr5v/AQIhAIAWoP+yhfHY4wVs3FOJJ97BvCCLATku6Y4YMQuNYSOfAiEA02//44uiXZhTyBqnbW5MQ8hnN7dIdxiamlrJHsjkXlg=',PUBDER=>'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMML4Cc0le3kZteB/WHNGau3g9vExes9O+CiAdSCOSFwk/WhKG9dx1HBpJQjc2w3JHmLutpLRcYsPROhOr3JsjMCAwEAAQ=='},
33 {ID=>'key-1024-5',SIZE=>1024,PRI=>'12AA04034D59BAADE4CC3B211560E6EFCCA91ABECE7D8086AEC8FA38E853283FFC4DFA8A3C108BF888C46751C5975CC670AC33CA581D66F7862DC08DD41CF2C99CB0F57CEB0F7791A8AA00D95E81E58EA709B90A9C38464F260ABC84CEE5A089C72793FE4BC734460E440137FC0FC0C613FC99D5580F7ACC932AB55A5639F7C9',PUB=>'E908786E7C06D454D61C938C56E8D95BD10755E1B97DED92D1044ACF34EB7ECFE3CEFA34E5C01C88FC4A54DED4CB96BDFC5320F27C5AAB6D5A24843F3D70DA0AC261A3DB6648A85C93C986B7CF5A125B0E56403A23C8F229DFDB9F300CF0C39E6E7CCA8FAC879BDB3648FF77DE7F885DC40689F6CFD4115F77F9F0502E3CBAA7',SIGSHA1=>'D5oXoRS/S/G34Y1cXFHpwmD5Jx1jRNM25gheVyCEwUOJxMU/oOgeYku/g9ajKg23eKWK52Bm4w95ulhSMqU0tITm2XrO0wMz7Kwg5RVye7IkxOE9kNt+wUi1PuYuHejq38RJ8iZP5hYDZOTp9L8ciH7+BiMgcBEP5FmKYZY5G1c=',SIGSHA256=>'mG4rSBDJWE2Azmv1KQ94et+a3zDgqVYJhEIVnKcLWyI4WapZyccdBtYMiBdSnDVjmEHsy1LaeJHDwClBWNo9Zzb3HMPGatgGcvk9FdgeOHC6dkvilE4tx6KZQgf2uWhads1H8vPMecE0kxS/jPghQsBT23fBbFHuITd0JR5HOAg=',SIGSHA512=>'R8S0lj9FXRluVUY6M8gmLyD4W1KtW7v4yPyWqgayeBcZOPuH6evAtOorYjJxgxcYL73b5wgeogOOpNJdONcDS6k2S7dKllJbTWECpbLaVE9qsFMIqOVTnZud1ZNog/HprwPlniA9MXf1HPF/XolPBcAJpIVLqyftwTka/9e7iYA=',ENC=>'ywKO5B5JkXGlQrlfWx/9ySOcWEQNjhShMKnM7aGS1xW865WmyUMHBBqfZWEepvdqJXa9GJdwTB7PXyscXYiqPs/R2EXPIirkhVJe+7n6NB/7RcxZ86/uXu5Ey7Xwsc64V+GB6p5kUISuphn5dGHZTF44XwEE6/vgYsPjbAayE1s=',PRIDER=>'MIICWwIBAAKBgQDpCHhufAbUVNYck4xW6Nlb0QdV4bl97ZLRBErPNOt+z+PO+jTlwByI/EpU3tTLlr38UyDyfFqrbVokhD89cNoKwmGj22ZIqFyTyYa3z1oSWw5WQDojyPIp39ufMAzww55ufMqPrIeb2zZI/3fef4hdxAaJ9s/UEV93+fBQLjy6pwIDAQABAoGAEqoEA01Zuq3kzDshFWDm78ypGr7OfYCGrsj6OOhTKD/8TfqKPBCL+IjEZ1HFl1zGcKwzylgdZveGLcCN1BzyyZyw9XzrD3eRqKoA2V6B5Y6nCbkKnDhGTyYKvITO5aCJxyeT/kvHNEYORAE3/A/AxhP8mdVYD3rMkyq1WlY598kCQQD3sSWF9HcUlX20brB3RS3pcXJnRJcT9fhw49QUPEljPceulZmceZ9Wo4jnSoj4FguQPxLVzEmM7cDXrjWv14TLAkEA8Nlz2pyrdM1E0lmPGw5OGqxuAy3FJA9jaCVFApR/aWFl7CUqW0jAzyq37RBZr/vEPbIDyat4CjiOo9FkHCfCFQJAVzbE45nkpBbPIE0pTZXKSLxtb/cyyxB83iMaddWUcaE7Qjni0LnyZOtINUiFWfVJNQ1AcI9yBnFgyZDJzpSwaQJALzpEuIJuMIory5+aKzED6cEUFXV9KdQGpx5fyOC7lzttFAA5rQq4HCeBR3AkVhjlYz+r9Hi2IjLy7XaazdaR/QJAIYKGeXMzIoc0fqyUYAMLYfY4GBQktMTmc2oZMIe/ixoLqI10muJ6SqYqSA4FN0LIKIboqW/EIn+CHiioq3PpPg==',PUBDER=>'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDpCHhufAbUVNYck4xW6Nlb0QdV4bl97ZLRBErPNOt+z+PO+jTlwByI/EpU3tTLlr38UyDyfFqrbVokhD89cNoKwmGj22ZIqFyTyYa3z1oSWw5WQDojyPIp39ufMAzww55ufMqPrIeb2zZI/3fef4hdxAaJ9s/UEV93+fBQLjy6pwIDAQAB'},
34 {ID=>'key-1536-5',SIZE=>1536,PRI=>'BDB3C6581DF6F498CA3524E260786DF2E9E8C31827DC855C51B8D10DC340691AE00147744DFF4B3FAD9D51A7FA131693419E39FDAA46398E9F6F1AA4BB4C18D4F66910A178D141759CC33084F031A00B902A585106E5439B74B7EA11EFE12091B8D728B8DBCDACD275463D0A9C3DEAB876159CE8755691883F1A69F1C671ED226148D41926157275B884406C8CCBCF2A38AD6513118FF4E3A10CB9598FEC98194443717B4B562C1F047003000D29F8F51CE4C8FEAF0A32CBA1E67FB4F0D6101',PUB=>'C09EEBDDE0135D9A755496E029FD84CDF5F4C16E7701D44F8B50FC9966BC45EA34A8333C1E6971D81E527EF1325E3DD5F547F267342E166BBA702CC142D3C8CB226347C093AF006872F6479DA3905FAFFA1F211BAA6AA7CAEAA08CEBEC2624410CE47DB9373D66A282B9B530F29CE5C65222BD7D7B9C00B82A225C37496A1241B585972FFE08BC2C1522D9F8C067977895F6B42CE2E9CF9352B8A7166952C6BF8D1C5E95F6599BF3DD94A5F6188D290CD078618D41E1D3AD6D9E29F8209D5125',SIGSHA1=>'jsmwKnxqKXZgC6Jp9lH02ZkAibcuY6ILFczWf7HlGNYGpGRikgyePyji0UoxP9zbGFpo55yfJM4KQ0kzi7wxblMixuex+Rg6X0fIVrPZSQUL15+NIC714jLgt2hHzlPEvU+SDNWiKc7WNKAWy7kxUGcZYSSArOVeX8jktDtbeha6qcKVENdI2XgV2XBi11g7S3BmsSJTdYLAltjLTCWGirUsBFBTiGQQGoELo0isSgm/lF0BrcouIqdaR5uAkabS',SIGSHA256=>'ATGAbyuVhS70RmcmYOe5tkjrLc29wSDMWSo95eclTd1yJhV6fpLTtfUH627+YubQs4zjTJtyQnYnB+J5SDskIehwTOvNZyp4dEhN7RDpyISbOlO2wN9xm6IiPL8p0XSmux8ZXUnLx0SekO5DlIhCwFjpTJFAMdC9VN3wyqcQe2aJDiznVUrcWRRGVOqDGSAu3h4fGwt9RXY2F5fLfYYsFfVvTnOOYz7f9WHs/aWTEyP2aRioea8I9nPNWiwwWSla',SIGSHA512=>'ZWRve7ER2mwD7ICyJAbhg8v7o0HflbJNRs/7a6CtjeDbN2maExzem3DFVAFw7XBAwdOLzIAqzeh3RgqLMtRfvTAdsFrcUpukgD0hPQ/H/rNKqCH+eDQEKcyYZBgqrRPxaVriY9o6R/exOeMBr5kjLyPvs0R1sJRdPHDVeHLpMGEU4nES1Wb/wWaw9sQLRAjmapbZLL9iLA3wgOEmVS5jPslBZe+dQzEUP+oSZ/Tn4HAK33yvts2ncBuSzho+GWqH',ENC=>'iHSXIxn7yjMw3xNQsZVzy577dWefYKIkcvzsNSGxydhD2sHGgHHQ/rOYGM4oNz6FQuPWzEC0+s8/rX24wbEktX80VhvS4E9wKM92/3Mk1Bx0KTD08lkWJw/CLEdU55XKT3/0L4ATbi+bT+2DDnnkvQR3oWhPU+u7AfMn8wvHxn54N6HnLfZ4uJo+gBasZ7Br87GslUoaCGRnN5HT7HeoNC+7cycWNbr0fqts6L75oZ7jzWZb6fFW8vYhJZ6T99Xt',PRIDER=>'MIIDfQIBAAKBwQDAnuvd4BNdmnVUluAp/YTN9fTBbncB1E+LUPyZZrxF6jSoMzweaXHYHlJ+8TJePdX1R/JnNC4Wa7pwLMFC08jLImNHwJOvAGhy9kedo5Bfr/ofIRuqaqfK6qCM6+wmJEEM5H25Nz1mooK5tTDynOXGUiK9fXucALgqIlw3SWoSQbWFly/+CLwsFSLZ+MBnl3iV9rQs4unPk1K4pxZpUsa/jRxelfZZm/PdlKX2GI0pDNB4YY1B4dOtbZ4p+CCdUSUCAwEAAQKBwAvbPGWB329JjKNSTiYHht8unowxgn3IVcUbjRDcNAaRrgAUd0Tf9LP62dUaf6ExaTQZ45/apGOY6fbxqku0wY1PZpEKF40UF1nMMwhPAxoAuQKlhRBuVDm3S36hHv4SCRuNcouNvNrNJ1Rj0KnD3quHYVnOh1VpGIPxpp8cZx7SJhSNQZJhVydbiEQGyMy88qOK1lExGP9OOhDLlZj+yYGURDcXtLViwfBHADAA0p+PUc5Mj+rwoyy6Hmf7Tw1hAQJhAPRq0Z8hfwbttjss309MTmau22aBH4ryJuhAxJM33LY0HIBvtdrrLI+HJ8KpBoTeqyv8s8DhkbsM2IgSJhDLiRzfndfGsS30YAKukoIfrbTEhvAUv6jQoekV/BaIa4osIQJhAMm/uf/r1XB1lXB/nxYlB5wtDypRMpE4VETqsd1/tIAlJduxbrzCVZB0HOFNpJfauto1SGJleQ3ZBBaVzWfcf/3yzmaToT77AfT8IXpBDR8fNHzaj3Apz1EEDAx5SafkhQJgd7Y1843xbJBTWApzWaCTKeHs3fjSXTiba9gFL+IFfUxqxVFxrcbP7YCSLdqhscRp7EJ6PDd/LDFvgL363PEDuBuicMQFle+Ccu3UHl2rs8UqHj7bXLDLDKHS9apdmbBhAmEAgvOy3H4Mhbmc7W+5KFuSy/mnbVVVGFPSxwT7vIVG+SKjpy1NbrJJbcEgedG282ZjgH2zZULuR2HEuJA1yqOiZIi1Fnne4Q12YLlDVaJhzQCpRh1rm2dYDQMueu5DM/otAmEAySDf+y82WDkLV082VT9lTQk3ZWrtcQInSp1OiwDJtBGm2nle/1gZaIitkqUP0husWQ+g0dkaDd+/aoERKSyNM8s+DTJHuZL8tUVU2/u4g9ayC8jQxTrBYWlEBJCnMCDP',PUBDER=>'MIHfMA0GCSqGSIb3DQEBAQUAA4HNADCByQKBwQDAnuvd4BNdmnVUluAp/YTN9fTBbncB1E+LUPyZZrxF6jSoMzweaXHYHlJ+8TJePdX1R/JnNC4Wa7pwLMFC08jLImNHwJOvAGhy9kedo5Bfr/ofIRuqaqfK6qCM6+wmJEEM5H25Nz1mooK5tTDynOXGUiK9fXucALgqIlw3SWoSQbWFly/+CLwsFSLZ+MBnl3iV9rQs4unPk1K4pxZpUsa/jRxelfZZm/PdlKX2GI0pDNB4YY1B4dOtbZ4p+CCdUSUCAwEAAQ=='},
35 {ID=>'key-2048-5',SIZE=>2048,PRI=>'3E6121165F1F794322F9E17E749CE560D804FDCA988B8D2F40044B8BD68F8A49FFC64B46416BBE1AB975BBCEF6CAE76A757D68FCCEAB792C7E688D350463BCBA458077F838CEC595545E99E155B48789FEBDAC32AF2F407E3846FEF435CAFB8046F874F97EB393B35238081E9BE16DF3A458F81B91016662999835451D0509FB7C66E80AEBC19083E288D3B82D2B908E759C3316F8074D1E0F1B8BCDD7F5116C72B21A86E5DD00A17A0B853B2441947179E12E627E5864669DEF1F8F15F2EE16E2AF001BDE32AE2BF8590F3C0643303F265AA8FBA216CA8C826D00068532081D9A8D1F79ED05FECF7164F01DAA885543E2BC1D3B366D026B638226ACB6C3CF81',PUB=>'BB3ACA8506BD5A15BD58FB2F6D1042F1536A9B57929D32397C90B836B4F20BDC0DD68E20DC10A4975504AB5ED849CB8FBD1F823F6CA6FFC0DF1A27036E349BB8E21398C992BDC026928789296AC585A6C2087FD88D5EED872DAE2DC929999D7BD969879D4712D27C2ECBB9AF683DBCF9190FDE49863E27B2CE9770EEA3C449C83A10B49CF928EBA554103DC98E17ED3432F5F71316FEA5C3467CBC9BAE0074AF021E4815B7D7ACD9F615F5E516C38A2B5ADF4D04C56DAF9887C865D7B61908443DF9C2C9482AE817712993237F018489B046CA26F9614481656A74975047BFBD4E09FA82ED2F1DF49DFBE2A2732D756BE16935BF5F1EE80EB72298B347DEAD89',SIGSHA1=>'K9aM1mc3ZOy166WMDKDPwSMmVqOJDyiFNK6BifTHP4N0+ig7oxn7yk/BKoXHdBM6txsBSGOP45ARMS2Q1cGqf2ZAPsdzGH1lyb9OD0Z956Oj3DdE1s6ZY6DTCDDsdkIhbWhDSAs7SWwcrKnXfM2F8ZSFNuoAXcqI4/AiF0UfvKa4yJYTMugmHxRo/jrp9D8FCDZvYqEs4SrpHg8IWMEwBmcD+OHf20H8EY+FW+0yGJtdezwGr8QXXeMDlviZ57ZRg1gGMxyVWG4c/++wK2ceA91285GrUMd3quSgXWK3XyBc0mwwjGVhxBAAI/3xA0iylunWhdWV6GyK40kmWkx6qQ==',SIGSHA256=>'ql5wKgWx8y7cDJ3Ux1Y5Q9EGSF2GD0izUJ+Rl2ZnuGmW29vD0IzirpCDwOrskNn6MZJ2orV5MHXWIzciTqzxV9pb29tIgSZXoIg0zh7cSjd/DQ3CRDrE+rbmlN6rzfJ7y8suiK2UkORaALjn1cPEOxd0R6d8t6MrmayHAbIpqf6Wbv6zY3Go4zsYpaEO4cWWI3Hvb6gN0YCwTNJpUXSYCYVn3yuJiRCIdLuxpa2Nkeza4MQpkag3azDQQ7hfU40XtnecMNx2g5hSaYHxJBCzpk9cKcUJXGIN1S+ZrKIsuR//ypI9NQTue5gnBiocZKQwQaM/mPpg1SLkR2Q+VG1PKQ==',SIGSHA512=>'Onok7KNm/0Jf1gEUb6jWfVHHIJQ/lb34pRQtDdN/YGZiHjdpTbBCofiwtJb+/SJsXpF3KEM4YhCDPPzxST5xJzg4pSTFL682q3EBMvph44XlUzWN5Eb4Y7Xqxghr7u7b7KpVCZ181I4s/GR4bLwL83Xb6WydElR41M3VBbm5kXtHPfF8tdxxkvjf8eUYlJtCPLb1ZB3yhgRqIZz3LJBnL4FGWk4N6Om/lkd1BwAuwJsjmPjeMZnTXgSzlBaOrVXiL3sorNcEIlPe0mSSaqvNJUcvytHg4iPyKcmBZHZCSFLZFwBtF0ZLDxwz2JsDgtcvl2INmnrkkuo+dxxr+7A6Bg==',ENC=>'fJTsjrc+XwWd5F0lRy9DjDbstm9JYw/6YC/JDdgdaapZFlNYR8FI7msoJn0cMtPkn8tDQGH/ZyVq5EPrI7NdF7z1i6I3n3bRXhyR8F3pAYnXasuEaHGgA1itei8Ji3V+8pejwaLMBVB4iVxxWeBIp5df98VCvv/v9/x8EQhJ00RuWhcPDTJroPzZLLe/AhrOixrg+vDwBJ9m2Iwerdjx55ZaFmnm3MdFLwWfn6/Ixt1M3R+7D/DHa6Za6j/uGUu0NJ1CDyZFRcPR/tit4MNhqXYGoJHTW33LGWJyr3Hw4rL6vuUaMg9miCaIe7mYhUp0qXfUwJHrvYrZi8hvYIRRfQ==',PRIDER=>'MIIEogIBAAKCAQEAuzrKhQa9WhW9WPsvbRBC8VNqm1eSnTI5fJC4NrTyC9wN1o4g3BCkl1UEq17YScuPvR+CP2ym/8DfGicDbjSbuOITmMmSvcAmkoeJKWrFhabCCH/YjV7thy2uLckpmZ172WmHnUcS0nwuy7mvaD28+RkP3kmGPieyzpdw7qPEScg6ELSc+SjrpVQQPcmOF+00MvX3Exb+pcNGfLybrgB0rwIeSBW316zZ9hX15RbDiita300ExW2vmIfIZde2GQhEPfnCyUgq6BdxKZMjfwGEibBGyib5YUSBZWp0l1BHv71OCfqC7S8d9J374qJzLXVr4Wk1v18e6A63IpizR96tiQIDAQABAoIBAD5hIRZfH3lDIvnhfnSc5WDYBP3KmIuNL0AES4vWj4pJ/8ZLRkFrvhq5dbvO9srnanV9aPzOq3ksfmiNNQRjvLpFgHf4OM7FlVRemeFVtIeJ/r2sMq8vQH44Rv70Ncr7gEb4dPl+s5OzUjgIHpvhbfOkWPgbkQFmYpmYNUUdBQn7fGboCuvBkIPiiNO4LSuQjnWcMxb4B00eDxuLzdf1EWxyshqG5d0AoXoLhTskQZRxeeEuYn5YZGad7x+PFfLuFuKvABveMq4r+FkPPAZDMD8mWqj7ohbKjIJtAAaFMggdmo0fee0F/s9xZPAdqohVQ+K8HTs2bQJrY4ImrLbDz4ECgYEA8PL8H0tC77cWA/2VXajlmviaAXnq8M6aehXz8am6DFcKKiqtOU1IYkQvHsjCU7oODJBTAhqwyjVk3NoxpOsq/iBMUKa2pWTOF2Va+mfw8MFw77CimxMcI0rMQMNBbnSFsTnmT9aqvcnlUnTdNrSlKW0i4MzDnBfly96KhDa5LfECgYEAxuzHOvts6nTHMLjbyg9o1u5UxqD6pQwIHsTxVMWrF2SeIJUf/Jb0gbMV/f4NTwkMCD+FWIPxioYbJmJLbq4jsTJTSdcVddhHsQGx25Mv+A5gB6Dh4WnCy+b9bAFMqh+Sa872+2dGZCjj04NWCQ+XH+EWgkIdKtj4yqd8rNoPQRkCgYBGAjPjW9jNEeNhsXKOzh44kvccarIq2bzksDA7DVezci7P5aqDNcNMWgde6HIeJbcjS2Py/pJTjoQJ75PxGStav0OtQ2NaVxnSjm6Kx1yod2w7GJWGfVz1nCwQvSrrzwtxXSNgGz1s+5aYCMClvoMmsEEsFBLZ7c+lFrokhEn14QKBgEDBV2G18xCnjygnJTUzqvc8glBemvkbX5FUnxLvffCRioAky1LYeSO3fpM+Hmr6EPamZuwXl4t2eGQYX2HaQjgun7pLz+qay0utt4447cacN1qEXsOYQBdMTHbaPXCr8mgx6WiRh/KW9QMnn9w3PQTdqwwgJYqLMwIVX5qNKaYRAoGAHjyXYmuAAU/sAdY9AQXhwSUYt07YDadpHmhpFatgAeUoGpS07KlcYE4mvyK2+JTuhNbFe8gIGVBK/5g8HIAxPXZbV/I8bKVfqYtJvR60lBqSfKsYmVREjfgIzRLKxh6WPaxLg54boBZie/5UUTAsWl6h8pMixqVn+JvFD34nSeU=',PUBDER=>'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzrKhQa9WhW9WPsvbRBC8VNqm1eSnTI5fJC4NrTyC9wN1o4g3BCkl1UEq17YScuPvR+CP2ym/8DfGicDbjSbuOITmMmSvcAmkoeJKWrFhabCCH/YjV7thy2uLckpmZ172WmHnUcS0nwuy7mvaD28+RkP3kmGPieyzpdw7qPEScg6ELSc+SjrpVQQPcmOF+00MvX3Exb+pcNGfLybrgB0rwIeSBW316zZ9hX15RbDiita300ExW2vmIfIZde2GQhEPfnCyUgq6BdxKZMjfwGEibBGyib5YUSBZWp0l1BHv71OCfqC7S8d9J374qJzLXVr4Wk1v18e6A63IpizR96tiQIDAQAB'},
36 {ID=>'key-3072-5',SIZE=>3072,PRI=>'775608030A89E4C9FCF420B9CAD5ECAA4C84BD71AFFADAF8369E18E679E90CF7CEEDAAC388EB70D7A767F8D797A6917204BE1181449852A6C7B421EA02D500D49FDE2FC9AEE4557E310C434CD610CE8D24412B70CAD0B5086682174F97A5C8AFC10DBC1FA7F4C85325887EC61FACAD595B102ECE5EADD0A527B8B6061CFB3950581850DE0D921DD886870C24205B8A05C1ABDB9D1202B63DE5BD36F6336B2CB85C2E4E35E55D2E2AA37C7B8211A1CC9FD1E789113F491DE2EB8811C0C0218F27F31D80ADE1D125C1FFFCD7AA795F46EED8A5DEB81D0D62237A7DC2D916057630D197169F068D8D9F919319ED3FEA0834B68481CDEB0BA6EAA829AB5E1ED732B8760A2795F44C0EB9C84AC6EC274B96C1A93E98239693D79A02093172437FCF1C54A1CADAF8683625DAF076F8E59761F0EF3880B8306B8E37D1B66C6554DF825F996F66F1258F24D35086A1069BCBFD9CD6A99A0D29B72674DB8EFFC283F144C0CDC1501121B1DEBF0DB3BC34B689F34630A9B01E77E36475CD95E783D0407FA1',PUB=>'A4D3FCBF3E5BAEFBEA15C608674913814DCF8CE0CBCAFDC1854528C931A0E5A08EA3212E961F8755DB3104701DC59E4B7DD855D88CE3C8B9DE6CBEB3AD5C5C185E6926E20B335ED31BE13A2EDEE327A384C8DA7442327CF3162EBE5D687452E12CE9AFA680F5C44626035B85F361202ED5487ED87F9C1E82940618641BF466DA602872B7556189B23104E2E61C5DD3635CEBAC13849EAFDB4A5E740C8D2B4EFD558E6BC421BF700DA5ED3AD69E7AD73F5C060982BC0F330B78FBC0043D742962A448AB7DFC39262F07CFCE7421CE8888A500CE6567D4B5DC8B02F29F8986A2F4CE32C3DFBFCB5756BE8EC4AAC017A2C40524F57BC6E5B57589478E0289B1194F88BDCEEA933C9E00577D6902B2A498CD8D4E3A85675AFAA5ACF276C063CA93765419E99E29DFCFF08231FC5159B7C4D61F76F5311521BE503A7885707EE6326597283EBC54420FEA0B6E1B5DA4D57AAD61A622700DB9A2B2B7F451BB70698CD7D72885677CDA86A49C92AA83ECBF9196E16172ADCA3D2A854DE0E61BA113245D',SIGSHA1=>'eQrZXVydUvzndnZd2jRRk9QFYzApxtT1aK/e1vDfhj6v+vAV1Zs3CzRVza/FX05pb45zUQf/DoJrmdJcqbHCZzEkMqTWNDMX0CUIlhOvnIC+bgLqAvm2pH3dTKKVvXEgEH5D5lld6r4vMPCde7P0m2rrZNbJWazueFxrkK3cdDZxm/PTwxitgRUo9wd5BRwOCOmRKTGGfJNx1qb5Cuw+idD4HXSbwSBEeq+SC+hdKADn0T7p6F9IU+s+ICOQaL7+akSZS9DFxq2nezVNAmUr2SSzTT90URTk5Wuo3NVRQyBUgFDQv+Z8ddJxkkyveJuNHpulrV/5bmSh8x1QOr0gmWTHpL33G382ST/ApdUjc2kiaY6msZ1OU6SZ2YbfW4kqR9Lq4GWa2PDqlud9miR7eMACXZUfoprjKkjrPgriNQthv5tHEFqk6jfJLdATvl8Z7UwG7LMElbvDYw8pS4KucIKPLUVtkwP0zqnejvDMY6uibrR+mxAaxDofYDhLXIU9',SIGSHA256=>'VsmZbsrygjQXjDNNLcuSeeaP4U06hto5lpcJmdcnGxKBQ4gLor3ogpQooYCwWGkr4b2hWdS3oo7CYZwzgFhAohWJhEwZs8vEf0xet3eMmINt10dtSSSTVVYG2rZ+OxnChYadRh93cQO3NalN7BmZVs0NjI0U/RGrK+eiMEYbQ1Qo6OG/wq2w5CiefKm+hRaLx0nic0zrQuRJ3u09jqKLQW5XkX0iDo5vPc1VCIyAI3dJgzKCfMzfyP8e13a2nSOoqnKWF4+erIdVjjIOsm/u0BnONiviDcjQbkaOSjYQs4eTnwxFw2atgxcvjSUBxiIzy5FZpeuTzQTYoeP75g+jyyk2+MKeMjNGW0KOQRjPjUGgbBHBW/Xoi+R6tGLgmY93NFPgMR1GgGQ45FcndbjRNa6k8iDCCWgwYSSHBomO73ov8ev8TJcN1jDzT8gS6Ex44Q6JIgHtxJRzbG0Ljefmhe37IU6CDl8NQOGl37LkXkLKOuKS+dIq7kyDdQB+JjQX',SIGSHA512=>'Yvbx7o7NWufXxb9OrAKEhvbHRHZxG2UU77ani+CIe4WLf++GdFceE66F7i4S9tpT/VkV07QekVKk1VHzXY3kJVBk7YPTwWjA9kCxsjWlCF70PdoXgNI5QqU9avu4dht+CtfQ0fewiFkeO7XXlwIS29rS4SHmX/UMZ636aH7FxUDFl+JgN6fwyU/3RmRbXtfJPX0aL6f2/JAoo/WeAFtKbYfhdfedZT9D5AajRtDOpDH4Rv0tff40OiWwleMIuRGazXHcTNt/XhhfIl34RR3y3t1q9dFg0ljfLbtGungP5Fiu7kTiW47zo7POG+eOyjOG+82Kr3yDYT2nOu8Eo0ZLcEYNOsJ2kAb5+Xm8uXpfLz1n/ph9vjIF2leAKE9KJDQhsqnoytvCo/mAJz3+lgXwiLIZcqPAo3Q8Rw5BmqKmcSw4eR3Ai9A2il799KcFDa9rBZp0HAslSNBrD93/jU9JDULc7zlDDR3JwE5i08Irbb2Yv31QEWtofRF6NHUReRcM',ENC=>'K4yf8bh7N8GDz5Sh/lniUNIHkjRPJPzUOU/UV+Uzc6Y9gQzxwsY/TywHpCH4MOqLy99d5yiaXt6hzKCPp1ELs8554pKmlOaIk9PYA+mU40XPjEY44ut+1cAh0C3UGE4EIdSvYicEBDy8dtwbwxEt4xx0i3a6EP2xX2pmGaJCi0KvVgHHJY+ipze+3rpAyGj90Wm/Mqdclj/OwI0lLHefP3zZnn1IG0mWHzdhi0Ei9XakUVHaQeTz4o7gZWDEZV2Ri5uKoo3T8rLZai7edsnyBfgPwcq+PokwLV2hqoct/YjsMv7LsOsNGqutKwgErXUDYTN87u6dyuN6XYugEpYLq4DJQm4AfaZopipSyheWkRykHOHpy/GfI5fKp2phOExUTeEW4fpapBP4UFdISuwAW1fT4f4tyw+rmrlRV2jCHEH6yLqY1xiq/lkyp19ZrrOp9mUBVMyRhWAx4ZSx04PyWypUwOF9nKBKFVTk4WhqZX1MrhSmediBedXiUc3SBH4C',PRIDER=>'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',PUBDER=>'MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEApNP8vz5brvvqFcYIZ0kTgU3PjODLyv3BhUUoyTGg5aCOoyEulh+HVdsxBHAdxZ5LfdhV2IzjyLnebL6zrVxcGF5pJuILM17TG+E6Lt7jJ6OEyNp0QjJ88xYuvl1odFLhLOmvpoD1xEYmA1uF82EgLtVIfth/nB6ClAYYZBv0ZtpgKHK3VWGJsjEE4uYcXdNjXOusE4Ser9tKXnQMjStO/VWOa8Qhv3ANpe061p561z9cBgmCvA8zC3j7wAQ9dClipEirffw5Ji8Hz850Ic6IiKUAzmVn1LXciwLyn4mGovTOMsPfv8tXVr6OxKrAF6LEBST1e8bltXWJR44CibEZT4i9zuqTPJ4AV31pArKkmM2NTjqFZ1r6pazydsBjypN2VBnpninfz/CCMfxRWbfE1h929TEVIb5QOniFcH7mMmWXKD68VEIP6gtuG12k1XqtYaYicA25orK39FG7cGmM19cohWd82oaknJKqg+y/kZbhYXKtyj0qhU3g5huhEyRdAgMBAAE='},
37 {ID=>'key-4096-5',SIZE=>4096,PRI=>'A05B5E14CF4BD1CEB276E3F91326C97EFD51B8D9B1A95009F305953CE15093B22A90BBD40F477A692014F03DBEBFC55BA101AD0100875B7D459214A957834E2A6A3486F53B4486BD3B38F2B315BFEF7DAFE12778564E1C4CF16B4515F6BE0E8C183D0F78CBAE237A8774A0639664C559F0B9B216E0E4E9C4FA537F023216E487F7B4FA33C0666A4A4D35182A8791BC35B4EB93B02D70997ACC5AE31D5E7C6319F6F88482D49C80B9CB7B35E8ADA5426A86C9B54EE1F7A33B976702AA1D35C57BC7E84841D10B7EDCCA4E32F4A90335B85A113E60FB0763C970BECC9BD073ECDE6EA2E02542D1938B3D3FD190AA118BF7B02D0A090777E2DA5B7904C42634E5249F86ED0A1C868DBB827D574C661375F1624CE72F8CA10529B3788D679981569325E21BE56E16C41523B745E4009D348BEBB9F6BA8BE3379F7A382385DFD22EFBCBABBDF48DF3FD82E313F0C603CCB423147E219033E678FA16C4ADADD3A72F67C73269369BEF302151BBA10CBA0775CDF697DEBA0CDB83C00B6049B3F6A9BB87DDF1F5E2AE0A41F0638DFF00530E0FA107E05F774DEDE98BFBE0A2A6647A0A413D5AEFBFC861BC86912D60A44248A104A867C5E768E28B24426082700CC09CDC9382638BCDCBB1B41E6EBD0FC4DC62DCF33AAC17FC41C96D49577184FB602C3F8AC60408B3E3C646F9665DCBD422785751D2D05C7BBDDEC607C0B6536C6F2BC1',PUB=>'E36035CB090541BF60293E69026A03CC5F5BD26C92AEA269DF84AFEC738BC23F4F2199A065888CD1E8D0B3783AA706C6AD1A82271CA5F6691080776F15EFDBBDEFA4D11B985E7ACAD121DD047FFBC67901B31315695687842F8BADADDEEC3EB5D73DC9D76DFE446B0643E1BCD1CF1A4A6E0A9B0B12632E1D666CBE62F32DA754695A11FE6B549487CE8C0126649B5F04F261C036F34F3DFC7176F2604B4AC818125BA6E9577C6DEC598897BD05F2C06FB6340ADBF32FAF1BAFA2EAA071F6D7C0CCBBDFE312A9655C3CC3EC40EF951E20D5184318EE9C4630FCC9F31375385E91F9D9222F8F945CC462B1E5BA1966DAB85A1051799DDBDB258B15C793F1DEF6A4ED667275658C838FF5D14C6D73523A662B8AE9BC82D0B158D6F8C443D83BEACB591A5359016C2CD515FC6D2E1A8D13DA66B29EBE9B3A646565DCA9C97D9A3CBF5700F9603DF37373AEBE6E51D4781E7A3A9BAEDAAF01C1B9D86B2F5EB627D3D7B0CA3C37A20D71D8745926C8DA6590CA23318668D9E2BB599A5CD32A8FA53FCB1E037CB7129AD8BC9ECDE9AD67BBB31711F2C7E526F894EDE37E6548770D5ADBD6F9412200ADF8C411E391C5B25C1C44D7D9EED8F3EB3126D7EBFB9C3FBFA8C33771FD8DD7A2E2B3228FFAE267C32FA7D4E5DDB26C5BF9AAFB199511832294A5737B8553EF71307F3F73AA36116BFC70978EC54DC45037D1F6D8396808111B33',SIGSHA1=>'f16UOf4fb5p/vf0g/l3a4wFZo+R9Xo/VvrSEtUP0CaoXktQI55WZOl5cFBcgMi4DAfB0ubtYQsZXVeQuqlrcv13Q0tinQ0y2EJB0v2ivOPbN+2guLYjCvsmp2kTKU5fkxiXOAzTFnX70awoVoMsSG6quQOTwWb0bzQb/hYh/qqzIqHyZRP/DNLQeI3Pl4GXhrIeCD/WVrXUsKTVqcsvnkxEutO+MXMw8baaCYe3u+W6P75Tch5VyDkpAPVv9pdSja/s/pLyTqGNSyD+Mw2a0LLbHiVTTKamVxKA8GGYWjvNvZiprm8W0vughgJXCDpWeJ53D2Ydt3VZxP5JOcZhv09dCsnhSKs16+izZ9S0wPkgamfF4r3VT46AYzDjaAfbXm2ppxz0IIPGkAAV0MlFf9idvXmrKVeQHD1KDus5SDwk0I4YdeYEplgN9vgESgQ4iIkduHnZdWSNUF6ZH6dbyHSde/8ejOm6WFlS4IrMdFjAs4t7n9am9T3xINY/Be5E9b5LOjG58yjmhmOkGJ0k0xObPaT4AeuKr0sROblKJHM33N837Teob2GcRb8xWi6LmDOt/ngbsk+8rGIWNmpDrTqjCQVaGnwR/wTIzpLeW0wYOfG4ZKzXF1FD4IIq4NQegIwfmSXg75rG+/ge3x5LYyl2+iVXPNeGiK+4lHy2Livo=',SIGSHA256=>'jdhbUKJKcc2tsQsh02yKXtx8fTLqTonPTGmfIsU5lR/TDRSWcFg3Ip2jpwiymBStNtL+gaNaMBCUkv24aH1GO0M4xK+nodK5vQkvLrleJfLiDqozxZ/LrPwDNcO8Z93mygNhArs4yANshDEBSiVOKS2qRmPgLrbBfb0+lDuYoXa0lHi1XxddcvzTqwnpnCTJgwqzUX+UWZsN99bcowwJIwNh14JHwiynTKi+5zG2VIshF7OQMkJzQEuImhm0iMO7zkEBAknVHdMSn1D/QVO4DVuBE8WmnqTnQrdaoUUswnQas7uOSBR+TiHz2BNjP+D0ZHQD7AoODXr7nDnOauWvqm1dx5lNcUOB0GVqzgsD7OrxKGqEhoI8WoS5K+aagXY5NYm3tDgSfhAIiaImRvaQZARHzaLBy7ruAnI5aG1aJ0aIKqpnfAO98KWwD45O3Q/KpktCCJ7vvgy56AqzyDEjpHVobUq8ilsa+f+P90kWbcFhfrIak3UnmKJOuw6XSYUu/8Nl7cSqHDjRdPk8A2OaHvTtsWX6B2gmpUgaK1RkMUT9GIf8iLwTNOFcg6cIqnqP+cfU+qmJav8JNJNoUV0x+vHzMQGE/qiCwprk8zmI6PzThPZckRQkLgP4sVFBVre1mjVUPRJH5tLRmQyeuy8WkIKmPdR0LeSykPmM/nMYebU=',SIGSHA512=>'SeCwmfSwBbCw7d0Bsrdm/gb3qi4HH+8z72YhWJw+SOQrgQmSX1Lu/bRnwJFdnzCSYNzcdUCtTbAmNiFWhZknlJW6+O3KJmfABJ/Snmxzj7PgdQswmQF/a+JTyvLAn79hLpMtA08oq/G5A1BLoCkAHgMIvHVd9O1DReJ9ndZQ59wMkT9+twP2HVr4iAQHSleENJDZnUtHJeNQthrlbx8Dx4tjaAds7nKR7vo0T0friGJZmGhh7Kv20NGWWziXJD/cC97/G0iv7v2W9PgdK75d+DjM9zOx40bK89ZURL0wtHeB7V1avHRheaHNtPW9dZItsrniE5W02HrfFFiOpbRnVdqFYPKsWkhjwLYZKpQ/SH+LbjB8spskLa44S1jH7oQ3vMCMDafhOCZpzfUhlHUe9xBfG1yYc1WM3Tr3KwXtQLONVy39ka6V+1rBdqVarf891jJiifT9uafxCD5G0mP/s65KlYmtqCihHmkWLX33+mztZb7THlNNPTO+hVh/R08L0ZHPSk6suNNY8F83LfxqccMslgbwCH0CcP2m0DozC4vsP2K+bz+QdSNKjeka0cg8vsJQm/xE6viUzSormEfDl8XS3lNq7RpWB5wJaMLBj9DCuXfzyMYFJqluZp+rysV0HMk+ank1aQ84TsjdNXsroHTsoOOjtt0N1L+0KSh3KD0=',ENC=>'rGSh2uDhVc6qoFtyuIH5WgVQtV0sngA/JWnEMVn5FpAHdEdikiShbM2rOHochRKibG7YA6hpuAQAbKhvWujmZerBRB8knIhkCX5HFY7mLVUm4u4vhrPGLlXmBnHsIgcgXjDNRplcRC1syM2M0ZS0/bST7Evaw3zRJfLjbk6eKk4KoguPIeqd0yFSU3z7TsDAj6bQ9qHyRinsA2KT2djvRu3q7QFalao6gdGhERQzWVm+tOXOrvyRxOyBNhchcpYL9NI2oCAFf8DiobFSY8k98VRVBykj+bR1G7LHgdhYfwUXNkYmjHp5wVMjABryOQZWiSXnpV8YzlkaPF1FPn3XXqOxFE3xUNTpZ9z+kaaK1Q2164NO4TIHJ/VEpDJj0LHJnVNmiiLtfdd6wWdYbMslQnkgeuwbqZKcAZgvyF0Ts7nClIdgD2hzMFB4Uco9ht/yxF37xXILWPmD115Pmp0e8vbH2r6o8rpUKTwgisRC/nMw/orc+FIujbApqbHV4yq6W+EcxGbff3hJRbfGE1ydbns2Xdxoqa087i63WFVlERYogpvqB49b2EPodprJTQNYzZOi/lW+Pz+E7eC7x3EiEsI1SYKcG7vgjiGOIOlCX3bw25MhHR6UUSea25m3S1MWkmRNpO+U1FVzLJUqamrzIR2+c5J/4pUo42wlieY8HbE=',PRIDER=>'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',PUBDER=>'MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA42A1ywkFQb9gKT5pAmoDzF9b0mySrqJp34Sv7HOLwj9PIZmgZYiM0ejQs3g6pwbGrRqCJxyl9mkQgHdvFe/bve+k0RuYXnrK0SHdBH/7xnkBsxMVaVaHhC+Lra3e7D611z3J123+RGsGQ+G80c8aSm4KmwsSYy4dZmy+YvMtp1RpWhH+a1SUh86MASZkm18E8mHANvNPPfxxdvJgS0rIGBJbpulXfG3sWYiXvQXywG+2NArb8y+vG6+i6qBx9tfAzLvf4xKpZVw8w+xA75UeINUYQxjunEYw/MnzE3U4XpH52SIvj5RcxGKx5boZZtq4WhBReZ3b2yWLFceT8d72pO1mcnVljIOP9dFMbXNSOmYrium8gtCxWNb4xEPYO+rLWRpTWQFsLNUV/G0uGo0T2maynr6bOmRlZdypyX2aPL9XAPlgPfNzc66+blHUeB56Opuu2q8BwbnYay9etifT17DKPDeiDXHYdFkmyNplkMojMYZo2eK7WZpc0yqPpT/LHgN8txKa2LyezemtZ7uzFxHyx+Um+JTt435lSHcNWtvW+UEiAK34xBHjkcWyXBxE19nu2PPrMSbX6/ucP7+owzdx/Y3XouKzIo/64mfDL6fU5d2ybFv5qvsZlRGDIpSlc3uFU+9xMH8/c6o2EWv8cJeOxU3EUDfR9tg5aAgRGzMCAwEAAQ=='},
38 {ID=>'key-512-6',SIZE=>512,PRI=>'BBB69FD9A0683F82805A0E73535E1033921E98D50761129958E3073DBBD5D63BCE0B83EC1704B68B017A7DDAB76D1A7A96D1BD3D6D8095EBD949CD1F3E709AC1',PUB=>'C4369075B9568511F4EDD35211A0D0574A008D0F690CAC7A8194E8EF0D2FC17E61D8E6549E9B9EB81258DA9BB9C0D104B74E3EC3E8BA63FEE8CDDF86D15AA7A7',SIGSHA1=>'FQp1Znk/8TYc363qnNpTc80rdX7pZG+GmHtUxxuYueu+6iuDQEZypDPjIFfGxkOab+fGmjItZtweVHnMVHOssw==',SIGSHA256=>'P7FHwDaA/p0bGASkokVjZseslhy6gNWVRFsvX5aSBM5LvuB1OZs2M9LkNdp3KBQWe4x6tMqCdAafqzOT1t1pkw==',SIGSHA512=>'',ENC=>'s6tkTZzxdTmrb8uWLzxo8WcGfw7HaPDrLnTbrFRptlTN+FGldg3xOQRTt0ltIg4BBi6HXmLNDq9yc5UPl841yQ==',PRIDER=>'MIIBOwIBAAJBAMQ2kHW5VoUR9O3TUhGg0FdKAI0PaQyseoGU6O8NL8F+YdjmVJ6bnrgSWNqbucDRBLdOPsPoumP+6M3fhtFap6cCAwEAAQJBALu2n9mgaD+CgFoOc1NeEDOSHpjVB2ESmVjjBz271dY7zguD7BcEtosBen3at20aepbRvT1tgJXr2UnNHz5wmsECIQD0zEfMMCBlYfuIRCrd9j4Kqfdw+sZGQ3MdGFH7b57k9wIhAM0xIVLCikrSNL7nDUzPr79Ozju2nnK1ZYILQTg0D5bRAiAKY0TEsGIfiznePW5IPvPBBhde7vVM8/3FhUutTL5EXwIhALY/mepo8e3M0J5yl+SOXvnbY9+zrv4RUax0lKP30ZTRAiA94qsxTTA4fcZRi8OlFnu1+9jElazXyomF7Mj44PhrZQ==',PUBDER=>'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMQ2kHW5VoUR9O3TUhGg0FdKAI0PaQyseoGU6O8NL8F+YdjmVJ6bnrgSWNqbucDRBLdOPsPoumP+6M3fhtFap6cCAwEAAQ=='},
39 {ID=>'key-1024-6',SIZE=>1024,PRI=>'B673C14CF50DE43FFCD33425AFDAE605E446C302F37369DF5CDFFED3ACC404F928F218D3E84F964E7063F74722084F4660E9B2E3C31A2C12B3D2CC9C0CCD3E7358AC4EDA84559544C5241150BE42D84EFCAFBA970EE4ED8E92D9DBC4B1ABF3272455B9FF75A19DD9EB849C6AAC1CB2EC57DDA07731C02EADFD62C03AA30E1EE1',PUB=>'C25B269D018C1A89E4A897CC73F66331BCFC23C685701BB51CD44755E9522F0875857F74FE1685AB6688B4A2B3CBE47B51494DE7AECD13EE4E8AB4C264AD7EF12424E97BCAD544DE8E18F9BEFD2F2C88B3604AF4C14133E1FA2B9142B37A8A7B5BB2E3FF9715E3CDFF9010EB9657B1C72AD72B6AA6923F688E977CC28FB23A03',SIGSHA1=>'ULBdJR3sSXlkAuaYws8ymIQDcuY9JAjHc0YgGIlBHz87sanlLiCEIqLX5XDHX7VkB4SIAWzfAKEgXOgmENBU7SjwaJVRVtwINJ6zmI0ruc4Pr5WtZ/TjKg05Mu4msi9+20C7Pott0JMeespcRHf7Teqpgd2VDd0JahRZ4n2lGnM=',SIGSHA256=>'Y6goUfxWcoFK2uZXd3BYM1uQSPOUwmewYV1yyCzvhSfu1TKbUKK8BsuUptmRdj4iYyXNJ/YgKdCO2hQjFqO47OhsMUjXd0AmFqgaNt1n2t2uP8XnD/MeGLhDKy+YyJ78s7BvenxagW+TjK3ticr90qFx5yb7zyHnybKD9JEOSdA=',SIGSHA512=>'WOqjwwqoJ1AfcbMVFK3VN3nbY1q1hJBZ4c4xTv8Kkz7+9rhairVY+sYhiM3U2APPZkI/pIWxhkPPaQSFWdWV5zV6o+bTbidqk6DKopyAr+CFrVSnGTr25RO2nwGKRc0f95utCMyp9lAppThzZbJflDGAG/JCn/Yxg8djq4t0hkY=',ENC=>'b01Hb1XB1W5z8thPNZ0Mnoa638k4f6xs1dKsnO4HI8Dq03ZXQYOAKZ/CPt/Ow+VtJUQvgfu2xbrjofPZWMBv4xKrh0VBDDjM1PhHoPSno1/hpPiZscYHLUJ2eFeoJXW/uOfaIEYB8UNvubbuFHVNpU+nqihC9p3SesrhLBzXViI=',PRIDER=>'MIICXAIBAAKBgQDCWyadAYwaieSol8xz9mMxvPwjxoVwG7Uc1EdV6VIvCHWFf3T+FoWrZoi0orPL5HtRSU3nrs0T7k6KtMJkrX7xJCTpe8rVRN6OGPm+/S8siLNgSvTBQTPh+iuRQrN6intbsuP/lxXjzf+QEOuWV7HHKtcraqaSP2iOl3zCj7I6AwIDAQABAoGBALZzwUz1DeQ//NM0Ja/a5gXkRsMC83Np31zf/tOsxAT5KPIY0+hPlk5wY/dHIghPRmDpsuPDGiwSs9LMnAzNPnNYrE7ahFWVRMUkEVC+QthO/K+6lw7k7Y6S2dvEsavzJyRVuf91oZ3Z64ScaqwcsuxX3aB3McAurf1iwDqjDh7hAkEA5Py9rkvaufu/OQkvVisUIwr2Nz9TnXErdqCzh9b0Yg8pUWXjQ7dIysAyj1kAH5fnV8X+SE1adDX+LxCdHUxuEwJBANlIkitY/OhbtKCoF9lu1QJ5p1n00/9PXu9DBNmLCz/qX9L71wu5b1pOutOAngC/HQjKXLy+QlCzJO//zbOjwlECQEJuhIT9Yq5UN8zPOllwU/46nuW2TIa/n1FiG9OL7AhKx7zip0Us9kRD8CcgNeX0htwzB6toLZbLVzvGQR6P3tsCQG84MGmz0TD20Ax0PlDz5GCx+LGZGnLTI9sAyRi5jXaX95i9hCPiNVdaeVMNwNLNAIWhX7rVAIjiSgP3QkmzhyECQHY0Kltajao6C3h9eNzSG38R7SSzJa/J1kArEOZewYpujTgKAiPG+UfWntD8hUubDQYqHJXQXt4RkC4gUlbUD+s=',PUBDER=>'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCWyadAYwaieSol8xz9mMxvPwjxoVwG7Uc1EdV6VIvCHWFf3T+FoWrZoi0orPL5HtRSU3nrs0T7k6KtMJkrX7xJCTpe8rVRN6OGPm+/S8siLNgSvTBQTPh+iuRQrN6intbsuP/lxXjzf+QEOuWV7HHKtcraqaSP2iOl3zCj7I6AwIDAQAB'},
40 {ID=>'key-1536-6',SIZE=>1536,PRI=>'24E9ACD23DB3D0674E3541DFDB847B6AC2CB8EEC8E0CA0849F445DAF985AB30F1C428A4E63453646E2C7FEF7D5920012B50F10135497F95E2F68CE18696DA73F5392EDE1DAD140E6AF7DDDE939ACC1E291965A974D728E41A30FD16EBFE6D1980694443B8F2BA1303406EA18C45D0E7837F27D20B42DEE9E6B6413FBECFA6060F054738CC87A60C2E62B74644EBD3523232686E53399C8DF751B51CE7CC0D04FE12627932F0F722BC113A67C0781F1923F51C18866F2AC5A771611743F8FCC01',PUB=>'B0949FE081458D402DFA786F2BCE7FCC8AD80B36BB2EB0455BE125F830A0772D352C987F053981E8668751FDD7AC17B50D698F7ABE3639F7A4A4B0B8031A65BEE020511CCA2AD2C746B7F8F5013BA34DDFBA4445CFE635259F0240672C20EA623C5F929B332E97B2B3D9631DF2FC6BE7865F53CD56E40876EEAFE48CAFCDA61957CFD337745C4FB18FFAA37171F2D8500C470B540857E85D9AE5CE77FDCE3A2657846D04BD9494DDF6805EA9D93839906339A72046A73B4AECE609C0CA7C1479',SIGSHA1=>'kL62p9L1ccnobou2FjEO6uawr2eOFMBsvkzSARQ1K6XfDmqPhED6QtIgGQ+xaOQK8R/HHEVKhz6SGhaha/vYpGdLEY9e7optmrA1IydiWV3L04RS3FNJz3TecjAlTCG1dwANqNDoqPsF8dBx9iP/HOPtq+NkQ6VMc++BYNE6LVr7B+CwmxKg6+4ognoFjllJ/wAsdAiQeLB10rGcYmQox3pZLg1+HU7h9p64JMYlxxumYak4yRSDZBZzojKXaIcF',SIGSHA256=>'rEyxs2x6TBd9j7p4mRaIoATqYSl1KOxZmSQW7346Cy/xVI8hYxjQyBc1tZ93hjdBGT9TwQuIM6V5NfLgfGKnogHgRzxbTUBnynRwl/bO/btja0bWbNsMRrfC1g+HuHlsraaUJt2mJPJpvEdiadxwwwtbXtyA6d/LYZYQXRNhSB9CdEDy+gpn0szyF+s9fmyBCYgP/pF6MFAe0kjJ5RW295ZviShAiDV+zkXcpjIvpD2caozm+u0NPS6bi9jO49GF',SIGSHA512=>'nOObxwLzDBmX25gOLAQBhksmYfShwAJXtNVndzqRpzRyfwKcWDGriYyjzGp+PODySkhT6n73Q6M/naC6GDw4oUH9evUPujEBQsqR+WqahYBFL+X8OPMGAUz8mOPpds8dp1BMIQxaEOIBdJ7A8JXvvFxzr/FCN43hk/lyPAlOjzsLLQFUXfaN8LeAru13RlasDGwAs3QsciCEsLlem2NSsMClADALAabMl/JHlDVgqh271B/v+Xxg1iUS4swkhk+4',ENC=>'WH9GeChK7CgU6mV13XSIYhz+aiijPF+DgaKtW5QIeUcxdYlEd9VcWc/P7J0OWzWdm+QnluwIzSX/Cjl9Lb+dcZT/YY1s/TKU6mFG3HHEGqjX1iyuxvVuHPCxLq67laSsTOH6Q4hFrwrcvxXAx/VbqnGtZacQUZuvzF2oaSgnBE2AMtEBWPMDRxkGFRvm8dx+bsetV6zxmlgkIiAagWEv8HMG4YDa9r/xzfNNLpsJ/YcqrO+cEuXcGp5+MQubfsei',PRIDER=>'MIIDfAIBAAKBwQCwlJ/ggUWNQC36eG8rzn/MitgLNrsusEVb4SX4MKB3LTUsmH8FOYHoZodR/desF7UNaY96vjY596SksLgDGmW+4CBRHMoq0sdGt/j1ATujTd+6REXP5jUlnwJAZywg6mI8X5KbMy6XsrPZYx3y/Gvnhl9TzVbkCHbur+SMr82mGVfP0zd0XE+xj/qjcXHy2FAMRwtUCFfoXZrlznf9zjomV4RtBL2UlN32gF6p2Tg5kGM5pyBGpztK7OYJwMp8FHkCAwEAAQKBwCTprNI9s9BnTjVB39uEe2rCy47sjgyghJ9EXa+YWrMPHEKKTmNFNkbix/731ZIAErUPEBNUl/leL2jOGGltpz9Tku3h2tFA5q993ek5rMHikZZal01yjkGjD9Fuv+bRmAaURDuPK6EwNAbqGMRdDng38n0gtC3unmtkE/vs+mBg8FRzjMh6YMLmK3RkTr01IyMmhuUzmcjfdRtRznzA0E/hJieTLw9yK8ETpnwHgfGSP1HBiGbyrFp3FhF0P4/MAQJhAN486/f/pc9FgqAq7L59s6H0DL0kRGMhNyO8bkbcji4ikdcpOOEODxFvTSTmMnGK3rqL7cQw4/IUTxs/BWoiF7Hbbgx4ctOOxlNLfBoMA5HAR4IEuPL3aYZQf5ga/P+mWQJhAMtoCTqR86kvusUaAFnVS7gI92FO1MpACgOPik3hLqAwdn3vjvs3W4J5WwDT/aB5KWje4T+E9Db96qVuwB0kAUFoKtf2+lrAElg/uy1mi2nrv0IevPmjDRgJSwCqV9ZbIQJgNwoxiscm4pGdi1t2LKtnHLobmZBs23wzcsdNLIGdOPHY2sfbzWk09CVznqrgXVx+UwcqyMcu/RpoiR/vkFyHL8Zfl/kQvzKCDckJIE5PZ/6N9zaCM7Jw0RIIt7wfYpVpAmBneU4wkGzOpWwytm51RI9XWKBXzR1sobU2aH/n7GSmsuCkYghvfZK8xfVob283gktxgOg/QuhlTThf3f43FMjauB4LbSWgotLyN8GFcAP95yKNhUuHBs4zaw7PkNhMQGECYQCJAQP9LlOCZjZ9rQoe4AM/Lsuuxr9Xr5/vYndwxBbhCdS78x4PYs3AOs4LrieEJLncbF7BGT+WKP/8YqOZNOFShz8QdbbMPBwo1cFU2x6Q9fw9pS0iC4nErobkjEHxdJw=',PUBDER=>'MIHfMA0GCSqGSIb3DQEBAQUAA4HNADCByQKBwQCwlJ/ggUWNQC36eG8rzn/MitgLNrsusEVb4SX4MKB3LTUsmH8FOYHoZodR/desF7UNaY96vjY596SksLgDGmW+4CBRHMoq0sdGt/j1ATujTd+6REXP5jUlnwJAZywg6mI8X5KbMy6XsrPZYx3y/Gvnhl9TzVbkCHbur+SMr82mGVfP0zd0XE+xj/qjcXHy2FAMRwtUCFfoXZrlznf9zjomV4RtBL2UlN32gF6p2Tg5kGM5pyBGpztK7OYJwMp8FHkCAwEAAQ=='},
41 {ID=>'key-2048-6',SIZE=>2048,PRI=>'7EC4BDD99A49898D28E94937515CD953E014A25A64AC4FDF3805836B067902DD4CF9DCB31FDDA9502A0A32DE67C1E96F4BDE7B8EFAC575BA1CF88704A4A0D2EFD4BF324B3CB4E35FF35975A8C37A756B668746BAFBCE233D8BFB383F08884800795071C561B1AA0A098ABA93310EBA4EE634B7EA49DBAA9B70040DE733EF41D491600F724E2FB473AC538D0490411508F037DB7AFD713CAC81A6403A44889AA7C660B820BA20620CF7B8C01B4C9659CDA63D7E54749E5A6CF840EF7C3E735B7817D896A1F8E14DD56DE625CF985B26A47028002DA95820B7FDA1C41AE63FAA59EBB56D4D71421CB51CF51701A9A8CF6D98CE103FE4CB37897820C2EFCC020B01',PUB=>'A64DB84D126078A471D0BBADEB93311F03D73E20E22A087E6DC75F57A4657319D4D144D4BA2F196E79494C8E7E128156027565B0EBFDCF2EC62762D9C675DE8FBCED415012F0C15BC19789FC6DD28296F45B0E91ECE446F60F4E2F2A952B006B4015DDC4A0399E123082F5BEE32CBF89C5B68980D4E0BD0647D4D242C7CAF0D260AAD2B1406912495DAF7E9E38C750B32C6FFA4F65DCE35A71D8C6EE0D62E9707BBD039BA8053BBE36FED27CD0E12333097BED9E93E2EC63A7C6F00712479B88A42D6DF40DDED6402378F7329DB6A5169FDC2EDCBE577A2C5D03A38B25FE711C7E518B6EF6B474181C27E10A00FB684B65969D878A222E2CABAC60FDD989D2F5',SIGSHA1=>'JdSm/mDI/mDzAAmPPoQ7bVBtJ4U3a7DHkt8nMgh6Z/SQMpJoyS1eTisgVy+6HYgrgJc/stbjzB9avcn6ITdY7tWK5hMhFxFXI6ICLwbOdwR4xB4+O0V4gQSEiVbq+1SeK62g23G3jqnDmBZKBdj5sdR0eXtlB4FItNSO6MzFES7YAoaqRI6k9T+iK4TfNKYEIqkFxPVh1FpuMn7dWVuvIs15E93gmQf1wKlfbRuKZlJtPX9UV6A5pFBTXggtfMJsRgdgvj4v1hz8RkkOp0ZWjoytLvTKIQDn9niS1hqYgSlXOihLYSoKovYyX5aLcgkNwPFTHWkTnivPwrORBBvd9A==',SIGSHA256=>'Q+avXg2WrgirrSe3u5Hgx8ybpX2E115jzFFbt0L7ZXvGwf9gyu9N/jv6lG3/q6heAUry7o0OLVQJpYYTy1VzMryt9XkDkBiNCd0rWea7MM9KxlMsaZkr+Bd0VWNFo+6Q7VC2s9Ur2GVxpByodLCrZNz13rZ56QlO+/IbVsTVmYvqiai0xWTB4Un7ChdwuYjsHljdRC8HVyz2q0oZpCqMa2OkaQ36J8hNdt58zM57wsQusOelkdPgtTXiE/a+M4YXFjQV06OHu4XoIiND7LPe4rEwSd+lXW7a+Q+kmkadXvx9MW0F0tb88Xrq7tPDX1Z5si+ScOU3I+lu0zZIdfyj+g==',SIGSHA512=>'aLA8+vhasUXdYp3Kya7lyKJLfdbVVwc76U64+k62lbF4UB0xXQ+9guK3dLVkhhlOn2WQxg6gXh7YhX4ihkQKYpbwD2d5FBe+Uka5fDU/kR+ygDoQkM+NBdZ9B/QNCP67S7968en2mFqueRkFw3a4rHDl99DmRvBv2hSgk0l/kJ4nXz0k5HPgcHpCPTMFm6fGVrbbBW284Lm4102KrbiVdrJ5MSjo9QsE4L4ZRmOf+0wdi82nQNn9t0a+VsmEmVqD389GfoeAlZYrJ/nLHUZN615PbeTinru+/dWtxxStCblIknXAHwpNUgObs4IBhGs9tFYI9QihYOXZFNGHROApKA==',ENC=>'V8KCfS7javTY7+EACNP5YTpxH+Qt7BAp+MfllSF3TNeclfdQme11GuJu9ia1KAfWyQi0Wx5LsO0IVqP//7J0hVa6OgHGRJEAXgjTzufu7uKkrHc8cC+0XOtZoXSLd4OvVbTk84rDlauFsQEjkKWlZUuS2AI6GWhUozM6zPBwKxOgGc7OQHP9b3NVDGgzJEv6c7R/Uf8S/laOlbUla6XeJBGEWNT+elmu3pQC+qiR+mnQxZYFAF70geCfXoiB18XvDN9G08552RLS2gn4QQKSQhTCiFnVKdTWgRQHcAihQBgIdmGgYjX8G5uUx5jqGuk7r8YtVqabNIFQBsmiNuBUjg==',PRIDER=>'MIIEowIBAAKCAQEApk24TRJgeKRx0Lut65MxHwPXPiDiKgh+bcdfV6RlcxnU0UTUui8ZbnlJTI5+EoFWAnVlsOv9zy7GJ2LZxnXej7ztQVAS8MFbwZeJ/G3Sgpb0Ww6R7ORG9g9OLyqVKwBrQBXdxKA5nhIwgvW+4yy/icW2iYDU4L0GR9TSQsfK8NJgqtKxQGkSSV2vfp44x1CzLG/6T2Xc41px2MbuDWLpcHu9A5uoBTu+Nv7SfNDhIzMJe+2ek+LsY6fG8AcSR5uIpC1t9A3e1kAjePcynbalFp/cLty+V3osXQOjiyX+cRx+UYtu9rR0GBwn4QoA+2hLZZadh4oiLiyrrGD92YnS9QIDAQABAoIBAH7EvdmaSYmNKOlJN1Fc2VPgFKJaZKxP3zgFg2sGeQLdTPncsx/dqVAqCjLeZ8Hpb0vee476xXW6HPiHBKSg0u/UvzJLPLTjX/NZdajDenVrZodGuvvOIz2L+zg/CIhIAHlQccVhsaoKCYq6kzEOuk7mNLfqSduqm3AEDecz70HUkWAPck4vtHOsU40EkEEVCPA323r9cTysgaZAOkSImqfGYLgguiBiDPe4wBtMllnNpj1+VHSeWmz4QO98PnNbeBfYlqH44U3VbeYlz5hbJqRwKAAtqVggt/2hxBrmP6pZ67VtTXFCHLUc9RcBqajPbZjOED/kyzeJeCDC78wCCwECgYEA1vXsRspYGbGm8QXZyxmr+WOYePVLen1fEcJobHm34O099XS1XHeXzsmR7C7hmL2+2gdMVSpJHl9suwtB0rpIpae0B76I1MTGHBnDsPLji6y/8doljvzU0fADU3GZoK22qjK2vgM+1ReyOE4bVJFxJhZtj8LlP8CnHCG1slQVasECgYEAxg22Smo/1etAyL6SRkNfPRieoDuAINiq39cQGE6vGd9JJzaBo+XCPoyo+/MdzIBjQl0plgR8qsopmnyZw0rXEtTJjYKo7eP/udd+NiCmwf5InW/+mJW5kYLoyHAeQ/bEVnU7v7OI5jgvOCavhFLBq6OkoOprxbwMu+mo8KaF+TUCgYBsec2yK4op7SyBlKJDi8DtKQVYhPCB76J6I9DubL4OE6qgozSiZPeGstGgjkfp/FbDT8uFbsFXQnBsM1IUNU1Tyz1eaxhBxsryg03tjaSmZ5a1RZCOh6geCTCkez87hm4XlWACo0Ch6ENXhpLkKkEfJ1JCqedmNKIf4CMAys3EAQKBgQCLJsszUZ90T4v+/1aKo39gz9Fzxxpo+ZJlHxeh3HbOeMFPGc7QNvfZNr7r9o6zRml3ETnMu25UGSJN9smaGxUtl+/cyzahnhXonu2AXkSL/HtMkomQ73GoORAQ9CVvnwunq0rFkADZsBQNIbEkCXklfR6IKOx7y3ou9SbLnlR3GQKBgGvUaWGs6qFobXbPJvFBmWwhwqTyV98F1GSTP+IqiWcWDHQoZ/GDxAPHjkLRmifWJ7271xlK/YkL3wD6mw8Mvb8G5VdMw2/T24H3WNbSPdiy/sx9shvbx7EFVL9O1sz01eGSUyuMAYGhRAZ32JWvgkqT8Hdq2EFOoOsnlrsDmlXh',PUBDER=>'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApk24TRJgeKRx0Lut65MxHwPXPiDiKgh+bcdfV6RlcxnU0UTUui8ZbnlJTI5+EoFWAnVlsOv9zy7GJ2LZxnXej7ztQVAS8MFbwZeJ/G3Sgpb0Ww6R7ORG9g9OLyqVKwBrQBXdxKA5nhIwgvW+4yy/icW2iYDU4L0GR9TSQsfK8NJgqtKxQGkSSV2vfp44x1CzLG/6T2Xc41px2MbuDWLpcHu9A5uoBTu+Nv7SfNDhIzMJe+2ek+LsY6fG8AcSR5uIpC1t9A3e1kAjePcynbalFp/cLty+V3osXQOjiyX+cRx+UYtu9rR0GBwn4QoA+2hLZZadh4oiLiyrrGD92YnS9QIDAQAB'},
42 {ID=>'key-3072-6',SIZE=>3072,PRI=>'16FBBF8203E2D8B2348D325B0DAD6195F89B74474CFCA36C51949AB49C938D6B741F878D62E2A8F18785F9D1FA9F0BD0EA3A76F29EB682F85F0C139D20C755FDDD80763AC91C0A2EC5A3862ACE4907E5F91CE9B32E92E9178C0684B3226360945BE4A0CD3DE401D43C37356A80641877578A749CE45A91B0B7AEB2DC1036E270102B3753DA828D5079336DCBAAF6570E030324B66CF63CADBE6D7419E434BE5475D83B2E0E55C82B3D41A1CF6C442642116637D396DEC2E48D93627431CB81BC628587E30EDFE516B63385CBBAAD4731B54B993552A3DFC5EE01748FB2B510811FAEA89E0ADA99AE285B363F0DDCEC62C4BD6D96C5BEA9A02B5831E114A1D700D9E337C75D84DD96A85BDFBE99DCD2691310291BB0C0BBC5DF72CC6D6D78724B3F55CBE31ACA06DDF8ED74B054D6CD4B92E8D1F37243B01CC4ED8486718D4D5EB50A32E0BC2773433BA2628BF3517EE8BD83CA1C680DDD1CD00D2CEB3A6E36208034824C393E14B703CC03AF3B05CC4764C023DFC2A021786FC15FE532B2225D',PUB=>'ADAC2FC057FC5B6A53C0544EC085A177C1775CE974F940B3235BE4FF98576DCD925820BB53BDA4170975D77144F3C36E20FB4851A23A8D5A5A0A2C5EB3A74B8298E83B212FDF09CB470E4F59E46D28ACA5068C1708007660512C62A29C746257ADDAA6F19630755DC6C7A431A44774C81FEE6997990778154AED187DF3650E39C0C0E8545ABF348A730DD055446410114C832A39D7EF84DADEF268878CF63EE81123E4AD0381FA4DCA20BC778BB0D9E66DA2597D51DC562B491C8B3071CEEDD9B09BC364085695803325887E1617CC900102953BED86ADF05B690B067CFE7B313DCEC69149A3E56E56240AB24928167743BFBD113E8C434B81B55E41855643148349A0A32DB8EF0B559B6661334D67BFD4F2BA539A74EE0D55EA5807B714BCA884F6D893B2E8B6B52FD055D96BA879F22178B534DC3E70A47EB00FF18A266DD342E0140B8E92C04C15547ECFBD3A74160A14A9AD010AF6A22B31DD04E9FB80E48A5853EEBB64CC3A6B5D8072937F532D19894484EC72E43AECBDB0537B1812CD',SIGSHA1=>'CEyhH4ii4bEPnfn4DimH9NmIJnQH/CktEOtf31/kdaz5PnIZ3BJmrNSl6cQ1BNzA2DVB2bCdp8hJKNujUZyyOvFnjB2obkkvneNU8qUBumxGyAiUOvIvyqOWpLvFBpzw59ozcCeI8ttD9DRQnlEiz8f19DMlLUvIkS6B2QX3R1isUGeLGT/78pI6eps0HLabXvdZorxVmD9miv1sGhi6nuarjErx74952vgP4eb5pzZBiuWo3Uxtj1JxYnmV7HfXpSSKsgIPbjXhwPXCyJccp5glFmOL8KRtK1F1mmm3FrBbZ3nmw2mBeHtdNHy7io3oc7/ESjwG2Mntgck4KnLXzNoRgTChmIEoUEON9QX49VoQAj/cbhBzQ5QO6vL4aEMwqkh5HOuTQ9LeBdHwmfsoEee/PHAXfxRU69FLb3lEQxkU+G9Do1V+pyL8XvKgK8YJTKKyQvxuzt0WUX8uiB61uxKY1g119adniFo/VSvCHg7kS9GFRoOk2flDhZhlWpbd',SIGSHA256=>'PphQHkIPb2AhcBdLd4pHJBn89NR8DWXViKRTncx4PRxr5p3XfN9tZGjuIRBRHoXb3BVJM36r2mbabHkNXIj85jdE5W4mkg8xjQuqp/XocRzzjuwAox3uKJfyKUt5c2S0t3hWCwkA71gl/61PH3b7RITeECA4Op3d6epu6xREPDVvQ5RpnXQRf1qVPXv8sdfQyKJ1U8ZkA6XdmpTNwVSn/qQ8R5R4EIBssi5cS5UDyPdrzVTz6S7KQngkfU9Wlrn+RtfAWheRrszZFSYD9MjiwOwJNuncXc+zYCceGcDC+ADE67NTPFTxSGM0+JM0btXSIb74wCZzXpVLR9HXcmIc4l6T7jgG+5lMEWcHnou87Lq8PLPI6v474YyhRWbm5cOwVKvvlbLsBZUJAAZmumlwD3xS72BEht2JugwzvnBsYxlYMthTlf6H0WGktTgEE/+2AxG64XO3graJIlAuRcZxzv/Jdo1Tc0hTMYr6kwGjiNRwHYwHkbJ+aDVEeqr1HE5z',SIGSHA512=>'NF4+LH+6+/wNOis3mjCklNpQ+j4PK7/rKmEpB2ZcL3qb0gbKAYjCNX7hZoay6SLWlYtBma3H7xf9vKaZsr8zFy2OV81HlQnG4eaz363lEoDfzPgl3of29BiV16lnfOSjr+qh2q9fYq6YvALxsBY0l5tfNkKBERr/rCWDZCg5Dv5fFc9RFFBGwy0dah16pQmJ5cd1EXsE942Kf8btDs2Tnjyy03802fuS6VKX3knS0Nbl0+zvN/UnhQileX8Z6ts3rD30fEz+k/u001Akw0AH7lj6BIjJnS4IUCMoGNTIN0BIorjOfXMFmJy9DaLqFuk8Ju1ZWxN0xtk6gDQrIPgVy91pGFSBVPhxyHMIXY1wDy30HVSzcac1tMZIKeceV1RjF7+iurmFlsJmnCR3qE69QmUFtmSEbGtprRyQxG2UTermqTrZQb2ToVoQYTsFvt/qgqHa1ZkK5U60tEPq+4QHwqlYC/LpVFvEcP4VAEqG8Kla99od4QaYEtg9C7U5ZR6/',ENC=>'OFH7LDDe6C9m6aSZpm2n+WFzeiVT5ahldTopxVITobxH1q5TFEk1uJHV4JKUFEOCHwPeWiCsv5BzvzUVZOS3lp7vp7MgBNUNE4JJ4L1Wb6gL4WajBMwaqUUrz+GEeIjrWJ81ZWxkiseZfc4Z/4duU4R+Aaq3U6rZRGp4GbEp2iCYEdBhOzQhvzNFm62tW9ajFpU0TpZ8XJYqXQgw/26/dkv6W9zS3KvAvVuLP336fnxtKKBqr+HVKU8BSwS+wQJwNchK7jgOp3/kMGZmy6JVAWfv4E+FOdQma9a5ewNgq8GErz8PC8ScA6egWQTn+edFixnTPcWEU0k6UBvZQe8taDd0Kf9ymr56r5hVjsJh/Wa0Gfnp66y3nK2ZhQt+odI8Kzi+JLHePHr6+qRxrgYT6/0740bktgRQhQC9mYC9K/274QAkCj7qWWcGyZodzvBj4vPyg/Ck6ISGjyjnl89lkwS7L4Zi7P9AjFlPsaaXdtdcBXnly3Rhbuvg3B7EHgB5',PRIDER=>'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',PUBDER=>'MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEArawvwFf8W2pTwFROwIWhd8F3XOl0+UCzI1vk/5hXbc2SWCC7U72kFwl113FE88NuIPtIUaI6jVpaCixes6dLgpjoOyEv3wnLRw5PWeRtKKylBowXCAB2YFEsYqKcdGJXrdqm8ZYwdV3Gx6QxpEd0yB/uaZeZB3gVSu0YffNlDjnAwOhUWr80inMN0FVEZBARTIMqOdfvhNre8miHjPY+6BEj5K0DgfpNyiC8d4uw2eZtoll9UdxWK0kcizBxzu3ZsJvDZAhWlYAzJYh+FhfMkAEClTvthq3wW2kLBnz+ezE9zsaRSaPlblYkCrJJKBZ3Q7+9ET6MQ0uBtV5BhVZDFINJoKMtuO8LVZtmYTNNZ7/U8rpTmnTuDVXqWAe3FLyohPbYk7LotrUv0FXZa6h58iF4tTTcPnCkfrAP8YombdNC4BQLjpLATBVUfs+9OnQWChSprQEK9qIrMd0E6fuA5IpYU+67ZMw6a12AcpN/Uy0ZiUSE7HLkOuy9sFN7GBLNAgMBAAE='},
43 {ID=>'key-4096-6',SIZE=>4096,PRI=>'9B4353CAEBE8457014F496E6865D04E3DFD95F1D54965675A0B257C297C519AD1359390ACD4797F29AB4B2F21552F23309A8223A2F61AD44A15B77DC3F6F5DE2F4E4767D42E681510303182A9849C10396C105BA681626DEB97F668ED5653AAA4A2E1137FA1FED9641AC4D45B54F6FEF2439E173C86AEF262226C006AC68DA79F330DC37DD5772782172E14DF778DD9F09E7B4517671A868A99E1F025BB62B151EAD2710F976266CC4B291712BEB9E8CD815A27F8E1ACC131C32958F55B454CFA6B3B0A096AA66D17E1B09E5497F1AF68C61438CF962FFEAC0B3739BC3C8250148F5A33C67753E7BD2B2489F8F551E98F1F8202639773E1450A0C0380B2F48F6F61097E1586E5F125F7ECDED98A6C242FA5118B53B6D9150E04753FB8ED333C32C91B9F687730BCA3059620A4B8BE8931D67AB7B9D48491ED8BF3C0CD87071DDEC12DBDF1772109253FC4DB3FA800BF8B52790E5A4D4E01786D2BBC1702690D50A5CB3E2714590C3BA595B48BC6EA70962DA2D63106E1B2CB7A9CC626250E3079E08074CCEF32595CD21813B59302A1AA70DD371B5B1DECC9CFD27E05FF90295856A46D347B9B54261AAF854273AD2593BD8F6A01D4BC1216F4523403486CCAC37DA149813D844C5332735407885B39C20ACF99F2B087D2B92AB5CADA2914D274B5A6D47775E495B2797C9542072DAA97BBD1D30BDFEF2A75DB127AF1C4B4D01',PUB=>'B91601C0831133E391BCC4D5CB769C824602F2883376466F17366505B6199BAE6C4AF3E5DC2597C9E2A206941FD1654623DC465C7059E91C304C2F968956389B17C0045449FB346F3C5F364EA678A31D273977D04524677D6F041A45E4CC0C3C2A734396D5AF9E479AA63DBEC185156D5E2785D70A776B1BE4CF690B0AE60DB19ED03EB2C9E49C10A6B769D763C28A154BED75798AEC201A755421BBDE9B2874FAB290E45B5B372B7478425CF59188142F2764592A53129A2D8077835EC5A47FF54978BFB1F89A63E2D58E5AEB7B0CCA2E8E036DA4386C9435B0B851A7465709586D2AF00E03B00B2E5B1B13A7A43D23DA5CA568D9344B81F3B89C5016C1FFE09F4E2F6EF2EC5F86F86BFEC1BBF9BF58432A7AC36D0AA8F43756ABE217581E5AEEA5BA0913DC60908F6268BDE41680728A5722A730C17EF86EBADC126B8E6883212E1F5FFD277F5F2FEEFDC5FB124CEEE80E6005C440882475216BCC9C75CF06CAF649D502A04544E8D04E351E1838C6540ECC06226FE162AE908A34DCD13BD15C02A8ECC5C176C86812222A01AE206D01C993A4D80BF6AEB6C934790C35991AC52B9551C203F0BF352A58A5E614A1D85E870ED69AECF584DF0FEB26FD9AB2D785A65BDFE4AC53878F5AB5D8C56FC91F83F7816F35D23168E91CAF91DAA00F2786AF54C06EC9526565319A2CC2B3F3BC76F1610D6EB891FAF9285272AE1FB0AB',SIGSHA1=>'oG7/hP8GnOzxxPjk4tMUoiuE2winrQvLCZjmoRn4BzYfwXYuUOwi+IIgOp9kX3UYLjIN93ATvt74eE+Pd66TSvcoosejr08Am57JReN5dZQqy/dXA9TB23CTlJah61W5Cv7iKmImjefMfFuIB0nNEKTwsgSdeZmdsP+Ehuvcpqayte8IEknVGpS7pHKIEqqYr9BeqG43Xj3uJIySRYZOIDP951pvUluHOBTLz7n3bbCatTYE+OxGtlS5Yx7Tl/iMaixii13L0BIFpxJN1m74S0ZhwQWsLALJeNl/WFQWYe42OHbuKY5EHakUVxmAeWM5lEq5uUVGSgTmdc1BkK2ZZI0piVRMyu4Bs0jj9PTsZ03cJ2SA39fyKZQAxGf8Ivs2vgnsPFxj9R5WQC0heEkcFSjlRbWGFaC+IwktfySUdVYymd9aSxar3ZvwsfM3K9z+hOLFQ40OXlvACHgsX9RfDQPZnA6eFEm148P4Mtk69uJxZbfArqlAQJlwc5eJCKsLnnDyCPF0iltuvMChxKz8KUWuxA2jTLCF7hq0/E4MNmyq/FEdPQ/RNAqO5PMIkh+gX9i5cv74usfZTDupfnsJ0PpXxwEcTkIfLfwlRbSmQI3H/4dFNk7CwxV6Ac0HuAGOJMSmmDBHa2O4L8Dn2/PsJep2bi+jq8z9PCT6FB/c6HI=',SIGSHA256=>'AvNlYUj7fO58cfoK9UARP4ZGV0HH+/u6EjD6pQOkO5FGVXSQHOT4Fpz1tAsqSJeTdYRB7n5mVdErpav9/WRupQGnP8oeNRwPR3lVmsQmahbKo+qj5+gFQqNwl4ILi9pQ18BhJ0E5/MvZWye39iKfjtWvB/VdcbD2pEcoKbyTy5sWOQT3bFPt5hUQ5JGJrGgVwj1ZA3afPmbCJk1AzkWFVc9bn8q/wOvz77m7uPRX7s5WSmZQt1V853puJeoW+OLURLFUvmb0XBFcd654ub7KQI1XTdpM89BZjTq/uG1aodElpOodcf5tDQ6mVy5G9i1Z1EMQGPwFXhz9BI1KnoW77uGo2VgDnFJ0Kn7Ns7ijlI5xzJwXQOfyo+Mus8zalyUkcUp+f0KXgpkg1jbEkPA3SldcLkVoa2k/WZOesDGNu2hF4rbp5KtfPpyD15AHmN/ae3CKkvguvlEyeCda7wwGdYJ0sAanuxeFW2tHrxzdOrAPrcyYLz5idWqGenPXSJl3XY+A/LcaUgKFFnWw8AfPYEjThN3fJP2WNRBe7tUgP6xfk33DJUF6ArPUbs3oewZjU/ilSAbRN8ozc7fgBSk7dijwUh1J8FYTigdKlkp505bPFj/QcvAymVISlJQFCPU9IjVlrY+NaA0BcN1/7yFZqIBeOWi6mjTLsw7XWPHixiM=',SIGSHA512=>'TKMhcP73ggPod4FRlNHue5EiPGj9fSt5Wk3M4h14/eHHmR4HV6f58d2TRtZiCBPZK4hJResiLF3x7ycJOBG5YUhcEltVtiwKqLJU+g56c3BDocuQkhiLKS98TcLhpSHWyAk8YLAENFw7cwVsXzh/IsKTsQordTe3nBu2OqnqQV4gSmFqptLB56z2wA+B4lqSPeQMf/9s7WluldE28uZb3hOiyfiTtH0n7+l2mL/6wyCGhAtdXUmLIi2C8AN+nqTYU2hQ3HuFXiNl3TVuTkV2izEy3PtSUvu27vOETOtw2SLHiyDNVpFEhbfgJ3eRSo/dSKNhrHERJzdq5aQKljC3dPbsp7eKDrk95Vv5hfUXy7RwgvS8F3yNgfBN80AlBOChKOlO8str/eEKiQLvBArrvcqbsB5QJY6GGxgeRtxBV3p48SsRfK4TlBtifnS55Mvj+BgdyqKeKymj83R380aC8DIlv2ooaCFGduAvgoy9lmIXXdQxiPBmS79DfMr1Kir2+UMJqinKguCU9YCITxMjDw2meZ71nQfEJ2Oam1rpscGTSPuwAPkQIY2m4oXwtUI7ECYn3ZZuqXdT8Y6gllgAGky5gROiHVYRZMFTSmpJDh+mkezlPSEvg9NV//6hNCUaGZWfsvHjbjYf2MYlRKm+sJhC8ZVUpDYXKDdcSxDCPfc=',ENC=>'kawY94mUiF6MpZNZzWoBssLR3cT2skUZnm3eYX4z25piUigiEpolH9Dw0nilU+D5xm5jGFFCXtXH9IpNLD2Din0wu0pQ6vOVnMl0tCWabO/gmkSZ2uKJlzLhTR3T+jd8BKKDl+52hELsYbot8J7fZPmkfaYvEYmh9Na6+o1BbogcT5E52Qnrr/+ivIoljLl8TPnP5mUrmW0HGxDVB/KYv/icGTZrTGx8J/ABkjCG5KcP/EK8Mj7YghCXjcv04nNAH9SuWGzVG1tRICiaUHYWQab5dxENwkQz0E3l2+oC4PUyu342e1Ab7hRX/U/TZz0/cEoj/LewGSgMMIEhsTdMJPvxRQvgLYqMuoMy/tGby2eKyYjrCubrJCJaTOkYGqoNGtivkdcSxS0vHgh5P8nD+jsntzbDwmrsE2392xFiUKxURuLNspk9AyZjRXo0Sm3yiY3FJqyIEV12bnp+aslabW3NtNy4ZLkygdVYFw63NvJxcaB/88ImLSuGDWHDIjC8gxfRWaS66s3a8RyQv/NgfBzoeYFx5iShUr6O5Sm8OnQr+14cfcEHNVz6X++fQL7oUjSKRQa5Y2mS65IIfq3IodGfEd9EP8YofS75t5dh+bZsaupCDBiba/PN/f2243SZ87BYsW+vEUBg4SSfPBrJiovpmByNbXJZ6xZVRndsHbc=',PRIDER=>'MIIJKQIBAAKCAgEAuRYBwIMRM+ORvMTVy3acgkYC8ogzdkZvFzZlBbYZm65sSvPl3CWXyeKiBpQf0WVGI9xGXHBZ6RwwTC+WiVY4mxfABFRJ+zRvPF82TqZ4ox0nOXfQRSRnfW8EGkXkzAw8KnNDltWvnkeapj2+wYUVbV4nhdcKd2sb5M9pCwrmDbGe0D6yyeScEKa3addjwooVS+11eYrsIBp1VCG73psodPqykORbWzcrdHhCXPWRiBQvJ2RZKlMSmi2Ad4NexaR/9Ul4v7H4mmPi1Y5a63sMyi6OA22kOGyUNbC4UadGVwlYbSrwDgOwCy5bGxOnpD0j2lylaNk0S4HzuJxQFsH/4J9OL27y7F+G+Gv+wbv5v1hDKnrDbQqo9DdWq+IXWB5a7qW6CRPcYJCPYmi95BaAcopXIqcwwX74brrcEmuOaIMhLh9f/Sd/Xy/u/cX7Ekzu6A5gBcRAiCR1IWvMnHXPBsr2SdUCoEVE6NBONR4YOMZUDswGIm/hYq6QijTc0TvRXAKo7MXBdshoEiIqAa4gbQHJk6TYC/autsk0eQw1mRrFK5VRwgPwvzUqWKXmFKHYXocO1prs9YTfD+sm/Zqy14WmW9/krFOHj1q12MVvyR+D94FvNdIxaOkcr5HaoA8nhq9UwG7JUmVlMZoswrPzvHbxYQ1uuJH6+ShScq4fsKsCAwEAAQKCAgEAm0NTyuvoRXAU9Jbmhl0E49/ZXx1UllZ1oLJXwpfFGa0TWTkKzUeX8pq0svIVUvIzCagiOi9hrUShW3fcP29d4vTkdn1C5oFRAwMYKphJwQOWwQW6aBYm3rl/Zo7VZTqqSi4RN/of7ZZBrE1FtU9v7yQ54XPIau8mIibABqxo2nnzMNw33VdyeCFy4U33eN2fCee0UXZxqGipnh8CW7YrFR6tJxD5diZsxLKRcSvrnozYFaJ/jhrMExwylY9VtFTPprOwoJaqZtF+GwnlSX8a9oxhQ4z5Yv/qwLNzm8PIJQFI9aM8Z3U+e9KySJ+PVR6Y8fggJjl3PhRQoMA4Cy9I9vYQl+FYbl8SX37N7ZimwkL6URi1O22RUOBHU/uO0zPDLJG59odzC8owWWIKS4vokx1nq3udSEke2L88DNhwcd3sEtvfF3IQklP8TbP6gAv4tSeQ5aTU4BeG0rvBcCaQ1Qpcs+JxRZDDullbSLxupwli2i1jEG4bLLepzGJiUOMHnggHTM7zJZXNIYE7WTAqGqcN03G1sd7MnP0n4F/5ApWFakbTR7m1QmGq+FQnOtJZO9j2oB1LwSFvRSNANIbMrDfaFJgT2ETFMyc1QHiFs5wgrPmfKwh9K5KrXK2ikU0nS1ptR3deSVsnl8lUIHLaqXu9HTC9/vKnXbEnrxxLTQECggEBAOypoHOiXVG6ZpGkbgrGsi0qEykB/ER3q3FD/586Usz+wYlQdHP2ugTfiKuYd6OOfCzgCLmY7zl19sU9H2Lw6oqISmQUpPzNkuARwBL0F8CgCZm/8G2W/dBv6L4T/RKIeRGpR4ZmyUcG+i1h0DP1K1BIK6VAE53N4d0qq0uWCMHIz5pxVo2XnPJBPrP9r2djl0ggJo9hJfwe3inRA1NN9ndpfbSZbEflhvYkHVg8noUl3g5MRxiBsEW6F6JPRV3XfWF/w/qYKpHJ3C6PKTPDMdCzFYEBvLGKBvAwiVfrQxwGD5xwX8TOTUiQ9zV1KQznhUyXuOJFW0haTYqARGYvlysCggEBAMg1h4SDGznYlxTTvQrqFtm1iiJm+AlzvCnbIQhXacPS/8HYh5WhqPYWTgAW5IQGTUPAynHyFVK5YhstLBePql+qEFFazD47q5yKLN/FQvHtiKFm5C5ixqa0xRxu4zIUcAdJ+MncWJ7TCYXKGUQ7zLZgW63TJezirRCQxVKtd4ILfIaD8KgYsaRVSqdMtvOzom23g6uE71rJO9lQ35HZWet7h9Lm0qBbPIkAGo299GhPJAQhm8n7CagZkqBQMroLtH5Mj3BTYgUatFIas5WAQrgEzV884S2w6gy+1dryMcyfl9tXg7g+mdbEhaNXv1GpPXuANCS4hTkrjHUcua/rjIECggEBAMaZAgCHe/Adj/0gEwgP/W1RJYsAE4YRNllySoyAEQPdtONaFJ9LqIZ2XuZAqAUkiKfPyQKWiAmcKF0UEcahjPB7tpGNkXZjvKEzxA8jrtsCcYwIOeZ9Erlbb+AyPejThWWAvHjYwIdOH5r9vg4b6yEPrzCZONzv7F4AdIaVfPvBXBWqjot7c0UH42p/tDX6qPTppfIkABA2hxBoSXYasn06lTZ8mRUsU7kyTT3CgPQS9ujgsbiq/BVHOJYIF5nMP3cWFIuyLebxkkev809wudj8r0r2/jWuMmxVDqwszMAzhd4tnvA0fz4qCIlfq/ccQgwoNgoLUbLBtNhJExz9SskCggEAD/1Gb2zRFdOYbU9jv6VmYci/2XODx614j5cykin5BmyphF+4pFie19h8LkGlym1+ajTRdjwxO8QWc7kt1kvg/XblirnHqgi18fCPGOf2KsAfs1Q2UQYOe23geB7bAjrjn5FmzyhL45NTJV44mlx0QvR7HezJEJwh2jrVp363Fqm4Lj4HUEV4mnk9VxMnYVstU7neSCp7uzJrFzYARPOo3Mem108b7zaaJQ7fEAblqBb592J/wKfN46D3Ntpw0q7woU2X/w6Ju4KgeBYt1XjC21N2225PRYjliFMNXUkOdRsh06Cvol1Nh/t1+M+fNfRgNqbMg0pBSYmS1B+RLN2RAQKCAQAuUdM+3CIQlReGY4gplnQdJvMeAl9BVD+zmjcU6368ZSXYw0IIQpL1OSayFo0gri8dqdc7gvFkYjv0GpawD0mi3bHZwyMuqWsX7+MbGkgkzSlYj8JNhq/Flx3UMoN/cd1X4alixYNwuhU5WYv/7ufYv4MD2DXBEcnm7Nhj+GwSdPoscjmLXe1g66LzOlcFimWUYU2+37Lx+CuoyLU10r2EICPt9tLvcOReLrqREph9xcuw0YCRcfohonb3Nyu/nd8zZvhqMek599XA/sIBA296PYoH/3YOGhkfSMELltZfZb5OrZSd3jYI/fOewfZoshKtsUHFj15aOEqWkYlvb3W8',PUBDER=>'MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuRYBwIMRM+ORvMTVy3acgkYC8ogzdkZvFzZlBbYZm65sSvPl3CWXyeKiBpQf0WVGI9xGXHBZ6RwwTC+WiVY4mxfABFRJ+zRvPF82TqZ4ox0nOXfQRSRnfW8EGkXkzAw8KnNDltWvnkeapj2+wYUVbV4nhdcKd2sb5M9pCwrmDbGe0D6yyeScEKa3addjwooVS+11eYrsIBp1VCG73psodPqykORbWzcrdHhCXPWRiBQvJ2RZKlMSmi2Ad4NexaR/9Ul4v7H4mmPi1Y5a63sMyi6OA22kOGyUNbC4UadGVwlYbSrwDgOwCy5bGxOnpD0j2lylaNk0S4HzuJxQFsH/4J9OL27y7F+G+Gv+wbv5v1hDKnrDbQqo9DdWq+IXWB5a7qW6CRPcYJCPYmi95BaAcopXIqcwwX74brrcEmuOaIMhLh9f/Sd/Xy/u/cX7Ekzu6A5gBcRAiCR1IWvMnHXPBsr2SdUCoEVE6NBONR4YOMZUDswGIm/hYq6QijTc0TvRXAKo7MXBdshoEiIqAa4gbQHJk6TYC/autsk0eQw1mRrFK5VRwgPwvzUqWKXmFKHYXocO1prs9YTfD+sm/Zqy14WmW9/krFOHj1q12MVvyR+D94FvNdIxaOkcr5HaoA8nhq9UwG7JUmVlMZoswrPzvHbxYQ1uuJH6+ShScq4fsKsCAwEAAQ=='},
44 ];
45
46 sub test_rsa {
47 my $h = shift;
48 my $rsa_pri = Crypt::PK::RSA->new->import_key(\decode_base64($h->{PRIDER}));
49 my $rsa_pub = Crypt::PK::RSA->new->import_key(\decode_base64($h->{PUBDER}));
50 my $rsa_pri_h = $rsa_pri->key2hash;
51 my $rsa_pub_h = $rsa_pub->key2hash;
52 is($rsa_pri_h->{d}, $h->{PRI}, "$h->{ID}/PRI");
53 is($rsa_pri_h->{N}, $h->{PUB}, "$h->{ID}/PUB");
54 is($rsa_pub_h->{N}, $h->{PUB}, "$h->{ID}/PUB");
55 is( $rsa_pri->decrypt(decode_base64($h->{ENC}), 'v1.5'), 'test-data', "$h->{ID}/ENC") || return 0;
56 ok( $rsa_pub->verify_message(decode_base64($h->{SIGSHA1}), 'test-data', 'SHA1', 'v1.5'), "$h->{ID}/SIGSHA1") || return 0;
57 ok( $rsa_pub->verify_message(decode_base64($h->{SIGSHA256}), 'test-data', 'SHA256', 'v1.5'), "$h->{ID}/SIGSHA256") || return 0;
58 return 1 if !$h->{SIGSHA512}; #SHA512 might be too big for short RSA keys
59 ok( $rsa_pub->verify_message(decode_base64($h->{SIGSHA512}), 'test-data', 'SHA512', 'v1.5'), "$h->{ID}/SIGSHA512") || return 0;
60 return 1;
61 }
62
63 #diag("samples_count=". @$data);
64 test_rsa($_) for @$data;
65 done_testing();