]> git.codecow.com Git - Monocypher.git/commitdiff
cleanups
authorLoup Vaillant <loup@loup-vaillant.fr>
Mon, 13 Feb 2017 11:55:29 +0000 (12:55 +0100)
committerLoup Vaillant <loup@loup-vaillant.fr>
Mon, 13 Feb 2017 11:55:29 +0000 (12:55 +0100)
makefile
monocypher.c
monocypher.h

index 4388c3bc273d50e04fb94a8c1a416fe9fe633eee..9c8cf6c6725d9cb9e3637231c82f84f92ad48c43 100644 (file)
--- a/makefile
+++ b/makefile
@@ -14,8 +14,8 @@ test: test.o monocypher.o sha512.o
 test.o: test.c
        $(CC) $(CFLAGS) -c $^
 
-sha512.o: sha512.c
+sha512.o: sha512.c sha512.h
        $(CC) $(CFLAGS) -c $^
 
-monocypher.o: monocypher.c
+monocypher.o: monocypher.c monocypher.h
        $(CC) $(CFLAGS) -c $^ -DED25519_SHA512
index ef5844172e703569f1e677a3e5393bc6576431d0..8bf0d74d330daee6dc8d18df6bd55ff3c78e404b 100644 (file)
@@ -74,10 +74,10 @@ sv store64_le(u8 output[8], u64 input)
 static u64 rotr64(u64 x, u64 n) { return (x >> n) ^ (x << (64 - n)); }
 static u32 rotl32(u32 x, u32 n) { return (x << n) ^ (x >> (32 - n)); }
 
-int crypto_memcmp(const u8 mac1[16], const u8 mac2[16], size_t n)
+int crypto_memcmp(const u8 *p1, const u8 *p2, size_t n)
 {
     unsigned diff = 0;
-    FOR (i, 0, n) { diff |= (mac1[i] ^ mac2[i]); }
+    FOR (i, 0, n) { diff |= (p1[i] ^ p2[i]); }
     return diff;
 }
 
index ac68b65043ab52fdba65845225fe29368175b31e..e0cb151f6f4dee0daac211bba49efa9e4a8e06cf 100644 (file)
@@ -6,85 +6,34 @@
 
 // Constant time equality verification
 // returns 0 if it matches, something else otherwise.
-int crypto_memcmp(const uint8_t mac1[16], const uint8_t mac2[16], size_t n);
+int crypto_memcmp(const uint8_t *p1, const uint8_t *p2, size_t n);
 
 ////////////////
 /// Chacha20 ///
 ////////////////
-
-// This is a chacha20 context.
-// To use safely, just follow these guidelines:
-// - Always initialize your context with one of the crypto_init_* functions below
-// - Dont't modify it, except through the crypto_chacha20_* below.
-// - Never duplicate it.
-typedef struct crypto_chacha_ctx {
+typedef struct {
     uint32_t input[16];       // current input, unencrypted
     uint8_t  random_pool[64]; // last input, encrypted
     uint8_t  pool_index;      // pointer to random_pool
 } crypto_chacha_ctx;
 
-// HChacha20.  *Kind* of a cryptographic hash, based on the chacha20 rounds.
-// Used for XChacha20, and the key derivation of the X25519 shared secret.
-// Don't use it unless you really know what you're doing.
 void crypto_chacha20_H(uint8_t       out[32],
                        const uint8_t key[32],
                        const uint8_t in [16]);
 
-// Initializes a chacha context.
-//
-// WARNING: DON'T USE THE SAME NONCE AND KEY TWICE
-//
-// You'd be exposing the XOR of subsequent encrypted
-// messages, thus destroying your confidentiality.
-//
-// WARNING: DON'T SELECT THE NONCE AT RANDOM
-//
-// If you encode enough messages with a random nonce, there's a good
-// chance some of them will use the same nonce by accident. 64 bits
-// just aren't enough.  Use a counter instead.
-//
-// If there are multiple parties sending out messages, you can give them
-// all an initial nonce of 0, 1 .. n-1 respectively, and have them increment
-// their nonce  by n.  (Also make sure the nonces never wrap around.)
 void crypto_chacha20_init(crypto_chacha_ctx *ctx,
                           const uint8_t      key[32],
                           const uint8_t      nonce[8]);
 
-// Initializes a chacha context, with a big nonce (192 bits),
-// more than enough to be selected at random.
-//
-// The price you pay for that is a slower initialization.  The security
-// guarantees are the same as regular initialization.
 void crypto_chacha20_Xinit(crypto_chacha_ctx *ctx,
                            const uint8_t      key[32],
                            const uint8_t      nonce[24]);
 
-// Encrypts the plain_text by XORing it with a pseudo-random
-// stream of numbers, seeded by the provided chacha20 context.
-// Decryption uses the exact same method.
-//
-// Once the context is initialized, encryptions can safely be chained thus:
-//
-//    crypto_encrypt_chacha20(ctx, plain_0, cipher_0, length_0);
-//    crypto_encrypt_chacha20(ctx, plain_1, cipher_1, length_1);
-//    crypto_encrypt_chacha20(ctx, plain_2, cipher_2, length_2);
-//
-// plain_text and cipher_text may point to the same location, for in-place
-// encryption.
-//
-// plain_text is allowed to be null (0), in which case it will be
-// interpreted as an all zero input.  The cipher_text will then
-// contain the raw chacha20 stream.  Useful as a random number
-// generator.
-//
-// WARNING: ENCRYPTION ALONE IS NOT SECURE.  YOU NEED AUTHENTICATION AS WELL.
-// Use the provided authenticated encryption constructions.
 void crypto_chacha20_encrypt(crypto_chacha_ctx *ctx,
                              const uint8_t     *plain_text,
                              uint8_t           *cipher_text,
                              size_t             message_size);
 
-// convenience function.  Same as chacha20_encrypt() with a null plain_text.
 void crypto_chacha20_random(crypto_chacha_ctx *ctx,
                             uint8_t           *cipher_text,
                             size_t             message_size);
@@ -92,7 +41,6 @@ void crypto_chacha20_random(crypto_chacha_ctx *ctx,
 /////////////////
 /// Poly 1305 ///
 /////////////////
-
 typedef struct {
     uint32_t r[4];
     uint32_t h[5];
@@ -101,35 +49,20 @@ typedef struct {
     size_t   c_index;
 } crypto_poly1305_ctx;
 
-// Initializes the poly1305 context with the secret key.
-// Call first (obviously).
-// WARNING: NEVER AUTHENTICATE 2 MESSAGES WITH THE SAME KEY.
-// This is a ONE TIME authenticator.  If you authenticate 2 messages
-// with the same key, the attacker may deduce your secret key and
-// authenticate messages in your stead.
 void crypto_poly1305_init(crypto_poly1305_ctx *ctx, const uint8_t key[32]);
 
-// Updates the poly1305 context with a chunk of the message
-// Can be called multiple times, once for each chunk.
-// Make sure the chunks are processed in order, without overlap or hole...
 void crypto_poly1305_update(crypto_poly1305_ctx *ctx,
                             const uint8_t *m, size_t bytes);
 
-// Authenticate the message munched through previous update() calls.
-// Call last (obviously).
 void crypto_poly1305_finish(crypto_poly1305_ctx *ctx, uint8_t mac[16]);
 
-
-// Convenience all in one function
 void crypto_poly1305_auth(uint8_t        mac[16],
-                          const uint8_t *m,
-                          size_t         msg_length,
+                          const uint8_t *msg, size_t msg_length,
                           const uint8_t  key[32]);
 
 ////////////////
 /// Blake2 b ///
 ////////////////
-
 typedef struct {
     uint8_t  buf[128];      // input buffer
     uint64_t hash[8];       // chained state
@@ -138,53 +71,25 @@ typedef struct {
     uint8_t  output_size;   // digest size
 } crypto_blake2b_ctx;
 
-// Initializes the context with user defined parameters:
-// outlen: the length of the hash.  Must be between 1 and 64.
-// keylen: length of the key.       Must be between 0 and 64.
-// key   : some secret key.         May be NULL if keylen is 0.
-// Any deviation from these invariants results in UNDEFINED BEHAVIOR
 void crypto_blake2b_general_init(crypto_blake2b_ctx *ctx, size_t outlen,
                                  const uint8_t      *key, size_t keylen);
 
-// Convenience function: 64 bytes hash, no secret key.
 void crypto_blake2b_init(crypto_blake2b_ctx *ctx);
 
-// Add "inlen" bytes from "in" into the hash.
 void crypto_blake2b_update(crypto_blake2b_ctx *ctx,
                            const uint8_t *in, size_t inlen);
 
-// Generate the message digest (size given in init).
 void crypto_blake2b_final(crypto_blake2b_ctx *ctx, uint8_t *out);
 
-// All-in-one convenience function.
-// outlen, keylen, and key work the same as they do in the general_init function
 void crypto_blake2b_general(uint8_t       *out, size_t outlen, // digest
                             const uint8_t *key, size_t keylen, // optional secret
                             const uint8_t *in , size_t inlen);
 
-// All-in-one convenience function: 64 bytes hash, no secret key.
 void crypto_blake2b(uint8_t out[64], const uint8_t *in, size_t inlen);
 
-
 ////////////////
 /// Argon2 i ///
 ////////////////
-
-// Implements argon2i, with degree of paralelism 1,
-// because it's good enough, and threads are scary.
-//
-// key and ad are optionnal.  They can be NULL if their respective size is 0.
-// work_area is a pointer to a contiguous chunk of memory of at least
-// nb_blocks * 1024 bytes.  It must be suitably aligned for 64-bit words.
-// Don't worry too much about alignment, malloc()'s results work.
-//
-// Choice of parameters for password hashing:
-// - If you need a key, use a 32 bytes one.
-// - Do what you will with the ad.
-// - Use a 32 bytes tag (to get a 256-bit key)
-// - Put 128 bits of entropy in the salt.  16 random bytes work well.
-// - Use all the memory you can get away with.
-// - Use as much iterations as reasonable.  No less than 10 passes if you can.
 void crypto_argon2i(uint8_t       *tag,       uint32_t tag_size,      // >= 4
                     const uint8_t *password,  uint32_t password_size,
                     const uint8_t *salt,      uint32_t salt_size,     // >= 8
@@ -197,32 +102,10 @@ void crypto_argon2i(uint8_t       *tag,       uint32_t tag_size,      // >= 4
 ///////////////
 /// X-25519 ///
 ///////////////
-
-// Computes a shared secret from your private key and their public key.
-// WARNING: DO NOT USE THE SHARED SECRET DIRECTLY.
-// The shared secret is not pseudo-random.  You need to hash it to derive
-// an acceptable secret key.  Any cryptographic hash can work, as well as
-// HChacha20.
-//
-// Implementation details: this is an elliptic curve.  The public key is
-// a point on this curve, and your private key is a scalar.  The shared
-// secret is another point on this curve, obtained by scalar multiplication.
-// Basically:
-//     shared_secret == your_sk * their_pk == your_sk * (their_sk * base_point)
-//                   == their_sk * your_pk == their_sk * (your_sk * base_point)
 void crypto_x25519(uint8_t       shared_secret   [32],
                    const uint8_t your_secret_key [32],
                    const uint8_t their_public_key[32]);
 
-// Generates a public key from the specified secret key.
-// Make sure the secret key is randomly selected.
-// Don't use the same key for signature and key exchange.
-//
-// Implementation detail: your secret key is a scalar, and we multiply
-// the base point (a constant) by it to obtain a public key.  That is:
-//     public_key == secret_key * base_point
-// Reversing the operation is conjectured to be infeasible
-// without quantum computers (128 bits of security).
 void crypto_x25519_public_key(uint8_t       public_key[32],
                               const uint8_t secret_key[32]);
 
@@ -230,32 +113,20 @@ void crypto_x25519_public_key(uint8_t       public_key[32],
 ///////////////
 /// Ed25519 ///
 ///////////////
-
-// Generates a public key from the specified secret key.
-// Make sure the secret key is randomly selected.
-// Don't use the same key for signature and key exchange.
 void crypto_ed25519_public_key(uint8_t        public_key[32],
                                const uint8_t  secret_key[32]);
 
-// Produces a signature from a message and your secret key.
 void crypto_ed25519_sign(uint8_t        signature[64],
                          const uint8_t  secret_key[32],
-                         const uint8_t *message,
-                         size_t         message_size);
+                         const uint8_t *message, size_t message_size);
 
-// Checks that a given signature is genuine: whoever signed
-// this message must know the secret key.
 int crypto_ed25519_check(const uint8_t  signature[64],
                          const uint8_t  public_key[32],
-                         const uint8_t *message,
-                         size_t         message_size);
-
+                         const uint8_t *message, size_t message_size);
 
 ////////////////////////////////
 /// Authenticated encryption ///
 ////////////////////////////////
-
-// Authenticated encryption with XChacha20 and Poly1305.
 void crypto_ae_lock_detached(uint8_t        mac[16],
                              uint8_t       *ciphertext,
                              const uint8_t  key[32],
@@ -263,8 +134,6 @@ void crypto_ae_lock_detached(uint8_t        mac[16],
                              const uint8_t *plaintext,
                              size_t         text_size);
 
-// Authenticated encryption with XChacha20 and Poly1305.
-// Returns -1 and has no effect if the message is forged.
 int crypto_ae_unlock_detached(uint8_t       *plaintext,
                               const uint8_t  key[32],
                               const uint8_t  nonce[24],
@@ -272,15 +141,12 @@ int crypto_ae_unlock_detached(uint8_t       *plaintext,
                               const uint8_t *ciphertext,
                               size_t         text_size);
 
-// Like the above, only puts the mac and the ciphertext together
-// in a "box", mac first.
 void crypto_ae_lock(uint8_t       *box,      // text_size + 16
                     const uint8_t  key[32],
                     const uint8_t  nonce[24],
                     const uint8_t *plaintext,
                     size_t         text_size);
 
-// Unlocks a box locked by aead_lock()
 int crypto_ae_unlock(uint8_t       *plaintext,
                      const uint8_t  key[32],
                      const uint8_t  nonce[24],
@@ -288,18 +154,13 @@ int crypto_ae_unlock(uint8_t       *plaintext,
                      size_t         text_size);
 
 
-/////////////////////////////////////////////
-/// Public key (authenticated) encryption ///
-/////////////////////////////////////////////
-
-// Computes a shared key with your secret key and their public key,
-// suitable for crypto_ae* functions.
+///////////////////////////////////////////
+/// Public key authenticated encryption ///
+///////////////////////////////////////////
 void crypto_lock_key(uint8_t       shared_key      [32],
                      const uint8_t your_secret_key [32],
                      const uint8_t their_public_key[32]);
 
-// Authenticated encryption with the sender's secret key and the recipient's
-// public key.  The message leaks if one secret key gets compromised.
 void crypto_lock_detached(uint8_t        mac[16],
                           uint8_t       *ciphertext,
                           const uint8_t  your_secret_key [32],
@@ -308,8 +169,6 @@ void crypto_lock_detached(uint8_t        mac[16],
                           const uint8_t *plaintext,
                           size_t         text_size);
 
-// Authenticated decryption with the recipient's secret key, and the sender's
-// public key.  Has no effect if the message is forged.
 int crypto_unlock_detached(uint8_t       *plaintext,
                            const uint8_t  your_secret_key [32],
                            const uint8_t  their_public_key[32],
@@ -318,8 +177,6 @@ int crypto_unlock_detached(uint8_t       *plaintext,
                            const uint8_t *ciphertext,
                            size_t         text_size);
 
-// Like the above, only puts the mac and the ciphertext together
-// in a "box", mac first.
 void crypto_lock(uint8_t       *box,  // text_size + 16
                  const uint8_t  your_secret_key [32],
                  const uint8_t  their_public_key[32],
@@ -327,7 +184,6 @@ void crypto_lock(uint8_t       *box,  // text_size + 16
                  const uint8_t *plaintext,
                  size_t         text_size);
 
-// Unlocks a box locked by crypto_lock()
 int crypto_unlock(uint8_t       *plaintext,
                   const uint8_t  your_secret_key [32],
                   const uint8_t  their_public_key[32],
@@ -335,21 +191,15 @@ int crypto_unlock(uint8_t       *plaintext,
                   const uint8_t *box,  // text_size + 16
                   size_t         text_size);
 
-// Anonymous public key encryption.
-// Throw away your random secret after use.
-// Make sure your random secret is random.
-// WARNING: provides no protection against forgery
-// (the attacker can just use his own random secret).
+///////////////////////////////////////
+/// Anonymous public key encryption ///
+///////////////////////////////////////
 void crypto_anonymous_lock(uint8_t       *box,   // text_size + 48
                            const uint8_t  random_secret_key[32],
                            const uint8_t  their_public_key[32],
                            const uint8_t *plaintext,
                            size_t         text_size);
 
-// Anonypous public key decryption.
-// You cannot know who sent this message, but you do
-// know that the message itself is unmodified.
-// Again, if this is a forgery, you can't know.
 int crypto_anonymous_unlock(uint8_t       *plaintext,
                             const uint8_t  your_secret_key[32],
                             const uint8_t *box,   // text_size + 48