/**
 * This module describes the _digest APIs used in Phobos. All digests follow
 * these APIs. Additionally, this module contains useful helper methods which
 * can be used with every _digest type.
 *
$(SCRIPT inhibitQuickIndex = 1;)

$(DIVC quickindex,
$(BOOKTABLE ,
$(TR $(TH Category) $(TH Functions)
)
$(TR $(TDNW Template API) $(TD $(MYREF isDigest) $(MYREF DigestType) $(MYREF hasPeek)
  $(MYREF hasBlockSize)
  $(MYREF ExampleDigest) $(MYREF _digest) $(MYREF hexDigest) $(MYREF makeDigest)
)
)
$(TR $(TDNW OOP API) $(TD $(MYREF Digest)
)
)
$(TR $(TDNW Helper functions) $(TD $(MYREF toHexString))
)
$(TR $(TDNW Implementation helpers) $(TD $(MYREF digestLength) $(MYREF WrapperDigest))
)
)
)

 * APIs:
 * There are two APIs for digests: The template API and the OOP API. The template API uses structs
 * and template helpers like $(LREF isDigest). The OOP API implements digests as classes inheriting
 * the $(LREF Digest) interface. All digests are named so that the template API struct is called "$(B x)"
 * and the OOP API class is called "$(B x)Digest". For example we have $(D MD5) <--> $(D MD5Digest),
 * $(D CRC32) <--> $(D CRC32Digest), etc.
 *
 * The template API is slightly more efficient. It does not have to allocate memory dynamically,
 * all memory is allocated on the stack. The OOP API has to allocate in the finish method if no
 * buffer was provided. If you provide a buffer to the OOP APIs finish function, it doesn't allocate,
 * but the $(LREF Digest) classes still have to be created using $(D new) which allocates them using the GC.
 *
 * The OOP API is useful to change the _digest function and/or _digest backend at 'runtime'. The benefit here
 * is that switching e.g. Phobos MD5Digest and an OpenSSLMD5Digest implementation is ABI compatible.
 *
 * If just one specific _digest type and backend is needed, the template API is usually a good fit.
 * In this simplest case, the template API can even be used without templates: Just use the "$(B x)" structs
 * directly.
 *
 * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
 * Authors:
 * Johannes Pfau
 *
 * Source:    $(PHOBOSSRC std/_digest/_package.d)
 *
 * CTFE:
 * Digests do not work in CTFE
 *
 * TODO:
 * Digesting single bits (as opposed to bytes) is not implemented. This will be done as another
 * template constraint helper (hasBitDigesting!T) and an additional interface (BitDigest)
 */
/*          Copyright Johannes Pfau 2012.
 * Distributed under the Boost Software License, Version 1.0.
 *    (See accompanying file LICENSE_1_0.txt or copy at
 *          http://www.boost.org/LICENSE_1_0.txt)
 */
module std.digest;

public import std.ascii : LetterCase;
import std.meta : allSatisfy;
import std.range.primitives;
import std.traits;


///
@system unittest
{
    import std.digest.crc;

    //Simple example
    char[8] hexHash = hexDigest!CRC32("The quick brown fox jumps over the lazy dog");
    assert(hexHash == "39A34F41");

    //Simple example, using the API manually
    CRC32 context = makeDigest!CRC32();
    context.put(cast(ubyte[])"The quick brown fox jumps over the lazy dog");
    ubyte[4] hash = context.finish();
    assert(toHexString(hash) == "39A34F41");
}

///
@system unittest
{
    //Generating the hashes of a file, idiomatic D way
    import std.digest.crc, std.digest.md, std.digest.sha;
    import std.stdio;

    // Digests a file and prints the result.
    void digestFile(Hash)(string filename)
    if (isDigest!Hash)
    {
        auto file = File(filename);
        auto result = digest!Hash(file.byChunk(4096 * 1024));
        writefln("%s (%s) = %s", Hash.stringof, filename, toHexString(result));
    }

    void main(string[] args)
    {
        foreach (name; args[1 .. $])
        {
            digestFile!MD5(name);
            digestFile!SHA1(name);
            digestFile!CRC32(name);
        }
    }
}
///
@system unittest
{
    //Generating the hashes of a file using the template API
    import std.digest.crc, std.digest.md, std.digest.sha;
    import std.stdio;
    // Digests a file and prints the result.
    void digestFile(Hash)(ref Hash hash, string filename)
    if (isDigest!Hash)
    {
        File file = File(filename);

        //As digests imlement OutputRange, we could use std.algorithm.copy
        //Let's do it manually for now
        foreach (buffer; file.byChunk(4096 * 1024))
            hash.put(buffer);

        auto result = hash.finish();
        writefln("%s (%s) = %s", Hash.stringof, filename, toHexString(result));
    }

    void uMain(string[] args)
    {
        MD5 md5;
        SHA1 sha1;
        CRC32 crc32;

        md5.start();
        sha1.start();
        crc32.start();

        foreach (arg; args[1 .. $])
        {
            digestFile(md5, arg);
            digestFile(sha1, arg);
            digestFile(crc32, arg);
        }
    }
}

///
@system unittest
{
    import std.digest.crc, std.digest.md, std.digest.sha;
    import std.stdio;

    // Digests a file and prints the result.
    void digestFile(Digest hash, string filename)
    {
        File file = File(filename);

        //As digests implement OutputRange, we could use std.algorithm.copy
        //Let's do it manually for now
        foreach (buffer; file.byChunk(4096 * 1024))
          hash.put(buffer);

        ubyte[] result = hash.finish();
        writefln("%s (%s) = %s", typeid(hash).toString(), filename, toHexString(result));
    }

    void umain(string[] args)
    {
        auto md5 = new MD5Digest();
        auto sha1 = new SHA1Digest();
        auto crc32 = new CRC32Digest();

        foreach (arg; args[1 .. $])
        {
          digestFile(md5, arg);
          digestFile(sha1, arg);
          digestFile(crc32, arg);
        }
    }
}

version (StdDdoc)
    version = ExampleDigest;

version (ExampleDigest)
{
    /**
     * This documents the general structure of a Digest in the template API.
     * All digest implementations should implement the following members and therefore pass
     * the $(LREF isDigest) test.
     *
     * Note:
     * $(UL
     * $(LI A digest must be a struct (value type) to pass the $(LREF isDigest) test.)
     * $(LI A digest passing the $(LREF isDigest) test is always an $(D OutputRange))
     * )
     */
    struct ExampleDigest
    {
        public:
            /**
             * Use this to feed the digest with data.
             * Also implements the $(REF isOutputRange, std,range,primitives)
             * interface for $(D ubyte) and $(D const(ubyte)[]).
             * The following usages of $(D put) must work for any type which
             * passes $(LREF isDigest):
             * Example:
             * ----
             * ExampleDigest dig;
             * dig.put(cast(ubyte) 0); //single ubyte
             * dig.put(cast(ubyte) 0, cast(ubyte) 0); //variadic
             * ubyte[10] buf;
             * dig.put(buf); //buffer
             * ----
             */
            @trusted void put(scope const(ubyte)[] data...)
            {

            }

            /**
             * This function is used to (re)initialize the digest.
             * It must be called before using the digest and it also works as a 'reset' function
             * if the digest has already processed data.
             */
            @trusted void start()
            {

            }

            /**
             * The finish function returns the final hash sum and resets the Digest.
             *
             * Note:
             * The actual type returned by finish depends on the digest implementation.
             * $(D ubyte[16]) is just used as an example. It is guaranteed that the type is a
             * static array of ubytes.
             *
             * $(UL
             * $(LI Use $(LREF DigestType) to obtain the actual return type.)
             * $(LI Use $(LREF digestLength) to obtain the length of the ubyte array.)
             * )
             */
            @trusted ubyte[16] finish()
            {
                return (ubyte[16]).init;
            }
    }
}

///
@system unittest
{
    //Using the OutputRange feature
    import std.algorithm.mutation : copy;
    import std.digest.md;
    import std.range : repeat;

    auto oneMillionRange = repeat!ubyte(cast(ubyte)'a', 1000000);
    auto ctx = makeDigest!MD5();
    copy(oneMillionRange, &ctx); //Note: You must pass a pointer to copy!
    assert(ctx.finish().toHexString() == "7707D6AE4E027C70EEA2A935C2296F21");
}

/**
 * Use this to check if a type is a digest. See $(LREF ExampleDigest) to see what
 * a type must provide to pass this check.
 *
 * Note:
 * This is very useful as a template constraint (see examples)
 *
 * BUGS:
 * $(UL
 * $(LI Does not yet verify that put takes scope parameters.)
 * $(LI Should check that finish() returns a ubyte[num] array)
 * )
 */
template isDigest(T)
{
    import std.range : isOutputRange;
    enum bool isDigest = isOutputRange!(T, const(ubyte)[]) && isOutputRange!(T, ubyte) &&
        is(T == struct) &&
        is(typeof(
        {
            T dig = void; //Can define
            dig.put(cast(ubyte) 0, cast(ubyte) 0); //varags
            dig.start(); //has start
            auto value = dig.finish(); //has finish
        }));
}

///
@system unittest
{
    import std.digest.crc;
    static assert(isDigest!CRC32);
}
///
@system unittest
{
    import std.digest.crc;
    void myFunction(T)()
    if (isDigest!T)
    {
        T dig;
        dig.start();
        auto result = dig.finish();
    }
    myFunction!CRC32();
}

/**
 * Use this template to get the type which is returned by a digest's $(LREF finish) method.
 */
template DigestType(T)
{
    static if (isDigest!T)
    {
        alias DigestType =
            ReturnType!(typeof(
            {
                T dig = void;
                return dig.finish();
            }));
    }
    else
        static assert(false, T.stringof ~ " is not a digest! (fails isDigest!T)");
}

///
@system unittest
{
    import std.digest.crc;
    assert(is(DigestType!(CRC32) == ubyte[4]));
}
///
@system unittest
{
    import std.digest.crc;
    CRC32 dig;
    dig.start();
    DigestType!CRC32 result = dig.finish();
}

/**
 * Used to check if a digest supports the $(D peek) method.
 * Peek has exactly the same function signatures as finish, but it doesn't reset
 * the digest's internal state.
 *
 * Note:
 * $(UL
 * $(LI This is very useful as a template constraint (see examples))
 * $(LI This also checks if T passes $(LREF isDigest))
 * )
 */
template hasPeek(T)
{
    enum bool hasPeek = isDigest!T &&
        is(typeof(
        {
            T dig = void; //Can define
            DigestType!T val = dig.peek();
        }));
}

///
@system unittest
{
    import std.digest.crc, std.digest.md;
    assert(!hasPeek!(MD5));
    assert(hasPeek!CRC32);
}
///
@system unittest
{
    import std.digest.crc;
    void myFunction(T)()
    if (hasPeek!T)
    {
        T dig;
        dig.start();
        auto result = dig.peek();
    }
    myFunction!CRC32();
}

/**
 * Checks whether the digest has a $(D blockSize) member, which contains the
 * digest's internal block size in bits. It is primarily used by $(REF HMAC, std,digest,hmac).
 */

template hasBlockSize(T)
if (isDigest!T)
{
    enum bool hasBlockSize = __traits(compiles, { size_t blockSize = T.blockSize; });
}

///
@system unittest
{
    import std.digest.hmac, std.digest.md;
    static assert(hasBlockSize!MD5        && MD5.blockSize      == 512);
    static assert(hasBlockSize!(HMAC!MD5) && HMAC!MD5.blockSize == 512);
}

package template isDigestibleRange(Range)
{
    import std.digest.md;
    import std.range : isInputRange, ElementType;
    enum bool isDigestibleRange = isInputRange!Range && is(typeof(
          {
          MD5 ha; //Could use any conformant hash
          ElementType!Range val;
          ha.put(val);
          }));
}

/**
 * This is a convenience function to calculate a hash using the template API.
 * Every digest passing the $(LREF isDigest) test can be used with this function.
 *
 * Params:
 *  range= an $(D InputRange) with $(D ElementType) $(D ubyte), $(D ubyte[]) or $(D ubyte[num])
 */
DigestType!Hash digest(Hash, Range)(auto ref Range range)
if (!isArray!Range
    && isDigestibleRange!Range)
{
    import std.algorithm.mutation : copy;
    Hash hash;
    hash.start();
    copy(range, &hash);
    return hash.finish();
}

///
@system unittest
{
    import std.digest.md;
    import std.range : repeat;
    auto testRange = repeat!ubyte(cast(ubyte)'a', 100);
    auto md5 = digest!MD5(testRange);
}

/**
 * This overload of the digest function handles arrays.
 *
 * Params:
 *  data= one or more arrays of any type
 */
DigestType!Hash digest(Hash, T...)(scope const T data)
if (allSatisfy!(isArray, typeof(data)))
{
    Hash hash;
    hash.start();
    foreach (datum; data)
        hash.put(cast(const(ubyte[]))datum);
    return hash.finish();
}

///
@system unittest
{
    import std.digest.crc, std.digest.md, std.digest.sha;
    auto md5   = digest!MD5(  "The quick brown fox jumps over the lazy dog");
    auto sha1  = digest!SHA1( "The quick brown fox jumps over the lazy dog");
    auto crc32 = digest!CRC32("The quick brown fox jumps over the lazy dog");
    assert(toHexString(crc32) == "39A34F41");
}

///
@system unittest
{
    import std.digest.crc;
    auto crc32 = digest!CRC32("The quick ", "brown ", "fox jumps over the lazy dog");
    assert(toHexString(crc32) == "39A34F41");
}

/**
 * This is a convenience function similar to $(LREF digest), but it returns the string
 * representation of the hash. Every digest passing the $(LREF isDigest) test can be used with this
 * function.
 *
 * Params:
 *  order= the order in which the bytes are processed (see $(LREF toHexString))
 *  range= an $(D InputRange) with $(D ElementType) $(D ubyte), $(D ubyte[]) or $(D ubyte[num])
 */
char[digestLength!(Hash)*2] hexDigest(Hash, Order order = Order.increasing, Range)(ref Range range)
if (!isArray!Range && isDigestibleRange!Range)
{
    return toHexString!order(digest!Hash(range));
}

///
@system unittest
{
    import std.digest.md;
    import std.range : repeat;
    auto testRange = repeat!ubyte(cast(ubyte)'a', 100);
    assert(hexDigest!MD5(testRange) == "36A92CC94A9E0FA21F625F8BFB007ADF");
}

/**
 * This overload of the hexDigest function handles arrays.
 *
 * Params:
 *  order= the order in which the bytes are processed (see $(LREF toHexString))
 *  data= one or more arrays of any type
 */
char[digestLength!(Hash)*2] hexDigest(Hash, Order order = Order.increasing, T...)(scope const T data)
if (allSatisfy!(isArray, typeof(data)))
{
    return toHexString!order(digest!Hash(data));
}

///
@system unittest
{
    import std.digest.crc;
    assert(hexDigest!(CRC32, Order.decreasing)("The quick brown fox jumps over the lazy dog") == "414FA339");
}
///
@system unittest
{
    import std.digest.crc;
    assert(hexDigest!(CRC32, Order.decreasing)("The quick ", "brown ", "fox jumps over the lazy dog") == "414FA339");
}

/**
 * This is a convenience function which returns an initialized digest, so it's not necessary to call
 * start manually.
 */
Hash makeDigest(Hash)()
{
    Hash hash;
    hash.start();
    return hash;
}

///
@system unittest
{
    import std.digest.md;
    auto md5 = makeDigest!MD5();
    md5.put(0);
    assert(toHexString(md5.finish()) == "93B885ADFE0DA089CDF634904FD59F71");
}

/*+*************************** End of template part, welcome to OOP land **************************/

/**
 * This describes the OOP API. To understand when to use the template API and when to use the OOP API,
 * see the module documentation at the top of this page.
 *
 * The Digest interface is the base interface which is implemented by all digests.
 *
 * Note:
 * A Digest implementation is always an $(D OutputRange)
 */
interface Digest
{
    public:
        /**
         * Use this to feed the digest with data.
         * Also implements the $(REF isOutputRange, std,range,primitives)
         * interface for $(D ubyte) and $(D const(ubyte)[]).
         *
         * Example:
         * ----
         * void test(Digest dig)
         * {
         *     dig.put(cast(ubyte) 0); //single ubyte
         *     dig.put(cast(ubyte) 0, cast(ubyte) 0); //variadic
         *     ubyte[10] buf;
         *     dig.put(buf); //buffer
         * }
         * ----
         */
        @trusted nothrow void put(scope const(ubyte)[] data...);

        /**
         * Resets the internal state of the digest.
         * Note:
         * $(LREF finish) calls this internally, so it's not necessary to call
         * $(D reset) manually after a call to $(LREF finish).
         */
        @trusted nothrow void reset();

        /**
         * This is the length in bytes of the hash value which is returned by $(LREF finish).
         * It's also the required size of a buffer passed to $(LREF finish).
         */
        @trusted nothrow @property size_t length() const;

        /**
         * The finish function returns the hash value. It takes an optional buffer to copy the data
         * into. If a buffer is passed, it must be at least $(LREF length) bytes big.
         */
        @trusted nothrow ubyte[] finish();
        ///ditto
        nothrow ubyte[] finish(ubyte[] buf);
        //@@@BUG@@@ http://d.puremagic.com/issues/show_bug.cgi?id=6549
        /*in
        {
            assert(buf.length >= this.length);
        }*/

        /**
         * This is a convenience function to calculate the hash of a value using the OOP API.
         */
        final @trusted nothrow ubyte[] digest(scope const(void[])[] data...)
        {
            this.reset();
            foreach (datum; data)
                this.put(cast(ubyte[]) datum);
            return this.finish();
        }
}

///
@system unittest
{
    //Using the OutputRange feature
    import std.algorithm.mutation : copy;
    import std.digest.md;
    import std.range : repeat;

    auto oneMillionRange = repeat!ubyte(cast(ubyte)'a', 1000000);
    auto ctx = new MD5Digest();
    copy(oneMillionRange, ctx);
    assert(ctx.finish().toHexString() == "7707D6AE4E027C70EEA2A935C2296F21");
}

///
@system unittest
{
    import std.digest.crc, std.digest.md, std.digest.sha;
    ubyte[] md5   = (new MD5Digest()).digest("The quick brown fox jumps over the lazy dog");
    ubyte[] sha1  = (new SHA1Digest()).digest("The quick brown fox jumps over the lazy dog");
    ubyte[] crc32 = (new CRC32Digest()).digest("The quick brown fox jumps over the lazy dog");
    assert(crcHexString(crc32) == "414FA339");
}

///
@system unittest
{
    import std.digest.crc;
    ubyte[] crc32 = (new CRC32Digest()).digest("The quick ", "brown ", "fox jumps over the lazy dog");
    assert(crcHexString(crc32) == "414FA339");
}

@system unittest
{
    import std.range : isOutputRange;
    assert(!isDigest!(Digest));
    assert(isOutputRange!(Digest, ubyte));
}

///
@system unittest
{
    void test(Digest dig)
    {
        dig.put(cast(ubyte) 0); //single ubyte
        dig.put(cast(ubyte) 0, cast(ubyte) 0); //variadic
        ubyte[10] buf;
        dig.put(buf); //buffer
    }
}

/*+*************************** End of OOP part, helper functions follow ***************************/

/**
 * See $(LREF toHexString)
 */
enum Order : bool
{
    increasing, ///
    decreasing ///
}


/**
 * Used to convert a hash value (a static or dynamic array of ubytes) to a string.
 * Can be used with the OOP and with the template API.
 *
 * The additional order parameter can be used to specify the order of the input data.
 * By default the data is processed in increasing order, starting at index 0. To process it in the
 * opposite order, pass Order.decreasing as a parameter.
 *
 * The additional letterCase parameter can be used to specify the case of the output data.
 * By default the output is in upper case. To change it to the lower case
 * pass LetterCase.lower as a parameter.
 *
 * Note:
 * The function overloads returning a string allocate their return values
 * using the GC. The versions returning static arrays use pass-by-value for
 * the return value, effectively avoiding dynamic allocation.
 */
char[num*2] toHexString(Order order = Order.increasing, size_t num, LetterCase letterCase = LetterCase.upper)
(in ubyte[num] digest)
{
    static if (letterCase == LetterCase.upper)
    {
        import std.ascii : hexDigits = hexDigits;
    }
    else
    {
        import std.ascii : hexDigits = lowerHexDigits;
    }


    char[num*2] result;
    size_t i;

    static if (order == Order.increasing)
    {
        foreach (u; digest)
        {
            result[i++] = hexDigits[u >> 4];
            result[i++] = hexDigits[u & 15];
        }
    }
    else
    {
        size_t j = num - 1;
        while (i < num*2)
        {
            result[i++] = hexDigits[digest[j] >> 4];
            result[i++] = hexDigits[digest[j] & 15];
            j--;
        }
    }
    return result;
}

///ditto
char[num*2] toHexString(LetterCase letterCase, Order order = Order.increasing, size_t num)(in ubyte[num] digest)
{
    return toHexString!(order, num, letterCase)(digest);
}

///ditto
string toHexString(Order order = Order.increasing, LetterCase letterCase = LetterCase.upper)
(in ubyte[] digest)
{
    static if (letterCase == LetterCase.upper)
    {
        import std.ascii : hexDigits = hexDigits;
    }
    else
    {
        import std.ascii : hexDigits = lowerHexDigits;
    }

    auto result = new char[digest.length*2];
    size_t i;

    static if (order == Order.increasing)
    {
        foreach (u; digest)
        {
            result[i++] = hexDigits[u >> 4];
            result[i++] = hexDigits[u & 15];
        }
    }
    else
    {
        import std.range : retro;
        foreach (u; retro(digest))
        {
            result[i++] = hexDigits[u >> 4];
            result[i++] = hexDigits[u & 15];
        }
    }
    import std.exception : assumeUnique;
    // memory was just created, so casting to immutable is safe
    return () @trusted { return assumeUnique(result); }();
}

///ditto
string toHexString(LetterCase letterCase, Order order = Order.increasing)(in ubyte[] digest)
{
    return toHexString!(order, letterCase)(digest);
}

//For more example unittests, see Digest.digest, digest

///
@safe unittest
{
    import std.digest.crc;
    //Test with template API:
    auto crc32 = digest!CRC32("The quick ", "brown ", "fox jumps over the lazy dog");
    //Lower case variant:
    assert(toHexString!(LetterCase.lower)(crc32) == "39a34f41");
    //Usually CRCs are printed in this order, though:
    assert(toHexString!(Order.decreasing)(crc32) == "414FA339");
    assert(toHexString!(LetterCase.lower, Order.decreasing)(crc32) == "414fa339");
}

///
@safe unittest
{
    import std.digest.crc;
    // With OOP API
    auto crc32 = (new CRC32Digest()).digest("The quick ", "brown ", "fox jumps over the lazy dog");
    //Usually CRCs are printed in this order, though:
    assert(toHexString!(Order.decreasing)(crc32) == "414FA339");
}

@safe unittest
{
    ubyte[16] data;
    assert(toHexString(data) == "00000000000000000000000000000000");

    assert(toHexString(cast(ubyte[4])[42, 43, 44, 45]) == "2A2B2C2D");
    assert(toHexString(cast(ubyte[])[42, 43, 44, 45]) == "2A2B2C2D");
    assert(toHexString!(Order.decreasing)(cast(ubyte[4])[42, 43, 44, 45]) == "2D2C2B2A");
    assert(toHexString!(Order.decreasing, LetterCase.lower)(cast(ubyte[4])[42, 43, 44, 45]) == "2d2c2b2a");
    assert(toHexString!(Order.decreasing)(cast(ubyte[])[42, 43, 44, 45]) == "2D2C2B2A");
}

/*+*********************** End of public helper part, private helpers follow ***********************/

/*
 * Used to convert from a ubyte[] slice to a ref ubyte[N].
 * This helper is used internally in the WrapperDigest template to wrap the template API's
 * finish function.
 */
ref T[N] asArray(size_t N, T)(ref T[] source, string errorMsg = "")
{
     assert(source.length >= N, errorMsg);
     return *cast(T[N]*) source.ptr;
}

/*
 * Returns the length (in bytes) of the hash value produced by T.
 */
template digestLength(T)
if (isDigest!T)
{
    enum size_t digestLength = (ReturnType!(T.finish)).length;
}

@safe pure nothrow @nogc
unittest
{
    import std.digest.md : MD5;
    import std.digest.sha : SHA1, SHA256, SHA512;
    assert(digestLength!MD5 == 16);
    assert(digestLength!SHA1 == 20);
    assert(digestLength!SHA256 == 32);
    assert(digestLength!SHA512 == 64);
}

/**
 * Wraps a template API hash struct into a Digest interface.
 * Modules providing digest implementations will usually provide
 * an alias for this template (e.g. MD5Digest, SHA1Digest, ...).
 */
class WrapperDigest(T)
if (isDigest!T) : Digest
{
    protected:
        T _digest;

    public final:
        /**
         * Initializes the digest.
         */
        this()
        {
            _digest.start();
        }

        /**
         * Use this to feed the digest with data.
         * Also implements the $(REF isOutputRange, std,range,primitives)
         * interface for $(D ubyte) and $(D const(ubyte)[]).
         */
        @trusted nothrow void put(scope const(ubyte)[] data...)
        {
            _digest.put(data);
        }

        /**
         * Resets the internal state of the digest.
         * Note:
         * $(LREF finish) calls this internally, so it's not necessary to call
         * $(D reset) manually after a call to $(LREF finish).
         */
        @trusted nothrow void reset()
        {
            _digest.start();
        }

        /**
         * This is the length in bytes of the hash value which is returned by $(LREF finish).
         * It's also the required size of a buffer passed to $(LREF finish).
         */
        @trusted nothrow @property size_t length() const pure
        {
            return digestLength!T;
        }

        /**
         * The finish function returns the hash value. It takes an optional buffer to copy the data
         * into. If a buffer is passed, it must have a length at least $(LREF length) bytes.
         *
         * Example:
         * --------
         *
         * import std.digest.md;
         * ubyte[16] buf;
         * auto hash = new WrapperDigest!MD5();
         * hash.put(cast(ubyte) 0);
         * auto result = hash.finish(buf[]);
         * //The result is now in result (and in buf). If you pass a buffer which is bigger than
         * //necessary, result will have the correct length, but buf will still have it's original
         * //length
         * --------
         */
        nothrow ubyte[] finish(ubyte[] buf)
        in
        {
            assert(buf.length >= this.length);
        }
        body
        {
            enum string msg = "Buffer needs to be at least " ~ digestLength!(T).stringof ~ " bytes " ~
                "big, check " ~ typeof(this).stringof ~ ".length!";
            asArray!(digestLength!T)(buf, msg) = _digest.finish();
            return buf[0 .. digestLength!T];
        }

        ///ditto
        @trusted nothrow ubyte[] finish()
        {
            enum len = digestLength!T;
            auto buf = new ubyte[len];
            asArray!(digestLength!T)(buf) = _digest.finish();
            return buf;
        }

        version (StdDdoc)
        {
            /**
             * Works like $(D finish) but does not reset the internal state, so it's possible
             * to continue putting data into this WrapperDigest after a call to peek.
             *
             * These functions are only available if $(D hasPeek!T) is true.
             */
            @trusted ubyte[] peek(ubyte[] buf) const;
            ///ditto
            @trusted ubyte[] peek() const;
        }
        else static if (hasPeek!T)
        {
            @trusted ubyte[] peek(ubyte[] buf) const
            in
            {
                assert(buf.length >= this.length);
            }
            body
            {
                enum string msg = "Buffer needs to be at least " ~ digestLength!(T).stringof ~ " bytes " ~
                    "big, check " ~ typeof(this).stringof ~ ".length!";
                asArray!(digestLength!T)(buf, msg) = _digest.peek();
                return buf[0 .. digestLength!T];
            }

            @trusted ubyte[] peek() const
            {
                enum len = digestLength!T;
                auto buf = new ubyte[len];
                asArray!(digestLength!T)(buf) = _digest.peek();
                return buf;
            }
        }
}

///
@system unittest
{
    import std.digest.md;
    //Simple example
    auto hash = new WrapperDigest!MD5();
    hash.put(cast(ubyte) 0);
    auto result = hash.finish();
}

///
@system unittest
{
    //using a supplied buffer
    import std.digest.md;
    ubyte[16] buf;
    auto hash = new WrapperDigest!MD5();
    hash.put(cast(ubyte) 0);
    auto result = hash.finish(buf[]);
    //The result is now in result (and in buf). If you pass a buffer which is bigger than
    //necessary, result will have the correct length, but buf will still have it's original
    //length
}

@safe unittest
{
    // Test peek & length
    import std.digest.crc;
    auto hash = new WrapperDigest!CRC32();
    assert(hash.length == 4);
    hash.put(cast(const(ubyte[]))"The quick brown fox jumps over the lazy dog");
    assert(hash.peek().toHexString() == "39A34F41");
    ubyte[5] buf;
    assert(hash.peek(buf).toHexString() == "39A34F41");
}

/**
 * Securely compares two digest representations while protecting against timing
 * attacks. Do not use `==` to compare digest representations.
 *
 * The attack happens as follows:
 *
 * $(OL
 *     $(LI An attacker wants to send harmful data to your server, which
 *     requires a integrity HMAC SHA1 token signed with a secret.)
 *     $(LI The length of the token is known to be 40 characters long due to its format,
 *     so the attacker first sends `"0000000000000000000000000000000000000000"`,
 *     then `"1000000000000000000000000000000000000000"`, and so on.)
 *     $(LI The given HMAC token is compared with the expected token using the
 *     `==` string comparison, which returns `false` as soon as the first wrong
 *     element is found. If a wrong element is found, then a rejection is sent
 *     back to the sender.)
 *     $(LI Eventually, the attacker is able to determine the first character in
 *     the correct token because the sever takes slightly longer to return a
 *     rejection. This is due to the comparison moving on to second item in
 *     the two arrays, seeing they are different, and then sending the rejection.)
 *     $(LI It may seem like too small of a difference in time for the attacker
 *     to notice, but security researchers have shown that differences as
 *     small as $(LINK2 http://www.cs.rice.edu/~dwallach/pub/crosby-timing2009.pdf,
 *     20µs can be reliably distinguished) even with network inconsistencies.)
 *     $(LI Repeat the process for each character until the attacker has the whole
 *     correct token and the server accepts the harmful data. This can be done
 *     in a week with the attacker pacing the attack to 10 requests per second
 *     with only one client.)
 * )
 *
 * This function defends against this attack by always comparing every single
 * item in the array if the two arrays are the same length. Therefore, this
 * function is always $(BIGOH n) for ranges of the same length.
 *
 * This attack can also be mitigated via rate limiting and banning IPs which have too
 * many rejected requests. However, this does not completely solve the problem,
 * as the attacker could be in control of a bot net. To fully defend against
 * the timing attack, rate limiting, banning IPs, and using this function
 * should be used together.
 *
 * Params:
 *     r1 = A digest representation
 *     r2 = A digest representation
 * Returns:
 *     `true` if both representations are equal, `false` otherwise
 * See_Also:
 *     $(LINK2 https://en.wikipedia.org/wiki/Timing_attack, The Wikipedia article
 *     on timing attacks).
 */
bool secureEqual(R1, R2)(R1 r1, R2 r2)
if (isInputRange!R1 && isInputRange!R2 && !isInfinite!R1 && !isInfinite!R2 &&
    (isIntegral!(ElementEncodingType!R1) || isSomeChar!(ElementEncodingType!R1)) &&
    !is(CommonType!(ElementEncodingType!R1, ElementEncodingType!R2) == void))
{
    static if (hasLength!R1 && hasLength!R2)
        if (r1.length != r2.length)
            return false;

    int result;

    static if (isRandomAccessRange!R1 && isRandomAccessRange!R2 &&
               hasLength!R1 && hasLength!R2)
    {
        foreach (i; 0 .. r1.length)
            result |= r1[i] ^ r2[i];
    }
    else static if (hasLength!R1 && hasLength!R2)
    {
        // Lengths are the same so we can squeeze out a bit of performance
        // by not checking if r2 is empty
        for (; !r1.empty; r1.popFront(), r2.popFront())
        {
            result |= r1.front ^ r2.front;
        }
    }
    else
    {
        // Generic case, walk both ranges
        for (; !r1.empty; r1.popFront(), r2.popFront())
        {
            if (r2.empty) return false;
            result |= r1.front ^ r2.front;
        }
        if (!r2.empty) return false;
    }

    return result == 0;
}

///
@system pure unittest
{
    import std.digest.hmac : hmac;
    import std.digest.sha : SHA1;
    import std.string : representation;

    // a typical HMAC data integrity verification
    auto secret = "A7GZIP6TAQA6OHM7KZ42KB9303CEY0MOV5DD6NTV".representation;
    auto data = "data".representation;

    string hex1 = data.hmac!SHA1(secret).toHexString;
    string hex2 = data.hmac!SHA1(secret).toHexString;
    string hex3 = "data1".representation.hmac!SHA1(secret).toHexString;

    assert( secureEqual(hex1, hex2));
    assert(!secureEqual(hex1, hex3));
}

@system pure unittest
{
    import std.internal.test.dummyrange : ReferenceInputRange;
    import std.range : takeExactly;
    import std.string : representation;
    import std.utf : byWchar, byDchar;

    {
        auto hex1 = "02CA3484C375EDD3C0F08D3F50D119E61077".representation;
        auto hex2 = "02CA3484C375EDD3C0F08D3F50D119E610779018".representation;
        assert(!secureEqual(hex1, hex2));
    }
    {
        auto hex1 = "02CA3484C375EDD3C0F08D3F50D119E610779018"w.representation;
        auto hex2 = "02CA3484C375EDD3C0F08D3F50D119E610779018"d.representation;
        assert(secureEqual(hex1, hex2));
    }
    {
        auto hex1 = "02CA3484C375EDD3C0F08D3F50D119E610779018".byWchar;
        auto hex2 = "02CA3484C375EDD3C0F08D3F50D119E610779018".byDchar;
        assert(secureEqual(hex1, hex2));
    }
    {
        auto hex1 = "02CA3484C375EDD3C0F08D3F50D119E61077".byWchar;
        auto hex2 = "02CA3484C375EDD3C0F08D3F50D119E610779018".byDchar;
        assert(!secureEqual(hex1, hex2));
    }
    {
        auto hex1 = new ReferenceInputRange!int([0, 1, 2, 3, 4, 5, 6, 7, 8]).takeExactly(9);
        auto hex2 = new ReferenceInputRange!int([0, 1, 2, 3, 4, 5, 6, 7, 8]).takeExactly(9);
        assert(secureEqual(hex1, hex2));
    }
    {
        auto hex1 = new ReferenceInputRange!int([0, 1, 2, 3, 4, 5, 6, 7, 8]).takeExactly(9);
        auto hex2 = new ReferenceInputRange!int([0, 1, 2, 3, 4, 5, 6, 7, 9]).takeExactly(9);
        assert(!secureEqual(hex1, hex2));
    }
}
