///////////////////////////////////////////////////////////////////////////////////////////////// // TagGeneration - Reads chunks from a file and xor them with r as well. // * INPUT: stream of bytes m, Chunk r // * OUTPUT: Chunk tag ///////////////////////////////////////////////////////////////////////////////////////////////// void TagGeneration(const unsigned char *m, Chunk r, Chunk tag, unsigned long long numOfChunks) { Chunk temp; int i, j, k; memset(tag, 0, SIZE); for (i = 0; i < numOfChunks - 2; i++) { memcpy(temp, m + (SIZE * i), SIZE); if (i == numOfChunks - 2) { for (j = 0; j < SIZE; j++) if (temp[j] == EOT) { for (k = j; k < SIZE; k++) temp[k] = 0x00; break; } } ModularAddition(tag, temp); } for (i = 0; i < SIZE; i++) temp[i] = r[i]; ModularAddition(tag, temp); }
///////////////////////////////////////////////////////////////////////////////////////////////// // crypto_aead_decrypt -The code for the cipher implementation (decryption part) goes here. // * INPUT: ciphertext c,associated data ad, // public message number or nonce npub, and secret key k. // * OUTPUT: plaintext m ///////////////////////////////////////////////////////////////////////////////////////////////// int crypto_aead_decrypt(unsigned char *m, unsigned long long *mlen, unsigned char *nsec, const unsigned char *c, unsigned long long clen, const unsigned char *ad, unsigned long long adlen, const unsigned char *npub, const unsigned char *k) { int i; int isValid = -1; //not valid message Byte PCMACKey[kSIZE]; Chunk RMACKey; Chunk prime; Chunk PCMACTag; //tag of PCMAC Chunk RMACTag; //tag of RMAC Chunk tagFromCipher; // tag retrieved from the cipher Byte nonce[kSIZE] = { 0 }; for (i = 0; i < SIZE; i++) tagFromCipher[i] = c[clen - SIZE + i]; clen -= SIZE; //actual clen without the tag for (i = 0; i < kSIZE; i++) PCMACKey[i] = k[i]; for (i = 0; i < SIZE; i++) { RMACKey[i] = k[i + kSIZE]; prime[i] = k[i + SIZE + kSIZE]; } for (i = SIZE; i < CRYPTO_NPUBBYTES; i++) nonce[i - SIZE] = npub[i]; isValid = PCMACDec(PCMACTag, m, mlen, c, clen, nonce, PCMACKey); if (isValid != 0) return isValid; Sign(prime, RMACKey, ad, adlen, RMACTag); ModularAddition(RMACTag, PCMACTag); isValid = Verify(RMACTag, tagFromCipher); return isValid; }
///////////////////////////////////////////////////////////////////////////////////////////////// // crypto_aead_encrypt - The code for the cipher implementation (encryption part) goes here. // * INPUT: plaintext m , associated data ad, // secret message number nsec, public message number or nonce npub, // and secret key k. // * OUTPUT: ciphertext c ///////////////////////////////////////////////////////////////////////////////////////////////// int crypto_aead_encrypt(unsigned char *c, unsigned long long *clen, const unsigned char *m, unsigned long long mlen, const unsigned char *ad, unsigned long long adlen, const unsigned char *nsec, const unsigned char *npub, const unsigned char *k) { Byte PCMACKey[kSIZE]; Chunk RMACKey; Chunk prime; int i; //counter Chunk PCMACTag; //tag of PCMAC Chunk RMACTag; //tag of RMAC Chunk r; Byte nonce[kSIZE] = { 0 }; unsigned long long numOfChunks = (unsigned long long) ceil( (float) mlen / SIZE) + 2; //length of plain message plus r plus tag for (i = 0; i < kSIZE; i++) PCMACKey[i] = k[i]; for (i = 0; i < SIZE; i++) { RMACKey[i] = k[i + kSIZE]; prime[i] = k[i + SIZE + kSIZE]; r[i] = npub[i]; } for (i = SIZE; i < CRYPTO_NPUBBYTES; i++) nonce[i - SIZE] = npub[i]; PCMACEnc(PCMACTag, c, clen, m, mlen, nonce, r, PCMACKey); Sign(prime, RMACKey, ad, adlen, RMACTag); ModularAddition(RMACTag, PCMACTag); for (i = 0; i < SIZE; i++) c[*clen - SIZE + i] = RMACTag[i]; return 0; }