crypto_hxx.py 5.21 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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
from gen_file import gen_file

crypto_hxx = gen_file(
    name = "decaf/crypto_%(shortname)s.hxx",
    doc = """
        @brief Example Decaf cyrpto routines, C++ wrapper.
        @warning These are merely examples, though they ought to be secure.  But real
        protocols will decide differently on magic numbers, formats, which items to
        hash, etc.
        @warning Experimental!  The names, parameter orders etc are likely to change.
    """, code = """
#include <decaf.hxx>
#include <decaf/shake.hxx>

/** @cond internal */
#if __cplusplus >= 201103L
#define NOEXCEPT noexcept
#else
#define NOEXCEPT throw()
#endif
/** @endcond */

namespace decaf {
    
template <typename Group> class PublicKey;
template <typename Group> class PrivateKey;

template<> class PublicKey<%(cxx_ns)s>
  : public Serializable< PublicKey<%(cxx_ns)s> > {
private:
    typedef %(c_ns)s_public_key_t Wrapped;
    Wrapped wrapped;
    template<class Group> friend class PrivateKey;
    
public:
    /** @brief Underlying group */
    typedef %(cxx_ns)s Group;
    
    /** @brief Signature size. */
    static const size_t SIG_BYTES = sizeof(%(c_ns)s_signature_t);
    
    /** @brief Serialization size. */
    static const size_t SER_BYTES = sizeof(Wrapped);
    
    /* TODO: convenience types like signature? */
    
    /** @brief Read a private key from a string*/
    inline explicit PublicKey(const FixedBlock<SER_BYTES> &b) NOEXCEPT {
        memcpy(wrapped,b.data(),sizeof(wrapped));
    }
    
    /** @brief Read a private key from a string*/
    inline explicit PublicKey(const PrivateKey<%(cxx_ns)s> &b) NOEXCEPT;
    
    /** @brief Create but don't initialize */
    inline explicit PublicKey(const NOINIT&) NOEXCEPT { }
    
    /** @brief Serialize into a buffer. */
    inline void serializeInto(unsigned char *x) const NOEXCEPT {
        memcpy(x,wrapped,sizeof(wrapped));
    }
    
    /** @brief Serialization size. */
    inline size_t serSize() const NOEXCEPT { return SER_BYTES; }
    
66
    /* TODO: verify_strobe */
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
    
    /** @brief Verify a message */
    inline void verify(
        const Block &message,
        const FixedBlock<SIG_BYTES> &sig
    ) const throw(CryptoException) {
        if (DECAF_SUCCESS != %(c_ns)s_verify(sig.data(),wrapped,message.data(),message.size())) {
            throw(CryptoException());
        }
    }
};

template<> class PrivateKey<%(cxx_ns)s>
  : public Serializable< PrivateKey<%(cxx_ns)s> > {
private:
    typedef %(c_ns)s_private_key_t Wrapped;
    Wrapped wrapped;
    template<class Group> friend class PublicKey;
    
public:
    /** @brief Underlying group */
    typedef %(cxx_ns)s Group;
    
    /** @brief Signature size. */
    static const size_t SIG_BYTES = sizeof(%(c_ns)s_signature_t);
    
    /** @brief Serialization size. */
    static const size_t SER_BYTES = sizeof(Wrapped);
    
    /** @brief Compressed size. */
    static const size_t SYM_BYTES = %(C_NS)s_SYMMETRIC_KEY_BYTES;
    
    /** @brief Create but don't initialize */
    inline explicit PrivateKey(const NOINIT&) NOEXCEPT { }
    
    /** @brief Read a private key from a string*/
    inline explicit PrivateKey(const FixedBlock<SER_BYTES> &b) NOEXCEPT {
        memcpy(wrapped,b.data(),sizeof(wrapped));
    }
    
    /** @brief Read a private key from a string*/
    inline explicit PrivateKey(const FixedBlock<SYM_BYTES> &b) NOEXCEPT {
        %(c_ns)s_derive_private_key(wrapped, b.data());
    }
    
    /** @brief Create at random */
    inline explicit PrivateKey(Rng &r) NOEXCEPT {
        FixedArrayBuffer<SYM_BYTES> tmp(r);
        %(c_ns)s_derive_private_key(wrapped, tmp.data());
    }
    
    /** @brief Secure destructor */
    inline ~PrivateKey() NOEXCEPT {
        %(c_ns)s_destroy_private_key(wrapped);
    }
    
    /** @brief Serialization size. */
    inline size_t serSize() const NOEXCEPT { return SER_BYTES; }
    
    /** @brief Serialize into a buffer. */
    inline void serializeInto(unsigned char *x) const NOEXCEPT {
        memcpy(x,wrapped,sizeof(wrapped));
    }
    
    /** @brief Compressed serialize. */
    inline SecureBuffer compress() const throw(std::bad_alloc) {
        SecureBuffer ret(sizeof(wrapped->sym));
        memcpy(ret.data(),wrapped->sym,sizeof(wrapped->sym));
        return ret;
    }
    
    /** @brief Get the public key */
    inline PublicKey<%(cxx_ns)s> pub() const NOEXCEPT {
        PublicKey<%(cxx_ns)s> ret(*this); return ret;
    }
    
    /** @brief Derive a shared secret */
    inline SecureBuffer sharedSecret(
        const PublicKey<%(cxx_ns)s> &pub,
        size_t bytes,
        bool me_first
    ) const throw(CryptoException,std::bad_alloc) {
        SecureBuffer ret(bytes);
        if (DECAF_SUCCESS != %(c_ns)s_shared_secret(ret.data(),bytes,wrapped,pub.wrapped,me_first)) {
            throw(CryptoException());
        }
        return ret;
    }

    /** @brief Sign a message. */ 
    inline SecureBuffer sign(const Block &message) const {
        SecureBuffer sig(SIG_BYTES);
        %(c_ns)s_sign(sig.data(), wrapped, message.data(), message.size());
        return sig;
    }
};

/** @cond internal */
PublicKey<%(cxx_ns)s>::PublicKey(const PrivateKey<%(cxx_ns)s> &b) NOEXCEPT {
    %(c_ns)s_private_to_public(wrapped,b.wrapped);
}
/** @endcond */

#undef NOEXCEPT
} /* namespace decaf */
""")