source: project/release/4/ripemd/trunk/ripemd.scm @ 34381

Last change on this file since 34381 was 34381, checked in by kon, 23 months ago

add raw-update

File size: 4.9 KB
Line 
1;;;; ripemd.scm
2;;;; Kon Lovett, Jan '06
3;;;; Kon Lovett, Aug '10
4
5(module ripemd
6
7(;export
8  ripemd128-primitive
9  ripemd160-primitive)
10
11(import scheme chicken foreign)
12(use message-digest-primitive)
13
14;;;
15
16#>
17typedef void (*initializef)( uint32_t * );
18typedef void (*compressf)( uint32_t *, uint32_t * );
19typedef void (*finishf)( uint32_t *, uint8_t *, uint32_t, uint32_t );
20
21typedef struct {
22  uint8_t rembuf[16 * sizeof(uint32_t)];
23  uint32_t length[2];
24  uint32_t MDbuf[0];
25} ripemdctx;
26
27static void
28ripemdX_init( initializef init, ripemdctx *ctx )
29{
30  memset( ctx->rembuf, 0, sizeof(ctx->rembuf) );
31  ctx->length[0] = ctx->length[1] = 0;
32  (*init)( ctx->MDbuf );
33}
34
35static void
36ripemdX_update( compressf compress, ripemdctx *ctx, uint8_t *data, size_t nbytes )
37{
38# define BYTES_TO_DWORD( strptr ) \
39    (((uint32_t) *((strptr)+3) << 24) | \
40     ((uint32_t) *((strptr)+2) << 16) | \
41     ((uint32_t) *((strptr)+1) <<  8) | \
42     ((uint32_t) *(strptr)))
43
44  uint32_t X[16];
45  unsigned int i, j;
46
47  /* process all complete 16-uint32_t blocks */
48  for( i = nbytes; i > 63; i -= 64 ) {
49     for( j = 0; j < 16; j++ ) {
50        X[j] = BYTES_TO_DWORD( data );
51        data += sizeof(uint32_t);
52      }
53     (*compress)( ctx->MDbuf, X );
54  }
55
56  /* update length[] */
57  if( ctx->length[0] + nbytes < ctx->length[0] )
58     ctx->length[1]++;      /* overflow to msb of length */
59  ctx->length[0] += nbytes;
60
61  /* remaining bytes? */
62  /* MUST only occur on the last call to update */
63  if( i ) {
64    memcpy( ctx->rembuf, data, i );
65  }
66
67# undef BYTES_TO_DWORD
68}
69
70static
71void ripemdX_final( finishf finish, uint8_t *str, ripemdctx *ctx, size_t mdlen )
72{
73  int i;
74
75  (*finish)( ctx->MDbuf, ctx->rembuf, ctx->length[0], ctx->length[1] );
76
77  for( i = 0; i < mdlen; i += sizeof(uint32_t) ) {
78    str[i]   =  ctx->MDbuf[i>>2];
79    str[i+1] = (ctx->MDbuf[i>>2] >>  8);
80    str[i+2] = (ctx->MDbuf[i>>2] >> 16);
81    str[i+3] = (ctx->MDbuf[i>>2] >> 24);
82  }
83}
84
85#define C_VISIBILITY static
86
87#define dword uint32_t
88#define byte uint8_t
89
90#include "rmd160.c"
91#define RMD160blksiz 64
92#define RMD160hshsiz (160/8)
93#define RMD160ctxsiz (sizeof(ripemdctx) + sizeof(uint32_t)*(160/32))
94#undef BYTES_TO_DWORD
95#undef ROL
96#undef F
97#undef G
98#undef H
99#undef I
100#undef J
101#undef FF
102#undef GG
103#undef HH
104#undef II
105#undef JJ
106#undef FFF
107#undef GGG
108#undef HHH
109#undef III
110#undef JJJ
111
112#include "rmd128.c"
113#define RMD128blksiz 64
114#define RMD128hshsiz (128/8)
115#define RMD128ctxsiz (sizeof(ripemdctx) + sizeof(uint32_t)*(128/32))
116#undef BYTES_TO_DWORD
117#undef ROL
118#undef F
119#undef G
120#undef H
121#undef I
122#undef FF
123#undef GG
124#undef HH
125#undef II
126#undef FFF
127#undef GGG
128#undef HHH
129#undef III
130
131#undef dword
132#undef byte
133
134#undef C_VISIBILITY
135<#
136
137;;;
138
139(define-foreign-variable context-size128 unsigned-int "RMD128ctxsiz")
140(define-foreign-variable digest-length128 unsigned-int "RMD128hshsiz")
141(define-foreign-variable block-length128 unsigned-int "RMD128blksiz")
142
143(define init128
144  (foreign-lambda* void ((c-pointer ctx)) "ripemdX_init( &MDinit128, ctx );"))
145(define update128
146  (foreign-lambda* void ((c-pointer ctx) (scheme-pointer obj) (int len))
147    "ripemdX_update( &compress128, ctx, obj, len );"))
148(define final128
149  (foreign-lambda* void ((c-pointer ctx) (scheme-pointer result))
150    "ripemdX_final( &MDfinish128, result, ctx, RMD128hshsiz );"))
151(define raw-update128
152  (foreign-lambda* void ((c-pointer ctx) (c-pointer obj) (int len))
153    "ripemdX_update( &compress128, ctx, obj, len );"))
154
155(define ripemd128-primitive
156  (let ((the-prim #f))
157    (lambda ()
158      (or the-prim
159          (begin
160            (set! the-prim
161                  (make-message-digest-primitive
162                    context-size128 digest-length128
163                    init128 update128 final128
164                    block-length128 'ripemd128-primitive
165                    raw-update128))
166            the-prim ) ) ) ) )
167
168;;;
169
170(define-foreign-variable context-size160 unsigned-int "RMD160ctxsiz")
171(define-foreign-variable digest-length160 unsigned-int "RMD160hshsiz")
172(define-foreign-variable block-length160 unsigned-int "RMD160blksiz")
173
174(define init160
175  (foreign-lambda* void ((c-pointer ctx))
176    "ripemdX_init( &MDinit160, ctx );"))
177(define update160
178  (foreign-lambda* void ((c-pointer ctx) (scheme-pointer obj) (int len))
179    "ripemdX_update( &compress160, ctx, obj, len );"))
180(define final160
181  (foreign-lambda* void ((c-pointer ctx) (scheme-pointer result))
182    "ripemdX_final( &MDfinish160, result, ctx, RMD160hshsiz );"))
183(define raw-update160
184  (foreign-lambda* void ((c-pointer ctx) (c-pointer obj) (int len))
185    "ripemdX_update( &compress160, ctx, obj, len );"))
186
187(define ripemd160-primitive
188  (let ((the-prim #f))
189    (lambda ()
190      (or the-prim
191          (begin
192            (set! the-prim
193                  (make-message-digest-primitive
194                    context-size160 digest-length160
195                    init160 update160 final160
196                    block-length160 'ripemd160-primitive
197                    raw-update160))
198            the-prim ) ) ) ) )
199
200) ;module ripemd
Note: See TracBrowser for help on using the repository browser.