int
ntruees439ep1_encrypt(const ntruees439ep1_public_key_t *pk,
                      const size_t msg_len,
                      const uint8_t *msg,
                      ntruees439ep1_ciphertext_t *ct)
{
  DRBG_HANDLE drbg;
  uint16_t    ct_len;
  uint32_t    rc;

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

  /* Ensure this encrypt routine outputs NTRUEES439EP1_CIPHERTEXT_LEN bytes */
  rc = ntru_crypto_ntru_encrypt(drbg, NTRUEES439EP1_PUBKEY_LEN, pk->public_key,
                                0, NULL, &ct_len, NULL);
  if(rc != NTRU_OK || ct_len != NTRUEES439EP1_CIPHERTEXT_LEN)
  {
    ntru_crypto_drbg_uninstantiate(drbg);
    return 1;
  }

  rc = ntru_crypto_ntru_encrypt(drbg, NTRUEES439EP1_PUBKEY_LEN, pk->public_key,
                                msg_len, msg, &ct_len, ct->ciphertext);
  if(rc != NTRU_OK)
  {
    ntru_crypto_drbg_uninstantiate(drbg);
    return 1;
  }

  ntru_crypto_drbg_uninstantiate(drbg);
  return 0;
}
Example #2
0
int
main(void)
{
    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 */
    uint16_t drbg_strength;

    NTRU_ENCRYPT_PARAM_SET_ID param_set_ids[] = {
      NTRU_EES401EP1, NTRU_EES449EP1, NTRU_EES677EP1, NTRU_EES1087EP2,
      NTRU_EES541EP1, NTRU_EES613EP1, NTRU_EES887EP1, NTRU_EES1171EP1,
      NTRU_EES659EP1, NTRU_EES761EP1, NTRU_EES1087EP1, NTRU_EES1499EP1,
      NTRU_EES401EP2, NTRU_EES439EP1, NTRU_EES593EP1, NTRU_EES743EP1
    };
    NTRU_ENCRYPT_PARAM_SET_ID param_set_id;

    uint32_t error[(sizeof(param_set_ids)/sizeof(param_set_id))] = {0};

    for(i=0; i<(sizeof(param_set_ids)/sizeof(param_set_id)); i++)
    {
      param_set_id = param_set_ids[i];
      fprintf(stderr, "Testing parameter set %s\n", ntru_encrypt_get_param_set_name(param_set_id));

      drbg_strength = 256;
      rc = ntru_crypto_drbg_instantiate(drbg_strength, NULL, 0,
                                        (ENTROPY_FN) &get_entropy, &drbg);
      if (rc != DRBG_OK)
      {
        fprintf(stderr,"\tError: An error occurred instantiating the DRBG\n");
        error[i] = 1;
        continue;
      }

      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;
      }

      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;
      }

      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;
      }

      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;
      }

      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));

      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: Decrypted plaintext does not match original plaintext\n");
          error[i] = 1;
          break;
        }
      }

      ntru_crypto_drbg_uninstantiate(drbg);
      free(message);
      free(public_key);
      free(private_key);
      free(plaintext);
      free(ciphertext);
    }

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

    fprintf(stderr, "Result: Pass\n");
    return 0;
}
Example #3
0
void bench_ntru(void)
{
    int    i;
    double start, total, each, milliEach;

    byte   public_key[557];
    word16 public_key_len = sizeof(public_key);
    byte   private_key[607];
    word16 private_key_len = sizeof(private_key);

    byte ciphertext[552];
    word16 ciphertext_len;
    byte plaintext[16];
    word16 plaintext_len;

    DRBG_HANDLE drbg;
    static byte const aes_key[] = {
        0xf3, 0xe9, 0x87, 0xbb, 0x18, 0x08, 0x3c, 0xaa,
        0x7b, 0x12, 0x49, 0x88, 0xaf, 0xb3, 0x22, 0xd8
    };

    static byte const cyasslStr[] = {
        'C', 'y', 'a', 'S', 'S', 'L', ' ', 'N', 'T', 'R', 'U'
    };

    word32 rc = ntru_crypto_drbg_instantiate(112, cyasslStr, sizeof(cyasslStr),
                                            (ENTROPY_FN) GetEntropy, &drbg);
    if(rc != DRBG_OK) {
        printf("NTRU drbg instantiate failed\n");
        return;
    }

    rc = ntru_crypto_ntru_encrypt_keygen(drbg, NTRU_EES401EP2, 
        &public_key_len, NULL, &private_key_len, NULL);
    if (rc != NTRU_OK) {
        ntru_crypto_drbg_uninstantiate(drbg);
        printf("NTRU failed to get key lengths\n");
        return;
    }

    rc = ntru_crypto_ntru_encrypt_keygen(drbg, NTRU_EES401EP2, &public_key_len,
                                     public_key, &private_key_len, 
                                     private_key);

    ntru_crypto_drbg_uninstantiate(drbg);

    if (rc != NTRU_OK) {
        ntru_crypto_drbg_uninstantiate(drbg);
        printf("NTRU keygen failed\n");
        return;
    }

    rc = ntru_crypto_drbg_instantiate(112, NULL, 0, (ENTROPY_FN)GetEntropy,
                                      &drbg);
    if (rc != DRBG_OK) {
        printf("NTRU error occurred during DRBG instantiation\n");
        return;
    }

    rc = ntru_crypto_ntru_encrypt(drbg, public_key_len, public_key, sizeof(
        aes_key), aes_key, &ciphertext_len, NULL);

    if (rc != NTRU_OK) {
        printf("NTRU error occurred requesting the buffer size needed\n");
        return;
    }
    start = current_time(1);

    for (i = 0; i < ntimes; i++) {

        rc = ntru_crypto_ntru_encrypt(drbg, public_key_len, public_key, sizeof(
            aes_key), aes_key, &ciphertext_len, ciphertext);

        if (rc != NTRU_OK) {
            printf("NTRU encrypt error\n");
            return;
        }

    }
    rc = ntru_crypto_drbg_uninstantiate(drbg);

    if (rc != DRBG_OK) {
        printf("NTRU error occurred uninstantiating the DRBG\n");
        return;
    }

    total = current_time(0) - start;
    each  = total / ntimes;   /* per second   */
    milliEach = each * 1000; /* milliseconds */

    printf("NTRU 112 encryption took %6.3f milliseconds, avg over %d"
           " iterations\n", milliEach, ntimes);


    rc = ntru_crypto_ntru_decrypt(private_key_len, private_key, ciphertext_len,
                                  ciphertext, &plaintext_len, NULL);

    if (rc != NTRU_OK) {
        printf("NTRU decrypt error occurred getting the buffer size needed\n");
        return;
    }

    plaintext_len = sizeof(plaintext);
    start = current_time(1);

    for (i = 0; i < ntimes; i++) {
        rc = ntru_crypto_ntru_decrypt(private_key_len, private_key,
                                      ciphertext_len, ciphertext,
                                      &plaintext_len, plaintext);

        if (rc != NTRU_OK) {
            printf("NTRU error occurred decrypting the key\n");
            return;
        }
    }

    total = current_time(0) - start;
    each  = total / ntimes;   /* per second   */
    milliEach = each * 1000; /* milliseconds */

    printf("NTRU 112 decryption took %6.3f milliseconds, avg over %d"
           " iterations\n", milliEach, ntimes);
}
Example #4
0
/* 
 *
 * This sample code will:
 *   1) generate a public-key pair for the EES401EP2 parameter set
 *   2) DER-encode the public key for storage in a certificate
 *   3) DER-decode the public key from a certificate for use
 *   4) encrypt a 128-bit AES key
 *   5) decrypt the 128-bit AES key
 */
static int __init ntru_init_module(void)
{
    uint8_t public_key[557];          /* sized for EES401EP2 */
    uint16_t public_key_len;          /* no. of octets in public key */
    uint8_t private_key[607];         /* sized for EES401EP2 */
    uint16_t private_key_len;         /* no. of octets in private key */
    uint8_t encoded_public_key[591];  /* sized for EES401EP2 */
    uint16_t encoded_public_key_len;  /* no. of octets in encoded public key */
    uint8_t ciphertext[552];          /* sized fof EES401EP2 */
    uint16_t ciphertext_len;          /* no. of octets in ciphertext */
    uint8_t plaintext[16];            /* size of AES-128 key */
    uint16_t plaintext_len;           /* no. of octets in plaintext */
    uint8_t *next = NULL;             /* points to next cert field to parse */
    DRBG_HANDLE drbg;                 /* handle for instantiated DRBG */
    uint32_t rc;                      /* return code */
    bool error = FALSE;               /* records if error occurred */

    /* Instantiate a DRBG with 112-bit security strength for key generation
     * to match the security strength of the EES401EP2 parameter set.
     * Here we've chosen to use the personalization string.
     */
    rc = ntru_crypto_drbg_instantiate(112, pers_str, sizeof(pers_str),
                                      (ENTROPY_FN) &get_entropy, &drbg);
    if (rc != DRBG_OK)
        /* An error occurred during DRBG instantiation. */
        return 1;

    printk(KERN_DEBUG "DRBG at 112-bit security for key generation instantiated successfully.\n");


    /* Let's find out how large a buffer we need for the public and private
     * keys.
     */
    rc = ntru_crypto_ntru_encrypt_keygen(drbg, NTRU_EES401EP2, &public_key_len,
                                         NULL, &private_key_len, NULL);
    if (rc != NTRU_OK)
        /* An error occurred requesting the buffer sizes needed. */
        return 1;
    printk(KERN_DEBUG "Public-key buffer size required: %d octets.\n", public_key_len);
    printk(KERN_DEBUG "Private-key buffer size required: %d octets.\n", private_key_len);


    /* Now we could allocate a buffer of length public_key_len to hold the
     * public key, and a buffer of length private_key_len to hold the private
     * key, but in this example we already have them as local variables.
     */


    /* Generate a key pair for EES401EP2.
     * We must set the public-key length to the size of the buffer we have
     * for the public key, and similarly for the private-key length.
     * We've already done this by getting the sizes from the previous call
     * to ntru_crypto_ntru_encrypt_keygen() above.
     */
    rc = ntru_crypto_ntru_encrypt_keygen(drbg, NTRU_EES401EP2, &public_key_len,
                                         public_key, &private_key_len,
                                         private_key);
    if (rc != NTRU_OK)
        /* An error occurred during key generation. */
        error = TRUE;
    printk(KERN_DEBUG "Key-pair for NTRU_EES401EP2 generated successfully.\n");


    /* Uninstantiate the DRBG. */
    rc = ntru_crypto_drbg_uninstantiate(drbg);
    if ((rc != DRBG_OK) || error)
        /* An error occurred uninstantiating the DRBG, or generating keys. */
        return 1;
    printk(KERN_DEBUG "Key-generation DRBG uninstantiated successfully.\n");


    /* Let's find out how large a buffer we need for holding a DER-encoding
     * of the public key.
     */
    rc = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo(
            public_key_len, public_key, &encoded_public_key_len, NULL);
    if (rc != NTRU_OK)
        /* An error occurred requesting the buffer size needed. */
        return 1;
    printk(KERN_DEBUG "DER-encoded public-key buffer size required: %d octets.\n",
            encoded_public_key_len);


    /* Now we could allocate a buffer of length encoded_public_key_len to
     * hold the encoded public key, but in this example we already have it
     * as a local variable.
     */


    /* DER-encode the public key for inclusion in a certificate.
     * This creates a SubjectPublicKeyInfo field from a public key.
     * We must set the encoded public-key length to the size of the buffer
     * we have for the encoded public key.
     * We've already done this by getting the size from the previous call
     * to ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKey() above.
     */
    rc = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo(
            public_key_len, public_key, &encoded_public_key_len,
            encoded_public_key);
    printk(KERN_DEBUG "Public key DER-encoded for SubjectPublicKeyInfo successfully.\n");


    /* Now suppose we are parsing a certificate so we can use the
     * public key it contains, and the next field is the SubjectPublicKeyInfo
     * field.  This is indicated by the "next" pointer.  We'll decode this
     * field to retrieve the public key so we can use it for encryption.
     * First let's find out how large a buffer we need for holding the
     * DER-decoded public key.
     */
    next = encoded_public_key;          /* the next pointer will be pointing
                                           to the SubjectPublicKeyInfo field */
    rc = ntru_crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(next,
            &public_key_len, NULL, &next);
    if (rc != NTRU_OK)
        /* An error occurred requesting the buffer size needed. */
        return 1;
    printk(KERN_DEBUG "Public-key buffer size required: %d octets.\n", public_key_len);


    /* Now we could allocate a buffer of length public_key_len to hold the
     * decoded public key, but in this example we already have it as a
     * local variable.
     */


    /* Decode the SubjectPublicKeyInfo field.  Note that if successful,
     * the "next" pointer will now point to the next field following
     * the SubjectPublicKeyInfo field.
     */
    rc = ntru_crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(next,
            &public_key_len, public_key, &next);
    if (rc != NTRU_OK)
        /* An error occurred decoding the SubjectPublicKeyInfo field.
         * This could indicate that the field is not a valid encoding
         * of an NTRUEncrypt public key.
         */
        return 1;
    printk(KERN_DEBUG "Public key decoded from SubjectPublicKeyInfo successfully.\n");


    /* We need to instantiate a DRBG with 112-bit security strength for
     * encryption to match the security strength of the EES401EP2 parameter
     * set that we generated keys for.
     * Here we've chosen not to use the personalization string.
     */
    rc = ntru_crypto_drbg_instantiate(112, NULL, 0, (ENTROPY_FN) &get_entropy,
                                      &drbg);
    if (rc != DRBG_OK)
        /* An error occurred during DRBG instantiation. */
        return 1;
    printk(KERN_DEBUG "DRBG at 112-bit security for encryption instantiated "
            "successfully.\n");


    /* Now that we have the public key from the certificate, we'll use
     * it to encrypt an AES-128 key.
     * First let's find out how large a buffer we need for holding the
     * ciphertext.
     */
    rc = ntru_crypto_ntru_encrypt(drbg, public_key_len, public_key,
                                  sizeof(aes_key), aes_key, &ciphertext_len,
                                  NULL);
    if (rc != NTRU_OK)
        /* An error occurred requesting the buffer size needed. */
        return 1;
    printk(KERN_DEBUG "Ciphertext buffer size required: %d octets.\n", ciphertext_len);


    /* Now we could allocate a buffer of length ciphertext_len to hold the
     * ciphertext, but in this example we already have it as a local variable.
     */


    /* Encrypt the AES-128 key.
     * We must set the ciphertext length to the size of the buffer we have
     * for the ciphertext.
     * We've already done this by getting the size from the previous call
     * to ntru_crypto_ntru_encrypt() above.
     */
     rc = ntru_crypto_ntru_encrypt(drbg, public_key_len, public_key,
                                   sizeof(aes_key), aes_key, &ciphertext_len,
                                   ciphertext);
     if (rc != NTRU_OK)
         /* An error occurred encrypting the AES-128 key. */
         error = TRUE;
     printk(KERN_DEBUG "AES-128 key encrypted successfully.\n");


    /* Uninstantiate the DRBG. */
    rc = ntru_crypto_drbg_uninstantiate(drbg);
    if ((rc != DRBG_OK) || error)
        /* An error occurred uninstantiating the DRBG, or encrypting. */
        return 1;
    printk(KERN_DEBUG "Encryption DRBG uninstantiated successfully.\n");


     /* We've received ciphertext, and want to decrypt it.
      * We can find out the maximum plaintext size as follows.
      */
    rc = ntru_crypto_ntru_decrypt(private_key_len, private_key, ciphertext_len,
                                  ciphertext, &plaintext_len, NULL);
    if (rc != NTRU_OK)
        /* An error occurred requesting the buffer size needed. */
        return 1;
    printk(KERN_DEBUG "Maximum plaintext buffer size required: %d octets.\n",
            plaintext_len);

    /* Now we could allocate a buffer of length plaintext_len to hold the
     * plaintext, but note that plaintext_len has the maximum plaintext
     * size for the EES401EP2 parameter set.  Since we know that we've
     * received an encrypted AES-128 key in this example, and since we
     * already have a plaintext buffer as a local variable, we'll just
     * supply the length of that plaintext buffer for decryption.
     */
    plaintext_len = sizeof(plaintext);
    rc = ntru_crypto_ntru_decrypt(private_key_len, private_key, ciphertext_len,
                                  ciphertext, &plaintext_len, plaintext);
    if (rc != NTRU_OK)
        /* An error occurred decrypting the AES-128 key. */
        return 1;
    printk(KERN_DEBUG "AES-128 key decrypted successfully.\n");
    
    /* And now the plaintext buffer holds the decrypted AES-128 key. */
    printk(KERN_DEBUG "Sample code completed successfully.\n");

    return 0;
}
Example #5
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;
}
Example #6
0
int
main(int argc, char **argv)
{
    int i, j;
    uint8_t *public_key;
    uint8_t *private_key;
    uint8_t *message;
    uint8_t *ciphertext;
    uint8_t *plaintext;

    uint16_t max_msg_len;
    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 */
    uint32_t loops = LOOPS;           /* number of loops when benchmarking */

    clock_t clk;

    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;
      }

      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;
      }

      public_key = (uint8_t *)malloc(public_key_len * sizeof(uint8_t));
      private_key = (uint8_t *)malloc(private_key_len * sizeof(uint8_t));

      clk = clock();
      for (j = 0; j < loops/10 || j < 1; j++)
      {
        rc = ntru_crypto_ntru_encrypt_keygen(drbg, param_set_id, &public_key_len,
                                           public_key,
                                           &private_key_len,
                                           private_key);
        if (rc != NTRU_OK) break;
      }
      clk = clock() - clk;
      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;
      }

      if (loops) {
        fprintf(stderr, "kg %dus, ", (int)((1.0*clk)/(loops/10)));
        fflush (stderr);
      }

      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;
      }

      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;
      }


      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));

      plaintext_len = max_msg_len;
      randombytes(message, max_msg_len);
      randombytes(ciphertext, ciphertext_len);
      randombytes(plaintext, plaintext_len);

      clk = clock();
      for (j = 0; j < loops || j < 1; j++)
      {
        rc = ntru_crypto_ntru_encrypt(drbg, public_key_len, public_key,
              max_msg_len, message, &ciphertext_len, ciphertext);
        if(rc != NTRU_OK) break;
      }
      clk = clock() - clk;
      if (rc != NTRU_OK){
        fprintf(stderr, "\tError: Encryption error %x\n", rc);
        error[i] = 1;
        break;
      }

      if (loops) {
        fprintf(stderr, "e %dus, ", (int)((1.0*clk)/loops));
        fflush (stderr);
      }

      clk = clock();
      for (j = 0; j < loops || j < 1; j++)
      {
        rc = ntru_crypto_ntru_decrypt(private_key_len, private_key,
              ciphertext_len, ciphertext,
              &plaintext_len, plaintext);
        if(rc != NTRU_OK) break;
      }
      clk = clock() - clk;
      if (rc != NTRU_OK)
      {
        fprintf(stderr, "\tError: Decryption error %x\n", rc);
        error[i] = 1;
        break;
      }

      if (loops) {
        fprintf(stderr, "d %dus", (int)((1.0*clk)/loops));
      }

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

      ntru_crypto_drbg_uninstantiate(drbg);
      free(message);
      free(public_key);
      free(private_key);
      free(plaintext);
      free(ciphertext);

      fprintf(stderr, "\t pk %d, sk %d, ct %d bytes",
              public_key_len, private_key_len-public_key_len, ciphertext_len);
      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;
}