Add ISAAC rand

This commit is contained in:
Simon 2022-01-30 00:53:20 +00:00
parent 5a1de60e4d
commit 45dbdf1fc7
8 changed files with 328 additions and 48 deletions

View File

@ -13,4 +13,5 @@ project(romulus
)
set(CMAKE_POSITION_INDEPENDENT_CODE on)
add_subdirectory(ISAAC/)
add_subdirectory(Romulus-M/)

6
ISAAC/CMakeLists.txt Normal file
View File

@ -0,0 +1,6 @@
set(SRC
rand.c
)
add_library(isaac STATIC ${SRC})

137
ISAAC/rand.c Normal file
View File

@ -0,0 +1,137 @@
/*
------------------------------------------------------------------------------
rand.c: By Bob Jenkins. My random number generator, ISAAC. Public Domain.
MODIFIED:
960327: Creation (addition of randinit, really)
970719: use context, not global variables, for internal state
980324: added main (ifdef'ed out), also rearranged randinit()
010626: Note that this is public domain
------------------------------------------------------------------------------
*/
#ifndef STANDARD
#include "standard.h"
#endif
#ifndef RAND
#include "rand.h"
#endif
#define ind(mm,x) (*(ub4 *)((ub1 *)(mm) + ((x) & ((RANDSIZ-1)<<2))))
#define rngstep(mix,a,b,mm,m,m2,r,x) \
{ \
x = *m; \
a = (a^(mix)) + *(m2++); \
*(m++) = y = ind(mm,x) + a + b; \
*(r++) = b = ind(mm,y>>RANDSIZL) + x; \
}
void isaac(ctx)
randctx *ctx;
{
register ub4 a,b,x,y,*m,*mm,*m2,*r,*mend;
mm=ctx->randmem; r=ctx->randrsl;
a = ctx->randa; b = ctx->randb + (++ctx->randc);
for (m = mm, mend = m2 = m+(RANDSIZ/2); m<mend; )
{
rngstep( a<<13, a, b, mm, m, m2, r, x);
rngstep( a>>6 , a, b, mm, m, m2, r, x);
rngstep( a<<2 , a, b, mm, m, m2, r, x);
rngstep( a>>16, a, b, mm, m, m2, r, x);
}
for (m2 = mm; m2<mend; )
{
rngstep( a<<13, a, b, mm, m, m2, r, x);
rngstep( a>>6 , a, b, mm, m, m2, r, x);
rngstep( a<<2 , a, b, mm, m, m2, r, x);
rngstep( a>>16, a, b, mm, m, m2, r, x);
}
ctx->randb = b; ctx->randa = a;
}
#define mix(a,b,c,d,e,f,g,h) \
{ \
a^=b<<11; d+=a; b+=c; \
b^=c>>2; e+=b; c+=d; \
c^=d<<8; f+=c; d+=e; \
d^=e>>16; g+=d; e+=f; \
e^=f<<10; h+=e; f+=g; \
f^=g>>4; a+=f; g+=h; \
g^=h<<8; b+=g; h+=a; \
h^=a>>9; c+=h; a+=b; \
}
/* if (flag==TRUE), then use the contents of randrsl[] to initialize mm[]. */
void randinit(ctx, flag)
randctx *ctx;
word flag;
{
word i;
ub4 a,b,c,d,e,f,g,h;
ub4 *m,*r;
ctx->randa = ctx->randb = ctx->randc = 0;
m=ctx->randmem;
r=ctx->randrsl;
a=b=c=d=e=f=g=h=0x9e3779b9; /* the golden ratio */
for (i=0; i<4; ++i) /* scramble it */
{
mix(a,b,c,d,e,f,g,h);
}
if (flag)
{
/* initialize using the contents of r[] as the seed */
for (i=0; i<RANDSIZ; i+=8)
{
a+=r[i ]; b+=r[i+1]; c+=r[i+2]; d+=r[i+3];
e+=r[i+4]; f+=r[i+5]; g+=r[i+6]; h+=r[i+7];
mix(a,b,c,d,e,f,g,h);
m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
}
/* do a second pass to make all of the seed affect all of m */
for (i=0; i<RANDSIZ; i+=8)
{
a+=m[i ]; b+=m[i+1]; c+=m[i+2]; d+=m[i+3];
e+=m[i+4]; f+=m[i+5]; g+=m[i+6]; h+=m[i+7];
mix(a,b,c,d,e,f,g,h);
m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
}
}
else
{
/* fill in m[] with messy stuff */
for (i=0; i<RANDSIZ; i+=8)
{
mix(a,b,c,d,e,f,g,h);
m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
}
}
isaac(ctx); /* fill in the first set of results */
ctx->randcnt=RANDSIZ; /* prepare to use the first set of results */
}
#ifdef NEVER
int main()
{
ub4 i,j;
randctx ctx;
ctx.randa=ctx.randb=ctx.randc=(ub4)0;
for (i=0; i<256; ++i) ctx.randrsl[i]=(ub4)0;
randinit(&ctx, TRUE);
for (i=0; i<2; ++i)
{
isaac(&ctx);
for (j=0; j<256; ++j)
{
printf("%.8lx",ctx.randrsl[j]);
if ((j&7)==7) printf("\n");
}
}
}
#endif

56
ISAAC/rand.h Normal file
View File

@ -0,0 +1,56 @@
/*
------------------------------------------------------------------------------
rand.h: definitions for a random number generator
By Bob Jenkins, 1996, Public Domain
MODIFIED:
960327: Creation (addition of randinit, really)
970719: use context, not global variables, for internal state
980324: renamed seed to flag
980605: recommend RANDSIZL=4 for noncryptography.
010626: note this is public domain
------------------------------------------------------------------------------
*/
#ifndef STANDARD
#include "standard.h"
#endif
#ifndef RAND
#define RAND
#define RANDSIZL (8)
#define RANDSIZ (1<<RANDSIZL)
/* context of random number generator */
struct randctx
{
ub4 randcnt;
ub4 randrsl[RANDSIZ];
ub4 randmem[RANDSIZ];
ub4 randa;
ub4 randb;
ub4 randc;
};
typedef struct randctx randctx;
/*
------------------------------------------------------------------------------
If (flag==TRUE), then use the contents of randrsl[0..RANDSIZ-1] as the seed.
------------------------------------------------------------------------------
*/
void randinit(/*_ randctx *r, word flag _*/);
void isaac(/*_ randctx *r _*/);
/*
------------------------------------------------------------------------------
Call rand(/o_ randctx *r _o/) to retrieve a single 32-bit random value
------------------------------------------------------------------------------
*/
#define rand(r) \
(!(r)->randcnt-- ? \
(isaac(r), (r)->randcnt=RANDSIZ-1, (r)->randrsl[(r)->randcnt]) : \
(r)->randrsl[(r)->randcnt])
#endif /* RAND */

57
ISAAC/standard.h Normal file
View File

@ -0,0 +1,57 @@
/*
------------------------------------------------------------------------------
Standard definitions and types, Bob Jenkins
------------------------------------------------------------------------------
*/
#ifndef STANDARD
# define STANDARD
# ifndef STDIO
# include <stdio.h>
# define STDIO
# endif
# ifndef STDDEF
# include <stddef.h>
# define STDDEF
# endif
typedef unsigned long long ub8;
#define UB8MAXVAL 0xffffffffffffffffLL
#define UB8BITS 64
typedef signed long long sb8;
#define SB8MAXVAL 0x7fffffffffffffffLL
typedef unsigned long int ub4; /* unsigned 4-byte quantities */
#define UB4MAXVAL 0xffffffff
typedef signed long int sb4;
#define UB4BITS 32
#define SB4MAXVAL 0x7fffffff
typedef unsigned short int ub2;
#define UB2MAXVAL 0xffff
#define UB2BITS 16
typedef signed short int sb2;
#define SB2MAXVAL 0x7fff
typedef unsigned char ub1;
#define UB1MAXVAL 0xff
#define UB1BITS 8
typedef signed char sb1; /* signed 1-byte quantities */
#define SB1MAXVAL 0x7f
typedef int word; /* fastest type available */
#define bis(target,mask) ((target) |= (mask))
#define bic(target,mask) ((target) &= ~(mask))
#define bit(target,mask) ((target) & (mask))
#ifndef min
# define min(a,b) (((a)<(b)) ? (a) : (b))
#endif /* min */
#ifndef max
# define max(a,b) (((a)<(b)) ? (b) : (a))
#endif /* max */
#ifndef align
# define align(a) (((ub4)a+(sizeof(void *)-1))&(~(sizeof(void *)-1)))
#endif /* align */
#ifndef abs
# define abs(a) (((a)>0) ? (a) : -(a))
#endif
#define TRUE 1
#define FALSE 0
#define SUCCESS 0 /* 1 on VAX */
#endif /* STANDARD */

View File

@ -6,5 +6,6 @@ set(SRC
encrypt_wrapper.c
)
include_directories(../ISAAC)
link_libraries(isaac)
add_library(romulus-m STATIC ${SRC})
install(TARGETS romulus-m)

View File

@ -3,22 +3,32 @@
#include <string.h>
#ifdef _MSC_VER
#define _CRT_RAND_S
#define __bswap_16 _byteswap_ushort
#define __bswap_32 _byteswap_ulong
#else
#include <byteswap.h>
#include <sys/random.h>
#endif
#include <stdlib.h>
#include "romulus_m.h"
#include "api.h"
#include <rand.h>
#ifdef _DEBUG
#define DEBUG_PRINT printf
#else
#define DEBUG_PRINT
#endif
int encrypt(packet *packet, unsigned char* outBuf, UINT16 *len, unsigned char* key){
if(sizeof(UINT16) + sizeof(UINT16) + packet->Size > *len){
#define MIN(a,b) ((a) < (b) ? (a) : (b))
randctx rCtx = {0};
int encrypt(packet *packet, unsigned char *outBuf, UINT16 *len, unsigned char *key)
{
randinit();
if (sizeof(UINT16) + sizeof(UINT16) + packet->Size > *len)
{
return 1;
}
@ -26,32 +36,25 @@ int encrypt(packet *packet, unsigned char* outBuf, UINT16 *len, unsigned char* k
// enc
// ciphertext - out, MAX 16 bytes larger than plaintext - defined as CRYPTO_ABYTES
unsigned long long clen = packetSize + CRYPTO_ABYTES;
unsigned char* c = (unsigned char*) calloc(clen, 1);
unsigned char *c = (unsigned char *)calloc(clen, 1);
// plaintext - in
int mlen = packetSize;
unsigned char* m = packet->Data;
unsigned char *m = packet->Data;
// additional text
int adlen = sizeof(packet->DataType);
unsigned char* ad = (unsigned char*)&packet->DataType;
unsigned char *ad = (unsigned char *)&packet->DataType;
// n = nonce, CRYPTO_NPUBBYTES size 16
unsigned char npub[CRYPTO_NPUBBYTES];
#ifdef _MSC_VER
UINT32 secRandom;
for (size_t i = 0; i < CRYPTO_NPUBBYTES; i+=sizeof(UINT32))
{
rand_s(&secRandom);
memcpy(&npub[i], &secRandom, sizeof(UINT32));
}
#else
getrandom(&npub[0], sizeof(npub), 0);
#endif
fill_random(npub, CRYPTO_NPUBBYTES);
int ret = romulus_m_encrypt(c, &clen, m, mlen, ad, adlen, 0, &npub[0], key);
if(clen > *len + CRYPTO_NPUBBYTES || ret != 0){
if (clen > *len + CRYPTO_NPUBBYTES || ret != 0)
{
free(c);
return 1;
}
@ -60,7 +63,7 @@ int encrypt(packet *packet, unsigned char* outBuf, UINT16 *len, unsigned char* k
// Swap after adding it as additional data
packet->DataType = __bswap_16(packet->DataType);
int loc = 0;
memcpy(&outBuf[loc], &packet->DataType,sizeof(UINT16));
memcpy(&outBuf[loc], &packet->DataType, sizeof(UINT16));
loc += sizeof(UINT16);
// data size 2 3
@ -84,11 +87,14 @@ int encrypt(packet *packet, unsigned char* outBuf, UINT16 *len, unsigned char* k
return 0;
}
int decrypt(packetEx *packet, unsigned char* inBuf, UINT16 len, unsigned char* key){
int decrypt(packetEx *packet, unsigned char *inBuf, UINT16 len, unsigned char *key)
{
int loc = 0;
if(inBuf == 0 ){
if (inBuf == 0)
{
return 1;
}
DEBUG_PRINT("line %d\n", 95);
memcpy(&packet->DataType, &inBuf[loc], sizeof(UINT16));
loc += sizeof(UINT16);
memcpy(&packet->Id, &inBuf[loc], sizeof(UINT32));
@ -100,38 +106,52 @@ int decrypt(packetEx *packet, unsigned char* inBuf, UINT16 len, unsigned char* k
packet->Size = __bswap_16(packet->Size);
packet->Id = __bswap_32(packet->Id);
if(packet->Size < CRYPTO_NPUBBYTES){
if ((len - loc) < 0 || packet->Size < CRYPTO_NPUBBYTES || packet->Size > 1000)
{
return 1;
}
DEBUG_PRINT("line %d\n", 111);
// Data
// Nonce|Data
// dec
// n = nonce, CRYPTO_NPUBBYTES size 16
unsigned char* npub = &inBuf[loc];
unsigned char *npub = &inBuf[loc];
loc += CRYPTO_NPUBBYTES;
// ciphertext - out, MAX 16 bytes larger than plaintext - defined as CRYPTO_ABYTES
int clen = packet->Size - CRYPTO_NPUBBYTES;
unsigned char* c = &inBuf[loc];
// ciphertext - in, MAX 16 bytes larger than plaintext - defined as CRYPTO_ABYTES
int clen = len - loc;
unsigned char *c = &inBuf[loc];
DEBUG_PRINT("line %d len:%d loc:%d\n", 132, len, loc);
// plaintext - in
// plaintext - out
unsigned long long mlen = clen;
unsigned char* m = (unsigned char*)calloc(mlen, 1);
unsigned char *m = (unsigned char *)calloc(clen, 1);
// additional text
int adlen = sizeof(packet->DataType);
unsigned char* ad = (unsigned char*)&packet->DataType;
unsigned char *ad = (unsigned char *)&packet->DataType;
DEBUG_PRINT("line %d mlen:%d clen:%d\n", 132, mlen, clen);
int ret = romulus_m_decrypt(m, &mlen, 0, c, clen, ad, adlen, npub, key);
if(mlen <= 1000 && ret == 0){
DEBUG_PRINT("line %d packet:%d, mlen %d\n", 134, packet->Size, mlen);
if (ret == 0)
{
DEBUG_PRINT("line %d\n", 138);
memcpy(packet->Data, m, mlen);
packet->Size = (UINT16)mlen;
}
else{
free(m);
return -1;
}
free(m);
return 0;
DEBUG_PRINT("line %d\n", 143);
return ret;
}
void fill_random(unsigned char* buffer, int length){
UINT32 secRandom;
for (size_t i = 0; i < length; i += sizeof(UINT32))
{
secRandom = rand(&rCtx);
memcpy(&buffer[i], &secRandom, MIN(sizeof(UINT32), length-i));
}
}

View File

@ -27,3 +27,5 @@ EXPORT int encrypt(packet *packet, unsigned char* outBuf, UINT16 *len, unsigned
EXPORT int decrypt(packetEx *packet, unsigned char* inBuf, UINT16 len, unsigned char* key);
void fill_random(unsigned char* buffer, int length);