int ntruees439ep1_decrypt(const ntruees439ep1_secret_key_t *sk, const ntruees439ep1_ciphertext_t *ct, uint16_t expected_pt_len, uint8_t *pt) { /* We only need to decrypt plaintexts of known size, so allocate * enough space to hold the maximum length, but ensure that the * actual plaintext matches the expected size */ uint8_t pt_buf[NTRUEES439EP1_MAX_PT_LEN]; uint16_t pt_len = NTRUEES439EP1_MAX_PT_LEN; uint32_t rc; rc = ntru_crypto_ntru_decrypt(NTRUEES439EP1_SECKEY_LEN, sk->secret_key, NTRUEES439EP1_CIPHERTEXT_LEN, ct->ciphertext, &pt_len, pt_buf); if (rc != NTRU_OK || pt_len != expected_pt_len) { return 1; } memcpy(pt, pt_buf, expected_pt_len); return 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; }
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); }
/* * * 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; }
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; }
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; }