Codebase list libcryptx-perl / a136569
release 0.013_1 Karel Miko 10 years ago
8 changed file(s) with 243 addition(s) and 17 deletion(s). Raw diff Collapse all Expand all
00 Changes for CryptX
11
22 TODO:
3 before 0.014:
4 - Crypt::PK::DH/ECC - sign/verify replaced by sign_message/verify_message + sign_hash/verify_hash
5 - Crypt::PK::DH/ECC - new method key2hash
6 later:
37 - consider: RSA->check_key, RSA password protected keys
48 - consider: PK->encrypt|decrypt ... add 'armour' param and make it compatible with Crypt::RSA
59 - croak with the "real caller" (Crypt::Mac::*, Crypt::Mode::*, ...)
1115 RSA: my $k = Crypt::PK::RSA->new; $k->generate_key(256, 65537);
1216 - "libtom-src/bn_mp_invmod.c", line 37: warning: statement not reached
1317
14 0.014 2013/09/11
18 0.013_1 2013/09/11
1519 - Crypt::Digest::NNN + Crypt::Mac::NNN - can produce Base64-URL-Safe encoded digest/mac
1620 - Crypt::PRNG + Crypt::PRNG::NNN - Base64-URL-Safe encoded random bytes (random_bytes_b64u/bytes_b64u)
1721 - Crypt::PK::RSA/DSA - sign/verify replaced by sign_message/verify_message + sign_hash/verify_hash
22 - Crypt::PK::RSA/DSA - new method key2hash
1823 - documentation fixes
1924
2025 0.013 2013/08/28
7171 return $self->_decrypt($data);
7272 }
7373
74 sub _truncate {
75 my ($self, $hash) = @_;
76 ### section 4.6 of FIPS 186-4
77 # let N be the bit length of q
78 # z = the leftmost min(N, outlen) bits of Hash(M).
79 my $q = $self->size_q; # = size in bytes
80 return $hash if $q >= length($hash);
81 return substr($hash, 0, $q);
82 }
83
7484 sub sign_message {
7585 my ($self, $data, $hash_name) = @_;
7686 $hash_name ||= 'SHA1';
7787 my $data_hash = digest_data($hash_name, $data);
78 #XXX truncation
79 return $self->_sign($data_hash);
88 return $self->_sign($self->_truncate($data_hash));
8089 }
8190
8291 sub sign_hash {
8392 my ($self, $data_hash) = @_;
84 #XXX truncation
85 return $self->_sign($data_hash);
93 return $self->_sign($self->_truncate($data_hash));
8694 }
8795
8896 sub verify_message {
8997 my ($self, $sig, $data, $hash_name) = @_;
9098 $hash_name ||= 'SHA1';
9199 my $data_hash = digest_data($hash_name, $data);
92 #XXX truncation
93 return $self->_verify($sig, $data_hash);
100 return $self->_verify($sig, $self->_truncate($data_hash));
94101 }
95102
96103 sub verify_hash {
97104 my ($self, $sig, $data_hash) = @_;
98 #XXX truncation
99 return $self->_verify($sig, $data_hash);
105 return $self->_verify($sig, $self->_truncate($data_hash));
100106 }
101107
102108 ### FUNCTIONS
359365
360366 my $size = $pk->is_private;
361367 # returns key size in bytes or undef if no key loaded
368
369 =head2 key2hash
370
371 my $hash = $pk->key2hash;
372
373 returns hash like this (or undef if no key loaded):
374 {
375 type => 1, # integer: 1 .. private, 0 .. public
376 qord => 30, # integer: order of the sub-group
377 # all the rest are hex strings
378 g => "847E8896D12C9BF18FE283AE7AD58ED7F3...", #generator
379 p => "AAF839A764E04D80824B79FA1F0496C093...", #prime used to generate the sub-group
380 q => "D05C4CB45F29D353442F1FEC43A6BE2BE8...", #large prime that generats the field the contains the sub-group
381 x => "6C801901AC74E2DC714D75A9F6969483CF...", #private key
382 y => "8F7604D77FA62C7539562458A63C7611B7...", #public key
383 }
431431
432432 my $size = $pk->is_private;
433433 # returns key size in bytes or undef if no key loaded
434
435 =head2 key2hash
436
437 my $hash = $pk->key2hash;
438
439 returns hash like this (or undef if no key loaded):
440 {
441 type => 1, # integer: 1 .. private, 0 .. public
442 # all the rest are hex strings
443 e => "10001", #public exponent
444 d => "9ED5C3D3F866E06957CA0E9478A273C39BBDA4EEAC5B...", #private exponent
445 N => "D0A5CCCAE03DF9C2F5C4C8C0CE840D62CDE279990DC6...", #modulus
446 p => "D3EF0028FFAB508E2773C659E428A80FB0E9211346B4...", #p factor of N
447 q => "FC07E46B163CAB6A83B8E467D169534B2077DCDEECAE...", #q factor of N
448 qP => "88C6D406F833DF73C8B734548E0385261AD51F4187CF...", #1/q mod p CRT param
449 dP => "486F142FEF0A1F53269AC43D2EE4D263E2841B60DA36...", #d mod (p - 1) CRT param
450 dQ => "4597284B2968B72C4212DB7E8F24360B987B80514DA9...", #d mod (q - 1) CRT param
451 }
22 use strict;
33 use warnings ;
44
5 our $VERSION = '0.014';
6 $VERSION = eval $VERSION;
5 our $VERSION = '0.013_1';
76
87 require XSLoader;
98 XSLoader::load('CryptX', $VERSION);
33
44 #undef LTC_SOURCE
55 #include "tomcrypt.h"
6 #include "tommath.h"
67
78 typedef struct cipher_struct { /* used by Crypt::Cipher */
89 symmetric_key skey;
6060 OUTPUT:
6161 RETVAL
6262
63 int
64 size_q(Crypt::PK::DSA self)
65 CODE:
66 if (self->key.type == -1 || self->key.qord <= 0) XSRETURN_UNDEF;
67 RETVAL = ltc_mp.unsigned_size(self->key.q);
68 OUTPUT:
69 RETVAL
70
71 SV*
72 key2hash(Crypt::PK::DSA self)
73 INIT:
74 HV *rv_hash;
75 unsigned char buf[20001];
76 CODE:
77 if (self->key.type == -1 || self->key.qord <= 0) XSRETURN_UNDEF;
78 rv_hash = newHV();
79 /* =====> g */
80 if (ltc_mp.unsigned_size(self->key.g)>10000) {
81 croak("FATAL: key2hash failed - 'g' too big number");
82 }
83 if (ltc_mp.unsigned_size(self->key.g)>0) {
84 mp_tohex(self->key.g, buf);
85 hv_store(rv_hash, "g", 1, newSVpv(buf, strlen(buf)), 0);
86 }
87 else{
88 hv_store(rv_hash, "g", 1, newSVpv("", 0), 0);
89 }
90 /* =====> q */
91 if (ltc_mp.unsigned_size(self->key.q)>10000) {
92 croak("FATAL: key2hash failed - 'q' too big number");
93 }
94 if (ltc_mp.unsigned_size(self->key.q)>0) {
95 mp_tohex(self->key.q, buf);
96 hv_store(rv_hash, "q", 1, newSVpv(buf, strlen(buf)), 0);
97 }
98 else{
99 hv_store(rv_hash, "q", 1, newSVpv("", 0), 0);
100 }
101 /* =====> p */
102 if (ltc_mp.unsigned_size(self->key.p)>10000) {
103 croak("FATAL: key2hash failed - 'p' too big number");
104 }
105 if (ltc_mp.unsigned_size(self->key.p)>0) {
106 mp_tohex(self->key.p, buf);
107 hv_store(rv_hash, "p", 1, newSVpv(buf, strlen(buf)), 0);
108 }
109 else{
110 hv_store(rv_hash, "p", 1, newSVpv("", 0), 0);
111 }
112 /* =====> x */
113 if (ltc_mp.unsigned_size(self->key.x)>10000) {
114 croak("FATAL: key2hash failed - 'x' too big number");
115 }
116 if (ltc_mp.unsigned_size(self->key.x)>0) {
117 mp_tohex(self->key.x, buf);
118 hv_store(rv_hash, "x", 1, newSVpv(buf, strlen(buf)), 0);
119 }
120 else{
121 hv_store(rv_hash, "x", 1, newSVpv("", 0), 0);
122 }
123 /* =====> y */
124 if (ltc_mp.unsigned_size(self->key.y)>10000) {
125 croak("FATAL: key2hash failed - 'y' too big number");
126 }
127 if (ltc_mp.unsigned_size(self->key.y)>0) {
128 mp_tohex(self->key.y, buf);
129 hv_store(rv_hash, "y", 1, newSVpv(buf, strlen(buf)), 0);
130 }
131 else{
132 hv_store(rv_hash, "y", 1, newSVpv("", 0), 0);
133 }
134 /* =====> qord */
135 hv_store(rv_hash, "qord", 4, newSViv(self->key.qord), 0);
136 /* =====> type */
137 hv_store(rv_hash, "type", 4, newSViv(self->key.type), 0);
138 RETVAL = newRV_noinc((SV*)rv_hash);
139 OUTPUT:
140 RETVAL
141
63142 SV *
64143 export_key_der(Crypt::PK::DSA self, char * type)
65144 CODE:
5858 CODE:
5959 if (self->key.type == -1 || self->key.N == NULL) XSRETURN_UNDEF;
6060 RETVAL = ltc_mp.unsigned_size(self->key.N);
61 OUTPUT:
62 RETVAL
63
64 SV*
65 key2hash(Crypt::PK::RSA self)
66 INIT:
67 HV *rv_hash;
68 unsigned char buf[20001];
69 CODE:
70 if (self->key.type == -1 || self->key.N == NULL) XSRETURN_UNDEF;
71 rv_hash = newHV();
72 /* =====> e */
73 if (ltc_mp.unsigned_size(self->key.e)>10000) {
74 croak("FATAL: key2hash failed - 'e' too big number");
75 }
76 if (ltc_mp.unsigned_size(self->key.e)>0) {
77 mp_tohex(self->key.e, buf);
78 hv_store(rv_hash, "e", 1, newSVpv(buf, strlen(buf)), 0);
79 }
80 else{
81 hv_store(rv_hash, "e", 1, newSVpv("", 0), 0);
82 }
83 /* =====> d */
84 if (ltc_mp.unsigned_size(self->key.d)>10000) {
85 croak("FATAL: key2hash failed - 'd' too big number");
86 }
87 if (ltc_mp.unsigned_size(self->key.d)>0) {
88 mp_tohex(self->key.d, buf);
89 hv_store(rv_hash, "d", 1, newSVpv(buf, strlen(buf)), 0);
90 }
91 else{
92 hv_store(rv_hash, "d", 1, newSVpv("", 0), 0);
93 }
94 /* =====> N */
95 if (ltc_mp.unsigned_size(self->key.N)>10000) {
96 croak("FATAL: key2hash failed - 'N' too big number");
97 }
98 if (ltc_mp.unsigned_size(self->key.N)>0) {
99 mp_tohex(self->key.N, buf);
100 hv_store(rv_hash, "N", 1, newSVpv(buf, strlen(buf)), 0);
101 }
102 else{
103 hv_store(rv_hash, "N", 1, newSVpv("", 0), 0);
104 }
105 /* =====> q */
106 if (ltc_mp.unsigned_size(self->key.q)>10000) {
107 croak("FATAL: key2hash failed - 'q' too big number");
108 }
109 if (ltc_mp.unsigned_size(self->key.q)>0) {
110 mp_tohex(self->key.q, buf);
111 hv_store(rv_hash, "q", 1, newSVpv(buf, strlen(buf)), 0);
112 }
113 else{
114 hv_store(rv_hash, "q", 1, newSVpv("", 0), 0);
115 }
116 /* =====> p */
117 if (ltc_mp.unsigned_size(self->key.p)>10000) {
118 croak("FATAL: key2hash failed - 'p' too big number");
119 }
120 if (ltc_mp.unsigned_size(self->key.p)>0) {
121 mp_tohex(self->key.p, buf);
122 hv_store(rv_hash, "p", 1, newSVpv(buf, strlen(buf)), 0);
123 }
124 else{
125 hv_store(rv_hash, "p", 1, newSVpv("", 0), 0);
126 }
127 /* =====> qP */
128 if (ltc_mp.unsigned_size(self->key.qP)>10000) {
129 croak("FATAL: key2hash failed - 'qP' too big number");
130 }
131 if (ltc_mp.unsigned_size(self->key.qP)>0) {
132 mp_tohex(self->key.qP, buf);
133 hv_store(rv_hash, "qP", 2, newSVpv(buf, strlen(buf)), 0);
134 }
135 else{
136 hv_store(rv_hash, "qP", 2, newSVpv("", 0), 0);
137 }
138 /* =====> dP */
139 if (ltc_mp.unsigned_size(self->key.dP)>10000) {
140 croak("FATAL: key2hash failed - 'dP' too big number");
141 }
142 if (ltc_mp.unsigned_size(self->key.dP)>0) {
143 mp_tohex(self->key.dP, buf);
144 hv_store(rv_hash, "dP", 2, newSVpv(buf, strlen(buf)), 0);
145 }
146 else{
147 hv_store(rv_hash, "dP", 2, newSVpv("", 0), 0);
148 }
149 /* =====> dQ */
150 if (ltc_mp.unsigned_size(self->key.dQ)>10000) {
151 croak("FATAL: key2hash failed - 'dQ' too big number");
152 }
153 if (ltc_mp.unsigned_size(self->key.dQ)>0) {
154 mp_tohex(self->key.dQ, buf);
155 hv_store(rv_hash, "dQ", 2, newSVpv(buf, strlen(buf)), 0);
156 }
157 else{
158 hv_store(rv_hash, "dQ", 2, newSVpv("", 0), 0);
159 }
160 /* =====> type */
161 hv_store(rv_hash, "type", 4, newSViv(self->key.type), 0);
162 RETVAL = newRV_noinc((SV*)rv_hash);
61163 OUTPUT:
62164 RETVAL
63165
11 use warnings;
22 use Test::More;
33
4 use Crypt::PK::DSA qw(dsa_encrypt dsa_decrypt dsa_sign dsa_verify);
4 use Crypt::PK::DSA qw(dsa_encrypt dsa_decrypt dsa_sign_message dsa_verify_message);
55
66 {
77 my $k;
6767 ok(length $ct > 200, 'encrypt ' . length($ct));
6868 is($pt, "secret message", 'decrypt');
6969
70 my $sig = $pr1->sign("message");
70 my $sig = $pr1->sign_message("message");
7171 ok(length $sig > 60, 'sign ' . length($sig));
72 ok($pu1->verify($sig, "message"), 'verify');
72 ok($pu1->verify_message($sig, "message"), 'verify');
7373
7474 my $pr2 = Crypt::PK::DSA->new;
7575 $pr2->import_key('t/data/cryptx_priv_dsa2.der');
9797 ok($ct, 'dsa_encrypt');
9898 my $pt = dsa_decrypt('t/data/cryptx_priv_dsa1.der', $ct);
9999 ok($pt, 'dsa_decrypt');
100 my $sig = dsa_sign('t/data/cryptx_priv_dsa1.der', 'test string');
101 ok($sig, 'dsa_sign');
102 ok(dsa_verify('t/data/cryptx_pub_dsa1.der', $sig, 'test string'), 'dsa_verify');
100 my $sig = dsa_sign_message('t/data/cryptx_priv_dsa1.der', 'test string');
101 ok($sig, 'dsa_sign_message');
102 ok(dsa_verify_message('t/data/cryptx_pub_dsa1.der', $sig, 'test string'), 'dsa_verify_message');
103103 }
104104
105105 done_testing;