41 Commits
v0.36 ... v0.37

Author SHA1 Message Date
PartialVolume
28271712db Update CHANGELOG.md 2024-05-10 20:08:28 +01:00
PartialVolume
ef312ff90d Merge pull request #577 from PartialVolume/change_nwipe.1_to_nwipe.8
Request change man/nwipe.1 to man/nwipe.8
2024-05-10 19:59:04 +01:00
PartialVolume
6d6b7ac8c1 Request change man/nwipe.1 to man/nwipe.8
Manpage is named nwipe.1 which would be correct but manpage
contains section 8 which forms a mismatch(warning) in Debian.

# Man sections
1   Executable programs or shell commands
2   System calls (functions provided by the kernel)
3   Library calls (functions within program libraries)
4   Special files (usually found in /dev)
5   File formats and conventions, e.g. /etc/passwd
6   Games
7   Miscellaneous (including macro packages and conventions), e.g. man(7), groff(7), man-pages(7)
8   System administration commands (usually only for root)
9   Kernel routines [Non standard]

(requested by MvB)
2024-05-10 19:32:36 +01:00
PartialVolume
5140f92077 Merge pull request #576 from PartialVolume/master
Update CHANGELOG.md
2024-05-08 22:04:05 +01:00
PartialVolume
4893fa7ea0 Update CHANGELOG.md 2024-05-08 22:00:34 +01:00
PartialVolume
b83423a424 Merge pull request #575 from PartialVolume/bump_to_0.37
Bump to v0.37
2024-05-08 21:37:09 +01:00
PartialVolume
4394f24245 Bump to v0.37 2024-05-08 21:31:53 +01:00
PartialVolume
1ae76b5774 Merge pull request #574 from Polynomial-C/configure_ac_fix
configure.ac: Fix check for parted
2024-05-06 23:15:31 +01:00
Lars Wendler
fca8937f26 configure.ac: Fix check for parted
PKG_CHECK_MODULES needs all modules in a single list or else the following
error message appears during configure run:

  ./configure: 6807: libconfig: not found

because the macro interprets "[libconfig]" as the action that needs to be
done if parted was found.

Removed superfluous check for libconfig as requested by PartialVolume
2024-05-06 19:34:02 +02:00
PartialVolume
09d620c9c7 Update README.md
Update readme.md with the new prngs that will be available from V0.37+
2024-04-19 23:37:32 +01:00
Martijn van Brummelen
f0ed2fe7f0 Update nwipe.1
W: nwipe: wrong-manual-section 1 != 20 [usr/share/man/man1/nwipe.1.gz:1]
2024-04-16 20:11:10 +02:00
PartialVolume
9400ff5219 Merge pull request #571 from PartialVolume/Fix_conditional_jump_or_move_on_unitialised_value
Fix conditional jump on uninitialised value
2024-04-08 21:26:59 +01:00
PartialVolume
81fc479239 Fix conditional jump on unitialised value
This fixes a valgrind detected error. We check that
the number of real max sectors is greater than zero before
incrementing the value by 1. However ocassionaly the ioctl
call may not be able to obtain the dco and therefore the
ioctl data block is never populated. By zeroing the data
block prior to use and if it is not populated by the ioctl
call then the calculated real max sectors will be
zero and no increment will occur which is what we want.
2024-04-08 21:17:41 +01:00
PartialVolume
28095801ac Merge pull request #569 from AndCycle/fix_help
Add missing help for HMG IS5 enhanced
2024-04-05 12:14:54 +01:00
AndCycle
66a951722d Add missing help for HMG IS5 enhanced 2024-04-05 05:36:06 +08:00
PartialVolume
834348c8c8 Merge pull request #566 from Knogle/master
XORoshiro-256 and ALFG as default PRNG for 64-Bit and 32-Bit platforms. Also PRNG method as default method.
2024-03-28 22:09:22 +00:00
PartialVolume
e4a51c00c1 Merge pull request #565 from PartialVolume/Fix_valgrind_unconditional_jump_or_move_on_unitialised_value
Fix valgrind jump or move on unconditional value in nwipe config code
2024-03-28 17:38:21 +00:00
PartialVolume
00bcce475b Fix valgrind jump or move on unconditional 2024-03-28 17:17:19 +00:00
Fabian Druschke
0114ccf937 Fixed formatting using make format for options.c 2024-03-28 11:58:07 -03:00
Fabian Druschke
616a2ab236 Forgot nwipe_ in front of add_lagged_fibonacci, leading to compiling error 2024-03-28 11:56:54 -03:00
Fabian Druschke
e6e638c4dc Advocate for PRNG as default option, as well as XORoshiro-256 for 64-Bit systems, and Additive Lagged Fibonacci Generator for 32-Bit legacy systems 2024-03-28 11:51:47 -03:00
PartialVolume
8ad4fe200d Merge pull request #562 from Knogle/master
Fixed memory leak in line 328, writing 1 byte beyond allocated memory.
2024-03-26 21:39:28 +00:00
PartialVolume
a4ce92be6f Merge pull request #561 from PartialVolume/Update_pdf_with_xoro_and_fibonacci_prngs
Update PDF code with new PRNGs
2024-03-26 21:21:18 +00:00
PartialVolume
e851769025 Update PDF code with new PRNGs
Updated pdf to recognise XORshiro256 and
lagged Fibonacci PRNGs.
2024-03-26 21:17:23 +00:00
Fabian Druschke
c7ada53d4e Fixed memory leak in line 328, writing 1 byte beyond allocated memory. 2024-03-26 13:28:10 -03:00
PartialVolume
bb93793d7f Merge pull request #558 from Knogle/master
Renamed N and M to MT_STATE_SIZE and MT_MIDDLE_WORD due to const naming of mt19937ar-cok.h, causing conflicts with SHA-512 HMAC's libssl.
2024-03-22 01:35:17 +00:00
PartialVolume
ea386f35e7 Update gui.c with correct number of prngs 2024-03-21 22:51:31 +00:00
PartialVolume
204a82f6f0 Merge pull request #555 from Knogle/xoroshiro256
Implement XORoshiro-256 PRNG for Enhanced Random Number Generation Efficiency
2024-03-21 22:10:14 +00:00
PartialVolume
f66d838b23 Fix formatting in gui.c 2024-03-21 22:07:52 +00:00
PartialVolume
4fad31ec50 Fix a couple of formatting issues in prng.c 2024-03-21 22:03:24 +00:00
PartialVolume
0e03653ab5 Merge branch 'master' into xoroshiro256 2024-03-21 21:28:06 +00:00
Fabian Druschke
4e29f6c514 Renamed N and M to MT_STATE_SIZE and MT_MIDDLE_WORD due to const naming of mt19937ar-cok.h, causing conflicts with SHA-512 HMAC's libssl. 2024-03-21 17:28:57 -03:00
PartialVolume
d40c28bfc5 Merge pull request #556 from Knogle/fibonacci
Implemented Lagged Fibonacci generator PRNG providing high-speed, medium-quality numbers.
2024-03-21 18:49:16 +00:00
Fabian Druschke
0d0150393c Fixed stray / inside of options.c 2024-03-21 10:01:17 -03:00
Fabian Druschke
238656a5b4 Fixed leftovers from XORoshiro-256, fixed missing PRNG option in options.c 2024-03-21 05:01:10 -03:00
Fabian Druschke
a2d998d7c3 Fixed formatting 2024-03-20 17:48:55 -03:00
Fabian Druschke
a89dc8b9e9 Implemented Substract-and-Carry, now offering high-quality output. 2024-03-20 17:45:14 -03:00
Fabian Druschke
87376a0bbb Removed leftover references to AES-CTR, not belonging here. 2024-03-20 17:39:32 -03:00
Fabian Druschke
201eb565f9 Implemented Lagged Fibonacci generator PRNG providing high-speed, medium-security numbers. 2024-03-20 17:28:57 -03:00
Fabian Druschke
50bcf81ea6 Fixed src/temperature.c formatting 2024-03-19 08:25:09 -03:00
Fabian Druschke
5e532c9367 Rebased branch, fixed conflicts. Now Xoroshiro-256 in standalone branch 2024-03-19 08:24:38 -03:00
22 changed files with 649 additions and 105 deletions

View File

@@ -1,6 +1,17 @@
RELEASE NOTES
=============
v0.37
-----------------------
includes the following changes:
- Added the XORoshiro-256 pseudo random number generator (PRNG). Thanks to Fabian Druschke @knogle #555
- Added the Lagged Fibonacci PRNG generator. Thanks again to Fabian Druschke @knogle #556
- Added missing help for HMG IS5 enhanced. Thanks to @AndCycle #569
- Changed the default method from "DOD Short" to "prng stream", using the XORoshiro-256 prng
- Fixed an issue in configure.ac which was producing an error while running `./configure`, mentioning libconfig, however the presence of libconfig had already been checked for, earlier in configure.ac. Although this error did not cause `./configure` to abort prematurely and therefore make would build the source correctly, it did cause a issue for inclusion into Debian Sid. Thanks to @Polynomial-C #574
- Minor change to nwipe's man page filename, nwipe.1 to nwipe.8 to fix a Debian warning. #577
v0.36
-----------------------
- Added the abbreviation MMC for mmcblk devices such as SD and microSD cards and some low budget laptops. #526

View File

@@ -30,10 +30,15 @@ The user can select from a variety of recognised secure erase methods which incl
* Verify Ones - This method only reads the device and checks that it is filled with ones (0xFF).
* HMG IS5 enhanced - Secure Sanitisation of Protectively Marked Information or Sensitive Information
nwipe also includes the following pseudo random number generators:
nwipe also includes the following pseudo random number generators (prng):
* Mersenne Twister
* ISAAC
In addition to the above, the following prngs will be available in v0.37
* XORoshiro-256
* Lagged Fibonacci
* AES-CTR (openssl)
These can be used to overwrite a drive with a stream of randomly generated characters.
nwipe can be found in many [Linux distro repositories](#which-linux-distro-uses-the-latest-nwipe).

View File

@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.63])
AC_INIT([nwipe],[0.36],[git@brumit.nl])
AC_INIT([nwipe],[0.37],[git@brumit.nl])
AM_INIT_AUTOMAKE(foreign subdir-objects)
AC_CONFIG_FILES([Makefile src/Makefile man/Makefile])
AC_OUTPUT
@@ -69,7 +69,7 @@ PKG_CHECK_MODULES(
AC_CHECK_LIB([intl], [libintl_dgettext]) # needed to statically link libparted, but not given in its pkgconfig file
AC_CHECK_LIB([uuid], [uuid_generate]) # needed to statically link libparted, but not given in its pkgconfig file
PKG_CHECK_MODULES([PARTED], [libparted], [libconfig])
PKG_CHECK_MODULES([PARTED], [libparted])
AC_CHECK_LIB([pthread], [main], ,[AC_MSG_ERROR([pthread development library not found])])
# Checks for header files.

View File

@@ -1 +1 @@
dist_man_MANS = nwipe.1
dist_man_MANS = nwipe.8

View File

@@ -1,4 +1,4 @@
.TH NWIPE "20" "February 2024" "nwipe version 0.36" "User Commands"
.TH NWIPE "8" "May 2024" "nwipe version 0.37" "User Commands"
.SH NAME
nwipe \- securely erase disks
.SH SYNOPSIS
@@ -131,6 +131,7 @@ Number of times to wipe the device using the selected method (default: 1)
Up to ten comma separated devices to be excluded, examples:
--exclude=/dev/sdc
--exclude=/dev/sdc,/dev/sdd
--exclude=/dev/sdc,/dev/sdd,/dev/mapper/cryptswap1
.SH BUGS
Please see the GitHub site for the latest list
(https://github.com/martijnvanbrummelen/nwipe/issues)

View File

@@ -6,5 +6,5 @@ AM_LDFLAGS =
# this lists the binaries to produce, the (non-PHONY, binary) targets in
# the previous manual Makefile
bin_PROGRAMS = nwipe
nwipe_SOURCES = context.h logging.h options.h prng.h version.h temperature.h nwipe.c gui.c method.h pass.c device.c gui.h isaac_rand/isaac_standard.h isaac_rand/isaac_rand.h isaac_rand/isaac_rand.c isaac_rand/isaac64.h isaac_rand/isaac64.c mt19937ar-cok/mt19937ar-cok.c nwipe.h mt19937ar-cok/mt19937ar-cok.h pass.h device.h logging.c method.c options.c prng.c version.c temperature.c PDFGen/pdfgen.h PDFGen/pdfgen.c create_pdf.c create_pdf.h embedded_images/shred_db.jpg.c embedded_images/shred_db.jpg.h embedded_images/tick_erased.jpg.c embedded_images/tick_erased.jpg.h embedded_images/redcross.c embedded_images/redcross.h hpa_dco.h hpa_dco.c miscellaneous.h miscellaneous.c embedded_images/nwipe_exclamation.jpg.h embedded_images/nwipe_exclamation.jpg.c conf.h conf.c customers.h customers.c hddtemp_scsi/hddtemp.h hddtemp_scsi/scsi.h hddtemp_scsi/scsicmds.h hddtemp_scsi/get_scsi_temp.c hddtemp_scsi/scsi.c hddtemp_scsi/scsicmds.c
nwipe_SOURCES = context.h logging.h options.h prng.h version.h temperature.h nwipe.c gui.c method.h pass.c device.c gui.h isaac_rand/isaac_standard.h isaac_rand/isaac_rand.h isaac_rand/isaac_rand.c isaac_rand/isaac64.h isaac_rand/isaac64.c mt19937ar-cok/mt19937ar-cok.c nwipe.h mt19937ar-cok/mt19937ar-cok.h alfg/add_lagg_fibonacci_prng.h alfg/add_lagg_fibonacci_prng.c xor/xoroshiro256_prng.h xor/xoroshiro256_prng.c pass.h device.h logging.c method.c options.c prng.c version.c temperature.c PDFGen/pdfgen.h PDFGen/pdfgen.c create_pdf.c create_pdf.h embedded_images/shred_db.jpg.c embedded_images/shred_db.jpg.h embedded_images/tick_erased.jpg.c embedded_images/tick_erased.jpg.h embedded_images/redcross.c embedded_images/redcross.h hpa_dco.h hpa_dco.c miscellaneous.h miscellaneous.c embedded_images/nwipe_exclamation.jpg.h embedded_images/nwipe_exclamation.jpg.c conf.h conf.c customers.h customers.c hddtemp_scsi/hddtemp.h hddtemp_scsi/scsi.h hddtemp_scsi/scsicmds.h hddtemp_scsi/get_scsi_temp.c hddtemp_scsi/scsi.c hddtemp_scsi/scsicmds.c
nwipe_LDADD = $(PARTED_LIBS) $(LIBCONFIG)

View File

@@ -0,0 +1,79 @@
/*
* Additive Lagged Fibonacci Generator (ALFG) Implementation
* Author: Fabian Druschke
* Date: 2024-03-13
*
* This is an implementation of the Additive Lagged Fibonacci Generator (ALFG),
* a pseudorandom number generator known for its simplicity and good statistical properties
* for a wide range of applications. ALFGs are particularly noted for their long periods
* and efficiency in generating sequences of random numbers. However, like many other PRNGs,
* they are not suitable for cryptographic purposes due to their predictability.
*
* As the author of this implementation, I, Fabian Druschke, hereby release this work into
* the public domain. I dedicate any and all copyright interest in this work to the public
* domain, making it free to use for anyone for any purpose without any conditions, unless
* such conditions are required by law.
*
* This software is provided "as is", without warranty of any kind, express or implied,
* including but not limited to the warranties of merchantability, fitness for a particular
* purpose, and noninfringement. In no event shall the authors be liable for any claim,
* damages, or other liability, whether in an action of contract, tort, or otherwise, arising
* from, out of, or in connection with the software or the use or other dealings in the software.
*
* Note: This implementation is designed for non-cryptographic applications and should not be
* used where cryptographic security is required.
*/
#include "add_lagg_fibonacci_prng.h"
#include <stdint.h>
#include <string.h>
#define STATE_SIZE 64 // Size of the state array, sufficient for a high period
#define LAG_BIG 55 // Large lag, e.g., 55
#define LAG_SMALL 24 // Small lag, e.g., 24
#define MODULUS ( 1ULL << 48 ) // Modulus for the operations, here 2^48 for simple handling
void add_lagg_fibonacci_init( add_lagg_fibonacci_state_t* state, uint64_t init_key[], unsigned long key_length )
{
// Simple initialization: Fill the state with the key values and then with a linear combination of them
for( unsigned long i = 0; i < STATE_SIZE; i++ )
{
if( i < key_length )
{
state->s[i] = init_key[i];
}
else
{
// Simple method to generate further state values. Should be improved for serious applications.
state->s[i] = ( 6364136223846793005ULL * state->s[i - 1] + 1 ) % MODULUS;
}
}
state->index = 0; // Initialize the index for the first generation
}
void add_lagg_fibonacci_genrand_uint256_to_buf( add_lagg_fibonacci_state_t* state, unsigned char* bufpos )
{
uint64_t* buf_as_uint64 = (uint64_t*) bufpos; // Interprets bufpos as a uint64_t array for direct assignment
int64_t result; // Use signed integer to handle potential negative results from subtraction
for (int i = 0; i < 4; i++) {
// Subtract the two previous numbers in the sequence
result = (int64_t)state->s[(state->index + LAG_BIG) % STATE_SIZE] - (int64_t)state->s[(state->index + LAG_SMALL) % STATE_SIZE];
// Handle borrow if result is negative
if (result < 0) {
result += MODULUS;
// Optionally set a borrow flag or adjust the next operation based on borrow logic
}
// Store the result (after adjustment) back into the state, ensuring it's positive and within range
state->s[state->index] = (uint64_t)result;
// Write the result into buf_as_uint64
buf_as_uint64[i] = state->s[state->index];
// Update the index for the next round
state->index = (state->index + 1) % STATE_SIZE;
}
}

View File

@@ -0,0 +1,43 @@
/*
* Additive Lagged Fibonacci Generator (ALFG) Implementation definitions
* Author: Fabian Druschke
* Date: 2024-03-13
*
* This is an implementation of the Additive Lagged Fibonacci Generator (ALFG),
* a pseudorandom number generator known for its simplicity and good statistical properties
* for a wide range of applications. ALFGs are particularly noted for their long periods
* and efficiency in generating sequences of random numbers. However, like many other PRNGs,
* they are not suitable for cryptographic purposes due to their predictability.
*
* As the author of this implementation, I, Fabian Druschke, hereby release this work into
* the public domain. I dedicate any and all copyright interest in this work to the public
* domain, making it free to use for anyone for any purpose without any conditions, unless
* such conditions are required by law.
*
* This software is provided "as is", without warranty of any kind, express or implied,
* including but not limited to the warranties of merchantability, fitness for a particular
* purpose, and noninfringement. In no event shall the authors be liable for any claim,
* damages, or other liability, whether in an action of contract, tort, or otherwise, arising
* from, out of, or in connection with the software or the use or other dealings in the software.
*
* Note: This implementation is designed for non-cryptographic applications and should not be
* used where cryptographic security is required.
*/
#ifndef ADD_LAGG_FIBONACCI_PRNG_H
#define ADD_LAGG_FIBONACCI_PRNG_H
#include <stdint.h>
// State definition for the Additive Lagged Fibonacci Generator
typedef struct
{
uint64_t s[64]; // State array
unsigned int index; // Current index in the state array
} add_lagg_fibonacci_state_t;
// Function prototypes
void add_lagg_fibonacci_init( add_lagg_fibonacci_state_t* state, uint64_t init_key[], unsigned long key_length );
void add_lagg_fibonacci_genrand_uint256_to_buf( add_lagg_fibonacci_state_t* state, unsigned char* bufpos );
#endif // ADD_LAGG_FIBONACCI_PRNG_H

View File

@@ -392,11 +392,12 @@ int nwipe_conf_update_setting( char* group_name_setting_name, char* setting_valu
int nwipe_conf_read_setting( char* group_name_setting_name, const char** setting_value )
{
/* You would call this function if you wanted to read a settings value in nwipe.conf, i.e
/* This function returns a setting value from nwipe's configuration file nwipe.conf
* when provided with a groupname.settingname string.
*
* Example:
* const char ** pReturnString;
* nwipe_conf_read_setting( "PDF_Certificate", "PDF_Enable", pReturnString );
*
*/
/* Separate group_name_setting_name i.e "PDF_Certificate.PDF_Enable" string
@@ -406,20 +407,20 @@ int nwipe_conf_read_setting( char* group_name_setting_name, const char** setting
int return_status;
int length = strlen( group_name_setting_name );
char* group_name = malloc( length );
char* setting_name = malloc( length );
char* group_name = calloc( length, sizeof( char ) );
char* setting_name = calloc( length, sizeof( char ) );
int idx = 0;
while( group_name_setting_name[idx] != 0 && group_name_setting_name[idx] != '.' )
{
if( group_name_setting_name[idx] == '.' )
{
break;
}
idx++;
}
// Copy the group name from the combined input string
memcpy( group_name, group_name_setting_name, idx );
group_name[idx] = '\0'; // Null-terminate group_name
// Copy the setting name from the combined input string
strcpy( setting_name, &group_name_setting_name[idx + 1] );
if( !( setting = config_lookup( &nwipe_cfg, group_name ) ) )

View File

@@ -63,6 +63,8 @@ int create_pdf( nwipe_context_t* ptr )
extern nwipe_prng_t nwipe_twister;
extern nwipe_prng_t nwipe_isaac;
extern nwipe_prng_t nwipe_isaac64;
extern nwipe_prng_t nwipe_add_lagg_fibonacci_prng;
extern nwipe_prng_t nwipe_xoroshiro256_prng;
/* Used by libconfig functions to retrieve data from nwipe.conf defined in conf.c */
extern config_t nwipe_cfg;
@@ -466,7 +468,21 @@ int create_pdf( nwipe_context_t* ptr )
}
else
{
snprintf( prng_type, sizeof( prng_type ), "Unknown" );
if( nwipe_options.prng == &nwipe_add_lagg_fibonacci_prng )
{
snprintf( prng_type, sizeof( prng_type ), "Fibonacci" );
}
else
{
if( nwipe_options.prng == &nwipe_xoroshiro256_prng )
{
snprintf( prng_type, sizeof( prng_type ), "XORshiro256" );
}
else
{
snprintf( prng_type, sizeof( prng_type ), "Unknown" );
}
}
}
}
}

120
src/gui.c
View File

@@ -1599,10 +1599,14 @@ void nwipe_gui_prng( void )
extern nwipe_prng_t nwipe_twister;
extern nwipe_prng_t nwipe_isaac;
extern nwipe_prng_t nwipe_isaac64;
extern nwipe_prng_t nwipe_aes_ctr_prng;
extern nwipe_prng_t nwipe_xoroshiro256_prng;
extern nwipe_prng_t nwipe_add_lagg_fibonacci_prng;
extern int terminate_signal;
/* The number of implemented PRNGs. */
const int count = 3;
const int count = 5;
/* The first tabstop. */
const int tab1 = 2;
@@ -1636,7 +1640,14 @@ void nwipe_gui_prng( void )
{
focus = 2;
}
if( nwipe_options.prng == &nwipe_add_lagg_fibonacci_prng )
{
focus = 3;
}
if( nwipe_options.prng == &nwipe_xoroshiro256_prng )
{
focus = 4;
}
do
{
/* Clear the main window. */
@@ -1651,6 +1662,8 @@ void nwipe_gui_prng( void )
mvwprintw( main_window, yy++, tab1, " %s", nwipe_twister.label );
mvwprintw( main_window, yy++, tab1, " %s", nwipe_isaac.label );
mvwprintw( main_window, yy++, tab1, " %s", nwipe_isaac64.label );
mvwprintw( main_window, yy++, tab1, " %s", nwipe_add_lagg_fibonacci_prng.label );
mvwprintw( main_window, yy++, tab1, " %s", nwipe_xoroshiro256_prng.label );
yy++;
/* Print the cursor. */
@@ -1734,7 +1747,100 @@ void nwipe_gui_prng( void )
"Performs best on a 64-bit CPU. Use ISAAC if this system has a 32-bit CPU. " );
break;
} /* switch */
case 3:
mvwprintw( main_window,
yy++,
tab1,
"ALFG (Additive Lagged Fibonacci Generator), is a class of PRNGs utilizing" );
mvwprintw( main_window,
yy++,
tab1,
"the Fibonacci sequence with additive operations between lagged values. While" );
mvwprintw( main_window,
yy++,
tab1,
"they offer a good balance between speed and randomness, it's important to note" );
mvwprintw( main_window,
yy++,
tab1,
"that they provide lower levels of security, making them less suitable for" );
mvwprintw( main_window,
yy++,
tab1,
"cryptographic applications. Their periodicity depends on the choice of lags" );
mvwprintw( main_window,
yy++,
tab1,
"and arithmetic operations, potentially achieving large values, often 2^N or" );
mvwprintw( main_window,
yy++,
tab1,
"higher, where N is the bit length of the states. " );
mvwprintw( main_window,
yy++,
tab1,
" " );
mvwprintw( main_window,
yy++,
tab1,
"Efficient on CPUs of any bit width, particularly suited for non-cryptographic" );
mvwprintw( main_window,
yy++,
tab1,
"applications requiring long sequences with a good speed-randomness trade-off. " );
break;
case 4:
mvwprintw( main_window,
yy++,
tab1,
"Xoroshiro256**, originally designed by David Blackman and Sebastiano Vigna" );
mvwprintw( main_window,
yy++,
tab1,
"for 128 bits, was adapted to 256 bits by Fabian Druschke. This adaptation " );
mvwprintw( main_window,
yy++,
tab1,
"enhances its capability for fast, high-quality generation of pseudo-random " );
mvwprintw( main_window,
yy++,
tab1,
"numbers with a state size of 256 bits. It boasts an extremely long period " );
mvwprintw( main_window,
yy++,
tab1,
"of 2^256-1 without sacrificing performance, suitable for a wide range of " );
mvwprintw( main_window,
yy++,
tab1,
"applications. " );
mvwprintw( main_window,
yy++,
tab1,
" " );
mvwprintw( main_window,
yy++,
tab1,
"The simple arithmetic operations (shifts, rotations, and XORs) of " );
mvwprintw( main_window,
yy++,
tab1,
"Xoroshiro256** ensure low computational complexity. This, combined with " );
mvwprintw( main_window,
yy++,
tab1,
"the adaptation for 256 bits by Fabian Druschke, allows efficient use " );
mvwprintw( main_window,
yy++,
tab1,
"especially for legacy systems, due to its efficiency and minimal demands. " );
break;
}
/* switch */
/* Add a border. */
box( main_window, 0, 0 );
@@ -1794,6 +1900,14 @@ void nwipe_gui_prng( void )
{
nwipe_options.prng = &nwipe_isaac64;
}
if( focus == 3 )
{
nwipe_options.prng = &nwipe_add_lagg_fibonacci_prng;
}
if( focus == 4 )
{
nwipe_options.prng = &nwipe_xoroshiro256_prng;
}
return;
case KEY_BACKSPACE:

View File

@@ -722,6 +722,9 @@ u64 nwipe_read_dco_real_max_sectors( char* device )
unsigned char buffer[LBA_SIZE]; // Received data block
unsigned char sense_buffer[SENSE_BUFFER_SIZE]; // Sense data
/* Zero the data block prior to use */
memset( buffer, 0, LBA_SIZE );
/* three characters represent one byte of sense data, i.e
* two characters and a space "01 AE 67"
*/

View File

@@ -1,16 +1,16 @@
/*
This code is modified for use in nwipe.
/*
This code is modified for use in nwipe.
A C-program for MT19937, with initialization improved 2002/2/10.
Coded by Takuji Nishimura and Makoto Matsumoto.
This is a faster version by taking Shawn Cokus's optimization,
Matthe Bellew's simplification, Isaku Wada's real version.
Before using, initialize the state by using init_genrand(seed)
Before using, initialize the state by using init_genrand(seed)
or init_by_array(init_key, key_length).
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
All rights reserved.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -23,8 +23,8 @@
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of its contributors may not be used to endorse or promote
products derived from this software without specific prior written
3. The names of its contributors may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
@@ -48,77 +48,89 @@
#include <stdio.h>
#include "mt19937ar-cok.h"
/* initializes state[N] with a seed */
void init_genrand( twister_state_t* state, unsigned long s)
/* initializes state[MT_STATE_SIZE] with a seed */
void init_genrand( twister_state_t* state, unsigned long s )
{
int j;
state->array[0]= s & 0xffffffffUL;
for( j = 1; j < N; j++ )
{
state->array[j] = (1812433253UL * (state->array[j-1] ^ (state->array[j-1] >> 30)) + j);
state->array[j] &= 0xffffffffUL; /* for >32 bit machines */
}
state->left = 1;
state->initf = 1;
int j;
state->array[0] = s & 0xffffffffUL;
for( j = 1; j < MT_STATE_SIZE; j++ )
{
state->array[j] = ( 1812433253UL * ( state->array[j - 1] ^ ( state->array[j - 1] >> 30 ) ) + j );
state->array[j] &= 0xffffffffUL; /* for >32 bit machines */
}
state->left = 1;
state->initf = 1;
}
void twister_init( twister_state_t* state, unsigned long init_key[], unsigned long key_length )
{
int i = 1;
int j = 0;
int k = ( N > key_length ? N : key_length );
int j = 0;
int k = ( MT_STATE_SIZE > key_length ? MT_STATE_SIZE : key_length );
init_genrand( state, 19650218UL );
for( ; k; k-- )
{
state->array[i] = (state->array[i] ^ ((state->array[i-1] ^ (state->array[i-1] >> 30)) * 1664525UL)) + init_key[j] + j;
state->array[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
++i;
++j;
{
state->array[i] = ( state->array[i] ^ ( ( state->array[i - 1] ^ ( state->array[i - 1] >> 30 ) ) * 1664525UL ) )
+ init_key[j] + j;
state->array[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
++i;
++j;
if ( i >= N )
{
state->array[0] = state->array[N-1];
i = 1;
}
if( i >= MT_STATE_SIZE )
{
state->array[0] = state->array[MT_STATE_SIZE - 1];
i = 1;
}
if ( j >= key_length )
{
j = 0;
}
if( j >= key_length )
{
j = 0;
}
}
for( k = N -1; k; k-- )
{
state->array[i] = (state->array[i] ^ ((state->array[i-1] ^ (state->array[i-1] >> 30)) * 1566083941UL)) - i;
state->array[i] &= 0xffffffffUL;
++i;
for( k = MT_STATE_SIZE - 1; k; k-- )
{
state->array[i] =
( state->array[i] ^ ( ( state->array[i - 1] ^ ( state->array[i - 1] >> 30 ) ) * 1566083941UL ) ) - i;
state->array[i] &= 0xffffffffUL;
++i;
if ( i >= N )
{
state->array[0] = state->array[N-1];
i = 1;
}
if( i >= MT_STATE_SIZE )
{
state->array[0] = state->array[MT_STATE_SIZE - 1];
i = 1;
}
}
state->array[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */
state->left = 1;
state->initf = 1;
state->array[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */
state->left = 1;
state->initf = 1;
}
static void next_state( twister_state_t* state )
{
unsigned long *p = state->array;
unsigned long* p = state->array;
int j;
if( state->initf == 0) { init_genrand( state, 5489UL ); }
state->left = N;
// Ensures the generator is initialized
if( state->initf == 0 )
{
init_genrand( state, 5489UL );
}
state->left = MT_STATE_SIZE;
state->next = state->array;
for( j = N - M + 1; --j; p++ ) { *p = p[M] ^ TWIST(p[0], p[1]); }
for( j = M; --j; p++ ) { *p = p[M-N] ^ TWIST(p[0], p[1]); }
*p = p[M-N] ^ TWIST(p[0], state->array[0]);
for( j = MT_STATE_SIZE - MT_MIDDLE_WORD + 1; --j; p++ )
{
*p = p[MT_MIDDLE_WORD] ^ TWIST( p[0], p[1] );
}
for( j = MT_MIDDLE_WORD; --j; p++ )
{
*p = p[MT_MIDDLE_WORD - MT_STATE_SIZE] ^ TWIST( p[0], p[1] );
}
*p = p[MT_MIDDLE_WORD - MT_STATE_SIZE] ^ TWIST( p[0], state->array[0] );
}
/* generates a random number on [0,0xffffffff]-interval */
@@ -126,14 +138,18 @@ unsigned long twister_genrand_int32( twister_state_t* state )
{
unsigned long y;
if ( --state->left == 0 ) { next_state( state ); }
// Advance internal state if necessary
if( --state->left == 0 )
{
next_state( state );
}
y = *state->next++;
/* Tempering */
y ^= (y >> 11);
y ^= (y << 7) & 0x9d2c5680UL;
y ^= (y << 15) & 0xefc60000UL;
y ^= (y >> 18);
// Tempering
y ^= ( y >> 11 );
y ^= ( y << 7 ) & 0x9d2c5680UL;
y ^= ( y << 15 ) & 0xefc60000UL;
y ^= ( y >> 18 );
return y;
}

View File

@@ -1,30 +1,29 @@
/*
* mt19937ar-cok.h: The Mersenne Twister PRNG implementation for nwipe.
*
* mt19937ar-cok.h: The Mersenne Twister PRNG implementation for nwipe.
*/
#ifndef MT19937AR_H_
#define MT19937AR_H_
/* Period parameters */
#define N 624
#define M 397
#define MATRIX_A 0x9908b0dfUL /* constant vector a */
#define MT_STATE_SIZE 624
#define MT_MIDDLE_WORD 397
#define MATRIX_A 0x9908b0dfUL /* constant vector a */
#define UMASK 0x80000000UL /* most significant w-r bits */
#define LMASK 0x7fffffffUL /* least significant r bits */
#define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) )
#define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL))
#define MIXBITS( u, v ) ( ( (u) &UMASK ) | ( (v) &LMASK ) )
#define TWIST( u, v ) ( ( MIXBITS( u, v ) >> 1 ) ^ ( (v) &1UL ? MATRIX_A : 0UL ) )
typedef struct twister_state_t_
{
unsigned long array[N];
int left;
int initf;
unsigned long *next;
} twister_state_t;
unsigned long array[MT_STATE_SIZE]; // Updated to use MT_STATE_SIZE
int left;
int initf;
unsigned long* next;
} twister_state_t;
/* Initialize the MT state. ( 0 < key_length <= 624 ). */
void twister_init( twister_state_t* state, unsigned long init_key[], unsigned long key_length);
void twister_init( twister_state_t* state, unsigned long init_key[], unsigned long key_length );
/* Generate a random integer on the [0,0xffffffff] interval. */
unsigned long twister_genrand_int32( twister_state_t* state );

View File

@@ -42,6 +42,8 @@ int nwipe_options_parse( int argc, char** argv )
extern nwipe_prng_t nwipe_twister;
extern nwipe_prng_t nwipe_isaac;
extern nwipe_prng_t nwipe_isaac64;
extern nwipe_prng_t nwipe_add_lagg_fibonacci_prng;
extern nwipe_prng_t nwipe_xoroshiro256_prng;
/* The getopt() result holder. */
int nwipe_opt;
@@ -127,8 +129,9 @@ int nwipe_options_parse( int argc, char** argv )
/* Set default options. */
nwipe_options.autonuke = 0;
nwipe_options.autopoweroff = 0;
nwipe_options.method = &nwipe_dodshort;
nwipe_options.prng = ( sizeof( unsigned long int ) >= 8 ) ? &nwipe_isaac64 : &nwipe_isaac;
nwipe_options.method = &nwipe_random;
nwipe_options.prng =
( sizeof( unsigned long int ) >= 8 ) ? &nwipe_xoroshiro256_prng : &nwipe_add_lagg_fibonacci_prng;
nwipe_options.rounds = 1;
nwipe_options.noblank = 0;
nwipe_options.nousb = 0;
@@ -490,6 +493,16 @@ int nwipe_options_parse( int argc, char** argv )
nwipe_options.prng = &nwipe_isaac64;
break;
}
if( strcmp( optarg, "add_lagg_fibonacci_prng" ) == 0 )
{
nwipe_options.prng = &nwipe_add_lagg_fibonacci_prng;
break;
}
if( strcmp( optarg, "xoroshiro256_prng" ) == 0 )
{
nwipe_options.prng = &nwipe_xoroshiro256_prng;
break;
}
/* Else we do not know this PRNG. */
fprintf( stderr, "Error: Unknown prng '%s'.\n", optarg );
@@ -539,6 +552,8 @@ void nwipe_options_log( void )
extern nwipe_prng_t nwipe_twister;
extern nwipe_prng_t nwipe_isaac;
extern nwipe_prng_t nwipe_isaac64;
extern nwipe_prng_t nwipe_add_lagg_fibonacci_prng;
extern nwipe_prng_t nwipe_xoroshiro256_prng;
/**
* Prints a manifest of options to the log.
@@ -592,19 +607,33 @@ void nwipe_options_log( void )
}
else
{
if( nwipe_options.prng == &nwipe_isaac )
if( nwipe_options.prng == &nwipe_add_lagg_fibonacci_prng )
{
nwipe_log( NWIPE_LOG_NOTICE, " prng = Isaac" );
nwipe_log( NWIPE_LOG_NOTICE, " prng = Lagged Fibonacci generator (EXPERIMENTAL!)" );
}
else
{
if( nwipe_options.prng == &nwipe_isaac64 )
if( nwipe_options.prng == &nwipe_xoroshiro256_prng )
{
nwipe_log( NWIPE_LOG_NOTICE, " prng = Isaac64" );
nwipe_log( NWIPE_LOG_NOTICE, " prng = XORoshiro-256 (EXPERIMENTAL!)" );
}
else
{
nwipe_log( NWIPE_LOG_NOTICE, " prng = Undefined" );
if( nwipe_options.prng == &nwipe_isaac )
{
nwipe_log( NWIPE_LOG_NOTICE, " prng = Isaac" );
}
else
{
if( nwipe_options.prng == &nwipe_isaac64 )
{
nwipe_log( NWIPE_LOG_NOTICE, " prng = Isaac64" );
}
else
{
nwipe_log( NWIPE_LOG_NOTICE, " prng = Undefined" );
}
}
}
}
}
@@ -666,7 +695,10 @@ void display_help()
puts( " (default: last)" );
puts( " off - Do not verify" );
puts( " last - Verify after the last pass" );
puts( " all - Verify every pass\n" );
puts( " all - Verify every pass" );
puts( " " );
puts( " Please mind that HMG IS5 enhanced always verifies the" );
puts( " last (PRNG) pass regardless of this option.\n" );
puts( " -m, --method=METHOD The wiping method. See man page for more details." );
puts( " (default: dodshort)" );
puts( " dod522022m / dod - 7 pass DOD 5220.22-M method" );
@@ -677,11 +709,12 @@ void display_help()
puts( " zero / quick - Overwrite with zeros" );
puts( " one - Overwrite with ones (0xFF)" );
puts( " verify_zero - Verifies disk is zero filled" );
puts( " verify_one - Verifies disk is 0xFF filled\n" );
puts( " verify_one - Verifies disk is 0xFF filled" );
puts( " is5enh - HMG IS5 enhanced\n" );
puts( " -l, --logfile=FILE Filename to log to. Default is STDOUT\n" );
puts( " -P, --PDFreportpath=PATH Path to write PDF reports to. Default is \".\"" );
puts( " If set to \"noPDF\" no PDF reports are written.\n" );
puts( " -p, --prng=METHOD PRNG option (mersenne|twister|isaac|isaac64)\n" );
puts( " -p, --prng=METHOD PRNG option (mersenne|twister|isaac|isaac64|add_lagg_fibonacci_prng)\n" );
puts( " -q, --quiet Anonymize logs and the GUI by removing unique data, i.e." );
puts( " serial numbers, LU WWN Device ID, and SMBIOS/DMI data" );
puts( " XXXXXX = S/N exists, ????? = S/N not obtainable\n" );

View File

@@ -324,7 +324,7 @@ int nwipe_random_pass( NWIPE_METHOD_SIGNATURE )
/* For the first block only, check the prng actually wrote something to the buffer */
if( z == c->device_size )
{
idx = c->device_stat.st_blksize;
idx = c->device_stat.st_blksize - 1;
while( idx > 0 )
{
if( b[idx] != 0 )

View File

@@ -25,12 +25,21 @@
#include "mt19937ar-cok/mt19937ar-cok.h"
#include "isaac_rand/isaac_rand.h"
#include "isaac_rand/isaac64.h"
#include "alfg/add_lagg_fibonacci_prng.h" //Lagged Fibonacci generator prototype
#include "xor/xoroshiro256_prng.h" //XORoshiro-256 prototype
nwipe_prng_t nwipe_twister = { "Mersenne Twister (mt19937ar-cok)", nwipe_twister_init, nwipe_twister_read };
nwipe_prng_t nwipe_isaac = { "ISAAC (rand.c 20010626)", nwipe_isaac_init, nwipe_isaac_read };
nwipe_prng_t nwipe_isaac64 = { "ISAAC-64 (isaac64.c)", nwipe_isaac64_init, nwipe_isaac64_read };
/* ALFG PRNG Structure */
nwipe_prng_t nwipe_add_lagg_fibonacci_prng = { "Lagged Fibonacci generator",
nwipe_add_lagg_fibonacci_prng_init,
nwipe_add_lagg_fibonacci_prng_read };
/* XOROSHIRO-256 PRNG Structure */
nwipe_prng_t nwipe_xoroshiro256_prng = { "XORoshiro-256", nwipe_xoroshiro256_prng_init, nwipe_xoroshiro256_prng_read };
/* Print given number of bytes from unsigned integer number to a byte stream buffer starting with low-endian. */
static inline void u32_to_buffer( u8* restrict buffer, u32 val, const int len )
{
@@ -250,3 +259,85 @@ int nwipe_isaac64_read( NWIPE_PRNG_READ_SIGNATURE )
return 0;
}
/* EXPERIMENTAL implementation of Lagged Fibonacci generator a lot of random numbers */
int nwipe_add_lagg_fibonacci_prng_init( NWIPE_PRNG_INIT_SIGNATURE )
{
if( *state == NULL )
{
nwipe_log( NWIPE_LOG_NOTICE, "Initialising Lagged Fibonacci generator PRNG" );
*state = malloc( sizeof( add_lagg_fibonacci_state_t ) );
}
add_lagg_fibonacci_init(
(add_lagg_fibonacci_state_t*) *state, (unsigned long*) ( seed->s ), seed->length / sizeof( unsigned long ) );
return 0;
}
/* EXPERIMENTAL implementation of XORoroshiro256 algorithm to provide high-quality, but a lot of random numbers */
int nwipe_xoroshiro256_prng_init( NWIPE_PRNG_INIT_SIGNATURE )
{
nwipe_log( NWIPE_LOG_NOTICE, "Initialising XORoroshiro-256 PRNG" );
if( *state == NULL )
{
/* This is the first time that we have been called. */
*state = malloc( sizeof( xoroshiro256_state_t ) );
}
xoroshiro256_init(
(xoroshiro256_state_t*) *state, (unsigned long*) ( seed->s ), seed->length / sizeof( unsigned long ) );
return 0;
}
int nwipe_add_lagg_fibonacci_prng_read( NWIPE_PRNG_READ_SIGNATURE )
{
u8* restrict bufpos = buffer;
size_t words = count / SIZE_OF_ADD_LAGG_FIBONACCI_PRNG;
/* Loop to fill the buffer with blocks directly from the Fibonacci algorithm */
for( size_t ii = 0; ii < words; ++ii )
{
add_lagg_fibonacci_genrand_uint256_to_buf( (add_lagg_fibonacci_state_t*) *state, bufpos );
bufpos += SIZE_OF_ADD_LAGG_FIBONACCI_PRNG; // Move to the next block
}
/* Handle remaining bytes if count is not a multiple of SIZE_OF_ADD_LAGG_FIBONACCI_PRNG */
const size_t remain = count % SIZE_OF_ADD_LAGG_FIBONACCI_PRNG;
if( remain > 0 )
{
unsigned char temp_output[16]; // Temporary buffer for the last block
add_lagg_fibonacci_genrand_uint256_to_buf( (add_lagg_fibonacci_state_t*) *state, temp_output );
// Copy the remaining bytes
memcpy( bufpos, temp_output, remain );
}
return 0; // Success
}
int nwipe_xoroshiro256_prng_read( NWIPE_PRNG_READ_SIGNATURE )
{
u8* restrict bufpos = buffer;
size_t words = count / SIZE_OF_XOROSHIRO256_PRNG;
/* Loop to fill the buffer with blocks directly from the XORoroshiro256 algorithm */
for( size_t ii = 0; ii < words; ++ii )
{
xoroshiro256_genrand_uint256_to_buf( (xoroshiro256_state_t*) *state, bufpos );
bufpos += SIZE_OF_XOROSHIRO256_PRNG; // Move to the next block
}
/* Handle remaining bytes if count is not a multiple of SIZE_OF_XOROSHIRO256_PRNG */
const size_t remain = count % SIZE_OF_XOROSHIRO256_PRNG;
if( remain > 0 )
{
unsigned char temp_output[16]; // Temporary buffer for the last block
xoroshiro256_genrand_uint256_to_buf( (xoroshiro256_state_t*) *state, temp_output );
// Copy the remaining bytes
memcpy( bufpos, temp_output, remain );
}
return 0; // Success
}

View File

@@ -55,6 +55,14 @@ int nwipe_isaac_read( NWIPE_PRNG_READ_SIGNATURE );
int nwipe_isaac64_init( NWIPE_PRNG_INIT_SIGNATURE );
int nwipe_isaac64_read( NWIPE_PRNG_READ_SIGNATURE );
/* ALFG prototypes. */
int nwipe_add_lagg_fibonacci_prng_init( NWIPE_PRNG_INIT_SIGNATURE );
int nwipe_add_lagg_fibonacci_prng_read( NWIPE_PRNG_READ_SIGNATURE );
/* XOROSHIRO-256 prototypes. */
int nwipe_xoroshiro256_prng_init( NWIPE_PRNG_INIT_SIGNATURE );
int nwipe_xoroshiro256_prng_read( NWIPE_PRNG_READ_SIGNATURE );
/* Size of the twister is not derived from the architecture, but it is strictly 4 bytes */
#define SIZE_OF_TWISTER 4
@@ -62,4 +70,10 @@ int nwipe_isaac64_read( NWIPE_PRNG_READ_SIGNATURE );
#define SIZE_OF_ISAAC 4
#define SIZE_OF_ISAAC64 8
/* Size of the Lagged Fibonacci generator is not derived from the architecture, but it is strictly 32 bytes */
#define SIZE_OF_ADD_LAGG_FIBONACCI_PRNG 32
/* Size of the XOROSHIRO-256 is not derived from the architecture, but it is strictly 32 bytes */
#define SIZE_OF_XOROSHIRO256_PRNG 32
#endif /* PRNG_H_ */

View File

@@ -16,8 +16,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
//#define _LARGEFILE64_SOURCE
//#define _FILE_OFFSET_BITS 64
// #define _LARGEFILE64_SOURCE
// #define _FILE_OFFSET_BITS 64
#define _BSD_SOURCE
#include <stdio.h>

View File

@@ -4,7 +4,7 @@
* used by configure to dynamically assign those values
* to documentation files.
*/
const char* version_string = "0.36";
const char* version_string = "0.37";
const char* program_name = "nwipe";
const char* author_name = "Martijn van Brummelen";
const char* email_address = "git@brumit.nl";
@@ -14,4 +14,4 @@ Modifications to original dwipe Copyright Andy Beverley <andy@andybev.com>\n\
This is free software; see the source for copying conditions.\n\
There is NO warranty; not even for MERCHANTABILITY or FITNESS\n\
FOR A PARTICULAR PURPOSE.\n";
const char* banner = "nwipe 0.36";
const char* banner = "nwipe 0.37";

View File

@@ -0,0 +1,74 @@
/*
* XORoshiro-256 PRNG Implementation
* Author: Fabian Druschke
* Date: 2024-03-13
*
* This is a XORoshiro-256 (XOR/rotate/shift/rotate) pseudorandom number generator
* implementation, designed for fast and efficient generation of high-quality
* pseudorandom numbers. XORoshiro-256 is part of the XORoshiro family of PRNGs known
* for their simplicity and excellent statistical properties for a wide range of
* applications, though they are not suitable for cryptographic purposes due to their
* predictability.
*
* As the author of this implementation, I, Fabian Druschke, hereby release this work into
* the public domain. I dedicate any and all copyright interest in this work to the public
* domain, making it free to use for anyone for any purpose without any conditions, unless
* such conditions are required by law.
*
* This software is provided "as is", without warranty of any kind, express or implied,
* including but not limited to the warranties of merchantability, fitness for a particular
* purpose, and noninfringement. In no event shall the authors be liable for any claim,
* damages, or other liability, whether in an action of contract, tort, or otherwise, arising
* from, out of, or in connection with the software or the use or other dealings in the software.
*
* Note: This implementation does not utilize OpenSSL or any cryptographic libraries, as
* XORoshiro-256 is not intended for cryptographic applications. It is crucial for applications
* requiring cryptographic security to use a cryptographically secure PRNG.
*/
#include "xoroshiro256_prng.h"
#include <stdint.h>
#include <string.h>
void xoroshiro256_init( xoroshiro256_state_t* state, uint64_t init_key[], unsigned long key_length )
{
// Initialization logic; ensure 256 bits are properly seeded
for( int i = 0; i < 4; i++ )
{
if( i < key_length )
{
state->s[i] = init_key[i];
}
else
{
// Example fallback for insufficient seeds; consider better seeding strategies
state->s[i] = state->s[i - 1] * 6364136223846793005ULL + 1;
}
}
}
static inline uint64_t rotl( const uint64_t x, int k )
{
return ( x << k ) | ( x >> ( 64 - k ) );
}
void xoroshiro256_genrand_uint256_to_buf( xoroshiro256_state_t* state, unsigned char* bufpos )
{
// This part of the code updates the state using xoroshiro256**'s algorithm.
const uint64_t result_starstar = rotl( state->s[1] * 5, 7 ) * 9;
const uint64_t t = state->s[1] << 17;
state->s[2] ^= state->s[0];
state->s[3] ^= state->s[1];
state->s[1] ^= state->s[2];
state->s[0] ^= state->s[3];
state->s[2] ^= t;
state->s[3] = rotl( state->s[3], 45 );
// Note: 'result_starstar' was only used for demonstration purposes and is not part of the
// original Xoroshiro256** specification. Here, we write the complete state into the buffer.
// Ensure that 'bufpos' has enough storage space (256 bits / 32 bytes).
memcpy( bufpos, state->s, 32 ); // Copies the entire 256-bit (32 bytes) state into 'bufpos'
}

View File

@@ -0,0 +1,44 @@
/*
* XORoshiro-256 PRNG Definitions
* Author: Fabian Druschke
* Date: 2024-03-13
*
* This header file contains definitions for the XORoshiro-256 pseudorandom number generator
* (PRNG) implementation. XORoshiro-256 is part of the XORoshiro family of PRNGs, known for
* their simplicity, efficiency, and high-quality pseudorandom number generation suitable for
* a wide range of applications, excluding cryptographic purposes due to its predictable nature.
*
* As the author of this work, I, Fabian Druschke, hereby release this work into the public
* domain. I dedicate any and all copyright interest in this work to the public domain, making
* it free to use for anyone for any purpose without any conditions, unless such conditions are
* required by law.
*
* This software is provided "as is", without warranty of any kind, express or implied,
* including but not limited to the warranties of merchantability, fitness for a particular
* purpose, and noninfringement. In no event shall the authors be liable for any claim,
* damages, or other liability, whether in an action of contract, tort, or otherwise, arising
* from, out of, or in connection with the software or the use or other dealings in the software.
*
* Note: This implementation does not utilize any cryptographic libraries, as XORoshiro-256 is
* not intended for cryptographic applications. It is crucial for applications requiring
* cryptographic security to use a cryptographically secure PRNG.
*/
#ifndef XOROSHIRO256_PRNG_H
#define XOROSHIRO256_PRNG_H
#include <stdint.h>
// Structure to store the state of the xoroshiro256** random number generator
typedef struct xoroshiro256_state_s
{
uint64_t s[4];
} xoroshiro256_state_t;
// Initializes the xoroshiro256** random number generator with a seed
void xoroshiro256_init( xoroshiro256_state_t* state, uint64_t init_key[], unsigned long key_length );
// Generates a 256-bit random number using xoroshiro256** and stores it directly in the output buffer
void xoroshiro256_genrand_uint256_to_buf( xoroshiro256_state_t* state, unsigned char* bufpos );
#endif // XOROSHIRO256_PRNG_H