Ejemplo n.º 1
0
int
main(void)
{
    unsigned char *alicepk =
        (unsigned char *) sodium_malloc(crypto_scalarmult_BYTES);
    unsigned char *bobpk =
        (unsigned char *) sodium_malloc(crypto_scalarmult_BYTES);
    unsigned char *k = (unsigned char *) sodium_malloc(crypto_scalarmult_BYTES);
    int            ret;

    assert(alicepk != NULL && bobpk != NULL && k != NULL);

    crypto_scalarmult_base(alicepk, alicesk);
    sodium_bin2hex(hex, sizeof hex, alicepk, crypto_scalarmult_BYTES);
    printf("%s\n", hex);

    crypto_scalarmult_base(bobpk, bobsk);
    sodium_bin2hex(hex, sizeof hex, bobpk, crypto_scalarmult_BYTES);
    printf("%s\n", hex);

    ret = crypto_scalarmult(k, alicesk, bobpk);
    assert(ret == 0);
    sodium_bin2hex(hex, sizeof hex, k, crypto_scalarmult_BYTES);
    printf("%s\n", hex);

    ret = crypto_scalarmult(k, bobsk, alicepk);
    assert(ret == 0);
    sodium_bin2hex(hex, sizeof hex, k, crypto_scalarmult_BYTES);
    printf("%s\n", hex);

    ret = crypto_scalarmult(k, bobsk, small_order_p);
    assert(ret == -1);
    sodium_bin2hex(hex, sizeof hex, k, crypto_scalarmult_BYTES);
    printf("%s\n", hex);

    sodium_free(bobpk);
    sodium_free(alicepk);
    sodium_free(k);

    assert(crypto_scalarmult_bytes() > 0U);
    assert(crypto_scalarmult_scalarbytes() > 0U);
    assert(strcmp(crypto_scalarmult_primitive(), "curve25519") == 0);
    assert(crypto_scalarmult_bytes() == crypto_scalarmult_curve25519_bytes());
    assert(crypto_scalarmult_scalarbytes() ==
           crypto_scalarmult_curve25519_scalarbytes());
    assert(crypto_scalarmult_bytes() == crypto_scalarmult_scalarbytes());

    return 0;
}
Ejemplo n.º 2
0
static nif_term_t
salt_scalarmult_base(nif_heap_t *hp, int argc, const nif_term_t argv[])
{
	/* salt_scalarmult(Integer) -> Group_q. */
	nif_bin_t 		n;
	nif_bin_t 		q;

	if (argc != 1)
		return (BADARG);

	/* Unpack arguments ensuring they're suitably typed. */
	if (! enif_inspect_binary(hp, argv[0], &n))
		return (BADARG);

	/* Check constraints on size. */
	if (n.size != crypto_scalarmult_SCALARBYTES)
		return (BADARG);

	/* Allocate space for plain text. NB: Passing ENOMEM as BADARG. */
	if (! enif_alloc_binary(crypto_scalarmult_BYTES, &q))
		return (BADARG);
	
	crypto_scalarmult_base(q.data, n.data);
	return (enif_make_binary(hp, &q));
}
Ejemplo n.º 3
0
int zmq_curve_public (char *z85_public_key, const char *z85_secret_key)
{
#if defined (ZMQ_HAVE_CURVE)
#   if crypto_box_PUBLICKEYBYTES != 32 \
    || crypto_box_SECRETKEYBYTES != 32
#       error "CURVE encryption library not built correctly"
#   endif

    uint8_t public_key[32];
    uint8_t secret_key[32];

    if (zmq_z85_decode (secret_key, z85_secret_key) == NULL)
        return -1;

    // Return codes are suppressed as none of these can actually fail.
    crypto_scalarmult_base (public_key, secret_key);
    zmq_z85_encode (z85_public_key, public_key, 32);

    return 0;
#else
    (void) z85_public_key, (void) z85_secret_key;
    errno = ENOTSUP;
    return -1;
#endif
}
Ejemplo n.º 4
0
bool unit_test_scalarmult(){
  // Random key values
  uint8_t *random_bytes = malloc(32 * NUM_SCALARMULT * sizeof(uint8_t));
  READ_RANDOM_BYTES(32 * NUM_SCALARMULT, random_bytes);
  // Storage buffers
  uint8_t expected_bytes[32], hacl_bytes[32];
  int a, b;
  bool pass = true;
  for (int i = 0; i < NUM_SCALARMULT; i++){
    b = tweet_crypto_scalarmult_base(expected_bytes, random_bytes + 32 * i);
    b =crypto_scalarmult_base(hacl_bytes, random_bytes + 32 * i);
    a = memcmp(hacl_bytes, expected_bytes, 16 * sizeof (uint8_t));
    if (a != 0){
      pass = false;
      printf("Scalarmult base failed\n");
      break;
    }
  }
  for (int i = 0; i < NUM_SCALARMULT / 2; i++){
    b = tweet_crypto_scalarmult(expected_bytes, random_bytes + 32 * 2 * i, random_bytes + 32 * (2 * i + 1));
    b = crypto_scalarmult(hacl_bytes, random_bytes + 32 * 2 * i, random_bytes + 32 * (2 * i + 1));
    a = memcmp(hacl_bytes, expected_bytes, 16 * sizeof (uint8_t));
    if (a != 0){
      pass = false;
      printf("crypto_scalarmult failed\n");
      break;
    }
  }

  free(random_bytes);

  return pass;
}
Ejemplo n.º 5
0
/** @internal
 * @brief Starts [email protected] key exchange
 */
int ssh_client_curve25519_init(ssh_session_t * session){
  ssh_string_t * client_pubkey;
  int rc;

  rc = buffer_add_u8(session->out_buffer, SSH2_MSG_KEX_ECDH_INIT);
  if (rc < 0) {
      return SSH_ERROR;
  }

  rc = ssh_get_random(session->next_crypto->curve25519_privkey, CURVE25519_PRIVKEY_SIZE, 1);
  if (rc == 0){
	  ssh_set_error(session, SSH_FATAL, "PRNG error");
	  return SSH_ERROR;
  }

  crypto_scalarmult_base(session->next_crypto->curve25519_client_pubkey,
		  session->next_crypto->curve25519_privkey);
  client_pubkey = ssh_string_new(CURVE25519_PUBKEY_SIZE);
  if (client_pubkey == NULL) {
      return SSH_ERROR;
  }
  ssh_string_fill(client_pubkey, session->next_crypto->curve25519_client_pubkey,
		  CURVE25519_PUBKEY_SIZE);
  rc = buffer_add_ssh_string(session->out_buffer,client_pubkey);
  ssh_string_free(client_pubkey);
  if (rc < 0) {
      return SSH_ERROR;
  }

  rc = packet_send(session);

  return rc;
}
Ejemplo n.º 6
0
int
crypto_kx_seed_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES],
                       unsigned char sk[crypto_kx_SECRETKEYBYTES],
                       const unsigned char seed[crypto_kx_SEEDBYTES])
{
    crypto_generichash(sk, crypto_kx_SECRETKEYBYTES,
                       seed, crypto_kx_SEEDBYTES, NULL, 0);
    return crypto_scalarmult_base(pk, sk);
}
Ejemplo n.º 7
0
int
crypto_kx_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES],
                  unsigned char sk[crypto_kx_SECRETKEYBYTES])
{
    COMPILER_ASSERT(crypto_kx_SECRETKEYBYTES == crypto_scalarmult_SCALARBYTES);
    COMPILER_ASSERT(crypto_kx_PUBLICKEYBYTES == crypto_scalarmult_BYTES);

    randombytes_buf(sk, crypto_kx_SECRETKEYBYTES);
    return crypto_scalarmult_base(pk, sk);
}
Ejemplo n.º 8
0
main()
{
  int i;
  crypto_scalarmult_base(alicepk,alicesk);
  for (i = 0;i < 32;++i) {
    if (alicepk[i] != expectedpk[i]) {
      fprintf(stderr, "Incorrect byte at position %d: ",i);
      fprintf(stderr, "expected 0x%x, got 0x%x\n", expectedpk[i], alicepk[i]);
      exit(1);
    }
  }
  fprintf(stderr, "Test passed.\n");
  return 0;
}
Ejemplo n.º 9
0
ClientConfiguration::BackupData ClientConfiguration::fromBackup(QString const& backup, QString const& password) {
	QByteArray decodedBase32 = Base32::decodeBase32Sequence(backup);
	if (decodedBase32.size() != BACKUP_DECODED_BYTES) {
		throw IllegalArgumentException() << "Invalid Backup: Size of decoded Backup String is incorrect (" << decodedBase32.size() << " Bytes instead of " << BACKUP_DECODED_BYTES << " Bytes).";
	}

	unsigned char encryptionKey[BACKUP_ENCRYPTION_KEY_BYTES];
	sodium_memzero(encryptionKey, BACKUP_ENCRYPTION_KEY_BYTES);

	// The pointer to the base32-decoded Backup
	unsigned char* decodedBase32Ptr = reinterpret_cast<unsigned char*>(decodedBase32.data());

	// The Salt used in the PBKDF2 Key Derivation process is embedded in the first 8 bytes of the Backup.
	QByteArray password8Bit = password.toUtf8();
	PKCS5_PBKDF2_HMAC(reinterpret_cast<unsigned char*>(password8Bit.data()), password8Bit.size(), decodedBase32Ptr, BACKUP_SALT_BYTES, BACKUP_KEY_PBKDF_ITERATIONS, BACKUP_ENCRYPTION_KEY_BYTES, encryptionKey);

	unsigned char nonceBytes[crypto_stream_NONCEBYTES];
	sodium_memzero(nonceBytes, crypto_stream_NONCEBYTES);

	crypto_stream_xor(&decodedBase32Ptr[BACKUP_SALT_BYTES], &decodedBase32Ptr[BACKUP_SALT_BYTES], BACKUP_IDENTITY_BYTES + PROTO_KEY_LENGTH_BYTES + BACKUP_HASH_BYTES, nonceBytes, encryptionKey);

	// The last two bytes of the Backup contain the truncated SHA-256 Hash over the identity and its Private Key.
	unsigned char controlHash[crypto_hash_sha256_BYTES];
	sodium_memzero(controlHash, crypto_hash_sha256_BYTES);
	crypto_hash_sha256(controlHash, &(decodedBase32Ptr[BACKUP_SALT_BYTES]), BACKUP_IDENTITY_BYTES + PROTO_KEY_LENGTH_BYTES);

	if (sodium_memcmp(&(decodedBase32Ptr[BACKUP_SALT_BYTES + BACKUP_IDENTITY_BYTES + PROTO_KEY_LENGTH_BYTES]), controlHash, BACKUP_HASH_BYTES) != 0) {
		throw IllegalArgumentException() << "Decryption of Backup failed: Invalid Control Hash (" << controlHash[0] << controlHash[1] << " vs. " << decodedBase32Ptr[BACKUP_SALT_BYTES + BACKUP_IDENTITY_BYTES + PROTO_KEY_LENGTH_BYTES] << decodedBase32Ptr[BACKUP_SALT_BYTES + BACKUP_IDENTITY_BYTES + PROTO_KEY_LENGTH_BYTES + 1] << ").";
	}

	unsigned char derivedPublicKey[PROTO_KEY_LENGTH_BYTES];
	crypto_scalarmult_base(derivedPublicKey, &decodedBase32Ptr[BACKUP_SALT_BYTES + BACKUP_IDENTITY_BYTES]);
	KeyPair kp = KeyPair::fromArrays(derivedPublicKey, &decodedBase32Ptr[BACKUP_SALT_BYTES + BACKUP_IDENTITY_BYTES]);

	QString identityString(QByteArray(reinterpret_cast<char*>(&decodedBase32Ptr[BACKUP_SALT_BYTES]), BACKUP_IDENTITY_BYTES));
	if (!isValidIdentity(identityString)) {
		throw IllegalArgumentException() << "Invalid ClientConfiguration: Decryption of Backup failed: Not a valid Identity.";
	}

	return BackupData(ContactId(identityString.toUtf8()), kp);
}
Ejemplo n.º 10
0
const char *checksum_compute(void)
{
  long long i;
  long long j;
  long long tests;

  for (i = 0;i < mlen;++i) m[i] = i;
  for (i = 0;i < nlen;++i) n[i] = i + 1;
  for (i = 0;i < plen;++i) p[i] = i + 2;
  for (i = 0;i < qlen;++i) q[i] = i + 3;
  for (i = 0;i < rlen;++i) r[i] = i + 4;

  for (i = -16;i < 0;++i) p[i] = rand();
  for (i = -16;i < 0;++i) n[i] = rand();
  for (i = plen;i < plen + 16;++i) p[i] = rand();
  for (i = nlen;i < nlen + 16;++i) n[i] = rand();
  for (i = -16;i < plen + 16;++i) p2[i] = p[i];
  for (i = -16;i < nlen + 16;++i) n2[i] = n[i];

  if (crypto_scalarmult_base(p,n) != 0) return "crypto_scalarmult_base returns nonzero";

  for (i = -16;i < nlen + 16;++i) if (n2[i] != n[i]) return "crypto_scalarmult_base overwrites input";
  for (i = -16;i < 0;++i) if (p2[i] != p[i]) return "crypto_scalarmult_base writes before output";
  for (i = plen;i < plen + 16;++i) if (p2[i] != p[i]) return "crypto_scalarmult_base writes after output";

  for (tests = 0;tests < 100;++tests) {
    for (i = -16;i < 0;++i) q[i] = rand();
    for (i = -16;i < 0;++i) p[i] = rand();
    for (i = -16;i < 0;++i) m[i] = rand();
    for (i = qlen;i < qlen + 16;++i) q[i] = rand();
    for (i = plen;i < plen + 16;++i) p[i] = rand();
    for (i = mlen;i < mlen + 16;++i) m[i] = rand();
    for (i = -16;i < qlen + 16;++i) q2[i] = q[i];
    for (i = -16;i < plen + 16;++i) p2[i] = p[i];
    for (i = -16;i < mlen + 16;++i) m2[i] = m[i];

    if (crypto_scalarmult(q,m,p) != 0) return "crypto_scalarmult returns nonzero";

    for (i = -16;i < mlen + 16;++i) if (m2[i] != m[i]) return "crypto_scalarmult overwrites n input";
    for (i = -16;i < plen + 16;++i) if (p2[i] != p[i]) return "crypto_scalarmult overwrites p input";
    for (i = -16;i < 0;++i) if (q2[i] != q[i]) return "crypto_scalarmult writes before output";
    for (i = qlen;i < qlen + 16;++i) if (q2[i] != q[i]) return "crypto_scalarmult writes after output";

    if (crypto_scalarmult(m2,m2,p) != 0) return "crypto_scalarmult returns nonzero";
    for (i = 0;i < qlen;++i) if (q[i] != m2[i]) return "crypto_scalarmult does not handle n overlap";
    for (i = 0;i < qlen;++i) m2[i] = m[i];

    if (crypto_scalarmult(p2,m2,p2) != 0) return "crypto_scalarmult returns nonzero";
    for (i = 0;i < qlen;++i) if (q[i] != p2[i]) return "crypto_scalarmult does not handle p overlap";

    if (crypto_scalarmult(r,n,q) != 0) return "crypto_scalarmult returns nonzero";
    if (crypto_scalarmult(q,n,p) != 0) return "crypto_scalarmult returns nonzero";
    if (crypto_scalarmult(p,m,q) != 0) return "crypto_scalarmult returns nonzero";
    for (j = 0;j < plen;++j) if (p[j] != r[j]) return "crypto_scalarmult not associative";
    for (j = 0;j < mlen;++j) m[j] ^= q[j % qlen];
    for (j = 0;j < nlen;++j) n[j] ^= p[j % plen];
  }

  sodium_bin2hex(checksum, sizeof checksum, p, crypto_scalarmult_BYTES);

  return 0;
}
Ejemplo n.º 11
0
void doit(void)
{
  crypto_scalarmult(q,n,p);
  crypto_scalarmult_base(r,n);
}
Ejemplo n.º 12
0
/** @brief Parse a SSH_MSG_KEXDH_INIT packet (server) and send a
 * SSH_MSG_KEXDH_REPLY
 */
int ssh_server_curve25519_init(ssh_session_t * session, ssh_buffer_t * packet){
    /* ECDH keys */
    ssh_string_t * q_c_string;
    ssh_string_t * q_s_string;

    /* SSH host keys (rsa,dsa,ecdsa) */
    ssh_key_t * privkey;
    ssh_string_t * sig_blob = NULL;
    int rc;

    /* Extract the client pubkey from the init packet */
    q_c_string = buffer_get_ssh_string(packet);
    if (q_c_string == NULL) {
        ssh_set_error(session,SSH_FATAL, "No Q_C ECC point in packet");
        return SSH_ERROR;
    }
    if (ssh_string_len(q_c_string) != CURVE25519_PUBKEY_SIZE){
    	ssh_set_error(session, SSH_FATAL, "Incorrect size for server Curve25519 public key: %d",
    			(int)ssh_string_len(q_c_string));
    	ssh_string_free(q_c_string);
    	return SSH_ERROR;
    }

    memcpy(session->next_crypto->curve25519_client_pubkey,
    		ssh_string_data(q_c_string), CURVE25519_PUBKEY_SIZE);
    ssh_string_free(q_c_string);
    /* Build server's keypair */

    rc = ssh_get_random(session->next_crypto->curve25519_privkey, CURVE25519_PRIVKEY_SIZE, 1);
    if (rc == 0){
        ssh_set_error(session, SSH_FATAL, "PRNG error");
        return SSH_ERROR;
    }

    crypto_scalarmult_base(session->next_crypto->curve25519_server_pubkey,
  		  session->next_crypto->curve25519_privkey);

    rc = buffer_add_u8(session->out_buffer, SSH2_MSG_KEX_ECDH_REPLY);
    if (rc < 0) {
        ssh_set_error_oom(session);
        goto error;
    }

    /* build k and session_id */
    rc = ssh_curve25519_build_k(session);
    if (rc < 0) {
        ssh_set_error(session, SSH_FATAL, "Cannot build k number");
        goto error;
    }

    /* privkey is not allocated */
    rc = ssh_get_key_params(session, &privkey);
    if (rc == SSH_ERROR) {
        goto error;
    }

    rc = make_sessionid(session);
    if (rc != SSH_OK) {
        ssh_set_error(session, SSH_FATAL, "Could not create a session id");
        goto error;
    }

    /* add host's public key */
    rc = buffer_add_ssh_string(session->out_buffer,
                               session->next_crypto->server_pubkey);
    if (rc < 0) {
        ssh_set_error_oom(session);
        goto error;
    }

    /* add ecdh public key */
    q_s_string = ssh_string_new(CURVE25519_PUBKEY_SIZE);
    if (q_s_string == NULL) {
        goto error;
    }

    ssh_string_fill(q_s_string,
                    session->next_crypto->curve25519_server_pubkey,
                    CURVE25519_PUBKEY_SIZE);

    rc = buffer_add_ssh_string(session->out_buffer, q_s_string);
    ssh_string_free(q_s_string);
    if (rc < 0) {
        ssh_set_error_oom(session);
        goto error;
    }
    /* add signature blob */
    sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey);
    if (sig_blob == NULL) {
        ssh_set_error(session, SSH_FATAL, "Could not sign the session id");
        goto error;
    }

    rc = buffer_add_ssh_string(session->out_buffer, sig_blob);
    ssh_string_free(sig_blob);
    if (rc < 0) {
        ssh_set_error_oom(session);
        goto error;
    }

    SSH_INFO(SSH_LOG_PROTOCOL, "SSH_MSG_KEX_ECDH_REPLY sent");
    rc = packet_send(session);
    if (rc == SSH_ERROR) {
        return SSH_ERROR;
    }

    /* Send the MSG_NEWKEYS */
    rc = buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS);
    if (rc < 0) {
        goto error;
    }

    session->dh_handshake_state = DH_STATE_NEWKEYS_SENT;
    rc = packet_send(session);
    SSH_INFO(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent");

    return rc;
error:
    buffer_reinit(session->out_buffer);
    return SSH_ERROR;
}