Giter Club home page Giter Club logo

chacha20-poly1305's Introduction

ChaCha20 & Poly1305

build License: MIT

A from scratch C++ (with slight inline assembly) implementation of ChaCha20 & Poly1305 stream cipher described in RFC - 8439.

tests:

gcc-gnu clang mingw64

All test from RFC-8439 is implemented here and is inside the tests folder.


Environment Requirements

  • x86_64 or aarch64 architecture
  • little endian system

If your system does not have these requirements, it might produce wrong results or might not even compile.


Main Functions

Note: one byte is equivalent to one unsigned char, If we have an array with a size of 5 bytes, that is an array of type unsigned char with 5 elements.

/**Encryption.
 * 
 * @param outputCipher resulting cipher text output, 
 * The size of outputCipher in bytes is equivalent to textLen.
 * 
 * @param outputTag resulting 128bit / 16 byte array,
 * GENERATED after ENCRYPTION.
 * 
 * @param inputText plain text to be ENCRYPTED.
 * 
 * @param textLen size of the inputText in bytes.
 * 
 * @param AAD Arbitrary length additional authenticated data.
 * 
 * @param AAD_len size of the AAD in bytes.
 * 
 * @param key a 256-bit key or 32 byte unsigned char array.
 * 
 * @param nonce number only once.
*/
ChaCha20_Poly1305::aead_encrypt(
    unsigned char       *outputCipher,
    unsigned char       *outputTag,
    const unsigned char *inputText,
    size_t               textLen,
    const unsigned char *AAD,
    size_t               AAD_len,
    const unsigned char *key,
    const unsigned char *nonce
);

/**Decryption.
 * 
 * @param outputText recovered plain text output, 
 * The size of outputText in bytes is equivalent to cipherLen.
 * 
 * @param outputTag resulting 128bit / 16 byte array,
 * GENERATED after DECRYPTION.
 * 
 * @param inputCipher cipher text to be DECRYPTED.
 * 
 * @param cipherLen size of the input inputCipher in bytes.
 * 
 * @param AAD Arbitrary length additional authenticated data.
 * 
 * @param AAD_len size of the AAD in bytes.
 * 
 * @param key a 256-bit key or 32 byte unsigned char array.
 * 
 * @param nonce number only once.
*/
ChaCha20_Poly1305::aead_decrypt(
    unsigned char       *outputText,
    unsigned char       *outputTag,
    const unsigned char *inputCipher,
    size_t               cipherLen,
    const unsigned char *AAD,
    size_t               AAD_len,
    const unsigned char *key,
    const unsigned char *nonce
);

To know if the message is authentic:

The outputTag of generated by encryption should match the outputTag generated by decryption.

  1. The sender will send the encrypted cipher text along with the encrypted tag.

  2. Then the receiver will decrypt the cipher text, the decryption function will generate the output recovered plain text and the output decryption tag.

  3. The receiver then compares the sender's encryption tag to the generated output decryption tag; if both tag matched / is-equal then the message was authentic / not altered.


Compilation

There are TWO WAYS to use the library, either using the header only mode, or building the static library.

  • Using header only

    Directly include the Header-Mode-Chaha20-Poly1305.hpp in your source code, and you can directly compile it without building the static library.

    #include "Header-Mode-Chaha20-Poly1305.hpp"

    But you always need to enable the optimization flags for this method to work.

    g++ main.cpp main.out -O2
    clang++ main.cpp main.out -O2

  • Static Build with GNU-GCC Linux makefiles

    Build & install static library

    make -f staticlib
    sudo make -f staticlib install

    Run tests (optional)

    make -f staticlib build_test
    

    Include #include <ChaCha20-Poly1305.hpp> in your program then compile with -lchacha20

    g++ main.cpp -o main.out -lchacha20
    

    To uninstall library

    sudo make -f staticlib uninstall
    

    Clean Up compiled objects

    make -f staticlib cleanup
    

  • Static Build with Clang Linux makefiles

    Build static library with clang

    make -f staticlib CC=clang++
    sudo make -f staticlib install

    Run tests with clang (optional)

    make -f staticlib build_test CC=clang++
    

    Include #include <ChaCha20-Poly1305.hpp> in your program then compile with -lchacha20

    clang++ main.cpp -o main.out -lchacha20
    

    To uninstall library

    sudo make -f staticlib uninstall
    

    Clean Up compiled objects

    make -f staticlib cleanup
    

  • Static Build with Mingw64 Windows makefiles

    Build & install static library

    mingw32-make -f staticlib
    mingw32-make -f staticlib install INSTALL_PREFIX=(path/to/mingw64)

    Run tests (optional)

    mingw32-make -f staticlib build_test
    

    Include #include <ChaCha20-Poly1305.hpp> in your program then compile with -lchacha20

    g++ main.cpp -o main.out -lchacha20
    

    To uninstall library

    mingw32-make -f staticlib uninstall INSTALL_PREFIX=(path/to/mingw64)
    

    Clean Up compiled objects

    mingw32-make -f staticlib cleanup
    

You can also modify the installation path in linux by setting up a new value for the INSTALL_PREFIX= when executing the make build commands similar to what is shown in the windows build.

chacha20-poly1305's People

Contributors

mrdcvlsc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

apkc

chacha20-poly1305's Issues

implementation of uint320 to replace uint512

currently this repo is using uint512 for the Poly1305 mac/tag generation.

But since the multiplication of (acc+block) and r inside the Poly1305 does not exceed 2^288, a uint320 would be enough, It will use less operations and gain faster performance.

A more C++ friendly api

Implementation of a more C++ api

  • implement a much easier api like maybe an encryption or decryption that returns a vector<unsigned char> results?

I can't compile this file in MSVC

Hello, when I was searching for chacha20-ploy305 encryption, I saw your code on GitHub and thought it was great, but I couldn't compile this file in my own VS2022 MSVC environment.

known timing attack vulnerabilities

These are known timing attack vulnerabilities in the code that should be addressed/fix in the future.

  • uint320 uint320::% - returns the quotient right away if it detects that the dividen is equal to the divisor, or if the dividen is less than the divisor.
  • uint320 uint320::compare() - returns the boolean right away if it detects less than or greater than cases early. (due to being the backend function for the operators ==, !=, and <=, they are also adds up to the vulnerability on each use cases).
  • There is no constant time comparison function for authenticating the Poly1305 tags.

32 bit mul on uint512/uint320

Currently this repo is taking advantage of the assembly instruction mulq and the rdx:rax registers to get the product of two 64 bit unsigned integers.

This arises to the problem of propagating the carry to the most significant limbs.

If the next limb where the rdx is added using adc %%rdx, %[i] overflows, that would mean we need to add the carry again to the second next limb and then if that second next limb also overflows after adding the carry using adc $0, %[i+1] then we need to add the carry again to the third next limbadc $0, %[i+2], and this can go on until we reach the last limb or the most significant limb.

In short, In order to get the result correctly we need to call the adc sequentially from where we perform the first add operation with the rax, to the adc operation with the rdx, up until to the most significant limb.

Meaning we repeatedly use adc just to propagate the carry until to the most significant limb which I think is expensive?

I wonder if we can avoid this (maybe) expensive(?) carry overflow solution by using only 32 bits of integers in the multiplication operations when getting the product so that the sequential use of adc can be avoided(?).

(or maybe it's not needed because it's just operating on a uint512?, maybe it's only expensive for dynamically big integers?).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.