-
Notifications
You must be signed in to change notification settings - Fork 696
Coding conventions
Subdirectories of src contain modules. The first component of a module name is the type of module it is, either rand for a pseudorandom number generator, or kex for a key exchange method.
- For pseudorandom number generators, every module has a name of the form
rand_<algid>, where<algid>describes the generator in an appropriate way. - For key exchange methods, every module has a name of the form
kex_<problem>_<algid>, where<problem>denotes the mathematical problem the algorithm is based on (e.g., rlwe, lwe, sidh, ntru, mceliece, ...) and<algid>denotes a specific algorithm identifier (e.g., bcns15, frodo, newhope, ...).
Public functions are functions which are intended to be used by calling applications/libraries, and which are exported in .h files. Public functions start with upper-case letters and are of the form OQS_RAND_<algid>_<name> or OQS_KEX_<problem>_<algid>_<name>. For example, OQS_KEX_rlwe_bcns15_alice_0 or OQS_RAND_urandom_chacha20_32.
Private functions that still have global scope are functions which might be meaningful on their own, and could be useful to another research, but are not generally intended to be used by calling applications/libraries. They might be tested independently by a test hardness. Private functions with global scope start with lower-case letters and are of the form oqs_rand_<algid>_<name> or oqs_kex_<problem>_<algid>_<name>. For example, oqs_kex_rlwe_bcns15_crossround2 .
Private functions that do not have global scope can be named in any way. However, they must be declared static to avoid polluting the global namespace. You can check to make sure you haven't missed any such functions by ensuring the following command gives empty output:
nm -g liboqs.a | grep ' T ' | grep -E -v -i ' T [_]?[OQS|ntru]'
Code will be compiled using -std=c99. The code should compile cleanly—without warnings—with the following compiler flags:
-Wpedantic -Wall -Wextra
Memory involving secrets (secret keys, derived shared secrets) should be explicitly zeroed-out once it is not longer required. OQS_MEM_cleanse should be used to zero-out memory on the stack; OQS_MEM_secure_free should be used to zero-out and deallocate memory on the heap. Note that you should use one of these two instead of directly calling memset or bzero: an optimizing compiler may optimize out the seemingly "unnecessary" call to be memset or bzero, whereas we have taken steps in our two functions to prevent that from happening.
To indicate success/failure, functions should return the type OQS_STATUS, which is an enum defined in src/common/common.h. New error codes can be added for distinguishing new error types as required. New error codes should have numbers manually assigned to them (for consistency over time as new errors are added), and should be grouped (eg., reserve -100..-199 for errors related to some Algorithm A, -200..-299 for errors related to some Algorithm B, etc.).
Callers should compare with the symbol rather than the individual value. For example,
ret = OQS_KEM_encaps(...);
if (ret == OQS_SUCCESS) { ... }Source code should be formatted using the make prettyprint target before committing. We use clang-format for consistent formatting. However, there are inconsistencies between versions of clang-format, so we have currently fixed our version of clang-format to version 3.9
To install and use clang-format 3.9 on Ubuntu:
- Try
sudo apt install clang-format-3.9 - If that doesn't work, try following the commands in our script .travis/install-clang-format.sh
To install and use clang-format 3.9 on macOS using brew:
brew unlink clang-formatbrew install https://raw.githubusercontent.com/Homebrew/homebrew-core/0c4314c499576b28e4c082b591228a8f940954c0/Formula/clang-format.rb
Inline documentation in .c and .h files is done using Doxygen.