skein-1.0.9.1: Skein, a family of cryptographic hash functions. Includes Skein-MAC as well.

Copyright(c) 2011 Felipe A. Lessa
LicenseBSD3 (see LICENSE)
Maintainerfelipe.lessa@gmail.com
Stabilityprovisional
Portabilityportable (needs FFI)
Safe HaskellNone
LanguageHaskell98

Crypto.Skein

Contents

Description

High-level interface for the Skein family of hash functions.

Synopsis

Using this module

Currently this module provides both Skein as a cryptographic hash function and Skein as a MAC. This module currently does not provide some Skein functions, such as tree hashing, pseudo-random number generation, stream ciphing or key derivation.

Terminology note: we say "message" for your variable-sized data that is given to Skein.

Skein as a cryptographic hash function

There are many variants of Skein as a cryptographic hash function. They are called Skein_X_Y, where X is internal state size in bits and Y is the output size in bits. The main ones are Skein_512_512, Skein_1024_1024 and Skein_256_256. If you are unsure, then use Skein_512_512.

To use these data types, you have to use Hash and Serialize. Suppose you wanted to hash a lazy ByteString bs. Then you could use

  digest :: ByteString
  digest = let h = hash bs :: Skein_512_512
           in encode h

where hash is from Crypto.Classes (crypto-api package), encode is from Serialize (cereal package) and digest is a strict ByteString with the hash. Given that we've used Skein_512_512 which has an output size of 512 bits, digest will have 512 / 8 = 64 bytes of length.

Skein as a message authentication code (MAC)

If you need a message authentication code (MAC), you may use HMAC with Skein (e.g. HMAC-Skein-512-512). Using HMAC with Skein is supported and secure. However, Skein also supports another secure method, called Skein-MAC.

Skein-MAC is as secure as HMAC with Skein, however with a much lower overhead (especially for short messages). HMAC requires two hash invocations. Skein-MAC, on the other hand, requires just one hash invocation after the setup.

To use Skein-MAC, you need skeinMAC (or skeinMAC') and Serialize. You also need a Key with at least as many bits as the state size you choose (256, 512 or 1024 bits).

Suppose you want to use Skein-MAC with Skein_512_512. To setup the MAC function with a Key key (that has at least 512 / 8 = 64 bytes), use

  let calcMAC :: ByteString -> Skein_512_512
      calcMAC = skeinMAC key

It is recommended to partially apply skeinMAC (or skeinMAC') to avoid recomputing the key setup. We give an explicit type to calcMAC because we have to choose which Skein we want.

Now, if you want to calculate the Skein-MAC of a lazy ByteString message msg, use

  let msgMAC = encode (calcMAC msg)

where encode is from Serialize (cereal package) and msgMAC is a strict ByteString with the MAC.

Now, suppose you are given a msg' with MAC msgMAC' and want to check the integrity and authenticity of msg'. You may do so by calculating the MAC of msg' and checking against msgMAC':

  let msgMAC'' = encode (calcMAC msg')
  in if msgMAC' == msgMAC''
     then Right "Message is okay"
     else Left "Message has been corrupted or tampered with"

About Skein

From http://www.skein-hash.info/about at 09/2011:

Skein is a new family of cryptographic hash functions. Its design combines speed, security, simplicity, and a great deal of flexibility in a modular package that is easy to analyze.

Skein is fast. Skein-512 -- our primary proposal -- hashes data at 6.1 clock cycles per byte on a 64-bit CPU. This means that on a 3.1 GHz x64 Core 2 Duo CPU, Skein hashes data at 500 MBytes/second per core -- almost twice as fast as SHA-512 and three times faster than SHA-256. An optional hash-tree mode speeds up parallelizable implementations even more. Skein is fast for short messages, too; Skein-512 hashes short messages in about 1000 clock cycles.

Skein is secure. Our current best attack on Skein-512 is on 25 of 72 rounds, for a safety factor of 2.9. For comparison, at a similar stage in the standardization process, the AES encryption algorithm had an attack on 6 of 10 rounds, for a safety factor of only 1.7. Additionally, Skein has a number of provably secure properties, increasing confidence in the algorithm.

Skein is simple. Using only three primitive operations, the Skein compression function can be easily understood and remembered. The rest of the algorithm is a straightforward iteration of this function.

Skein is flexible. Skein is defined for three different internal state sizes -- 256 bits, 512 bits, and 1024 bits -- and any output size. This allows Skein to be a drop-in replacement for the entire SHA family of hash functions. A completely optional and extendable argument system makes Skein an efficient tool to use for a very large number of functions: a PRNG, a stream cipher, a key derivation function, authentication without the overhead of HMAC, and a personalization capability. All these features can be implemented with very low overhead. Together with the Threefish large-block cipher at Skein core, this design provides a full set of symmetric cryptographic primitives suitable for most modern applications.

Skein is efficient on a variety of platforms, both hardware and software. Skein-512 can be implemented in about 200 bytes of state. Small devices, such as 8-bit smart cards, can implement Skein-256 using about 100 bytes of memory. Larger devices can implement the larger versions of Skein to achieve faster speeds.

Skein was designed by a team of highly experienced cryptographic experts from academia and industry, with expertise in cryptography, security analysis, software, chip design, and implementation of real-world cryptographic systems. This breadth of knowledge allowed them to create a balanced design that works well in all environments.

Main cryptographic hash functions

These are the main Skein hash functions. Unless you have any special reasons, you should use one of these.

Skein_512_512
is the primary cryptographic hash function of this package. It can safely be used for all current hashing applications, and should remain secure for the foreseeable future.
Skein_1024_1024
is the ultra-conservative variant. Even if some future attack managed to break Skein_512_512, it is quite likely that Skein_1024_1024 would remain secure.
Skein_256_256
is the low-memory variant. It can be implemented using 100 bytes of RAM, but this is not the case with this implementation. It is faster than Skein_512_512 only for small message lengths, so it's preferable to use Skein_512_512. If you can't afford 512 bits of output, you may get the speed advantage of Skein_512_512 by using Skein_512_256.

Skein-512-512

data Skein_512_512 Source

Skein-512-512 hash. You probably want to use encode to obtain a 512-bit (64-byte) ByteString. It's the main Skein hash function. May be used as a drop-in replacement for SHA-512 as well.

data Skein_512_512_Ctx Source

Context of the Skein-512-512 hash function.

Skein-1024-1024

data Skein_1024_1024 Source

Skein-1024-1024 hash. You probably want to use encode to obtain a 1024-bit (128-byte) ByteString. This is the ultra-conservative variant. Even if some future attack managed to break Skein-512, it's quite likely that Skein-1024 would remain secure.

data Skein_1024_1024_Ctx Source

Context of the Skein-1024-1024 hash function.

Skein-256-256

data Skein_256_256 Source

Skein-256-256 hash. You probably want to use encode to obtain a 256-bit (32-byte) ByteString. Usually it's better to use Skein_512_256 (256 bits of output) or Skein_512_512 (512 bits of output).

data Skein_256_256_Ctx Source

Context of the Skein-256-256 hash function.

Skein-MAC

The standard way to use a hash function for authentication is to use the HMAC construction. While you may securely use Skein with HMAC (e.g. HMAC-Skein-512-512), Skein also supports another mode for MAC. Skein-MAC is as secure as HMAC-Skein, however faster. Skein-MAC is as fast as Skein as a hash function, with zero overhead.

type Key = ByteString Source

Secret key used to calculate the Skein-MAC.

The Key may have any length. However, it's recommended to have at least the same number of bits of the state size. For example, when using skeinMAC with Skein_512_256, it is recommended to have a key with at least 64 bytes (512 bits), which is the state size of Skein_512_256 (the first of the two numbers).

skeinMAC :: (SkeinMAC skeinCtx, Hash skeinCtx digest) => Key -> ByteString -> digest Source

Calculate the Skein-MAC of a lazy ByteString given a Key. You probably also want to apply encode to get a ByteString out of the digest.

This function may be partially applied for increased performance. Using a partially applied skeinMAC is as fast as using Skein as a cryptographic hash function. So, instead of

let mac1 = skeinMAC key message1
    mac2 = skeinMAC key message2
    mac3 = skeinMAC key message3
    ...

write the following code:

let calcMAC = skeinMAC key
    mac1 = calcMAC message1
    mac2 = calcMAC message2
    mac3 = calcMAC message3
    ...

This way the key will be processed only once (with skeinMACCtx).

skeinMAC' :: (SkeinMAC skeinCtx, Hash skeinCtx digest) => Key -> ByteString -> digest Source

Same as skeinMAC, however using a strict ByteString. Should be faster for small ByteStrings.

class SkeinMAC skeinCtx where Source

Class of Skein contexts that may be used for Skein-MAC (all of them). Included here mostly for documentation purposes, since adding new instances is not safe (functions using SkeinMAC unsurprisingly assume that they are using Skein).

Methods

skeinMACCtx :: Key -> skeinCtx Source

Construct a context skeinCtx given a Key. This context may be used with the usual Hash interface to obtain a message authentication code (MAC).

For a simpler interface, see skeinMAC and skeinMAC'.

Other variants of cryptographic hash functions

These hash functions produce less output bits than their state size. For example, Skein_512_160 produces 160 output bits while having 512 bits of state size. Their main use is to be a drop-in replacement to legacy hash functions. If you don't have any special reason for using them, use one of the main hash functions above (e.g. Skein_512_512).

You may replace:

MD5
with Skein_256_128 or Skein_512_128.
SHA-1
with Skein_256_160 or Skein_512_160.
SHA-224
with Skein_256_224 or Skein_512_224.
SHA-256
with Skein_256_256 or Skein_512_256.
SHA-384
with Skein_512_384 or Skein_1024_384.
SHA-512
with Skein_512_512 or Skein_1024_512.

Skein-256-128

data Skein_256_128 Source

Skein-256-128 hash. You probably want to use encode to obtain a 128-bit (16-byte) ByteString. May be used as a drop-in replacement for MD5.

data Skein_256_128_Ctx Source

Context of the Skein-256-128 hash function.

Skein-256-160

data Skein_256_160 Source

Skein-256-160 hash. You probably want to use encode to obtain a 160-bit (20-byte) ByteString. May be used as a drop-in replacement for SHA-1.

data Skein_256_160_Ctx Source

Context of the Skein-256-160 hash function.

Skein-256-224

data Skein_256_224 Source

Skein-256-224 hash. You probably want to use encode to obtain a 224-bit (28-byte) ByteString. May be used as a drop-in replacement for SHA-224.

data Skein_256_224_Ctx Source

Context of the Skein-256-224 hash function.

Skein-512

Skein-512-128

data Skein_512_128 Source

Skein-512-128 hash. You probably want to use encode to obtain a 128-bit (16-byte) ByteString. May be used as a drop-in replacement for MD5.

data Skein_512_128_Ctx Source

Context of the Skein-512-128 hash function.

Skein-512-160

data Skein_512_160 Source

Skein-512-160 hash. You probably want to use encode to obtain a 160-bit (20-byte) ByteString. May be used as a drop-in replacement for SHA-1.

data Skein_512_160_Ctx Source

Context of the Skein-512-160 hash function.

Skein-512-224

data Skein_512_224 Source

Skein-512-224 hash. You probably want to use encode to obtain a 224-bit (28-byte) ByteString. May be used as a drop-in replacement for SHA-224.

data Skein_512_224_Ctx Source

Context of the Skein-512-224 hash function.

Skein-512-256

data Skein_512_256 Source

Skein-512-256 hash. You probably want to use encode to obtain a 256-bit (32-byte) ByteString.

data Skein_512_256_Ctx Source

Context of the Skein-512-256 hash function.

Skein-512-384

data Skein_512_384 Source

Skein-512-384 hash. You probably want to use encode to obtain a 384-bit (48-byte) ByteString. May be used as a drop-in replacement for SHA-384.

data Skein_512_384_Ctx Source

Context of the Skein-512-384 hash function.

Skein-1024

Skein-1024-384

data Skein_1024_384 Source

Skein-1024-384 hash. You probably want to use encode to obtain a 384-bit (48-byte) ByteString. May be used as a drop-in replacement for SHA-384.

data Skein_1024_384_Ctx Source

Context of the Skein-1024-384 hash function.

Skein-1024-512

data Skein_1024_512 Source

Skein-1024-512 hash. You probably want to use encode to obtain a 512-bit (64-byte) ByteString. May be used as a drop-in replacement for SHA-512.

data Skein_1024_512_Ctx Source

Context of the Skein-1024-512 hash function.