new Crypt::Stream::Rabbit
Karel Miko
6 years ago
0 | 0 | Changes for CryptX |
1 | ||
2 | 0.055_1 2017-12-14 | |
3 | - new Crypt::Stream::Rabbit | |
1 | 4 | |
2 | 5 | 0.055 2017-11-28 |
3 | 6 | - new Crypt::Cipher::IDEA |
72 | 72 | sosemanuk_state state; |
73 | 73 | int id; |
74 | 74 | } *Crypt__Stream__Sosemanuk; |
75 | ||
76 | typedef struct rabbit_struct { /* used by Crypt::Stream::Rabbit */ | |
77 | rabbit_state state; | |
78 | int id; | |
79 | } *Crypt__Stream__Rabbit; | |
75 | 80 | |
76 | 81 | typedef struct rc4_struct { /* used by Crypt::Stream::RC4 */ |
77 | 82 | rc4_state state; |
692 | 697 | INCLUDE: inc/CryptX_Stream_RC4.xs.inc |
693 | 698 | INCLUDE: inc/CryptX_Stream_Sober128.xs.inc |
694 | 699 | INCLUDE: inc/CryptX_Stream_Sosemanuk.xs.inc |
700 | INCLUDE: inc/CryptX_Stream_Rabbit.xs.inc | |
695 | 701 | |
696 | 702 | INCLUDE: inc/CryptX_Mac_F9.xs.inc |
697 | 703 | INCLUDE: inc/CryptX_Mac_HMAC.xs.inc |
0 | MODULE = CryptX PACKAGE = Crypt::Stream::Rabbit | |
1 | ||
2 | Crypt::Stream::Rabbit | |
3 | new(Class, SV * key, SV * nonce=&PL_sv_undef) | |
4 | CODE: | |
5 | { | |
6 | int rv; | |
7 | STRLEN iv_len=0, k_len=0; | |
8 | unsigned char *iv=NULL, *k=NULL; | |
9 | ||
10 | if (!SvPOK(key)) croak("FATAL: key must be string/buffer scalar"); | |
11 | k = (unsigned char *)SvPVbyte(key, k_len); | |
12 | ||
13 | Newz(0, RETVAL, 1, struct rabbit_struct); | |
14 | if (!RETVAL) croak("FATAL: Newz failed"); | |
15 | ||
16 | rv = rabbit_setup(&RETVAL->state, k, (unsigned long)k_len); | |
17 | if (rv != CRYPT_OK) { | |
18 | Safefree(RETVAL); | |
19 | croak("FATAL: rabbit_setup failed: %s", error_to_string(rv)); | |
20 | } | |
21 | ||
22 | if (SvOK(nonce)) { | |
23 | if (!SvPOK(nonce)) croak("FATAL: nonce must be string/buffer scalar"); | |
24 | iv = (unsigned char *)SvPVbyte(nonce, iv_len); | |
25 | rv = rabbit_setiv(&RETVAL->state, iv, (unsigned long)iv_len); | |
26 | } | |
27 | else { | |
28 | rv = rabbit_setiv(&RETVAL->state, NULL, 0); | |
29 | } | |
30 | if (rv != CRYPT_OK) { | |
31 | Safefree(RETVAL); | |
32 | croak("FATAL: rabbit_setiv failed: %s", error_to_string(rv)); | |
33 | } | |
34 | ||
35 | } | |
36 | OUTPUT: | |
37 | RETVAL | |
38 | ||
39 | void | |
40 | DESTROY(Crypt::Stream::Rabbit self) | |
41 | CODE: | |
42 | rabbit_done(&self->state); | |
43 | Safefree(self); | |
44 | ||
45 | Crypt::Stream::Rabbit | |
46 | clone(Crypt::Stream::Rabbit self) | |
47 | CODE: | |
48 | Newz(0, RETVAL, 1, struct rabbit_struct); | |
49 | if (!RETVAL) croak("FATAL: Newz failed"); | |
50 | Copy(&self->state, &RETVAL->state, 1, struct rabbit_struct); | |
51 | OUTPUT: | |
52 | RETVAL | |
53 | ||
54 | SV * | |
55 | keystream(Crypt::Stream::Rabbit self, STRLEN out_len) | |
56 | CODE: | |
57 | { | |
58 | int rv; | |
59 | unsigned char *out_data; | |
60 | ||
61 | RETVAL = NEWSV(0, out_len); | |
62 | SvPOK_only(RETVAL); | |
63 | SvCUR_set(RETVAL, out_len); | |
64 | out_data = (unsigned char *)SvPVX(RETVAL); | |
65 | rv = rabbit_keystream(&self->state, out_data, (unsigned long)out_len); | |
66 | if (rv != CRYPT_OK) { | |
67 | SvREFCNT_dec(RETVAL); | |
68 | croak("FATAL: rabbit_keystream failed: %s", error_to_string(rv)); | |
69 | } | |
70 | } | |
71 | OUTPUT: | |
72 | RETVAL | |
73 | ||
74 | SV * | |
75 | crypt(Crypt::Stream::Rabbit self, SV * data) | |
76 | CODE: | |
77 | { | |
78 | int rv; | |
79 | STRLEN in_data_len; | |
80 | unsigned char *in_data, *out_data; | |
81 | ||
82 | in_data = (unsigned char *)SvPVbyte(data, in_data_len); | |
83 | if (in_data_len == 0) { | |
84 | RETVAL = newSVpvn("", 0); | |
85 | } | |
86 | else { | |
87 | RETVAL = NEWSV(0, in_data_len); | |
88 | SvPOK_only(RETVAL); | |
89 | SvCUR_set(RETVAL, in_data_len); | |
90 | out_data = (unsigned char *)SvPVX(RETVAL); | |
91 | rv = rabbit_crypt(&self->state, in_data, (unsigned long)in_data_len, out_data); | |
92 | if (rv != CRYPT_OK) { | |
93 | SvREFCNT_dec(RETVAL); | |
94 | croak("FATAL: rabbit_crypt failed: %s", error_to_string(rv)); | |
95 | } | |
96 | } | |
97 | } | |
98 | OUTPUT: | |
99 | RETVAL |
0 | package Crypt::Stream::Rabbit; | |
1 | ||
2 | use strict; | |
3 | use warnings; | |
4 | our $VERSION = '0.055_001'; | |
5 | ||
6 | use CryptX; | |
7 | ||
8 | 1; | |
9 | ||
10 | =pod | |
11 | ||
12 | =head1 NAME | |
13 | ||
14 | Crypt::Stream::Rabbit - Stream cipher Rabbit | |
15 | ||
16 | =head1 SYNOPSIS | |
17 | ||
18 | use Crypt::Stream::Rabbit; | |
19 | ||
20 | # encrypt | |
21 | $key = "1234567890123456"; | |
22 | $iv = "123456789012"; | |
23 | $stream = Crypt::Stream::Rabbit->new($key, $iv); | |
24 | $ct = $stream->crypt("plain message"); | |
25 | ||
26 | # decrypt | |
27 | $key = "1234567890123456"; | |
28 | $iv = "123456789012"; | |
29 | $stream = Crypt::Stream::Rabbit->new($key, $iv); | |
30 | $pt = $stream->crypt($ct); | |
31 | ||
32 | =head1 DESCRIPTION | |
33 | ||
34 | Provides an interface to the Rabbit stream cipher. | |
35 | ||
36 | =head1 METHODS | |
37 | ||
38 | =head2 new | |
39 | ||
40 | $stream = Crypt::Stream::Rabbit->new($key, $iv); | |
41 | # $key .. keylen must be multiple of 4 bytes | |
42 | # $iv .. ivlen must be multiple of 4 bytes (OPTIONAL) | |
43 | ||
44 | =head2 crypt | |
45 | ||
46 | $ciphertext = $stream->crypt($plaintext); | |
47 | #or | |
48 | $plaintext = $stream->crypt($ciphertext); | |
49 | ||
50 | =head2 keystream | |
51 | ||
52 | $random_key = $stream->keystream($length); | |
53 | ||
54 | =head2 clone | |
55 | ||
56 | $stream->clone(); | |
57 | ||
58 | =head1 SEE ALSO | |
59 | ||
60 | =over | |
61 | ||
62 | =item * L<Crypt::Stream::RC4>, L<Crypt::Stream::ChaCha>, L<Crypt::Stream::Salsa20>, L<Crypt::Stream::Sober128> | |
63 | ||
64 | =item * L<https://en.wikipedia.org/wiki/Rabbit_(cipher)> | |
65 | ||
66 | =back | |
67 | ||
68 | =cut |
61 | 61 | |
62 | 62 | =item * L<Crypt::Stream::RC4>, L<Crypt::Stream::ChaCha>, L<Crypt::Stream::Salsa20>, L<Crypt::Stream::Sober128> |
63 | 63 | |
64 | =item * L<https://en.wikipedia.org/wiki/SOBER-128|https://en.wikipedia.org/wiki/SOBER-128> | |
64 | =item * L<https://en.wikipedia.org/wiki/SOSEMANUK> | |
65 | 65 | |
66 | 66 | =back |
67 | 67 |
84 | 84 | |
85 | 85 | =item * Stream ciphers |
86 | 86 | |
87 | L<Crypt::Stream::RC4>, L<Crypt::Stream::ChaCha>, L<Crypt::Stream::Salsa20>, L<Crypt::Stream::Sober128>, L<Crypt::Stream::Sosemanuk> | |
87 | L<Crypt::Stream::RC4>, L<Crypt::Stream::ChaCha>, L<Crypt::Stream::Salsa20>, L<Crypt::Stream::Sober128>, | |
88 | L<Crypt::Stream::Sosemanuk>, L<Crypt::Stream::Rabbit> | |
88 | 89 | |
89 | 90 | =item * Authenticated encryption modes |
90 | 91 |
108 | 108 | use Crypt::Stream::Salsa20; |
109 | 109 | use Crypt::Stream::Sober128; |
110 | 110 | use Crypt::Stream::Sosemanuk; |
111 | use Crypt::Stream::Rabbit; | |
111 | 112 | use CryptX; |
112 | 113 | use Math::BigInt::LTM; |
113 | 114 |
5 | 5 | plan skip_all => "set TEST_POD to enable this test (developer only!)" unless $ENV{TEST_POD}; |
6 | 6 | plan skip_all => "File::Find not installed" unless eval { require File::Find }; |
7 | 7 | plan skip_all => "Test::Pod not installed" unless eval { require Test::Pod }; |
8 | plan tests => 102; | |
8 | plan tests => 103; | |
9 | 9 | |
10 | 10 | my @files; |
11 | 11 | File::Find::find({ wanted=>sub { push @files, $_ if /\.pm$/ }, no_chdir=>1 }, 'lib'); |
9 | 9 | Test::Pod::Spelling->import( |
10 | 10 | spelling => { |
11 | 11 | allow_words => [qw( |
12 | AES BLAKEb BLAKEs CPAN CRC ChaCha CryptX DCIT DER Diffie EAX ECCDH ECDH ECDSA Flickr HKDF JSON JWA JWK | |
12 | ASN AES BLAKEb BLAKEs CPAN CRC ChaCha CryptX DCIT DER Diffie EAX ECCDH ECDH ECDSA Flickr HKDF JSON JWA JWK | |
13 | 13 | Karel Miko OCB OCBv OID OMAC OO OpenSSL PBKDF PEM PKCS RIPEMD Rijndael SHA UUID RFC |
14 | 14 | decrypt decrypts interoperability cryptographically cryptographic octects |
15 | 15 | libtomcrypt libtommath |
20 | 20 | }, |
21 | 21 | ); |
22 | 22 | |
23 | plan tests => 102; | |
23 | plan tests => 103; | |
24 | 24 | |
25 | 25 | my @files; |
26 | 26 | File::Find::find({ wanted=>sub { push @files, $_ if /\.pm$/ }, no_chdir=>1 }, 'lib'); |
5 | 5 | plan skip_all => "set TEST_POD to enable this test (developer only!)" unless $ENV{TEST_POD}; |
6 | 6 | plan skip_all => "Pod::Coverage not installed" unless eval { require Pod::Coverage }; |
7 | 7 | plan skip_all => "File::Find not installed" unless eval { require File::Find }; |
8 | plan tests => 102; | |
8 | plan tests => 103; | |
9 | 9 | |
10 | 10 | my @files; |
11 | 11 | File::Find::find({ wanted=>sub { push @files, $_ if /\.pm$/ }, no_chdir=>1 }, 'lib'); |
0 | 0 | use strict; |
1 | 1 | use warnings; |
2 | 2 | |
3 | use Test::More tests => 14; | |
3 | use Test::More tests => 16; | |
4 | 4 | |
5 | 5 | use Crypt::Stream::RC4; |
6 | 6 | use Crypt::Stream::Sober128; |
7 | 7 | use Crypt::Stream::ChaCha; |
8 | 8 | use Crypt::Stream::Salsa20; |
9 | use Crypt::Stream::Sosemanuk; | |
10 | use Crypt::Stream::Rabbit; | |
9 | 11 | |
10 | 12 | { |
11 | 13 | my $key = pack("H*", "0123456789abcdef"); |
83 | 85 | is(unpack("H*", $dec), unpack("H*", $pt), "Crypt::Stream::Sosemanuk decrypt (no IV)"); |
84 | 86 | } |
85 | 87 | |
88 | { | |
89 | my $key = pack("H*", "74657374206b65792031323862697473"); | |
90 | my $iv = pack("H*", "00000000"); | |
91 | my $ct = pack("H*", "442cf424c5da8d78000c6b874050260792ae8ce0"); | |
92 | my $pt = pack("H*", "0000000000000000000000000000000000000000"); | |
93 | my $enc = Crypt::Stream::Rabbit->new($key, $iv)->crypt($pt); | |
94 | my $dec = Crypt::Stream::Rabbit->new($key, $iv)->crypt($ct); | |
95 | is(unpack("H*", $enc), unpack("H*", $ct), "Crypt::Stream::Rabbit encrypt"); | |
96 | is(unpack("H*", $dec), unpack("H*", $pt), "Crypt::Stream::Rabbit decrypt"); | |
97 | } |