|Portability||portable (needs FFI)|
- Using this module
- About Skein
- Main cryptographic hash functions
- Other variants of cryptographic hash functions
High-level interface for the Skein family of hash functions.
- data Skein_512_512
- data Skein_512_512_Ctx
- data Skein_1024_1024
- data Skein_1024_1024_Ctx
- data Skein_256_256
- data Skein_256_256_Ctx
- type Key = ByteString
- skeinMAC :: (SkeinMAC skeinCtx, Hash skeinCtx digest) => Key -> ByteString -> digest
- skeinMAC' :: (SkeinMAC skeinCtx, Hash skeinCtx digest) => Key -> ByteString -> digest
- class SkeinMAC skeinCtx where
- data Skein_256_128
- data Skein_256_128_Ctx
- data Skein_256_160
- data Skein_256_160_Ctx
- data Skein_256_224
- data Skein_256_224_Ctx
- data Skein_512_128
- data Skein_512_128_Ctx
- data Skein_512_160
- data Skein_512_160_Ctx
- data Skein_512_224
- data Skein_512_224_Ctx
- data Skein_512_256
- data Skein_512_256_Ctx
- data Skein_512_384
- data Skein_512_384_Ctx
- data Skein_1024_384
- data Skein_1024_384_Ctx
- data Skein_1024_512
- data Skein_1024_512_Ctx
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
X is internal
state size in bits and
Y is the output size in bits. The
main ones are
Skein_256_256. If you are unsure, then use
ByteStringdigest = let h =
hash is from Crypto.Classes (
encode is from
cereal package) and
is a strict
ByteString with the hash. Given that we've
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.
let calcMAC ::
Now, if you want to calculate the Skein-MAC of a lazy
let msgMAC =
Now, suppose you are given a
msg' with MAC
want to check the integrity and authenticity of
may do so by calculating the MAC of
msg' and checking
let msgMAC'' =
encode(calcMAC msg') in if msgMAC' == msgMAC'' then Right "Message is okay" else Left "Message has been corrupted or tampered with"
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.
- 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.
- is the ultra-conservative variant. Even
if some future attack managed to break
Skein_512_512, it is quite likely that
Skein_1024_1024would remain secure.
- 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_512only 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
Context of the Skein-512-512 hash function.
Skein-1024-1024 hash. You probably want to use
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.
Context of the Skein-1024-1024 hash function.
Context of the Skein-256-256 hash function.
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.
Secret key used to calculate the Skein-MAC.
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
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
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
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
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).
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.
You may replace:
Context of the Skein-256-128 hash function.
Context of the Skein-256-160 hash function.
Context of the Skein-256-224 hash function.
Context of the Skein-512-128 hash function.
Context of the Skein-512-160 hash function.
Context of the Skein-512-224 hash function.
Context of the Skein-512-256 hash function.
Context of the Skein-512-384 hash function.
Context of the Skein-1024-384 hash function.