spongerng.hxx 3.1 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26


/**
 * @file decaf/strobe.hxx
 * @copyright
 *   Based on CC0 code by David Leon Gil, 2015 \n
 *   Copyright (c) 2015 Cryptography Research, Inc.  \n
 *   Released under the MIT License.  See LICENSE.txt for license information.
 * @author Mike Hamburg
 * @brief Sponge RNG instances, C++ wrapper.
 * @warning The guts of this are subject to change.  Please don't implement
 * anything that depends on the deterministic RNG being stable across versions
 * of this library.
 */

#ifndef __DECAF_SPONGERNG_HXX__
#define __DECAF_SPONGERNG_HXX__

#include <decaf/spongerng.h>

#include <string>
#include <sys/types.h>
#include <errno.h>

/** @cond internal */
#if __cplusplus >= 201103L
27 28
#define DECAF_NOEXCEPT noexcept
#define DECAF_DELETE = delete
29
#else
30 31
#define DECAF_NOEXCEPT throw()
#define DECAF_DELETE
32 33 34 35 36 37 38 39 40
#endif
/** @endcond */

namespace decaf {

/** Sponge-based random-number generator */
class SpongeRng : public Rng {
private:
    /** C wrapped object */
41
    decaf_keccak_prng_t sp;
42 43
    
public:
44 45 46 47 48 49
    /** Deterministic flag.
     * The idea is that DETERMINISTIC is used for testing or for lockstep computations,
     * and NONDETERMINISTIC is used in production.
     */
    enum Deterministic { RANDOM = 0, DETERMINISTIC = 1 };
    
50 51 52 53 54 55 56 57
    /** Exception thrown when The RNG fails (to seed itself) */
    class RngException : public std::exception {
    private:
        /** @cond internal */
        const char *const what_;
        /** @endcond */
    public:
        const int err_code; /**< errno that caused the reseed to fail. */
58 59
        const char *what() const DECAF_NOEXCEPT { return what_; } /**< Description of exception. */
        RngException(int err_code, const char *what_) DECAF_NOEXCEPT : what_(what_), err_code(err_code) {} /**< Construct */
60 61 62
    };
    
    /** Initialize, deterministically by default, from block */
63
    inline SpongeRng( const Block &in, Deterministic det ) {
64
        decaf_spongerng_init_from_buffer(sp,in.data(),in.size(),(int)det);
65 66 67
    }
    
    /** Initialize, non-deterministically by default, from C/C++ filename */
68
    inline SpongeRng( const std::string &in = "/dev/urandom", size_t len = 32, Deterministic det = RANDOM )
69
        /*throw(RngException)*/ {
70
        decaf_error_t ret = decaf_spongerng_init_from_file(sp,in.c_str(),len,det);
71 72 73 74 75 76
        if (!decaf_successful(ret)) {
            throw RngException(errno, "Couldn't load from file");
        }
    }
    
    /** Stir in new data */
77
    inline void stir( const Block &data ) DECAF_NOEXCEPT {
78
        decaf_spongerng_stir(sp,data.data(),data.size());
79 80 81
    }
    
    /** Securely destroy by overwriting state. */
82
    inline ~SpongeRng() DECAF_NOEXCEPT { decaf_spongerng_destroy(sp); }
83 84 85 86
    
    using Rng::read;
    
    /** Read data to a buffer. */
87
    virtual inline void read(Buffer buffer) DECAF_NOEXCEPT
88 89 90
#if __cplusplus >= 201103L
        final
#endif
91
        { decaf_spongerng_next(sp,buffer.data(),buffer.size()); }
92 93
    
private:
94 95
    SpongeRng(const SpongeRng &) DECAF_DELETE;
    SpongeRng &operator=(const SpongeRng &) DECAF_DELETE;
96 97 98 99 100
};
/**@endcond*/
  
} /* namespace decaf */

101 102
#undef DECAF_NOEXCEPT
#undef DECAF_DELETE
103 104

#endif /* __DECAF_SPONGERNG_HXX__ */