From fe3399dee5c9ed0268bd5a21c0fc798095672ae2 Mon Sep 17 00:00:00 2001 From: Charles Wright <cvwright@futo.org> Date: Thu, 10 Feb 2022 14:59:33 -0600 Subject: [PATCH] Cut out all of the encryption stuff from monocypher. Should now be OK to export from the US without issue. --- monocypher.c | 236 --------------------------------------------------- monocypher.h | 73 ---------------- 2 files changed, 309 deletions(-) diff --git a/monocypher.c b/monocypher.c index 7ab3958..ed05e2b 100644 --- a/monocypher.c +++ b/monocypher.c @@ -159,156 +159,6 @@ void crypto_wipe(void *secret, size_t size) ZERO(v_secret, size); } -///////////////// -/// Chacha 20 /// -///////////////// -#define QUARTERROUND(a, b, c, d) \ - a += b; d = rotl32(d ^ a, 16); \ - c += d; b = rotl32(b ^ c, 12); \ - a += b; d = rotl32(d ^ a, 8); \ - c += d; b = rotl32(b ^ c, 7) - -static void chacha20_rounds(u32 out[16], const u32 in[16]) -{ - // The temporary variables make Chacha20 10% faster. - u32 t0 = in[ 0]; u32 t1 = in[ 1]; u32 t2 = in[ 2]; u32 t3 = in[ 3]; - u32 t4 = in[ 4]; u32 t5 = in[ 5]; u32 t6 = in[ 6]; u32 t7 = in[ 7]; - u32 t8 = in[ 8]; u32 t9 = in[ 9]; u32 t10 = in[10]; u32 t11 = in[11]; - u32 t12 = in[12]; u32 t13 = in[13]; u32 t14 = in[14]; u32 t15 = in[15]; - - FOR (i, 0, 10) { // 20 rounds, 2 rounds per loop. - QUARTERROUND(t0, t4, t8 , t12); // column 0 - QUARTERROUND(t1, t5, t9 , t13); // column 1 - QUARTERROUND(t2, t6, t10, t14); // column 2 - QUARTERROUND(t3, t7, t11, t15); // column 3 - QUARTERROUND(t0, t5, t10, t15); // diagonal 0 - QUARTERROUND(t1, t6, t11, t12); // diagonal 1 - QUARTERROUND(t2, t7, t8 , t13); // diagonal 2 - QUARTERROUND(t3, t4, t9 , t14); // diagonal 3 - } - out[ 0] = t0; out[ 1] = t1; out[ 2] = t2; out[ 3] = t3; - out[ 4] = t4; out[ 5] = t5; out[ 6] = t6; out[ 7] = t7; - out[ 8] = t8; out[ 9] = t9; out[10] = t10; out[11] = t11; - out[12] = t12; out[13] = t13; out[14] = t14; out[15] = t15; -} - -static void chacha20_init_key(u32 block[16], const u8 key[32]) -{ - load32_le_buf(block , (const u8*)"expand 32-byte k", 4); // constant - load32_le_buf(block+4, key , 8); // key -} - -void crypto_hchacha20(u8 out[32], const u8 key[32], const u8 in [16]) -{ - u32 block[16]; - chacha20_init_key(block, key); - // input - load32_le_buf(block + 12, in, 4); - chacha20_rounds(block, block); - // prevent reversal of the rounds by revealing only half of the buffer. - store32_le_buf(out , block , 4); // constant - store32_le_buf(out+16, block+12, 4); // counter and nonce - WIPE_BUFFER(block); -} - -u64 crypto_chacha20_ctr(u8 *cipher_text, const u8 *plain_text, - size_t text_size, const u8 key[32], const u8 nonce[8], - u64 ctr) -{ - u32 input[16]; - chacha20_init_key(input, key); - input[12] = (u32) ctr; - input[13] = (u32)(ctr >> 32); - load32_le_buf(input+14, nonce, 2); - - // Whole blocks - u32 pool[16]; - size_t nb_blocks = text_size >> 6; - FOR (i, 0, nb_blocks) { - chacha20_rounds(pool, input); - if (plain_text != 0) { - FOR (j, 0, 16) { - u32 p = pool[j] + input[j]; - store32_le(cipher_text, p ^ load32_le(plain_text)); - cipher_text += 4; - plain_text += 4; - } - } else { - FOR (j, 0, 16) { - u32 p = pool[j] + input[j]; - store32_le(cipher_text, p); - cipher_text += 4; - } - } - input[12]++; - if (input[12] == 0) { - input[13]++; - } - } - text_size &= 63; - - // Last (incomplete) block - if (text_size > 0) { - if (plain_text == 0) { - plain_text = zero; - } - chacha20_rounds(pool, input); - u8 tmp[64]; - FOR (i, 0, 16) { - store32_le(tmp + i*4, pool[i] + input[i]); - } - FOR (i, 0, text_size) { - cipher_text[i] = tmp[i] ^ plain_text[i]; - } - WIPE_BUFFER(tmp); - } - ctr = input[12] + ((u64)input[13] << 32) + (text_size > 0); - - WIPE_BUFFER(pool); - WIPE_BUFFER(input); - return ctr; -} - -u32 crypto_ietf_chacha20_ctr(u8 *cipher_text, const u8 *plain_text, - size_t text_size, - const u8 key[32], const u8 nonce[12], u32 ctr) -{ - u64 big_ctr = ctr + ((u64)load32_le(nonce) << 32); - return (u32)crypto_chacha20_ctr(cipher_text, plain_text, text_size, - key, nonce + 4, big_ctr); -} - -u64 crypto_xchacha20_ctr(u8 *cipher_text, const u8 *plain_text, - size_t text_size, - const u8 key[32], const u8 nonce[24], u64 ctr) -{ - u8 sub_key[32]; - crypto_hchacha20(sub_key, key, nonce); - ctr = crypto_chacha20_ctr(cipher_text, plain_text, text_size, - sub_key, nonce+16, ctr); - WIPE_BUFFER(sub_key); - return ctr; -} - -void crypto_chacha20(u8 *cipher_text, const u8 *plain_text, size_t text_size, - const u8 key[32], const u8 nonce[8]) -{ - crypto_chacha20_ctr(cipher_text, plain_text, text_size, key, nonce, 0); - -} -void crypto_ietf_chacha20(u8 *cipher_text, const u8 *plain_text, - size_t text_size, - const u8 key[32], const u8 nonce[12]) -{ - crypto_ietf_chacha20_ctr(cipher_text, plain_text, text_size, key, nonce, 0); -} - -void crypto_xchacha20(u8 *cipher_text, const u8 *plain_text, size_t text_size, - const u8 key[32], const u8 nonce[24]) -{ - crypto_xchacha20_ctr(cipher_text, plain_text, text_size, key, nonce, 0); -} - ///////////////// /// Poly 1305 /// ///////////////// @@ -2821,38 +2671,6 @@ int crypto_curve_to_hidden(u8 hidden[32], const u8 public_key[32], u8 tweak) return 0; } -void crypto_hidden_key_pair(u8 hidden[32], u8 secret_key[32], u8 seed[32]) -{ - u8 pk [32]; // public key - u8 buf[64]; // seed + representative - COPY(buf + 32, seed, 32); - do { - crypto_chacha20(buf, 0, 64, buf+32, zero); - crypto_x25519_dirty_fast(pk, buf); // or the "small" version - } while(crypto_curve_to_hidden(buf+32, pk, buf[32])); - // Note that the return value of crypto_curve_to_hidden() is - // independent from its tweak parameter. - // Therefore, buf[32] is not actually reused. Either we loop one - // more time and buf[32] is used for the new seed, or we succeeded, - // and buf[32] becomes the tweak parameter. - - crypto_wipe(seed, 32); - COPY(hidden , buf + 32, 32); - COPY(secret_key, buf , 32); - WIPE_BUFFER(buf); - WIPE_BUFFER(pk); -} - -//////////////////// -/// Key exchange /// -//////////////////// -void crypto_key_exchange(u8 shared_key[32], - const u8 your_secret_key [32], - const u8 their_public_key[32]) -{ - crypto_x25519(shared_key, your_secret_key, their_public_key); - crypto_hchacha20(shared_key, shared_key, zero); -} /////////////////////// /// Scalar division /// @@ -2990,57 +2808,3 @@ static void lock_auth(u8 mac[16], const u8 auth_key[32], crypto_poly1305_final (&poly_ctx, mac); // ...here } -void crypto_lock_aead(u8 mac[16], u8 *cipher_text, - const u8 key[32], const u8 nonce[24], - const u8 *ad , size_t ad_size, - const u8 *plain_text, size_t text_size) -{ - u8 sub_key[32]; - u8 auth_key[64]; // "Wasting" the whole Chacha block is faster - crypto_hchacha20(sub_key, key, nonce); - crypto_chacha20(auth_key, 0, 64, sub_key, nonce + 16); - crypto_chacha20_ctr(cipher_text, plain_text, text_size, - sub_key, nonce + 16, 1); - lock_auth(mac, auth_key, ad, ad_size, cipher_text, text_size); - WIPE_BUFFER(sub_key); - WIPE_BUFFER(auth_key); -} - -int crypto_unlock_aead(u8 *plain_text, const u8 key[32], const u8 nonce[24], - const u8 mac[16], - const u8 *ad , size_t ad_size, - const u8 *cipher_text, size_t text_size) -{ - u8 sub_key[32]; - u8 auth_key[64]; // "Wasting" the whole Chacha block is faster - crypto_hchacha20(sub_key, key, nonce); - crypto_chacha20(auth_key, 0, 64, sub_key, nonce + 16); - u8 real_mac[16]; - lock_auth(real_mac, auth_key, ad, ad_size, cipher_text, text_size); - WIPE_BUFFER(auth_key); - if (crypto_verify16(mac, real_mac)) { - WIPE_BUFFER(sub_key); - WIPE_BUFFER(real_mac); - return -1; - } - crypto_chacha20_ctr(plain_text, cipher_text, text_size, - sub_key, nonce + 16, 1); - WIPE_BUFFER(sub_key); - WIPE_BUFFER(real_mac); - return 0; -} - -void crypto_lock(u8 mac[16], u8 *cipher_text, - const u8 key[32], const u8 nonce[24], - const u8 *plain_text, size_t text_size) -{ - crypto_lock_aead(mac, cipher_text, key, nonce, 0, 0, plain_text, text_size); -} - -int crypto_unlock(u8 *plain_text, - const u8 key[32], const u8 nonce[24], const u8 mac[16], - const u8 *cipher_text, size_t text_size) -{ - return crypto_unlock_aead(plain_text, key, nonce, mac, 0, 0, - cipher_text, text_size); -} diff --git a/monocypher.h b/monocypher.h index 040ee25..30ac774 100644 --- a/monocypher.h +++ b/monocypher.h @@ -130,34 +130,6 @@ int crypto_verify64(const uint8_t a[64], const uint8_t b[64]); void crypto_wipe(void *secret, size_t size); -// Authenticated encryption -// ------------------------ -void crypto_lock(uint8_t mac[16], - uint8_t *cipher_text, - const uint8_t key[32], - const uint8_t nonce[24], - const uint8_t *plain_text, size_t text_size); -int crypto_unlock(uint8_t *plain_text, - const uint8_t key[32], - const uint8_t nonce[24], - const uint8_t mac[16], - const uint8_t *cipher_text, size_t text_size); - -// With additional data -void crypto_lock_aead(uint8_t mac[16], - uint8_t *cipher_text, - const uint8_t key[32], - const uint8_t nonce[24], - const uint8_t *ad , size_t ad_size, - const uint8_t *plain_text, size_t text_size); -int crypto_unlock_aead(uint8_t *plain_text, - const uint8_t key[32], - const uint8_t nonce[24], - const uint8_t mac[16], - const uint8_t *ad , size_t ad_size, - const uint8_t *cipher_text, size_t text_size); - - // General purpose hash (Blake2b) // ------------------------------ @@ -229,51 +201,6 @@ int crypto_check(const uint8_t signature [64], // For experts only. You have been warned. -// Chacha20 -// -------- - -// Specialised hash. -// Used to hash X25519 shared secrets. -void crypto_hchacha20(uint8_t out[32], - const uint8_t key[32], - const uint8_t in [16]); - -// Unauthenticated stream cipher. -// Don't forget to add authentication. -void crypto_chacha20(uint8_t *cipher_text, - const uint8_t *plain_text, - size_t text_size, - const uint8_t key[32], - const uint8_t nonce[8]); -void crypto_xchacha20(uint8_t *cipher_text, - const uint8_t *plain_text, - size_t text_size, - const uint8_t key[32], - const uint8_t nonce[24]); -void crypto_ietf_chacha20(uint8_t *cipher_text, - const uint8_t *plain_text, - size_t text_size, - const uint8_t key[32], - const uint8_t nonce[12]); -uint64_t crypto_chacha20_ctr(uint8_t *cipher_text, - const uint8_t *plain_text, - size_t text_size, - const uint8_t key[32], - const uint8_t nonce[8], - uint64_t ctr); -uint64_t crypto_xchacha20_ctr(uint8_t *cipher_text, - const uint8_t *plain_text, - size_t text_size, - const uint8_t key[32], - const uint8_t nonce[24], - uint64_t ctr); -uint32_t crypto_ietf_chacha20_ctr(uint8_t *cipher_text, - const uint8_t *plain_text, - size_t text_size, - const uint8_t key[32], - const uint8_t nonce[12], - uint32_t ctr); - // Poly 1305 // --------- -- GitLab