;;;; ripemd160-api.scm -*- Scheme -*- ;;;; Kon Lovett, Sep '21 ;; Issues #> typedef void (*initializef)( uint32_t * ); typedef void (*compressf)( uint32_t *, uint32_t * ); typedef void (*finishf)( uint32_t *, uint8_t *, uint32_t, uint32_t ); typedef struct { uint8_t rembuf[16 * sizeof(uint32_t)]; uint32_t length[2]; uint32_t MDbuf[0]; } ripemdctx; static void ripemdX_init( initializef init, ripemdctx *ctx ) { memset( ctx->rembuf, 0, sizeof(ctx->rembuf) ); ctx->length[0] = ctx->length[1] = 0; (*init)( ctx->MDbuf ); } static void ripemdX_update( compressf compress, ripemdctx *ctx, uint8_t *data, size_t nbytes ) { # define BYTES_TO_DWORD( strptr ) \ (((uint32_t) *((strptr)+3) << 24) | \ ((uint32_t) *((strptr)+2) << 16) | \ ((uint32_t) *((strptr)+1) << 8) | \ ((uint32_t) *(strptr))) uint32_t X[16]; unsigned int i, j; /* process all complete 16-uint32_t blocks */ for( i = nbytes; i > 63; i -= 64 ) { for( j = 0; j < 16; j++ ) { X[j] = BYTES_TO_DWORD( data ); data += sizeof(uint32_t); } (*compress)( ctx->MDbuf, X ); } /* update length[] */ if( ctx->length[0] + nbytes < ctx->length[0] ) ctx->length[1]++; /* overflow to msb of length */ ctx->length[0] += nbytes; /* remaining bytes? */ /* MUST only occur on the last call to update */ if( i ) { memcpy( ctx->rembuf, data, i ); } # undef BYTES_TO_DWORD } static void ripemdX_final( finishf finish, uint8_t *str, ripemdctx *ctx, size_t mdlen ) { int i; (*finish)( ctx->MDbuf, ctx->rembuf, ctx->length[0], ctx->length[1] ); for( i = 0; i < mdlen; i += sizeof(uint32_t) ) { str[i] = ctx->MDbuf[i>>2]; str[i+1] = (ctx->MDbuf[i>>2] >> 8); str[i+2] = (ctx->MDbuf[i>>2] >> 16); str[i+3] = (ctx->MDbuf[i>>2] >> 24); } } #define C_VISIBILITY static #define dword uint32_t #define byte uint8_t #include "rmd160.c" #define RMD160blksiz 64 #define RMD160hshsiz (160/8) #define RMD160ctxsiz (sizeof(ripemdctx) + sizeof(uint32_t)*(160/32)) #undef BYTES_TO_DWORD #undef ROL #undef F #undef G #undef H #undef I #undef J #undef FF #undef GG #undef HH #undef II #undef JJ #undef FFF #undef GGG #undef HHH #undef III #undef JJJ #undef dword #undef byte #undef C_VISIBILITY <# (module ripemd160-api (;export name version context-size digest-length block-length init update final raw-update) (import scheme (chicken base) (chicken foreign) (chicken type)) ;; (define name 'ripemd160) (define version "1.0.0") ;; (define-foreign-variable DIGEST_LENGTH size_t "RMD160hshsiz") (define-foreign-variable BLOCK_LENGTH size_t "RMD160blksiz") (define-foreign-variable CONTEXT_SIZE size_t "RMD160ctxsiz") (define context-size CONTEXT_SIZE) (define digest-length DIGEST_LENGTH) (define block-length BLOCK_LENGTH) (define init (foreign-lambda* void ((nonnull-c-pointer ctx)) "ripemdX_init( &MDinit160, ctx );")) (define update (foreign-lambda* void ((nonnull-c-pointer ctx) (nonnull-scheme-pointer obj) (size_t len)) "ripemdX_update( &compress160, ctx, obj, len );")) (define final (foreign-lambda* void ((nonnull-c-pointer ctx) (nonnull-scheme-pointer result)) "ripemdX_final( &MDfinish160, result, ctx, RMD160hshsiz );")) (define raw-update (foreign-lambda* void ((nonnull-c-pointer ctx) (nonnull-c-pointer obj) (size_t len)) "ripemdX_update( &compress160, ctx, obj, len );")) ) ;module ripemd160-api