Skip to content

Commit

Permalink
v1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMatjaz committed Apr 28, 2020
2 parents 0d40f1c + ec46ab5 commit faf751c
Show file tree
Hide file tree
Showing 15 changed files with 3,094 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
cmake-build-*/
tst/original/
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Changelog
===============================================================================

All notable changes to this project will be documented in this file.

The format is based on
[Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).

*******************************************************************************

[1.0.0] - 2020-04-28
----------------------------------------

Initial version.


### Added

- ISAAC and ISAAC-64, choose version with `ISAAC_BITS`
- Initialise context
- Generate stream of integers of arbitrary length
- Convert integers to bytes LE/BE
- Cleanup context
83 changes: 83 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
cmake_minimum_required(VERSION 3.5)
project(LibISAAC
VERSION 1.0.0
LANGUAGES C
DESCRIPTION
"A modern reimplementation of the ISAAC CPRNG.")

# Unless specified, by default create Release builds
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif ()

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

set(CMAKE_C_STANDARD 11)
# Activate a million warnings to have the cleanest possible code
set(FLAGS_WARNINGS -Wall -Wextra -pedantic -Wconversion -Wdouble-promotion
-Wswitch-default -Wswitch-enum -Wuninitialized -Wno-unused-variable
-Wpacked -Wpadded -Wshadow -Wformat-security -Wlogical-not-parentheses
-Waggregate-return -Wmissing-declarations -Wmissing-declarations)
# Debug build: compile with no optimisation, debug info and printing
set(CMAKE_C_FLAGS_DEBUG "${WARNING_FLAGS} -g -O0 -DDEBUG")
# Append sanitiser flags on non-Windows systems
if (NOT WIN32 AND NOT CYGWIN AND NOT MSYS)
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} \
-fsanitize=address,undefined -static-libsan")
endif ()

# Mini-sized release build: compile with optimisation for size
# convert warnings into errors and some other optimisations
set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} \
${WARNING_FLAGS} \
-Os -Werror -fomit-frame-pointer -march=native -mtune=native")

# Performance-oriented release build: compile with optimisation for speed
# convert warnings into errors and some other optimisations
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} \
${WARNING_FLAGS} \
-O3 -Werror -fomit-frame-pointer -march=native -mtune=native \
-funroll-loops")

include_directories(inc/)
set(LIB_FILES src/isaac.c)
include_directories(tst/ tst/atto/)
set(TEST_FILES
tst/atto/atto.c
tst/test.c
tst/test_init.c
tst/test_stream.c
tst/test_convert.c
tst/test_cleanup.c)

add_library(isaac32 STATIC ${LIB_FILES})
target_compile_definitions(isaac32 PUBLIC ISAAC_BITS=32)
add_library(isaac64 STATIC ${LIB_FILES})
target_compile_definitions(isaac64 PUBLIC ISAAC_BITS=64)
add_executable(testisaac32 ${LIB_FILES} ${TEST_FILES})
target_compile_definitions(testisaac32 PUBLIC ISAAC_BITS=32)
add_executable(testisaac64 ${LIB_FILES} ${TEST_FILES})
target_compile_definitions(testisaac64 PUBLIC ISAAC_BITS=64)

# Doxygen documentation builder
find_package(Doxygen)
if (DOXYGEN_FOUND)
# Cmake's wrapper of Doxygen, constructing a doxyfile from the
# DOXYGEN_* variables, which are mapped to the Doxygen variables.
set(DOXYGEN_GENERATE_HTML YES)
set(DOXYGEN_GENERATE_MAN YES)
set(DOXYGEN_JAVADOC_AUTOBRIEF YES)
set(DOXYGEN_OPTIMIZE_OUTPUT_FOR_C YES)
set(DOXYGEN_SORT_MEMBER_DOCS NO)
set(DOXYGEN_ALIASES license="**License:**")
set(DOXYGEN_USE_MDFILE_AS_MAINPAGE README.md)
doxygen_add_docs(doxygen
ALL # Build doxygen on make-all
# List of input files for Doxygen
${PROJECT_SOURCE_DIR}/inc/isaac.h
${PROJECT_SOURCE_DIR}/LICENSE.md
${PROJECT_SOURCE_DIR}/README.md
${PROJECT_SOURCE_DIR}/CHANGELOG.md)
else (DOXYGEN_FOUND)
message(WARNING "Doxygen not found. Cannot generate documentation.")
endif (DOXYGEN_FOUND)
28 changes: 28 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
BSD 3-Clause License
==============================================================================

Copyright © 2020, Matjaž Guštin <[email protected]> <https://matjaz.it>.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS “AS IS” AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
125 changes: 125 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
ISAAC, the fast CSPRNG, reimplemented in a nicer, documented, modern C11 API
===============================================================================

LibISAAC offers the tiny and fast
[ISAAC](https://www.burtleburtle.net/bob/rand/isaacafa.html) cryptographically
secure pseudo random number generator (CSPRNG), in its 32-bit and 64-bit version
wrapped into a modern, ISO C11, documented API, ready for embedded usage.



About ISAAC
----------------------------------------

Quoting from [its website](https://www.burtleburtle.net/bob/rand/isaacafa.html):

> ISAAC (Indirection, Shift, Accumulate, Add, and Count) generates 32-bit
> random numbers. Averaged out, it requires 18.75 machine cycles to
> generate each 32-bit value. Cycles are guaranteed to be at least 240
> values long, and they are 28295 values long on average. The results are
> uniformly distributed, unbiased, and unpredictable unless you know the
> seed.
> [...]
> ISAAC-64 generates a different sequence than ISAAC, but it uses the same
> principles. It uses 64-bit arithmetic. It generates a 64-bit result every
> 19 instructions. All cycles are at least 272 values, and the average
> cycle length is 216583.
ISAAC and its original source code (on which this version is based on)
were created by Bob Jenkins and released into the public domain.



Usage example
----------------------------------------

```c
// Init the context with a secret seed
isaac_ctx_t ctx;
const uint8_t seed[16] = {1, 2, 3, 4, 5, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16};
isaac_init(&ctx, seed, sizeof(seed));

// If you DON'T need ISAAC for security purposes, an all-zero
// seed may also be of interested. Just pass a NULL seed.
isaac_init(&ctx, NULL, 0);

// Extract ANY amount of pseudo-random integers
isaac_uint_t stream[300] = {0};
isaac_stream(&ctx, stream, 300);
isaac_uint_t another_stream[5000] = {0};
isaac_stream(&ctx, stream, 5000);

// Note that ISAAC provides integers, not bytes.
// If you need bytes, convert the integers to little endian-
// or big endian-encoded stream of bytes.
uint8_t bytes[300 * sizeof(isaac_uint_t)];
isaac_to_big_endian(bytes, stream, 300);
// or isaac_to_little_endian(bytes, stream, 300);

// Done using ISAAC? Cleanup the context to avoid leaving traces
// of the state and of the seed.
isaac_cleanup(&ctx);
```
Include it in your project
----------------------------------------
### Bitness
Depending on your architecture, you may want to use the version of ISAAC
optimised for 32 or 64 bit words. To do so, set the `#define ISAAC_BITS`
to `32` or `64` during compilation or directly in the header file. It defaults
to 64 when unspecified.
Differences:
- the output differs between the two (it's expected to differ)
- the context grows twice in size when using the 64 bit version
- 32 bit: 2064 B
- 64 bit: 4128 B
- in the 64 bit version, twice the amount of bytes is provided per reshuffling
of the state
Please note that altering `ISAAC_BITS` does not set your compiler to
compile LibISAAC for a 32 or 64 target architecture, it simply chooses which
integers to use based on **your** choice, not the compiler's. You may want to
choose the best version for your system, but you can compile both versions on
any system.
Examples:
- a 32-bit microcontroller works best with `ISAAC_BITS=32`
- a 64-bit desktop works best with `ISAAC_BITS=64`
- a 64-bit desktop that has to test the output of ISAAC coming from a 32-bit
microcontroller (assuming the same seed is known to both), should compile with
`ISAAC=BITS=32` to get the same output.
### Static source inclusion
Copy the `inc/isaac.h` and `src/isaac.c` files into your existing
C project, add them to the source folders and compile..
If you prefer a specific bitness, redefine `ISAAC_BITS` in the header file.
### Compiling into all possible targets
```
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DISAAC_BITS=32
cmake --build .
```
This will build all targets:
- a `libisaac32.a` static library
- a test runner executable `testisaac32`
- the Doxygen documentation (if Doxygen is installed)
To compile with the optimisation for size, use the
`-DCMAKE_BUILD_TYPE=MinSizeRel` flag instead.
If you prefer using 64 bit integers, set `-DISAAC_BITS=64`.
Loading

0 comments on commit faf751c

Please sign in to comment.