void bench_ntruKeyGen(void) { double start, total, each, milliEach; int i; byte public_key[557]; /* 2048 key equivalent to rsa */ word16 public_key_len = sizeof(public_key); byte private_key[607]; word16 private_key_len = sizeof(private_key); DRBG_HANDLE drbg; static uint8_t const pers_str[] = { 'C', 'y', 'a', 'S', 'S', 'L', ' ', 't', 'e', 's', 't' }; word32 rc = ntru_crypto_drbg_instantiate(112, pers_str, sizeof(pers_str), GetEntropy, &drbg); if(rc != DRBG_OK) { printf("NTRU drbg instantiate failed\n"); return; } start = current_time(1); for(i = 0; i < genTimes; i++) { ntru_crypto_ntru_encrypt_keygen(drbg, NTRU_EES401EP2, &public_key_len, public_key, &private_key_len, private_key); } total = current_time(0) - start; rc = ntru_crypto_drbg_uninstantiate(drbg); if (rc != NTRU_OK) { printf("NTRU drbg uninstantiate failed\n"); return; } each = total / genTimes; milliEach = each * 1000; printf("\n"); printf("NTRU 112 key generation %6.3f milliseconds, avg over %d" " iterations\n", milliEach, genTimes); }
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; }