OSDN Git Service

libgo: Update to current Go library.
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 7 Apr 2011 17:09:10 +0000 (17:09 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 7 Apr 2011 17:09:10 +0000 (17:09 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@172106 138bc75d-0d04-0410-961f-82ee72b054a4

110 files changed:
libgo/MERGE
libgo/Makefile.am
libgo/Makefile.in
libgo/go/archive/tar/reader.go
libgo/go/archive/tar/reader_test.go
libgo/go/archive/zip/reader.go
libgo/go/bufio/bufio.go
libgo/go/compress/lzw/writer_test.go
libgo/go/compress/zlib/writer_test.go
libgo/go/crypto/block/cbc.go [deleted file]
libgo/go/crypto/block/cfb.go [deleted file]
libgo/go/crypto/block/cfb_aes_test.go [deleted file]
libgo/go/crypto/block/cipher.go [deleted file]
libgo/go/crypto/block/cmac.go [deleted file]
libgo/go/crypto/block/cmac_aes_test.go [deleted file]
libgo/go/crypto/block/ctr.go [deleted file]
libgo/go/crypto/block/eax.go [deleted file]
libgo/go/crypto/block/eax_aes_test.go [deleted file]
libgo/go/crypto/block/ecb.go [deleted file]
libgo/go/crypto/block/ecb_aes_test.go [deleted file]
libgo/go/crypto/block/ecb_test.go [deleted file]
libgo/go/crypto/block/ofb.go [deleted file]
libgo/go/crypto/block/ofb_aes_test.go [deleted file]
libgo/go/crypto/block/xor.go [deleted file]
libgo/go/crypto/block/xor_test.go [deleted file]
libgo/go/crypto/des/block.go [new file with mode: 0644]
libgo/go/crypto/des/cipher.go [new file with mode: 0644]
libgo/go/crypto/des/const.go [new file with mode: 0644]
libgo/go/crypto/des/des_test.go [new file with mode: 0644]
libgo/go/crypto/ecdsa/ecdsa.go
libgo/go/crypto/rand/rand_unix.go
libgo/go/crypto/rsa/pkcs1v15.go
libgo/go/crypto/rsa/rsa.go
libgo/go/crypto/rsa/rsa_test.go
libgo/go/crypto/tls/generate_cert.go
libgo/go/crypto/tls/tls.go
libgo/go/crypto/x509/x509.go
libgo/go/crypto/x509/x509_test.go
libgo/go/debug/elf/file.go
libgo/go/debug/macho/file.go
libgo/go/debug/pe/file.go
libgo/go/debug/proc/proc_linux.go
libgo/go/exec/exec.go
libgo/go/exp/draw/x11/auth.go
libgo/go/exp/ogle/cmd.go
libgo/go/fmt/fmt_test.go
libgo/go/fmt/format.go
libgo/go/fmt/print.go
libgo/go/go/parser/interface.go
libgo/go/go/parser/parser.go
libgo/go/html/parse_test.go
libgo/go/http/fs.go
libgo/go/http/fs_test.go
libgo/go/http/httptest/server.go
libgo/go/http/response_test.go
libgo/go/http/serve_test.go
libgo/go/http/transfer.go
libgo/go/http/transport.go
libgo/go/http/transport_test.go
libgo/go/http/url.go
libgo/go/http/url_test.go
libgo/go/image/decode_test.go
libgo/go/image/png/reader_test.go
libgo/go/io/ioutil/ioutil.go
libgo/go/io/ioutil/tempfile.go
libgo/go/log/log.go
libgo/go/log/log_test.go
libgo/go/mime/type.go
libgo/go/net/hosts.go
libgo/go/net/parse.go
libgo/go/net/parse_test.go
libgo/go/net/resolv_windows.go
libgo/go/os/dir_plan9.go [new file with mode: 0644]
libgo/go/os/dir_unix.go [new file with mode: 0644]
libgo/go/os/env_plan9.go [new file with mode: 0644]
libgo/go/os/error.go
libgo/go/os/error_plan9.go [new file with mode: 0644]
libgo/go/os/error_posix.go [new file with mode: 0644]
libgo/go/os/exec.go
libgo/go/os/exec_plan9.go [new file with mode: 0644]
libgo/go/os/exec_posix.go [new file with mode: 0644]
libgo/go/os/file.go
libgo/go/os/file_plan9.go [new file with mode: 0644]
libgo/go/os/file_posix.go [new file with mode: 0644]
libgo/go/os/file_unix.go
libgo/go/os/getwd.go
libgo/go/os/inotify/inotify_linux_test.go
libgo/go/os/os_test.go
libgo/go/os/path.go
libgo/go/os/path_test.go
libgo/go/os/proc.go
libgo/go/os/stat_plan9.go [new file with mode: 0644]
libgo/go/os/sys_linux.go
libgo/go/os/sys_plan9.go [new file with mode: 0644]
libgo/go/os/time.go
libgo/go/path/filepath/match.go
libgo/go/path/filepath/match_test.go
libgo/go/path/filepath/path.go
libgo/go/path/filepath/path_plan9.go [new file with mode: 0644]
libgo/go/path/filepath/path_test.go
libgo/go/path/filepath/path_unix.go
libgo/go/scanner/scanner.go
libgo/go/scanner/scanner_test.go
libgo/go/strconv/fp_test.go
libgo/go/testing/testing.go
libgo/mksysinfo.sh
libgo/syscalls/syscall.go
libgo/syscalls/syscall_unix.go
libgo/syscalls/sysfile_largefile.go
libgo/syscalls/sysfile_regfile.go

index b78ba69..237a0c2 100644 (file)
@@ -1,4 +1,4 @@
-342e3b11f21a
+f618e5e0991d
 
 The first line of this file holds the Mercurial revision number of the
 last merge done from the master library sources.
index c40456f..3c94331 100644 (file)
@@ -177,10 +177,10 @@ toolexeclibgocryptodir = $(toolexeclibgodir)/crypto
 
 toolexeclibgocrypto_DATA = \
        crypto/aes.gox \
-       crypto/block.gox \
        crypto/blowfish.gox \
        crypto/cast5.gox \
        crypto/cipher.gox \
+       crypto/des.gox \
        crypto/dsa.gox \
        crypto/ecdsa.gox \
        crypto/elliptic.gox \
@@ -727,9 +727,12 @@ go_os_files = \
        go/os/env.go \
        go/os/env_unix.go \
        go/os/error.go \
+       go/os/error_posix.go \
        go/os/exec.go \
+       go/os/exec_posix.go \
        go/os/exec_unix.go \
        go/os/file.go \
+       go/os/file_posix.go \
        go/os/file_unix.go \
        go/os/getwd.go \
        go/os/path.go \
@@ -932,16 +935,6 @@ go_crypto_aes_files = \
        go/crypto/aes/block.go \
        go/crypto/aes/cipher.go \
        go/crypto/aes/const.go
-go_crypto_block_files = \
-       go/crypto/block/cbc.go \
-       go/crypto/block/cfb.go \
-       go/crypto/block/cmac.go \
-       go/crypto/block/cipher.go \
-       go/crypto/block/ctr.go \
-       go/crypto/block/eax.go \
-       go/crypto/block/ecb.go \
-       go/crypto/block/ofb.go \
-       go/crypto/block/xor.go
 go_crypto_blowfish_files = \
        go/crypto/blowfish/block.go \
        go/crypto/blowfish/const.go \
@@ -956,6 +949,10 @@ go_crypto_cipher_files = \
        go/crypto/cipher/io.go \
        go/crypto/cipher/ocfb.go \
        go/crypto/cipher/ofb.go
+go_crypto_des_files = \
+       go/crypto/des/block.go \
+       go/crypto/des/cipher.go \
+       go/crypto/des/const.go
 go_crypto_dsa_files = \
        go/crypto/dsa/dsa.go
 go_crypto_ecdsa_files = \
@@ -1428,10 +1425,10 @@ libgo_go_objs = \
        container/ring.lo \
        container/vector.lo \
        crypto/aes.lo \
-       crypto/block.lo \
        crypto/blowfish.lo \
        crypto/cast5.lo \
        crypto/cipher.lo \
+       crypto/des.lo \
        crypto/dsa.lo \
        crypto/ecdsa.lo \
        crypto/elliptic.lo \
@@ -2026,13 +2023,6 @@ crypto/aes/check: $(CHECK_DEPS)
        @$(CHECK)
 .PHONY: crypto/aes/check
 
-crypto/block.lo: $(go_crypto_block_files) fmt.gox io.gox os.gox strconv.gox
-       $(BUILDPACKAGE)
-crypto/block/check: $(CHECK_DEPS)
-       @$(MKDIR_P) crypto/block
-       @$(CHECK)
-.PHONY: crypto/block/check
-
 crypto/blowfish.lo: $(go_crypto_blowfish_files) os.gox strconv.gox
        $(BUILDPACKAGE)
 crypto/blowfish/check: $(CHECK_DEPS)
@@ -2054,6 +2044,13 @@ crypto/cipher/check: $(CHECK_DEPS)
        @$(CHECK)
 .PHONY: crypto/cipher/check
 
+crypto/des.lo: $(go_crypto_des_files) encoding/binary.gox os.gox strconv.gox
+       $(BUILDPACKAGE)
+crypto/des/check: $(CHECK_DEPS)
+       @$(MKDIR_P) crypto/des
+       @$(CHECK)
+.PHONY: crypto/des/check
+
 crypto/dsa.lo: $(go_crypto_dsa_files) big.gox io.gox os.gox
        $(BUILDPACKAGE)
 crypto/dsa/check: $(CHECK_DEPS)
@@ -2139,7 +2136,8 @@ crypto/ripemd160/check: $(CHECK_DEPS)
 .PHONY: crypto/ripemd160/check
 
 crypto/rsa.lo: $(go_crypto_rsa_files) big.gox crypto.gox crypto/sha1.gox \
-               crypto/subtle.gox encoding/hex.gox hash.gox io.gox os.gox
+               crypto/subtle.gox encoding/hex.gox hash.gox io.gox os.gox \
+               sync.gox
        $(BUILDPACKAGE)
 crypto/rsa/check: $(CHECK_DEPS)
        @$(MKDIR_P) crypto/rsa
@@ -2475,8 +2473,8 @@ http/cgi/check: $(CHECK_DEPS)
        @$(CHECK)
 .PHONY: http/cgi/check
 
-http/httptest.lo: $(go_http_httptest_files) bytes.gox fmt.gox http.gox \
-               net.gox os.gox
+http/httptest.lo: $(go_http_httptest_files) bytes.gox crypto/rand.gox \
+               crypto/tls.gox fmt.gox http.gox net.gox os.gox time.gox
        $(BUILDPACKAGE)
 http/httptest/check: $(CHECK_DEPS)
        @$(MKDIR_P) http/httptest
@@ -2767,14 +2765,14 @@ container/vector.gox: container/vector.lo
 
 crypto/aes.gox: crypto/aes.lo
        $(BUILDGOX)
-crypto/block.gox: crypto/block.lo
-       $(BUILDGOX)
 crypto/blowfish.gox: crypto/blowfish.lo
        $(BUILDGOX)
 crypto/cast5.gox: crypto/cast5.lo
        $(BUILDGOX)
 crypto/cipher.gox: crypto/cipher.lo
        $(BUILDGOX)
+crypto/des.gox: crypto/des.lo
+       $(BUILDGOX)
 crypto/dsa.gox: crypto/dsa.lo
        $(BUILDGOX)
 crypto/ecdsa.gox: crypto/ecdsa.lo      
@@ -3002,10 +3000,10 @@ TEST_PACKAGES = \
        container/ring/check \
        container/vector/check \
        crypto/aes/check \
-       crypto/block/check \
        crypto/blowfish/check \
        crypto/cast5/check \
        crypto/cipher/check \
+       crypto/des/check \
        crypto/dsa/check \
        crypto/ecdsa/check \
        crypto/elliptic/check \
index 10f86f1..da881d5 100644 (file)
@@ -140,31 +140,30 @@ am__DEPENDENCIES_2 = asn1/asn1.lo big/big.lo bufio/bufio.lo \
        archive/zip.lo compress/bzip2.lo compress/flate.lo \
        compress/gzip.lo compress/lzw.lo compress/zlib.lo \
        container/heap.lo container/list.lo container/ring.lo \
-       container/vector.lo crypto/aes.lo crypto/block.lo \
-       crypto/blowfish.lo crypto/cast5.lo crypto/cipher.lo \
-       crypto/dsa.lo crypto/ecdsa.lo crypto/elliptic.lo \
-       crypto/hmac.lo crypto/md4.lo crypto/md5.lo crypto/ocsp.lo \
-       crypto/openpgp.lo crypto/rand.lo crypto/rc4.lo \
-       crypto/ripemd160.lo crypto/rsa.lo crypto/sha1.lo \
-       crypto/sha256.lo crypto/sha512.lo crypto/subtle.lo \
-       crypto/tls.lo crypto/twofish.lo crypto/x509.lo crypto/xtea.lo \
-       crypto/openpgp/armor.lo crypto/openpgp/error.lo \
-       crypto/openpgp/packet.lo crypto/openpgp/s2k.lo debug/dwarf.lo \
-       debug/elf.lo debug/gosym.lo debug/macho.lo debug/pe.lo \
-       debug/proc.lo encoding/ascii85.lo encoding/base32.lo \
-       encoding/base64.lo encoding/binary.lo encoding/git85.lo \
-       encoding/hex.lo encoding/line.lo encoding/pem.lo \
-       exp/datafmt.lo exp/draw.lo exp/eval.lo go/ast.lo go/doc.lo \
-       go/parser.lo go/printer.lo go/scanner.lo go/token.lo \
-       go/typechecker.lo hash/adler32.lo hash/crc32.lo hash/crc64.lo \
-       hash/fnv.lo http/cgi.lo http/httptest.lo http/pprof.lo \
-       image/jpeg.lo image/png.lo index/suffixarray.lo io/ioutil.lo \
-       mime/multipart.lo net/dict.lo net/textproto.lo \
-       $(am__DEPENDENCIES_1) os/signal.lo path/filepath.lo \
-       rpc/jsonrpc.lo runtime/debug.lo runtime/pprof.lo \
-       sync/atomic.lo sync/atomic_c.lo syscalls/syscall.lo \
-       syscalls/errno.lo testing/testing.lo testing/iotest.lo \
-       testing/quick.lo testing/script.lo
+       container/vector.lo crypto/aes.lo crypto/blowfish.lo \
+       crypto/cast5.lo crypto/cipher.lo crypto/des.lo crypto/dsa.lo \
+       crypto/ecdsa.lo crypto/elliptic.lo crypto/hmac.lo \
+       crypto/md4.lo crypto/md5.lo crypto/ocsp.lo crypto/openpgp.lo \
+       crypto/rand.lo crypto/rc4.lo crypto/ripemd160.lo crypto/rsa.lo \
+       crypto/sha1.lo crypto/sha256.lo crypto/sha512.lo \
+       crypto/subtle.lo crypto/tls.lo crypto/twofish.lo \
+       crypto/x509.lo crypto/xtea.lo crypto/openpgp/armor.lo \
+       crypto/openpgp/error.lo crypto/openpgp/packet.lo \
+       crypto/openpgp/s2k.lo debug/dwarf.lo debug/elf.lo \
+       debug/gosym.lo debug/macho.lo debug/pe.lo debug/proc.lo \
+       encoding/ascii85.lo encoding/base32.lo encoding/base64.lo \
+       encoding/binary.lo encoding/git85.lo encoding/hex.lo \
+       encoding/line.lo encoding/pem.lo exp/datafmt.lo exp/draw.lo \
+       exp/eval.lo go/ast.lo go/doc.lo go/parser.lo go/printer.lo \
+       go/scanner.lo go/token.lo go/typechecker.lo hash/adler32.lo \
+       hash/crc32.lo hash/crc64.lo hash/fnv.lo http/cgi.lo \
+       http/httptest.lo http/pprof.lo image/jpeg.lo image/png.lo \
+       index/suffixarray.lo io/ioutil.lo mime/multipart.lo \
+       net/dict.lo net/textproto.lo $(am__DEPENDENCIES_1) \
+       os/signal.lo path/filepath.lo rpc/jsonrpc.lo runtime/debug.lo \
+       runtime/pprof.lo sync/atomic.lo sync/atomic_c.lo \
+       syscalls/syscall.lo syscalls/errno.lo testing/testing.lo \
+       testing/iotest.lo testing/quick.lo testing/script.lo
 libgo_la_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) \
        $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
        $(am__DEPENDENCIES_1)
@@ -624,10 +623,10 @@ toolexeclibgocontainer_DATA = \
 toolexeclibgocryptodir = $(toolexeclibgodir)/crypto
 toolexeclibgocrypto_DATA = \
        crypto/aes.gox \
-       crypto/block.gox \
        crypto/blowfish.gox \
        crypto/cast5.gox \
        crypto/cipher.gox \
+       crypto/des.gox \
        crypto/dsa.gox \
        crypto/ecdsa.gox \
        crypto/elliptic.gox \
@@ -1087,9 +1086,12 @@ go_os_files = \
        go/os/env.go \
        go/os/env_unix.go \
        go/os/error.go \
+       go/os/error_posix.go \
        go/os/exec.go \
+       go/os/exec_posix.go \
        go/os/exec_unix.go \
        go/os/file.go \
+       go/os/file_posix.go \
        go/os/file_unix.go \
        go/os/getwd.go \
        go/os/path.go \
@@ -1279,17 +1281,6 @@ go_crypto_aes_files = \
        go/crypto/aes/cipher.go \
        go/crypto/aes/const.go
 
-go_crypto_block_files = \
-       go/crypto/block/cbc.go \
-       go/crypto/block/cfb.go \
-       go/crypto/block/cmac.go \
-       go/crypto/block/cipher.go \
-       go/crypto/block/ctr.go \
-       go/crypto/block/eax.go \
-       go/crypto/block/ecb.go \
-       go/crypto/block/ofb.go \
-       go/crypto/block/xor.go
-
 go_crypto_blowfish_files = \
        go/crypto/blowfish/block.go \
        go/crypto/blowfish/const.go \
@@ -1307,6 +1298,11 @@ go_crypto_cipher_files = \
        go/crypto/cipher/ocfb.go \
        go/crypto/cipher/ofb.go
 
+go_crypto_des_files = \
+       go/crypto/des/block.go \
+       go/crypto/des/cipher.go \
+       go/crypto/des/const.go
+
 go_crypto_dsa_files = \
        go/crypto/dsa/dsa.go
 
@@ -1766,10 +1762,10 @@ libgo_go_objs = \
        container/ring.lo \
        container/vector.lo \
        crypto/aes.lo \
-       crypto/block.lo \
        crypto/blowfish.lo \
        crypto/cast5.lo \
        crypto/cipher.lo \
+       crypto/des.lo \
        crypto/dsa.lo \
        crypto/ecdsa.lo \
        crypto/elliptic.lo \
@@ -2008,10 +2004,10 @@ TEST_PACKAGES = \
        container/ring/check \
        container/vector/check \
        crypto/aes/check \
-       crypto/block/check \
        crypto/blowfish/check \
        crypto/cast5/check \
        crypto/cipher/check \
+       crypto/des/check \
        crypto/dsa/check \
        crypto/ecdsa/check \
        crypto/elliptic/check \
@@ -4436,13 +4432,6 @@ crypto/aes/check: $(CHECK_DEPS)
        @$(CHECK)
 .PHONY: crypto/aes/check
 
-crypto/block.lo: $(go_crypto_block_files) fmt.gox io.gox os.gox strconv.gox
-       $(BUILDPACKAGE)
-crypto/block/check: $(CHECK_DEPS)
-       @$(MKDIR_P) crypto/block
-       @$(CHECK)
-.PHONY: crypto/block/check
-
 crypto/blowfish.lo: $(go_crypto_blowfish_files) os.gox strconv.gox
        $(BUILDPACKAGE)
 crypto/blowfish/check: $(CHECK_DEPS)
@@ -4464,6 +4453,13 @@ crypto/cipher/check: $(CHECK_DEPS)
        @$(CHECK)
 .PHONY: crypto/cipher/check
 
+crypto/des.lo: $(go_crypto_des_files) encoding/binary.gox os.gox strconv.gox
+       $(BUILDPACKAGE)
+crypto/des/check: $(CHECK_DEPS)
+       @$(MKDIR_P) crypto/des
+       @$(CHECK)
+.PHONY: crypto/des/check
+
 crypto/dsa.lo: $(go_crypto_dsa_files) big.gox io.gox os.gox
        $(BUILDPACKAGE)
 crypto/dsa/check: $(CHECK_DEPS)
@@ -4549,7 +4545,8 @@ crypto/ripemd160/check: $(CHECK_DEPS)
 .PHONY: crypto/ripemd160/check
 
 crypto/rsa.lo: $(go_crypto_rsa_files) big.gox crypto.gox crypto/sha1.gox \
-               crypto/subtle.gox encoding/hex.gox hash.gox io.gox os.gox
+               crypto/subtle.gox encoding/hex.gox hash.gox io.gox os.gox \
+               sync.gox
        $(BUILDPACKAGE)
 crypto/rsa/check: $(CHECK_DEPS)
        @$(MKDIR_P) crypto/rsa
@@ -4885,8 +4882,8 @@ http/cgi/check: $(CHECK_DEPS)
        @$(CHECK)
 .PHONY: http/cgi/check
 
-http/httptest.lo: $(go_http_httptest_files) bytes.gox fmt.gox http.gox \
-               net.gox os.gox
+http/httptest.lo: $(go_http_httptest_files) bytes.gox crypto/rand.gox \
+               crypto/tls.gox fmt.gox http.gox net.gox os.gox time.gox
        $(BUILDPACKAGE)
 http/httptest/check: $(CHECK_DEPS)
        @$(MKDIR_P) http/httptest
@@ -5172,14 +5169,14 @@ container/vector.gox: container/vector.lo
 
 crypto/aes.gox: crypto/aes.lo
        $(BUILDGOX)
-crypto/block.gox: crypto/block.lo
-       $(BUILDGOX)
 crypto/blowfish.gox: crypto/blowfish.lo
        $(BUILDGOX)
 crypto/cast5.gox: crypto/cast5.lo
        $(BUILDGOX)
 crypto/cipher.gox: crypto/cipher.lo
        $(BUILDGOX)
+crypto/des.gox: crypto/des.lo
+       $(BUILDGOX)
 crypto/dsa.gox: crypto/dsa.lo
        $(BUILDGOX)
 crypto/ecdsa.gox: crypto/ecdsa.lo      
index 35a15f7..1b41196 100644 (file)
@@ -95,7 +95,7 @@ func (tr *Reader) skipUnread() {
        nr := tr.nb + tr.pad // number of bytes to skip
        tr.nb, tr.pad = 0, 0
        if sr, ok := tr.r.(io.Seeker); ok {
-               if _, err := sr.Seek(nr, 1); err == nil {
+               if _, err := sr.Seek(nr, os.SEEK_CUR); err == nil {
                        return
                }
        }
index aa4c797..32fc8f9 100644 (file)
@@ -113,7 +113,7 @@ var untarTests = []*untarTest{
 func TestReader(t *testing.T) {
 testLoop:
        for i, test := range untarTests {
-               f, err := os.Open(test.file, os.O_RDONLY, 0444)
+               f, err := os.Open(test.file)
                if err != nil {
                        t.Errorf("test %d: Unexpected error: %v", i, err)
                        continue
@@ -143,7 +143,7 @@ testLoop:
 }
 
 func TestPartialRead(t *testing.T) {
-       f, err := os.Open("testdata/gnu.tar", os.O_RDONLY, 0444)
+       f, err := os.Open("testdata/gnu.tar")
        if err != nil {
                t.Fatalf("Unexpected error: %v", err)
        }
@@ -181,7 +181,7 @@ func TestPartialRead(t *testing.T) {
 
 func TestIncrementalRead(t *testing.T) {
        test := gnuTarTest
-       f, err := os.Open(test.file, os.O_RDONLY, 0444)
+       f, err := os.Open(test.file)
        if err != nil {
                t.Fatalf("Unexpected error: %v", err)
        }
@@ -235,7 +235,7 @@ func TestIncrementalRead(t *testing.T) {
 
 func TestNonSeekable(t *testing.T) {
        test := gnuTarTest
-       f, err := os.Open(test.file, os.O_RDONLY, 0444)
+       f, err := os.Open(test.file)
        if err != nil {
                t.Fatalf("Unexpected error: %v", err)
        }
index 3b265c9..543007a 100644 (file)
@@ -49,7 +49,7 @@ func (f *File) hasDataDescriptor() bool {
 
 // OpenReader will open the Zip file specified by name and return a Reader.
 func OpenReader(name string) (*Reader, os.Error) {
-       f, err := os.Open(name, os.O_RDONLY, 0644)
+       f, err := os.Open(name)
        if err != nil {
                return nil, err
        }
@@ -73,7 +73,7 @@ func NewReader(r io.ReaderAt, size int64) (*Reader, os.Error) {
                Comment: end.comment,
        }
        rs := io.NewSectionReader(r, 0, size)
-       if _, err = rs.Seek(int64(end.directoryOffset), 0); err != nil {
+       if _, err = rs.Seek(int64(end.directoryOffset), os.SEEK_SET); err != nil {
                return nil, err
        }
        buf := bufio.NewReader(rs)
@@ -94,7 +94,7 @@ func (f *File) Open() (rc io.ReadCloser, err os.Error) {
                if err = readFileHeader(f, r); err != nil {
                        return
                }
-               if f.bodyOffset, err = r.Seek(0, 1); err != nil {
+               if f.bodyOffset, err = r.Seek(0, os.SEEK_CUR); err != nil {
                        return
                }
        }
index eae5c5c..cd08be3 100644 (file)
@@ -415,38 +415,27 @@ func (b *Writer) Buffered() int { return b.n }
 // If nn < len(p), it also returns an error explaining
 // why the write is short.
 func (b *Writer) Write(p []byte) (nn int, err os.Error) {
-       if b.err != nil {
-               return 0, b.err
-       }
-       nn = 0
-       for len(p) > 0 {
-               n := b.Available()
-               if n <= 0 {
-                       if b.Flush(); b.err != nil {
-                               break
-                       }
-                       n = b.Available()
-               }
-               if b.Buffered() == 0 && len(p) >= len(b.buf) {
+       for len(p) > b.Available() && b.err == nil {
+               var n int
+               if b.Buffered() == 0 {
                        // Large write, empty buffer.
                        // Write directly from p to avoid copy.
                        n, b.err = b.wr.Write(p)
-                       nn += n
-                       p = p[n:]
-                       if b.err != nil {
-                               break
-                       }
-                       continue
-               }
-               if n > len(p) {
-                       n = len(p)
+               } else {
+                       n = copy(b.buf[b.n:], p)
+                       b.n += n
+                       b.Flush()
                }
-               copy(b.buf[b.n:b.n+n], p[0:n])
-               b.n += n
                nn += n
                p = p[n:]
        }
-       return nn, b.err
+       if b.err != nil {
+               return nn, b.err
+       }
+       n := copy(b.buf[b.n:], p)
+       b.n += n
+       nn += n
+       return nn, nil
 }
 
 // WriteByte writes a single byte.
@@ -496,24 +485,21 @@ func (b *Writer) WriteRune(rune int) (size int, err os.Error) {
 // If the count is less than len(s), it also returns an error explaining
 // why the write is short.
 func (b *Writer) WriteString(s string) (int, os.Error) {
-       if b.err != nil {
-               return 0, b.err
-       }
-       // Common case, worth making fast.
-       if b.Available() >= len(s) || len(b.buf) >= len(s) && b.Flush() == nil {
-               for i := 0; i < len(s); i++ { // loop over bytes, not runes.
-                       b.buf[b.n] = s[i]
-                       b.n++
-               }
-               return len(s), nil
+       nn := 0
+       for len(s) > b.Available() && b.err == nil {
+               n := copy(b.buf[b.n:], s)
+               b.n += n
+               nn += n
+               s = s[n:]
+               b.Flush()
        }
-       for i := 0; i < len(s); i++ { // loop over bytes, not runes.
-               b.WriteByte(s[i])
-               if b.err != nil {
-                       return i, b.err
-               }
+       if b.err != nil {
+               return nn, b.err
        }
-       return len(s), nil
+       n := copy(b.buf[b.n:], s)
+       b.n += n
+       nn += n
+       return nn, nil
 }
 
 // buffered input and output
index 2e0a8de..e5815a0 100644 (file)
@@ -21,7 +21,7 @@ var filenames = []string{
 // the given options yields equivalent bytes to the original file.
 func testFile(t *testing.T, fn string, order Order, litWidth int) {
        // Read the file, as golden output.
-       golden, err := os.Open(fn, os.O_RDONLY, 0400)
+       golden, err := os.Open(fn)
        if err != nil {
                t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err)
                return
@@ -29,7 +29,7 @@ func testFile(t *testing.T, fn string, order Order, litWidth int) {
        defer golden.Close()
 
        // Read the file again, and push it through a pipe that compresses at the write end, and decompresses at the read end.
-       raw, err := os.Open(fn, os.O_RDONLY, 0400)
+       raw, err := os.Open(fn)
        if err != nil {
                t.Errorf("%s (order=%d litWidth=%d): %v", fn, order, litWidth, err)
                return
index 5a13ba8..7eb1cd4 100644 (file)
@@ -20,7 +20,7 @@ var filenames = []string{
 // yields equivalent bytes to the original file.
 func testFileLevel(t *testing.T, fn string, level int) {
        // Read the file, as golden output.
-       golden, err := os.Open(fn, os.O_RDONLY, 0444)
+       golden, err := os.Open(fn)
        if err != nil {
                t.Errorf("%s (level=%d): %v", fn, level, err)
                return
@@ -28,7 +28,7 @@ func testFileLevel(t *testing.T, fn string, level int) {
        defer golden.Close()
 
        // Read the file again, and push it through a pipe that compresses at the write end, and decompresses at the read end.
-       raw, err := os.Open(fn, os.O_RDONLY, 0444)
+       raw, err := os.Open(fn)
        if err != nil {
                t.Errorf("%s (level=%d): %v", fn, level, err)
                return
diff --git a/libgo/go/crypto/block/cbc.go b/libgo/go/crypto/block/cbc.go
deleted file mode 100644 (file)
index 23229c0..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Cipher block chaining (CBC) mode.
-
-// CBC provides confidentiality by xoring (chaining) each plaintext block
-// with the previous ciphertext block before applying the block cipher.
-
-// See NIST SP 800-38A, pp 10-11
-
-package block
-
-import (
-       "io"
-)
-
-type cbcCipher struct {
-       c         Cipher
-       blockSize int
-       iv        []byte
-       tmp       []byte
-}
-
-func newCBC(c Cipher, iv []byte) *cbcCipher {
-       n := c.BlockSize()
-       x := new(cbcCipher)
-       x.c = c
-       x.blockSize = n
-       x.iv = dup(iv)
-       x.tmp = make([]byte, n)
-       return x
-}
-
-func (x *cbcCipher) BlockSize() int { return x.blockSize }
-
-func (x *cbcCipher) Encrypt(dst, src []byte) {
-       for i := 0; i < x.blockSize; i++ {
-               x.iv[i] ^= src[i]
-       }
-       x.c.Encrypt(x.iv, x.iv)
-       for i := 0; i < x.blockSize; i++ {
-               dst[i] = x.iv[i]
-       }
-}
-
-func (x *cbcCipher) Decrypt(dst, src []byte) {
-       x.c.Decrypt(x.tmp, src)
-       for i := 0; i < x.blockSize; i++ {
-               x.tmp[i] ^= x.iv[i]
-               x.iv[i] = src[i]
-               dst[i] = x.tmp[i]
-       }
-}
-
-// NewCBCDecrypter returns a reader that reads data from r and decrypts it using c
-// in cipher block chaining (CBC) mode with the initialization vector iv.
-// The returned Reader does not buffer or read ahead except
-// as required by the cipher's block size.
-func NewCBCDecrypter(c Cipher, iv []byte, r io.Reader) io.Reader {
-       return NewECBDecrypter(newCBC(c, iv), r)
-}
-
-// NewCBCEncrypter returns a writer that encrypts data using c
-// in cipher block chaining (CBC) mode with the initialization vector iv
-// and writes the encrypted data to w.
-// The returned Writer does no buffering except as required
-// by the cipher's block size, so there is no need for a Flush method.
-func NewCBCEncrypter(c Cipher, iv []byte, w io.Writer) io.Writer {
-       return NewECBEncrypter(newCBC(c, iv), w)
-}
diff --git a/libgo/go/crypto/block/cfb.go b/libgo/go/crypto/block/cfb.go
deleted file mode 100644 (file)
index f20c0a0..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Cipher feedback (CFB) mode.
-
-// CFB provides confidentiality by feeding a fraction of
-// the previous ciphertext in as the plaintext for the next
-// block operation.
-
-// See NIST SP 800-38A, pp 11-13
-
-package block
-
-import (
-       "io"
-)
-
-type cfbCipher struct {
-       c          Cipher
-       blockSize  int // our block size (s/8)
-       cipherSize int // underlying cipher block size
-       iv         []byte
-       tmp        []byte
-}
-
-func newCFB(c Cipher, s int, iv []byte) *cfbCipher {
-       if s == 0 || s%8 != 0 {
-               panic("crypto/block: invalid CFB mode")
-       }
-       b := c.BlockSize()
-       x := new(cfbCipher)
-       x.c = c
-       x.blockSize = s / 8
-       x.cipherSize = b
-       x.iv = dup(iv)
-       x.tmp = make([]byte, b)
-       return x
-}
-
-func (x *cfbCipher) BlockSize() int { return x.blockSize }
-
-func (x *cfbCipher) Encrypt(dst, src []byte) {
-       // Encrypt old IV and xor prefix with src to make dst.
-       x.c.Encrypt(x.tmp, x.iv)
-       for i := 0; i < x.blockSize; i++ {
-               dst[i] = src[i] ^ x.tmp[i]
-       }
-
-       // Slide unused IV pieces down and insert dst at end.
-       for i := 0; i < x.cipherSize-x.blockSize; i++ {
-               x.iv[i] = x.iv[i+x.blockSize]
-       }
-       off := x.cipherSize - x.blockSize
-       for i := off; i < x.cipherSize; i++ {
-               x.iv[i] = dst[i-off]
-       }
-}
-
-func (x *cfbCipher) Decrypt(dst, src []byte) {
-       // Encrypt [sic] old IV and xor prefix with src to make dst.
-       x.c.Encrypt(x.tmp, x.iv)
-       for i := 0; i < x.blockSize; i++ {
-               dst[i] = src[i] ^ x.tmp[i]
-       }
-
-       // Slide unused IV pieces down and insert src at top.
-       for i := 0; i < x.cipherSize-x.blockSize; i++ {
-               x.iv[i] = x.iv[i+x.blockSize]
-       }
-       off := x.cipherSize - x.blockSize
-       for i := off; i < x.cipherSize; i++ {
-               // Reconstruct src = dst ^ x.tmp
-               // in case we overwrote src (src == dst).
-               x.iv[i] = dst[i-off] ^ x.tmp[i-off]
-       }
-}
-
-// NewCFBDecrypter returns a reader that reads data from r and decrypts it using c
-// in s-bit cipher feedback (CFB) mode with the initialization vector iv.
-// The returned Reader does not buffer or read ahead except
-// as required by the cipher's block size.
-// Modes for s not a multiple of 8 are unimplemented.
-func NewCFBDecrypter(c Cipher, s int, iv []byte, r io.Reader) io.Reader {
-       return NewECBDecrypter(newCFB(c, s, iv), r)
-}
-
-// NewCFBEncrypter returns a writer that encrypts data using c
-// in s-bit cipher feedback (CFB) mode with the initialization vector iv
-// and writes the encrypted data to w.
-// The returned Writer does no buffering except as required
-// by the cipher's block size, so there is no need for a Flush method.
-// Modes for s not a multiple of 8 are unimplemented.
-func NewCFBEncrypter(c Cipher, s int, iv []byte, w io.Writer) io.Writer {
-       return NewECBEncrypter(newCFB(c, s, iv), w)
-}
diff --git a/libgo/go/crypto/block/cfb_aes_test.go b/libgo/go/crypto/block/cfb_aes_test.go
deleted file mode 100644 (file)
index e400c18..0000000
+++ /dev/null
@@ -1,311 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// CFB AES test vectors.
-
-// See U.S. National Institute of Standards and Technology (NIST)
-// Special Publication 800-38A, ``Recommendation for Block Cipher
-// Modes of Operation,'' 2001 Edition, pp. 29-52.
-
-package block
-
-import (
-       "bytes"
-       "crypto/aes"
-       "io"
-       "testing"
-)
-
-type cfbTest struct {
-       name string
-       s    int
-       key  []byte
-       iv   []byte
-       in   []byte
-       out  []byte
-}
-
-var cfbAESTests = []cfbTest{
-       {
-               "CFB1-AES128",
-               1,
-               commonKey128,
-               commonIV,
-               []byte{
-                       0<<7 | 1<<6 | 1<<5 | 0<<4 | 1<<3 | 0<<2 | 1<<1,
-                       1<<7 | 1<<6 | 0<<5 | 0<<4 | 0<<3 | 0<<2 | 0<<1,
-               },
-               []byte{
-                       0<<7 | 1<<6 | 1<<5 | 0<<4 | 1<<3 | 0<<2 | 0<<1,
-                       1<<7 | 0<<6 | 1<<5 | 1<<4 | 0<<3 | 0<<2 | 1<<1,
-               },
-       },
-       {
-               "CFB1-AES192",
-               1,
-               commonKey192,
-               commonIV,
-               []byte{
-                       0<<7 | 1<<6 | 1<<5 | 0<<4 | 1<<3 | 0<<2 | 1<<1,
-                       1<<7 | 1<<6 | 0<<5 | 0<<4 | 0<<3 | 0<<2 | 0<<1,
-               },
-               []byte{
-                       1<<7 | 0<<6 | 0<<5 | 1<<4 | 0<<3 | 0<<2 | 1<<1,
-                       0<<7 | 1<<6 | 0<<5 | 1<<4 | 1<<3 | 0<<2 | 0<<1,
-               },
-       },
-       {
-               "CFB1-AES256",
-               1,
-               commonKey256,
-               commonIV,
-               []byte{
-                       0<<7 | 1<<6 | 1<<5 | 0<<4 | 1<<3 | 0<<2 | 1<<1,
-                       1<<7 | 1<<6 | 0<<5 | 0<<4 | 0<<3 | 0<<2 | 0<<1,
-               },
-               []byte{
-                       1<<7 | 0<<6 | 0<<5 | 1<<4 | 0<<3 | 0<<2 | 0<<1,
-                       0<<7 | 0<<6 | 1<<5 | 0<<4 | 1<<3 | 0<<2 | 0<<1,
-               },
-       },
-
-       {
-               "CFB8-AES128",
-               8,
-               commonKey128,
-               commonIV,
-               []byte{
-                       0x6b,
-                       0xc1,
-                       0xbe,
-                       0xe2,
-                       0x2e,
-                       0x40,
-                       0x9f,
-                       0x96,
-                       0xe9,
-                       0x3d,
-                       0x7e,
-                       0x11,
-                       0x73,
-                       0x93,
-                       0x17,
-                       0x2a,
-                       0xae,
-                       0x2d,
-               },
-               []byte{
-                       0x3b,
-                       0x79,
-                       0x42,
-                       0x4c,
-                       0x9c,
-                       0x0d,
-                       0xd4,
-                       0x36,
-                       0xba,
-                       0xce,
-                       0x9e,
-                       0x0e,
-                       0xd4,
-                       0x58,
-                       0x6a,
-                       0x4f,
-                       0x32,
-                       0xb9,
-               },
-       },
-
-       {
-               "CFB8-AES192",
-               8,
-               commonKey192,
-               commonIV,
-               []byte{
-                       0x6b,
-                       0xc1,
-                       0xbe,
-                       0xe2,
-                       0x2e,
-                       0x40,
-                       0x9f,
-                       0x96,
-                       0xe9,
-                       0x3d,
-                       0x7e,
-                       0x11,
-                       0x73,
-                       0x93,
-                       0x17,
-                       0x2a,
-                       0xae,
-                       0x2d,
-               },
-               []byte{
-                       0xcd,
-                       0xa2,
-                       0x52,
-                       0x1e,
-                       0xf0,
-                       0xa9,
-                       0x05,
-                       0xca,
-                       0x44,
-                       0xcd,
-                       0x05,
-                       0x7c,
-                       0xbf,
-                       0x0d,
-                       0x47,
-                       0xa0,
-                       0x67,
-                       0x8a,
-               },
-       },
-
-       {
-               "CFB8-AES256",
-               8,
-               commonKey256,
-               commonIV,
-               []byte{
-                       0x6b,
-                       0xc1,
-                       0xbe,
-                       0xe2,
-                       0x2e,
-                       0x40,
-                       0x9f,
-                       0x96,
-                       0xe9,
-                       0x3d,
-                       0x7e,
-                       0x11,
-                       0x73,
-                       0x93,
-                       0x17,
-                       0x2a,
-                       0xae,
-                       0x2d,
-               },
-               []byte{
-                       0xdc,
-                       0x1f,
-                       0x1a,
-                       0x85,
-                       0x20,
-                       0xa6,
-                       0x4d,
-                       0xb5,
-                       0x5f,
-                       0xcc,
-                       0x8a,
-                       0xc5,
-                       0x54,
-                       0x84,
-                       0x4e,
-                       0x88,
-                       0x97,
-                       0x00,
-               },
-       },
-
-       {
-               "CFB128-AES128",
-               128,
-               commonKey128,
-               commonIV,
-               []byte{
-                       0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
-                       0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
-                       0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
-                       0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10,
-               },
-               []byte{
-                       0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20, 0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a,
-                       0xc8, 0xa6, 0x45, 0x37, 0xa0, 0xb3, 0xa9, 0x3f, 0xcd, 0xe3, 0xcd, 0xad, 0x9f, 0x1c, 0xe5, 0x8b,
-                       0x26, 0x75, 0x1f, 0x67, 0xa3, 0xcb, 0xb1, 0x40, 0xb1, 0x80, 0x8c, 0xf1, 0x87, 0xa4, 0xf4, 0xdf,
-                       0xc0, 0x4b, 0x05, 0x35, 0x7c, 0x5d, 0x1c, 0x0e, 0xea, 0xc4, 0xc6, 0x6f, 0x9f, 0xf7, 0xf2, 0xe6,
-               },
-       },
-
-       {
-               "CFB128-AES192",
-               128,
-               commonKey192,
-               commonIV,
-               []byte{
-                       0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
-                       0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
-                       0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
-                       0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10,
-               },
-               []byte{
-                       0xcd, 0xc8, 0x0d, 0x6f, 0xdd, 0xf1, 0x8c, 0xab, 0x34, 0xc2, 0x59, 0x09, 0xc9, 0x9a, 0x41, 0x74,
-                       0x67, 0xce, 0x7f, 0x7f, 0x81, 0x17, 0x36, 0x21, 0x96, 0x1a, 0x2b, 0x70, 0x17, 0x1d, 0x3d, 0x7a,
-                       0x2e, 0x1e, 0x8a, 0x1d, 0xd5, 0x9b, 0x88, 0xb1, 0xc8, 0xe6, 0x0f, 0xed, 0x1e, 0xfa, 0xc4, 0xc9,
-                       0xc0, 0x5f, 0x9f, 0x9c, 0xa9, 0x83, 0x4f, 0xa0, 0x42, 0xae, 0x8f, 0xba, 0x58, 0x4b, 0x09, 0xff,
-               },
-       },
-
-       {
-               "CFB128-AES256",
-               128,
-               commonKey256,
-               commonIV,
-               []byte{
-                       0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
-                       0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
-                       0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
-                       0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10,
-               },
-               []byte{
-                       0xdc, 0x7e, 0x84, 0xbf, 0xda, 0x79, 0x16, 0x4b, 0x7e, 0xcd, 0x84, 0x86, 0x98, 0x5d, 0x38, 0x60,
-                       0x39, 0xff, 0xed, 0x14, 0x3b, 0x28, 0xb1, 0xc8, 0x32, 0x11, 0x3c, 0x63, 0x31, 0xe5, 0x40, 0x7b,
-                       0xdf, 0x10, 0x13, 0x24, 0x15, 0xe5, 0x4b, 0x92, 0xa1, 0x3e, 0xd0, 0xa8, 0x26, 0x7a, 0xe2, 0xf9,
-                       0x75, 0xa3, 0x85, 0x74, 0x1a, 0xb9, 0xce, 0xf8, 0x20, 0x31, 0x62, 0x3d, 0x55, 0xb1, 0xe4, 0x71,
-               },
-       },
-}
-
-func TestCFB_AES(t *testing.T) {
-       for _, tt := range cfbAESTests {
-               test := tt.name
-
-               if tt.s == 1 {
-                       // 1-bit CFB not implemented
-                       continue
-               }
-
-               c, err := aes.NewCipher(tt.key)
-               if err != nil {
-                       t.Errorf("%s: NewCipher(%d bytes) = %s", test, len(tt.key), err)
-                       continue
-               }
-
-               var crypt bytes.Buffer
-               w := NewCFBEncrypter(c, tt.s, tt.iv, &crypt)
-               var r io.Reader = bytes.NewBuffer(tt.in)
-               n, err := io.Copy(w, r)
-               if n != int64(len(tt.in)) || err != nil {
-                       t.Errorf("%s: CFBEncrypter io.Copy = %d, %v want %d, nil", test, n, err, len(tt.in))
-               } else if d := crypt.Bytes(); !same(tt.out, d) {
-                       t.Errorf("%s: CFBEncrypter\nhave %x\nwant %x", test, d, tt.out)
-               }
-
-               var plain bytes.Buffer
-               r = NewCFBDecrypter(c, tt.s, tt.iv, bytes.NewBuffer(tt.out))
-               w = &plain
-               n, err = io.Copy(w, r)
-               if n != int64(len(tt.out)) || err != nil {
-                       t.Errorf("%s: CFBDecrypter io.Copy = %d, %v want %d, nil", test, n, err, len(tt.out))
-               } else if d := plain.Bytes(); !same(tt.in, d) {
-                       t.Errorf("%s: CFBDecrypter\nhave %x\nwant %x", test, d, tt.in)
-               }
-
-               if t.Failed() {
-                       break
-               }
-       }
-}
diff --git a/libgo/go/crypto/block/cipher.go b/libgo/go/crypto/block/cipher.go
deleted file mode 100644 (file)
index e1099e9..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// The block package is deprecated, use cipher instead.
-// The block package implements standard block cipher modes
-// that can be wrapped around low-level block cipher implementations.
-// See http://csrc.nist.gov/groups/ST/toolkit/BCM/current_modes.html
-// and NIST Special Publication 800-38A.
-package block
-
-// A Cipher represents an implementation of block cipher
-// using a given key.  It provides the capability to encrypt
-// or decrypt individual blocks.  The mode implementations
-// extend that capability to streams of blocks.
-type Cipher interface {
-       // BlockSize returns the cipher's block size.
-       BlockSize() int
-
-       // Encrypt encrypts the first block in src into dst.
-       // Src and dst may point at the same memory.
-       Encrypt(dst, src []byte)
-
-       // Decrypt decrypts the first block in src into dst.
-       // Src and dst may point at the same memory.
-       Decrypt(dst, src []byte)
-}
-
-// Utility routines
-
-func shift1(dst, src []byte) byte {
-       var b byte
-       for i := len(src) - 1; i >= 0; i-- {
-               bb := src[i] >> 7
-               dst[i] = src[i]<<1 | b
-               b = bb
-       }
-       return b
-}
-
-func same(p, q []byte) bool {
-       if len(p) != len(q) {
-               return false
-       }
-       for i := 0; i < len(p); i++ {
-               if p[i] != q[i] {
-                       return false
-               }
-       }
-       return true
-}
-
-func dup(p []byte) []byte {
-       q := make([]byte, len(p))
-       copy(q, p)
-       return q
-}
diff --git a/libgo/go/crypto/block/cmac.go b/libgo/go/crypto/block/cmac.go
deleted file mode 100644 (file)
index b85cde7..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// CMAC message authentication code, defined in
-// NIST Special Publication SP 800-38B.
-
-package block
-
-import (
-       "hash"
-       "os"
-)
-
-const (
-       // minimal irreducible polynomial of degree b
-       r64  = 0x1b
-       r128 = 0x87
-)
-
-type cmac struct {
-       k1, k2, ci, digest []byte
-       p                  int // position in ci
-       c                  Cipher
-}
-
-// TODO(rsc): Should this return an error instead of panic?
-
-// NewCMAC returns a new instance of a CMAC message authentication code
-// digest using the given Cipher.
-func NewCMAC(c Cipher) hash.Hash {
-       var r byte
-       n := c.BlockSize()
-       switch n {
-       case 64 / 8:
-               r = r64
-       case 128 / 8:
-               r = r128
-       default:
-               panic("crypto/block: NewCMAC: invalid cipher block size")
-       }
-
-       d := new(cmac)
-       d.c = c
-       d.k1 = make([]byte, n)
-       d.k2 = make([]byte, n)
-       d.ci = make([]byte, n)
-       d.digest = make([]byte, n)
-
-       // Subkey generation, p. 7
-       c.Encrypt(d.k1, d.k1)
-       if shift1(d.k1, d.k1) != 0 {
-               d.k1[n-1] ^= r
-       }
-       if shift1(d.k2, d.k1) != 0 {
-               d.k2[n-1] ^= r
-       }
-
-       return d
-}
-
-// Reset clears the digest state, starting a new digest.
-func (d *cmac) Reset() {
-       for i := range d.ci {
-               d.ci[i] = 0
-       }
-       d.p = 0
-}
-
-// Write adds the given data to the digest state.
-func (d *cmac) Write(p []byte) (n int, err os.Error) {
-       // Xor input into ci.
-       for _, c := range p {
-               // If ci is full, encrypt and start over.
-               if d.p >= len(d.ci) {
-                       d.c.Encrypt(d.ci, d.ci)
-                       d.p = 0
-               }
-               d.ci[d.p] ^= c
-               d.p++
-       }
-       return len(p), nil
-}
-
-// Sum returns the CMAC digest, one cipher block in length,
-// of the data written with Write.
-func (d *cmac) Sum() []byte {
-       // Finish last block, mix in key, encrypt.
-       // Don't edit ci, in case caller wants
-       // to keep digesting after call to Sum.
-       k := d.k1
-       if d.p < len(d.digest) {
-               k = d.k2
-       }
-       for i := 0; i < len(d.ci); i++ {
-               d.digest[i] = d.ci[i] ^ k[i]
-       }
-       if d.p < len(d.digest) {
-               d.digest[d.p] ^= 0x80
-       }
-       d.c.Encrypt(d.digest, d.digest)
-       return d.digest
-}
-
-func (d *cmac) Size() int { return len(d.digest) }
diff --git a/libgo/go/crypto/block/cmac_aes_test.go b/libgo/go/crypto/block/cmac_aes_test.go
deleted file mode 100644 (file)
index 0a4a1a4..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// CMAC test vectors.  See NIST SP 800-38B, Appendix D.
-
-package block
-
-import (
-       "crypto/aes"
-       "testing"
-)
-
-type cmacAESTest struct {
-       key    []byte
-       in     []byte
-       digest []byte
-}
-
-var cmacAESTests = []cmacAESTest{
-       {
-               commonKey128,
-               nil,
-               []byte{0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28, 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46},
-       },
-       {
-               commonKey128,
-               []byte{0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a},
-               []byte{0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44, 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c},
-       },
-       {
-               commonKey128,
-               []byte{
-                       0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
-                       0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
-                       0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
-               },
-               []byte{0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30, 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27},
-       },
-       {
-               commonKey128,
-               []byte{
-                       0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
-                       0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
-                       0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
-                       0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10,
-               },
-               []byte{0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92, 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe},
-       },
-       {
-               commonKey192,
-               nil,
-               []byte{0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5, 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67},
-       },
-       {
-               commonKey192,
-               []byte{0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a},
-               []byte{0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90, 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84},
-       },
-       {
-               commonKey192,
-               []byte{
-                       0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
-                       0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
-                       0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
-               },
-               []byte{0x8a, 0x1d, 0xe5, 0xbe, 0x2e, 0xb3, 0x1a, 0xad, 0x08, 0x9a, 0x82, 0xe6, 0xee, 0x90, 0x8b, 0x0e},
-       },
-       {
-               commonKey192,
-               []byte{
-                       0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
-                       0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
-                       0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
-                       0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10,
-               },
-               []byte{0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79, 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11},
-       },
-       {
-               commonKey256,
-               nil,
-               []byte{0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e, 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83},
-       },
-       {
-               commonKey256,
-               []byte{0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a},
-               []byte{0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82, 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c},
-       },
-       {
-               commonKey256,
-               []byte{
-                       0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
-                       0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
-                       0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
-               },
-               []byte{0xaa, 0xf3, 0xd8, 0xf1, 0xde, 0x56, 0x40, 0xc2, 0x32, 0xf5, 0xb1, 0x69, 0xb9, 0xc9, 0x11, 0xe6},
-       },
-       {
-               commonKey256,
-               []byte{
-                       0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
-                       0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
-                       0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
-                       0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10,
-               },
-               []byte{0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5, 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10},
-       },
-}
-
-func TestCMAC_AES(t *testing.T) {
-       for i, tt := range cmacAESTests {
-               c, err := aes.NewCipher(tt.key)
-               if err != nil {
-                       t.Errorf("test %d: NewCipher: %s", i, err)
-                       continue
-               }
-               d := NewCMAC(c)
-               n, err := d.Write(tt.in)
-               if err != nil || n != len(tt.in) {
-                       t.Errorf("test %d: Write %d: %d, %s", i, len(tt.in), n, err)
-                       continue
-               }
-               sum := d.Sum()
-               if !same(sum, tt.digest) {
-                       x := d.(*cmac)
-                       t.Errorf("test %d: digest mismatch\n\twant %x\n\thave %x\n\tk1 %x\n\tk2 %x", i, tt.digest, sum, x.k1, x.k2)
-                       continue
-               }
-       }
-}
diff --git a/libgo/go/crypto/block/ctr.go b/libgo/go/crypto/block/ctr.go
deleted file mode 100644 (file)
index 5d65c0c..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Counter (CTR) mode.
-
-// CTR converts a block cipher into a stream cipher by
-// repeatedly encrypting an incrementing counter and
-// xoring the resulting stream of data with the input.
-
-// See NIST SP 800-38A, pp 13-15
-
-package block
-
-import (
-       "io"
-)
-
-type ctrStream struct {
-       c   Cipher
-       ctr []byte
-       out []byte
-}
-
-func newCTRStream(c Cipher, ctr []byte) *ctrStream {
-       x := new(ctrStream)
-       x.c = c
-       x.ctr = dup(ctr)
-       x.out = make([]byte, len(ctr))
-       return x
-}
-
-func (x *ctrStream) Next() []byte {
-       // Next block is encryption of counter.
-       x.c.Encrypt(x.out, x.ctr)
-
-       // Increment counter
-       for i := len(x.ctr) - 1; i >= 0; i-- {
-               x.ctr[i]++
-               if x.ctr[i] != 0 {
-                       break
-               }
-       }
-
-       return x.out
-}
-
-// NewCTRReader returns a reader that reads data from r, decrypts (or encrypts)
-// it using c in counter (CTR) mode with the initialization vector iv.
-// The returned Reader does not buffer and has no block size.
-// In CTR mode, encryption and decryption are the same operation:
-// a CTR reader applied to an encrypted stream produces a decrypted
-// stream and vice versa.
-func NewCTRReader(c Cipher, iv []byte, r io.Reader) io.Reader {
-       return newXorReader(newCTRStream(c, iv), r)
-}
-
-// NewCTRWriter returns a writer that encrypts (or decrypts) data using c
-// in counter (CTR) mode with the initialization vector iv
-// and writes the encrypted data to w.
-// The returned Writer does not buffer and has no block size.
-// In CTR mode, encryption and decryption are the same operation:
-// a CTR writer applied to an decrypted stream produces an encrypted
-// stream and vice versa.
-func NewCTRWriter(c Cipher, iv []byte, w io.Writer) io.Writer {
-       return newXorWriter(newCTRStream(c, iv), w)
-}
diff --git a/libgo/go/crypto/block/eax.go b/libgo/go/crypto/block/eax.go
deleted file mode 100644 (file)
index 3f3b964..0000000
+++ /dev/null
@@ -1,253 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// EAX mode, not a NIST standard (yet).
-// EAX provides encryption and authentication.
-// EAX targets the same uses as NIST's CCM mode,
-// but EAX adds the ability to run in streaming mode.
-
-// See
-// http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/eax/eax-spec.pdf
-// http://www.cs.ucdavis.edu/~rogaway/papers/eax.pdf
-// What those papers call OMAC is now called CMAC.
-
-package block
-
-import (
-       "fmt"
-       "hash"
-       "io"
-       "os"
-)
-
-// An EAXTagError is returned when the message has failed to authenticate,
-// because the tag at the end of the message stream (Read) does not match
-// the tag computed from the message itself (Computed).
-type EAXTagError struct {
-       Read     []byte
-       Computed []byte
-}
-
-func (e *EAXTagError) String() string {
-       return fmt.Sprintf("crypto/block: EAX tag mismatch: read %x but computed %x", e.Read, e.Computed)
-}
-
-func setupEAX(c Cipher, iv, hdr []byte, tagBytes int) (ctrIV, tag []byte, cmac hash.Hash) {
-       n := len(iv)
-       if n != c.BlockSize() {
-               panic(fmt.Sprintln("crypto/block: EAX: iv length", n, "!=", c.BlockSize()))
-       }
-       buf := make([]byte, n) // zeroed
-
-       // tag = CMAC(0 + iv) ^ CMAC(1 + hdr) ^ CMAC(2 + data)
-       cmac = NewCMAC(c)
-       cmac.Write(buf) // 0
-       cmac.Write(iv)
-       sum := cmac.Sum()
-       ctrIV = dup(sum)
-       tag = dup(sum[0:tagBytes])
-
-       cmac.Reset()
-       buf[n-1] = 1
-       cmac.Write(buf) // 1
-       cmac.Write(hdr)
-       sum = cmac.Sum()
-       for i := 0; i < tagBytes; i++ {
-               tag[i] ^= sum[i]
-       }
-
-       cmac.Reset()
-       buf[n-1] = 2 // 2
-       cmac.Write(buf)
-
-       return
-}
-
-func finishEAX(tag []byte, cmac hash.Hash) {
-       // Finish CMAC #2 and xor into tag.
-       sum := cmac.Sum()
-       for i := range tag {
-               tag[i] ^= sum[i]
-       }
-}
-
-// Writer adapter.  Tees writes into both w and cmac.
-// Knows that cmac never returns write errors.
-type cmacWriter struct {
-       w    io.Writer
-       cmac hash.Hash
-}
-
-func (cw *cmacWriter) Write(p []byte) (n int, err os.Error) {
-       n, err = cw.w.Write(p)
-       cw.cmac.Write(p[0:n])
-       return
-}
-
-// An eaxEncrypter implements the EAX encryption mode.
-type eaxEncrypter struct {
-       ctr io.Writer  // CTR encrypter
-       cw  cmacWriter // CTR's output stream
-       tag []byte
-}
-
-// NewEAXEncrypter creates and returns a new EAX encrypter
-// using the given cipher c, initialization vector iv, associated data hdr,
-// and tag length tagBytes.  The encrypter's Write method encrypts
-// the data it receives and writes that data to w.
-// The encrypter's Close method writes a final authenticating tag to w.
-func NewEAXEncrypter(c Cipher, iv []byte, hdr []byte, tagBytes int, w io.Writer) io.WriteCloser {
-       x := new(eaxEncrypter)
-
-       // Create new CTR instance writing to both
-       // w for encrypted output and cmac for digesting.
-       x.cw.w = w
-       var ctrIV []byte
-       ctrIV, x.tag, x.cw.cmac = setupEAX(c, iv, hdr, tagBytes)
-       x.ctr = NewCTRWriter(c, ctrIV, &x.cw)
-       return x
-}
-
-func (x *eaxEncrypter) Write(p []byte) (n int, err os.Error) {
-       return x.ctr.Write(p)
-}
-
-func (x *eaxEncrypter) Close() os.Error {
-       x.ctr = nil // crash if Write is called again
-
-       // Write tag.
-       finishEAX(x.tag, x.cw.cmac)
-       n, err := x.cw.w.Write(x.tag)
-       if n != len(x.tag) && err == nil {
-               err = io.ErrShortWrite
-       }
-
-       return err
-}
-
-// Reader adapter.  Returns data read from r but hangs
-// on to the last len(tag) bytes for itself (returns EOF len(tag)
-// bytes early).  Also tees all data returned from Read into
-// the cmac digest.  The "don't return the last t bytes"
-// and the "tee into digest" functionality could be separated,
-// but the latter half is trivial.
-type cmacReader struct {
-       r    io.Reader
-       cmac hash.Hash
-       tag  []byte
-       tmp  []byte
-}
-
-func (cr *cmacReader) Read(p []byte) (n int, err os.Error) {
-       // TODO(rsc): Maybe fall back to simpler code if
-       // we recognize the underlying r as a ByteBuffer
-       // or ByteReader.  Then we can just take the last piece
-       // off at the start.
-
-       // First, read a tag-sized chunk.
-       // It's probably not the tag (unless there's no data).
-       tag := cr.tag
-       if len(tag) < cap(tag) {
-               nt := len(tag)
-               nn, err1 := io.ReadFull(cr.r, tag[nt:cap(tag)])
-               tag = tag[0 : nt+nn]
-               cr.tag = tag
-               if err1 != nil {
-                       return 0, err1
-               }
-       }
-
-       tagBytes := len(tag)
-       if len(p) > 4*tagBytes {
-               // If p is big, try to read directly into p to avoid a copy.
-               n, err = cr.r.Read(p[tagBytes:])
-               if n == 0 {
-                       goto out
-               }
-               // copy old tag into p
-               for i := 0; i < tagBytes; i++ {
-                       p[i] = tag[i]
-               }
-               // copy new tag out of p
-               for i := 0; i < tagBytes; i++ {
-                       tag[i] = p[n+i]
-               }
-               goto out
-       }
-
-       // Otherwise, read into p and then slide data
-       n, err = cr.r.Read(p)
-       if n == 0 {
-               goto out
-       }
-
-       // copy tag+p into p+tmp and then swap tmp, tag
-       tmp := cr.tmp
-       for i := n + tagBytes - 1; i >= 0; i-- {
-               var c byte
-               if i < tagBytes {
-                       c = tag[i]
-               } else {
-                       c = p[i-tagBytes]
-               }
-               if i < n {
-                       p[i] = c
-               } else {
-                       tmp[i] = c
-               }
-       }
-       cr.tmp, cr.tag = tag, tmp
-
-out:
-       cr.cmac.Write(p[0:n])
-       return
-}
-
-type eaxDecrypter struct {
-       ctr io.Reader
-       cr  cmacReader
-       tag []byte
-}
-
-// NewEAXDecrypter creates and returns a new EAX decrypter
-// using the given cipher c, initialization vector iv, associated data hdr,
-// and tag length tagBytes.  The encrypter's Read method decrypts and
-// returns data read from r.  At r's EOF, the encrypter checks the final
-// authenticating tag and returns an EAXTagError if the tag is invalid.
-// In that case, the message should be discarded.
-// Note that the data stream returned from Read cannot be
-// assumed to be valid, authenticated data until Read returns
-// 0, nil to signal the end of the data.
-func NewEAXDecrypter(c Cipher, iv []byte, hdr []byte, tagBytes int, r io.Reader) io.Reader {
-       x := new(eaxDecrypter)
-
-       x.cr.r = r
-       x.cr.tag = make([]byte, 0, tagBytes)
-       x.cr.tmp = make([]byte, 0, tagBytes)
-       var ctrIV []byte
-       ctrIV, x.tag, x.cr.cmac = setupEAX(c, iv, hdr, tagBytes)
-       x.ctr = NewCTRReader(c, ctrIV, &x.cr)
-       return x
-}
-
-func (x *eaxDecrypter) checkTag() os.Error {
-       x.ctr = nil // crash if Read is called again
-
-       finishEAX(x.tag, x.cr.cmac)
-       if !same(x.tag, x.cr.tag) {
-               e := new(EAXTagError)
-               e.Computed = dup(x.tag)
-               e.Read = dup(x.cr.tag)
-               return e
-       }
-       return nil
-}
-
-func (x *eaxDecrypter) Read(p []byte) (n int, err os.Error) {
-       n, err = x.ctr.Read(p)
-       if n == 0 && err == nil {
-               err = x.checkTag()
-       }
-       return n, err
-}
diff --git a/libgo/go/crypto/block/eax_aes_test.go b/libgo/go/crypto/block/eax_aes_test.go
deleted file mode 100644 (file)
index 93aa771..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package block
-
-import (
-       "bytes"
-       "crypto/aes"
-       "fmt"
-       "io"
-       "testing"
-)
-
-// Test vectors from http://www.cs.ucdavis.edu/~rogaway/papers/eax.pdf
-
-type eaxAESTest struct {
-       msg    []byte
-       key    []byte
-       nonce  []byte
-       header []byte
-       cipher []byte
-}
-
-var eaxAESTests = []eaxAESTest{
-       {
-               []byte{},
-               []byte{0x23, 0x39, 0x52, 0xDE, 0xE4, 0xD5, 0xED, 0x5F, 0x9B, 0x9C, 0x6D, 0x6F, 0xF8, 0x0F, 0xF4, 0x78},
-               []byte{0x62, 0xEC, 0x67, 0xF9, 0xC3, 0xA4, 0xA4, 0x07, 0xFC, 0xB2, 0xA8, 0xC4, 0x90, 0x31, 0xA8, 0xB3},
-               []byte{0x6B, 0xFB, 0x91, 0x4F, 0xD0, 0x7E, 0xAE, 0x6B},
-               []byte{0xE0, 0x37, 0x83, 0x0E, 0x83, 0x89, 0xF2, 0x7B, 0x02, 0x5A, 0x2D, 0x65, 0x27, 0xE7, 0x9D, 0x01},
-       },
-       {
-               []byte{0xF7, 0xFB},
-               []byte{0x91, 0x94, 0x5D, 0x3F, 0x4D, 0xCB, 0xEE, 0x0B, 0xF4, 0x5E, 0xF5, 0x22, 0x55, 0xF0, 0x95, 0xA4},
-               []byte{0xBE, 0xCA, 0xF0, 0x43, 0xB0, 0xA2, 0x3D, 0x84, 0x31, 0x94, 0xBA, 0x97, 0x2C, 0x66, 0xDE, 0xBD},
-               []byte{0xFA, 0x3B, 0xFD, 0x48, 0x06, 0xEB, 0x53, 0xFA},
-               []byte{0x19, 0xDD, 0x5C, 0x4C, 0x93, 0x31, 0x04, 0x9D, 0x0B, 0xDA, 0xB0, 0x27, 0x74, 0x08, 0xF6, 0x79, 0x67, 0xE5},
-       },
-       {
-               []byte{0x1A, 0x47, 0xCB, 0x49, 0x33},
-               []byte{0x01, 0xF7, 0x4A, 0xD6, 0x40, 0x77, 0xF2, 0xE7, 0x04, 0xC0, 0xF6, 0x0A, 0xDA, 0x3D, 0xD5, 0x23},
-               []byte{0x70, 0xC3, 0xDB, 0x4F, 0x0D, 0x26, 0x36, 0x84, 0x00, 0xA1, 0x0E, 0xD0, 0x5D, 0x2B, 0xFF, 0x5E},
-               []byte{0x23, 0x4A, 0x34, 0x63, 0xC1, 0x26, 0x4A, 0xC6},
-               []byte{0xD8, 0x51, 0xD5, 0xBA, 0xE0, 0x3A, 0x59, 0xF2, 0x38, 0xA2, 0x3E, 0x39, 0x19, 0x9D, 0xC9, 0x26, 0x66, 0x26, 0xC4, 0x0F, 0x80},
-       },
-       {
-               []byte{0x48, 0x1C, 0x9E, 0x39, 0xB1},
-               []byte{0xD0, 0x7C, 0xF6, 0xCB, 0xB7, 0xF3, 0x13, 0xBD, 0xDE, 0x66, 0xB7, 0x27, 0xAF, 0xD3, 0xC5, 0xE8},
-               []byte{0x84, 0x08, 0xDF, 0xFF, 0x3C, 0x1A, 0x2B, 0x12, 0x92, 0xDC, 0x19, 0x9E, 0x46, 0xB7, 0xD6, 0x17},
-               []byte{0x33, 0xCC, 0xE2, 0xEA, 0xBF, 0xF5, 0xA7, 0x9D},
-               []byte{0x63, 0x2A, 0x9D, 0x13, 0x1A, 0xD4, 0xC1, 0x68, 0xA4, 0x22, 0x5D, 0x8E, 0x1F, 0xF7, 0x55, 0x93, 0x99, 0x74, 0xA7, 0xBE, 0xDE},
-       },
-       {
-               []byte{0x40, 0xD0, 0xC0, 0x7D, 0xA5, 0xE4},
-               []byte{0x35, 0xB6, 0xD0, 0x58, 0x00, 0x05, 0xBB, 0xC1, 0x2B, 0x05, 0x87, 0x12, 0x45, 0x57, 0xD2, 0xC2},
-               []byte{0xFD, 0xB6, 0xB0, 0x66, 0x76, 0xEE, 0xDC, 0x5C, 0x61, 0xD7, 0x42, 0x76, 0xE1, 0xF8, 0xE8, 0x16},
-               []byte{0xAE, 0xB9, 0x6E, 0xAE, 0xBE, 0x29, 0x70, 0xE9},
-               []byte{0x07, 0x1D, 0xFE, 0x16, 0xC6, 0x75, 0xCB, 0x06, 0x77, 0xE5, 0x36, 0xF7, 0x3A, 0xFE, 0x6A, 0x14, 0xB7, 0x4E, 0xE4, 0x98, 0x44, 0xDD},
-       },
-       {
-               []byte{0x4D, 0xE3, 0xB3, 0x5C, 0x3F, 0xC0, 0x39, 0x24, 0x5B, 0xD1, 0xFB, 0x7D},
-               []byte{0xBD, 0x8E, 0x6E, 0x11, 0x47, 0x5E, 0x60, 0xB2, 0x68, 0x78, 0x4C, 0x38, 0xC6, 0x2F, 0xEB, 0x22},
-               []byte{0x6E, 0xAC, 0x5C, 0x93, 0x07, 0x2D, 0x8E, 0x85, 0x13, 0xF7, 0x50, 0x93, 0x5E, 0x46, 0xDA, 0x1B},
-               []byte{0xD4, 0x48, 0x2D, 0x1C, 0xA7, 0x8D, 0xCE, 0x0F},
-               []byte{0x83, 0x5B, 0xB4, 0xF1, 0x5D, 0x74, 0x3E, 0x35, 0x0E, 0x72, 0x84, 0x14, 0xAB, 0xB8, 0x64, 0x4F, 0xD6, 0xCC, 0xB8, 0x69, 0x47, 0xC5, 0xE1, 0x05, 0x90, 0x21, 0x0A, 0x4F},
-       },
-       {
-               []byte{0x8B, 0x0A, 0x79, 0x30, 0x6C, 0x9C, 0xE7, 0xED, 0x99, 0xDA, 0xE4, 0xF8, 0x7F, 0x8D, 0xD6, 0x16, 0x36},
-               []byte{0x7C, 0x77, 0xD6, 0xE8, 0x13, 0xBE, 0xD5, 0xAC, 0x98, 0xBA, 0xA4, 0x17, 0x47, 0x7A, 0x2E, 0x7D},
-               []byte{0x1A, 0x8C, 0x98, 0xDC, 0xD7, 0x3D, 0x38, 0x39, 0x3B, 0x2B, 0xF1, 0x56, 0x9D, 0xEE, 0xFC, 0x19},
-               []byte{0x65, 0xD2, 0x01, 0x79, 0x90, 0xD6, 0x25, 0x28},
-               []byte{0x02, 0x08, 0x3E, 0x39, 0x79, 0xDA, 0x01, 0x48, 0x12, 0xF5, 0x9F, 0x11, 0xD5, 0x26, 0x30, 0xDA, 0x30, 0x13, 0x73, 0x27, 0xD1, 0x06, 0x49, 0xB0, 0xAA, 0x6E, 0x1C, 0x18, 0x1D, 0xB6, 0x17, 0xD7, 0xF2},
-       },
-       {
-               []byte{0x1B, 0xDA, 0x12, 0x2B, 0xCE, 0x8A, 0x8D, 0xBA, 0xF1, 0x87, 0x7D, 0x96, 0x2B, 0x85, 0x92, 0xDD, 0x2D, 0x56},
-               []byte{0x5F, 0xFF, 0x20, 0xCA, 0xFA, 0xB1, 0x19, 0xCA, 0x2F, 0xC7, 0x35, 0x49, 0xE2, 0x0F, 0x5B, 0x0D},
-               []byte{0xDD, 0xE5, 0x9B, 0x97, 0xD7, 0x22, 0x15, 0x6D, 0x4D, 0x9A, 0xFF, 0x2B, 0xC7, 0x55, 0x98, 0x26},
-               []byte{0x54, 0xB9, 0xF0, 0x4E, 0x6A, 0x09, 0x18, 0x9A},
-               []byte{0x2E, 0xC4, 0x7B, 0x2C, 0x49, 0x54, 0xA4, 0x89, 0xAF, 0xC7, 0xBA, 0x48, 0x97, 0xED, 0xCD, 0xAE, 0x8C, 0xC3, 0x3B, 0x60, 0x45, 0x05, 0x99, 0xBD, 0x02, 0xC9, 0x63, 0x82, 0x90, 0x2A, 0xEF, 0x7F, 0x83, 0x2A},
-       },
-       {
-               []byte{0x6C, 0xF3, 0x67, 0x20, 0x87, 0x2B, 0x85, 0x13, 0xF6, 0xEA, 0xB1, 0xA8, 0xA4, 0x44, 0x38, 0xD5, 0xEF, 0x11},
-               []byte{0xA4, 0xA4, 0x78, 0x2B, 0xCF, 0xFD, 0x3E, 0xC5, 0xE7, 0xEF, 0x6D, 0x8C, 0x34, 0xA5, 0x61, 0x23},
-               []byte{0xB7, 0x81, 0xFC, 0xF2, 0xF7, 0x5F, 0xA5, 0xA8, 0xDE, 0x97, 0xA9, 0xCA, 0x48, 0xE5, 0x22, 0xEC},
-               []byte{0x89, 0x9A, 0x17, 0x58, 0x97, 0x56, 0x1D, 0x7E},
-               []byte{0x0D, 0xE1, 0x8F, 0xD0, 0xFD, 0xD9, 0x1E, 0x7A, 0xF1, 0x9F, 0x1D, 0x8E, 0xE8, 0x73, 0x39, 0x38, 0xB1, 0xE8, 0xE7, 0xF6, 0xD2, 0x23, 0x16, 0x18, 0x10, 0x2F, 0xDB, 0x7F, 0xE5, 0x5F, 0xF1, 0x99, 0x17, 0x00},
-       },
-       {
-               []byte{0xCA, 0x40, 0xD7, 0x44, 0x6E, 0x54, 0x5F, 0xFA, 0xED, 0x3B, 0xD1, 0x2A, 0x74, 0x0A, 0x65, 0x9F, 0xFB, 0xBB, 0x3C, 0xEA, 0xB7},
-               []byte{0x83, 0x95, 0xFC, 0xF1, 0xE9, 0x5B, 0xEB, 0xD6, 0x97, 0xBD, 0x01, 0x0B, 0xC7, 0x66, 0xAA, 0xC3},
-               []byte{0x22, 0xE7, 0xAD, 0xD9, 0x3C, 0xFC, 0x63, 0x93, 0xC5, 0x7E, 0xC0, 0xB3, 0xC1, 0x7D, 0x6B, 0x44},
-               []byte{0x12, 0x67, 0x35, 0xFC, 0xC3, 0x20, 0xD2, 0x5A},
-               []byte{0xCB, 0x89, 0x20, 0xF8, 0x7A, 0x6C, 0x75, 0xCF, 0xF3, 0x96, 0x27, 0xB5, 0x6E, 0x3E, 0xD1, 0x97, 0xC5, 0x52, 0xD2, 0x95, 0xA7, 0xCF, 0xC4, 0x6A, 0xFC, 0x25, 0x3B, 0x46, 0x52, 0xB1, 0xAF, 0x37, 0x95, 0xB1, 0x24, 0xAB, 0x6E},
-       },
-}
-
-func TestEAXEncrypt_AES(t *testing.T) {
-       b := new(bytes.Buffer)
-       for i, tt := range eaxAESTests {
-               test := fmt.Sprintf("test %d", i)
-               c, err := aes.NewCipher(tt.key)
-               if err != nil {
-                       t.Fatalf("%s: NewCipher(%d bytes) = %s", test, len(tt.key), err)
-               }
-               b.Reset()
-               enc := NewEAXEncrypter(c, tt.nonce, tt.header, 16, b)
-               n, err := io.Copy(enc, bytes.NewBuffer(tt.msg))
-               if n != int64(len(tt.msg)) || err != nil {
-                       t.Fatalf("%s: io.Copy into encrypter: %d, %s", test, n, err)
-               }
-               err = enc.Close()
-               if err != nil {
-                       t.Fatalf("%s: enc.Close: %s", test, err)
-               }
-               if d := b.Bytes(); !same(d, tt.cipher) {
-                       t.Fatalf("%s: got %x want %x", test, d, tt.cipher)
-               }
-       }
-}
-
-func TestEAXDecrypt_AES(t *testing.T) {
-       b := new(bytes.Buffer)
-       for i, tt := range eaxAESTests {
-               test := fmt.Sprintf("test %d", i)
-               c, err := aes.NewCipher(tt.key)
-               if err != nil {
-                       t.Fatalf("%s: NewCipher(%d bytes) = %s", test, len(tt.key), err)
-               }
-               b.Reset()
-               dec := NewEAXDecrypter(c, tt.nonce, tt.header, 16, bytes.NewBuffer(tt.cipher))
-               n, err := io.Copy(b, dec)
-               if n != int64(len(tt.msg)) || err != nil {
-                       t.Fatalf("%s: io.Copy into decrypter: %d, %s", test, n, err)
-               }
-               if d := b.Bytes(); !same(d, tt.msg) {
-                       t.Fatalf("%s: got %x want %x", test, d, tt.msg)
-               }
-       }
-}
diff --git a/libgo/go/crypto/block/ecb.go b/libgo/go/crypto/block/ecb.go
deleted file mode 100644 (file)
index cf09f7c..0000000
+++ /dev/null
@@ -1,270 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Electronic codebook (ECB) mode.
-// ECB is a fancy name for ``encrypt and decrypt each block separately.''
-// It's a pretty bad thing to do for any large amount of data (more than one block),
-// because the individual blocks can still be identified, duplicated, and reordered.
-// The ECB implementation exists mainly to provide buffering for
-// the other modes, which wrap it by providing modified Ciphers.
-
-// See NIST SP 800-38A, pp 9-10
-
-package block
-
-import (
-       "io"
-       "os"
-       "strconv"
-)
-
-type ecbDecrypter struct {
-       c         Cipher
-       r         io.Reader
-       blockSize int // block size
-
-       // Buffered data.
-       // The buffer buf is used as storage for both
-       // plain or crypt; at least one of those is nil at any given time.
-       buf   []byte
-       plain []byte // plain text waiting to be read
-       crypt []byte // ciphertext waiting to be decrypted
-}
-
-// Read into x.crypt until it has a full block or EOF or an error happens.
-func (x *ecbDecrypter) fillCrypt() os.Error {
-       var err os.Error
-       for len(x.crypt) < x.blockSize {
-               off := len(x.crypt)
-               var m int
-               m, err = x.r.Read(x.crypt[off:x.blockSize])
-               x.crypt = x.crypt[0 : off+m]
-               if m == 0 {
-                       break
-               }
-
-               // If an error happened but we got enough
-               // data to do some decryption, we can decrypt
-               // first and report the error (with some data) later.
-               // But if we don't have enough to decrypt,
-               // have to stop now.
-               if err != nil && len(x.crypt) < x.blockSize {
-                       break
-               }
-       }
-       return err
-}
-
-// Read from plain text buffer into p.
-func (x *ecbDecrypter) readPlain(p []byte) int {
-       n := len(x.plain)
-       if n > len(p) {
-               n = len(p)
-       }
-       for i := 0; i < n; i++ {
-               p[i] = x.plain[i]
-       }
-       if n < len(x.plain) {
-               x.plain = x.plain[n:]
-       } else {
-               x.plain = nil
-       }
-       return n
-}
-
-type ecbFragmentError int
-
-func (n ecbFragmentError) String() string {
-       return "crypto/block: " + strconv.Itoa(int(n)) + "-byte fragment at EOF"
-}
-
-func (x *ecbDecrypter) Read(p []byte) (n int, err os.Error) {
-       if len(p) == 0 {
-               return
-       }
-
-       // If there's no plaintext waiting and p is not big enough
-       // to hold a whole cipher block, we'll have to work in the
-       // cipher text buffer.  Set it to non-nil so that the
-       // code below will fill it.
-       if x.plain == nil && len(p) < x.blockSize && x.crypt == nil {
-               x.crypt = x.buf[0:0]
-       }
-
-       // If there is a leftover cipher text buffer,
-       // try to accumulate a full block.
-       if x.crypt != nil {
-               err = x.fillCrypt()
-               if err != nil || len(x.crypt) == 0 {
-                       return
-               }
-               x.c.Decrypt(x.crypt, x.crypt)
-               x.plain = x.crypt
-               x.crypt = nil
-       }
-
-       // If there is a leftover plain text buffer, read from it.
-       if x.plain != nil {
-               n = x.readPlain(p)
-               return
-       }
-
-       // Read and decrypt directly in caller's buffer.
-       n, err = io.ReadAtLeast(x.r, p, x.blockSize)
-       if err == os.EOF && n > 0 {
-               // EOF is only okay on block boundary
-               err = os.ErrorString("block fragment at EOF during decryption")
-               return
-       }
-       var i int
-       for i = 0; i+x.blockSize <= n; i += x.blockSize {
-               a := p[i : i+x.blockSize]
-               x.c.Decrypt(a, a)
-       }
-
-       // There might be an encrypted fringe remaining.
-       // Save it for next time.
-       if i < n {
-               p = p[i:n]
-               copy(x.buf, p)
-               x.crypt = x.buf[0:len(p)]
-               n = i
-       }
-
-       return
-}
-
-// NewECBDecrypter returns a reader that reads data from r and decrypts it using c.
-// It decrypts by calling c.Decrypt on each block in sequence;
-// this mode is known as electronic codebook mode, or ECB.
-// The returned Reader does not buffer or read ahead except
-// as required by the cipher's block size.
-func NewECBDecrypter(c Cipher, r io.Reader) io.Reader {
-       x := new(ecbDecrypter)
-       x.c = c
-       x.r = r
-       x.blockSize = c.BlockSize()
-       x.buf = make([]byte, x.blockSize)
-       return x
-}
-
-type ecbEncrypter struct {
-       c         Cipher
-       w         io.Writer
-       blockSize int
-
-       // Buffered data.
-       // The buffer buf is used as storage for both
-       // plain or crypt.  If both are non-nil, plain
-       // follows crypt in buf.
-       buf   []byte
-       plain []byte // plain text waiting to be encrypted
-       crypt []byte // encrypted text waiting to be written
-}
-
-// Flush the x.crypt buffer to x.w.
-func (x *ecbEncrypter) flushCrypt() os.Error {
-       if len(x.crypt) == 0 {
-               return nil
-       }
-       n, err := x.w.Write(x.crypt)
-       if n < len(x.crypt) {
-               x.crypt = x.crypt[n:]
-               if err == nil {
-                       err = io.ErrShortWrite
-               }
-       }
-       if err != nil {
-               return err
-       }
-       x.crypt = nil
-       return nil
-}
-
-// Slide x.plain down to the beginning of x.buf.
-// Plain is known to have less than one block of data,
-// so this is cheap enough.
-func (x *ecbEncrypter) slidePlain() {
-       if len(x.plain) == 0 {
-               x.plain = x.buf[0:0]
-       } else if cap(x.plain) < cap(x.buf) {
-               copy(x.buf, x.plain)
-               x.plain = x.buf[0:len(x.plain)]
-       }
-}
-
-// Fill x.plain from the data in p.
-// Return the number of bytes copied.
-func (x *ecbEncrypter) fillPlain(p []byte) int {
-       off := len(x.plain)
-       n := len(p)
-       if max := cap(x.plain) - off; n > max {
-               n = max
-       }
-       x.plain = x.plain[0 : off+n]
-       for i := 0; i < n; i++ {
-               x.plain[off+i] = p[i]
-       }
-       return n
-}
-
-// Encrypt x.plain; record encrypted range as x.crypt.
-func (x *ecbEncrypter) encrypt() {
-       var i int
-       n := len(x.plain)
-       for i = 0; i+x.blockSize <= n; i += x.blockSize {
-               a := x.plain[i : i+x.blockSize]
-               x.c.Encrypt(a, a)
-       }
-       x.crypt = x.plain[0:i]
-       x.plain = x.plain[i:n]
-}
-
-func (x *ecbEncrypter) Write(p []byte) (n int, err os.Error) {
-       for {
-               // If there is data waiting to be written, write it.
-               // This can happen on the first iteration
-               // if a write failed in an earlier call.
-               if err = x.flushCrypt(); err != nil {
-                       return
-               }
-
-               // Now that encrypted data is gone (flush ran),
-               // perhaps we need to slide the plaintext down.
-               x.slidePlain()
-
-               // Fill plaintext buffer from p.
-               m := x.fillPlain(p)
-               if m == 0 {
-                       break
-               }
-               n += m
-               p = p[m:]
-
-               // Encrypt, adjusting crypt and plain.
-               x.encrypt()
-
-               // Write x.crypt.
-               if err = x.flushCrypt(); err != nil {
-                       break
-               }
-       }
-       return
-}
-
-// NewECBEncrypter returns a writer that encrypts data using c and writes it to w.
-// It encrypts by calling c.Encrypt on each block in sequence;
-// this mode is known as electronic codebook mode, or ECB.
-// The returned Writer does no buffering except as required
-// by the cipher's block size, so there is no need for a Flush method.
-func NewECBEncrypter(c Cipher, w io.Writer) io.Writer {
-       x := new(ecbEncrypter)
-       x.c = c
-       x.w = w
-       x.blockSize = c.BlockSize()
-
-       // Create a buffer that is an integral number of blocks.
-       x.buf = make([]byte, 8192/x.blockSize*x.blockSize)
-       return x
-}
diff --git a/libgo/go/crypto/block/ecb_aes_test.go b/libgo/go/crypto/block/ecb_aes_test.go
deleted file mode 100644 (file)
index 14481d0..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// ECB AES test vectors.
-
-// See U.S. National Institute of Standards and Technology (NIST)
-// Special Publication 800-38A, ``Recommendation for Block Cipher
-// Modes of Operation,'' 2001 Edition, pp. 24-27.
-
-package block
-
-import (
-       "bytes"
-       "crypto/aes"
-       "io"
-       "testing"
-)
-
-type ecbTest struct {
-       name string
-       key  []byte
-       in   []byte
-       out  []byte
-}
-
-var commonInput = []byte{
-       0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
-       0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
-       0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
-       0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10,
-}
-
-var commonKey128 = []byte{0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}
-
-var commonKey192 = []byte{
-       0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5,
-       0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b,
-}
-
-var commonKey256 = []byte{
-       0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
-       0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4,
-}
-
-var commonIV = []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f}
-
-var ecbAESTests = []ecbTest{
-       // FIPS 197, Appendix B, C
-       {
-               "FIPS-197 Appendix B",
-               commonKey128,
-               []byte{0x32, 0x43, 0xf6, 0xa8, 0x88, 0x5a, 0x30, 0x8d, 0x31, 0x31, 0x98, 0xa2, 0xe0, 0x37, 0x07, 0x34},
-               []byte{0x39, 0x25, 0x84, 0x1d, 0x02, 0xdc, 0x09, 0xfb, 0xdc, 0x11, 0x85, 0x97, 0x19, 0x6a, 0x0b, 0x32},
-       },
-
-       // NIST SP 800-38A pp 24-27
-       {
-               "ECB-AES128",
-               commonKey128,
-               commonInput,
-               []byte{
-                       0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60, 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
-                       0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d, 0xe7, 0x85, 0x89, 0x5a, 0x96, 0xfd, 0xba, 0xaf,
-                       0x43, 0xb1, 0xcd, 0x7f, 0x59, 0x8e, 0xce, 0x23, 0x88, 0x1b, 0x00, 0xe3, 0xed, 0x03, 0x06, 0x88,
-                       0x7b, 0x0c, 0x78, 0x5e, 0x27, 0xe8, 0xad, 0x3f, 0x82, 0x23, 0x20, 0x71, 0x04, 0x72, 0x5d, 0xd4,
-               },
-       },
-       {
-               "ECB-AES192",
-               commonKey192,
-               commonInput,
-               []byte{
-                       0xbd, 0x33, 0x4f, 0x1d, 0x6e, 0x45, 0xf2, 0x5f, 0xf7, 0x12, 0xa2, 0x14, 0x57, 0x1f, 0xa5, 0xcc,
-                       0x97, 0x41, 0x04, 0x84, 0x6d, 0x0a, 0xd3, 0xad, 0x77, 0x34, 0xec, 0xb3, 0xec, 0xee, 0x4e, 0xef,
-                       0xef, 0x7a, 0xfd, 0x22, 0x70, 0xe2, 0xe6, 0x0a, 0xdc, 0xe0, 0xba, 0x2f, 0xac, 0xe6, 0x44, 0x4e,
-                       0x9a, 0x4b, 0x41, 0xba, 0x73, 0x8d, 0x6c, 0x72, 0xfb, 0x16, 0x69, 0x16, 0x03, 0xc1, 0x8e, 0x0e,
-               },
-       },
-       {
-               "ECB-AES256",
-               commonKey256,
-               commonInput,
-               []byte{
-                       0xf3, 0xee, 0xd1, 0xbd, 0xb5, 0xd2, 0xa0, 0x3c, 0x06, 0x4b, 0x5a, 0x7e, 0x3d, 0xb1, 0x81, 0xf8,
-                       0x59, 0x1c, 0xcb, 0x10, 0xd4, 0x10, 0xed, 0x26, 0xdc, 0x5b, 0xa7, 0x4a, 0x31, 0x36, 0x28, 0x70,
-                       0xb6, 0xed, 0x21, 0xb9, 0x9c, 0xa6, 0xf4, 0xf9, 0xf1, 0x53, 0xe7, 0xb1, 0xbe, 0xaf, 0xed, 0x1d,
-                       0x23, 0x30, 0x4b, 0x7a, 0x39, 0xf9, 0xf3, 0xff, 0x06, 0x7d, 0x8d, 0x8f, 0x9e, 0x24, 0xec, 0xc7,
-               },
-       },
-}
-
-func TestECB_AES(t *testing.T) {
-       for _, tt := range ecbAESTests {
-               test := tt.name
-
-               c, err := aes.NewCipher(tt.key)
-               if err != nil {
-                       t.Errorf("%s: NewCipher(%d bytes) = %s", test, len(tt.key), err)
-                       continue
-               }
-
-               var crypt bytes.Buffer
-               w := NewECBEncrypter(c, &crypt)
-               var r io.Reader = bytes.NewBuffer(tt.in)
-               n, err := io.Copy(w, r)
-               if n != int64(len(tt.in)) || err != nil {
-                       t.Errorf("%s: ECBReader io.Copy = %d, %v want %d, nil", test, n, err, len(tt.in))
-               } else if d := crypt.Bytes(); !same(tt.out, d) {
-                       t.Errorf("%s: ECBReader\nhave %x\nwant %x", test, d, tt.out)
-               }
-
-               var plain bytes.Buffer
-               r = NewECBDecrypter(c, bytes.NewBuffer(tt.out))
-               w = &plain
-               n, err = io.Copy(w, r)
-               if n != int64(len(tt.out)) || err != nil {
-                       t.Errorf("%s: ECBWriter io.Copy = %d, %v want %d, nil", test, n, err, len(tt.out))
-               } else if d := plain.Bytes(); !same(tt.in, d) {
-                       t.Errorf("%s: ECBWriter\nhave %x\nwant %x", test, d, tt.in)
-               }
-
-               if t.Failed() {
-                       break
-               }
-       }
-}
diff --git a/libgo/go/crypto/block/ecb_test.go b/libgo/go/crypto/block/ecb_test.go
deleted file mode 100644 (file)
index 6f79d92..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package block
-
-import (
-       "bytes"
-       "fmt"
-       "io"
-       "testing"
-       "testing/iotest"
-)
-
-// Simple Cipher for testing: adds an incrementing amount
-// to each byte in each
-type IncCipher struct {
-       blockSize  int
-       delta      byte
-       encrypting bool
-}
-
-func (c *IncCipher) BlockSize() int { return c.blockSize }
-
-func (c *IncCipher) Encrypt(dst, src []byte) {
-       if !c.encrypting {
-               panic("encrypt: not encrypting")
-       }
-       if len(src) != c.blockSize || len(dst) != c.blockSize {
-               panic(fmt.Sprintln("encrypt: wrong block size", c.blockSize, len(src), len(dst)))
-       }
-       c.delta++
-       for i, b := range src {
-               dst[i] = b + c.delta
-       }
-}
-
-func (c *IncCipher) Decrypt(dst, src []byte) {
-       if c.encrypting {
-               panic("decrypt: not decrypting")
-       }
-       if len(src) != c.blockSize || len(dst) != c.blockSize {
-               panic(fmt.Sprintln("decrypt: wrong block size ", c.blockSize, " ", len(src), " ", len(dst)))
-       }
-       c.delta--
-       for i, b := range src {
-               dst[i] = b + c.delta
-       }
-}
-
-func TestECBEncrypter(t *testing.T) {
-       var plain, crypt [256]byte
-       for i := 0; i < len(plain); i++ {
-               plain[i] = byte(i)
-       }
-       b := new(bytes.Buffer)
-       for block := 1; block <= 64; block *= 2 {
-               // compute encrypted version
-               delta := byte(0)
-               for i := 0; i < len(crypt); i++ {
-                       if i%block == 0 {
-                               delta++
-                       }
-                       crypt[i] = plain[i] + delta
-               }
-
-               for frag := 0; frag < 2; frag++ {
-                       c := &IncCipher{block, 0, true}
-                       b.Reset()
-                       r := bytes.NewBuffer(plain[0:])
-                       w := NewECBEncrypter(c, b)
-
-                       // copy plain into w in increasingly large chunks: 1, 1, 2, 4, 8, ...
-                       // if frag != 0, move the 1 to the end to cause fragmentation.
-                       if frag == 0 {
-                               _, err := io.Copyn(w, r, 1)
-                               if err != nil {
-                                       t.Errorf("block=%d frag=0: first Copyn: %s", block, err)
-                                       continue
-                               }
-                       }
-                       for n := 1; n <= len(plain)/2; n *= 2 {
-                               _, err := io.Copyn(w, r, int64(n))
-                               if err != nil {
-                                       t.Errorf("block=%d frag=%d: Copyn %d: %s", block, frag, n, err)
-                               }
-                       }
-                       if frag != 0 {
-                               _, err := io.Copyn(w, r, 1)
-                               if err != nil {
-                                       t.Errorf("block=%d frag=1: last Copyn: %s", block, err)
-                                       continue
-                               }
-                       }
-
-                       // check output
-                       data := b.Bytes()
-                       if len(data) != len(crypt) {
-                               t.Errorf("block=%d frag=%d: want %d bytes, got %d", block, frag, len(crypt), len(data))
-                               continue
-                       }
-
-                       if string(data) != string(crypt[0:]) {
-                               t.Errorf("block=%d frag=%d: want %x got %x", block, frag, data, crypt)
-                       }
-               }
-       }
-}
-
-func testECBDecrypter(t *testing.T, maxio int) {
-       var readers = []func(io.Reader) io.Reader{
-               func(r io.Reader) io.Reader { return r },
-               iotest.OneByteReader,
-               iotest.HalfReader,
-       }
-       var plain, crypt [256]byte
-       for i := 0; i < len(plain); i++ {
-               plain[i] = byte(255 - i)
-       }
-       b := new(bytes.Buffer)
-       for block := 1; block <= 64 && block <= maxio; block *= 2 {
-               // compute encrypted version
-               delta := byte(0)
-               for i := 0; i < len(crypt); i++ {
-                       if i%block == 0 {
-                               delta++
-                       }
-                       crypt[i] = plain[i] + delta
-               }
-
-               for mode := 0; mode < len(readers); mode++ {
-                       for frag := 0; frag < 2; frag++ {
-                               test := fmt.Sprintf("block=%d mode=%d frag=%d maxio=%d", block, mode, frag, maxio)
-                               c := &IncCipher{block, 0, false}
-                               b.Reset()
-                               r := NewECBDecrypter(c, readers[mode](bytes.NewBuffer(crypt[0:maxio])))
-
-                               // read from crypt in increasingly large chunks: 1, 1, 2, 4, 8, ...
-                               // if frag == 1, move the 1 to the end to cause fragmentation.
-                               if frag == 0 {
-                                       _, err := io.Copyn(b, r, 1)
-                                       if err != nil {
-                                               t.Errorf("%s: first Copyn: %s", test, err)
-                                               continue
-                                       }
-                               }
-                               for n := 1; n <= maxio/2; n *= 2 {
-                                       _, err := io.Copyn(b, r, int64(n))
-                                       if err != nil {
-                                               t.Errorf("%s: Copyn %d: %s", test, n, err)
-                                       }
-                               }
-                               if frag != 0 {
-                                       _, err := io.Copyn(b, r, 1)
-                                       if err != nil {
-                                               t.Errorf("%s: last Copyn: %s", test, err)
-                                               continue
-                                       }
-                               }
-
-                               // check output
-                               data := b.Bytes()
-                               if len(data) != maxio {
-                                       t.Errorf("%s: want %d bytes, got %d", test, maxio, len(data))
-                                       continue
-                               }
-
-                               if string(data) != string(plain[0:maxio]) {
-                                       t.Errorf("%s: input=%x want %x got %x", test, crypt[0:maxio], plain[0:maxio], data)
-                               }
-                       }
-               }
-       }
-}
-
-func TestECBDecrypter(t *testing.T) {
-       // Do shorter I/O sizes first; they're easier to debug.
-       for n := 1; n <= 256 && !t.Failed(); n *= 2 {
-               testECBDecrypter(t, n)
-       }
-}
diff --git a/libgo/go/crypto/block/ofb.go b/libgo/go/crypto/block/ofb.go
deleted file mode 100644 (file)
index 11aaaa4..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Output feedback (OFB) mode.
-
-// OFB converts a block cipher into a stream cipher by
-// repeatedly encrypting an initialization vector and
-// xoring the resulting stream of data with the input.
-
-// See NIST SP 800-38A, pp 13-15
-
-package block
-
-import (
-       "fmt"
-       "io"
-)
-
-type ofbStream struct {
-       c  Cipher
-       iv []byte
-}
-
-func newOFBStream(c Cipher, iv []byte) *ofbStream {
-       x := new(ofbStream)
-       x.c = c
-       n := len(iv)
-       if n != c.BlockSize() {
-               panic(fmt.Sprintln("crypto/block: newOFBStream: invalid iv size", n, "!=", c.BlockSize()))
-       }
-       x.iv = dup(iv)
-       return x
-}
-
-func (x *ofbStream) Next() []byte {
-       x.c.Encrypt(x.iv, x.iv)
-       return x.iv
-}
-
-// NewOFBReader returns a reader that reads data from r, decrypts (or encrypts)
-// it using c in output feedback (OFB) mode with the initialization vector iv.
-// The returned Reader does not buffer and has no block size.
-// In OFB mode, encryption and decryption are the same operation:
-// an OFB reader applied to an encrypted stream produces a decrypted
-// stream and vice versa.
-func NewOFBReader(c Cipher, iv []byte, r io.Reader) io.Reader {
-       return newXorReader(newOFBStream(c, iv), r)
-}
-
-// NewOFBWriter returns a writer that encrypts (or decrypts) data using c
-// in cipher feedback (OFB) mode with the initialization vector iv
-// and writes the encrypted data to w.
-// The returned Writer does not buffer and has no block size.
-// In OFB mode, encryption and decryption are the same operation:
-// an OFB writer applied to an decrypted stream produces an encrypted
-// stream and vice versa.
-func NewOFBWriter(c Cipher, iv []byte, w io.Writer) io.Writer {
-       return newXorWriter(newOFBStream(c, iv), w)
-}
diff --git a/libgo/go/crypto/block/ofb_aes_test.go b/libgo/go/crypto/block/ofb_aes_test.go
deleted file mode 100644 (file)
index 9c527a6..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// OFB AES test vectors.
-
-// See U.S. National Institute of Standards and Technology (NIST)
-// Special Publication 800-38A, ``Recommendation for Block Cipher
-// Modes of Operation,'' 2001 Edition, pp. 52-55.
-
-package block
-
-import (
-       "bytes"
-       "crypto/aes"
-       "io"
-       "testing"
-)
-
-type ofbTest struct {
-       name string
-       key  []byte
-       iv   []byte
-       in   []byte
-       out  []byte
-}
-
-var ofbAESTests = []ofbTest{
-       // NIST SP 800-38A pp 52-55
-       {
-               "OFB-AES128",
-               commonKey128,
-               commonIV,
-               commonInput,
-               []byte{
-                       0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20, 0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a,
-                       0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03, 0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25,
-                       0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6, 0x43, 0x44, 0xf7, 0xa8, 0x22, 0x60, 0xed, 0xcc,
-                       0x30, 0x4c, 0x65, 0x28, 0xf6, 0x59, 0xc7, 0x78, 0x66, 0xa5, 0x10, 0xd9, 0xc1, 0xd6, 0xae, 0x5e,
-               },
-       },
-       {
-               "OFB-AES192",
-               commonKey192,
-               commonIV,
-               commonInput,
-               []byte{
-                       0xcd, 0xc8, 0x0d, 0x6f, 0xdd, 0xf1, 0x8c, 0xab, 0x34, 0xc2, 0x59, 0x09, 0xc9, 0x9a, 0x41, 0x74,
-                       0xfc, 0xc2, 0x8b, 0x8d, 0x4c, 0x63, 0x83, 0x7c, 0x09, 0xe8, 0x17, 0x00, 0xc1, 0x10, 0x04, 0x01,
-                       0x8d, 0x9a, 0x9a, 0xea, 0xc0, 0xf6, 0x59, 0x6f, 0x55, 0x9c, 0x6d, 0x4d, 0xaf, 0x59, 0xa5, 0xf2,
-                       0x6d, 0x9f, 0x20, 0x08, 0x57, 0xca, 0x6c, 0x3e, 0x9c, 0xac, 0x52, 0x4b, 0xd9, 0xac, 0xc9, 0x2a,
-               },
-       },
-       {
-               "OFB-AES256",
-               commonKey256,
-               commonIV,
-               commonInput,
-               []byte{
-                       0xdc, 0x7e, 0x84, 0xbf, 0xda, 0x79, 0x16, 0x4b, 0x7e, 0xcd, 0x84, 0x86, 0x98, 0x5d, 0x38, 0x60,
-                       0x4f, 0xeb, 0xdc, 0x67, 0x40, 0xd2, 0x0b, 0x3a, 0xc8, 0x8f, 0x6a, 0xd8, 0x2a, 0x4f, 0xb0, 0x8d,
-                       0x71, 0xab, 0x47, 0xa0, 0x86, 0xe8, 0x6e, 0xed, 0xf3, 0x9d, 0x1c, 0x5b, 0xba, 0x97, 0xc4, 0x08,
-                       0x01, 0x26, 0x14, 0x1d, 0x67, 0xf3, 0x7b, 0xe8, 0x53, 0x8f, 0x5a, 0x8b, 0xe7, 0x40, 0xe4, 0x84,
-               },
-       },
-}
-
-func TestOFB_AES(t *testing.T) {
-       for _, tt := range ofbAESTests {
-               test := tt.name
-
-               c, err := aes.NewCipher(tt.key)
-               if err != nil {
-                       t.Errorf("%s: NewCipher(%d bytes) = %s", test, len(tt.key), err)
-                       continue
-               }
-
-               for j := 0; j <= 5; j += 5 {
-                       var crypt bytes.Buffer
-                       in := tt.in[0 : len(tt.in)-j]
-                       w := NewOFBWriter(c, tt.iv, &crypt)
-                       var r io.Reader = bytes.NewBuffer(in)
-                       n, err := io.Copy(w, r)
-                       if n != int64(len(in)) || err != nil {
-                               t.Errorf("%s/%d: OFBWriter io.Copy = %d, %v want %d, nil", test, len(in), n, err, len(in))
-                       } else if d, out := crypt.Bytes(), tt.out[0:len(in)]; !same(out, d) {
-                               t.Errorf("%s/%d: OFBWriter\ninpt %x\nhave %x\nwant %x", test, len(in), in, d, out)
-                       }
-               }
-
-               for j := 0; j <= 7; j += 7 {
-                       var plain bytes.Buffer
-                       out := tt.out[0 : len(tt.out)-j]
-                       r := NewOFBReader(c, tt.iv, bytes.NewBuffer(out))
-                       w := &plain
-                       n, err := io.Copy(w, r)
-                       if n != int64(len(out)) || err != nil {
-                               t.Errorf("%s/%d: OFBReader io.Copy = %d, %v want %d, nil", test, len(out), n, err, len(out))
-                       } else if d, in := plain.Bytes(), tt.in[0:len(out)]; !same(in, d) {
-                               t.Errorf("%s/%d: OFBReader\nhave %x\nwant %x", test, len(out), d, in)
-                       }
-               }
-
-               if t.Failed() {
-                       break
-               }
-       }
-}
diff --git a/libgo/go/crypto/block/xor.go b/libgo/go/crypto/block/xor.go
deleted file mode 100644 (file)
index 9d8b172..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Encrypt/decrypt data by xor with a pseudo-random data stream.
-
-package block
-
-import (
-       "io"
-       "os"
-)
-
-// A dataStream is an interface to an unending stream of data,
-// used by XorReader and XorWriter to model a pseudo-random generator.
-// Calls to Next() return sequential blocks of data from the stream.
-// Each call must return at least one byte: there is no EOF.
-type dataStream interface {
-       Next() []byte
-}
-
-type xorReader struct {
-       r    io.Reader
-       rand dataStream // pseudo-random
-       buf  []byte     // data available from last call to rand
-}
-
-func newXorReader(rand dataStream, r io.Reader) io.Reader {
-       x := new(xorReader)
-       x.r = r
-       x.rand = rand
-       return x
-}
-
-func (x *xorReader) Read(p []byte) (n int, err os.Error) {
-       n, err = x.r.Read(p)
-
-       // xor input with stream.
-       bp := 0
-       buf := x.buf
-       for i := 0; i < n; i++ {
-               if bp >= len(buf) {
-                       buf = x.rand.Next()
-                       bp = 0
-               }
-               p[i] ^= buf[bp]
-               bp++
-       }
-       x.buf = buf[bp:]
-       return n, err
-}
-
-type xorWriter struct {
-       w     io.Writer
-       rand  dataStream // pseudo-random
-       buf   []byte     // last buffer returned by rand
-       extra []byte     // extra random data (use before buf)
-       work  []byte     // work space
-}
-
-func newXorWriter(rand dataStream, w io.Writer) io.Writer {
-       x := new(xorWriter)
-       x.w = w
-       x.rand = rand
-       x.work = make([]byte, 4096)
-       return x
-}
-
-func (x *xorWriter) Write(p []byte) (n int, err os.Error) {
-       for len(p) > 0 {
-               // Determine next chunk of random data
-               // and xor with p into x.work.
-               var chunk []byte
-               m := len(p)
-               if nn := len(x.extra); nn > 0 {
-                       // extra points into work, so edit directly
-                       if m > nn {
-                               m = nn
-                       }
-                       for i := 0; i < m; i++ {
-                               x.extra[i] ^= p[i]
-                       }
-                       chunk = x.extra[0:m]
-               } else {
-                       // xor p ^ buf into work, refreshing buf as needed
-                       if nn := len(x.work); m > nn {
-                               m = nn
-                       }
-                       bp := 0
-                       buf := x.buf
-                       for i := 0; i < m; i++ {
-                               if bp >= len(buf) {
-                                       buf = x.rand.Next()
-                                       bp = 0
-                               }
-                               x.work[i] = buf[bp] ^ p[i]
-                               bp++
-                       }
-                       x.buf = buf[bp:]
-                       chunk = x.work[0:m]
-               }
-
-               // Write chunk.
-               var nn int
-               nn, err = x.w.Write(chunk)
-               if nn != len(chunk) && err == nil {
-                       err = io.ErrShortWrite
-               }
-               if nn < len(chunk) {
-                       // Reconstruct the random bits from the unwritten
-                       // data and save them for next time.
-                       for i := nn; i < m; i++ {
-                               chunk[i] ^= p[i]
-                       }
-                       x.extra = chunk[nn:]
-               }
-               n += nn
-               if err != nil {
-                       return
-               }
-               p = p[m:]
-       }
-       return
-}
diff --git a/libgo/go/crypto/block/xor_test.go b/libgo/go/crypto/block/xor_test.go
deleted file mode 100644 (file)
index 50f6bb0..0000000
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package block
-
-import (
-       "bytes"
-       "fmt"
-       "io"
-       "testing"
-       "testing/iotest"
-)
-
-// Simple "pseudo-random" stream for testing.
-type incStream struct {
-       buf []byte
-       n   byte
-}
-
-func newIncStream(blockSize int) *incStream {
-       x := new(incStream)
-       x.buf = make([]byte, blockSize)
-       return x
-}
-
-func (x *incStream) Next() []byte {
-       x.n++
-       for i := range x.buf {
-               x.buf[i] = x.n
-               x.n++
-       }
-       return x.buf
-}
-
-func testXorWriter(t *testing.T, maxio int) {
-       var plain, crypt [256]byte
-       for i := 0; i < len(plain); i++ {
-               plain[i] = byte(i)
-       }
-       b := new(bytes.Buffer)
-       for block := 1; block <= 64 && block <= maxio; block *= 2 {
-               // compute encrypted version
-               n := byte(0)
-               for i := 0; i < len(crypt); i++ {
-                       if i%block == 0 {
-                               n++
-                       }
-                       crypt[i] = plain[i] ^ n
-                       n++
-               }
-
-               for frag := 0; frag < 2; frag++ {
-                       test := fmt.Sprintf("block=%d frag=%d maxio=%d", block, frag, maxio)
-                       b.Reset()
-                       r := bytes.NewBuffer(plain[0:])
-                       s := newIncStream(block)
-                       w := newXorWriter(s, b)
-
-                       // copy plain into w in increasingly large chunks: 1, 1, 2, 4, 8, ...
-                       // if frag != 0, move the 1 to the end to cause fragmentation.
-                       if frag == 0 {
-                               _, err := io.Copyn(w, r, 1)
-                               if err != nil {
-                                       t.Errorf("%s: first Copyn: %s", test, err)
-                                       continue
-                               }
-                       }
-                       for n := 1; n <= len(plain)/2; n *= 2 {
-                               _, err := io.Copyn(w, r, int64(n))
-                               if err != nil {
-                                       t.Errorf("%s: Copyn %d: %s", test, n, err)
-                               }
-                       }
-
-                       // check output
-                       crypt := crypt[0 : len(crypt)-frag]
-                       data := b.Bytes()
-                       if len(data) != len(crypt) {
-                               t.Errorf("%s: want %d bytes, got %d", test, len(crypt), len(data))
-                               continue
-                       }
-
-                       if string(data) != string(crypt) {
-                               t.Errorf("%s: want %x got %x", test, data, crypt)
-                       }
-               }
-       }
-}
-
-
-func TestXorWriter(t *testing.T) {
-       // Do shorter I/O sizes first; they're easier to debug.
-       for n := 1; n <= 256 && !t.Failed(); n *= 2 {
-               testXorWriter(t, n)
-       }
-}
-
-func testXorReader(t *testing.T, maxio int) {
-       var readers = []func(io.Reader) io.Reader{
-               func(r io.Reader) io.Reader { return r },
-               iotest.OneByteReader,
-               iotest.HalfReader,
-       }
-       var plain, crypt [256]byte
-       for i := 0; i < len(plain); i++ {
-               plain[i] = byte(255 - i)
-       }
-       b := new(bytes.Buffer)
-       for block := 1; block <= 64 && block <= maxio; block *= 2 {
-               // compute encrypted version
-               n := byte(0)
-               for i := 0; i < len(crypt); i++ {
-                       if i%block == 0 {
-                               n++
-                       }
-                       crypt[i] = plain[i] ^ n
-                       n++
-               }
-
-               for mode := 0; mode < len(readers); mode++ {
-                       for frag := 0; frag < 2; frag++ {
-                               test := fmt.Sprintf("block=%d mode=%d frag=%d maxio=%d", block, mode, frag, maxio)
-                               s := newIncStream(block)
-                               b.Reset()
-                               r := newXorReader(s, readers[mode](bytes.NewBuffer(crypt[0:maxio])))
-
-                               // read from crypt in increasingly large chunks: 1, 1, 2, 4, 8, ...
-                               // if frag == 1, move the 1 to the end to cause fragmentation.
-                               if frag == 0 {
-                                       _, err := io.Copyn(b, r, 1)
-                                       if err != nil {
-                                               t.Errorf("%s: first Copyn: %s", test, err)
-                                               continue
-                                       }
-                               }
-                               for n := 1; n <= maxio/2; n *= 2 {
-                                       _, err := io.Copyn(b, r, int64(n))
-                                       if err != nil {
-                                               t.Errorf("%s: Copyn %d: %s", test, n, err)
-                                       }
-                               }
-
-                               // check output
-                               data := b.Bytes()
-                               crypt := crypt[0 : maxio-frag]
-                               plain := plain[0 : maxio-frag]
-                               if len(data) != len(plain) {
-                                       t.Errorf("%s: want %d bytes, got %d", test, len(plain), len(data))
-                                       continue
-                               }
-
-                               if string(data) != string(plain) {
-                                       t.Errorf("%s: input=%x want %x got %x", test, crypt, plain, data)
-                               }
-                       }
-               }
-       }
-}
-
-func TestXorReader(t *testing.T) {
-       // Do shorter I/O sizes first; they're easier to debug.
-       for n := 1; n <= 256 && !t.Failed(); n *= 2 {
-               testXorReader(t, n)
-       }
-}
-
-// TODO(rsc): Test handling of writes after write errors.
diff --git a/libgo/go/crypto/des/block.go b/libgo/go/crypto/des/block.go
new file mode 100644 (file)
index 0000000..e18eaed
--- /dev/null
@@ -0,0 +1,98 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package des
+
+import (
+       "encoding/binary"
+)
+
+func cryptBlock(subkeys []uint64, dst, src []byte, decrypt bool) {
+       b := binary.BigEndian.Uint64(src)
+       b = permuteBlock(b, initialPermutation[:])
+       left, right := uint32(b>>32), uint32(b)
+
+       var subkey uint64
+       for i := 0; i < 16; i++ {
+               if decrypt {
+                       subkey = subkeys[15-i]
+               } else {
+                       subkey = subkeys[i]
+               }
+
+               left, right = right, left^feistel(right, subkey)
+       }
+       // switch left & right and perform final permutation
+       preOutput := (uint64(right) << 32) | uint64(left)
+       binary.BigEndian.PutUint64(dst, permuteBlock(preOutput, finalPermutation[:]))
+}
+
+// Encrypt one block from src into dst, using the subkeys.
+func encryptBlock(subkeys []uint64, dst, src []byte) {
+       cryptBlock(subkeys, dst, src, false)
+}
+
+// Decrypt one block from src into dst, using the subkeys.
+func decryptBlock(subkeys []uint64, dst, src []byte) {
+       cryptBlock(subkeys, dst, src, true)
+}
+
+// DES Feistel function
+func feistel(right uint32, key uint64) (result uint32) {
+       sBoxLocations := key ^ permuteBlock(uint64(right), expansionFunction[:])
+       var sBoxResult uint32
+       for i := uint8(0); i < 8; i++ {
+               sBoxLocation := uint8(sBoxLocations>>42) & 0x3f
+               sBoxLocations <<= 6
+               // row determined by 1st and 6th bit
+               row := (sBoxLocation & 0x1) | ((sBoxLocation & 0x20) >> 4)
+               // column is middle four bits
+               column := (sBoxLocation >> 1) & 0xf
+               sBoxResult |= uint32(sBoxes[i][row][column]) << (4 * (7 - i))
+       }
+       return uint32(permuteBlock(uint64(sBoxResult), permutationFunction[:]))
+}
+
+// general purpose function to perform DES block permutations
+func permuteBlock(src uint64, permutation []uint8) (block uint64) {
+       for position, n := range permutation {
+               bit := (src >> n) & 1
+               block |= bit << uint((len(permutation)-1)-position)
+       }
+       return
+}
+
+// creates 16 28-bit blocks rotated according
+// to the rotation schedule
+func ksRotate(in uint32) (out []uint32) {
+       out = make([]uint32, 16)
+       last := in
+       for i := 0; i < 16; i++ {
+               // 28-bit circular left shift
+               left := (last << (4 + ksRotations[i])) >> 4
+               right := (last << 4) >> (32 - ksRotations[i])
+               out[i] = left | right
+               last = out[i]
+       }
+       return
+}
+
+// creates 16 56-bit subkeys from the original key
+func (c *Cipher) generateSubkeys(keyBytes []byte) {
+       // apply PC1 permutation to key
+       key := binary.BigEndian.Uint64(keyBytes)
+       permutedKey := permuteBlock(key, permutedChoice1[:])
+
+       // rotate halves of permuted key according to the rotation schedule
+       leftRotations := ksRotate(uint32(permutedKey >> 28))
+       rightRotations := ksRotate(uint32(permutedKey<<4) >> 4)
+
+       // generate subkeys
+       for i := 0; i < 16; i++ {
+               // combine halves to form 56-bit input to PC2
+               pc2Input := uint64(leftRotations[i])<<28 | uint64(rightRotations[i])
+               // apply PC2 permutation to 7 byte input
+               c.subkeys[i] = permuteBlock(pc2Input, permutedChoice2[:])
+       }
+}
diff --git a/libgo/go/crypto/des/cipher.go b/libgo/go/crypto/des/cipher.go
new file mode 100644 (file)
index 0000000..d17a1a7
--- /dev/null
@@ -0,0 +1,103 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package des
+
+import (
+       "os"
+       "strconv"
+)
+
+// The DES block size in bytes.
+const BlockSize = 8
+
+type KeySizeError int
+
+func (k KeySizeError) String() string {
+       return "crypto/des: invalid key size " + strconv.Itoa(int(k))
+}
+
+// Cipher is an instance of DES encryption.
+type Cipher struct {
+       subkeys [16]uint64
+}
+
+// NewCipher creates and returns a new Cipher.
+func NewCipher(key []byte) (*Cipher, os.Error) {
+       if len(key) != 8 {
+               return nil, KeySizeError(len(key))
+       }
+
+       c := new(Cipher)
+       c.generateSubkeys(key)
+       return c, nil
+}
+
+// BlockSize returns the DES block size, 8 bytes.
+func (c *Cipher) BlockSize() int { return BlockSize }
+
+// Encrypts the 8-byte buffer src and stores the result in dst.
+// Note that for amounts of data larger than a block,
+// it is not safe to just call Encrypt on successive blocks;
+// instead, use an encryption mode like CBC (see crypto/cipher/cbc.go).
+func (c *Cipher) Encrypt(dst, src []byte) { encryptBlock(c.subkeys[:], dst, src) }
+
+// Decrypts the 8-byte buffer src and stores the result in dst.
+func (c *Cipher) Decrypt(dst, src []byte) { decryptBlock(c.subkeys[:], dst, src) }
+
+// Reset zeros the key data, so that it will no longer
+// appear in the process's memory.
+func (c *Cipher) Reset() {
+       for i := 0; i < len(c.subkeys); i++ {
+               c.subkeys[i] = 0
+       }
+}
+
+// A TripleDESCipher is an instance of TripleDES encryption.
+type TripleDESCipher struct {
+       cipher1, cipher2, cipher3 Cipher
+}
+
+// NewCipher creates and returns a new Cipher.
+func NewTripleDESCipher(key []byte) (*TripleDESCipher, os.Error) {
+       if len(key) != 24 {
+               return nil, KeySizeError(len(key))
+       }
+
+       c := new(TripleDESCipher)
+       c.cipher1.generateSubkeys(key[:8])
+       c.cipher2.generateSubkeys(key[8:16])
+       c.cipher3.generateSubkeys(key[16:])
+       return c, nil
+}
+
+// BlockSize returns the TripleDES block size, 8 bytes.
+// It is necessary to satisfy the Block interface in the
+// package "crypto/cipher".
+func (c *TripleDESCipher) BlockSize() int { return BlockSize }
+
+// Encrypts the 8-byte buffer src and stores the result in dst.
+// Note that for amounts of data larger than a block,
+// it is not safe to just call Encrypt on successive blocks;
+// instead, use an encryption mode like CBC (see crypto/cipher/cbc.go).
+func (c *TripleDESCipher) Encrypt(dst, src []byte) {
+       c.cipher1.Encrypt(dst, src)
+       c.cipher2.Decrypt(dst, dst)
+       c.cipher3.Encrypt(dst, dst)
+}
+
+// Decrypts the 8-byte buffer src and stores the result in dst.
+func (c *TripleDESCipher) Decrypt(dst, src []byte) {
+       c.cipher3.Decrypt(dst, src)
+       c.cipher2.Encrypt(dst, dst)
+       c.cipher1.Decrypt(dst, dst)
+}
+
+// Reset zeros the key data, so that it will no longer
+// appear in the process's memory.
+func (c *TripleDESCipher) Reset() {
+       c.cipher1.Reset()
+       c.cipher2.Reset()
+       c.cipher3.Reset()
+}
diff --git a/libgo/go/crypto/des/const.go b/libgo/go/crypto/des/const.go
new file mode 100644 (file)
index 0000000..2bd485e
--- /dev/null
@@ -0,0 +1,139 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package des implements the Data Encryption Standard (DES) and the
+// Triple Data Encryption Algorithm (TDEA) as defined
+// in U.S. Federal Information Processing Standards Publication 46-3.
+package des
+
+// Used to perform an initial permutation of a 64-bit input block.
+var initialPermutation = [64]byte{
+       6, 14, 22, 30, 38, 46, 54, 62,
+       4, 12, 20, 28, 36, 44, 52, 60,
+       2, 10, 18, 26, 34, 42, 50, 58,
+       0, 8, 16, 24, 32, 40, 48, 56,
+       7, 15, 23, 31, 39, 47, 55, 63,
+       5, 13, 21, 29, 37, 45, 53, 61,
+       3, 11, 19, 27, 35, 43, 51, 59,
+       1, 9, 17, 25, 33, 41, 49, 57,
+}
+
+// Used to perform a final permutation of a 4-bit preoutput block. This is the
+// inverse of initialPermutation
+var finalPermutation = [64]byte{
+       24, 56, 16, 48, 8, 40, 0, 32,
+       25, 57, 17, 49, 9, 41, 1, 33,
+       26, 58, 18, 50, 10, 42, 2, 34,
+       27, 59, 19, 51, 11, 43, 3, 35,
+       28, 60, 20, 52, 12, 44, 4, 36,
+       29, 61, 21, 53, 13, 45, 5, 37,
+       30, 62, 22, 54, 14, 46, 6, 38,
+       31, 63, 23, 55, 15, 47, 7, 39,
+}
+
+// Used to expand an input block of 32 bits, producing an output block of 48
+// bits.
+var expansionFunction = [48]byte{
+       0, 31, 30, 29, 28, 27, 28, 27,
+       26, 25, 24, 23, 24, 23, 22, 21,
+       20, 19, 20, 19, 18, 17, 16, 15,
+       16, 15, 14, 13, 12, 11, 12, 11,
+       10, 9, 8, 7, 8, 7, 6, 5,
+       4, 3, 4, 3, 2, 1, 0, 31,
+}
+
+// Yields a 32-bit output from a 32-bit input
+var permutationFunction = [32]byte{
+       16, 25, 12, 11, 3, 20, 4, 15,
+       31, 17, 9, 6, 27, 14, 1, 22,
+       30, 24, 8, 18, 0, 5, 29, 23,
+       13, 19, 2, 26, 10, 21, 28, 7,
+}
+
+// Used in the key schedule to select 56 bits
+// from a 64-bit input.
+var permutedChoice1 = [56]byte{
+       7, 15, 23, 31, 39, 47, 55, 63,
+       6, 14, 22, 30, 38, 46, 54, 62,
+       5, 13, 21, 29, 37, 45, 53, 61,
+       4, 12, 20, 28, 1, 9, 17, 25,
+       33, 41, 49, 57, 2, 10, 18, 26,
+       34, 42, 50, 58, 3, 11, 19, 27,
+       35, 43, 51, 59, 36, 44, 52, 60,
+}
+
+// Used in the key schedule to produce each subkey by selecting 48 bits from
+// the 56-bit input
+var permutedChoice2 = [48]byte{
+       42, 39, 45, 32, 55, 51, 53, 28,
+       41, 50, 35, 46, 33, 37, 44, 52,
+       30, 48, 40, 49, 29, 36, 43, 54,
+       15, 4, 25, 19, 9, 1, 26, 16,
+       5, 11, 23, 8, 12, 7, 17, 0,
+       22, 3, 10, 14, 6, 20, 27, 24,
+}
+
+// 8 S-boxes composed of 4 rows and 16 columns
+// Used in the DES cipher function
+var sBoxes = [8][4][16]uint8{
+       // S-box 1
+       {
+               {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
+               {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
+               {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
+               {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13},
+       },
+       // S-box 2
+       {
+               {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
+               {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
+               {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
+               {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9},
+       },
+       // S-box 3
+       {
+               {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
+               {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
+               {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
+               {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12},
+       },
+       // S-box 4
+       {
+               {7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
+               {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
+               {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
+               {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14},
+       },
+       // S-box 5
+       {
+               {2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
+               {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
+               {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
+               {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3},
+       },
+       // S-box 6
+       {
+               {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
+               {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
+               {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
+               {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13},
+       },
+       // S-box 7
+       {
+               {4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
+               {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
+               {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
+               {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12},
+       },
+       // S-box 8
+       {
+               {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
+               {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
+               {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
+               {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11},
+       },
+}
+
+// Size of left rotation per round in each half of the key schedule
+var ksRotations = [16]uint8{1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}
diff --git a/libgo/go/crypto/des/des_test.go b/libgo/go/crypto/des/des_test.go
new file mode 100644 (file)
index 0000000..d1f3aa7
--- /dev/null
@@ -0,0 +1,1497 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package des
+
+import (
+       "bytes"
+       "testing"
+)
+
+type CryptTest struct {
+       key []byte
+       in  []byte
+       out []byte
+}
+
+// some custom tests for DES
+var encryptDESTests = []CryptTest{
+       {
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0x8c, 0xa6, 0x4d, 0xe9, 0xc1, 0xb1, 0x23, 0xa7}},
+       {
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+               []byte{0x35, 0x55, 0x50, 0xb2, 0x15, 0x0e, 0x24, 0x51}},
+       {
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
+               []byte{0x61, 0x7b, 0x3a, 0x0c, 0xe8, 0xf0, 0x71, 0x00}},
+       {
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
+               []byte{0x92, 0x31, 0xf2, 0x36, 0xff, 0x9a, 0xa9, 0x5c}},
+       {
+               []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0xca, 0xaa, 0xaf, 0x4d, 0xea, 0xf1, 0xdb, 0xae}},
+       {
+               []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+               []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+               []byte{0x73, 0x59, 0xb2, 0x16, 0x3e, 0x4e, 0xdc, 0x58}},
+       {
+               []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+               []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
+               []byte{0x6d, 0xce, 0x0d, 0xc9, 0x00, 0x65, 0x56, 0xa3}},
+       {
+               []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+               []byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
+               []byte{0x9e, 0x84, 0xc5, 0xf3, 0x17, 0x0f, 0x8e, 0xff}},
+       {
+               []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0xd5, 0xd4, 0x4f, 0xf7, 0x20, 0x68, 0x3d, 0x0d}},
+       {
+               []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
+               []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+               []byte{0x59, 0x73, 0x23, 0x56, 0xf3, 0x6f, 0xde, 0x06}},
+       {
+               []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
+               []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
+               []byte{0x56, 0xcc, 0x09, 0xe7, 0xcf, 0xdc, 0x4c, 0xef}},
+       {
+               []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
+               []byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
+               []byte{0x12, 0xc6, 0x26, 0xaf, 0x05, 0x8b, 0x43, 0x3b}},
+       {
+               []byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0xa6, 0x8c, 0xdc, 0xa9, 0x0c, 0x90, 0x21, 0xf9}},
+       {
+               []byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
+               []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+               []byte{0x2a, 0x2b, 0xb0, 0x08, 0xdf, 0x97, 0xc2, 0xf2}},
+       {
+               []byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
+               []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
+               []byte{0xed, 0x39, 0xd9, 0x50, 0xfa, 0x74, 0xbc, 0xc4}},
+       {
+               []byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
+               []byte{0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10},
+               []byte{0xa9, 0x33, 0xf6, 0x18, 0x30, 0x23, 0xb3, 0x10}},
+       {
+               []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
+               []byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11},
+               []byte{0x17, 0x66, 0x8d, 0xfc, 0x72, 0x92, 0x53, 0x2d}},
+       {
+               []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef},
+               []byte{0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
+               []byte{0xb4, 0xfd, 0x23, 0x16, 0x47, 0xa5, 0xbe, 0xc0}},
+       {
+               []byte{0x0e, 0x32, 0x92, 0x32, 0xea, 0x6d, 0x0d, 0x73},
+               []byte{0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87},
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
+       {
+               []byte{0x73, 0x65, 0x63, 0x52, 0x33, 0x74, 0x24, 0x3b}, // "secR3t$;"
+               []byte{0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x31, 0x32}, // "a test12"
+               []byte{0x37, 0x0d, 0xee, 0x2c, 0x1f, 0xb4, 0xf7, 0xa5}},
+       {
+               []byte{0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68}, // "abcdefgh"
+               []byte{0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68}, // "abcdefgh"
+               []byte{0x2a, 0x8d, 0x69, 0xde, 0x9d, 0x5f, 0xdf, 0xf9}},
+       {
+               []byte{0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68}, // "abcdefgh"
+               []byte{0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38}, // "12345678"
+               []byte{0x21, 0xc6, 0x0d, 0xa5, 0x34, 0x24, 0x8b, 0xce}},
+       {
+               []byte{0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38}, // "12345678"
+               []byte{0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68}, // "abcdefgh"
+               []byte{0x94, 0xd4, 0x43, 0x6b, 0xc3, 0xb5, 0xb6, 0x93}},
+       {
+               []byte{0x1f, 0x79, 0x90, 0x5f, 0x88, 0x01, 0xc8, 0x88}, // random
+               []byte{0xc7, 0x46, 0x18, 0x73, 0xaf, 0x48, 0x5f, 0xb3}, // random
+               []byte{0xb0, 0x93, 0x50, 0x88, 0xf9, 0x92, 0x44, 0x6a}},
+       {
+               []byte{0xe6, 0xf4, 0xf2, 0xdb, 0x31, 0x42, 0x53, 0x01}, // random
+               []byte{0xff, 0x3d, 0x25, 0x50, 0x12, 0xe3, 0x4a, 0xc5}, // random
+               []byte{0x86, 0x08, 0xd3, 0xd1, 0x6c, 0x2f, 0xd2, 0x55}},
+       {
+               []byte{0x69, 0xc1, 0x9d, 0xc1, 0x15, 0xc5, 0xfb, 0x2b}, // random
+               []byte{0x1a, 0x22, 0x5c, 0xaf, 0x1f, 0x1d, 0xa3, 0xf9}, // random
+               []byte{0x64, 0xba, 0x31, 0x67, 0x56, 0x91, 0x1e, 0xa7}},
+       {
+               []byte{0x6e, 0x5e, 0xe2, 0x47, 0xc4, 0xbf, 0xf6, 0x51}, // random
+               []byte{0x11, 0xc9, 0x57, 0xff, 0x66, 0x89, 0x0e, 0xf0}, // random
+               []byte{0x94, 0xc5, 0x35, 0xb2, 0xc5, 0x8b, 0x39, 0x72}},
+}
+
+var weakKeyTests = []CryptTest{
+       {
+               []byte{0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
+               []byte{0x55, 0x74, 0xc0, 0xbd, 0x7c, 0xdf, 0xf7, 0x39}, // random
+               nil},
+       {
+               []byte{0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe},
+               []byte{0xe8, 0xe1, 0xa7, 0xc1, 0xde, 0x11, 0x89, 0xaa}, // random
+               nil},
+       {
+               []byte{0xe0, 0xe0, 0xe0, 0xe0, 0xf1, 0xf1, 0xf1, 0xf1},
+               []byte{0x50, 0x6a, 0x4b, 0x94, 0x3b, 0xed, 0x7d, 0xdc}, // random
+               nil},
+       {
+               []byte{0x1f, 0x1f, 0x1f, 0x1f, 0x0e, 0x0e, 0x0e, 0x0e},
+               []byte{0x88, 0x81, 0x56, 0x38, 0xec, 0x3b, 0x1c, 0x97}, // random
+               nil},
+       {
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0x17, 0xa0, 0x83, 0x62, 0x32, 0xfe, 0x9a, 0x0b}, // random
+               nil},
+       {
+               []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+               []byte{0xca, 0x8f, 0xca, 0x1f, 0x50, 0xc5, 0x7b, 0x49}, // random
+               nil},
+       {
+               []byte{0xe1, 0xe1, 0xe1, 0xe1, 0xf0, 0xf0, 0xf0, 0xf0},
+               []byte{0xb1, 0xea, 0xad, 0x7d, 0xe7, 0xc3, 0x7a, 0x43}, // random
+               nil},
+       {
+               []byte{0x1e, 0x1e, 0x1e, 0x1e, 0x0f, 0x0f, 0x0f, 0x0f},
+               []byte{0xae, 0x74, 0x7d, 0x6f, 0xef, 0x16, 0xbb, 0x81}, // random
+               nil},
+}
+
+var semiWeakKeyTests = []CryptTest{
+       // key and out contain the semi-weak key pair
+       {
+               []byte{0x01, 0x1f, 0x01, 0x1f, 0x01, 0x0e, 0x01, 0x0e},
+               []byte{0x12, 0xfa, 0x31, 0x16, 0xf9, 0xc5, 0x0a, 0xe4}, // random
+               []byte{0x1f, 0x01, 0x1f, 0x01, 0x0e, 0x01, 0x0e, 0x01}},
+       {
+               []byte{0x01, 0xe0, 0x01, 0xe0, 0x01, 0xf1, 0x01, 0xf1},
+               []byte{0xb0, 0x4c, 0x7a, 0xee, 0xd2, 0xe5, 0x4d, 0xb7}, // random
+               []byte{0xe0, 0x01, 0xe0, 0x01, 0xf1, 0x01, 0xf1, 0x01}},
+       {
+               []byte{0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe},
+               []byte{0xa4, 0x81, 0xcd, 0xb1, 0x64, 0x6f, 0xd3, 0xbc}, // random
+               []byte{0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01, 0xfe, 0x01}},
+       {
+               []byte{0x1f, 0xe0, 0x1f, 0xe0, 0x0e, 0xf1, 0x0e, 0xf1},
+               []byte{0xee, 0x27, 0xdd, 0x88, 0x4c, 0x22, 0xcd, 0xce}, // random
+               []byte{0xe0, 0x1f, 0xe0, 0x1f, 0xf1, 0x0e, 0xf1, 0x0e}},
+       {
+               []byte{0x1f, 0xfe, 0x1f, 0xfe, 0x0e, 0xfe, 0x0e, 0xfe},
+               []byte{0x19, 0x3d, 0xcf, 0x97, 0x70, 0xfb, 0xab, 0xe1}, // random
+               []byte{0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x0e, 0xfe, 0x0e}},
+       {
+               []byte{0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1, 0xfe},
+               []byte{0x7c, 0x82, 0x69, 0xe4, 0x1e, 0x86, 0x99, 0xd7}, // random
+               []byte{0xfe, 0xe0, 0xfe, 0xe0, 0xfe, 0xf1, 0xfe, 0xf1}},
+}
+
+// some custom tests for TripleDES
+var encryptTripleDESTests = []CryptTest{
+       {
+               []byte{
+                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0x92, 0x95, 0xb5, 0x9b, 0xb3, 0x84, 0x73, 0x6e}},
+       {
+               []byte{
+                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+               []byte{0xc1, 0x97, 0xf5, 0x58, 0x74, 0x8a, 0x20, 0xe7}},
+       {
+               []byte{
+                       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0x3e, 0x68, 0x0a, 0xa7, 0x8b, 0x75, 0xdf, 0x18}},
+       {
+               []byte{
+                       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                       0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+               []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
+               []byte{0x6d, 0x6a, 0x4a, 0x64, 0x4c, 0x7b, 0x8c, 0x91}},
+       {
+               []byte{ // "abcdefgh12345678ABCDEFGH"
+                       0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+                       0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
+                       0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48},
+               []byte{0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30}, // "00000000"
+               []byte{0xe4, 0x61, 0xb7, 0x59, 0x68, 0x8b, 0xff, 0x66}},
+       {
+               []byte{ // "abcdefgh12345678ABCDEFGH"
+                       0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+                       0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
+                       0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48},
+               []byte{0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38}, // "12345678"
+               []byte{0xdb, 0xd0, 0x92, 0xde, 0xf8, 0x34, 0xff, 0x58}},
+       {
+               []byte{ // "abcdefgh12345678ABCDEFGH"
+                       0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+                       0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
+                       0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48},
+               []byte{0xf0, 0xc5, 0x82, 0x22, 0xd3, 0xe6, 0x12, 0xd2}, // random
+               []byte{0xba, 0xe4, 0x41, 0xb1, 0x3c, 0x37, 0x4d, 0xf4}},
+       {
+               []byte{ // random
+                       0xd3, 0x7d, 0x45, 0xee, 0x22, 0xe9, 0xcf, 0x52,
+                       0xf4, 0x65, 0xa2, 0x4f, 0x70, 0xd1, 0x81, 0x8a,
+                       0x3d, 0xbe, 0x2f, 0x39, 0xc7, 0x71, 0xd2, 0xe9},
+               []byte{0x49, 0x53, 0xc3, 0xe9, 0x78, 0xdf, 0x9f, 0xaf}, // random
+               []byte{0x53, 0x40, 0x51, 0x24, 0xd8, 0x3c, 0xf9, 0x88}},
+       {
+               []byte{ // random
+                       0xcb, 0x10, 0x7d, 0xda, 0x7e, 0x96, 0x57, 0x0a,
+                       0xe8, 0xeb, 0xe8, 0x07, 0x8e, 0x87, 0xd3, 0x57,
+                       0xb2, 0x61, 0x12, 0xb8, 0x2a, 0x90, 0xb7, 0x2f},
+               []byte{0xa3, 0xc2, 0x60, 0xb1, 0x0b, 0xb7, 0x28, 0x6e}, // random
+               []byte{0x56, 0x73, 0x7d, 0xfb, 0xb5, 0xa1, 0xc3, 0xde}},
+}
+
+// NIST Special Publication 800-20, Appendix A
+// Key for use with Table A.1 tests
+var tableA1Key = []byte{
+       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+}
+
+// Table A.1 Resulting Ciphertext from the Variable Plaintext Known Answer Test
+var tableA1Tests = []CryptTest{
+       {nil, // 0
+               []byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0x95, 0xf8, 0xa5, 0xe5, 0xdd, 0x31, 0xd9, 0x00}},
+       {nil, // 1
+               []byte{0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0xdd, 0x7f, 0x12, 0x1c, 0xa5, 0x01, 0x56, 0x19}},
+       {nil, // 2
+               []byte{0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0x2e, 0x86, 0x53, 0x10, 0x4f, 0x38, 0x34, 0xea}},
+       {nil, // 3
+               []byte{0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0x4b, 0xd3, 0x88, 0xff, 0x6c, 0xd8, 0x1d, 0x4f}},
+       {nil, // 4
+               []byte{0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0x20, 0xb9, 0xe7, 0x67, 0xb2, 0xfb, 0x14, 0x56}},
+       {nil, // 5
+               []byte{0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0x55, 0x57, 0x93, 0x80, 0xd7, 0x71, 0x38, 0xef}},
+       {nil, // 6
+               []byte{0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0x6c, 0xc5, 0xde, 0xfa, 0xaf, 0x04, 0x51, 0x2f}},
+       {nil, // 7
+               []byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0x0d, 0x9f, 0x27, 0x9b, 0xa5, 0xd8, 0x72, 0x60}},
+       {nil, // 8
+               []byte{0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0xd9, 0x03, 0x1b, 0x02, 0x71, 0xbd, 0x5a, 0x0a}},
+       {nil, // 9
+               []byte{0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0x42, 0x42, 0x50, 0xb3, 0x7c, 0x3d, 0xd9, 0x51}},
+       {nil, // 10
+               []byte{0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0xb8, 0x06, 0x1b, 0x7e, 0xcd, 0x9a, 0x21, 0xe5}},
+       {nil, // 11
+               []byte{0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0xf1, 0x5d, 0x0f, 0x28, 0x6b, 0x65, 0xbd, 0x28}},
+       {nil, // 12
+               []byte{0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0xad, 0xd0, 0xcc, 0x8d, 0x6e, 0x5d, 0xeb, 0xa1}},
+       {nil, // 13
+               []byte{0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0xe6, 0xd5, 0xf8, 0x27, 0x52, 0xad, 0x63, 0xd1}},
+       {nil, // 14
+               []byte{0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0xec, 0xbf, 0xe3, 0xbd, 0x3f, 0x59, 0x1a, 0x5e}},
+       {nil, // 15
+               []byte{0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0xf3, 0x56, 0x83, 0x43, 0x79, 0xd1, 0x65, 0xcd}},
+       {nil, // 16
+               []byte{0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0x2b, 0x9f, 0x98, 0x2f, 0x20, 0x03, 0x7f, 0xa9}},
+       {nil, // 17
+               []byte{0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0x88, 0x9d, 0xe0, 0x68, 0xa1, 0x6f, 0x0b, 0xe6}},
+       {nil, // 18
+               []byte{0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0xe1, 0x9e, 0x27, 0x5d, 0x84, 0x6a, 0x12, 0x98}},
+       {nil, // 19
+               []byte{0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0x32, 0x9a, 0x8e, 0xd5, 0x23, 0xd7, 0x1a, 0xec}},
+       {nil, // 20
+               []byte{0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0xe7, 0xfc, 0xe2, 0x25, 0x57, 0xd2, 0x3c, 0x97}},
+       {nil, // 21
+               []byte{0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0x12, 0xa9, 0xf5, 0x81, 0x7f, 0xf2, 0xd6, 0x5d}},
+       {nil, // 22
+               []byte{0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0xa4, 0x84, 0xc3, 0xad, 0x38, 0xdc, 0x9c, 0x19}},
+       {nil, // 23
+               []byte{0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00},
+               []byte{0xfb, 0xe0, 0x0a, 0x8a, 0x1e, 0xf8, 0xad, 0x72}},
+       {nil, // 24
+               []byte{0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00},
+               []byte{0x75, 0x0d, 0x07, 0x94, 0x07, 0x52, 0x13, 0x63}},
+       {nil, // 25
+               []byte{0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00},
+               []byte{0x64, 0xfe, 0xed, 0x9c, 0x72, 0x4c, 0x2f, 0xaf}},
+       {nil, // 26
+               []byte{0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00},
+               []byte{0xf0, 0x2b, 0x26, 0x3b, 0x32, 0x8e, 0x2b, 0x60}},
+       {nil, // 27
+               []byte{0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00},
+               []byte{0x9d, 0x64, 0x55, 0x5a, 0x9a, 0x10, 0xb8, 0x52}},
+       {nil, // 28
+               []byte{0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
+               []byte{0xd1, 0x06, 0xff, 0x0b, 0xed, 0x52, 0x55, 0xd7}},
+       {nil, // 29
+               []byte{0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00},
+               []byte{0xe1, 0x65, 0x2c, 0x6b, 0x13, 0x8c, 0x64, 0xa5}},
+       {nil, // 30
+               []byte{0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00},
+               []byte{0xe4, 0x28, 0x58, 0x11, 0x86, 0xec, 0x8f, 0x46}},
+       {nil, // 31
+               []byte{0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00},
+               []byte{0xae, 0xb5, 0xf5, 0xed, 0xe2, 0x2d, 0x1a, 0x36}},
+       {nil, // 32
+               []byte{0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00},
+               []byte{0xe9, 0x43, 0xd7, 0x56, 0x8a, 0xec, 0x0c, 0x5c}},
+       {nil, // 33
+               []byte{0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00},
+               []byte{0xdf, 0x98, 0xc8, 0x27, 0x6f, 0x54, 0xb0, 0x4b}},
+       {nil, // 34
+               []byte{0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00},
+               []byte{0xb1, 0x60, 0xe4, 0x68, 0x0f, 0x6c, 0x69, 0x6f}},
+       {nil, // 35
+               []byte{0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00},
+               []byte{0xfa, 0x07, 0x52, 0xb0, 0x7d, 0x9c, 0x4a, 0xb8}},
+       {nil, // 36
+               []byte{0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00},
+               []byte{0xca, 0x3a, 0x2b, 0x03, 0x6d, 0xbc, 0x85, 0x02}},
+       {nil, // 37
+               []byte{0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00},
+               []byte{0x5e, 0x09, 0x05, 0x51, 0x7b, 0xb5, 0x9b, 0xcf}},
+       {nil, // 38
+               []byte{0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00},
+               []byte{0x81, 0x4e, 0xeb, 0x3b, 0x91, 0xd9, 0x07, 0x26}},
+       {nil, // 39
+               []byte{0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00},
+               []byte{0x4d, 0x49, 0xdb, 0x15, 0x32, 0x91, 0x9c, 0x9f}},
+       {nil, // 40
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00},
+               []byte{0x25, 0xeb, 0x5f, 0xc3, 0xf8, 0xcf, 0x06, 0x21}},
+       {nil, // 41
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00},
+               []byte{0xab, 0x6a, 0x20, 0xc0, 0x62, 0x0d, 0x1c, 0x6f}},
+       {nil, // 42
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00},
+               []byte{0x79, 0xe9, 0x0d, 0xbc, 0x98, 0xf9, 0x2c, 0xca}},
+       {nil, // 43
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00},
+               []byte{0x86, 0x6e, 0xce, 0xdd, 0x80, 0x72, 0xbb, 0x0e}},
+       {nil, // 44
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00},
+               []byte{0x8b, 0x54, 0x53, 0x6f, 0x2f, 0x3e, 0x64, 0xa8}},
+       {nil, // 45
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00},
+               []byte{0xea, 0x51, 0xd3, 0x97, 0x55, 0x95, 0xb8, 0x6b}},
+       {nil, // 46
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00},
+               []byte{0xca, 0xff, 0xc6, 0xac, 0x45, 0x42, 0xde, 0x31}},
+       {nil, // 47
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00},
+               []byte{0x8d, 0xd4, 0x5a, 0x2d, 0xdf, 0x90, 0x79, 0x6c}},
+       {nil, // 48
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00},
+               []byte{0x10, 0x29, 0xd5, 0x5e, 0x88, 0x0e, 0xc2, 0xd0}},
+       {nil, // 49
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00},
+               []byte{0x5d, 0x86, 0xcb, 0x23, 0x63, 0x9d, 0xbe, 0xa9}},
+       {nil, // 50
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00},
+               []byte{0x1d, 0x1c, 0xa8, 0x53, 0xae, 0x7c, 0x0c, 0x5f}},
+       {nil, // 51
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00},
+               []byte{0xce, 0x33, 0x23, 0x29, 0x24, 0x8f, 0x32, 0x28}},
+       {nil, // 52
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00},
+               []byte{0x84, 0x05, 0xd1, 0xab, 0xe2, 0x4f, 0xb9, 0x42}},
+       {nil, // 53
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00},
+               []byte{0xe6, 0x43, 0xd7, 0x80, 0x90, 0xca, 0x42, 0x07}},
+       {nil, // 54
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00},
+               []byte{0x48, 0x22, 0x1b, 0x99, 0x37, 0x74, 0x8a, 0x23}},
+       {nil, // 55
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00},
+               []byte{0xdd, 0x7c, 0x0b, 0xbd, 0x61, 0xfa, 0xfd, 0x54}},
+       {nil, // 56
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80},
+               []byte{0x2f, 0xbc, 0x29, 0x1a, 0x57, 0x0d, 0xb5, 0xc4}},
+       {nil, // 57
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40},
+               []byte{0xe0, 0x7c, 0x30, 0xd7, 0xe4, 0xe2, 0x6e, 0x12}},
+       {nil, // 58
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20},
+               []byte{0x09, 0x53, 0xe2, 0x25, 0x8e, 0x8e, 0x90, 0xa1}},
+       {nil, // 59
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
+               []byte{0x5b, 0x71, 0x1b, 0xc4, 0xce, 0xeb, 0xf2, 0xee}},
+       {nil, // 60
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08},
+               []byte{0xcc, 0x08, 0x3f, 0x1e, 0x6d, 0x9e, 0x85, 0xf6}},
+       {nil, // 61
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04},
+               []byte{0xd2, 0xfd, 0x88, 0x67, 0xd5, 0x0d, 0x2d, 0xfe}},
+       {nil, // 62
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02},
+               []byte{0x06, 0xe7, 0xea, 0x22, 0xce, 0x92, 0x70, 0x8f}},
+       {nil, // 63
+               []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
+               []byte{0x16, 0x6b, 0x40, 0xb4, 0x4a, 0xba, 0x4b, 0xd6}},
+}
+
+// Plaintext for use with Table A.2 tests
+var tableA2Plaintext = []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+
+// Table A.2 Resulting Ciphertext from the Variable Key Known Answer Test
+var tableA2Tests = []CryptTest{
+       { // 0
+               []byte{
+                       0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0x95, 0xa8, 0xd7, 0x28, 0x13, 0xda, 0xa9, 0x4d}},
+       { // 1
+               []byte{
+                       0x40, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x40, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x40, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0x0e, 0xec, 0x14, 0x87, 0xdd, 0x8c, 0x26, 0xd5}},
+       { // 2
+               []byte{
+                       0x20, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x20, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x20, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0x7a, 0xd1, 0x6f, 0xfb, 0x79, 0xc4, 0x59, 0x26}},
+       { // 3
+               []byte{
+                       0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0xd3, 0x74, 0x62, 0x94, 0xca, 0x6a, 0x6c, 0xf3}},
+       { // 4
+               []byte{
+                       0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0x80, 0x9f, 0x5f, 0x87, 0x3c, 0x1f, 0xd7, 0x61}},
+       { // 5
+               []byte{
+                       0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0xc0, 0x2f, 0xaf, 0xfe, 0xc9, 0x89, 0xd1, 0xfc}},
+       { // 6
+               []byte{
+                       0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0x46, 0x15, 0xaa, 0x1d, 0x33, 0xe7, 0x2f, 0x10}},
+       { // 7
+               []byte{
+                       0x01, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0x20, 0x55, 0x12, 0x33, 0x50, 0xc0, 0x08, 0x58}},
+       { // 8
+               []byte{
+                       0x01, 0x40, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x40, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x40, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0xdf, 0x3b, 0x99, 0xd6, 0x57, 0x73, 0x97, 0xc8}},
+       { // 9
+               []byte{
+                       0x01, 0x20, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x20, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x20, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0x31, 0xfe, 0x17, 0x36, 0x9b, 0x52, 0x88, 0xc9}},
+       { // 10
+               []byte{
+                       0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0xdf, 0xdd, 0x3c, 0xc6, 0x4d, 0xae, 0x16, 0x42}},
+       { // 11
+               []byte{
+                       0x01, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0x17, 0x8c, 0x83, 0xce, 0x2b, 0x39, 0x9d, 0x94}},
+       { // 12
+               []byte{
+                       0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0x50, 0xf6, 0x36, 0x32, 0x4a, 0x9b, 0x7f, 0x80}},
+       { // 13
+               []byte{
+                       0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0xa8, 0x46, 0x8e, 0xe3, 0xbc, 0x18, 0xf0, 0x6d}},
+       { // 14
+               []byte{
+                       0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0xa2, 0xdc, 0x9e, 0x92, 0xfd, 0x3c, 0xde, 0x92}},
+       { // 15
+               []byte{
+                       0x01, 0x01, 0x40, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x40, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x40, 0x01, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0xca, 0xc0, 0x9f, 0x79, 0x7d, 0x03, 0x12, 0x87}},
+       { // 16
+               []byte{
+                       0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0x90, 0xba, 0x68, 0x0b, 0x22, 0xae, 0xb5, 0x25}},
+       { // 17
+               []byte{
+                       0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0xce, 0x7a, 0x24, 0xf3, 0x50, 0xe2, 0x80, 0xb6}},
+       { // 18
+               []byte{
+                       0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0x88, 0x2b, 0xff, 0x0a, 0xa0, 0x1a, 0x0b, 0x87}},
+       { // 19
+               []byte{
+                       0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0x25, 0x61, 0x02, 0x88, 0x92, 0x45, 0x11, 0xc2}},
+       { // 20
+               []byte{
+                       0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0xc7, 0x15, 0x16, 0xc2, 0x9c, 0x75, 0xd1, 0x70}},
+       { // 21
+               []byte{
+                       0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0x51, 0x99, 0xc2, 0x9a, 0x52, 0xc9, 0xf0, 0x59}},
+       { // 22
+               []byte{
+                       0x01, 0x01, 0x01, 0x40, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x40, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x40, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0xc2, 0x2f, 0x0a, 0x29, 0x4a, 0x71, 0xf2, 0x9f}},
+       { // 23
+               []byte{
+                       0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0xee, 0x37, 0x14, 0x83, 0x71, 0x4c, 0x02, 0xea}},
+       { // 24
+               []byte{
+                       0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0xa8, 0x1f, 0xbd, 0x44, 0x8f, 0x9e, 0x52, 0x2f}},
+       { // 25
+               []byte{
+                       0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0x4f, 0x64, 0x4c, 0x92, 0xe1, 0x92, 0xdf, 0xed}},
+       { // 26
+               []byte{
+                       0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0x1a, 0xfa, 0x9a, 0x66, 0xa6, 0xdf, 0x92, 0xae}},
+       { // 27
+               []byte{
+                       0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0xb3, 0xc1, 0xcc, 0x71, 0x5c, 0xb8, 0x79, 0xd8}},
+       { // 28
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0x19, 0xd0, 0x32, 0xe6, 0x4a, 0xb0, 0xbd, 0x8b}},
+       { // 29
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x40, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x40, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x40, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0x3c, 0xfa, 0xa7, 0xa7, 0xdc, 0x87, 0x20, 0xdc}},
+       { // 30
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0xb7, 0x26, 0x5f, 0x7f, 0x44, 0x7a, 0xc6, 0xf3}},
+       { // 31
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0x9d, 0xb7, 0x3b, 0x3c, 0x0d, 0x16, 0x3f, 0x54}},
+       { // 32
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0x81, 0x81, 0xb6, 0x5b, 0xab, 0xf4, 0xa9, 0x75}},
+       { // 33
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0x93, 0xc9, 0xb6, 0x40, 0x42, 0xea, 0xa2, 0x40}},
+       { // 34
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01},
+               nil,
+               []byte{0x55, 0x70, 0x53, 0x08, 0x29, 0x70, 0x55, 0x92}},
+       { // 35
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x01, 0x01},
+               nil,
+               []byte{0x86, 0x38, 0x80, 0x9e, 0x87, 0x87, 0x87, 0xa0}},
+       { // 36
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x40, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x40, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x40, 0x01, 0x01},
+               nil,
+               []byte{0x41, 0xb9, 0xa7, 0x9a, 0xf7, 0x9a, 0xc2, 0x08}},
+       { // 37
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x20, 0x01, 0x01},
+               nil,
+               []byte{0x7a, 0x9b, 0xe4, 0x2f, 0x20, 0x09, 0xa8, 0x92}},
+       { // 38
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x01, 0x01},
+               nil,
+               []byte{0x29, 0x03, 0x8d, 0x56, 0xba, 0x6d, 0x27, 0x45}},
+       { // 39
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x01, 0x01},
+               nil,
+               []byte{0x54, 0x95, 0xc6, 0xab, 0xf1, 0xe5, 0xdf, 0x51}},
+       { // 40
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01, 0x01},
+               nil,
+               []byte{0xae, 0x13, 0xdb, 0xd5, 0x61, 0x48, 0x89, 0x33}},
+       { // 41
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01, 0x01},
+               nil,
+               []byte{0x02, 0x4d, 0x1f, 0xfa, 0x89, 0x04, 0xe3, 0x89}},
+       { // 42
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80, 0x01},
+               nil,
+               []byte{0xd1, 0x39, 0x97, 0x12, 0xf9, 0x9b, 0xf0, 0x2e}},
+       { // 43
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x40, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x40, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x40, 0x01},
+               nil,
+               []byte{0x14, 0xc1, 0xd7, 0xc1, 0xcf, 0xfe, 0xc7, 0x9e}},
+       { // 44
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x20, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x20, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x20, 0x01},
+               nil,
+               []byte{0x1d, 0xe5, 0x27, 0x9d, 0xae, 0x3b, 0xed, 0x6f}},
+       { // 45
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10, 0x01},
+               nil,
+               []byte{0xe9, 0x41, 0xa3, 0x3f, 0x85, 0x50, 0x13, 0x03}},
+       { // 46
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08, 0x01},
+               nil,
+               []byte{0xda, 0x99, 0xdb, 0xbc, 0x9a, 0x03, 0xf3, 0x79}},
+       { // 47
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04, 0x01},
+               nil,
+               []byte{0xb7, 0xfc, 0x92, 0xf9, 0x1d, 0x8e, 0x92, 0xe9}},
+       { // 48
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x01},
+               nil,
+               []byte{0xae, 0x8e, 0x5c, 0xaa, 0x3c, 0xa0, 0x4e, 0x85}},
+       { // 49
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x80},
+               nil,
+               []byte{0x9c, 0xc6, 0x2d, 0xf4, 0x3b, 0x6e, 0xed, 0x74}},
+       { // 50
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x40,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x40,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x40},
+               nil,
+               []byte{0xd8, 0x63, 0xdb, 0xb5, 0xc5, 0x9a, 0x91, 0xa0}},
+       { // 50
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x20,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x20,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x20},
+               nil,
+               []byte{0xa1, 0xab, 0x21, 0x90, 0x54, 0x5b, 0x91, 0xd7}},
+       { // 52
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x10},
+               nil,
+               []byte{0x08, 0x75, 0x04, 0x1e, 0x64, 0xc5, 0x70, 0xf7}},
+       { // 53
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x08},
+               nil,
+               []byte{0x5a, 0x59, 0x45, 0x28, 0xbe, 0xbe, 0xf1, 0xcc}},
+       { // 54
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x04},
+               nil,
+               []byte{0xfc, 0xdb, 0x32, 0x91, 0xde, 0x21, 0xf0, 0xc0}},
+       { // 55
+               []byte{
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02,
+                       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02},
+               nil,
+               []byte{0x86, 0x9e, 0xfd, 0x7f, 0x9f, 0x26, 0x5a, 0x09}},
+}
+
+// Plaintext for use with Table A.3 tests
+var tableA3Plaintext = []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+
+// Table A.3 Values To Be Used for the Permutation Operation Known Answer Test
+var tableA3Tests = []CryptTest{
+       { // 0
+               []byte{
+                       0x10, 0x46, 0x91, 0x34, 0x89, 0x98, 0x01, 0x31,
+                       0x10, 0x46, 0x91, 0x34, 0x89, 0x98, 0x01, 0x31,
+                       0x10, 0x46, 0x91, 0x34, 0x89, 0x98, 0x01, 0x31,
+               },
+               nil,
+               []byte{0x88, 0xd5, 0x5e, 0x54, 0xf5, 0x4c, 0x97, 0xb4}},
+       { // 1
+               []byte{
+                       0x10, 0x07, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20,
+                       0x10, 0x07, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20,
+                       0x10, 0x07, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20,
+               },
+               nil,
+               []byte{0x0c, 0x0c, 0xc0, 0x0c, 0x83, 0xea, 0x48, 0xfd}},
+       { // 2
+               []byte{
+                       0x10, 0x07, 0x10, 0x34, 0xc8, 0x98, 0x01, 0x20,
+                       0x10, 0x07, 0x10, 0x34, 0xc8, 0x98, 0x01, 0x20,
+                       0x10, 0x07, 0x10, 0x34, 0xc8, 0x98, 0x01, 0x20,
+               },
+               nil,
+               []byte{0x83, 0xbc, 0x8e, 0xf3, 0xa6, 0x57, 0x01, 0x83}},
+       { // 3
+               []byte{
+                       0x10, 0x46, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20,
+                       0x10, 0x46, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20,
+                       0x10, 0x46, 0x10, 0x34, 0x89, 0x98, 0x80, 0x20,
+               },
+               nil,
+               []byte{0xdf, 0x72, 0x5d, 0xca, 0xd9, 0x4e, 0xa2, 0xe9}},
+       { // 4
+               []byte{
+                       0x10, 0x86, 0x91, 0x15, 0x19, 0x19, 0x01, 0x01,
+                       0x10, 0x86, 0x91, 0x15, 0x19, 0x19, 0x01, 0x01,
+                       0x10, 0x86, 0x91, 0x15, 0x19, 0x19, 0x01, 0x01,
+               },
+               nil,
+               []byte{0xe6, 0x52, 0xb5, 0x3b, 0x55, 0x0b, 0xe8, 0xb0}},
+       { // 5
+               []byte{
+                       0x10, 0x86, 0x91, 0x15, 0x19, 0x58, 0x01, 0x01,
+                       0x10, 0x86, 0x91, 0x15, 0x19, 0x58, 0x01, 0x01,
+                       0x10, 0x86, 0x91, 0x15, 0x19, 0x58, 0x01, 0x01,
+               },
+               nil,
+               []byte{0xaf, 0x52, 0x71, 0x20, 0xc4, 0x85, 0xcb, 0xb0}},
+       { // 6
+               []byte{
+                       0x51, 0x07, 0xb0, 0x15, 0x19, 0x58, 0x01, 0x01,
+                       0x51, 0x07, 0xb0, 0x15, 0x19, 0x58, 0x01, 0x01,
+                       0x51, 0x07, 0xb0, 0x15, 0x19, 0x58, 0x01, 0x01,
+               },
+               nil,
+               []byte{0x0f, 0x04, 0xce, 0x39, 0x3d, 0xb9, 0x26, 0xd5}},
+       { // 7
+               []byte{
+                       0x10, 0x07, 0xb0, 0x15, 0x19, 0x19, 0x01, 0x01,
+                       0x10, 0x07, 0xb0, 0x15, 0x19, 0x19, 0x01, 0x01,
+                       0x10, 0x07, 0xb0, 0x15, 0x19, 0x19, 0x01, 0x01,
+               },
+               nil,
+               []byte{0xc9, 0xf0, 0x0f, 0xfc, 0x74, 0x07, 0x90, 0x67}},
+       { // 8
+               []byte{
+                       0x31, 0x07, 0x91, 0x54, 0x98, 0x08, 0x01, 0x01,
+                       0x31, 0x07, 0x91, 0x54, 0x98, 0x08, 0x01, 0x01,
+                       0x31, 0x07, 0x91, 0x54, 0x98, 0x08, 0x01, 0x01,
+               },
+               nil,
+               []byte{0x7c, 0xfd, 0x82, 0xa5, 0x93, 0x25, 0x2b, 0x4e}},
+       { // 9
+               []byte{
+                       0x31, 0x07, 0x91, 0x94, 0x98, 0x08, 0x01, 0x01,
+                       0x31, 0x07, 0x91, 0x94, 0x98, 0x08, 0x01, 0x01,
+                       0x31, 0x07, 0x91, 0x94, 0x98, 0x08, 0x01, 0x01,
+               },
+               nil,
+               []byte{0xcb, 0x49, 0xa2, 0xf9, 0xe9, 0x13, 0x63, 0xe3}},
+       { // 10
+               []byte{
+                       0x10, 0x07, 0x91, 0x15, 0xb9, 0x08, 0x01, 0x40,
+                       0x10, 0x07, 0x91, 0x15, 0xb9, 0x08, 0x01, 0x40,
+                       0x10, 0x07, 0x91, 0x15, 0xb9, 0x08, 0x01, 0x40,
+               },
+               nil,
+               []byte{0x00, 0xb5, 0x88, 0xbe, 0x70, 0xd2, 0x3f, 0x56}},
+       { // 11
+               []byte{
+                       0x31, 0x07, 0x91, 0x15, 0x98, 0x08, 0x01, 0x40,
+                       0x31, 0x07, 0x91, 0x15, 0x98, 0x08, 0x01, 0x40,
+                       0x31, 0x07, 0x91, 0x15, 0x98, 0x08, 0x01, 0x40,
+               },
+               nil,
+               []byte{0x40, 0x6a, 0x9a, 0x6a, 0xb4, 0x33, 0x99, 0xae}},
+       { // 12
+               []byte{
+                       0x10, 0x07, 0xd0, 0x15, 0x89, 0x98, 0x01, 0x01,
+                       0x10, 0x07, 0xd0, 0x15, 0x89, 0x98, 0x01, 0x01,
+                       0x10, 0x07, 0xd0, 0x15, 0x89, 0x98, 0x01, 0x01,
+               },
+               nil,
+               []byte{0x6c, 0xb7, 0x73, 0x61, 0x1d, 0xca, 0x9a, 0xda}},
+       { // 13
+               []byte{
+                       0x91, 0x07, 0x91, 0x15, 0x89, 0x98, 0x01, 0x01,
+                       0x91, 0x07, 0x91, 0x15, 0x89, 0x98, 0x01, 0x01,
+                       0x91, 0x07, 0x91, 0x15, 0x89, 0x98, 0x01, 0x01,
+               },
+               nil,
+               []byte{0x67, 0xfd, 0x21, 0xc1, 0x7d, 0xbb, 0x5d, 0x70}},
+       { // 14
+               []byte{
+                       0x91, 0x07, 0xd0, 0x15, 0x89, 0x19, 0x01, 0x01,
+                       0x91, 0x07, 0xd0, 0x15, 0x89, 0x19, 0x01, 0x01,
+                       0x91, 0x07, 0xd0, 0x15, 0x89, 0x19, 0x01, 0x01,
+               },
+               nil,
+               []byte{0x95, 0x92, 0xcb, 0x41, 0x10, 0x43, 0x07, 0x87}},
+       { // 15
+               []byte{
+                       0x10, 0x07, 0xd0, 0x15, 0x98, 0x98, 0x01, 0x20,
+                       0x10, 0x07, 0xd0, 0x15, 0x98, 0x98, 0x01, 0x20,
+                       0x10, 0x07, 0xd0, 0x15, 0x98, 0x98, 0x01, 0x20,
+               },
+               nil,
+               []byte{0xa6, 0xb7, 0xff, 0x68, 0xa3, 0x18, 0xdd, 0xd3}},
+       { // 16
+               []byte{
+                       0x10, 0x07, 0x94, 0x04, 0x98, 0x19, 0x01, 0x01,
+                       0x10, 0x07, 0x94, 0x04, 0x98, 0x19, 0x01, 0x01,
+                       0x10, 0x07, 0x94, 0x04, 0x98, 0x19, 0x01, 0x01,
+               },
+               nil,
+               []byte{0x4d, 0x10, 0x21, 0x96, 0xc9, 0x14, 0xca, 0x16}},
+       { // 17
+               []byte{
+                       0x01, 0x07, 0x91, 0x04, 0x91, 0x19, 0x04, 0x01,
+                       0x01, 0x07, 0x91, 0x04, 0x91, 0x19, 0x04, 0x01,
+                       0x01, 0x07, 0x91, 0x04, 0x91, 0x19, 0x04, 0x01,
+               },
+               nil,
+               []byte{0x2d, 0xfa, 0x9f, 0x45, 0x73, 0x59, 0x49, 0x65}},
+       { // 18
+               []byte{
+                       0x01, 0x07, 0x91, 0x04, 0x91, 0x19, 0x01, 0x01,
+                       0x01, 0x07, 0x91, 0x04, 0x91, 0x19, 0x01, 0x01,
+                       0x01, 0x07, 0x91, 0x04, 0x91, 0x19, 0x01, 0x01,
+               },
+               nil,
+               []byte{0xb4, 0x66, 0x04, 0x81, 0x6c, 0x0e, 0x07, 0x74}},
+       { // 19
+               []byte{
+                       0x01, 0x07, 0x94, 0x04, 0x91, 0x19, 0x04, 0x01,
+                       0x01, 0x07, 0x94, 0x04, 0x91, 0x19, 0x04, 0x01,
+                       0x01, 0x07, 0x94, 0x04, 0x91, 0x19, 0x04, 0x01,
+               },
+               nil,
+               []byte{0x6e, 0x7e, 0x62, 0x21, 0xa4, 0xf3, 0x4e, 0x87}},
+       { // 20
+               []byte{
+                       0x19, 0x07, 0x92, 0x10, 0x98, 0x1a, 0x01, 0x01,
+                       0x19, 0x07, 0x92, 0x10, 0x98, 0x1a, 0x01, 0x01,
+                       0x19, 0x07, 0x92, 0x10, 0x98, 0x1a, 0x01, 0x01,
+               },
+               nil,
+               []byte{0xaa, 0x85, 0xe7, 0x46, 0x43, 0x23, 0x31, 0x99}},
+       { // 21
+               []byte{
+                       0x10, 0x07, 0x91, 0x19, 0x98, 0x19, 0x08, 0x01,
+                       0x10, 0x07, 0x91, 0x19, 0x98, 0x19, 0x08, 0x01,
+                       0x10, 0x07, 0x91, 0x19, 0x98, 0x19, 0x08, 0x01,
+               },
+               nil,
+               []byte{0x2e, 0x5a, 0x19, 0xdb, 0x4d, 0x19, 0x62, 0xd6}},
+       { // 22
+               []byte{
+                       0x10, 0x07, 0x91, 0x19, 0x98, 0x1a, 0x08, 0x01,
+                       0x10, 0x07, 0x91, 0x19, 0x98, 0x1a, 0x08, 0x01,
+                       0x10, 0x07, 0x91, 0x19, 0x98, 0x1a, 0x08, 0x01,
+               },
+               nil,
+               []byte{0x23, 0xa8, 0x66, 0xa8, 0x09, 0xd3, 0x08, 0x94}},
+       { // 23
+               []byte{
+                       0x10, 0x07, 0x92, 0x10, 0x98, 0x19, 0x01, 0x01,
+                       0x10, 0x07, 0x92, 0x10, 0x98, 0x19, 0x01, 0x01,
+                       0x10, 0x07, 0x92, 0x10, 0x98, 0x19, 0x01, 0x01,
+               },
+               nil,
+               []byte{0xd8, 0x12, 0xd9, 0x61, 0xf0, 0x17, 0xd3, 0x20}},
+       { // 24
+               []byte{
+                       0x10, 0x07, 0x91, 0x15, 0x98, 0x19, 0x01, 0x0b,
+                       0x10, 0x07, 0x91, 0x15, 0x98, 0x19, 0x01, 0x0b,
+                       0x10, 0x07, 0x91, 0x15, 0x98, 0x19, 0x01, 0x0b,
+               },
+               nil,
+               []byte{0x05, 0x56, 0x05, 0x81, 0x6e, 0x58, 0x60, 0x8f}},
+       { // 25
+               []byte{
+                       0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x01,
+                       0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x01,
+                       0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x01,
+               },
+               nil,
+               []byte{0xab, 0xd8, 0x8e, 0x8b, 0x1b, 0x77, 0x16, 0xf1}},
+       { // 26
+               []byte{
+                       0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x02,
+                       0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x02,
+                       0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x02,
+               },
+               nil,
+               []byte{0x53, 0x7a, 0xc9, 0x5b, 0xe6, 0x9d, 0xa1, 0xe1}},
+       { // 27
+               []byte{
+                       0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x08,
+                       0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x08,
+                       0x10, 0x04, 0x80, 0x15, 0x98, 0x19, 0x01, 0x08,
+               },
+               nil,
+               []byte{0xae, 0xd0, 0xf6, 0xae, 0x3c, 0x25, 0xcd, 0xd8}},
+       { // 28
+               []byte{
+                       0x10, 0x02, 0x91, 0x15, 0x98, 0x10, 0x01, 0x04,
+                       0x10, 0x02, 0x91, 0x15, 0x98, 0x10, 0x01, 0x04,
+                       0x10, 0x02, 0x91, 0x15, 0x98, 0x10, 0x01, 0x04,
+               },
+               nil,
+               []byte{0xb3, 0xe3, 0x5a, 0x5e, 0xe5, 0x3e, 0x7b, 0x8d}},
+       { // 29
+               []byte{
+                       0x10, 0x02, 0x91, 0x15, 0x98, 0x19, 0x01, 0x04,
+                       0x10, 0x02, 0x91, 0x15, 0x98, 0x19, 0x01, 0x04,
+                       0x10, 0x02, 0x91, 0x15, 0x98, 0x19, 0x01, 0x04,
+               },
+               nil,
+               []byte{0x61, 0xc7, 0x9c, 0x71, 0x92, 0x1a, 0x2e, 0xf8}},
+       { // 30
+               []byte{
+                       0x10, 0x02, 0x91, 0x15, 0x98, 0x10, 0x02, 0x01,
+                       0x10, 0x02, 0x91, 0x15, 0x98, 0x10, 0x02, 0x01,
+                       0x10, 0x02, 0x91, 0x15, 0x98, 0x10, 0x02, 0x01,
+               },
+               nil,
+               []byte{0xe2, 0xf5, 0x72, 0x8f, 0x09, 0x95, 0x01, 0x3c}},
+       { // 31
+               []byte{
+                       0x10, 0x02, 0x91, 0x16, 0x98, 0x10, 0x01, 0x01,
+                       0x10, 0x02, 0x91, 0x16, 0x98, 0x10, 0x01, 0x01,
+                       0x10, 0x02, 0x91, 0x16, 0x98, 0x10, 0x01, 0x01,
+               },
+               nil,
+               []byte{0x1a, 0xea, 0xc3, 0x9a, 0x61, 0xf0, 0xa4, 0x64}},
+}
+
+// Table A.4 Values To Be Used for the Substitution Table Known Answer Test
+var tableA4Tests = []CryptTest{
+       { // 0
+               []byte{
+                       0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57,
+                       0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57,
+                       0x7c, 0xa1, 0x10, 0x45, 0x4a, 0x1a, 0x6e, 0x57},
+               []byte{0x01, 0xa1, 0xd6, 0xd0, 0x39, 0x77, 0x67, 0x42},
+               []byte{0x69, 0x0f, 0x5b, 0x0d, 0x9a, 0x26, 0x93, 0x9b}},
+       { // 1
+               []byte{
+                       0x01, 0x31, 0xd9, 0x61, 0x9d, 0xc1, 0x37, 0x6e,
+                       0x01, 0x31, 0xd9, 0x61, 0x9d, 0xc1, 0x37, 0x6e,
+                       0x01, 0x31, 0xd9, 0x61, 0x9d, 0xc1, 0x37, 0x6e},
+               []byte{0x5c, 0xd5, 0x4c, 0xa8, 0x3d, 0xef, 0x57, 0xda},
+               []byte{0x7a, 0x38, 0x9d, 0x10, 0x35, 0x4b, 0xd2, 0x71}},
+       { // 2
+               []byte{
+                       0x07, 0xa1, 0x13, 0x3e, 0x4a, 0x0b, 0x26, 0x86,
+                       0x07, 0xa1, 0x13, 0x3e, 0x4a, 0x0b, 0x26, 0x86,
+                       0x07, 0xa1, 0x13, 0x3e, 0x4a, 0x0b, 0x26, 0x86},
+               []byte{0x02, 0x48, 0xd4, 0x38, 0x06, 0xf6, 0x71, 0x72},
+               []byte{0x86, 0x8e, 0xbb, 0x51, 0xca, 0xb4, 0x59, 0x9a}},
+       { // 3
+               []byte{
+                       0x38, 0x49, 0x67, 0x4c, 0x26, 0x02, 0x31, 0x9e,
+                       0x38, 0x49, 0x67, 0x4c, 0x26, 0x02, 0x31, 0x9e,
+                       0x38, 0x49, 0x67, 0x4c, 0x26, 0x02, 0x31, 0x9e},
+               []byte{0x51, 0x45, 0x4b, 0x58, 0x2d, 0xdf, 0x44, 0x0a},
+               []byte{0x71, 0x78, 0x87, 0x6e, 0x01, 0xf1, 0x9b, 0x2a}},
+       { // 4
+               []byte{
+                       0x04, 0xb9, 0x15, 0xba, 0x43, 0xfe, 0xb5, 0xb6,
+                       0x04, 0xb9, 0x15, 0xba, 0x43, 0xfe, 0xb5, 0xb6,
+                       0x04, 0xb9, 0x15, 0xba, 0x43, 0xfe, 0xb5, 0xb6},
+               []byte{0x42, 0xfd, 0x44, 0x30, 0x59, 0x57, 0x7f, 0xa2},
+               []byte{0xaf, 0x37, 0xfb, 0x42, 0x1f, 0x8c, 0x40, 0x95}},
+       { // 5
+               []byte{
+                       0x01, 0x13, 0xb9, 0x70, 0xfd, 0x34, 0xf2, 0xce,
+                       0x01, 0x13, 0xb9, 0x70, 0xfd, 0x34, 0xf2, 0xce,
+                       0x01, 0x13, 0xb9, 0x70, 0xfd, 0x34, 0xf2, 0xce},
+               []byte{0x05, 0x9b, 0x5e, 0x08, 0x51, 0xcf, 0x14, 0x3a},
+               []byte{0x86, 0xa5, 0x60, 0xf1, 0x0e, 0xc6, 0xd8, 0x5b}},
+       { // 6
+               []byte{
+                       0x01, 0x70, 0xf1, 0x75, 0x46, 0x8f, 0xb5, 0xe6,
+                       0x01, 0x70, 0xf1, 0x75, 0x46, 0x8f, 0xb5, 0xe6,
+                       0x01, 0x70, 0xf1, 0x75, 0x46, 0x8f, 0xb5, 0xe6},
+               []byte{0x07, 0x56, 0xd8, 0xe0, 0x77, 0x47, 0x61, 0xd2},
+               []byte{0x0c, 0xd3, 0xda, 0x02, 0x00, 0x21, 0xdc, 0x09}},
+       { // 7
+               []byte{
+                       0x43, 0x29, 0x7f, 0xad, 0x38, 0xe3, 0x73, 0xfe,
+                       0x43, 0x29, 0x7f, 0xad, 0x38, 0xe3, 0x73, 0xfe,
+                       0x43, 0x29, 0x7f, 0xad, 0x38, 0xe3, 0x73, 0xfe},
+               []byte{0x76, 0x25, 0x14, 0xb8, 0x29, 0xbf, 0x48, 0x6a},
+               []byte{0xea, 0x67, 0x6b, 0x2c, 0xb7, 0xdb, 0x2b, 0x7a}},
+       { // 8
+               []byte{
+                       0x07, 0xa7, 0x13, 0x70, 0x45, 0xda, 0x2a, 0x16,
+                       0x07, 0xa7, 0x13, 0x70, 0x45, 0xda, 0x2a, 0x16,
+                       0x07, 0xa7, 0x13, 0x70, 0x45, 0xda, 0x2a, 0x16},
+               []byte{0x3b, 0xdd, 0x11, 0x90, 0x49, 0x37, 0x28, 0x02},
+               []byte{0xdf, 0xd6, 0x4a, 0x81, 0x5c, 0xaf, 0x1a, 0x0f}},
+       { // 9
+               []byte{
+                       0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd, 0x3b, 0x2f,
+                       0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd, 0x3b, 0x2f,
+                       0x04, 0x68, 0x91, 0x04, 0xc2, 0xfd, 0x3b, 0x2f},
+               []byte{0x26, 0x95, 0x5f, 0x68, 0x35, 0xaf, 0x60, 0x9a},
+               []byte{0x5c, 0x51, 0x3c, 0x9c, 0x48, 0x86, 0xc0, 0x88}},
+       { // 10
+               []byte{
+                       0x37, 0xd0, 0x6b, 0xb5, 0x16, 0xcb, 0x75, 0x46,
+                       0x37, 0xd0, 0x6b, 0xb5, 0x16, 0xcb, 0x75, 0x46,
+                       0x37, 0xd0, 0x6b, 0xb5, 0x16, 0xcb, 0x75, 0x46},
+               []byte{0x16, 0x4d, 0x5e, 0x40, 0x4f, 0x27, 0x52, 0x32},
+               []byte{0x0a, 0x2a, 0xee, 0xae, 0x3f, 0xf4, 0xab, 0x77}},
+       { // 11
+               []byte{
+                       0x1f, 0x08, 0x26, 0x0d, 0x1a, 0xc2, 0x46, 0x5e,
+                       0x1f, 0x08, 0x26, 0x0d, 0x1a, 0xc2, 0x46, 0x5e,
+                       0x1f, 0x08, 0x26, 0x0d, 0x1a, 0xc2, 0x46, 0x5e},
+               []byte{0x6b, 0x05, 0x6e, 0x18, 0x75, 0x9f, 0x5c, 0xca},
+               []byte{0xef, 0x1b, 0xf0, 0x3e, 0x5d, 0xfa, 0x57, 0x5a}},
+       { // 12
+               []byte{
+                       0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76,
+                       0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76,
+                       0x58, 0x40, 0x23, 0x64, 0x1a, 0xba, 0x61, 0x76},
+               []byte{0x00, 0x4b, 0xd6, 0xef, 0x09, 0x17, 0x60, 0x62},
+               []byte{0x88, 0xbf, 0x0d, 0xb6, 0xd7, 0x0d, 0xee, 0x56}},
+       { // 13
+               []byte{
+                       0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xb0, 0x07,
+                       0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xb0, 0x07,
+                       0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xb0, 0x07},
+               []byte{0x48, 0x0d, 0x39, 0x00, 0x6e, 0xe7, 0x62, 0xf2},
+               []byte{0xa1, 0xf9, 0x91, 0x55, 0x41, 0x02, 0x0b, 0x56}},
+       { // 14
+               []byte{
+                       0x49, 0x79, 0x3e, 0xbc, 0x79, 0xb3, 0x25, 0x8f,
+                       0x49, 0x79, 0x3e, 0xbc, 0x79, 0xb3, 0x25, 0x8f,
+                       0x49, 0x79, 0x3e, 0xbc, 0x79, 0xb3, 0x25, 0x8f},
+               []byte{0x43, 0x75, 0x40, 0xc8, 0x69, 0x8f, 0x3c, 0xfa},
+               []byte{0x6f, 0xbf, 0x1c, 0xaf, 0xcf, 0xfd, 0x05, 0x56}},
+       { // 15
+               []byte{
+                       0x4f, 0xb0, 0x5e, 0x15, 0x15, 0xab, 0x73, 0xa7,
+                       0x4f, 0xb0, 0x5e, 0x15, 0x15, 0xab, 0x73, 0xa7,
+                       0x4f, 0xb0, 0x5e, 0x15, 0x15, 0xab, 0x73, 0xa7},
+               []byte{0x07, 0x2d, 0x43, 0xa0, 0x77, 0x07, 0x52, 0x92},
+               []byte{0x2f, 0x22, 0xe4, 0x9b, 0xab, 0x7c, 0xa1, 0xac}},
+       { // 16
+               []byte{
+                       0x49, 0xe9, 0x5d, 0x6d, 0x4c, 0xa2, 0x29, 0xbf,
+                       0x49, 0xe9, 0x5d, 0x6d, 0x4c, 0xa2, 0x29, 0xbf,
+                       0x49, 0xe9, 0x5d, 0x6d, 0x4c, 0xa2, 0x29, 0xbf},
+               []byte{0x02, 0xfe, 0x55, 0x77, 0x81, 0x17, 0xf1, 0x2a},
+               []byte{0x5a, 0x6b, 0x61, 0x2c, 0xc2, 0x6c, 0xce, 0x4a}},
+       { // 17
+               []byte{
+                       0x01, 0x83, 0x10, 0xdc, 0x40, 0x9b, 0x26, 0xd6,
+                       0x01, 0x83, 0x10, 0xdc, 0x40, 0x9b, 0x26, 0xd6,
+                       0x01, 0x83, 0x10, 0xdc, 0x40, 0x9b, 0x26, 0xd6},
+               []byte{0x1d, 0x9d, 0x5c, 0x50, 0x18, 0xf7, 0x28, 0xc2},
+               []byte{0x5f, 0x4c, 0x03, 0x8e, 0xd1, 0x2b, 0x2e, 0x41}},
+       { // 18
+               []byte{
+                       0x1c, 0x58, 0x7f, 0x1c, 0x13, 0x92, 0x4f, 0xef,
+                       0x1c, 0x58, 0x7f, 0x1c, 0x13, 0x92, 0x4f, 0xef,
+                       0x1c, 0x58, 0x7f, 0x1c, 0x13, 0x92, 0x4f, 0xef},
+               []byte{0x30, 0x55, 0x32, 0x28, 0x6d, 0x6f, 0x29, 0x5a},
+               []byte{0x63, 0xfa, 0xc0, 0xd0, 0x34, 0xd9, 0xf7, 0x93}},
+}
+
+// Use the known weak keys to test DES implementation
+func TestWeakKeys(t *testing.T) {
+       for i, tt := range weakKeyTests {
+               var encrypt = func(in []byte) (out []byte) {
+                       c, _ := NewCipher(tt.key)
+                       out = make([]byte, len(in))
+                       encryptBlock(c.subkeys[:], out, in)
+                       return
+               }
+
+               // Encrypting twice with a DES weak
+               // key should reproduce the original input
+               result := encrypt(tt.in)
+               result = encrypt(result)
+
+               if !bytes.Equal(result, tt.in) {
+                       t.Errorf("#%d: result: %x want: %x", i, result, tt.in)
+               }
+       }
+}
+
+// Use the known semi-weak key pairs to test DES implementation
+func TestSemiWeakKeyPairs(t *testing.T) {
+       for i, tt := range semiWeakKeyTests {
+               var encrypt = func(key, in []byte) (out []byte) {
+                       c, _ := NewCipher(key)
+                       out = make([]byte, len(in))
+                       encryptBlock(c.subkeys[:], out, in)
+                       return
+               }
+
+               // Encrypting with one member of the semi-weak pair
+               // and then encrypting the result with the other member
+               // should reproduce the original input.
+               result := encrypt(tt.key, tt.in)
+               result = encrypt(tt.out, result)
+
+               if !bytes.Equal(result, tt.in) {
+                       t.Errorf("#%d: result: %x want: %x", i, result, tt.in)
+               }
+       }
+}
+
+func TestDESEncryptBlock(t *testing.T) {
+       for i, tt := range encryptDESTests {
+               c, _ := NewCipher(tt.key)
+               out := make([]byte, len(tt.in))
+               encryptBlock(c.subkeys[:], out, tt.in)
+
+               if !bytes.Equal(out, tt.out) {
+                       t.Errorf("#%d: result: %x want: %x", i, out, tt.out)
+               }
+       }
+}
+
+func TestDESDecryptBlock(t *testing.T) {
+       for i, tt := range encryptDESTests {
+               c, _ := NewCipher(tt.key)
+               plain := make([]byte, len(tt.in))
+               decryptBlock(c.subkeys[:], plain, tt.out)
+
+               if !bytes.Equal(plain, tt.in) {
+                       t.Errorf("#%d: result: %x want: %x", i, plain, tt.in)
+               }
+       }
+}
+
+func TestEncryptTripleDES(t *testing.T) {
+       for i, tt := range encryptTripleDESTests {
+               c, _ := NewTripleDESCipher(tt.key)
+               out := make([]byte, len(tt.in))
+               c.Encrypt(out, tt.in)
+
+               if !bytes.Equal(out, tt.out) {
+                       t.Errorf("#%d: result: %x want: %x", i, out, tt.out)
+               }
+       }
+}
+
+func TestDecryptTripleDES(t *testing.T) {
+       for i, tt := range encryptTripleDESTests {
+               c, _ := NewTripleDESCipher(tt.key)
+
+               plain := make([]byte, len(tt.in))
+               c.Decrypt(plain, tt.out)
+
+               if !bytes.Equal(plain, tt.in) {
+                       t.Errorf("#%d: result: %x want: %x", i, plain, tt.in)
+               }
+       }
+}
+
+// Defined in Pub 800-20
+func TestVariablePlaintextKnownAnswer(t *testing.T) {
+       for i, tt := range tableA1Tests {
+               c, _ := NewTripleDESCipher(tableA1Key)
+
+               out := make([]byte, len(tt.in))
+               c.Encrypt(out, tt.in)
+
+               if !bytes.Equal(out, tt.out) {
+                       t.Errorf("#%d: result: %x want: %x", i, out, tt.out)
+               }
+       }
+}
+
+// Defined in Pub 800-20
+func TestVariableCiphertextKnownAnswer(t *testing.T) {
+       for i, tt := range tableA1Tests {
+               c, _ := NewTripleDESCipher(tableA1Key)
+
+               plain := make([]byte, len(tt.out))
+               c.Decrypt(plain, tt.out)
+
+               if !bytes.Equal(plain, tt.in) {
+                       t.Errorf("#%d: result: %x want: %x", i, plain, tt.in)
+               }
+       }
+}
+
+// Defined in Pub 800-20
+// Encrypting the Table A.1 ciphertext with the
+// 0x01... key produces the original plaintext
+func TestInversePermutationKnownAnswer(t *testing.T) {
+       for i, tt := range tableA1Tests {
+               c, _ := NewTripleDESCipher(tableA1Key)
+
+               plain := make([]byte, len(tt.in))
+               c.Encrypt(plain, tt.out)
+
+               if !bytes.Equal(plain, tt.in) {
+                       t.Errorf("#%d: result: %x want: %x", i, plain, tt.in)
+               }
+       }
+}
+
+// Defined in Pub 800-20
+// Decrypting the Table A.1 plaintext with the
+// 0x01... key produces the corresponding ciphertext
+func TestInitialPermutationKnownAnswer(t *testing.T) {
+       for i, tt := range tableA1Tests {
+               c, _ := NewTripleDESCipher(tableA1Key)
+
+               out := make([]byte, len(tt.in))
+               c.Decrypt(out, tt.in)
+
+               if !bytes.Equal(out, tt.out) {
+                       t.Errorf("#%d: result: %x want: %x", i, out, tt.out)
+               }
+       }
+}
+
+// Defined in Pub 800-20
+func TestVariableKeyKnownAnswerEncrypt(t *testing.T) {
+       for i, tt := range tableA2Tests {
+               c, _ := NewTripleDESCipher(tt.key)
+
+               out := make([]byte, len(tableA2Plaintext))
+               c.Encrypt(out, tableA2Plaintext)
+
+               if !bytes.Equal(out, tt.out) {
+                       t.Errorf("#%d: result: %x want: %x", i, out, tt.out)
+               }
+       }
+}
+
+// Defined in Pub 800-20
+func TestVariableKeyKnownAnswerDecrypt(t *testing.T) {
+       for i, tt := range tableA2Tests {
+               c, _ := NewTripleDESCipher(tt.key)
+
+               out := make([]byte, len(tt.out))
+               c.Decrypt(out, tt.out)
+
+               if !bytes.Equal(out, tableA2Plaintext) {
+                       t.Errorf("#%d: result: %x want: %x", i, out, tableA2Plaintext)
+               }
+       }
+}
+
+// Defined in Pub 800-20
+func TestPermutationOperationKnownAnswerEncrypt(t *testing.T) {
+       for i, tt := range tableA3Tests {
+               c, _ := NewTripleDESCipher(tt.key)
+
+               out := make([]byte, len(tableA3Plaintext))
+               c.Encrypt(out, tableA3Plaintext)
+
+               if !bytes.Equal(out, tt.out) {
+                       t.Errorf("#%d: result: %x want: %x", i, out, tt.out)
+               }
+       }
+}
+
+// Defined in Pub 800-20
+func TestPermutationOperationKnownAnswerDecrypt(t *testing.T) {
+       for i, tt := range tableA3Tests {
+               c, _ := NewTripleDESCipher(tt.key)
+
+               out := make([]byte, len(tt.out))
+               c.Decrypt(out, tt.out)
+
+               if !bytes.Equal(out, tableA3Plaintext) {
+                       t.Errorf("#%d: result: %x want: %x", i, out, tableA3Plaintext)
+               }
+       }
+}
+
+// Defined in Pub 800-20
+func TestSubstitutionTableKnownAnswerEncrypt(t *testing.T) {
+       for i, tt := range tableA4Tests {
+               c, _ := NewTripleDESCipher(tt.key)
+
+               out := make([]byte, len(tt.in))
+               c.Encrypt(out, tt.in)
+
+               if !bytes.Equal(out, tt.out) {
+                       t.Errorf("#%d: result: %x want: %x", i, out, tt.out)
+               }
+       }
+}
+
+// Defined in Pub 800-20
+func TestSubstitutionTableKnownAnswerDecrypt(t *testing.T) {
+       for i, tt := range tableA4Tests {
+               c, _ := NewTripleDESCipher(tt.key)
+
+               out := make([]byte, len(tt.out))
+               c.Decrypt(out, tt.out)
+
+               if !bytes.Equal(out, tt.in) {
+                       t.Errorf("#%d: result: %x want: %x", i, out, tt.in)
+               }
+       }
+}
index 1f37849..7bce1bc 100644 (file)
@@ -37,7 +37,7 @@ var one = new(big.Int).SetInt64(1)
 // curve using the procedure given in [NSA] A.2.1.
 func randFieldElement(c *elliptic.Curve, rand io.Reader) (k *big.Int, err os.Error) {
        b := make([]byte, c.BitSize/8+8)
-       _, err = rand.Read(b)
+       _, err = io.ReadFull(rand, b)
        if err != nil {
                return
        }
index 66b72c0..3a06aa8 100644 (file)
@@ -32,7 +32,7 @@ func (r *devReader) Read(b []byte) (n int, err os.Error) {
        r.mu.Lock()
        defer r.mu.Unlock()
        if r.f == nil {
-               f, err := os.Open(r.name, os.O_RDONLY, 0)
+               f, err := os.Open(r.name)
                if f == nil {
                        return 0, err
                }
index 2eaadee..9a71841 100644 (file)
@@ -127,7 +127,7 @@ func nonZeroRandomBytes(s []byte, rand io.Reader) (err os.Error) {
 
        for i := 0; i < len(s); i++ {
                for s[i] == 0 {
-                       _, err = rand.Read(s[i : i+1])
+                       _, err = io.ReadFull(rand, s[i:i+1])
                        if err != nil {
                                return
                        }
index faf9149..b3b212c 100644 (file)
@@ -13,6 +13,7 @@ import (
        "hash"
        "io"
        "os"
+       "sync"
 )
 
 var bigZero = big.NewInt(0)
@@ -91,15 +92,21 @@ type PublicKey struct {
 type PrivateKey struct {
        PublicKey          // public part.
        D         *big.Int // private exponent
-       P, Q      *big.Int // prime factors of N
+       P, Q, R   *big.Int // prime factors of N (R may be nil)
+
+       rwMutex    sync.RWMutex // protects the following
+       dP, dQ, dR *big.Int     // D mod (P-1) (or mod Q-1 etc) 
+       qInv       *big.Int     // q^-1 mod p
+       pq         *big.Int     // P*Q
+       tr         *big.Int     // pq·tr ≡ 1 mod r
 }
 
 // Validate performs basic sanity checks on the key.
 // It returns nil if the key is valid, or else an os.Error describing a problem.
 
-func (priv PrivateKey) Validate() os.Error {
-       // Check that p and q are prime. Note that this is just a sanity
-       // check. Since the random witnesses chosen by ProbablyPrime are
+func (priv *PrivateKey) Validate() os.Error {
+       // Check that p, q and, maybe, r are prime. Note that this is just a
+       // sanity check. Since the random witnesses chosen by ProbablyPrime are
        // deterministic, given the candidate number, it's easy for an attack
        // to generate composites that pass this test.
        if !big.ProbablyPrime(priv.P, 20) {
@@ -108,16 +115,26 @@ func (priv PrivateKey) Validate() os.Error {
        if !big.ProbablyPrime(priv.Q, 20) {
                return os.ErrorString("Q is composite")
        }
+       if priv.R != nil && !big.ProbablyPrime(priv.R, 20) {
+               return os.ErrorString("R is composite")
+       }
 
-       // Check that p*q == n.
+       // Check that p*q*r == n.
        modulus := new(big.Int).Mul(priv.P, priv.Q)
+       if priv.R != nil {
+               modulus.Mul(modulus, priv.R)
+       }
        if modulus.Cmp(priv.N) != 0 {
                return os.ErrorString("invalid modulus")
        }
-       // Check that e and totient(p, q) are coprime.
+       // Check that e and totient(p, q, r) are coprime.
        pminus1 := new(big.Int).Sub(priv.P, bigOne)
        qminus1 := new(big.Int).Sub(priv.Q, bigOne)
        totient := new(big.Int).Mul(pminus1, qminus1)
+       if priv.R != nil {
+               rminus1 := new(big.Int).Sub(priv.R, bigOne)
+               totient.Mul(totient, rminus1)
+       }
        e := big.NewInt(int64(priv.E))
        gcd := new(big.Int)
        x := new(big.Int)
@@ -126,7 +143,7 @@ func (priv PrivateKey) Validate() os.Error {
        if gcd.Cmp(bigOne) != 0 {
                return os.ErrorString("invalid public exponent E")
        }
-       // Check that de ≡ 1 (mod totient(p, q))
+       // Check that de ≡ 1 (mod totient(p, q, r))
        de := new(big.Int).Mul(priv.D, e)
        de.Mod(de, totient)
        if de.Cmp(bigOne) != 0 {
@@ -135,7 +152,7 @@ func (priv PrivateKey) Validate() os.Error {
        return nil
 }
 
-// GenerateKeyPair generates an RSA keypair of the given bit size.
+// GenerateKey generates an RSA keypair of the given bit size.
 func GenerateKey(rand io.Reader, bits int) (priv *PrivateKey, err os.Error) {
        priv = new(PrivateKey)
        // Smaller public exponents lead to faster public key
@@ -191,6 +208,77 @@ func GenerateKey(rand io.Reader, bits int) (priv *PrivateKey, err os.Error) {
        return
 }
 
+// Generate3PrimeKey generates a 3-prime RSA keypair of the given bit size, as
+// suggested in [1]. Although the public keys are compatible (actually,
+// indistinguishable) from the 2-prime case, the private keys are not. Thus it
+// may not be possible to export 3-prime private keys in certain formats or to
+// subsequently import them into other code.
+//
+// Table 1 in [2] suggests that size should be >= 1024 when using 3 primes.
+//
+// [1] US patent 4405829 (1972, expired)
+// [2] http://www.cacr.math.uwaterloo.ca/techreports/2006/cacr2006-16.pdf
+func Generate3PrimeKey(rand io.Reader, bits int) (priv *PrivateKey, err os.Error) {
+       priv = new(PrivateKey)
+       priv.E = 3
+
+       pminus1 := new(big.Int)
+       qminus1 := new(big.Int)
+       rminus1 := new(big.Int)
+       totient := new(big.Int)
+
+       for {
+               p, err := randomPrime(rand, bits/3)
+               if err != nil {
+                       return nil, err
+               }
+
+               todo := bits - p.BitLen()
+               q, err := randomPrime(rand, todo/2)
+               if err != nil {
+                       return nil, err
+               }
+
+               todo -= q.BitLen()
+               r, err := randomPrime(rand, todo)
+               if err != nil {
+                       return nil, err
+               }
+
+               if p.Cmp(q) == 0 ||
+                       q.Cmp(r) == 0 ||
+                       r.Cmp(p) == 0 {
+                       continue
+               }
+
+               n := new(big.Int).Mul(p, q)
+               n.Mul(n, r)
+               pminus1.Sub(p, bigOne)
+               qminus1.Sub(q, bigOne)
+               rminus1.Sub(r, bigOne)
+               totient.Mul(pminus1, qminus1)
+               totient.Mul(totient, rminus1)
+
+               g := new(big.Int)
+               priv.D = new(big.Int)
+               y := new(big.Int)
+               e := big.NewInt(int64(priv.E))
+               big.GcdInt(g, priv.D, y, e, totient)
+
+               if g.Cmp(bigOne) == 0 {
+                       priv.D.Add(priv.D, totient)
+                       priv.P = p
+                       priv.Q = q
+                       priv.R = r
+                       priv.N = n
+
+                       break
+               }
+       }
+
+       return
+}
+
 // incCounter increments a four byte, big-endian counter.
 func incCounter(c *[4]byte) {
        if c[3]++; c[3] != 0 {
@@ -321,6 +409,26 @@ func modInverse(a, n *big.Int) (ia *big.Int, ok bool) {
        return x, true
 }
 
+// precompute performs some calculations that speed up private key operations
+// in the future.
+func (priv *PrivateKey) precompute() {
+       priv.dP = new(big.Int).Sub(priv.P, bigOne)
+       priv.dP.Mod(priv.D, priv.dP)
+
+       priv.dQ = new(big.Int).Sub(priv.Q, bigOne)
+       priv.dQ.Mod(priv.D, priv.dQ)
+
+       priv.qInv = new(big.Int).ModInverse(priv.Q, priv.P)
+
+       if priv.R != nil {
+               priv.dR = new(big.Int).Sub(priv.R, bigOne)
+               priv.dR.Mod(priv.D, priv.dR)
+
+               priv.pq = new(big.Int).Mul(priv.P, priv.Q)
+               priv.tr = new(big.Int).ModInverse(priv.pq, priv.R)
+       }
+}
+
 // decrypt performs an RSA decryption, resulting in a plaintext integer. If a
 // random source is given, RSA blinding is used.
 func decrypt(rand io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err os.Error) {
@@ -359,7 +467,48 @@ func decrypt(rand io.Reader, priv *PrivateKey, c *big.Int) (m *big.Int, err os.E
                c.Mod(c, priv.N)
        }
 
-       m = new(big.Int).Exp(c, priv.D, priv.N)
+       priv.rwMutex.RLock()
+
+       if priv.dP == nil && priv.P != nil {
+               priv.rwMutex.RUnlock()
+               priv.rwMutex.Lock()
+               if priv.dP == nil && priv.P != nil {
+                       priv.precompute()
+               }
+               priv.rwMutex.Unlock()
+               priv.rwMutex.RLock()
+       }
+
+       if priv.dP == nil {
+               m = new(big.Int).Exp(c, priv.D, priv.N)
+       } else {
+               // We have the precalculated values needed for the CRT.
+               m = new(big.Int).Exp(c, priv.dP, priv.P)
+               m2 := new(big.Int).Exp(c, priv.dQ, priv.Q)
+               m.Sub(m, m2)
+               if m.Sign() < 0 {
+                       m.Add(m, priv.P)
+               }
+               m.Mul(m, priv.qInv)
+               m.Mod(m, priv.P)
+               m.Mul(m, priv.Q)
+               m.Add(m, m2)
+
+               if priv.dR != nil {
+                       // 3-prime CRT.
+                       m2.Exp(c, priv.dR, priv.R)
+                       m2.Sub(m2, m)
+                       m2.Mul(m2, priv.tr)
+                       m2.Mod(m2, priv.R)
+                       if m2.Sign() < 0 {
+                               m2.Add(m2, priv.R)
+                       }
+                       m2.Mul(m2, priv.pq)
+                       m.Add(m, m2)
+               }
+       }
+
+       priv.rwMutex.RUnlock()
 
        if ir != nil {
                // Unblind.
index bf7c051..d8a936e 100644 (file)
@@ -13,28 +13,48 @@ import (
 )
 
 func TestKeyGeneration(t *testing.T) {
-       random := rand.Reader
-
        size := 1024
        if testing.Short() {
                size = 128
        }
-       priv, err := GenerateKey(random, size)
+       priv, err := GenerateKey(rand.Reader, size)
+       if err != nil {
+               t.Errorf("failed to generate key")
+       }
+       testKeyBasics(t, priv)
+}
+
+func Test3PrimeKeyGeneration(t *testing.T) {
+       if testing.Short() {
+               return
+       }
+
+       size := 768
+       priv, err := Generate3PrimeKey(rand.Reader, size)
        if err != nil {
                t.Errorf("failed to generate key")
        }
+       testKeyBasics(t, priv)
+}
+
+func testKeyBasics(t *testing.T, priv *PrivateKey) {
+       if err := priv.Validate(); err != nil {
+               t.Errorf("Validate() failed: %s", err)
+       }
+
        pub := &priv.PublicKey
        m := big.NewInt(42)
        c := encrypt(new(big.Int), pub, m)
        m2, err := decrypt(nil, priv, c)
        if err != nil {
                t.Errorf("error while decrypting: %s", err)
+               return
        }
        if m.Cmp(m2) != 0 {
-               t.Errorf("got:%v, want:%v (%s)", m2, m, priv)
+               t.Errorf("got:%v, want:%v (%+v)", m2, m, priv)
        }
 
-       m3, err := decrypt(random, priv, c)
+       m3, err := decrypt(rand.Reader, priv, c)
        if err != nil {
                t.Errorf("error while decrypting (blind): %s", err)
        }
@@ -43,6 +63,57 @@ func TestKeyGeneration(t *testing.T) {
        }
 }
 
+func fromBase10(base10 string) *big.Int {
+       i := new(big.Int)
+       i.SetString(base10, 10)
+       return i
+}
+
+func BenchmarkRSA2048Decrypt(b *testing.B) {
+       b.StopTimer()
+       priv := &PrivateKey{
+               PublicKey: PublicKey{
+                       N: fromBase10("14314132931241006650998084889274020608918049032671858325988396851334124245188214251956198731333464217832226406088020736932173064754214329009979944037640912127943488972644697423190955557435910767690712778463524983667852819010259499695177313115447116110358524558307947613422897787329221478860907963827160223559690523660574329011927531289655711860504630573766609239332569210831325633840174683944553667352219670930408593321661375473885147973879086994006440025257225431977751512374815915392249179976902953721486040787792801849818254465486633791826766873076617116727073077821584676715609985777563958286637185868165868520557"),
+                       E: 3,
+               },
+               D: fromBase10("9542755287494004433998723259516013739278699355114572217325597900889416163458809501304132487555642811888150937392013824621448709836142886006653296025093941418628992648429798282127303704957273845127141852309016655778568546006839666463451542076964744073572349705538631742281931858219480985907271975884773482372966847639853897890615456605598071088189838676728836833012254065983259638538107719766738032720239892094196108713378822882383694456030043492571063441943847195939549773271694647657549658603365629458610273821292232646334717612674519997533901052790334279661754176490593041941863932308687197618671528035670452762731"),
+               P: fromBase10("130903255182996722426771613606077755295583329135067340152947172868415809027537376306193179624298874215608270802054347609836776473930072411958753044562214537013874103802006369634761074377213995983876788718033850153719421695468704276694983032644416930879093914927146648402139231293035971427838068945045019075433"),
+               Q: fromBase10("109348945610485453577574767652527472924289229538286649661240938988020367005475727988253438647560958573506159449538793540472829815903949343191091817779240101054552748665267574271163617694640513549693841337820602726596756351006149518830932261246698766355347898158548465400674856021497190430791824869615170301029"),
+       }
+       priv.precompute()
+
+       c := fromBase10("1000")
+
+       b.StartTimer()
+
+       for i := 0; i < b.N; i++ {
+               decrypt(nil, priv, c)
+       }
+}
+
+func Benchmark3PrimeRSA2048Decrypt(b *testing.B) {
+       b.StopTimer()
+       priv := &PrivateKey{
+               PublicKey: PublicKey{
+                       N: fromBase10("16346378922382193400538269749936049106320265317511766357599732575277382844051791096569333808598921852351577762718529818072849191122419410612033592401403764925096136759934497687765453905884149505175426053037420486697072448609022753683683718057795566811401938833367954642951433473337066311978821180526439641496973296037000052546108507805269279414789035461158073156772151892452251106173507240488993608650881929629163465099476849643165682709047462010581308719577053905787496296934240246311806555924593059995202856826239801816771116902778517096212527979497399966526283516447337775509777558018145573127308919204297111496233"),
+                       E: 3,
+               },
+               D: fromBase10("10897585948254795600358846499957366070880176878341177571733155050184921896034527397712889205732614568234385175145686545381899460748279607074689061600935843283397424506622998458510302603922766336783617368686090042765718290914099334449154829375179958369993407724946186243249568928237086215759259909861748642124071874879861299389874230489928271621259294894142840428407196932444474088857746123104978617098858619445675532587787023228852383149557470077802718705420275739737958953794088728369933811184572620857678792001136676902250566845618813972833750098806496641114644760255910789397593428910198080271317419213080834885003"),
+               P: fromBase10("1025363189502892836833747188838978207017355117492483312747347695538428729137306368764177201532277413433182799108299960196606011786562992097313508180436744488171474690412562218914213688661311117337381958560443"),
+               Q: fromBase10("3467903426626310123395340254094941045497208049900750380025518552334536945536837294961497712862519984786362199788654739924501424784631315081391467293694361474867825728031147665777546570788493758372218019373"),
+               R: fromBase10("4597024781409332673052708605078359346966325141767460991205742124888960305710298765592730135879076084498363772408626791576005136245060321874472727132746643162385746062759369754202494417496879741537284589047"),
+       }
+       priv.precompute()
+
+       c := fromBase10("1000")
+
+       b.StartTimer()
+
+       for i := 0; i < b.N; i++ {
+               decrypt(nil, priv, c)
+       }
+}
+
 type testEncryptOAEPMessage struct {
        in   []byte
        seed []byte
@@ -85,10 +156,12 @@ func TestDecryptOAEP(t *testing.T) {
        for i, test := range testEncryptOAEPData {
                n.SetString(test.modulus, 16)
                d.SetString(test.d, 16)
-               private := PrivateKey{PublicKey{n, test.e}, d, nil, nil}
+               private := new(PrivateKey)
+               private.PublicKey = PublicKey{n, test.e}
+               private.D = d
 
                for j, message := range test.msgs {
-                       out, err := DecryptOAEP(sha1, nil, &private, message.out, nil)
+                       out, err := DecryptOAEP(sha1, nil, private, message.out, nil)
                        if err != nil {
                                t.Errorf("#%d,%d error: %s", i, j, err)
                        } else if bytes.Compare(out, message.in) != 0 {
@@ -96,7 +169,7 @@ func TestDecryptOAEP(t *testing.T) {
                        }
 
                        // Decrypt with blinding.
-                       out, err = DecryptOAEP(sha1, random, &private, message.out, nil)
+                       out, err = DecryptOAEP(sha1, random, private, message.out, nil)
                        if err != nil {
                                t.Errorf("#%d,%d (blind) error: %s", i, j, err)
                        } else if bytes.Compare(out, message.in) != 0 {
index ee77f94..5b8c700 100644 (file)
@@ -50,7 +50,7 @@ func main() {
                return
        }
 
-       certOut, err := os.Open("cert.pem", os.O_WRONLY|os.O_CREAT, 0644)
+       certOut, err := os.Create("cert.pem")
        if err != nil {
                log.Fatalf("failed to open cert.pem for writing: %s", err)
                return
@@ -59,7 +59,7 @@ func main() {
        certOut.Close()
        log.Print("written cert.pem\n")
 
-       keyOut, err := os.Open("key.pem", os.O_WRONLY|os.O_CREAT, 0600)
+       keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREAT|os.O_TRUNC, 0600)
        if err != nil {
                log.Print("failed to open key.pem for writing:", err)
                return
index f66449c..7de44bb 100644 (file)
@@ -124,7 +124,16 @@ func LoadX509KeyPair(certFile string, keyFile string) (cert Certificate, err os.
        if err != nil {
                return
        }
+       keyPEMBlock, err := ioutil.ReadFile(keyFile)
+       if err != nil {
+               return
+       }
+       return X509KeyPair(certPEMBlock, keyPEMBlock)
+}
 
+// X509KeyPair parses a public/private key pair from a pair of
+// PEM encoded data.
+func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (cert Certificate, err os.Error) {
        var certDERBlock *pem.Block
        for {
                certDERBlock, certPEMBlock = pem.Decode(certPEMBlock)
@@ -141,11 +150,6 @@ func LoadX509KeyPair(certFile string, keyFile string) (cert Certificate, err os.
                return
        }
 
-       keyPEMBlock, err := ioutil.ReadFile(keyFile)
-       if err != nil {
-               return
-       }
-
        keyDERBlock, _ := pem.Decode(keyPEMBlock)
        if keyDERBlock == nil {
                err = os.ErrorString("crypto/tls: failed to parse key PEM data")
index 853bcde..6825030 100644 (file)
@@ -54,20 +54,21 @@ func ParsePKCS1PrivateKey(der []byte) (key *rsa.PrivateKey, err os.Error) {
                return
        }
 
-       key = &rsa.PrivateKey{
-               PublicKey: rsa.PublicKey{
-                       E: priv.E,
-                       N: new(big.Int).SetBytes(priv.N.Bytes),
-               },
-               D: new(big.Int).SetBytes(priv.D.Bytes),
-               P: new(big.Int).SetBytes(priv.P.Bytes),
-               Q: new(big.Int).SetBytes(priv.Q.Bytes),
+       key = new(rsa.PrivateKey)
+       key.PublicKey = rsa.PublicKey{
+               E: priv.E,
+               N: new(big.Int).SetBytes(priv.N.Bytes),
        }
 
+       key.D = new(big.Int).SetBytes(priv.D.Bytes)
+       key.P = new(big.Int).SetBytes(priv.P.Bytes)
+       key.Q = new(big.Int).SetBytes(priv.Q.Bytes)
+
        err = key.Validate()
        if err != nil {
                return nil, err
        }
+
        return
 }
 
index 57889e7..d9511b8 100644 (file)
@@ -11,7 +11,6 @@ import (
        "crypto/rsa"
        "encoding/hex"
        "encoding/pem"
-       "reflect"
        "testing"
        "time"
 )
@@ -22,7 +21,11 @@ func TestParsePKCS1PrivateKey(t *testing.T) {
        if err != nil {
                t.Errorf("Failed to parse private key: %s", err)
        }
-       if !reflect.DeepEqual(priv, rsaPrivateKey) {
+       if priv.PublicKey.N.Cmp(rsaPrivateKey.PublicKey.N) != 0 ||
+               priv.PublicKey.E != rsaPrivateKey.PublicKey.E ||
+               priv.D.Cmp(rsaPrivateKey.D) != 0 ||
+               priv.P.Cmp(rsaPrivateKey.P) != 0 ||
+               priv.Q.Cmp(rsaPrivateKey.Q) != 0 {
                t.Errorf("got:%+v want:%+v", priv, rsaPrivateKey)
        }
 }
index e69317a..6fdcda6 100644 (file)
@@ -144,7 +144,7 @@ func (e *FormatError) String() string {
 
 // Open opens the named file using os.Open and prepares it for use as an ELF binary.
 func Open(name string) (*File, os.Error) {
-       f, err := os.Open(name, os.O_RDONLY, 0)
+       f, err := os.Open(name)
        if err != nil {
                return nil, err
        }
@@ -228,7 +228,7 @@ func NewFile(r io.ReaderAt) (*File, os.Error) {
        switch f.Class {
        case ELFCLASS32:
                hdr := new(Header32)
-               sr.Seek(0, 0)
+               sr.Seek(0, os.SEEK_SET)
                if err := binary.Read(sr, f.ByteOrder, hdr); err != nil {
                        return nil, err
                }
@@ -243,7 +243,7 @@ func NewFile(r io.ReaderAt) (*File, os.Error) {
                shstrndx = int(hdr.Shstrndx)
        case ELFCLASS64:
                hdr := new(Header64)
-               sr.Seek(0, 0)
+               sr.Seek(0, os.SEEK_SET)
                if err := binary.Read(sr, f.ByteOrder, hdr); err != nil {
                        return nil, err
                }
@@ -269,7 +269,7 @@ func NewFile(r io.ReaderAt) (*File, os.Error) {
        names := make([]uint32, shnum)
        for i := 0; i < shnum; i++ {
                off := shoff + int64(i)*int64(shentsize)
-               sr.Seek(off, 0)
+               sr.Seek(off, os.SEEK_SET)
                s := new(Section)
                switch f.Class {
                case ELFCLASS32:
index fd8da94..a777d87 100644 (file)
@@ -159,7 +159,7 @@ func (e *FormatError) String() string {
 
 // Open opens the named file using os.Open and prepares it for use as a Mach-O binary.
 func Open(name string) (*File, os.Error) {
-       f, err := os.Open(name, os.O_RDONLY, 0)
+       f, err := os.Open(name)
        if err != nil {
                return nil, err
        }
index 1bcbdc5..6a14e50 100644 (file)
@@ -87,7 +87,7 @@ func (e *FormatError) String() string {
 
 // Open opens the named file using os.Open and prepares it for use as a PE binary.
 func Open(name string) (*File, os.Error) {
-       f, err := os.Open(name, os.O_RDONLY, 0)
+       f, err := os.Open(name)
        if err != nil {
                return nil, err
        }
@@ -132,7 +132,7 @@ func NewFile(r io.ReaderAt) (*File, os.Error) {
        } else {
                base = int64(0)
        }
-       sr.Seek(base, 0)
+       sr.Seek(base, os.SEEK_SET)
        if err := binary.Read(sr, binary.LittleEndian, &f.FileHeader); err != nil {
                return nil, err
        }
@@ -140,7 +140,7 @@ func NewFile(r io.ReaderAt) (*File, os.Error) {
                return nil, os.NewError("Invalid PE File Format.")
        }
        // get symbol string table
-       sr.Seek(int64(f.FileHeader.PointerToSymbolTable+18*f.FileHeader.NumberOfSymbols), 0)
+       sr.Seek(int64(f.FileHeader.PointerToSymbolTable+18*f.FileHeader.NumberOfSymbols), os.SEEK_SET)
        var l uint32
        if err := binary.Read(sr, binary.LittleEndian, &l); err != nil {
                return nil, err
@@ -149,9 +149,9 @@ func NewFile(r io.ReaderAt) (*File, os.Error) {
        if _, err := r.ReadAt(ss, int64(f.FileHeader.PointerToSymbolTable+18*f.FileHeader.NumberOfSymbols)); err != nil {
                return nil, err
        }
-       sr.Seek(base, 0)
+       sr.Seek(base, os.SEEK_SET)
        binary.Read(sr, binary.LittleEndian, &f.FileHeader)
-       sr.Seek(int64(f.FileHeader.SizeOfOptionalHeader), 1) //Skip OptionalHeader
+       sr.Seek(int64(f.FileHeader.SizeOfOptionalHeader), os.SEEK_CUR) //Skip OptionalHeader
        f.Sections = make([]*Section, f.FileHeader.NumberOfSections)
        for i := 0; i < int(f.FileHeader.NumberOfSections); i++ {
                sh := new(SectionHeader32)
index 6890a22..17c8fa5 100644 (file)
@@ -1184,7 +1184,7 @@ func (p *process) attachThread(tid int) (*thread, os.Error) {
 // attachAllThreads attaches to all threads in a process.
 func (p *process) attachAllThreads() os.Error {
        taskPath := "/proc/" + strconv.Itoa(p.pid) + "/task"
-       taskDir, err := os.Open(taskPath, os.O_RDONLY, 0)
+       taskDir, err := os.Open(taskPath)
        if err != nil {
                return err
        }
index 44e3b65..5398eb8 100644 (file)
@@ -2,9 +2,13 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// The exec package runs external commands.
+// The exec package runs external commands. It wraps os.StartProcess
+// to make it easier to remap stdin and stdout, connect I/O with pipes,
+// and do other adjustments.
 package exec
 
+// BUG(r): This package should be made even easier to use or merged into os.
+
 import (
        "os"
        "strconv"
@@ -49,7 +53,7 @@ func modeToFiles(mode, fd int) (*os.File, *os.File, os.Error) {
                if fd == 0 {
                        rw = os.O_RDONLY
                }
-               f, err := os.Open(os.DevNull, rw, 0)
+               f, err := os.OpenFile(os.DevNull, rw, 0)
                return f, nil, err
        case PassThrough:
                switch fd {
index 896dedf..d48936a 100644 (file)
@@ -53,7 +53,7 @@ func readAuth(displayStr string) (name, data string, err os.Error) {
                }
                fn = home + "/.Xauthority"
        }
-       r, err := os.Open(fn, os.O_RDONLY, 0444)
+       r, err := os.Open(fn)
        if err != nil {
                return
        }
index ba056e8..813d3a8 100644 (file)
@@ -170,7 +170,7 @@ func cmdLoad(args []byte) os.Error {
        }
 
        // Get symbols
-       f, err := os.Open(fname, os.O_RDONLY, 0)
+       f, err := os.Open(fname)
        if err != nil {
                tproc.Detach()
                return err
index 4d308ac..3766c83 100644 (file)
@@ -139,7 +139,17 @@ var fmttests = []struct {
        {"%5s", "abc", "  abc"},
        {"%2s", "\u263a", " \u263a"},
        {"%-5s", "abc", "abc  "},
+       {"%-8q", "abc", `"abc"   `},
        {"%05s", "abc", "00abc"},
+       {"%08q", "abc", `000"abc"`},
+       {"%5s", "abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz"},
+       {"%.5s", "abcdefghijklmnopqrstuvwxyz", "abcde"},
+       {"%.5s", "日本語日本語", "日本語日本"},
+       {"%.5s", []byte("日本語日本語"), "日本語日本"},
+       {"%.5q", "abcdefghijklmnopqrstuvwxyz", `"abcde"`},
+       {"%.3q", "日本語日本語", `"\u65e5\u672c\u8a9e"`},
+       {"%.3q", []byte("日本語日本語"), `"\u65e5\u672c\u8a9e"`},
+       {"%10.1q", "日本語日本語", `  "\u65e5"`},
 
        // integers
        {"%d", 12345, "12345"},
index caaa7ac..f9d2b4f 100644 (file)
@@ -235,13 +235,24 @@ func (f *fmt) integer(a int64, base uint64, signedness bool, digits string) {
        f.pad(buf[i:])
 }
 
-// fmt_s formats a string.
-func (f *fmt) fmt_s(s string) {
-       if f.precPresent {
-               if f.prec < len(s) {
-                       s = s[0:f.prec]
+// truncate truncates the string to the specified precision, if present.
+func (f *fmt) truncate(s string) string {
+       if f.precPresent && f.prec < utf8.RuneCountInString(s) {
+               n := f.prec
+               for i := range s {
+                       if n == 0 {
+                               s = s[:i]
+                               break
+                       }
+                       n--
                }
        }
+       return s
+}
+
+// fmt_s formats a string.
+func (f *fmt) fmt_s(s string) {
+       s = f.truncate(s)
        f.padString(s)
 }
 
@@ -275,6 +286,7 @@ func (f *fmt) fmt_sX(s string) {
 
 // fmt_q formats a string as a double-quoted, escaped Go string constant.
 func (f *fmt) fmt_q(s string) {
+       s = f.truncate(s)
        var quoted string
        if f.sharp && strconv.CanBackquote(s) {
                quoted = "`" + s + "`"
index 4e14fda..4b68051 100644 (file)
@@ -520,12 +520,14 @@ func (p *pp) fmtBytes(v []byte, verb int, goSyntax bool, depth int, value interf
 }
 
 func (p *pp) fmtPointer(field interface{}, value reflect.Value, verb int, goSyntax bool) {
-       v, ok := value.(uintptrGetter)
-       if !ok { // reflect.PtrValue is a uintptrGetter, so failure means it's not a pointer at all.
+       var u uintptr
+       switch value.(type) {
+       case *reflect.ChanValue, *reflect.FuncValue, *reflect.MapValue, *reflect.PtrValue, *reflect.SliceValue, *reflect.UnsafePointerValue:
+               u = value.(uintptrGetter).Get()
+       default:
                p.badVerb(verb, field)
                return
        }
-       u := v.Get()
        if goSyntax {
                p.add('(')
                p.buf.WriteString(reflect.Typeof(field).String())
@@ -534,7 +536,7 @@ func (p *pp) fmtPointer(field interface{}, value reflect.Value, verb int, goSynt
                if u == 0 {
                        p.buf.Write(nilBytes)
                } else {
-                       p.fmt0x64(uint64(v.Get()), true)
+                       p.fmt0x64(uint64(u), true)
                }
                p.add(')')
        } else {
@@ -811,7 +813,7 @@ BigSwitch:
                        break
                }
                p.fmt0x64(uint64(v), true)
-       case uintptrGetter:
+       case *reflect.ChanValue, *reflect.FuncValue, *reflect.UnsafePointerValue:
                p.fmtPointer(field, value, verb, goSyntax)
        default:
                p.unknownType(f)
index fc4ae09..b4780e0 100644 (file)
@@ -183,7 +183,7 @@ func ParseFiles(fset *token.FileSet, filenames []string, mode uint) (pkgs map[st
 // error are returned.
 //
 func ParseDir(fset *token.FileSet, path string, filter func(*os.FileInfo) bool, mode uint) (map[string]*ast.Package, os.Error) {
-       fd, err := os.Open(path, os.O_RDONLY, 0)
+       fd, err := os.Open(path)
        if err != nil {
                return nil, err
        }
index ad7e4cd..84a0da6 100644 (file)
@@ -332,7 +332,7 @@ func (p *parser) next() {
                var endline int
 
                if p.file.Line(p.pos) == line {
-                       // The comment is on same line as previous token; it
+                       // The comment is on same line as the previous token; it
                        // cannot be a lead comment but may be a line comment.
                        comment, endline = p.consumeCommentGroup()
                        if p.file.Line(p.pos) != endline {
@@ -2016,16 +2016,18 @@ func parseTypeSpec(p *parser, doc *ast.CommentGroup, _ int) ast.Spec {
        }
 
        ident := p.parseIdent()
-       typ := p.parseType()
-       p.expectSemi() // call before accessing p.linecomment
 
        // Go spec: The scope of a type identifier declared inside a function begins
        // at the identifier in the TypeSpec and ends at the end of the innermost
        // containing block.
        // (Global identifiers are resolved in a separate phase after parsing.)
-       spec := &ast.TypeSpec{doc, ident, typ, p.lineComment}
+       spec := &ast.TypeSpec{doc, ident, nil, nil}
        p.declare(spec, p.topScope, ast.Typ, ident)
 
+       spec.Type = p.parseType()
+       p.expectSemi() // call before accessing p.linecomment
+       spec.Comment = p.lineComment
+
        return spec
 }
 
@@ -2207,6 +2209,9 @@ func (p *parser) parseFile() *ast.File {
        // Go spec: The package clause is not a declaration;
        // the package name does not appear in any scope.
        ident := p.parseIdent()
+       if ident.Name == "_" {
+               p.error(p.pos, "invalid package name _")
+       }
        p.expectSemi()
 
        var decls []ast.Decl
index d153533..fe95543 100644 (file)
@@ -28,7 +28,7 @@ func pipeErr(err os.Error) io.Reader {
 }
 
 func readDat(filename string, c chan io.Reader) {
-       f, err := os.Open("testdata/webkit/"+filename, os.O_RDONLY, 0600)
+       f, err := os.Open("testdata/webkit/" + filename)
        if err != nil {
                c <- pipeErr(err)
                return
index 8b5c477..c5efffc 100644 (file)
@@ -72,7 +72,7 @@ func serveFile(w ResponseWriter, r *Request, name string, redirect bool) {
                return
        }
 
-       f, err := os.Open(name, os.O_RDONLY, 0)
+       f, err := os.Open(name)
        if err != nil {
                // TODO expose actual error?
                NotFound(w, r)
@@ -113,7 +113,7 @@ func serveFile(w ResponseWriter, r *Request, name string, redirect bool) {
        // use contents of index.html for directory, if present
        if d.IsDirectory() {
                index := name + filepath.FromSlash(indexPage)
-               ff, err := os.Open(index, os.O_RDONLY, 0)
+               ff, err := os.Open(index)
                if err == nil {
                        defer ff.Close()
                        dd, err := ff.Stat()
@@ -134,21 +134,23 @@ func serveFile(w ResponseWriter, r *Request, name string, redirect bool) {
        size := d.Size
        code := StatusOK
 
-       // use extension to find content type.
-       ext := filepath.Ext(name)
-       if ctype := mime.TypeByExtension(ext); ctype != "" {
-               w.Header().Set("Content-Type", ctype)
-       } else {
-               // read first chunk to decide between utf-8 text and binary
-               var buf [1024]byte
-               n, _ := io.ReadFull(f, buf[:])
-               b := buf[:n]
-               if isText(b) {
-                       w.Header().Set("Content-Type", "text-plain; charset=utf-8")
-               } else {
-                       w.Header().Set("Content-Type", "application/octet-stream") // generic binary
+       // If Content-Type isn't set, use the file's extension to find it.
+       if w.Header().Get("Content-Type") == "" {
+               ctype := mime.TypeByExtension(filepath.Ext(name))
+               if ctype == "" {
+                       // read a chunk to decide between utf-8 text and binary
+                       var buf [1024]byte
+                       n, _ := io.ReadFull(f, buf[:])
+                       b := buf[:n]
+                       if isText(b) {
+                               ctype = "text-plain; charset=utf-8"
+                       } else {
+                               // generic binary
+                               ctype = "application/octet-stream"
+                       }
+                       f.Seek(0, os.SEEK_SET) // rewind to output whole file
                }
-               f.Seek(0, 0) // rewind to output whole file
+               w.Header().Set("Content-Type", ctype)
        }
 
        // handle Content-Range header.
@@ -163,7 +165,7 @@ func serveFile(w ResponseWriter, r *Request, name string, redirect bool) {
        }
        if len(ranges) == 1 {
                ra := ranges[0]
-               if _, err := f.Seek(ra.start, 0); err != nil {
+               if _, err := f.Seek(ra.start, os.SEEK_SET); err != nil {
                        Error(w, err.String(), StatusRequestedRangeNotSatisfiable)
                        return
                }
index a89c76d..692b986 100644 (file)
@@ -85,6 +85,30 @@ func TestServeFile(t *testing.T) {
        }
 }
 
+func TestServeFileContentType(t *testing.T) {
+       const ctype = "icecream/chocolate"
+       override := false
+       ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+               if override {
+                       w.Header().Set("Content-Type", ctype)
+               }
+               ServeFile(w, r, "testdata/file")
+       }))
+       defer ts.Close()
+       get := func(want string) {
+               resp, _, err := Get(ts.URL)
+               if err != nil {
+                       t.Fatal(err)
+               }
+               if h := resp.Header.Get("Content-Type"); h != want {
+                       t.Errorf("Content-Type mismatch: got %q, want %q", h, want)
+               }
+       }
+       get("text-plain; charset=utf-8")
+       override = true
+       get(ctype)
+}
+
 func getBody(t *testing.T, req Request) (*Response, []byte) {
        r, err := DefaultClient.Do(&req)
        if err != nil {
index 6e825a8..8e385d0 100644 (file)
@@ -7,10 +7,13 @@
 package httptest
 
 import (
+       "crypto/rand"
+       "crypto/tls"
        "fmt"
        "http"
-       "os"
        "net"
+       "os"
+       "time"
 )
 
 // A Server is an HTTP server listening on a system-chosen port on the
@@ -18,6 +21,7 @@ import (
 type Server struct {
        URL      string // base URL of form http://ipaddr:port with no trailing slash
        Listener net.Listener
+       TLS      *tls.Config // nil if not using using TLS
 }
 
 // historyListener keeps track of all connections that it's ever
@@ -35,16 +39,21 @@ func (hs *historyListener) Accept() (c net.Conn, err os.Error) {
        return
 }
 
-// NewServer starts and returns a new Server.
-// The caller should call Close when finished, to shut it down.
-func NewServer(handler http.Handler) *Server {
-       ts := new(Server)
+func newLocalListener() net.Listener {
        l, err := net.Listen("tcp", "127.0.0.1:0")
        if err != nil {
                if l, err = net.Listen("tcp6", "[::1]:0"); err != nil {
                        panic(fmt.Sprintf("httptest: failed to listen on a port: %v", err))
                }
        }
+       return l
+}
+
+// NewServer starts and returns a new Server.
+// The caller should call Close when finished, to shut it down.
+func NewServer(handler http.Handler) *Server {
+       ts := new(Server)
+       l := newLocalListener()
        ts.Listener = &historyListener{l, make([]net.Conn, 0)}
        ts.URL = "http://" + l.Addr().String()
        server := &http.Server{Handler: handler}
@@ -52,6 +61,32 @@ func NewServer(handler http.Handler) *Server {
        return ts
 }
 
+// NewTLSServer starts and returns a new Server using TLS.
+// The caller should call Close when finished, to shut it down.
+func NewTLSServer(handler http.Handler) *Server {
+       l := newLocalListener()
+       ts := new(Server)
+
+       cert, err := tls.X509KeyPair(localhostCert, localhostKey)
+       if err != nil {
+               panic(fmt.Sprintf("httptest: NewTLSServer: %v", err))
+       }
+
+       ts.TLS = &tls.Config{
+               Rand:         rand.Reader,
+               Time:         time.Seconds,
+               NextProtos:   []string{"http/1.1"},
+               Certificates: []tls.Certificate{cert},
+       }
+       tlsListener := tls.NewListener(l, ts.TLS)
+
+       ts.Listener = &historyListener{tlsListener, make([]net.Conn, 0)}
+       ts.URL = "https://" + l.Addr().String()
+       server := &http.Server{Handler: handler}
+       go server.Serve(ts.Listener)
+       return ts
+}
+
 // Close shuts down the server.
 func (s *Server) Close() {
        s.Listener.Close()
@@ -68,3 +103,34 @@ func (s *Server) CloseClientConnections() {
                conn.Close()
        }
 }
+
+// localhostCert is a PEM-encoded TLS cert with SAN DNS names
+// "127.0.0.1" and "[::1]", expiring at the last second of 2049 (the end
+// of ASN.1 time).
+var localhostCert = []byte(`-----BEGIN CERTIFICATE-----
+MIIBwTCCASugAwIBAgIBADALBgkqhkiG9w0BAQUwADAeFw0xMTAzMzEyMDI1MDda
+Fw00OTEyMzEyMzU5NTlaMAAwggCdMAsGCSqGSIb3DQEBAQOCAIwAMIIAhwKCAIB6
+oy4iT42G6qk+GGn5VL5JlnJT6ZG5cqaMNFaNGlIxNb6CPUZLKq2sM3gRaimsktIw
+nNAcNwQGHpe1tZo+J/Pl04JTt71Y/TTAxy7OX27aZf1Rpt0SjdZ7vTPnFDPNsHGe
+KBKvPt55l2+YKjkZmV7eRevsVbpkNvNGB+T5d4Ge/wIBA6NPME0wDgYDVR0PAQH/
+BAQDAgCgMA0GA1UdDgQGBAQBAgMEMA8GA1UdIwQIMAaABAECAwQwGwYDVR0RBBQw
+EoIJMTI3LjAuMC4xggVbOjoxXTALBgkqhkiG9w0BAQUDggCBAHC3gbdvc44vs+wD
+g2kONiENnx8WKc0UTGg/TOXS3gaRb+CUIQtHWja65l8rAfclEovjHgZ7gx8brO0W
+JuC6p3MUAKsgOssIrrRIx2rpnfcmFVMzguCmrMNVmKUAalw18Yp0F72xYAIitVQl
+kJrLdIhBajcJRYu/YGltHQRaXuVt
+-----END CERTIFICATE-----
+`)
+
+// localhostKey is the private key for localhostCert.
+var localhostKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
+MIIBkgIBAQKCAIB6oy4iT42G6qk+GGn5VL5JlnJT6ZG5cqaMNFaNGlIxNb6CPUZL
+Kq2sM3gRaimsktIwnNAcNwQGHpe1tZo+J/Pl04JTt71Y/TTAxy7OX27aZf1Rpt0S
+jdZ7vTPnFDPNsHGeKBKvPt55l2+YKjkZmV7eRevsVbpkNvNGB+T5d4Ge/wIBAwKC
+AIBRwh7Bil5Z8cYpZZv7jdQxDvbim7Z7ocRdeDmzZuF2I9RW04QyHHPIIlALnBvI
+YeF1veASz1gEFGUjzmbUGqKYSbCoTzXoev+F4bmbRxcX9sOmtslqvhMSHRSzA5NH
+aDVI3Hn4wvBVD8gePu8ACWqvPGbCiql11OKCMfjlPn2uuwJAx/24/F5DjXZ6hQQ7
+HxScOxKrpx5WnA9r1wZTltOTZkhRRzuLc21WJeE3M15QUdWi3zZxCKRFoth65HEs
+jy9YHQJAnPueRI44tz79b5QqVbeaOMUr7ZCb1Kp0uo6G+ANPLdlfliAupwij2eIz
+mHRJOWk0jBtXfRft1McH2H51CpXAyw==
+-----END RSA PRIVATE KEY-----
+`)
index bf63ccb..ef67fdd 100644 (file)
@@ -164,6 +164,28 @@ var respTests = []respTest{
                "Body here\n",
        },
 
+       // Chunked response in response to a HEAD request (the "chunked" should
+       // be ignored, as HEAD responses never have bodies)
+       {
+               "HTTP/1.0 200 OK\r\n" +
+                       "Transfer-Encoding: chunked\r\n" +
+                       "\r\n",
+
+               Response{
+                       Status:        "200 OK",
+                       StatusCode:    200,
+                       Proto:         "HTTP/1.0",
+                       ProtoMajor:    1,
+                       ProtoMinor:    0,
+                       RequestMethod: "HEAD",
+                       Header:        Header{},
+                       Close:         true,
+                       ContentLength: 0,
+               },
+
+               "",
+       },
+
        // Status line without a Reason-Phrase, but trailing space.
        // (permitted by RFC 2616)
        {
index b0e26e5..cf88955 100644 (file)
@@ -507,3 +507,30 @@ func TestHeadResponses(t *testing.T) {
                t.Errorf("got unexpected body %q", string(body))
        }
 }
+
+func TestTLSServer(t *testing.T) {
+       ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+               fmt.Fprintf(w, "tls=%v", r.TLS != nil)
+       }))
+       defer ts.Close()
+       if !strings.HasPrefix(ts.URL, "https://") {
+               t.Fatalf("expected test TLS server to start with https://, got %q", ts.URL)
+       }
+       res, _, err := Get(ts.URL)
+       if err != nil {
+               t.Error(err)
+       }
+       if res == nil {
+               t.Fatalf("got nil Response")
+       }
+       if res.Body == nil {
+               t.Fatalf("got nil Response.Body")
+       }
+       body, err := ioutil.ReadAll(res.Body)
+       if err != nil {
+               t.Error(err)
+       }
+       if e, g := "tls=true", string(body); e != g {
+               t.Errorf("expected body %q; got %q", e, g)
+       }
+}
index 996e289..41614f1 100644 (file)
@@ -215,7 +215,7 @@ func readTransfer(msg interface{}, r *bufio.Reader) (err os.Error) {
        }
 
        // Transfer encoding, content length
-       t.TransferEncoding, err = fixTransferEncoding(t.Header)
+       t.TransferEncoding, err = fixTransferEncoding(t.RequestMethod, t.Header)
        if err != nil {
                return err
        }
@@ -289,13 +289,20 @@ func readTransfer(msg interface{}, r *bufio.Reader) (err os.Error) {
 func chunked(te []string) bool { return len(te) > 0 && te[0] == "chunked" }
 
 // Sanitize transfer encoding
-func fixTransferEncoding(header Header) ([]string, os.Error) {
+func fixTransferEncoding(requestMethod string, header Header) ([]string, os.Error) {
        raw, present := header["Transfer-Encoding"]
        if !present {
                return nil, nil
        }
 
        header["Transfer-Encoding"] = nil, false
+
+       // Head responses have no bodies, so the transfer encoding
+       // should be ignored.
+       if requestMethod == "HEAD" {
+               return nil, nil
+       }
+
        encodings := strings.Split(raw[0], ",", -1)
        te := make([]string, 0, len(encodings))
        // TODO: Even though we only support "identity" and "chunked"
index ed7843b..797d134 100644 (file)
@@ -24,6 +24,10 @@ import (
 // environment variables.
 var DefaultTransport RoundTripper = &Transport{}
 
+// DefaultMaxIdleConnsPerHost is the default value of Transport's
+// MaxIdleConnsPerHost.
+const DefaultMaxIdleConnsPerHost = 2
+
 // Transport is an implementation of RoundTripper that supports http,
 // https, and http proxies (for either http or https with CONNECT).
 // Transport can also cache connections for future re-use.
@@ -31,11 +35,17 @@ type Transport struct {
        lk       sync.Mutex
        idleConn map[string][]*persistConn
 
-       // TODO: tunables on max cached connections (total, per-server), duration
+       // TODO: tunable on global max cached connections
+       // TODO: tunable on timeout on cached connections
        // TODO: optional pipelining
 
        IgnoreEnvironment bool // don't look at environment variables for proxy configuration
        DisableKeepAlives bool
+
+       // MaxIdleConnsPerHost, if non-zero, controls the maximum idle
+       // (keep-alive) to keep to keep per-host.  If zero,
+       // DefaultMaxIdleConnsPerHost is used.
+       MaxIdleConnsPerHost int
 }
 
 // RoundTrip implements the RoundTripper interface.
@@ -147,7 +157,7 @@ func (cm *connectMethod) proxyAuth() string {
 func (t *Transport) putIdleConn(pconn *persistConn) {
        t.lk.Lock()
        defer t.lk.Unlock()
-       if t.DisableKeepAlives {
+       if t.DisableKeepAlives || t.MaxIdleConnsPerHost < 0 {
                pconn.close()
                return
        }
@@ -155,6 +165,14 @@ func (t *Transport) putIdleConn(pconn *persistConn) {
                return
        }
        key := pconn.cacheKey
+       max := t.MaxIdleConnsPerHost
+       if max == 0 {
+               max = DefaultMaxIdleConnsPerHost
+       }
+       if len(t.idleConn[key]) >= max {
+               pconn.close()
+               return
+       }
        t.idleConn[key] = append(t.idleConn[key], pconn)
 }
 
@@ -406,24 +424,37 @@ func (pc *persistConn) readLoop() {
 
                rc := <-pc.reqch
                resp, err := pc.cc.Read(rc.req)
-               if err == nil && !rc.req.Close {
-                       pc.t.putIdleConn(pc)
-               }
+
                if err == ErrPersistEOF {
                        // Succeeded, but we can't send any more
                        // persistent connections on this again.  We
                        // hide this error to upstream callers.
                        alive = false
                        err = nil
-               } else if err != nil {
+               } else if err != nil || rc.req.Close {
                        alive = false
                }
+
+               hasBody := resp != nil && resp.ContentLength != 0
+               var waitForBodyRead chan bool
+               if alive {
+                       if hasBody {
+                               waitForBodyRead = make(chan bool)
+                               resp.Body.(*bodyEOFSignal).fn = func() {
+                                       pc.t.putIdleConn(pc)
+                                       waitForBodyRead <- true
+                               }
+                       } else {
+                               pc.t.putIdleConn(pc)
+                       }
+               }
+
                rc.ch <- responseAndError{resp, err}
 
                // Wait for the just-returned response body to be fully consumed
                // before we race and peek on the underlying bufio reader.
-               if alive {
-                       <-resp.Body.(*bodyEOFSignal).ch
+               if waitForBodyRead != nil {
+                       <-waitForBodyRead
                }
        }
 }
@@ -494,34 +525,34 @@ func responseIsKeepAlive(res *Response) bool {
 // the response body with a bodyEOFSignal-wrapped version.
 func readResponseWithEOFSignal(r *bufio.Reader, requestMethod string) (resp *Response, err os.Error) {
        resp, err = ReadResponse(r, requestMethod)
-       if err == nil {
-               resp.Body = &bodyEOFSignal{resp.Body, make(chan bool, 1), false}
+       if err == nil && resp.ContentLength != 0 {
+               resp.Body = &bodyEOFSignal{resp.Body, nil}
        }
        return
 }
 
-// bodyEOFSignal wraps a ReadCloser but sends on ch once once
-// the wrapped ReadCloser is fully consumed (including on Close)
+// bodyEOFSignal wraps a ReadCloser but runs fn (if non-nil) at most
+// once, right before the final Read() or Close() call returns, but after
+// EOF has been seen.
 type bodyEOFSignal struct {
        body io.ReadCloser
-       ch   chan bool
-       done bool
+       fn   func()
 }
 
 func (es *bodyEOFSignal) Read(p []byte) (n int, err os.Error) {
        n, err = es.body.Read(p)
-       if err == os.EOF && !es.done {
-               es.ch <- true
-               es.done = true
+       if err == os.EOF && es.fn != nil {
+               es.fn()
+               es.fn = nil
        }
        return
 }
 
 func (es *bodyEOFSignal) Close() (err os.Error) {
        err = es.body.Close()
-       if err == nil && !es.done {
-               es.ch <- true
-               es.done = true
+       if err == nil && es.fn != nil {
+               es.fn()
+               es.fn = nil
        }
        return
 }
index 5c3e1cd..e46f830 100644 (file)
@@ -85,6 +85,7 @@ func TestTransportConnectionCloseOnResponse(t *testing.T) {
                                t.Fatalf("error in connectionClose=%v, req #%d, Do: %v", connectionClose, n, err)
                        }
                        body, err := ioutil.ReadAll(res.Body)
+                       defer res.Body.Close()
                        if err != nil {
                                t.Fatalf("error in connectionClose=%v, req #%d, ReadAll: %v", connectionClose, n, err)
                        }
@@ -154,9 +155,11 @@ func TestTransportIdleCacheKeys(t *testing.T) {
                t.Errorf("After CloseIdleConnections expected %d idle conn cache keys; got %d", e, g)
        }
 
-       if _, _, err := c.Get(ts.URL); err != nil {
+       resp, _, err := c.Get(ts.URL)
+       if err != nil {
                t.Error(err)
        }
+       ioutil.ReadAll(resp.Body)
 
        keys := tr.IdleConnKeysForTesting()
        if e, g := 1, len(keys); e != g {
@@ -164,7 +167,7 @@ func TestTransportIdleCacheKeys(t *testing.T) {
        }
 
        if e := "|http|" + ts.Listener.Addr().String(); keys[0] != e {
-               t.Logf("Expected idle cache key %q; got %q", e, keys[0])
+               t.Errorf("Expected idle cache key %q; got %q", e, keys[0])
        }
 
        tr.CloseIdleConnections()
@@ -173,6 +176,62 @@ func TestTransportIdleCacheKeys(t *testing.T) {
        }
 }
 
+func TestTransportMaxPerHostIdleConns(t *testing.T) {
+       ch := make(chan string)
+       ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+               fmt.Fprintf(w, "%s", <-ch)
+       }))
+       defer ts.Close()
+       maxIdleConns := 2
+       tr := &Transport{DisableKeepAlives: false, MaxIdleConnsPerHost: maxIdleConns}
+       c := &Client{Transport: tr}
+
+       // Start 3 outstanding requests (will hang until we write to
+       // ch)
+       donech := make(chan bool)
+       doReq := func() {
+               resp, _, err := c.Get(ts.URL)
+               if err != nil {
+                       t.Error(err)
+               }
+               ioutil.ReadAll(resp.Body)
+               donech <- true
+       }
+       go doReq()
+       go doReq()
+       go doReq()
+
+       if e, g := 0, len(tr.IdleConnKeysForTesting()); e != g {
+               t.Fatalf("Before writes, expected %d idle conn cache keys; got %d", e, g)
+       }
+
+       ch <- "res1"
+       <-donech
+       keys := tr.IdleConnKeysForTesting()
+       if e, g := 1, len(keys); e != g {
+               t.Fatalf("after first response, expected %d idle conn cache keys; got %d", e, g)
+       }
+       cacheKey := "|http|" + ts.Listener.Addr().String()
+       if keys[0] != cacheKey {
+               t.Fatalf("Expected idle cache key %q; got %q", cacheKey, keys[0])
+       }
+       if e, g := 1, tr.IdleConnCountForTesting(cacheKey); e != g {
+               t.Errorf("after first response, expected %d idle conns; got %d", e, g)
+       }
+
+       ch <- "res2"
+       <-donech
+       if e, g := 2, tr.IdleConnCountForTesting(cacheKey); e != g {
+               t.Errorf("after second response, expected %d idle conns; got %d", e, g)
+       }
+
+       ch <- "res3"
+       <-donech
+       if e, g := maxIdleConns, tr.IdleConnCountForTesting(cacheKey); e != g {
+               t.Errorf("after third response, still expected %d idle conns; got %d", e, g)
+       }
+}
+
 func TestTransportServerClosingUnexpectedly(t *testing.T) {
        ts := httptest.NewServer(hostPortHandler)
        defer ts.Close()
@@ -209,6 +268,63 @@ func TestTransportServerClosingUnexpectedly(t *testing.T) {
        }
 }
 
+// TestTransportHeadResponses verifies that we deal with Content-Lengths
+// with no bodies properly
+func TestTransportHeadResponses(t *testing.T) {
+       ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+               if r.Method != "HEAD" {
+                       panic("expected HEAD; got " + r.Method)
+               }
+               w.Header().Set("Content-Length", "123")
+               w.WriteHeader(200)
+       }))
+       defer ts.Close()
+
+       tr := &Transport{DisableKeepAlives: false}
+       c := &Client{Transport: tr}
+       for i := 0; i < 2; i++ {
+               res, err := c.Head(ts.URL)
+               if err != nil {
+                       t.Errorf("error on loop %d: %v", i, err)
+               }
+               if e, g := "123", res.Header.Get("Content-Length"); e != g {
+                       t.Errorf("loop %d: expected Content-Length header of %q, got %q", e, g)
+               }
+               if e, g := int64(0), res.ContentLength; e != g {
+                       t.Errorf("loop %d: expected res.ContentLength of %v, got %v", e, g)
+               }
+       }
+}
+
+// TestTransportHeadChunkedResponse verifies that we ignore chunked transfer-encoding
+// on responses to HEAD requests.
+func TestTransportHeadChunkedResponse(t *testing.T) {
+       ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+               if r.Method != "HEAD" {
+                       panic("expected HEAD; got " + r.Method)
+               }
+               w.Header().Set("Transfer-Encoding", "chunked") // client should ignore
+               w.Header().Set("x-client-ipport", r.RemoteAddr)
+               w.WriteHeader(200)
+       }))
+       defer ts.Close()
+
+       tr := &Transport{DisableKeepAlives: false}
+       c := &Client{Transport: tr}
+
+       res1, err := c.Head(ts.URL)
+       if err != nil {
+               t.Fatalf("request 1 error: %v", err)
+       }
+       res2, err := c.Head(ts.URL)
+       if err != nil {
+               t.Fatalf("request 2 error: %v", err)
+       }
+       if v1, v2 := res1.Header.Get("x-client-ipport"), res2.Header.Get("x-client-ipport"); v1 != v2 {
+               t.Errorf("ip/ports differed between head requests: %q vs %q", v1, v2)
+       }
+}
+
 func TestTransportNilURL(t *testing.T) {
        ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
                fmt.Fprintf(w, "Hi")
index efd90d8..0fc0cb2 100644 (file)
@@ -213,8 +213,8 @@ func urlEscape(s string, mode encoding) string {
                        j++
                case shouldEscape(c, mode):
                        t[j] = '%'
-                       t[j+1] = "0123456789abcdef"[c>>4]
-                       t[j+2] = "0123456789abcdef"[c&15]
+       &nb