1 /**
2  * @file decaf/ed255.hxx
3  * @author Mike Hamburg
4  *
5  * @copyright
6  *   Copyright (c) 2015-2016 Cryptography Research, Inc.  \n
7  *   Released under the MIT License.  See LICENSE.txt for license information.
8  *
9  *
10  *
11  * @warning This file was automatically generated in Python.
12  * Please do not edit it.
13  */
14 
15 #ifndef __DECAF_ED255_HXX__
16 #define __DECAF_ED255_HXX__ 1
17 /*
18  * Example Decaf cyrpto routines, C++ wrapper.
19  * @warning These are merely examples, though they ought to be secure.  But real
20  * protocols will decide differently on magic numbers, formats, which items to
21  * hash, etc.
22  * @warning Experimental!  The names, parameter orders etc are likely to change.
23  */
24 
25 #include <decaf/eddsa.hxx>
26 #include <decaf/point_255.hxx>
27 #include <decaf/ed255.h>
28 
29 #include <decaf/shake.hxx>
30 #include <decaf/sha512.hxx>
31 
32 /** @cond internal */
33 #if __cplusplus >= 201103L
34 #define DECAF_NOEXCEPT noexcept
35 #else
36 #define DECAF_NOEXCEPT throw()
37 #endif
38 /** @endcond */
39 
40 /** Namespace for all libdecaf C++ objects. */
41 namespace decaf {
42 
43 /** A public key for crypto over some Group */
44 template <typename Group> struct EdDSA;
45 
46 /** A public key for crypto over Ristretto */
47 template<> struct EdDSA<Ristretto> {
48 
49 /** @cond internal */
50 template<class CRTP, Prehashed> class Signing;
51 template<class CRTP, Prehashed> class Verification;
52 class PublicKeyBase;
53 class PrivateKeyBase;
54 typedef class PrivateKeyBase PrivateKey, PrivateKeyPure, PrivateKeyPh;
55 typedef class PublicKeyBase PublicKey, PublicKeyPure, PublicKeyPh;
56 /** @endcond */
57 
58 /**
59  * Signatures support a "context" block, which allows you to domain separate them if
60  * (for some reason) it's annoying to domain separate the message itself.  The default
61  * is no context.  For Ed25519, the spec defining contexts is an extension, and the
62  * default is not to use that extension.  This makes "no context" different from
63  * the empty string.  For Ed448, contexts are built-in and mandatory, so "no context"
64  * is the same as the empty string.
65  */
66 #if DECAF_EDDSA_25519_SUPPORTS_CONTEXTLESS_SIGS
NO_CONTEXTdecaf::EdDSA67 static inline const Block NO_CONTEXT() { return Block(DECAF_ED25519_NO_CONTEXT,0); }
68 #else
NO_CONTEXTdecaf::EdDSA69 static inline const Block NO_CONTEXT() { return Block(NULL,0); }
70 #endif
71 
72 /** Prehash context for EdDSA. */
73 class Prehash : public SHA512 {
74 private:
75     /** @cond internal */
76     typedef SHA512 Super;
77     SecureBuffer context_;
78     template<class T, Prehashed Ph> friend class Signing;
79     template<class T, Prehashed Ph> friend class Verification;
80 
init()81     void init() /*throw(LengthException)*/ {
82         Super::reset();
83 
84         if (context_.size() > 255) {
85             throw LengthException();
86         }
87 
88         decaf_ed25519_prehash_init((decaf_sha512_ctx_s *)wrapped);
89     }
90     /** @endcond */
91 
92 public:
93     /** Number of output bytes in prehash */
94     static const size_t OUTPUT_BYTES = Super::DEFAULT_OUTPUT_BYTES;
95 
96     /** Create the prehash */
Prehash(const Block & context=NO_CONTEXT ())97     Prehash(const Block &context = NO_CONTEXT()) /*throw(LengthException)*/ {
98         context_ = context;
99         init();
100     }
101 
102     /** Reset this hash */
reset()103     void reset() DECAF_NOEXCEPT { init(); }
104 
105     /** Output from this hash */
final()106     SecureBuffer final() /*throw(std::bad_alloc)*/ {
107         SecureBuffer ret = Super::final(OUTPUT_BYTES);
108         reset();
109         return ret;
110     }
111 
112     /** Output from this hash */
final(Buffer & b)113     void final(Buffer &b) /*throw(LengthException)*/ {
114         if (b.size() != OUTPUT_BYTES) throw LengthException();
115         Super::final(b);
116         reset();
117     }
118 };
119 
120 /** Signing (i.e. private) key class template */
121 template<class CRTP, Prehashed ph> class Signing;
122 
123 /** Signing (i.e. private) key class, PureEdDSA version */
124 template<class CRTP> class Signing<CRTP,PURE>  {
125 public:
126     /**
127      * Sign a message.
128      * @param [in] message The message to be signed.
129      * @param [in] context A context for the signature; must be at most 255 bytes.
130      *
131      * @warning It is generally unsafe to use Ed25519 with both prehashed and non-prehashed messages.
132      */
sign(const Block & message,const Block & context=NO_CONTEXT ()) const133     inline SecureBuffer sign (
134         const Block &message,
135         const Block &context = NO_CONTEXT()
136     ) const /* throw(LengthException, std::bad_alloc) */ {
137         if (context.size() > 255) {
138             throw LengthException();
139         }
140 
141         SecureBuffer out(CRTP::SIG_BYTES);
142         decaf_ed25519_sign (
143             out.data(),
144             ((const CRTP*)this)->priv_.data(),
145             ((const CRTP*)this)->pub_.data(),
146             message.data(),
147             message.size(),
148             0,
149             context.data(),
150             context.size()
151         );
152         return out;
153     }
154 };
155 
156 /** Signing (i.e. private) key class, prehashed version */
157 template<class CRTP> class Signing<CRTP,PREHASHED> {
158 public:
159     /** Sign a prehash context, and reset the context */
sign_prehashed(const Prehash & ph) const160     inline SecureBuffer sign_prehashed ( const Prehash &ph ) const /*throw(std::bad_alloc)*/ {
161         SecureBuffer out(CRTP::SIG_BYTES);
162         decaf_ed25519_sign_prehash (
163             out.data(),
164             ((const CRTP*)this)->priv_.data(),
165             ((const CRTP*)this)->pub_.data(),
166             (const decaf_ed25519_prehash_ctx_s*)ph.wrapped,
167             ph.context_.data(),
168             ph.context_.size()
169         );
170         return out;
171     }
172 
173     /** Sign a message using the prehasher */
sign_with_prehash(const Block & message,const Block & context=NO_CONTEXT ()) const174     inline SecureBuffer sign_with_prehash (
175         const Block &message,
176         const Block &context = NO_CONTEXT()
177     ) const /*throw(LengthException,CryptoException)*/ {
178         Prehash ph(context);
179         ph += message;
180         return sign_prehashed(ph);
181     }
182 };
183 
184 /** Signing (i.e. private) key base class */
185 class PrivateKeyBase
186     : public Serializable<PrivateKeyBase>
187     , public Signing<PrivateKeyBase,PURE>
188     , public Signing<PrivateKeyBase,PREHASHED> {
189 public:
190     /** Type of public key corresponding to this private key */
191     typedef class PublicKeyBase PublicKey;
192 private:
193 /** @cond internal */
194     friend class PublicKeyBase;
195     friend class Signing<PrivateKey,PURE>;
196     friend class Signing<PrivateKey,PREHASHED>;
197 /** @endcond */
198 
199     /** The pre-expansion form of the signing key. */
200     FixedArrayBuffer<DECAF_EDDSA_25519_PRIVATE_BYTES> priv_;
201 
202     /** The post-expansion public key. */
203     FixedArrayBuffer<DECAF_EDDSA_25519_PUBLIC_BYTES> pub_;
204 
205 public:
206     /** Underlying group */
207     typedef Ristretto Group;
208 
209     /** Signature size. */
210     static const size_t SIG_BYTES = DECAF_EDDSA_25519_SIGNATURE_BYTES;
211 
212     /** Serialization size. */
213     static const size_t SER_BYTES = DECAF_EDDSA_25519_PRIVATE_BYTES;
214 
215 
216     /** Create but don't initialize */
PrivateKeyBase(const NOINIT &)217     inline explicit PrivateKeyBase(const NOINIT&) DECAF_NOEXCEPT : priv_((NOINIT())), pub_((NOINIT())) { }
218 
219     /** Read a private key from a string */
PrivateKeyBase(const FixedBlock<SER_BYTES> & b)220     inline explicit PrivateKeyBase(const FixedBlock<SER_BYTES> &b) DECAF_NOEXCEPT { *this = b; }
221 
222     /** Copy constructor */
PrivateKeyBase(const PrivateKey & k)223     inline PrivateKeyBase(const PrivateKey &k) DECAF_NOEXCEPT { *this = k; }
224 
225     /** Create at random */
PrivateKeyBase(Rng & r)226     inline explicit PrivateKeyBase(Rng &r) DECAF_NOEXCEPT : priv_(r) {
227         decaf_ed25519_derive_public_key(pub_.data(), priv_.data());
228     }
229 
230     /** Assignment from string */
operator =(const FixedBlock<SER_BYTES> & b)231     inline PrivateKeyBase &operator=(const FixedBlock<SER_BYTES> &b) DECAF_NOEXCEPT {
232         memcpy(priv_.data(),b.data(),b.size());
233         decaf_ed25519_derive_public_key(pub_.data(), priv_.data());
234         return *this;
235     }
236 
237     /** Copy assignment */
operator =(const PrivateKey & k)238     inline PrivateKeyBase &operator=(const PrivateKey &k) DECAF_NOEXCEPT {
239         memcpy(priv_.data(),k.priv_.data(), priv_.size());
240         memcpy(pub_.data(),k.pub_.data(), pub_.size());
241         return *this;
242     }
243 
244     /** Serialization size. */
ser_size() const245     inline size_t ser_size() const DECAF_NOEXCEPT { return SER_BYTES; }
246 
247     /** Serialize into a buffer. */
serialize_into(unsigned char * x) const248     inline void serialize_into(unsigned char *x) const DECAF_NOEXCEPT {
249         memcpy(x,priv_.data(), priv_.size());
250     }
251 
252     /** Convert to X format (to be used for key exchange) */
convert_to_x() const253     inline SecureBuffer convert_to_x() const {
254         SecureBuffer out(DECAF_X25519_PRIVATE_BYTES);
255         decaf_ed25519_convert_private_key_to_x25519(out.data(), priv_.data());
256         return out;
257     }
258 
259     /** Return the corresponding public key */
pub() const260     inline PublicKey pub() const DECAF_NOEXCEPT {
261         PublicKey pub(*this);
262         return pub;
263     }
264 }; /* class PrivateKey */
265 
266 /** Verification (i.e. public) EdDSA key, PureEdDSA version. */
267 template<class CRTP> class Verification<CRTP,PURE> {
268 public:
269     /** Verify a signature, returning DECAF_FAILURE if verification fails */
verify_noexcept(const FixedBlock<DECAF_EDDSA_25519_SIGNATURE_BYTES> & sig,const Block & message,const Block & context=NO_CONTEXT ()) const270     inline decaf_error_t DECAF_WARN_UNUSED verify_noexcept (
271         const FixedBlock<DECAF_EDDSA_25519_SIGNATURE_BYTES> &sig,
272         const Block &message,
273         const Block &context = NO_CONTEXT()
274     ) const /*DECAF_NOEXCEPT*/ {
275         if (context.size() > 255) {
276             return DECAF_FAILURE;
277         }
278 
279         return decaf_ed25519_verify (
280             sig.data(),
281             ((const CRTP*)this)->pub_.data(),
282             message.data(),
283             message.size(),
284             0,
285             context.data(),
286             context.size()
287         );
288     }
289 
290     /** Verify a signature, throwing an exception if verification fails
291      * @param [in] sig The signature.
292      * @param [in] message The signed message.
293      * @param [in] context A context for the signature; must be at most 255 bytes.
294      *
295      * @warning It is generally unsafe to use Ed25519 with both prehashed and non-prehashed messages.
296      */
verify(const FixedBlock<DECAF_EDDSA_25519_SIGNATURE_BYTES> & sig,const Block & message,const Block & context=NO_CONTEXT ()) const297     inline void verify (
298         const FixedBlock<DECAF_EDDSA_25519_SIGNATURE_BYTES> &sig,
299         const Block &message,
300         const Block &context = NO_CONTEXT()
301     ) const /*throw(LengthException,CryptoException)*/ {
302         if (context.size() > 255) {
303             throw LengthException();
304         }
305 
306         if (DECAF_SUCCESS != verify_noexcept( sig, message, context )) {
307             throw CryptoException();
308         }
309     }
310 };
311 
312 /** Verification (i.e. public) EdDSA key, prehashed version. */
313 template<class CRTP> class Verification<CRTP,PREHASHED> {
314 public:
315     /** Verify that a signature is valid for a given prehashed message, given the context. */
verify_prehashed_noexcept(const FixedBlock<DECAF_EDDSA_25519_SIGNATURE_BYTES> & sig,const Prehash & ph) const316     inline decaf_error_t DECAF_WARN_UNUSED verify_prehashed_noexcept (
317         const FixedBlock<DECAF_EDDSA_25519_SIGNATURE_BYTES> &sig,
318         const Prehash &ph
319     ) const /*DECAF_NOEXCEPT*/ {
320         return decaf_ed25519_verify_prehash (
321             sig.data(),
322             ((const CRTP*)this)->pub_.data(),
323             (const decaf_ed25519_prehash_ctx_s*)ph.wrapped,
324             ph.context_.data(),
325             ph.context_.size()
326         );
327     }
328 
329     /** Verify that a signature is valid for a given prehashed message, given the context. */
verify_prehashed(const FixedBlock<DECAF_EDDSA_25519_SIGNATURE_BYTES> & sig,const Prehash & ph) const330     inline void verify_prehashed (
331         const FixedBlock<DECAF_EDDSA_25519_SIGNATURE_BYTES> &sig,
332         const Prehash &ph
333     ) const /*throw(CryptoException)*/ {
334         if (DECAF_SUCCESS != decaf_ed25519_verify_prehash (
335             sig.data(),
336             ((const CRTP*)this)->pub_.data(),
337             (const decaf_ed25519_prehash_ctx_s*)ph.wrapped,
338             ph.context_.data(),
339             ph.context_.size()
340         )) {
341             throw CryptoException();
342         }
343     }
344 
345     /** Hash and verify a message, using the prehashed verification mode. */
verify_with_prehash(const FixedBlock<DECAF_EDDSA_25519_SIGNATURE_BYTES> & sig,const Block & message,const Block & context=NO_CONTEXT ()) const346     inline void verify_with_prehash (
347         const FixedBlock<DECAF_EDDSA_25519_SIGNATURE_BYTES> &sig,
348         const Block &message,
349         const Block &context = NO_CONTEXT()
350     ) const /*throw(LengthException,CryptoException)*/ {
351         Prehash ph(context);
352         ph += message;
353         verify_prehashed(sig,ph);
354     }
355 };
356 
357 /** EdDSA Public key base class. */
358 class PublicKeyBase
359     : public Serializable<PublicKeyBase>
360     , public Verification<PublicKeyBase,PURE>
361     , public Verification<PublicKeyBase,PREHASHED> {
362 public:
363     /** Private key corresponding to this type of public key */
364     typedef class PrivateKeyBase PrivateKey;
365 
366 private:
367 /** @cond internal */
368     friend class PrivateKeyBase;
369     friend class Verification<PublicKey,PURE>;
370     friend class Verification<PublicKey,PREHASHED>;
371 
372 private:
373     /** The pre-expansion form of the signature */
374     FixedArrayBuffer<DECAF_EDDSA_25519_PUBLIC_BYTES> pub_;
375 /** @endcond */
376 
377 public:
378     /* PERF FUTURE: Pre-cached decoding? Precomputed table?? */
379 
380     /** Underlying group */
381     typedef Ristretto Group;
382 
383     /** Signature size. */
384     static const size_t SIG_BYTES = DECAF_EDDSA_25519_SIGNATURE_BYTES;
385 
386     /** Serialization size. */
387     static const size_t SER_BYTES = DECAF_EDDSA_25519_PRIVATE_BYTES;
388 
389     /** Create but don't initialize */
PublicKeyBase(const NOINIT &)390     inline explicit PublicKeyBase(const NOINIT&) DECAF_NOEXCEPT : pub_((NOINIT())) { }
391 
392     /** Read a private key from a string */
PublicKeyBase(const FixedBlock<SER_BYTES> & b)393     inline explicit PublicKeyBase(const FixedBlock<SER_BYTES> &b) DECAF_NOEXCEPT { *this = b; }
394 
395     /** Copy constructor */
PublicKeyBase(const PublicKeyBase & k)396     inline PublicKeyBase(const PublicKeyBase &k) DECAF_NOEXCEPT { *this = k; }
397 
398     /** Copy constructor */
PublicKeyBase(const PrivateKey & k)399     inline explicit PublicKeyBase(const PrivateKey &k) DECAF_NOEXCEPT { *this = k; }
400 
401     /** Assignment from string */
operator =(const FixedBlock<SER_BYTES> & b)402     inline PublicKey &operator=(const FixedBlock<SER_BYTES> &b) DECAF_NOEXCEPT {
403         memcpy(pub_.data(),b.data(),b.size());
404         return *this;
405     }
406 
407     /** Assignment from private key */
operator =(const PublicKey & p)408     inline PublicKey &operator=(const PublicKey &p) DECAF_NOEXCEPT {
409         return *this = p.pub_;
410     }
411 
412     /** Assignment from private key */
operator =(const PrivateKey & p)413     inline PublicKey &operator=(const PrivateKey &p) DECAF_NOEXCEPT {
414         return *this = p.pub_;
415     }
416 
417     /** Serialization size. */
ser_size() const418     inline size_t ser_size() const DECAF_NOEXCEPT { return SER_BYTES; }
419 
420     /** Serialize into a buffer. */
serialize_into(unsigned char * x) const421     inline void serialize_into(unsigned char *x) const DECAF_NOEXCEPT {
422         memcpy(x,pub_.data(), pub_.size());
423     }
424 
425     /** Convert to X format (to be used for key exchange) */
convert_to_x() const426     inline SecureBuffer convert_to_x() const {
427         SecureBuffer out(DECAF_X25519_PRIVATE_BYTES);
428         decaf_ed25519_convert_public_key_to_x25519(out.data(), pub_.data());
429         return out;
430     }
431 }; /* class PublicKey */
432 
433 }; /* template<> struct EdDSA<Ristretto> */
434 
435 #undef DECAF_NOEXCEPT
436 } /* namespace decaf */
437 
438 #endif /* __DECAF_ED255_HXX__ */
439