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