int main() { auto print = [&](unsigned char* c) { for (int i = 16;i < 163;++i) { printf(",0x%02x",(unsigned int) c[i]); if (i % 8 == 7) printf("\n"); } printf("\n"); }; crypto_box(c,m,163,nonce,bobpk,alicesk); print(c); int constexpr s = 163; Message mm(m , s); crypto_array<u8,s> mc; auto n = Nonce::wrap(nonce); auto pk = Key::wrap(bobpk); auto sk = Key::wrap(alicesk); auto out = Message(mc.p(), s); crypto_box(out, mm, n, pk, sk); print(mc.p()); return 0; }
/* encrypts plain of length length to encrypted of length + 16 using the public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce return -1 if there was a problem. return length of encrypted data if everything was fine. */ int encrypt_data(uint8_t * public_key, uint8_t * secret_key, uint8_t * nonce, uint8_t * plain, uint32_t length, uint8_t * encrypted) { if(length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE || length == 0) { return -1; } uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES] = {0}; uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES]; uint8_t zeroes[crypto_box_BOXZEROBYTES] = {0}; memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); /* pad the message with 32 0 bytes. */ crypto_box(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, public_key, secret_key); /* if encryption is successful the first crypto_box_BOXZEROBYTES of the message will be zero */ if(memcmp(temp_encrypted, zeroes, crypto_box_BOXZEROBYTES) != 0) { return -1; } /* unpad the encrypted message */ memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES); return length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES; }
int main(void) { size_t mlen; size_t i; int caught; for (mlen = 0;mlen < 1000 && mlen + crypto_box_ZEROBYTES < sizeof m;++mlen) { crypto_box_keypair(alicepk,alicesk); crypto_box_keypair(bobpk,bobsk); randombytes(n,crypto_box_NONCEBYTES); randombytes(m + crypto_box_ZEROBYTES,mlen); crypto_box(c,m,mlen + crypto_box_ZEROBYTES,n,bobpk,alicesk); caught = 0; while (caught < 10) { c[rand() % (mlen + crypto_box_ZEROBYTES)] = rand(); if (crypto_box_open(m2,c,mlen + crypto_box_ZEROBYTES,n,alicepk,bobsk) == 0) { for (i = 0;i < mlen + crypto_box_ZEROBYTES;++i) if (m2[i] != m[i]) { printf("forgery\n"); return 100; } } else { ++caught; } } } return 0; }
int main(int argc, char **argv) { int rc; uint8_t client_pub[32], client_sec[32]; uint8_t server_pub[32], server_sec[32]; uint8_t cipher[512], plain[512]; uint8_t nonce[24]; /* initialize memory */ memset(cipher, 0, 512); memset(plain, 0, 512); /* "generate" nonce */ memset(nonce, 0, 24); /* "generate" keys */ memcpy(client_pub, CLIENT_PUB, 32); memcpy(client_sec, CLIENT_SEC, 32); memcpy(server_pub, SERVER_PUB, 32); memcpy(server_sec, SERVER_SEC, 32); /* assemble plaintext */ memcpy(plain, MESSAGE, MESSAGE_LEN); dump("plaintext, before encryption", plain, MESSAGE_LEN); /* encipher message from client to server */ rc = crypto_box(cipher, plain, MESSAGE_LEN, nonce, server_pub, client_sec); dump("ciphertext", cipher, MESSAGE_LEN); assert(rc == 0); return 0; }
// TODO: This should probably be refactored so that the indices and stuff are more sane; to prevent // memory issues. size_t tunnel_buildPacket(struct tunnel *t, uint8_t *packet, uint8_t *message, size_t messageSize) { const bool sendingPublickey = t->state == TUNNEL_STATE_CLIENT_PRE_HANDSHAKE; const uint64_t tidWithFlags = t->tid | (sendingPublickey ? PUBLICKEY_FLAG : 0); const size_t headerSize = sizeof tidWithFlags + sizeof t->nonce + (sendingPublickey ? sizeof t->localPublickey : 0); writeUint64LE(packet, tidWithFlags); memcpy(&packet[sizeof tidWithFlags], t->nonce, sizeof t->nonce); if (sendingPublickey) { t->state = TUNNEL_STATE_NORMAL; memcpy(&packet[sizeof tidWithFlags + sizeof t->nonce], t->localPublickey, sizeof t->localPublickey); } uint8_t crypted[crypto_box_ZEROBYTES + messageSize]; memset(crypted, 0, crypto_box_ZEROBYTES); memcpy(&crypted[crypto_box_ZEROBYTES], message, messageSize); crypto_box(crypted, crypted, sizeof crypted, t->nonce, t->remotePublickey, t->localSecretkey); memcpy(&packet[headerSize], &crypted[crypto_box_BOXZEROBYTES], sizeof crypted - crypto_box_BOXZEROBYTES); return headerSize + sizeof crypted - crypto_box_BOXZEROBYTES; }
int main(int argc, const char **argv) { unsigned char *sk, *pk, *n, *m, *c; size_t mlen, clen; if (argc < 2) { puts("usage: cbox SK PK NONCE"); return 1; } if (strlen(argv[1]) != crypto_box_SECRETKEYBYTES * 2) errx(1, "bad SK length"); sk = decodehex(argv[1]); if (strlen(argv[2]) != crypto_box_PUBLICKEYBYTES * 2) errx(1, "bad PK length"); pk = decodehex(argv[2]); if (strlen(argv[3]) != crypto_box_NONCEBYTES * 2) errx(1, "bad NONCE length"); n = decodehex(argv[3]); mlen = readmsg(&m); if ((c = calloc(mlen, 1)) == NULL) err(1, NULL); crypto_box(c, m, mlen, n, pk, sk); c += crypto_box_BOXZEROBYTES; clen = mlen - crypto_box_BOXZEROBYTES; if (fwrite(c, 1, clen, stdout) != clen) err(1, NULL); return 0; }
int zmq::curve_server_t::produce_welcome (msg_t *msg_) { uint8_t cookie_nonce [crypto_secretbox_NONCEBYTES]; uint8_t cookie_plaintext [crypto_secretbox_ZEROBYTES + 64]; uint8_t cookie_ciphertext [crypto_secretbox_BOXZEROBYTES + 80]; // Create full nonce for encryption // 8-byte prefix plus 16-byte random nonce memcpy (cookie_nonce, "COOKIE--", 8); randombytes (cookie_nonce + 8, 16); // Generate cookie = Box [C' + s'](t) memset (cookie_plaintext, 0, crypto_secretbox_ZEROBYTES); memcpy (cookie_plaintext + crypto_secretbox_ZEROBYTES, cn_client, 32); memcpy (cookie_plaintext + crypto_secretbox_ZEROBYTES + 32, cn_secret, 32); // Generate fresh cookie key randombytes (cookie_key, crypto_secretbox_KEYBYTES); // Encrypt using symmetric cookie key int rc = crypto_secretbox (cookie_ciphertext, cookie_plaintext, sizeof cookie_plaintext, cookie_nonce, cookie_key); zmq_assert (rc == 0); uint8_t welcome_nonce [crypto_box_NONCEBYTES]; uint8_t welcome_plaintext [crypto_box_ZEROBYTES + 128]; uint8_t welcome_ciphertext [crypto_box_BOXZEROBYTES + 144]; // Create full nonce for encryption // 8-byte prefix plus 16-byte random nonce memcpy (welcome_nonce, "WELCOME-", 8); randombytes (welcome_nonce + 8, crypto_box_NONCEBYTES - 8); // Create 144-byte Box [S' + cookie](S->C') memset (welcome_plaintext, 0, crypto_box_ZEROBYTES); memcpy (welcome_plaintext + crypto_box_ZEROBYTES, cn_public, 32); memcpy (welcome_plaintext + crypto_box_ZEROBYTES + 32, cookie_nonce + 8, 16); memcpy (welcome_plaintext + crypto_box_ZEROBYTES + 48, cookie_ciphertext + crypto_secretbox_BOXZEROBYTES, 80); rc = crypto_box (welcome_ciphertext, welcome_plaintext, sizeof welcome_plaintext, welcome_nonce, cn_client, secret_key); if (rc == -1) return -1; rc = msg_->init_size (168); errno_assert (rc == 0); uint8_t * const welcome = static_cast <uint8_t *> (msg_->data ()); memcpy (welcome, "\x07WELCOME", 8); memcpy (welcome + 8, welcome_nonce + 8, 16); memcpy (welcome + 24, welcome_ciphertext + crypto_box_BOXZEROBYTES, 144); return 0; }
static void test_hacl_01(void) { int res; /* Creating keypair ALICE... */ crypto_box_keypair(alice_pk, alice_sk); /* Creating keypair BOB... */ crypto_box_keypair(bob_pk, bob_sk); memset(m, 0, crypto_box_ZEROBYTES); memcpy(m + crypto_box_ZEROBYTES, message, MLEN - crypto_box_ZEROBYTES); /* Encrypting using pk_bob... */ crypto_box(c, m, MLEN, n, bob_pk, alice_sk); memset(result, '\0', sizeof(result)); /* Decrypting... */ res = crypto_box_open(result, c, MLEN, n, alice_pk, bob_sk); TEST_ASSERT_EQUAL_INT(0, res); memset(r, 0, sizeof(r)); memcpy(r, result + crypto_box_ZEROBYTES, MLEN - crypto_box_ZEROBYTES); TEST_ASSERT_EQUAL_STRING((const char*)message, (const char*)r); }
/* encrypts plain of length length to encrypted of length + 16 using the public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce return -1 if there was a problem. return length of encrypted data if everything was fine. */ int encrypt_data(uint8_t *public_key, uint8_t *secret_key, uint8_t *nonce, uint8_t *plain, uint32_t length, uint8_t *encrypted) { if (length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES > MAX_DATA_SIZE || length == 0) return -1; uint8_t temp_plain[MAX_DATA_SIZE + crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES] = {0}; uint8_t temp_encrypted[MAX_DATA_SIZE + crypto_box_ZEROBYTES]; memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); /* pad the message with 32 0 bytes. */ crypto_box(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, public_key, secret_key); /* if encryption is successful the first crypto_box_BOXZEROBYTES of the message will be zero apparently memcmp should not be used so we do this instead:*/ uint32_t i; uint32_t check = 0; for(i = 0; i < crypto_box_BOXZEROBYTES; ++i) { check |= temp_encrypted[i] ^ 0; } if(check != 0) return -1; /* unpad the encrypted message */ memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES); return length - crypto_box_BOXZEROBYTES + crypto_box_ZEROBYTES; }
static ERL_NIF_TERM nacl_box_padded(ErlNifEnv *env, int argc, ERL_NIF_TERM const argv[]) { ErlNifBinary padded_msg; ErlNifBinary nonce; ErlNifBinary pk; ErlNifBinary sk; ErlNifBinary result; if (!enif_inspect_iolist_as_binary(env, argv[0], &padded_msg)) return enif_make_badarg(env); if (!enif_inspect_iolist_as_binary(env, argv[1], &nonce)) return enif_make_badarg(env); if (!enif_inspect_iolist_as_binary(env, argv[2], &pk)) return enif_make_badarg(env); if (!enif_inspect_iolist_as_binary(env, argv[3], &sk)) return enif_make_badarg(env); if (nonce.size != crypto_box_NONCEBYTES) return enif_make_badarg(env); if (pk.size != crypto_box_PUBLICKEYBYTES) return enif_make_badarg(env); if (sk.size != crypto_box_SECRETKEYBYTES) return enif_make_badarg(env); if (padded_msg.size < crypto_box_ZEROBYTES) return enif_make_badarg(env); if (!enif_alloc_binary(padded_msg.size, &result)) return nacl_error_tuple(env, "alloc_failed"); crypto_box(result.data, padded_msg.data, padded_msg.size, nonce.data, pk.data, sk.data); return enif_make_sub_binary(env, enif_make_binary(env, &result), crypto_box_BOXZEROBYTES, padded_msg.size - crypto_box_BOXZEROBYTES); }
int main() { unsigned char n[crypto_box_NONCEBYTES]; unsigned char m[32+crypto_box_ZEROBYTES]; unsigned char c[32+crypto_box_ZEROBYTES]; unsigned char pk[crypto_box_PUBLICKEYBYTES]; unsigned char sk[crypto_box_SECRETKEYBYTES]; //crypto_box_keypair(pk, sk); //randombytes(sk,32); sk[0]=1; crypto_scalarmult_curve25519_base(pk,sk); int r; unsigned char* buffer1offset = m + crypto_box_ZEROBYTES; strcpy(buffer1offset, "hello world"); printf("in=$s\n", buffer1offset); memset(m, 0, crypto_box_ZEROBYTES); r=crypto_box(c, m, 32+crypto_box_ZEROBYTES, n, pk, sk); printf("ret=%d\n", r); memset(c, 0, crypto_box_BOXZEROBYTES); r=crypto_box_open(m, c, 32+crypto_box_ZEROBYTES, n, pk, sk); printf("ret=%d\n", r); printf("out=$s\n", buffer1offset); }
EncryptedMessage CryptoEngine::EncryptWithPublicKeyAndSign(const Message &message, const VerificationEngine &ver_engine) { // check the public key if (ver_engine.public_key().empty()) { std::cout << "The recipient public key is empty. Cannot encrypt here." << std::endl; throw g_crypto_engine_encryption_failure; } if (ver_engine.signing_public_key().empty()) { std::cout << "The recipient signing public key is empty. Cannot encrypt here." << std::endl; throw g_crypto_engine_encryption_failure; } if (private_key_.empty()) { std::cout << "The secret key is empty. Cannot encrypt here." << std::endl; throw g_crypto_engine_encryption_failure; } if (nonce_master_key_.empty()) { std::cout << "The master key for deriving the nonce is not valid" << std::endl; throw g_crypto_engine_encryption_failure; } if (context_.empty()) { std::cout << "The context identifier for deriving the nonce is not valid" << std::endl; throw g_crypto_engine_encryption_failure; } if (salt_.empty()) { std::cout << "The salt for deriving the nonce is not valid" << std::endl; throw g_crypto_engine_encryption_failure; } // means the current crypto engine and the recipient crypto engine have the same public keys ! // This is NOT SAFE - stop immediately if(crypto_verify_32 (reinterpret_cast<const unsigned char *>(public_key_.data()), reinterpret_cast<const unsigned char *>(ver_engine.public_key().data())) == 0) { std::cout << "The engine public key and the recipient public key are the same !!! Did you copy the same files to two different peers ? This is NOT SAFE !! STOPPING !" << std::endl; throw g_crypto_engine_encryption_failure; } // derive the nonce std::string nonce = hkdf_.DeriveNonce(nonce_master_key_, salt_); // calculate the hash of the data std::string hash(crypto_hash(message.ToBytesString())); // calculate the signature on the hash std::string signed_hash = crypto_sign(hash, sign_private_key_); // prepend the signature+hash to the message std::string signed_message_string = signed_hash + message.ToBytesString(); // encrypt with the recipient public key std::string cipher_text = crypto_box(signed_message_string, nonce, ver_engine.public_key(), private_key_); return EncryptedMessage(nonce, cipher_text); }
int main(int argc, char *argv[]) { if (argc != 5) error(2, "Usage: tweetnacl-encrypt send-key.sec recv-key.pub text.txt text.enc"); // This will also erroneously fail if the file "-" exists if (file_exists(argv[4])) errorf(1, "File <%s> exists", argv[4]); // Alice is sending to Bob, not surprisingly unsigned char a_secret_key[crypto_box_SECRETKEYBYTES]; unsigned char b_public_key[crypto_box_PUBLICKEYBYTES]; read_key(argv[1], a_secret_key, crypto_box_SECRETKEYBYTES); read_key(argv[2], b_public_key, crypto_box_PUBLICKEYBYTES); unsigned char nonce[crypto_box_NONCEBYTES]; randombytes(nonce, sizeof(nonce)); FILE *out; if (strcmp(argv[4], "-") != 0) { out = create_file(argv[4]); fwrite(nonce, sizeof(nonce), 1, out); } else { out = stdout; fwrite(bytes_to_hex(nonce, sizeof(nonce)), sizeof(nonce) * 2, 1, out); fputs("\n", out); } // Input // unsigned char *message = read_file(argv[3]); Content c = read_file(argv[3]); long psize = crypto_box_ZEROBYTES + c.size; unsigned char *padded = malloc(psize); if (padded == NULL) error(1, "Malloc failed!"); memset(padded, 0, crypto_box_ZEROBYTES); memcpy(padded + crypto_box_ZEROBYTES, c.bytes, c.size); free(c.bytes); // Output unsigned char *encrypted = calloc(psize, sizeof(unsigned char)); if (encrypted == NULL) error(1, "Calloc failed!"); // Encrypt crypto_box(encrypted, padded, psize, nonce, b_public_key, a_secret_key); free(padded); if (out != stdout) { fwrite(encrypted + crypto_box_BOXZEROBYTES, psize - crypto_box_BOXZEROBYTES, 1, out); } else { fwrite(bytes_to_hex(encrypted + crypto_box_BOXZEROBYTES, psize - crypto_box_BOXZEROBYTES), (psize - crypto_box_BOXZEROBYTES) * 2, 1, out); fputs("\n", out); } free(encrypted); return 0; }
static nif_term_t salt_box(nif_heap_t *hp, int argc, const nif_term_t argv[]) { /* salt_box(Plain_text, Nonce, Public_key, Secret_key) -> Cipher_text. */ nif_bin_t pt; nif_bin_t nc; nif_bin_t pk; nif_bin_t sk; nif_bin_t ct; nif_term_t raw; nif_term_t sub; if (argc != 4) return (BADARG); /* Unpack arguments ensuring they're suitably typed. */ if (! enif_inspect_iolist_as_binary(hp, argv[0], &pt)) return (BADARG); if (! enif_inspect_binary(hp, argv[1], &nc)) return (BADARG); if (! enif_inspect_binary(hp, argv[2], &pk)) return (BADARG); if (! enif_inspect_binary(hp, argv[3], &sk)) return (BADARG); /* Check constraints on size and zero prefixing. */ if (pt.size < crypto_box_ZEROBYTES || pt.size > SALT_MAX_MESSAGE_SIZE) return (BADARG); if (memcmp((const void *)pt.data, &salt_box_zerobytes[0], crypto_box_ZEROBYTES) != 0) return (BADARG); if (nc.size != crypto_box_NONCEBYTES) return (BADARG); if (pk.size != crypto_box_PUBLICKEYBYTES) return (BADARG); if (sk.size != crypto_box_SECRETKEYBYTES) return (BADARG); /* Allocate space for cipher text. NB: Passing ENOMEM as BADARG. */ if (! enif_alloc_binary(pt.size, &ct)) return (BADARG); /* Perform the crypto, strip leading zeros. */ (void)crypto_box(ct.data, pt.data, pt.size, nc.data, pk.data, sk.data); raw = enif_make_binary(hp, &ct); sub = enif_make_sub_binary(hp, raw, crypto_box_BOXZEROBYTES, ct.size - crypto_box_BOXZEROBYTES); return (sub); }
int main() { char * padded_message; int padded_mlen; u8 sk[PRIV_KEY_LEN] = {0}; u8 pk[PUB_KEY_LEN] = {0}; u8 sk2[PRIV_KEY_LEN] = {0}; u8 pk2[PUB_KEY_LEN] = {0}; u8 nonce[NONCE_LEN] = {0}; char* message = "This is a cross-platform test of crypto_box/crypto_box_open in TweetNaCl."; u8 * ciphertext; char *decryptedmessage; // randomize nonce randombytes(nonce, NONCE_LEN); printf("Nonce: \n"); hexdump((char*)nonce, NONCE_LEN); crypto_box_keypair(pk, sk); crypto_box_keypair(pk2, sk2); printf("Public key: \n"); hexdump((char*)pk, PUB_KEY_LEN); printf("\nSecret key: \n"); hexdump((char*)sk, PRIV_KEY_LEN); printf("Public key2: \n"); hexdump((char*)pk2, PUB_KEY_LEN); printf("\nSecret key2: \n"); hexdump((char*)sk2, PRIV_KEY_LEN); padded_mlen = strlen(message) + PADDING_LEN; padded_message = (char*) malloc(padded_mlen); memset(padded_message, 0, PADDING_LEN); memcpy(padded_message + PADDING_LEN, message, strlen(message)); ciphertext = (u8*) malloc(padded_mlen); // we have a string so add 1 byte and NUL it so we can print it decryptedmessage = (char*) malloc(padded_mlen+1); decryptedmessage[padded_mlen] = '\0'; printf("crypto_box returned: %d\n",crypto_box(ciphertext, (u8*)padded_message, padded_mlen, nonce, pk2, sk)); free(padded_message); printf("\nCipher text: \n"); hexdump((char*)ciphertext, padded_mlen); printf("crypto_box_open returned: %d\n", crypto_box_open((u8*)decryptedmessage, ciphertext, padded_mlen, nonce, pk, sk2)); free(ciphertext); printf("\nDecrypted text: \n"); hexdump((char*)decryptedmessage, padded_mlen); printf("%s\n", decryptedmessage+32); free(decryptedmessage); return 0; }
int main(void) { unsigned char k[crypto_box_BEFORENMBYTES]; int i; int ret; ret = crypto_box(c, m, 163, nonce, bobpk, alicesk); assert(ret == 0); for (i = 16; i < 163; ++i) { printf(",0x%02x", (unsigned int)c[i]); if (i % 8 == 7) printf("\n"); } printf("\n"); memset(c, 0, sizeof c); ret = crypto_box_beforenm(k, bobpk, alicesk); assert(ret == 0); crypto_box_afternm(c, m, 163, nonce, k); for (i = 16; i < 163; ++i) { printf(",0x%02x", (unsigned int)c[i]); if (i % 8 == 7) printf("\n"); } printf("\n"); assert(crypto_box_seedbytes() > 0U); assert(crypto_box_publickeybytes() > 0U); assert(crypto_box_secretkeybytes() > 0U); assert(crypto_box_beforenmbytes() > 0U); assert(crypto_box_noncebytes() > 0U); assert(crypto_box_zerobytes() > 0U); assert(crypto_box_boxzerobytes() > 0U); assert(crypto_box_macbytes() > 0U); assert(strcmp(crypto_box_primitive(), "curve25519xsalsa20poly1305") == 0); assert(crypto_box_curve25519xsalsa20poly1305_seedbytes() == crypto_box_seedbytes()); assert(crypto_box_curve25519xsalsa20poly1305_publickeybytes() == crypto_box_publickeybytes()); assert(crypto_box_curve25519xsalsa20poly1305_secretkeybytes() == crypto_box_secretkeybytes()); assert(crypto_box_curve25519xsalsa20poly1305_beforenmbytes() == crypto_box_beforenmbytes()); assert(crypto_box_curve25519xsalsa20poly1305_noncebytes() == crypto_box_noncebytes()); assert(crypto_box_curve25519xsalsa20poly1305_zerobytes() == crypto_box_zerobytes()); assert(crypto_box_curve25519xsalsa20poly1305_boxzerobytes() == crypto_box_boxzerobytes()); assert(crypto_box_curve25519xsalsa20poly1305_macbytes() == crypto_box_macbytes()); return 0; }
// Decrypt with the same key but from the message bytes EncryptedMessage CryptoEngine::EncryptWithPublicKey(const Message &message, const VerificationEngine &ver_engine) { // check the public key if (ver_engine.public_key().empty()) { std::cout << "The recipient public key is empty. Cannot encrypt here." << std::endl; throw g_crypto_engine_encryption_failure; } if (private_key_.empty()) { std::cout << "The secret key is empty. Cannot encrypt here." << std::endl; throw g_crypto_engine_encryption_failure; } if (nonce_master_key_.empty()) { std::cout << "The master key for deriving the nonce is not valid" << std::endl; throw g_crypto_engine_encryption_failure; } if (context_.empty()) { std::cout << "The context identifier for deriving the nonce is not valid" << std::endl; throw g_crypto_engine_encryption_failure; } if (salt_.empty()) { std::cout << "The salt for deriving the nonce is not valid" << std::endl; throw g_crypto_engine_encryption_failure; } // means the current crypto engine and the recipient crypto engine have the same public keys ! // This is NOT SAFE - stop immediately if(crypto_verify_32 (reinterpret_cast<const unsigned char *>(public_key_.data()), reinterpret_cast<const unsigned char *>(ver_engine.public_key().data())) == 0) { std::cout << "The engine public key and the recipient public key are the same !!! Did you copy the same files to two different peers ? This is NOT SAFE !! STOPPING !" << std::endl; throw g_crypto_engine_encryption_failure; } try { // derive the nonce std::string nonce = hkdf_.DeriveNonce(nonce_master_key_, salt_); // Add the additional data (tcp_verion, type, message) to the string std::string full_clear_text(message.ToBytesString()); // encrypt with the recipient public key std::string cipher_text = crypto_box(full_clear_text, nonce, ver_engine.public_key(), private_key_); return EncryptedMessage(nonce, cipher_text); } catch (std::exception& e) { std::cout << "CryptoEngine::Encrypt exception: " << e.what() << std::endl; throw g_crypto_engine_encryption_failure; } }
String NaCl::public_encrypt(String msg) { try { std::string message = from_ruby<std::string>(msg); std::string encrypted_message = crypto_box(message, remote_nonce, remote_pk, my_sk); return to_ruby<std::string>(encrypted_message); } catch (int e) { return to_ruby<std::string>(""); } }
/** * Encrypt data without making it a packet. * @src: source of the data * @len: length of the data * @pk: public key to encrypt the data for * @sk: secret key to encrypt the data with * @dest: destination for ciphertext, must be as big as len + PREFIX */ void crypto_encipher_data (const void *src, int len, const unsigned char *pek, const unsigned char *sek, void *dest) { unsigned char m[crypto_box_ZEROBYTES + len]; memset(m, 0, crypto_box_ZEROBYTES + len); memset(dest, 0, PREFIX + len); memcpy(m + crypto_box_ZEROBYTES, src, len); randombytes_buf(dest, crypto_box_NONCEBYTES); crypto_box((unsigned char *)dest + crypto_box_NONCEBYTES, m, crypto_box_ZEROBYTES + len, dest, pek, sek); }
int main(int argc, char **argv) { int rc; uint8_t client_pub[32], client_sec[32]; uint8_t server_pub[32], server_sec[32]; uint8_t cipher[512], plain[512]; uint8_t nonce[24]; /* initialize memory */ memset(cipher, 0, 512); memset(plain, 0, 512); /* "generate" nonce */ memset(nonce, 0, 24); /* "generate" keys */ memcpy(client_pub, CLIENT_PUB, 32); memcpy(client_sec, CLIENT_SEC, 32); memcpy(server_pub, SERVER_PUB, 32); memcpy(server_sec, SERVER_SEC, 32); /* assemble plaintext */ memset(plain, 0, 32); /* first 32 octest are ZERO */ memcpy(plain+32, MESSAGE, MESSAGE_LEN); /* then comes the real data */ dump("plaintext, before encryption", plain, MESSAGE_LEN+32); /* encipher message from client to server */ rc = crypto_box(cipher, plain, MESSAGE_LEN+32, nonce, server_pub, client_sec); dump("ciphertext", cipher, MESSAGE_LEN); assert(rc == 0); /* erase all trace of plaintext */ memset(plain, 0, 512); /* decipher message as server, using client's public key */ rc = crypto_box_open(plain, cipher, MESSAGE_LEN+32, nonce, client_pub, server_sec); dump("plaintext, after decryption", plain, MESSAGE_LEN+32); assert(rc == 0); assert(memcmp(MESSAGE, plain, MESSAGE_LEN) == 0); plain[MESSAGE_LEN+1] = '\0'; printf("%s\n", plain); return 0; }
// encrypted_bytes = crypto_box(clear_bytes, nonce, pk_other, sk_self); static int tweetnacl_crypto_box( lua_State* L ) { unsigned int msg_len; const char* msg = luaL_checklstring(L,1,&msg_len); if(msg_len < 1) return luaL_error( L, "len(message)=%d, too short", msg_len); unsigned int nonce_len; const char* nonce = luaL_checklstring(L,2,&nonce_len); if(nonce_len != crypto_box_NONCEBYTES) return luaL_error( L, "len(nonce)=%d, should be %d", nonce_len, crypto_box_NONCEBYTES); unsigned int pk_len; const char* pk_other = luaL_checklstring(L,3,&pk_len); if(pk_len != crypto_box_PUBLICKEYBYTES) return luaL_error( L, "len(pk)=%d, should be %d", pk_len, crypto_box_PUBLICKEYBYTES); unsigned int sk_len; const char* sk_self = luaL_checklstring(L,4,&sk_len); if(sk_len != crypto_box_SECRETKEYBYTES) return luaL_error( L, "len(sk)=%d, should be %d", sk_len, crypto_box_SECRETKEYBYTES); unsigned int cmsg_len = msg_len + crypto_box_ZEROBYTES; char *cmsg = (char *)c_malloc(cmsg_len); if(!cmsg) return luaL_error( L, "malloc failed, %d bytes", cmsg_len); int i; for(i=0;i<crypto_box_ZEROBYTES;i++) cmsg[i] = 0; for(;i<cmsg_len;i++) cmsg[i] = msg[i-crypto_box_ZEROBYTES]; unsigned int emsg_len = cmsg_len; char *emsg = (char *)c_malloc(emsg_len); if(!emsg) { c_free(cmsg); return luaL_error( L, "malloc failed, %d bytes", emsg_len); } crypto_box(emsg, cmsg, cmsg_len, nonce, pk_other, sk_self); lua_pushlstring(L, emsg+crypto_box_BOXZEROBYTES, emsg_len-crypto_box_BOXZEROBYTES); c_free(cmsg); c_free(emsg); return 1; }
Connection::Connection(CryptoIdentity& ci, Path path, ConnectionPool& cp, ConnectionHandler& ch) : Forwarding(randint64()) , _ci(&ci) , _cp(cp) , _ch(ch) , _naclsession( std::get<1>(path.at(path.size()-1))->enc_key() ) , _their_id( std::get<1>(path.at(path.size()-1))->id() ) , _route_id( bytes( id() ) ) , _authenticated(false) , _request_packet(new std::string) , _packet_queue(new std::vector<std::string>) , _nonces(nullptr) { _request_packet->push_back('\1'); std::string nonce = _route_id + randomstring(8); _request_packet->append(nonce); nonce.resize(crypto_box_NONCEBYTES,'\0'); RoutingRequest rq; rq.set_enc_algo(enumval(PkencAlgo::CURVE25519XSALSA20POLY1305)); rq.set_sender_pubkey(_naclsession.our_pk()); Hop hop; { hop.set_type(Hop::UP); hop.set_nonce_algo(Hop::XTEA32); rq.set_details(_naclsession.encrypt(hop.SerializeAsString(), nonce)); } hop.Clear(); hop.set_type(Hop::SIMPLE); hop.set_next(_their_id); for (signed int i=path.size()-2; i>=0; --i) { auto dev = std::get<1>(path[i]); hop.set_details(rq.details()); rq.set_details( crypto_box( hop.SerializeAsString(), nonce, dev->enc_key(), _naclsession.our_sk()) ); hop.set_next(dev->id()); } rq.AppendToString(_request_packet.get()); }
int zmq::curve_client_t::produce_hello (msg_t *msg_) { uint8_t hello_nonce [crypto_box_NONCEBYTES]; uint8_t hello_plaintext [crypto_box_ZEROBYTES + 64]; uint8_t hello_box [crypto_box_BOXZEROBYTES + 80]; // Prepare the full nonce memcpy (hello_nonce, "CurveZMQHELLO---", 16); put_uint64 (hello_nonce + 16, cn_nonce); // Create Box [64 * %x0](C'->S) memset (hello_plaintext, 0, sizeof hello_plaintext); int rc = crypto_box (hello_box, hello_plaintext, sizeof hello_plaintext, hello_nonce, server_key, cn_secret); if (rc == -1) return -1; rc = msg_->init_size (200); errno_assert (rc == 0); uint8_t *hello = static_cast <uint8_t *> (msg_->data ()); memcpy (hello, "\x05HELLO", 6); // CurveZMQ major and minor version numbers memcpy (hello + 6, "\1\0", 2); // Anti-amplification padding memset (hello + 8, 0, 72); // Client public connection key memcpy (hello + 80, cn_public, crypto_box_PUBLICKEYBYTES); // Short nonce, prefixed by "CurveZMQHELLO---" memcpy (hello + 112, hello_nonce + 16, 8); // Signature, Box [64 * %x0](C'->S) memcpy (hello + 120, hello_box + crypto_box_BOXZEROBYTES, 80); cn_nonce++; return 0; }
PyObject *pycrypto_box(PyObject *self, PyObject *args, PyObject *kw){ char *m, *n, *pk, *sk; Py_ssize_t msize=0, nsize=0, pksize=0, sksize=0; static const char *kwlist[] = {"m", "n", "pk", "sk", 0}; unsigned int i; PyObject *ret; size_t mlen; unsigned char *mpad; unsigned char *cpad; if (!PyArg_ParseTupleAndKeywords(args, kw, "|s#s#s#s#:crypto_box", (char **) kwlist, &m, &msize, &n, &nsize, &pk, &pksize, &sk, &sksize)){ return (PyObject *)0;} if (nsize != crypto_box_NONCEBYTES) return Py_BuildValue("i", 0); if (pksize != crypto_box_PUBLICKEYBYTES) return Py_BuildValue("i", 0); if (sksize != crypto_box_SECRETKEYBYTES) return Py_BuildValue("i", 0); mlen = msize + crypto_box_ZEROBYTES; mpad = PyMem_Malloc(mlen); if (!mpad) return PyErr_NoMemory(); cpad = PyMem_Malloc(mlen); if (!cpad){ PyMem_Free(mpad); return PyErr_NoMemory();} for (i = 0;i < crypto_box_ZEROBYTES;++i) mpad[i] = 0; for (i = crypto_box_ZEROBYTES;i < mlen;++i) mpad[i] = m[i - crypto_box_ZEROBYTES]; crypto_box(cpad, mpad, mlen,(const unsigned char *) n,(const unsigned char *) pk,(const unsigned char *) sk); ret = PyBytes_FromStringAndSize((char *)cpad + crypto_box_BOXZEROBYTES,mlen - crypto_box_BOXZEROBYTES); PyMem_Free(mpad); PyMem_Free(cpad); return ret;}
static int produce_hello (void *data_, const uint8_t *server_key_, const uint64_t cn_nonce_, const uint8_t *cn_public_, const uint8_t *cn_secret_) { uint8_t hello_nonce[crypto_box_NONCEBYTES]; uint8_t hello_plaintext[crypto_box_ZEROBYTES + 64]; uint8_t hello_box[crypto_box_BOXZEROBYTES + 80]; // Prepare the full nonce memcpy (hello_nonce, "CurveZMQHELLO---", 16); put_uint64 (hello_nonce + 16, cn_nonce_); // Create Box [64 * %x0](C'->S) memset (hello_plaintext, 0, sizeof hello_plaintext); int rc = crypto_box (hello_box, hello_plaintext, sizeof hello_plaintext, hello_nonce, server_key_, cn_secret_); if (rc == -1) return -1; uint8_t *hello = static_cast<uint8_t *> (data_); memcpy (hello, "\x05HELLO", 6); // CurveZMQ major and minor version numbers memcpy (hello + 6, "\1\0", 2); // Anti-amplification padding memset (hello + 8, 0, 72); // Client public connection key memcpy (hello + 80, cn_public_, crypto_box_PUBLICKEYBYTES); // Short nonce, prefixed by "CurveZMQHELLO---" memcpy (hello + 112, hello_nonce + 16, 8); // Signature, Box [64 * %x0](C'->S) memcpy (hello + 120, hello_box + crypto_box_BOXZEROBYTES, 80); return 0; }
int main(void) { size_t mlen; size_t i; for (mlen = 0;mlen < 1000 && mlen + crypto_box_ZEROBYTES < sizeof m;++mlen) { crypto_box_keypair(alicepk,alicesk); crypto_box_keypair(bobpk,bobsk); randombytes(n,crypto_box_NONCEBYTES); randombytes(m + crypto_box_ZEROBYTES,mlen); crypto_box(c,m,mlen + crypto_box_ZEROBYTES,n,bobpk,alicesk); if (crypto_box_open(m2,c,mlen + crypto_box_ZEROBYTES,n,alicepk,bobsk) == 0) { for (i = 0;i < mlen + crypto_box_ZEROBYTES;++i) if (m2[i] != m[i]) { printf("bad decryption\n"); break; } } else { printf("ciphertext fails verification\n"); } } return 0; }
static int produce_initiate (void *data_, size_t size_, const uint64_t cn_nonce_, const uint8_t *server_key_, const uint8_t *public_key_, const uint8_t *secret_key_, const uint8_t *cn_public_, const uint8_t *cn_secret_, const uint8_t *cn_server_, const uint8_t *cn_cookie_, const uint8_t *metadata_plaintext_, const size_t metadata_length_) { uint8_t vouch_nonce[crypto_box_NONCEBYTES]; uint8_t vouch_plaintext[crypto_box_ZEROBYTES + 64]; uint8_t vouch_box[crypto_box_BOXZEROBYTES + 80]; // Create vouch = Box [C',S](C->S') memset (vouch_plaintext, 0, crypto_box_ZEROBYTES); memcpy (vouch_plaintext + crypto_box_ZEROBYTES, cn_public_, 32); memcpy (vouch_plaintext + crypto_box_ZEROBYTES + 32, server_key_, 32); memcpy (vouch_nonce, "VOUCH---", 8); randombytes (vouch_nonce + 8, 16); int rc = crypto_box (vouch_box, vouch_plaintext, sizeof vouch_plaintext, vouch_nonce, cn_server_, secret_key_); if (rc == -1) return -1; uint8_t initiate_nonce[crypto_box_NONCEBYTES]; uint8_t *initiate_box = static_cast<uint8_t *> ( malloc (crypto_box_BOXZEROBYTES + 144 + metadata_length_)); alloc_assert (initiate_box); uint8_t *initiate_plaintext = static_cast<uint8_t *> ( malloc (crypto_box_ZEROBYTES + 128 + metadata_length_)); alloc_assert (initiate_plaintext); // Create Box [C + vouch + metadata](C'->S') memset (initiate_plaintext, 0, crypto_box_ZEROBYTES); memcpy (initiate_plaintext + crypto_box_ZEROBYTES, public_key_, 32); memcpy (initiate_plaintext + crypto_box_ZEROBYTES + 32, vouch_nonce + 8, 16); memcpy (initiate_plaintext + crypto_box_ZEROBYTES + 48, vouch_box + crypto_box_BOXZEROBYTES, 80); memcpy (initiate_plaintext + crypto_box_ZEROBYTES + 48 + 80, metadata_plaintext_, metadata_length_); memcpy (initiate_nonce, "CurveZMQINITIATE", 16); put_uint64 (initiate_nonce + 16, cn_nonce_); rc = crypto_box (initiate_box, initiate_plaintext, crypto_box_ZEROBYTES + 128 + metadata_length_, initiate_nonce, cn_server_, cn_secret_); free (initiate_plaintext); if (rc == -1) return -1; uint8_t *initiate = static_cast<uint8_t *> (data_); zmq_assert (size_ == 113 + 128 + crypto_box_BOXZEROBYTES + metadata_length_); memcpy (initiate, "\x08INITIATE", 9); // Cookie provided by the server in the WELCOME command memcpy (initiate + 9, cn_cookie_, 96); // Short nonce, prefixed by "CurveZMQINITIATE" memcpy (initiate + 105, initiate_nonce + 16, 8); // Box [C + vouch + metadata](C'->S') memcpy (initiate + 113, initiate_box + crypto_box_BOXZEROBYTES, 128 + metadata_length_ + crypto_box_BOXZEROBYTES); free (initiate_box); return 0; }
bool unit_test_crypto_box(){ // Global length uint64_t len = HACL_UNIT_TESTS_SIZE * sizeof(uint8_t); // Scratch buffers uint8_t hacl_cipher[HACL_UNIT_TESTS_SIZE + 32], expected_cipher[HACL_UNIT_TESTS_SIZE + 32]; // Generation of the public/secret key couple uint8_t sk1[32], pk1[32]; uint8_t sk2[32], pk2[32]; tweet_crypto_box_keypair(pk1, sk1); tweet_crypto_box_keypair(pk2, sk2); // Random plaintext uint8_t *plaintext = malloc((HACL_UNIT_TESTS_SIZE + crypto_box_ZEROBYTES) * sizeof (uint8_t)); READ_RANDOM_BYTES(len, plaintext + crypto_box_ZEROBYTES); for (int i = 0; i < crypto_box_ZEROBYTES; i++) plaintext[i] = 0; // Random plaintext uint8_t nonce[24]; READ_RANDOM_BYTES(24, nonce); // Test 1 int a; bool pass = true; for (int i = 0; i < 3 * CHACHA_BLOCKSIZE; i++){ tweet_crypto_box(expected_cipher, plaintext, crypto_box_ZEROBYTES + i, nonce, pk1, sk2); crypto_box(hacl_cipher, plaintext, crypto_box_ZEROBYTES + i, nonce, pk1, sk2); a = memcmp(hacl_cipher, expected_cipher, (crypto_box_ZEROBYTES + i) * sizeof (uint8_t)); if (a != 0){ pass = false; printf("BOX failed on input of size %d\n.", i); break; } a = crypto_box_open(hacl_cipher, expected_cipher, i + crypto_box_ZEROBYTES, nonce, pk2, sk1); if (a != 0) { pass = false; printf("BOX OPEN failed to verify on input of size %d\n", i); break; } a = memcmp(hacl_cipher, plaintext, (crypto_box_ZEROBYTES + i) * sizeof (uint8_t)); if (a != 0) { pass = false; printf("BOX OPEN failed on input of size %d\n", i); break; } } if (!pass) return pass; // Test 2 tweet_crypto_box(expected_cipher, plaintext, crypto_box_ZEROBYTES + HACL_UNIT_TESTS_SIZE, nonce, pk1, sk2); crypto_box(hacl_cipher, plaintext, crypto_box_ZEROBYTES + HACL_UNIT_TESTS_SIZE, nonce, pk1, sk2); a = memcmp(hacl_cipher, expected_cipher, (crypto_box_ZEROBYTES + HACL_UNIT_TESTS_SIZE) * sizeof (uint8_t)); if (a != 0){ pass = false; printf("BOX failed on input of size %d\n.", HACL_UNIT_TESTS_SIZE); } a = crypto_box_open(hacl_cipher, expected_cipher, HACL_UNIT_TESTS_SIZE + crypto_box_ZEROBYTES, nonce, pk2, sk1); if (a != 0) { pass = false; printf("BOX OPEN failed to verify on input of size %d\n", HACL_UNIT_TESTS_SIZE); } a = memcmp(hacl_cipher, plaintext, (crypto_box_ZEROBYTES + HACL_UNIT_TESTS_SIZE) * sizeof (uint8_t)); if (a != 0) { pass = false; printf("BOX OPEN failed on input of size %d\n", HACL_UNIT_TESTS_SIZE); } free(plaintext); return pass; }
int zmq::curve_client_t::produce_initiate (msg_t *msg_) { uint8_t vouch_nonce [crypto_box_NONCEBYTES]; uint8_t vouch_plaintext [crypto_box_ZEROBYTES + 64]; uint8_t vouch_box [crypto_box_BOXZEROBYTES + 80]; // Create vouch = Box [C',S](C->S') memset (vouch_plaintext, 0, crypto_box_ZEROBYTES); memcpy (vouch_plaintext + crypto_box_ZEROBYTES, cn_public, 32); memcpy (vouch_plaintext + crypto_box_ZEROBYTES + 32, server_key, 32); memcpy (vouch_nonce, "VOUCH---", 8); randombytes (vouch_nonce + 8, 16); int rc = crypto_box (vouch_box, vouch_plaintext, sizeof vouch_plaintext, vouch_nonce, cn_server, secret_key); zmq_assert (rc == 0); // Assume here that metadata is limited to 256 bytes uint8_t initiate_nonce [crypto_box_NONCEBYTES]; uint8_t initiate_plaintext [crypto_box_ZEROBYTES + 128 + 256]; uint8_t initiate_box [crypto_box_BOXZEROBYTES + 144 + 256]; // Create Box [C + vouch + metadata](C'->S') memset (initiate_plaintext, 0, crypto_box_ZEROBYTES); memcpy (initiate_plaintext + crypto_box_ZEROBYTES, public_key, 32); memcpy (initiate_plaintext + crypto_box_ZEROBYTES + 32, vouch_nonce + 8, 16); memcpy (initiate_plaintext + crypto_box_ZEROBYTES + 48, vouch_box + crypto_box_BOXZEROBYTES, 80); // Metadata starts after vouch uint8_t *ptr = initiate_plaintext + crypto_box_ZEROBYTES + 128; // Add socket type property const char *socket_type = socket_type_string (options.type); ptr += add_property (ptr, "Socket-Type", socket_type, strlen (socket_type)); // Add identity property if (options.type == ZMQ_REQ || options.type == ZMQ_DEALER || options.type == ZMQ_ROUTER) ptr += add_property (ptr, "Identity", options.identity, options.identity_size); const size_t mlen = ptr - initiate_plaintext; memcpy (initiate_nonce, "CurveZMQINITIATE", 16); put_uint64 (initiate_nonce + 16, cn_nonce); rc = crypto_box (initiate_box, initiate_plaintext, mlen, initiate_nonce, cn_server, cn_secret); zmq_assert (rc == 0); rc = msg_->init_size (113 + mlen - crypto_box_BOXZEROBYTES); errno_assert (rc == 0); uint8_t *initiate = static_cast <uint8_t *> (msg_->data ()); memcpy (initiate, "\x08INITIATE", 9); // Cookie provided by the server in the WELCOME command memcpy (initiate + 9, cn_cookie, 96); // Short nonce, prefixed by "CurveZMQINITIATE" memcpy (initiate + 105, initiate_nonce + 16, 8); // Box [C + vouch + metadata](C'->S') memcpy (initiate + 113, initiate_box + crypto_box_BOXZEROBYTES, mlen - crypto_box_BOXZEROBYTES); cn_nonce++; return 0; }
int zmq::curve_server_t::produce_welcome (msg_t *msg_) { uint8_t cookie_nonce[crypto_secretbox_NONCEBYTES]; uint8_t cookie_plaintext[crypto_secretbox_ZEROBYTES + 64]; uint8_t cookie_ciphertext[crypto_secretbox_BOXZEROBYTES + 80]; // Create full nonce for encryption // 8-byte prefix plus 16-byte random nonce memcpy (cookie_nonce, "COOKIE--", 8); randombytes (cookie_nonce + 8, 16); // Generate cookie = Box [C' + s'](t) memset (cookie_plaintext, 0, crypto_secretbox_ZEROBYTES); memcpy (cookie_plaintext + crypto_secretbox_ZEROBYTES, _cn_client, 32); memcpy (cookie_plaintext + crypto_secretbox_ZEROBYTES + 32, _cn_secret, 32); // Generate fresh cookie key randombytes (_cookie_key, crypto_secretbox_KEYBYTES); // Encrypt using symmetric cookie key int rc = crypto_secretbox (cookie_ciphertext, cookie_plaintext, sizeof cookie_plaintext, cookie_nonce, _cookie_key); zmq_assert (rc == 0); uint8_t welcome_nonce[crypto_box_NONCEBYTES]; uint8_t welcome_plaintext[crypto_box_ZEROBYTES + 128]; uint8_t welcome_ciphertext[crypto_box_BOXZEROBYTES + 144]; // Create full nonce for encryption // 8-byte prefix plus 16-byte random nonce memcpy (welcome_nonce, "WELCOME-", 8); randombytes (welcome_nonce + 8, crypto_box_NONCEBYTES - 8); // Create 144-byte Box [S' + cookie](S->C') memset (welcome_plaintext, 0, crypto_box_ZEROBYTES); memcpy (welcome_plaintext + crypto_box_ZEROBYTES, _cn_public, 32); memcpy (welcome_plaintext + crypto_box_ZEROBYTES + 32, cookie_nonce + 8, 16); memcpy (welcome_plaintext + crypto_box_ZEROBYTES + 48, cookie_ciphertext + crypto_secretbox_BOXZEROBYTES, 80); rc = crypto_box (welcome_ciphertext, welcome_plaintext, sizeof welcome_plaintext, welcome_nonce, _cn_client, _secret_key); // TODO I think we should change this back to zmq_assert (rc == 0); // as it was before https://github.com/zeromq/libzmq/pull/1832 // The reason given there was that secret_key might be 0ed. // But if it were, we would never get this far, since we could // not have opened the client's hello box with a 0ed key. if (rc == -1) return -1; rc = msg_->init_size (168); errno_assert (rc == 0); uint8_t *const welcome = static_cast<uint8_t *> (msg_->data ()); memcpy (welcome, "\x07WELCOME", 8); memcpy (welcome + 8, welcome_nonce + 8, 16); memcpy (welcome + 24, welcome_ciphertext + crypto_box_BOXZEROBYTES, 144); return 0; }