diff --git a/Crypto/Cipher/Tests.hs b/Crypto/Cipher/Tests.hs
--- a/Crypto/Cipher/Tests.hs
+++ b/Crypto/Cipher/Tests.hs
@@ -31,3 +31,9 @@
     (  (if kats == defaultKATs  then [] else [testKATs kats cipher])
     ++ testModes cipher
     )
+
+testStreamCipher :: StreamCipher a => [KAT_Stream] -> a -> Test
+testStreamCipher kats cipher = testGroup (cipherName cipher)
+    (  (if kats == defaultStreamKATs then [] else [testStreamKATs kats cipher])
+    ++ testStream cipher
+    )
diff --git a/Crypto/Cipher/Tests/KATs.hs b/Crypto/Cipher/Tests/KATs.hs
--- a/Crypto/Cipher/Tests/KATs.hs
+++ b/Crypto/Cipher/Tests/KATs.hs
@@ -3,7 +3,7 @@
 
 import Data.ByteString (ByteString)
 
-import Test.Framework (Test, testGroup)
+import Test.Framework (Test, testGroup, TestName)
 import Test.Framework.Providers.HUnit (testCase)
 import Test.HUnit ((@?=))
 import Crypto.Cipher.Types
@@ -63,6 +63,13 @@
     , kat_AEAD :: [KAT_AEAD]
     } deriving (Show,Eq)
 
+-- | KAT for Stream cipher
+data KAT_Stream = KAT_Stream
+    { streamKey        :: ByteString
+    , streamPlaintext  :: ByteString
+    , streamCiphertext :: ByteString
+    } deriving (Show,Eq)
+
 -- | the empty KATs
 defaultKATs :: KATs
 defaultKATs = KATs
@@ -73,6 +80,10 @@
     , kat_AEAD = []
     }
 
+-- | the empty KATs for stream
+defaultStreamKATs :: [KAT_Stream]
+defaultStreamKATs = []
+
 -- | tests related to KATs
 testKATs :: BlockCipher cipher => KATs -> cipher -> Test
 testKATs kats cipher = testGroup "KAT"
@@ -121,16 +132,25 @@
                 etag = aeadFinalize aeadEFinal (aeadTaglen d)
                 dtag = aeadFinalize aeadDFinal (aeadTaglen d)
                
-        maybeGroup mkTest groupName l
-            | null l    = []
-            | otherwise = [testGroup groupName (concatMap (\(i, d) -> mkTest (show i) d) $ zip nbs l)]
-        nbs :: [Int]
-        nbs = [0..]
-        
-        cipherMakeKey :: BlockCipher cipher => cipher -> ByteString -> Key cipher
-        cipherMakeKey c bs = case makeKey bs of
-                                Left e -> error ("invalid key " ++ show bs ++ " for " ++ show (cipherName c) ++ " " ++ show e)
-                                Right k  -> k
-
         cipherMakeIV :: BlockCipher cipher => cipher -> ByteString -> IV cipher
         cipherMakeIV _ bs = fromJust $ makeIV bs
+
+testStreamKATs :: StreamCipher cipher => [KAT_Stream] -> cipher -> Test
+testStreamKATs kats cipher = testGroup "KAT" $ maybeGroup makeStreamTest "Stream" kats
+  where makeStreamTest i d =
+            [ testCase ("E" ++ i) (fst (streamCombine ctx (streamPlaintext d)) @?= streamCiphertext d)
+            , testCase ("D" ++ i) (fst (streamCombine ctx (streamCiphertext d)) @?= streamPlaintext d)
+            ]
+          where ctx = cipherInit (cipherMakeKey cipher $ streamKey d)
+
+cipherMakeKey :: Cipher cipher => cipher -> ByteString -> Key cipher
+cipherMakeKey c bs = case makeKey bs of
+                        Left e -> error ("invalid key " ++ show bs ++ " for " ++ show (cipherName c) ++ " " ++ show e)
+                        Right k  -> k
+
+maybeGroup :: (String -> t -> [Test]) -> TestName -> [t] -> [Test]
+maybeGroup mkTest groupName l
+    | null l    = []
+    | otherwise = [testGroup groupName (concatMap (\(i, d) -> mkTest (show i) d) $ zip nbs l)]
+  where nbs :: [Int]
+        nbs = [0..]
diff --git a/Crypto/Cipher/Tests/Properties.hs b/Crypto/Cipher/Tests/Properties.hs
--- a/Crypto/Cipher/Tests/Properties.hs
+++ b/Crypto/Cipher/Tests/Properties.hs
@@ -34,6 +34,9 @@
 data AEADUnit a = AEADUnit (Key a) B.ByteString B.ByteString B.ByteString
     deriving (Eq)
 
+data StreamUnit a = StreamUnit (Key a) B.ByteString
+    deriving (Eq)
+
 instance Show (ECBUnit a) where
     show (ECBUnit key b) = "ECB(key=" ++ show (toBytes key) ++ ",input=" ++ show b ++ ")"
 instance Show (CBCUnit a) where
@@ -44,11 +47,13 @@
     show (XTSUnit key1 key2 iv b) = "XTS(key1=" ++ show (toBytes key1) ++ ",key2=" ++ show (toBytes key2) ++ ",iv=" ++ show (toBytes iv) ++ ",input=" ++ show b ++ ")"
 instance Show (AEADUnit a) where
     show (AEADUnit key iv aad b) = "AEAD(key=" ++ show (toBytes key) ++ ",iv=" ++ show iv ++ ",aad=" ++ show (toBytes aad) ++ ",input=" ++ show b ++ ")"
+instance Show (StreamUnit a) where
+    show (StreamUnit key b) = "Stream(key=" ++ show (toBytes key) ++ ",input=" ++ show b ++ ")"
 
 -- | Generate an arbitrary valid key for a specific block cipher
-generateKey :: BlockCipher a => Gen (Key a)
+generateKey :: Cipher a => Gen (Key a)
 generateKey = keyFromCipher undefined
-  where keyFromCipher :: BlockCipher a => a -> Gen (Key a)
+  where keyFromCipher :: Cipher a => a -> Gen (Key a)
         keyFromCipher cipher = do
             sz <- case cipherKeySize cipher of
                          KeySizeRange low high -> choose (low, high)
@@ -100,6 +105,10 @@
                          <*> generatePlaintext
                          <*> generatePlaintext
 
+instance StreamCipher a => Arbitrary (StreamUnit a) where
+    arbitrary = StreamUnit <$> generateKey
+                           <*> generatePlaintext
+
 -- | Test a generic block cipher for properties
 -- related to block cipher modes.
 testModes :: BlockCipher a => a -> [Test]
@@ -149,6 +158,13 @@
                         dTag           = aeadFinalize aeadD (blockSize ctx)
                      in (plaintext `assertEq` dText) && (toBytes eTag `assertEq` toBytes dTag)
                 Nothing -> True
+
+testStream :: StreamCipher a => a -> [Test]
+testStream cipher = [testProperty "combine.combine==id" (testStreamUnit cipher)]
+  where testStreamUnit :: StreamCipher a => a -> (StreamUnit a -> Bool)
+        testStreamUnit _ (StreamUnit (cipherInit -> ctx) plaintext) =
+            let cipherText = fst $ streamCombine ctx plaintext
+             in fst (streamCombine ctx cipherText) `assertEq` plaintext
 
 assertEq :: B.ByteString -> B.ByteString -> Bool
 assertEq b1 b2 | b1 /= b2  = error ("b1: " ++ show b1 ++ " b2: " ++ show b2)
diff --git a/crypto-cipher-tests.cabal b/crypto-cipher-tests.cabal
--- a/crypto-cipher-tests.cabal
+++ b/crypto-cipher-tests.cabal
@@ -1,5 +1,5 @@
 Name:                crypto-cipher-tests
-Version:             0.0.4
+Version:             0.0.5
 Synopsis:            Generic cryptography cipher tests
 Description:         Generic cryptography cipher tests
 License:             BSD3
@@ -27,7 +27,7 @@
                    , bytestring
                    , byteable >= 0.1.1
                    , securemem >= 0.1.1
-                   , crypto-cipher-types >= 0.0.3
+                   , crypto-cipher-types >= 0.0.5
   ghc-options:       -Wall -fwarn-tabs
 
 Test-Suite test-crypto-cipher-dummy
diff --git a/tests/Tests.hs b/tests/Tests.hs
--- a/tests/Tests.hs
+++ b/tests/Tests.hs
@@ -8,6 +8,7 @@
 import Data.Bits (xor)
 
 -- | the XOR cipher is so awesome that it doesn't need any key or state.
+-- Also it's a stream and block cipher at the same time.
 data XorCipher = XorCipher
 
 instance Cipher XorCipher where
@@ -20,6 +21,12 @@
     ecbEncrypt _ b = B.pack $ B.zipWith xor (B.replicate (B.length b) 0xa5) b
     ecbDecrypt _ b = B.pack $ B.zipWith xor (B.replicate (B.length b) 0xa5) b
 
-tests = testBlockCipher defaultKATs (undefined :: XorCipher)
+instance StreamCipher XorCipher where
+    streamCombine _ b = (B.pack $ B.zipWith xor (B.replicate (B.length b) 0x12) b, XorCipher)
+
+tests =
+    [ testBlockCipher defaultKATs (undefined :: XorCipher)
+    , testStreamCipher defaultStreamKATs (undefined :: StreamCipher)
+    ]
 
 main = defaultMain [tests]
