Crypt-Twofish-2.17/0000755000175000017500000000000012147036751012315 5ustar amsamsCrypt-Twofish-2.17/tab/0000755000175000017500000000000012147036751013063 5ustar amsamsCrypt-Twofish-2.17/tab/misc.pl0000644000175000017500000000202507260125440014344 0ustar amsams#!/usr/bin/perl -w # $Id: misc.pl,v 1.2 2001/02/12 23:32:27 ams Exp $ # Copyright 2001 Abhijit Menon-Sen use strict; sub align { my @aligned = (); my $columns = @{$_[0]}; my @lengths = (0)x$columns; foreach (@_) { for my $i (0..$columns-1) { my $len = length $_->[$i]; $lengths[$i] = $len if $len > $lengths[$i]; } } foreach (@_) { my $text = ""; for my $i (0..$columns-1) { $text .= $_->[$i]." "x($lengths[$i]-length($_->[$i])); } push @aligned, $text; } return @aligned; } sub cwrap { my $n = shift; my ($i, $text, @text) = (0, ""); foreach (@_) { if (length($text) + length($_) + 2 < $n) { $text .= ", $_"; push @{$text[$i]}, $_; } else { $i++; $text = $_; push @{$text[$i]}, $_; } } return map { join(", ", @$_) } @text; } sub indent { my $n = shift; return map { " "x$n.$_ } @_; } 1; Crypt-Twofish-2.17/tab/tables.pl0000644000175000017500000000531607302251172014670 0ustar amsams#!/usr/bin/perl -w # $Id: tables.pl,v 2.12 2001/05/21 17:38:02 ams Exp $ # Copyright 2001 Abhijit Menon-Sen use strict; require 'tab/misc.pl'; my ($qtab, $mtab) = ([], []); my @ror4 = (0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15); my @ashx = (0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 5, 14, 7); # Finite field arithmetic for GF(2^8) with the modular polynomial: # x^8 + x^6 + x^5 + x^3 + 1 my $G = 0x0169; my @t5b = (0, $G >> 2 & 0xff, $G >> 1 & 0xff, ($G>>1)^($G>>2)&0xff); my @tef = (0, $t5b[3], $t5b[2], $t5b[1]); my $qt0 = [ [ 8, 1, 7, 13, 6, 15, 3, 2, 0, 11, 5, 9, 14, 12, 10, 4 ], [ 2, 8, 11, 13, 15, 7, 6, 14, 3, 1, 9, 4, 0, 10, 12, 5 ], ]; my $qt1 = [ [ 14, 12, 11, 8, 1, 2, 3, 5, 15, 4, 10, 6, 7, 0, 9, 13 ], [ 1, 14, 2, 11, 4, 12, 3, 7, 6, 13, 10, 5, 15, 9, 0, 8 ], ]; my $qt2 = [ [ 11, 10, 5, 14, 6, 13, 9, 0, 12, 8, 15, 3, 2, 4, 7, 1 ], [ 4, 12, 7, 5, 1, 6, 9, 10, 0, 14, 13, 8, 2, 11, 3, 15 ], ]; my $qt3 = [ [ 13, 7, 15, 4, 1, 2, 6, 14, 9, 11, 3, 0, 8, 5, 12, 10 ], [ 11, 9, 5, 1, 12, 3, 13, 14, 6, 4, 7, 15, 2, 0, 8, 10 ], ]; for my $i (0..15) { for my $j (0..15) { my $n = 16*$i+$j; my ($a, $b, $c, $p, $q, $r); $a = $i ^ $j; $p = $ashx[$i] ^ $ror4[$j]; $b = $qt0->[0][$a]; $q = $qt1->[0][$p]; $c = $qt0->[1][$a]; $r = $qt1->[1][$p]; $qtab->[0][$n] = $qt3->[0][$ashx[$b]^$ror4[$q]] << 4 | $qt2->[0][$b ^ $q]; $qtab->[1][$n] = $qt3->[1][$ashx[$c]^$ror4[$r]] << 4 | $qt2->[1][$c ^ $r]; } } for my $i (0..255) { my ($a, $b, $c); $a = $qtab->[1][$i]; $b = $a ^ $a>>2 ^ $t5b[$a & 3]; $c = $a ^ $a>>1 ^ $a>>2 ^ $tef[$a & 3]; $mtab->[0][$i] = ($a + ($b << 8) + ($c << 16) + ($c << 24))."UL"; $mtab->[2][$i] = ($b + ($c << 8) + ($a << 16) + ($c << 24))."UL"; $a = $qtab->[0][$i]; $b = $a ^ $a>>2 ^ $t5b[$a & 3]; $c = $a ^ $a>>1 ^ $a>>2 ^ $tef[$a & 3]; $mtab->[1][$i] = ($c + ($c << 8) + ($b << 16) + ($a << 24))."UL"; $mtab->[3][$i] = ($b + ($a << 8) + ($c << 16) + ($b << 24))."UL"; } my @q = map { join ",\n", indent(1, cwrap(76, @$_)) } @$qtab; my @m = map { join ",\n", indent(1, cwrap(76, @$_)) } @$mtab; (my $text = <<"TABLES") =~ s/^\| {0,3}//gm; | /* | * This file is automatically generated -- changes to it will be lost | * the next time "make tables.h" is run. | */ | | #ifndef _TWOFISH_TABLES_H_ | #define _TWOFISH_TABLES_H_ | | unsigned char q[2][256] = { | { | $q[0] | }, | { | $q[1] | } | }; | | uint32_t m[4][256] = { | { | $m[0] | }, | { | $m[1] | }, | { | $m[2] | }, | { | $m[3] | } | }; | | #endif TABLES open F, ">tables.h" or die "tables.h: $!\n"; print F $text; close F; Crypt-Twofish-2.17/Changes0000644000175000017500000000230712131270724013603 0ustar amsams2.16 2013-04-10 Abhijit Menon-Sen * Another attempt to silence cpantesters. No functional changes. 2.15 2012-09-07 Abhijit Menon-Sen * Include 'strict' in PREREQ_PM to silence cpantesters. No functional changes. 2.14 2010-05-08 Abhijit Menon-Sen * Fix inaccurate dependency in Makefile.PL 2.13 2009-05-11 Abhijit Menon-Sen * Relicensed on request from the old Artistic License to "the same terms as Perl itself" (i.e. new Artistic/GPL). (No functional changes.) 2.12 2001-05-21 * More Makefile.PL feature-probing updates. 2.10 2001-05-07 * Makefile.PL now tries to do the right thing on systems which don't have . * This release should work under Activeperl (thanks to Tony Cook). 2.02 2001-05-04 * The module is now distributed under the Artistic License. 2.00 2001-05-01 (By Abhijit Menon-Sen ) * Complete rewrite. The module is now Crypt::CBC compatible, has new test cases, and a cleaner Twofish implementation. 1.00 1999-11-08 (By Nishant Kakani) * original version; created by h2xs 1.16 Crypt-Twofish-2.17/Twofish.pm0000644000175000017500000000654012147036631014300 0ustar amsams# $Id: Twofish.pm,v 2.12 2001/05/21 17:38:01 ams Exp $ # Copyright 2001 Abhijit Menon-Sen package Crypt::Twofish; use strict; use Carp; use DynaLoader; use vars qw( @ISA $VERSION ); @ISA = qw( DynaLoader ); $VERSION = '2.17'; bootstrap Crypt::Twofish $VERSION; sub keysize () { 16 } sub blocksize () { 16 } sub new { my ($class, $key) = @_; croak "Usage: ".__PACKAGE__."->new(\$key)" unless $key; return Crypt::Twofish::setup($key); } sub encrypt { my ($self, $data) = @_; croak "Usage: \$cipher->encrypt(\$data)" unless ref($self) && $data; $self->crypt($data, $data, 0); } sub decrypt { my ($self, $data) = @_; croak "Usage: \$cipher->decrypt(\$data)" unless ref($self) && $data; $self->crypt($data, $data, 1); } # The functions below provide an interface that is call-compatible with # the Crypt::Twofish 1.0 module. They do not, however, behave in exactly # the same way: they don't pad keys, and cannot decrypt ciphertext which # was written by the old module. # # (This interface is deprecated. Please use the documented interface # instead). sub Encipher { my ($key, $keylength, $plaintext) = @_; require Crypt::CBC; my $cipher = Crypt::CBC->new($key, "Twofish"); return $cipher->encrypt($plaintext); } sub Decipher { my ($key, $keylength, $ciphertext, $cipherlength) = @_; require Crypt::CBC; my $cipher = Crypt::CBC->new($key, "Twofish"); return $cipher->decrypt($ciphertext); } sub LastError { ""; } sub CheckTwofish { undef; } 1; __END__ =head1 NAME Crypt::Twofish - The Twofish Encryption Algorithm =head1 SYNOPSIS use Crypt::Twofish; $cipher = Crypt::Twofish->new($key); $ciphertext = $cipher->encrypt($plaintext); $plaintext = $cipher->decrypt($ciphertext); =head1 DESCRIPTION Twofish is a 128-bit symmetric block cipher with a variable length (128, 192, or 256-bit) key, developed by Counterpane Labs. It is unpatented and free for all uses, as described at . This module implements Twofish encryption. It supports the Crypt::CBC interface, with the functions described below. It also provides an interface that is call-compatible with Crypt::Twofish 1.0, but its use in new code is strongly discouraged. =head2 Functions =over =item blocksize Returns the size (in bytes) of the block (16, in this case). =item keysize Returns the size (in bytes) of the key. Although the module understands 128, 192, and 256-bit keys, it returns 16 for compatibility with Crypt::CBC. =item new($key) This creates a new Crypt::Twofish object with the specified key (which should be 16, 24, or 32 bytes long). =item encrypt($data) Encrypts blocksize() bytes of $data and returns the corresponding ciphertext. =item decrypt($data) Decrypts blocksize() bytes of $data and returns the corresponding plaintext. =back =head1 SEE ALSO Crypt::CBC, Crypt::Blowfish, Crypt::TEA =head1 ACKNOWLEDGEMENTS =over 4 =item Nishant Kakani For writing Crypt::Twofish 1.0 (this version is a complete rewrite). =item Tony Cook For making the module work under Activeperl, testing on several platforms, and suggesting that I probe for features via %Config. =back =head1 AUTHOR Abhijit Menon-Sen Copyright 2001 Abhijit Menon-Sen. This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. Crypt-Twofish-2.17/MANIFEST0000644000175000017500000000045212147036751013447 0ustar amsamsChanges MANIFEST Makefile.PL README Twofish.pm Twofish.xs _twofish.c ppport.h tab/misc.pl tab/tables.pl test.pl twofish.h typemap META.yml Module YAML meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) Crypt-Twofish-2.17/README0000644000175000017500000000363611201726144013175 0ustar amsamsNAME Crypt::Twofish - The Twofish Encryption Algorithm SYNOPSIS use Crypt::Twofish; $cipher = Crypt::Twofish->new($key); $ciphertext = $cipher->encrypt($plaintext); $plaintext = $cipher->decrypt($ciphertext); DESCRIPTION Twofish is a 128-bit symmetric block cipher with a variable length (128, 192, or 256-bit) key, developed by Counterpane Labs. It is unpatented and free for all uses, as described at . This module implements Twofish encryption. It supports the Crypt::CBC interface, with the functions described below. It also provides an interface that is call- compatible with Crypt::Twofish 1.0, but its use in new code is strongly discouraged. Functions blocksize Returns the size (in bytes) of the block (16, in this case). keysize Returns the size (in bytes) of the key. Although the module understands 128, 192, and 256-bit keys, it returns 16 for compatibility with Crypt::CBC. new($key) This creates a new Crypt::Twofish object with the specified key (which should be 16, 24, or 32 bytes long). encrypt($data) Encrypts blocksize() bytes of $data and returns the corresponding ciphertext. decrypt($data) Decrypts blocksize() bytes of $data and returns the corresponding plaintext. SEE ALSO Crypt::CBC, Crypt::Blowfish, Crypt::TEA ACKNOWLEDGEMENTS Nishant Kakani For writing Crypt::Twofish 1.0 (this version is a complete rewrite). Tony Cook For making the module work under Activeperl, testing on several platforms, and suggesting that I probe for features via %Config. AUTHOR Abhijit Menon-Sen Copyright 2001 Abhijit Menon-Sen. This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. Crypt-Twofish-2.17/test.pl0000644000175000017500000000564507264310447013644 0ustar amsamsuse strict; use Test; use vars qw($loaded); use Benchmark qw(timediff timestr); BEGIN { plan tests => 10 } END { print "not ok 1\n" unless $loaded } my $key = pack "H*", '1234567890ABCDEFFEDCBA0987654321'; my $plaintext = "The quick brown fox jumps over the lazy dog."; use Crypt::Twofish; ok($loaded = 1); ok(my $two = Crypt::Twofish->new("abcdefghijklmnop")); ok("aaaabbbbccccdddd", $two->decrypt($two->encrypt("aaaabbbbccccdddd"))); foreach my $length (16, 24, 32) { my (@texts, @keys); my $key = pack "H*", "00"x$length; my $text = pack "H*", "00"x16; for my $i (1..49) { $two = Crypt::Twofish->new($key); $text = $two->encrypt($text); push @keys, $key; push @texts, $text; my $a = $texts[-2] || pack "H*", "00"x$length; my $b = $texts[-3] || pack "H*", "00"x$length; $key = substr($a.$b, 0, $length); } if ($length == 16) { ok(unpack("H*", $text), "5d9d4eeffa9151575524f115815a12e0"); } elsif ($length == 24) { ok(unpack("H*", $text), "e75449212beef9f4a390bd860a640941"); } elsif ($length == 32) { ok(unpack("H*", $text), "37fe26ff1cf66175f5ddf4c33b97a205"); } for (1..49) { $two = Crypt::Twofish->new(pop(@keys)); $text = $two->decrypt($text); } ok(unpack("H*", $text), "00"x16); } eval 'use Crypt::CBC'; if ($@) { print "skipping Crypt::CBC test\n"; } else { print "trying CBC... "; my $c = Crypt::CBC->new($key, "Twofish") || die "$!\n"; my $t = $c->encrypt_hex($plaintext); ok($plaintext, $c->decrypt_hex($t)); } print "\nBenchmarks\n"; { my $s = Benchmark->new; for (my $i = 0; $i < 10000; $i++) { my $in = pack "H*", "0123456789ABCDEFFEDCBA9876543210"; my $c = Crypt::Twofish->new($key); $c->encrypt($in); } my $t = Benchmark->new; print "Encrypting (10,000 cycles, uncached cipher): ", timestr(timediff($t, $s)), "\n"; } { my $s = Benchmark->new; for (my $i = 0; $i < 10000; $i++) { my $in = pack "H*", "0123456789ABCDEFFEDCBA9876543210"; my $c = Crypt::Twofish->new($key); $c->decrypt($in); } my $t = Benchmark->new; print "Decrypting (10,000 cycles, uncached cipher): ", timestr(timediff($t, $s)), "\n"; } { my $c = Crypt::Twofish->new($key); my $s = Benchmark->new; for (my $i = 0; $i < 10000; $i++) { my $in = pack "H*", "0123456789ABCDEFFEDCBA9876543210"; $c->encrypt($in); } my $t = Benchmark->new; print "Encrypting (10,000 cycles, cached cipher): ", timestr(timediff($t, $s)), "\n"; } { my $c = Crypt::Twofish->new($key); my $s = Benchmark->new; for (my $i = 0; $i < 10000; $i++) { my $in = pack "H*", "0123456789ABCDEFFEDCBA9876543210"; $c->decrypt($in); } my $t = Benchmark->new; print "Decrypting (10,000 cycles, cached cipher): ", timestr(timediff($t, $s)), "\n"; } Crypt-Twofish-2.17/Makefile.PL0000644000175000017500000000427312131270520014260 0ustar amsams# $Id: Makefile.PL,v 2.12 2001/05/21 17:38:01 ams Exp $ # Copyright 2001 Abhijit Menon-Sen use Config; use File::Spec; use ExtUtils::MakeMaker; ($stdint = <<"TEST") =~ s/^\| {0,3}//gm; | #include | int main(void) { | printf("%d%d", sizeof(uint16_t), sizeof(uint32_t)); | return 0; | } TEST ($inttypes = $stdint) =~ s/stdint/inttypes/; print "Searching for uint*_t... "; if (ftest($inttypes) eq "24") { print "inttypes.h"; $def = "#include "; } elsif (ftest($stdint) eq "24") { print "stdint.h"; $def = "#include "; } else { print "no"; foreach (qw(short int long)) { my $size = $Config{"${_}size"}; $sixteen ||= "unsigned $_" if ($size == 2); $thirtytwo ||= "unsigned $_" if ($size == 4); } $def = "typedef $sixteen uint16_t;\ntypedef $thirtytwo uint32_t;"; } print "\n"; ($text = <<"PLATFORM") =~ s/^\| {0,3}//gm; | /* Automatically generated by "perl Makefile.PL" */ | | #ifndef _PLATFORM_H_ | #define _PLATFORM_H_ | | $def | | #endif PLATFORM open(F, ">platform.h") || die "platform.h: $!\n"; print F $text; close F; sub MY::postamble { "tables.h: tab/tables.pl\n\t\$(PERL) tab/tables.pl\n" } WriteMakefile( NAME => 'Crypt::Twofish', OBJECT => 'Twofish.o _twofish.o', VERSION_FROM => 'Twofish.pm', ABSTRACT_FROM => 'Twofish.pm', depend => { '_twofish.o' => 'tables.h' }, PREREQ_PM => { 'strict' => '0' } ); # Compile and run a program to test for a particular feature. sub ftest { my $null = File::Spec->devnull; my $result = 0; open(F, ">ftest.c") || die "ftest.c: $!\n"; print F $_[0]; close F; unlink("ftest"); open OLDERR, ">&STDERR" || die; open OLDOUT, ">&STDOUT" || die; open STDOUT, ">$null" || die; open STDERR, ">$null" || die; if (system("$Config{cc} $Config{ccflags} -o ftest ftest.c") == 0) { open STDOUT, ">&OLDOUT" || die; open (F, "./ftest |") && do { local $/; $result = ; }; } open STDERR, ">&OLDERR" || die; open STDOUT, ">&OLDOUT" || die; unlink("ftest", "ftest.c"); return $result; } Crypt-Twofish-2.17/typemap0000644000175000017500000000003007273116776013722 0ustar amsamsCrypt::Twofish T_PTROBJ Crypt-Twofish-2.17/_twofish.c0000644000175000017500000003120607302251171014275 0ustar amsams/* * $Id: _twofish.c,v 2.12 2001/05/21 17:38:01 ams Exp $ * Copyright 1999 Dr. Brian Gladman * Copyright 2001 Abhijit Menon-Sen */ /* Twofish is a 128-bit symmetric block cipher with a variable length key, developed by Counterpane Labs. It is unpatented and free for all uses, as described at and . This implementation is based on code by Dr. Brian Gladman, at . Some of his comments are reproduced below: "Copyright in this implementation is held by Dr. B R Gladman but I hereby give permission for its free direct or derivative use subject to ackowledgement of its origin and compliance with any conditions that the originators of the algorithm place on its exploitation. My thanks to Doug Whiting and Niels Ferguson for comments that led to improvements in this implementation." */ #include "twofish.h" #include "tables.h" /* Extract the n'th byte from a 32-bit word */ #define byte(x,n) ((unsigned char)((x) >> (8 * n))) /* 32 bit rotate-left and right macros */ #define ror(x,n) (((x) >> ((int)(n))) | ((x) << (32 - (int)(n)))) #define rol(x,n) (((x) << ((int)(n))) | ((x) >> (32 - (int)(n)))) /* Endian-independent byte -> word conversion */ #define strtonl(s) (uint32_t)(*(s)|*(s+1)<<8|*(s+2)<<16|*(s+3)<<24) #define nltostr(l, s) \ do { \ *(s )=(unsigned char)((l) ); \ *(s+1)=(unsigned char)((l) >> 8); \ *(s+2)=(unsigned char)((l) >> 16); \ *(s+3)=(unsigned char)((l) >> 24); \ } while (0) static uint32_t mds_rem(uint32_t a, uint32_t b); static uint32_t h(int len, const int x, unsigned char *key, int odd); /* The key schedule takes a 128, 192, or 256-bit key, and provides 40 32-bit words of expanded key K0,...,K39 and the 4 key-dependent S-boxes used in the g function. */ struct twofish *twofish_setup(unsigned char *key, int len) { int i; uint32_t a, b, x; struct twofish *t; unsigned char *s, skey[16]; if ((t = malloc(sizeof(struct twofish))) == NULL) return NULL; /* The key consists of k=len/8 (2, 3 or 4) 64-bit units. */ t->len = len /= 8; /* We must derive three vectors Me, Mo, and S, each with k 32-bit words, from the 2k words in the key. Me = (key[0], key[2], ..., key[2k-2]) (even words) Mo = (key[1], key[3], ..., key[2k-1]) (odd words) The third vector is derived by multiplying each of the k groups of 8 bytes from the key by a 4x8 matrix, to get k 32-bit words. S = (S[k-1], S[k-2], ..., S[0]) where S[i] are the 4 bytes from the multiplication, interpreted as a 32-bit word. As described later, mds_rem is equivalent to the matrix multiplication, but faster. Since all these vectors are going to be used byte-by-byte, we avoid converting them to words altogether, and write the bytes of S into the array skey below: */ s = skey + 4*(len - 1); for (i = 0; i < len; i++) { x = mds_rem(strtonl(key+8*i), strtonl(key+8*i+4)); nltostr(x, s); s -= 4; } s = skey; /* The words of the expanded key K are defined using the h function: rho = 2^24 + 2^16 + 2^8 + 2^0 (0x01010101) A[i] = h(2i*rho, Me) B[i] = ROL(h(2(i+1)*rho, Mo), 8) K[2i] = (A[i] + B[i]) mod 2^32 K[2i+1] = ROL((A[i] + 2B[i]) mod 2^32, 9) rho has the property that, for i = 0..255, the word i*rho consists of four equal bytes, each with the value i. The function h is only applied to words of this type, so we only pass it the value of i. We also didn't generate the vectors Me and Mo separately: we pass the entire key, and indicate whether we want the even or odd words to be used. */ for (i = 0; i < 40; i += 2) { a = h(len, i, key, 0); b = rol(h(len, i+1, key, 1), 8); t->K[i] = a+b; t->K[i+1] = rol(a+2*b, 9); } /* The key-dependent S-boxes used in the g() function are created below. They are defined by g(X) = h(X, S), where S is the vector derived from the key. That is, for i=0..3, the S-box S[i] is formed by mapping from x[i] to y[i] in the h function. The relevant lookup tables qN have been precomputed and stored in tables.h; we also perform full key precomputations incorporating the MDS matrix multiplications. */ switch (len) { case 2: for (i = 0; i < 256; i++) { x = (unsigned char)i; t->S[0][i] = m[0][q[0][q[0][x]^s[4]]^s[0]]; t->S[1][i] = m[1][q[0][q[1][x]^s[5]]^s[1]]; t->S[2][i] = m[2][q[1][q[0][x]^s[6]]^s[2]]; t->S[3][i] = m[3][q[1][q[1][x]^s[7]]^s[3]]; } break; case 3: for (i = 0; i < 256; i++) { x = (unsigned char)i; t->S[0][i] = m[0][q[0][q[0][q[1][x]^s[ 8]]^s[4]]^s[0]]; t->S[1][i] = m[1][q[0][q[1][q[1][x]^s[ 9]]^s[5]]^s[1]]; t->S[2][i] = m[2][q[1][q[0][q[0][x]^s[10]]^s[6]]^s[2]]; t->S[3][i] = m[3][q[1][q[1][q[0][x]^s[11]]^s[7]]^s[3]]; } break; case 4: for (i = 0; i < 256; i++) { x = (unsigned char)i; t->S[0][i] = m[0][q[0][q[0][q[1][q[1][x]^s[12]]^s[ 8]]^s[4]]^s[0]]; t->S[1][i] = m[1][q[0][q[1][q[1][q[0][x]^s[13]]^s[ 9]]^s[5]]^s[1]]; t->S[2][i] = m[2][q[1][q[0][q[0][q[0][x]^s[14]]^s[10]]^s[6]]^s[2]]; t->S[3][i] = m[3][q[1][q[1][q[0][q[1][x]^s[15]]^s[11]]^s[7]]^s[3]]; } break; } return t; } void twofish_free(struct twofish *self) { free(self); } /* The function g splits the input word x into four bytes; each byte is run through its own key-dependent S-box. Each S-box is bijective, takes 8 bits of input and produces 8 bits of output. The four results are interpreted as a vector of length 4 over GF(2^8), and multiplied by the 4x4 MDS matrix. The resulting vector is interpreted as a 32-bit word. Since we have performed the full key precomputations, g consists only of four lookups and three XORs. g0 is g; g1 is a shortcut for g(ROL(x, 8)). */ #define g0(x) \ t->S[0][byte(x,0)]^t->S[1][byte(x,1)]^t->S[2][byte(x,2)]^t->S[3][byte(x,3)] #define g1(x) \ t->S[0][byte(x,3)]^t->S[1][byte(x,0)]^t->S[2][byte(x,1)]^t->S[3][byte(x,2)] /* F is a key-dependent permutation on 64-bit values. It takes two input words R0 and R1, and a round number r: T0 = g(R0) T1 = g(ROL(R1, 8)) F0 = (T0 + T1 + K[2r+8]) F1 = (T0 + 2*T1 + K[2r+9]) Each of the 16 encryption rounds consists of the following operations: (F0, F1) = F(R0, R1, r) R0 = ROR(R2 ^ F0, 1) R1 = ROL(R3, 1) ^ F1 R2 = R0 R3 = R1 For efficiency, two rounds are combined into one in the macros below. */ #define f_2rounds(i) \ t0 = g0(R[0]); \ t1 = g1(R[1]); \ R[2] = ror(R[2] ^ (t0 + t1 + t->K[4*i+8]), 1); \ R[3] = rol(R[3], 1) ^ (t0 + 2*t1 + t->K[4*i+9]); \ t0 = g0(R[2]); \ t1 = g1(R[3]); \ R[0] = ror(R[0] ^ (t0 + t1 + t->K[4*i+10]), 1); \ R[1] = rol(R[1], 1) ^ (t0 + 2*t1 + t->K[4*i+11]); /* This is the inverse of f_2rounds */ #define i_2rounds(i) \ t0 = g0(R[0]); \ t1 = g1(R[1]); \ R[2] = rol(R[2], 1) ^ (t0 + t1 + t->K[4*i+10]); \ R[3] = ror(R[3] ^ (t0 + 2*t1 + t->K[4*i+11]), 1); \ t0 = g0(R[2]); \ t1 = g1(R[3]); \ R[0] = rol(R[0], 1) ^ (t0 + t1 + t->K[4*i+8]); \ R[1] = ror(R[1] ^ (t0 + 2*t1 + t->K[4*i+9]), 1) /* This function encrypts or decrypts 16 bytes of input data and writes it to output, using the key defined in t. */ void twofish_crypt(struct twofish *t, unsigned char *input, unsigned char *output, int decrypt) { uint32_t t0, t1, R[4], out[4]; if (!decrypt) { /* Whiten four 32-bit input words. */ R[0] = t->K[0] ^ strtonl(input); R[1] = t->K[1] ^ strtonl(input+4); R[2] = t->K[2] ^ strtonl(input+8); R[3] = t->K[3] ^ strtonl(input+12); /* 16 rounds of encryption, combined into 8 pairs. */ f_2rounds(0); f_2rounds(1); f_2rounds(2); f_2rounds(3); f_2rounds(4); f_2rounds(5); f_2rounds(6); f_2rounds(7); /* Output whitening; The order of R[n] undoes the last swap. */ out[0] = t->K[4] ^ R[2]; out[1] = t->K[5] ^ R[3]; out[2] = t->K[6] ^ R[0]; out[3] = t->K[7] ^ R[1]; } else { R[0] = t->K[4] ^ strtonl(input); R[1] = t->K[5] ^ strtonl(input+4); R[2] = t->K[6] ^ strtonl(input+8); R[3] = t->K[7] ^ strtonl(input+12); i_2rounds(7); i_2rounds(6); i_2rounds(5); i_2rounds(4); i_2rounds(3); i_2rounds(2); i_2rounds(1); i_2rounds(0); out[0] = t->K[0] ^ R[2]; out[1] = t->K[1] ^ R[3]; out[2] = t->K[2] ^ R[0]; out[3] = t->K[3] ^ R[1]; } /* Write 16 output bytes. */ nltostr(out[0], output); nltostr(out[1], output+4); nltostr(out[2], output+8); nltostr(out[3], output+12); } /* h takes a 32-bit word X, and a list, L = (L[0],...,L[k-1]), of 32-bit words, and produces one word of output. During each of the k stages of the function, the four bytes from X are each passed through a fixed S-box, and XORed with a byte derived from the list. Finally, the bytes are once again passed through an S-box and multiplied by the MDS matrix, just as in g. We use the Lbyte macro to extract a given byte from the list L (expressed in little endian). */ #define Lbyte(w, b) L[4*(2*w+odd)+b] static uint32_t h(int len, const int X, unsigned char *L, int odd) { unsigned char b0, b1, b2, b3; b0 = b1 = b2 = b3 = (unsigned char)X; switch (len) { case 4: b0 = q[1][b0] ^ Lbyte(3, 0); b1 = q[0][b1] ^ Lbyte(3, 1); b2 = q[0][b2] ^ Lbyte(3, 2); b3 = q[1][b3] ^ Lbyte(3, 3); case 3: b0 = q[1][b0] ^ Lbyte(2, 0); b1 = q[1][b1] ^ Lbyte(2, 1); b2 = q[0][b2] ^ Lbyte(2, 2); b3 = q[0][b3] ^ Lbyte(2, 3); case 2: b0 = q[0][q[0][b0] ^ Lbyte(1, 0)] ^ Lbyte(0, 0); b1 = q[0][q[1][b1] ^ Lbyte(1, 1)] ^ Lbyte(0, 1); b2 = q[1][q[0][b2] ^ Lbyte(1, 2)] ^ Lbyte(0, 2); b3 = q[1][q[1][b3] ^ Lbyte(1, 3)] ^ Lbyte(0, 3); } return m[0][b0] ^ m[1][b1] ^ m[2][b2] ^ m[3][b3]; } /* The (12, 8) Reed Solomon code has the generator polynomial: g(x) = x^4 + (a + 1/a) * x^3 + a * x^2 + (a + 1/a) * x + 1 where the coefficients are in the finite field GF(2^8) with a modular polynomial a^8+a^6+a^3+a^2+1. To generate the remainder, we have to start with a 12th order polynomial with our eight input bytes as the coefficients of the 4th to 11th terms: m[7] * x^11 + m[6] * x^10 ... + m[0] * x^4 + 0 * x^3 +... + 0 We then multiply the generator polynomial by m[7]*x^7 and subtract it (XOR in GF(2^8)) from the above to eliminate the x^7 term (the arithmetic on the coefficients is done in GF(2^8)). We then multiply the generator polynomial by m[6]*x^6 and use this to remove the x^10 term, and so on until the x^4 term is removed, and we are left with: r[3] * x^3 + r[2] * x^2 + r[1] 8 x^1 + r[0] which give the resulting 4 bytes of the remainder. This is equivalent to the matrix multiplication described in the Twofish paper, but is much faster. */ static uint32_t mds_rem(uint32_t a, uint32_t b) { int i; uint32_t t, u; enum { G_MOD = 0x0000014d }; for (i = 0; i < 8; i++) { /* Get most significant coefficient */ t = b >> 24; /* Shift the others up */ b = (b << 8) | (a >> 24); a <<= 8; u = t << 1; /* Subtract the modular polynomial on overflow */ if (t & 0x80) u ^= G_MOD; /* Remove t * (a * x^2 + 1) */ b ^= t ^ (u << 16); /* Form u = a*t + t/a = t*(a + 1/a) */ u ^= t >> 1; /* Add the modular polynomial on underflow */ if (t & 0x01) u ^= G_MOD >> 1; /* Remove t * (a + 1/a) * (x^3 + x) */ b ^= (u << 24) | (u << 8); } return b; } Crypt-Twofish-2.17/META.json0000644000175000017500000000152512147036751013741 0ustar amsams{ "abstract" : "The Twofish Encryption Algorithm", "author" : [ "unknown" ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 6.62, CPAN::Meta::Converter version 2.130880", "license" : [ "unknown" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "Crypt-Twofish", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "requires" : { "strict" : "0" } } }, "release_status" : "stable", "version" : "2.17" } Crypt-Twofish-2.17/Twofish.xs0000644000175000017500000000317012147036621014311 0ustar amsams/* * $Id: Twofish.xs,v 2.12 2001/05/21 17:38:01 ams Exp $ * Copyright 2001 Abhijit Menon-Sen */ #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" #include "twofish.h" typedef struct twofish * Crypt__Twofish; MODULE = Crypt::Twofish PACKAGE = Crypt::Twofish PREFIX = twofish_ PROTOTYPES: DISABLE Crypt::Twofish twofish_setup(key) char * key = NO_INIT STRLEN keylen = NO_INIT CODE: { key = SvPV(ST(0), keylen); if (keylen != 16 && keylen != 24 && keylen != 32) croak("key must be 16, 24, or 32 bytes long"); RETVAL = twofish_setup((unsigned char *)key, keylen); } OUTPUT: RETVAL void twofish_DESTROY(self) Crypt::Twofish self CODE: twofish_free(self); void twofish_crypt(self, input, output, decrypt) Crypt::Twofish self char * input = NO_INIT SV * output int decrypt STRLEN inlen = NO_INIT STRLEN outlen = NO_INIT CODE: { input = SvPV(ST(1), inlen); if (inlen != 16) croak("input must be 16 bytes long"); if (output == &PL_sv_undef) output = sv_newmortal(); outlen = 16; SvUPGRADE(output, SVt_PV); if (SvREADONLY(output)) croak("cannot use output as lvalue"); twofish_crypt(self, (unsigned char *)input, (unsigned char *)SvGROW(output, outlen), decrypt); SvCUR_set(output, outlen); *SvEND(output) = '\0'; SvPOK_only(output); SvTAINT(output); ST(0) = output; } Crypt-Twofish-2.17/ppport.h0000644000175000017500000001716307274461373014031 0ustar amsams #ifndef _P_P_PORTABILITY_H_ #define _P_P_PORTABILITY_H_ /* Perl/Pollution/Portability Version 1.0007 */ /* Copyright (C) 1999, Kenneth Albanowski. This code may be used and distributed under the same license as any version of Perl. */ /* For the latest version of this code, please retreive the Devel::PPPort module from CPAN, contact the author at , or check with the Perl maintainers. */ /* If you needed to customize this file for your project, please mention your changes, and visible alter the version number. */ /* In order for a Perl extension module to be as portable as possible across differing versions of Perl itself, certain steps need to be taken. Including this header is the first major one, then using dTHR is all the appropriate places and using a PL_ prefix to refer to global Perl variables is the second. */ /* If you use one of a few functions that were not present in earlier versions of Perl, please add a define before the inclusion of ppport.h for a static include, or use the GLOBAL request in a single module to produce a global definition that can be referenced from the other modules. Function: Static define: Extern define: newCONSTSUB() NEED_newCONSTSUB NEED_newCONSTSUB_GLOBAL */ /* To verify whether ppport.h is needed for your module, and whether any special defines should be used, ppport.h can be run through Perl to check your source code. Simply say: perl -x ppport.h *.c *.h *.xs foo/*.c [etc] The result will be a list of patches suggesting changes that should at least be acceptable, if not necessarily the most efficient solution, or a fix for all possible problems. It won't catch where dTHR is needed, and doesn't attempt to account for global macro or function definitions, nested includes, typemaps, etc. In order to test for the need of dTHR, please try your module under a recent version of Perl that has threading compiled-in. */ /* #!/usr/bin/perl @ARGV = ("*.xs") if !@ARGV; %badmacros = %funcs = %macros = (); $replace = 0; foreach () { $funcs{$1} = 1 if /Provide:\s+(\S+)/; $macros{$1} = 1 if /^#\s*define\s+([a-zA-Z0-9_]+)/; $replace = $1 if /Replace:\s+(\d+)/; $badmacros{$2}=$1 if $replace and /^#\s*define\s+([a-zA-Z0-9_]+).*?\s+([a-zA-Z0-9_]+)/; $badmacros{$1}=$2 if /Replace (\S+) with (\S+)/; } foreach $filename (map(glob($_),@ARGV)) { unless (open(IN, "<$filename")) { warn "Unable to read from $file: $!\n"; next; } print "Scanning $filename...\n"; $c = ""; while () { $c .= $_; } close(IN); $need_include = 0; %add_func = (); $changes = 0; $has_include = ($c =~ /#.*include.*ppport/m); foreach $func (keys %funcs) { if ($c =~ /#.*define.*\bNEED_$func(_GLOBAL)?\b/m) { if ($c !~ /\b$func\b/m) { print "If $func isn't needed, you don't need to request it.\n" if $changes += ($c =~ s/^.*#.*define.*\bNEED_$func\b.*\n//m); } else { print "Uses $func\n"; $need_include = 1; } } else { if ($c =~ /\b$func\b/m) { $add_func{$func} =1 ; print "Uses $func\n"; $need_include = 1; } } } if (not $need_include) { foreach $macro (keys %macros) { if ($c =~ /\b$macro\b/m) { print "Uses $macro\n"; $need_include = 1; } } } foreach $badmacro (keys %badmacros) { if ($c =~ /\b$badmacro\b/m) { $changes += ($c =~ s/\b$badmacro\b/$badmacros{$badmacro}/gm); print "Uses $badmacros{$badmacro} (instead of $badmacro)\n"; $need_include = 1; } } if (scalar(keys %add_func) or $need_include != $has_include) { if (!$has_include) { $inc = join('',map("#define NEED_$_\n", sort keys %add_func)). "#include \"ppport.h\"\n"; $c = "$inc$c" unless $c =~ s/#.*include.*XSUB.*\n/$&$inc/m; } elsif (keys %add_func) { $inc = join('',map("#define NEED_$_\n", sort keys %add_func)); $c = "$inc$c" unless $c =~ s/^.*#.*include.*ppport.*$/$inc$&/m; } if (!$need_include) { print "Doesn't seem to need ppport.h.\n"; $c =~ s/^.*#.*include.*ppport.*\n//m; } $changes++; } if ($changes) { open(OUT,">/tmp/ppport.h.$$"); print OUT $c; close(OUT); open(DIFF, "diff -u $filename /tmp/ppport.h.$$|"); while () { s!/tmp/ppport\.h\.$$!$filename.patched!; print STDOUT; } close(DIFF); unlink("/tmp/ppport.h.$$"); } else { print "Looks OK\n"; } } __DATA__ */ #ifndef PERL_REVISION # ifndef __PATCHLEVEL_H_INCLUDED__ # include "patchlevel.h" # endif # ifndef PERL_REVISION # define PERL_REVISION (5) /* Replace: 1 */ # define PERL_VERSION PATCHLEVEL # define PERL_SUBVERSION SUBVERSION /* Replace PERL_PATCHLEVEL with PERL_VERSION */ /* Replace: 0 */ # endif #endif #define PERL_BCDVERSION ((PERL_REVISION * 0x1000000L) + (PERL_VERSION * 0x1000L) + PERL_SUBVERSION) #ifndef ERRSV # define ERRSV perl_get_sv("@",FALSE) #endif #if (PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION <= 5)) /* Replace: 1 */ # define PL_sv_undef sv_undef # define PL_sv_yes sv_yes # define PL_sv_no sv_no # define PL_na na # define PL_stdingv stdingv # define PL_hints hints # define PL_curcop curcop # define PL_curstash curstash # define PL_copline copline # define PL_Sv Sv /* Replace: 0 */ #endif #ifndef dTHR # ifdef WIN32 # define dTHR extern int Perl___notused # else # define dTHR extern int errno # endif #endif #ifndef boolSV # define boolSV(b) ((b) ? &PL_sv_yes : &PL_sv_no) #endif #ifndef gv_stashpvn # define gv_stashpvn(str,len,flags) gv_stashpv(str,flags) #endif #ifndef newSVpvn # define newSVpvn(data,len) ((len) ? newSVpv ((data), (len)) : newSVpv ("", 0)) #endif #ifndef newRV_inc /* Replace: 1 */ # define newRV_inc(sv) newRV(sv) /* Replace: 0 */ #endif #ifndef newRV_noinc # ifdef __GNUC__ # define newRV_noinc(sv) \ ({ \ SV *nsv = (SV*)newRV(sv); \ SvREFCNT_dec(sv); \ nsv; \ }) # else # if defined(CRIPPLED_CC) || defined(USE_THREADS) static SV * newRV_noinc (SV * sv) { SV *nsv = (SV*)newRV(sv); SvREFCNT_dec(sv); return nsv; } # else # define newRV_noinc(sv) \ ((PL_Sv=(SV*)newRV(sv), SvREFCNT_dec(sv), (SV*)PL_Sv) # endif # endif #endif /* Provide: newCONSTSUB */ /* newCONSTSUB from IO.xs is in the core starting with 5.004_63 */ #if (PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION < 63)) #if defined(NEED_newCONSTSUB) static #else extern void newCONSTSUB _((HV * stash, char * name, SV *sv)); #endif #if defined(NEED_newCONSTSUB) || defined(NEED_newCONSTSUB_GLOBAL) void newCONSTSUB(stash,name,sv) HV *stash; char *name; SV *sv; { U32 oldhints = PL_hints; HV *old_cop_stash = PL_curcop->cop_stash; HV *old_curstash = PL_curstash; line_t oldline = PL_curcop->cop_line; PL_curcop->cop_line = PL_copline; PL_hints &= ~HINT_BLOCK_SCOPE; if (stash) PL_curstash = PL_curcop->cop_stash = stash; newSUB( #if (PERL_VERSION < 3) || ((PERL_VERSION == 3) && (PERL_SUBVERSION < 22)) /* before 5.003_22 */ start_subparse(), #else # if (PERL_VERSION == 3) && (PERL_SUBVERSION == 22) /* 5.003_22 */ start_subparse(0), # else /* 5.003_23 onwards */ start_subparse(FALSE, 0), # endif #endif newSVOP(OP_CONST, 0, newSVpv(name,0)), newSVOP(OP_CONST, 0, &PL_sv_no), /* SvPV(&PL_sv_no) == "" -- GMB */ newSTATEOP(0, Nullch, newSVOP(OP_CONST, 0, sv)) ); PL_hints = oldhints; PL_curcop->cop_stash = old_cop_stash; PL_curstash = old_curstash; PL_curcop->cop_line = oldline; } #endif #endif /* newCONSTSUB */ #endif /* _P_P_PORTABILITY_H_ */ Crypt-Twofish-2.17/twofish.h0000644000175000017500000000126207302251171014142 0ustar amsams/* * $Id: twofish.h,v 2.12 2001/05/21 17:38:01 ams Exp $ * Copyright 2001 Abhijit Menon-Sen */ #include #include "platform.h" #ifndef _TWOFISH_H_ #define _TWOFISH_H_ struct twofish { int len; /* Key length in 64-bit units: 2, 3 or 4 */ uint32_t K[40]; /* Expanded key */ uint32_t S[4][256]; /* Key-dependent S-boxes */ }; struct twofish *twofish_setup(unsigned char *key, int len); void twofish_free(struct twofish *self); void twofish_crypt(struct twofish *t, unsigned char *input, unsigned char *output, int decrypt); #endif Crypt-Twofish-2.17/META.yml0000644000175000017500000000072112147036751013566 0ustar amsams--- abstract: 'The Twofish Encryption Algorithm' author: - unknown build_requires: ExtUtils::MakeMaker: 0 configure_requires: ExtUtils::MakeMaker: 0 dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 6.62, CPAN::Meta::Converter version 2.130880' license: unknown meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: Crypt-Twofish no_index: directory: - t - inc requires: strict: 0 version: 2.17