int
ntruees439ep1_keypair_generate(ntruees439ep1_public_key_t *pk,
                               ntruees439ep1_secret_key_t *sk)
{
  DRBG_HANDLE drbg;
  uint16_t    pk_len;
  uint16_t    sk_len;
  uint32_t    rc;

  rc = ntru_crypto_external_drbg_instantiate((RANDOM_BYTES_FN)&randombytes, &drbg);
  if (rc != DRBG_OK)
  {
    return 1;
  }

  /* Check that our implementation really supports ees439ep1 */
  rc = ntru_crypto_ntru_encrypt_keygen(drbg, NTRU_EES439EP1, &pk_len,
                                       NULL, &sk_len, NULL);
  if (rc != NTRU_OK)
  {
    ntru_crypto_drbg_uninstantiate(drbg);
    return 1;
  }

  if(pk_len != NTRUEES439EP1_PUBKEY_LEN || sk_len != NTRUEES439EP1_SECKEY_LEN)
  {
    ntru_crypto_drbg_uninstantiate(drbg);
    return 1;
  }

  /* Generate a key */
  do
  {
    rc = ntru_crypto_ntru_encrypt_keygen(drbg, NTRU_EES439EP1,
                                         &pk_len, pk->public_key,
                                         &sk_len, sk->secret_key);
    /* NTRU_FAIL signals that we should try again */
  } while(rc == NTRU_RESULT(NTRU_FAIL));
  /* For other errors we should abort */
  if (rc != NTRU_OK)
  {
    ntru_crypto_drbg_uninstantiate(drbg);
    return 1;
  }

  ntru_crypto_drbg_uninstantiate(drbg);
  return 0;
}
Ejemplo n.º 2
0
int
main(int argc, char **argv)
{
    int i;
    uint8_t *public_key;
    uint8_t *private_key;
    uint8_t *message;
    uint8_t *ciphertext;
    uint8_t *plaintext;

    uint16_t max_msg_len;
    uint16_t mlen;
    uint16_t public_key_len;          /* no. of octets in public key */
    uint16_t private_key_len;         /* no. of octets in private key */
    uint16_t ciphertext_len;          /* no. of octets in ciphertext */
    uint16_t plaintext_len;           /* no. of octets in plaintext */
    DRBG_HANDLE drbg;                 /* handle for instantiated DRBG */
    uint32_t rc;                      /* return code */

    NTRU_ENCRYPT_PARAM_SET_ID param_set_id;

    uint32_t error[NUM_PARAM_SETS] = {0};

    for(i=0; i<NUM_PARAM_SETS; i++)
    {
      param_set_id = PARAM_SET_IDS[i];
      fprintf(stderr, "Testing parameter set %s... ",
          ntru_encrypt_get_param_set_name(param_set_id));
      fflush (stderr);

      rc = ntru_crypto_drbg_external_instantiate(
                                        (RANDOM_BYTES_FN) &randombytes, &drbg);

      if (rc != DRBG_OK)
      {
        fprintf(stderr,"\tError: An error occurred instantiating the DRBG\n");
        error[i] = 1;
        continue;
      }

      /* Get public/private key lengths */
      rc = ntru_crypto_ntru_encrypt_keygen(drbg, param_set_id, &public_key_len,
                                           NULL, &private_key_len, NULL);
      if (rc != NTRU_OK)
      {
        ntru_crypto_drbg_uninstantiate(drbg);
        fprintf(stderr,"\tError: An error occurred getting the key lengths\n");
        error[i] = 1;
        continue;
      }

      /* Generate a key */
      public_key = (uint8_t *)malloc(public_key_len * sizeof(uint8_t));
      private_key = (uint8_t *)malloc(private_key_len * sizeof(uint8_t));
      rc = ntru_crypto_ntru_encrypt_keygen(drbg, param_set_id, &public_key_len,
                                         public_key,
                                         &private_key_len,
                                         private_key);
      if (rc != NTRU_OK)
      {
        ntru_crypto_drbg_uninstantiate(drbg);
        free(public_key);
        free(private_key);
        fprintf(stderr,"\tError: An error occurred during key generation\n");
        error[i] = 1;
        continue;
      }

      /* Check public key validity and get maximum ciphertext length */
      rc = ntru_crypto_ntru_encrypt(drbg, public_key_len, public_key, 0, NULL,
                                    &ciphertext_len, NULL);
      if (rc != NTRU_OK)
      {
        fprintf(stderr,"\tError: Bad public key");
        error[i] = 1;
        continue;
      }

      /* Check private key validity and get maximum plaintext length */
      rc = ntru_crypto_ntru_decrypt(private_key_len, private_key, 0, NULL,
                                    &max_msg_len, NULL);
      if (rc != NTRU_OK)
      {
        fprintf(stderr,"\tError: Bad private key");
        error[i] = 1;
        continue;
      }

      /* Allocate memory for plaintexts/ciphertexts */
      message = (uint8_t *) malloc(max_msg_len * sizeof(uint8_t));
      ciphertext = (uint8_t *) malloc(ciphertext_len * sizeof(uint8_t));
      plaintext = (uint8_t *) malloc(max_msg_len * sizeof(uint8_t));

      /* Encrypt/decrypt at every valid message length */
      for(mlen=0; mlen<=max_msg_len; mlen++)
      {
        plaintext_len = max_msg_len;
        randombytes(message, mlen);
        randombytes(ciphertext, ciphertext_len);
        randombytes(plaintext, plaintext_len);

        rc = ntru_crypto_ntru_encrypt(drbg, public_key_len, public_key,
              mlen, message, &ciphertext_len, ciphertext);
        if (rc != NTRU_OK){
          fprintf(stderr, "\tError: Encryption error %x\n", rc);
          error[i] = 1;
          break;
        }

        rc = ntru_crypto_ntru_decrypt(private_key_len, private_key,
              ciphertext_len, ciphertext,
              &plaintext_len, plaintext);
        if (rc != NTRU_OK)
        {
          fprintf(stderr, "\tError: Decryption error %x\n", rc);
          error[i] = 1;
          break;
        }

        if(plaintext_len != mlen || memcmp(plaintext,message,mlen))
        {
          fprintf(stderr,
            "\tError: Decryption result does not match original plaintext\n");
          error[i] = 1;
          break;
        }
      }

      /* Try decrypting junk */
      randombytes(ciphertext, ciphertext_len);
      rc = ntru_crypto_ntru_decrypt(private_key_len, private_key,
            ciphertext_len, ciphertext,
            &plaintext_len, plaintext);
      if (rc != NTRU_RESULT(NTRU_FAIL))
      {
        fprintf(stderr, "\tError: Accepted junk ciphertext\n");
        error[i] = 1;
        break;
      }

      ntru_crypto_drbg_uninstantiate(drbg);
      free(message);
      free(public_key);
      free(private_key);
      free(plaintext);
      free(ciphertext);
      fprintf(stderr, "\n");
    }

    for(i=0; i<NUM_PARAM_SETS; i++) {
      if(error[i]) {
        fprintf(stderr, "Result: Fail\n");
        return 1;
      }
    }

    fprintf(stderr, "Result: Pass\n");
    return 0;
}