Example #1
0
int
main(void)
{
    size_t i;
    int    ret;

    ret = crypto_box_easy(c, m, 131, nonce, bobpk, alicesk);
    assert(ret == 0);
    for (i = 0; i < 131 + crypto_box_MACBYTES; ++i) {
        printf(",0x%02x", (unsigned int) c[i]);
    }
    printf("\n");

    /* Null message */

    ret = crypto_box_easy(c, c, 0, nonce, bobpk, alicesk);
    assert(ret == 0);
    for (i = 0; i < 1 + crypto_box_MACBYTES; ++i) {
        printf(",0x%02x", (unsigned int) c[i]);
    }
    printf("\n");
    ret =
        crypto_box_open_easy(c, c, crypto_box_MACBYTES, nonce, bobpk, alicesk);
    assert(ret == 0);
    for (i = 0; i < 1 + crypto_box_MACBYTES; ++i) {
        printf(",0x%02x", (unsigned int) c[i]);
    }
    printf("\n");
    c[randombytes_uniform(crypto_box_MACBYTES)]++;
    ret = crypto_box_open_easy(c, c, crypto_box_MACBYTES, nonce, bobpk, alicesk);
    assert(ret == -1);

    return 0;
}
    static
    optional<message_header>
    decrypt(
      buffer& data
    , nonce const& nonce
    , public_key const& public_key
    , private_key const& private_key
    )
    noexcept {
      message_header_view view{gsl::as_span(data)};
      auto full_span = view.span();
      auto data_span = view.data_span();

      if (
        crypto_box_open_easy(
          &data_span[0]
        , &full_span[0]
        , static_cast<std::size_t>(full_span.size())
        , &nonce[0]
        , &public_key[0]
        , &private_key[0]
        )
        == 0
      ) {
        return message_header(view);
      } else {
        return {};
      }
    }
int
crypto_box_seal_open(unsigned char *m, const unsigned char *c,
                     unsigned long long clen,
                     const unsigned char *pk, const unsigned char *sk)
{
    unsigned char nonce[crypto_box_NONCEBYTES];

    if (clen < crypto_box_SEALBYTES) {
        return -1;
    }
    _crypto_box_seal_nonce(nonce, c, pk);

    (void) sizeof(int[crypto_box_PUBLICKEYBYTES < crypto_box_SEALBYTES ? 1 : -1]);
    return crypto_box_open_easy(m, c + crypto_box_PUBLICKEYBYTES,
                                clen - crypto_box_PUBLICKEYBYTES,
                                nonce, c, sk);
}
Example #4
0
int
shick_crypto_dec_message(const SC_CHAR recipient_secret_key[crypto_box_SECRETKEYBYTES],
                         const SC_CHAR sender_public_key[crypto_box_PUBLICKEYBYTES],
                         const SC_ENC_SYM_KEY encrypted_symmetric_key,
                         const SC_CHAR* ciphertext,
                         const SC_LEN ciphertext_len,
                         const SC_CHAR nonce[crypto_box_NONCEBYTES],
                         SC_CHAR* message) {
  int failed = 0;
  SC_CHAR buffer[sizeof(SC_SYM_KEY)];
  SC_SYM_KEY* sym_key;

  // Decrypt symmetric key 
  failed = crypto_box_open_easy(buffer, (SC_CHAR*) &encrypted_symmetric_key, sizeof encrypted_symmetric_key, nonce, sender_public_key, recipient_secret_key);
  if (failed) return SC_DEC_ASYM_FAILED;

  // Decrypt message with symmetric key
  sym_key = (SC_SYM_KEY*) buffer;
  failed = crypto_secretbox_open_easy(message, ciphertext, ciphertext_len, sym_key->nonce, sym_key->key);
  if (failed) return SC_DEC_SYM_FAILED;

  return 0;
}
Example #5
0
/// Given marshalled packet data corresponding to an CryptCurve25519 frame
/// return the corresponding Frame
/// In other words, un-marshall the data...
/// In our case, this means we decrypt it in-place into many other frames...
WINEXPORT Frame*
cryptcurve25519_tlvconstructor(gpointer tlvstart,	///<[in/out] Start of marshalled CStringFrame data
			  gconstpointer pktend,		///<[in] Pointer to first invalid byte past 'tlvstart'
		          gpointer* ignorednewpkt,	///<[ignored] replacement packet
		          gpointer* ignoredpktend)	///<[ignored] end of replacement packet
{
	guint8*			valptr = get_generic_tlv_nonconst_value(tlvstart, pktend);
	guint8*			nonce;
	guint8*			cyphertext;
	const guint8*		tlvend8 = valptr + get_generic_tlv_len(tlvstart, pktend);
	guint8*			plaintext;
	CryptCurve25519*	ret;
	guint			namelen;
	gsize			cypherlength;
				// The first key name is in sender's key name
				// The second key name is in receiver's key name
	CryptFramePublicKey *	sender_public_key = NULL;
	CryptFramePrivateKey*	receiver_secret_key = NULL;
	const char*		sender_pubkey_id = NULL;
	const char*		rcvr_seckey_id = NULL;
	int			j;

	(void)ignorednewpkt; (void)ignoredpktend;
	valptr = get_generic_tlv_nonconst_value(tlvstart, pktend);
	for (j=0; j < 2; ++j) {
		char *	key_id;
		g_return_val_if_fail((gpointer)(valptr+2) <= pktend, NULL);
		namelen = tlv_get_guint8(valptr, pktend);
		valptr += 1;
		g_return_val_if_fail((gpointer)(valptr+namelen) <= pktend, NULL);
		key_id = (char *)valptr;
		g_return_val_if_fail (strnlen(key_id, namelen) == namelen -1, NULL);
		g_return_val_if_fail(_is_valid_curve25519_key_id(key_id
		, 	0 == j ? PUBLICKEY : PRIVATEKEY), NULL);
		if (0 == j) {
			sender_public_key = cryptframe_public_key_by_id(key_id);
			sender_pubkey_id = key_id;
		}else{
			receiver_secret_key = cryptframe_private_key_by_id(key_id);
			rcvr_seckey_id = key_id;
		}
		g_return_val_if_fail(key_id != NULL, NULL);
		valptr += namelen;
	}
	if (NULL == sender_public_key) {
		g_warning("%s.%d: No access to sender %s public key"
		,	__FUNCTION__, __LINE__, sender_pubkey_id);
		return NULL;
	}
	if (NULL == receiver_secret_key) {
		g_warning("%s.%d: No access to receiver %s private key"
		,	__FUNCTION__, __LINE__, rcvr_seckey_id);
		return NULL;
	}
	g_return_val_if_fail((gpointer)(valptr + (crypto_box_NONCEBYTES+crypto_box_MACBYTES)) <= pktend, NULL);
	nonce = valptr;
	cyphertext = nonce + crypto_box_NONCEBYTES;
	plaintext = cyphertext + crypto_box_MACBYTES;
	cypherlength = tlvend8 - cyphertext;
	DEBUGCKSUM4("nonce:", nonce, crypto_box_NONCEBYTES);
	DEBUGCKSUM4("sender   public key :", sender_public_key -> public_key,  crypto_box_PUBLICKEYBYTES);
	DEBUGCKSUM4("receiver private key:", receiver_secret_key->private_key, crypto_box_SECRETKEYBYTES);
	DEBUGMSG4("cypher offset versus tlvstart: %ld", (long)(cyphertext-(guint8*)tlvstart));
	DEBUGCKSUM4("cypher text:", cyphertext, cypherlength);
	if (crypto_box_open_easy(plaintext, cyphertext, cypherlength, nonce
	,	sender_public_key->public_key, receiver_secret_key->private_key) != 0) {
		g_warning("%s.%d: could not decrypt %d byte message encrypted with key pair [pub:%s, sec:%s]"
		,	__FUNCTION__, __LINE__, (int)cypherlength, sender_pubkey_id, rcvr_seckey_id);
		return NULL;
	}
	DEBUGCKSUM4("plain text:", plaintext, cypherlength-crypto_box_MACBYTES);
	// Note that our return value's size will determine where the beginning of the
	// decrypted data is (according to it's dataspace() member function)
	ret = cryptcurve25519_new(get_generic_tlv_type(tlvstart, pktend)
	,	(const char *)sender_pubkey_id
	,	rcvr_seckey_id, FALSE, 0);
	return (ret ? &(ret->baseclass.baseclass) : NULL);
}
Example #6
0
int main(void)
{
    unsigned char *alicepk;
    unsigned char *alicesk;
    unsigned char *bobpk;
    unsigned char *bobsk;
    unsigned char *mac;
    unsigned char *nonce;
    unsigned char *k1;
    unsigned char *k2;
    unsigned char *m;
    unsigned char *m2;
    unsigned char *c;
    size_t         mlen;
    size_t         i;
    size_t         m_size;
    size_t         m2_size;
    size_t         c_size;
    int            ret;

    m2_size = m_size = 1U + randombytes_uniform(10000);
    c_size = crypto_box_MACBYTES + m_size;
    m = (unsigned char *) sodium_malloc(m_size);
    m2 = (unsigned char *) sodium_malloc(m2_size);
    c = (unsigned char *) sodium_malloc(c_size);
    alicepk = (unsigned char *) sodium_malloc(crypto_box_PUBLICKEYBYTES);
    alicesk = (unsigned char *) sodium_malloc(crypto_box_SECRETKEYBYTES);
    bobpk = (unsigned char *) sodium_malloc(crypto_box_PUBLICKEYBYTES);
    bobsk = (unsigned char *) sodium_malloc(crypto_box_SECRETKEYBYTES);
    mac = (unsigned char *) sodium_malloc(crypto_box_MACBYTES);
    nonce = (unsigned char *) sodium_malloc(crypto_box_NONCEBYTES);
    k1 = (unsigned char *) sodium_malloc(crypto_box_BEFORENMBYTES);
    k2 = (unsigned char *) sodium_malloc(crypto_box_BEFORENMBYTES);
    crypto_box_keypair(alicepk, alicesk);
    crypto_box_keypair(bobpk, bobsk);
    mlen = (size_t) randombytes_uniform((uint32_t) m_size) + 1U;
    randombytes_buf(m, mlen);
    randombytes_buf(nonce, crypto_box_NONCEBYTES);
    ret = crypto_box_easy(c, m, mlen, nonce, bobpk, alicesk);
    assert(ret == 0);
    if (crypto_box_open_easy(m2, c,
                             (unsigned long long) mlen + crypto_box_MACBYTES,
                             nonce, alicepk, bobsk) != 0) {
        printf("open() failed");
        return 1;
    }
    printf("%d\n", memcmp(m, m2, mlen));

    for (i = 0; i < mlen + crypto_box_MACBYTES - 1; i++) {
        if (crypto_box_open_easy(m2, c, (unsigned long long) i,
                                 nonce, alicepk, bobsk) == 0) {
            printf("short open() should have failed");
            return 1;
        }
    }
    memcpy(c, m, mlen);
    ret = crypto_box_easy(c, c, (unsigned long long) mlen, nonce, bobpk, alicesk);
    assert(ret == 0);
    printf("%d\n", memcmp(m, c, mlen) == 0);
    printf("%d\n", memcmp(m, c + crypto_box_MACBYTES, mlen) == 0);
    if (crypto_box_open_easy(c, c,
                             (unsigned long long) mlen + crypto_box_MACBYTES,
                             nonce, alicepk, bobsk) != 0) {
        printf("crypto_box_open_easy() failed\n");
    }

    ret = crypto_box_beforenm(k1, alicepk, bobsk);
    assert(ret == 0);
    ret = crypto_box_beforenm(k2, bobpk, alicesk);
    assert(ret == 0);

    memset(m2, 0, m2_size);

    if (crypto_box_easy_afternm(c, m, SIZE_MAX - 1U, nonce, k1) == 0) {
        printf("crypto_box_easy_afternm() with a short ciphertext should have failed\n");
    }
    crypto_box_easy_afternm(c, m, (unsigned long long) mlen, nonce, k1);
    if (crypto_box_open_easy_afternm(m2, c,
                                     (unsigned long long) mlen + crypto_box_MACBYTES,
                                 nonce, k2) != 0) {
        printf("crypto_box_open_easy_afternm() failed\n");
    }
    printf("%d\n", memcmp(m, m2, mlen));
    if (crypto_box_open_easy_afternm(m2, c, crypto_box_MACBYTES - 1U,
                                     nonce, k2) == 0) {
        printf("crypto_box_open_easy_afternm() with a huge ciphertext should have failed\n");
    }
    memset(m2, 0, m2_size);
    ret = crypto_box_detached(c, mac, m, (unsigned long long) mlen,
                              nonce, alicepk, bobsk);
    assert(ret == 0);
    if (crypto_box_open_detached(m2, c, mac, (unsigned long long) mlen,
                                 nonce, bobpk, alicesk) != 0) {
        printf("crypto_box_open_detached() failed\n");
    }
    printf("%d\n", memcmp(m, m2, mlen));

    memset(m2, 0, m2_size);
    crypto_box_detached_afternm(c, mac, m, (unsigned long long) mlen,
                                nonce, k1);
    if (crypto_box_open_detached_afternm(m2, c, mac, (unsigned long long) mlen,
                                         nonce, k2) != 0) {
        printf("crypto_box_open_detached_afternm() failed\n");
    }
    printf("%d\n", memcmp(m, m2, mlen));

    sodium_free(alicepk);
    sodium_free(alicesk);
    sodium_free(bobpk);
    sodium_free(bobsk);
    sodium_free(mac);
    sodium_free(nonce);
    sodium_free(k1);
    sodium_free(k2);
    sodium_free(m);
    sodium_free(m2);
    sodium_free(c);
    printf("OK\n");

    return 0;
}
Example #7
0
/*
 * Using public-key authenticated encryption, Bob can encrypt a
 * confidential message specifically for Alice, using Alice's public
 * key.
 *
 * Using Bob's public key, Alice can verify that the encrypted
 * message was actually created by Bob and was not tampered with,
 * before eventually decrypting it.
 *
 * Alice only needs Bob's public key, the nonce and the ciphertext.
 * Bob should never ever share his secret key, even with Alice.
 *
 * And in order to send messages to Alice, Bob only needs Alice's
 * public key. Alice should never ever share her secret key either,
 * even with Bob.
 *
 * Alice can reply to Bob using the same system, without having to
 * generate a distinct key pair.
 *
 * The nonce doesn't have to be confidential, but it should be used
 * with just one invokation of crypto_box_open_easy() for a
 * particular pair of public and secret keys.
 *
 * One easy way to generate a nonce is to use randombytes_buf(),
 * considering the size of nonces the risk of any random collisions
 * is negligible. For some applications, if you wish to use nonces to
 * detect missing messages or to ignore replayed messages, it is also
 * ok to use a simple incrementing counter as a nonce.
 *
 * When doing so you must ensure that the same value can never be
 * re-used (for example you may have multiple threads or even hosts
 * generating messages using the same key pairs).
 *
 * This system provides mutual authentication. However, a typical use
 * case is to secure communications between a server, whose public
 * key is known in advance, and clients connecting anonymously.
 */
static int
box(void)
{
    unsigned char bob_pk[crypto_box_PUBLICKEYBYTES]; /* Bob's public key */
    unsigned char bob_sk[crypto_box_SECRETKEYBYTES]; /* Bob's secret key */

    unsigned char alice_pk[crypto_box_PUBLICKEYBYTES]; /* Alice's public key */
    unsigned char alice_sk[crypto_box_SECRETKEYBYTES]; /* Alice's secret key */

    unsigned char nonce[crypto_box_NONCEBYTES];
    unsigned char message[MAX_INPUT_LEN];
    unsigned char ciphertext[crypto_box_MACBYTES + MAX_INPUT_LEN];
    size_t        message_len;
    size_t        ciphertext_len;
    int           ret;

    puts("Example: crypto_box_easy\n");

    puts("Generating keypairs...\n");
    crypto_box_keypair(bob_pk, bob_sk);     /* generate Bob's keys */
    crypto_box_keypair(alice_pk, alice_sk); /* generate Alice's keys */

    puts("Bob");
    printf("Public key: ");
    print_hex(bob_pk, sizeof bob_pk);
    printf("Secret key: ");
    print_hex(bob_sk, sizeof bob_sk);

    puts("Alice");
    printf("Public key: ");
    print_hex(alice_pk, sizeof alice_pk);
    printf("Secret key: ");
    print_hex(alice_sk, sizeof alice_sk);

    /* nonce must be unique per (key, message) - it can be public and deterministic */
    puts("Generating nonce...");
    randombytes_buf(nonce, sizeof nonce);
    printf("Nonce: ");
    print_hex(nonce, sizeof nonce);

    /* read input */
    message_len = prompt_input("a message", (char*)message, sizeof message, 1);

    print_hex(message, message_len);

    /* encrypt and authenticate the message */
    printf("Encrypting and authenticating with %s\n\n", crypto_box_primitive());
    crypto_box_easy(ciphertext, message, message_len, nonce, alice_pk, bob_sk);
    ciphertext_len = crypto_box_MACBYTES + message_len;

    /* send the nonce and the ciphertext */
    puts("Bob sends the nonce and the ciphertext...\n");
    printf("Ciphertext len: %zu bytes - Original message length: %zu bytes\n",
           ciphertext_len, message_len);
    puts("Notice the prepended 16 byte authentication token\n");
    printf("Nonce: ");
    print_hex(nonce, sizeof nonce);
    printf("Ciphertext: ");
    print_hex(ciphertext, ciphertext_len);

    /* decrypt the message */
    puts("Alice verifies and decrypts the ciphertext...");
    ret = crypto_box_open_easy(message, ciphertext, ciphertext_len, nonce, bob_pk,
                               alice_sk);
    print_hex(message, message_len);

    print_verification(ret);
    if (ret == 0) {
        printf("Plaintext: ");
        fwrite(message, 1U, message_len, stdout);
        putchar('\n');
    }
    sodium_memzero(bob_sk, sizeof bob_sk); /* wipe sensitive data */
    sodium_memzero(alice_sk, sizeof alice_sk);
    sodium_memzero(message, sizeof message);
    sodium_memzero(ciphertext, sizeof ciphertext);

    return ret;
}
Example #8
0
void
nc_otoc_start(nc_opts *opts, int pair_raw_sock)
{
  int shell_fd_sock;
  int pair_fd_sock;

  fd_set readfds;
  int maxfds;
  char time_str[NOW_STR_LEN];

  enum {init, none,
	text_sent, text_received,
	pkey_sent, pkey_received} last_action = init;

  shell_fd_sock = fileno(stdin);
  pair_fd_sock = nc_utils_get_rec_sockfd(pair_raw_sock);
  maxfds = pair_fd_sock + 1;

  /* --- start of sending public key --- */
  if(opts->secure) {

    char *msg = NULL;
    char *msg_type = OTOC_MTYPE_PKEY;
    char *msg_body = NULL;

    /* --- start of encoding public key --- */
    const char *plain_pkey = (const char*) my_publickey;
    int plain_pkey_len = crypto_box_PUBLICKEYBYTES;
    char encoded_pkey[Base64encode_len(plain_pkey_len)];
    Base64encode(encoded_pkey, plain_pkey, plain_pkey_len);
    nc_log_writef("debug", "encode my public key: %s", encoded_pkey);
    /* --- end of encoding public key --- */

    msg_body = encoded_pkey;
    nc_json_make_otoc_msg(&msg_type, &msg_body, plain_pkey_len, &msg);
    nn_send(pair_raw_sock, msg, strlen(msg), 0);
    nc_log_writef("debug", "one to one chat sent public key: %s", msg);
    last_action = pkey_sent;
    
  }
  /* --- end of sending public key --- */
  
  /* --- start of shel command registration --- */
  nc_otoc_register_cmd("/help", func_cmd_help);
  nc_otoc_register_cmd("/leave", func_cmd_leave);
  /* --- end of shell commmand registration --- */

  for(;;) {

    switch(last_action) {
    case init:
    case pkey_sent:
      fprintf(stdout,
	      ">> Entering (room code %d) ...\n",
	      pair_raw_sock);
      fprintf(stdout, ">>> ");
      fflush(stdout); 
      break;
    case text_received: 
      fprintf(stdout, ">>> ");
      fflush(stdout); 
      break;
    case text_sent: 
      fprintf(stdout, ">>> "); 
      fflush(stdout); 
      break;
    case none:
      fprintf(stdout, ">>> ");
      fflush(stdout);
      break;
    case pkey_received:
      break;
    }

    FD_ZERO(&readfds);
    FD_SET(pair_fd_sock, &readfds);
    FD_SET(shell_fd_sock, &readfds);

    select(maxfds, &readfds, NULL, NULL, NULL);

    if(FD_ISSET(shell_fd_sock, &readfds)) {      

      char *buf = NULL;
      size_t buf_sz = 1024;
      int i;

      nc_utils_now_str(time_str);      
      getline(&buf, &buf_sz, stdin);

      if(buf[0] == '\n') {
	
	last_action = none;

      } else if(buf[0] == '/') {

	nc_utils_del_new_line(buf);
	for(i = 0; i < cmd_current_code; i++) {
	  
	  if(strstr(buf, cmds[i].name)) {

	    if(cmds[i].func(buf) < 0) {
	      return;
	    }

	    break;
	  }
	}

	last_action = none;

      } else {

	if(opts->secure) {

	  /* --- make ciphermsg with key pairs --- */
	  int ciphermsg_len = crypto_box_MACBYTES + strlen(buf);
	  unsigned char nonce[crypto_box_NONCEBYTES];
	  unsigned char ciphermsg[ciphermsg_len];

	  /* @TODO: use random nonce */
	  //randombytes_buf(nonce, sizeof nonce);
	  memset(nonce, '\0', sizeof nonce);
	  
	  crypto_box_easy(ciphermsg, (const unsigned char*) buf,
	  		  strlen(buf), nonce,
	  		  peers_publickey[pair_raw_sock], my_secretkey);

	  /* --- make msg encoded with base64  --- */
	  const char *plain_ciphermsg = (const char*) ciphermsg;
	  int plain_ciphermsg_len = ciphermsg_len;
	  int encoded_ciphermsg_len = Base64encode_len(plain_ciphermsg_len);
	  char encoded_ciphermsg[encoded_ciphermsg_len];

	  Base64encode(encoded_ciphermsg, plain_ciphermsg, plain_ciphermsg_len);
	  nc_log_writef("debug", "encode ciphermsg: %s", encoded_ciphermsg);

	  /* --- serialize msg with json --- */
	  char *msg = NULL;
	  char *msg_type = OTOC_MTYPE_STXT;
	  char *msg_body = NULL;

	  msg_body = encoded_ciphermsg;
	  nc_json_make_otoc_msg(&msg_type, &msg_body, strlen(buf), &msg);
	  nc_log_writef("debug", "serialize encoded ciphermsg: %s", msg);
	  
	  /* --- send msg --- */
	  nn_send(pair_raw_sock, msg, strlen(msg), 0);

	} else {

	  char *msg = NULL;
	  char *msg_type = OTOC_MTYPE_RTXT;

	  nc_json_make_otoc_msg(&msg_type, &buf, strlen(buf), &msg);
	  nn_send(pair_raw_sock, msg, strlen(msg), 0);
	  fprintf(stdout, "[%s] >>> %s", time_str, buf);
	  fflush(stdout);
	  nc_utils_del_new_line(buf);
	  nc_log_writef("debug", "one to one chat sent: %s", buf);
	  nc_utils_empty_string(buf);
	  last_action = text_sent;

	}

      }
      
    } else if(FD_ISSET(pair_fd_sock, &readfds)) {

      char *buf = NULL;
      char *msg_body = NULL;
      char *msg_type = NULL;
      int original_msg_body_len;
      
      nn_recv(pair_raw_sock, &buf, NN_MSG, 0);
      nc_json_extract_otoc_msg(&buf, &msg_type, &original_msg_body_len, &msg_body);

      nc_utils_del_new_line(buf);
      nc_log_writef("debug", "one to one chat received: %s", msg_type);
      nn_freemsg(buf);
      
      if(strncmp(msg_type, OTOC_MTYPE_PKEY, OTOC_MTYPE_LEN) == 0) {

	/* public key message */

	/* --- start of decoding public key --- */
	int plain_pkey_len = Base64decode_len(msg_body);
	char plain_pkey[plain_pkey_len];

	Base64decode(plain_pkey, (const char*) msg_body);
	strncpy(peers_publickey[pair_raw_sock], plain_pkey, crypto_box_PUBLICKEYBYTES);
	nc_log_writef("debug", "decoded peer's public key was stored.");
	/* --- end of decoding public key --- */
	
	last_action = pkey_received;
	
      } else if(strncmp(msg_type, OTOC_MTYPE_RTXT, OTOC_MTYPE_LEN) == 0) {

	/* raw text message */

	nc_utils_now_str(time_str);
	fprintf(stdout, "\r[%s] <<< %s", time_str, msg_body);
	fflush(stdout);
	last_action = text_received;

      } else if(strncmp(msg_type, OTOC_MTYPE_STXT, OTOC_MTYPE_LEN) == 0) {

	/* secure text message */

	if(!opts->secure) {

	  char *alert =
	    "\r[%s] <<< { ... encrypted message ... }\n"
	    "==========================================\n"
	    "Your peer uses NanoChat undre secure mode.\n"
	    "Use -s flag to see his encrypted messages.\n"
	    "==========================================\n";

	  nc_utils_now_str(time_str);
	  fprintf(stdout, alert, time_str);
	  fflush(stdout);
	  last_action = text_received;

	} else {

	  /* --- decode  secure msg body --- */
	  int plain_ciphermsg_len = Base64decode_len(msg_body);
	  char plain_ciphermsg[plain_ciphermsg_len];

	  Base64decode(plain_ciphermsg, (const char*) msg_body);

	  /* --- decrypt ciphermsg --- */

	  int decrypted_len = original_msg_body_len;
	  int ciphermsg_len = crypto_box_MACBYTES + decrypted_len;
	  unsigned char decrypted[decrypted_len];
	  unsigned char nonce[crypto_box_NONCEBYTES];
	  memset(nonce, '\0', sizeof nonce);

	  crypto_box_open_easy(decrypted, plain_ciphermsg, ciphermsg_len, nonce,
			       peers_publickey[pair_raw_sock], my_secretkey);

	  /* --- show decrypted msg body --- */

	  decrypted[original_msg_body_len] = '\0';
	
	  nc_utils_now_str(time_str);
	  fprintf(stdout, "\r[%s] <<< %s", time_str, decrypted);
	  fflush(stdout);
	  last_action = text_received;

	}
      }
    }
    
  }

}
int main(int argc, char**argv)
{
	unsigned char shared_key[crypto_box_BEFORENMBYTES], shared_key2[crypto_box_BEFORENMBYTES];
	const unsigned char basepoint[32] = {9};
	int i = 0;


// The quick brown fox jumps over the lazy dog.
#define MESSAGE (const unsigned char *) "0123456789 The quick brown fox jumps over the lazy dog. _ 60 ______ 70 ______ 80 ______ 90 ______100"
#define MESSAGE_LEN 100
#define ADDITIONAL_DATA (const unsigned char *) "123456"
#define ADDITIONAL_DATA_LEN 6



unsigned char nonce[crypto_aead_chacha20poly1305_NPUBBYTES];
unsigned char key[crypto_aead_chacha20poly1305_KEYBYTES];

unsigned char ciphertext[MESSAGE_LEN + crypto_aead_chacha20poly1305_ABYTES];
unsigned long long ciphertext_len;

unsigned char ciphertext2[MESSAGE_LEN + crypto_box_SEALBYTES];
unsigned char ciphertext3[MESSAGE_LEN + crypto_secretbox_MACBYTES];


unsigned char decrypted[MESSAGE_LEN+1];
unsigned long long decrypted_len;


unsigned char mypublic[crypto_box_PUBLICKEYBYTES];
unsigned char mysecret[crypto_box_SECRETKEYBYTES];

unsigned char hispublic[crypto_box_PUBLICKEYBYTES];
unsigned char hissecret[crypto_box_SECRETKEYBYTES];

// unsigned char nonce2[crypto_secretbox_NONCEBYTES];

int msg1len = 1162;
//arc4random_buf(&(nonce2), crypto_secretbox_NONCEBYTES);
unsigned char *msg1_hex = (unsigned char*) "b7b9a33b97d5697c5659f33dc5723b0c6778d012ef8ebcabd36973d0c32db7adc982879cae1b65e6c7e86cd7f3790abd76fa3320322a2a86123ce8d5315b1edba981ee87da535677e2d49ab1aedd24e5cb07da136cbb469da2422d41eab6d70e5993be276021d41352cdc93c732f8897fa463d556fa835dac8d0126641f77649574dd13a032115e7793cd90fdacac13b764c5963b9a021074267ef45bc7ed816c153a3b7a7f9d53b98bb12a1888d2499eb1102db8e4c02f9316ea1fd3fc347cf3fc5b45751e02640f4b08fcdbdbf4bd7e1dc72c2344dfce4aaa8837e6713bd5545426047a9baff51b68b15a2bc72cf275a9cd90bf56fa0b5fa3dc1a6bcb93a5b115bc7456f425f7ca562dbbe2a71ef7f2f8ff7f1439e94cc238c60e20796d6e148e2f3754b253bd1774f24820dbc09678b52932324526ba80ac087d28d21d0420794612116d2b1c9d787ba6c28cf11964f97a148df78e82f92a5caf7561c95d91fcaed3ce044d83ed55c4af3286d3fb6d44cc0f4ed5b7027d190d2c09f4f6a69122fcdb2f9d5d3d865b84abe8cf36e5a51529914cf2d96dbca94f5ddaf293f1cdd7c4373e60b6eebfb4af1e25f888c85f920712952775d91e98ef034493bf5688fee92c584a67b81d2904dac88783ee934b08b7361714ed59455cb1f952228deb78292caaa05cc90f7fd4991ffc42f15b1a6e92191d8fae59ef37988850259e4e383952866dc37e2076dec9a9241fe091a3228325f4174da26a3eed8e020b1e2501a7ae918d8280fc5e5c8432e5a8e1d4a59e7fd345ee287aa7d92dae2f693fb0000000000";
unsigned char *nonce2_hex = (unsigned char*) "f92bb7c74cb377ebcc0776986f594bf2cc1c1359ba1ffc70";
unsigned char *hispublickey_hex  = (unsigned char*) "a1a3b1385509e56449269f9d995a7d2d6bc1d7edd3b0d404bac8959d177fea4f";
unsigned char *mypublickey_hex =(unsigned char*)"157b15dafa9fc6cf96338a996ea90b39418ae1b5c2ceaace2a2d4767d23da843";
unsigned char *mysecret_hex =(unsigned char*)"8db561b5e5f839dbdcb44d0fb27c25d6fe20264b4b12fd6b93d54c344e0c9e2c";

unsigned char *msg1;
unsigned char *nonce2;
unsigned char *hispublickey;
unsigned char *mypublickey;
unsigned char *mysecretkey;
unsigned char *decrypted2;
/*

Create "My" public/private key pair using libsodium using Curve25519-Poly1305

	Key exchange: Curve25519
	Encryption: XSalsa20 stream cipher
	Authentication: Poly1305 MAC

	https://download.libsodium.org/doc/public-key_cryptography/authenticated_encryption.html

*/

crypto_box_keypair((unsigned char *)&mypublic, (unsigned char *)&mysecret);
printf ( "mysecret: ");
pp ( (unsigned char *)&mysecret );
printf ( "mypublic: ");
pp ( (unsigned char *)&mypublic );

/*
	Create "His" public/private key pair using libsodium
*/

crypto_box_keypair((unsigned char *)&hispublic, (unsigned char *)&hissecret);
printf ( "hissecret: ");
pp ( (unsigned char *)&hissecret );
printf ( "hispublic: ");
pp ( (unsigned char *)&hispublic );


/*
	Calculate a shared-secret to use 

	http://doc.libsodium.org/public-key_cryptography/authenticated_encryption.html#precalculation-interface

	Key exchange: Curve25519
	Encryption: XSalsa20 stream cipher
	Authentication: Poly1305 MAC

*/

crypto_box_beforenm((unsigned char *)&shared_key,  (unsigned char *)&hispublic, (unsigned char *)&mysecret);
printf ( "shared_key : ");
pp ( (unsigned char *)&shared_key );

crypto_box_beforenm((unsigned char *)&shared_key2, (unsigned char *)&mypublic,  (unsigned char *)&hissecret);
printf ( "shared_key2: ");
pp ( (unsigned char *)&shared_key2 );
                        
/*
   Do the aead_chacha20poly1305 encrypt with shared_key 1
   http://doc.libsodium.org/secret-key_cryptography/aead.html

*/

crypto_aead_chacha20poly1305_encrypt(ciphertext, &ciphertext_len,
                                     MESSAGE, MESSAGE_LEN,
                                     NULL, 0,
                                     NULL, nonce, shared_key);
                                     
                                     
/*
   Do the aead_chacha20poly1305 decrypt with shared_key 2 
   http://doc.libsodium.org/secret-key_cryptography/aead.html

*/

if (crypto_aead_chacha20poly1305_decrypt(decrypted, &decrypted_len,
                                         NULL,
                                         ciphertext, ciphertext_len,
                                         NULL,
                                         0,
                                         nonce, shared_key2) == 0) 
    { 
    
    decrypted[100] = 0;
    
    	printf ( "Message good! \n" );
    	printf ( "CipherText[%d]: ", ciphertext_len );
    	for (i=0; i<ciphertext_len; i++) {
    		printf ("%02x", ciphertext[i] );
    	}
    	printf("\n");
    	printf ( "Original  Message[%d]: %s\n", MESSAGE_LEN, MESSAGE );
    	printf ( "Decrypted Message[%llu]: =%s=\n", decrypted_len, decrypted );
//    	printf ( "Decrypted Message[%llu]: =%02x=\n", decrypted_len, decrypted[100] );
    	
    	
    	
    
    } else {
    	printf ( "Message bad! \n" );
    
    }


// Boxes :
			printf( " ===========> crypto_box_seal!\n");


		for (i=0; i<MESSAGE_LEN; i++ ){
			decrypted[i] = 0;		
		}

		crypto_box_seal(ciphertext2, MESSAGE, MESSAGE_LEN, &(hispublic));
    	printf ( "CipherText[%d]: ", MESSAGE_LEN+crypto_box_SEALBYTES );
    	for (i=0; i<MESSAGE_LEN+crypto_box_SEALBYTES; i++) {
    		printf ("%02x", ciphertext2[i] );
    	}
    	printf("\n");

		if (crypto_box_seal_open(decrypted, ciphertext2, MESSAGE_LEN+crypto_box_SEALBYTES, (unsigned char *)&hispublic, (unsigned char *)&hissecret) == 0)
		{
	    	printf ( "Original  Message[%d]: %s\n", MESSAGE_LEN, MESSAGE );
    		printf ( "Decrypted Message[%llu]: =%s=\n", decrypted_len, decrypted );
		} else {
			printf( " ===========> decryption failed!\n");
		}


		for (i=0; i<MESSAGE_LEN; i++ ){
			decrypted[i] = 0;		
		}
		
		msg1=calloc(msg1len/2,sizeof(unsigned char));
		chatFabric_hex2int_bytes(msg1_hex, msg1len, msg1, msg1len/2);

		nonce2=calloc(crypto_secretbox_NONCEBYTES,sizeof(unsigned char));
		chatFabric_hex2int_bytes(nonce2_hex, crypto_secretbox_NONCEBYTES*2, nonce2, crypto_secretbox_NONCEBYTES);

		nonce2=calloc(crypto_secretbox_NONCEBYTES,sizeof(unsigned char));
		chatFabric_hex2int_bytes(nonce2_hex, crypto_secretbox_NONCEBYTES*2, nonce2, crypto_secretbox_NONCEBYTES);

		hispublickey=calloc(crypto_box_PUBLICKEYBYTES,sizeof(unsigned char));
		chatFabric_hex2int_bytes(hispublickey_hex, crypto_box_PUBLICKEYBYTES*2, hispublickey, crypto_box_PUBLICKEYBYTES);

		mysecretkey=calloc(crypto_box_SECRETKEYBYTES,sizeof(unsigned char));
		chatFabric_hex2int_bytes(mysecret_hex, crypto_box_SECRETKEYBYTES*2, mysecretkey, crypto_box_SECRETKEYBYTES);

		decrypted2=calloc(msg1len/2 - crypto_secretbox_MACBYTES,sizeof(unsigned char));

/*
		crypto_box_easy(
			ciphertext3, MESSAGE, MESSAGE_LEN,
			nonce2,
			hispublickey,
			mysecretkey
		);*/
		if (crypto_box_open_easy(decrypted2, msg1, msg1len/2, nonce2,
								 hispublickey,  mysecretkey ) == 0) {
	    	printf ( "Original  Message[%d]: %s\n", MESSAGE_LEN, MESSAGE );
    		printf ( "Decrypted Message[%llu]: =%s=\n", decrypted_len, decrypted );
		} else {
			printf( " ===========> decryption failed!\n");
		}

}