209 lines
6.7 KiB
C
209 lines
6.7 KiB
C
|
#include <stdio.h>
|
||
|
#include <time.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <unistd.h>
|
||
|
#include <fcntl.h>
|
||
|
#include "ntru_crypto.h"
|
||
|
#include "ntru_crypto_drbg.h"
|
||
|
|
||
|
//typedef uint32_t (*urnd)(uint8_t *out, uint32_t num_bytes);
|
||
|
static uint8_t const aes_key[] = "Decr";
|
||
|
uint32_t get_rand(uint8_t *out, uint32_t num_bytes)
|
||
|
{
|
||
|
int rng = 50;
|
||
|
int urnd = open("/dev/random", O_RDONLY);
|
||
|
read(urnd, &rng, sizeof(int));
|
||
|
*out = urnd;
|
||
|
close(urnd);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int main(void) {
|
||
|
|
||
|
|
||
|
//uint8_t public_key[557];
|
||
|
double cpu_time_used;
|
||
|
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 */
|
||
|
uint16_t expected_private_key_len;
|
||
|
uint16_t expected_encoded_public_key_len;
|
||
|
uint8_t encoded_public_key[593]; /* 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 */
|
||
|
uint32_t next_len; /* no. of octets it next */
|
||
|
DRBG_HANDLE drbg; /* handle for instantiated DRBG */
|
||
|
uint32_t rc; /* return code */
|
||
|
bool error = FALSE; /* records if error occurred */
|
||
|
FILE *Handle=NULL; /* File Handle for writing NTRU key to file */
|
||
|
clock_t time_s, time_e;
|
||
|
|
||
|
rc = ntru_crypto_drbg_external_instantiate(&get_rand, &drbg);
|
||
|
|
||
|
if (rc != DRBG_OK)
|
||
|
goto error;
|
||
|
|
||
|
rc = ntru_crypto_ntru_encrypt_keygen(drbg, NTRU_EES401EP2, &public_key_len, NULL, &private_key_len, NULL);
|
||
|
|
||
|
if (rc != NTRU_OK)
|
||
|
{
|
||
|
error = TRUE;
|
||
|
}
|
||
|
|
||
|
expected_private_key_len=private_key_len;
|
||
|
time_s = clock();
|
||
|
rc = ntru_crypto_ntru_encrypt_keygen(drbg, NTRU_EES401EP2, &public_key_len, public_key, &private_key_len, private_key);
|
||
|
time_e = clock();
|
||
|
|
||
|
if (rc != NTRU_OK)
|
||
|
error = TRUE;
|
||
|
|
||
|
if (expected_private_key_len!=private_key_len)
|
||
|
{
|
||
|
fprintf(stderr, "PRivate key length is different\n");
|
||
|
error = TRUE;
|
||
|
}
|
||
|
|
||
|
printf("Key sucessfully generated. \n");
|
||
|
|
||
|
rc = ntru_crypto_drbg_uninstantiate(drbg);
|
||
|
if ((rc != DRBG_OK) || error)
|
||
|
{
|
||
|
error = TRUE;
|
||
|
}
|
||
|
|
||
|
printf("KEY DRBG Success. \n");
|
||
|
|
||
|
Handle=fopen("Nino-ntru-key.raw","wb");
|
||
|
if (Handle!=NULL){
|
||
|
printf("Writing Pirvatkey\n");
|
||
|
fwrite(private_key, private_key_len, 1, Handle);
|
||
|
fclose(Handle);
|
||
|
}
|
||
|
Handle=fopen("Nino-ntru-pubkey.raw","wb");
|
||
|
if(Handle!=NULL){
|
||
|
printf("Writing Publickey\n");
|
||
|
printf("Public Key : \n %s\n", public_key);
|
||
|
fwrite(public_key, public_key_len, 1, Handle);
|
||
|
fclose(Handle);
|
||
|
}
|
||
|
|
||
|
rc = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo(public_key_len, public_key, &encoded_public_key_len, NULL);
|
||
|
if (rc != NTRU_OK)
|
||
|
goto error;
|
||
|
printf("DER encoded, sized requierd %d . \n", encoded_public_key_len);
|
||
|
expected_encoded_public_key_len = encoded_public_key_len;
|
||
|
rc = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo(public_key_len, public_key, &encoded_public_key_len, encoded_public_key);
|
||
|
|
||
|
if (expected_encoded_public_key_len!=encoded_public_key_len)
|
||
|
{
|
||
|
fprintf(stderr, "Different encoded pub key detected\n");
|
||
|
error = TRUE;
|
||
|
}
|
||
|
|
||
|
next = encoded_public_key;
|
||
|
next_len = encoded_public_key_len;
|
||
|
rc = ntru_crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(next, &public_key_len, NULL, &next, &next_len);
|
||
|
|
||
|
if (rc != NTRU_OK)
|
||
|
goto error;
|
||
|
printf("Pub key buffer must %d\n", public_key_len);
|
||
|
|
||
|
rc = ntru_crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(next, &public_key_len, public_key, &next, &next_len);
|
||
|
|
||
|
if (rc != NTRU_OK)
|
||
|
goto error;
|
||
|
|
||
|
printf("Pub DER Encoding success\n");
|
||
|
|
||
|
printf("Encryption Phase \n");
|
||
|
rc = ntru_crypto_drbg_external_instantiate(&get_rand, &drbg);
|
||
|
|
||
|
if (rc != DRBG_OK)
|
||
|
goto error;
|
||
|
printf("Sucess encrypt\n");
|
||
|
rc = ntru_crypto_ntru_encrypt(drbg, public_key_len, public_key, sizeof(aes_key), aes_key, &ciphertext_len, NULL);
|
||
|
|
||
|
if (rc != NTRU_OK)
|
||
|
goto error;
|
||
|
printf("String to be encrypted: %s\n", aes_key);
|
||
|
|
||
|
rc = ntru_crypto_ntru_encrypt(drbg, public_key_len, public_key, sizeof(aes_key), aes_key, &ciphertext_len, ciphertext);
|
||
|
|
||
|
if (rc != NTRU_OK)
|
||
|
goto error;
|
||
|
//printf("Ciphertext : %s\n", ciphertext);
|
||
|
rc = ntru_crypto_drbg_uninstantiate(drbg);
|
||
|
printf("Done BLyat!!!!\n");
|
||
|
|
||
|
if (rc != NTRU_OK)
|
||
|
goto error;
|
||
|
|
||
|
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. */
|
||
|
goto error;
|
||
|
printf("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)
|
||
|
{
|
||
|
fprintf(stderr,"Error: An error occurred decrypting the AES-128 key.\n");
|
||
|
return 1;
|
||
|
}
|
||
|
printf("AES-128 key decrypted successfully.\n");
|
||
|
printf("Decoded plaintext length: %d octets\n",plaintext_len);
|
||
|
|
||
|
if(plaintext_len!=sizeof(aes_key))
|
||
|
{
|
||
|
fprintf(stderr,"Error: Decrypted length does not match original plaintext length\n");
|
||
|
return 1;
|
||
|
}
|
||
|
if(memcmp(plaintext,aes_key,sizeof(aes_key)))
|
||
|
{
|
||
|
fprintf(stderr,"Error: Decrypted plaintext does not match original plaintext\n");
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
|
||
|
Handle=fopen("sample-decoded-plaintext.bin","wb");
|
||
|
if(Handle!=NULL)
|
||
|
{
|
||
|
printf("Writing decoded plaintext to decoded-plaintext.bin\n");
|
||
|
printf("Plain text : %s", plaintext);
|
||
|
fwrite(plaintext,plaintext_len,1,Handle);
|
||
|
fclose(Handle);
|
||
|
}
|
||
|
|
||
|
cpu_time_used = (float)(time_e - time_s) / CLOCKS_PER_SEC;
|
||
|
printf("Time Keygen NTRU : %lf\n", cpu_time_used);
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/* And now the plaintext buffer holds the decrypted AES-128 key. */
|
||
|
printf("Sample code completed successfully.\n");
|
||
|
error:
|
||
|
printf("ERROR %x\n", rc);
|
||
|
return 1;
|
||
|
|
||
|
}
|