source: project/release/5/message-digest-primitive/trunk/message-digest-primitive.scm @ 36722

Last change on this file since 36722 was 36722, checked in by Kon Lovett, 11 months ago

add raw -> cooked

File size: 6.4 KB
Line 
1;;;; message-digest-primitive.scm  -*- Scheme -*-
2;;;; Kon Lovett, Jul '18
3;;;; Kon Lovett, Aug '17
4;;;; Kon Lovett, Apr '12
5;;;; Kon Lovett, May '10 (message-digest.scm)
6;;;; Kon Lovett, Jan '06 (message-digest.scm)
7
8;; Issues
9;;
10;; - see tiger-hash , sha2 , sha1 , ripemd , md5 , hashes
11;;
12;; - synthesize raw-update from update
13
14(module message-digest-primitive
15
16(;export
17  ;
18  make-message-digest-primitive-context
19  ; Algorithm API
20  make-message-digest-primitive
21  message-digest-primitive? check-message-digest-primitive error-message-digest-primitive
22  message-digest-primitive-name
23  message-digest-primitive-block-length
24  message-digest-primitive-context-info
25  message-digest-primitive-digest-length
26  message-digest-primitive-init
27  message-digest-primitive-update
28  message-digest-primitive-final
29  message-digest-primitive-raw-update)
30
31(import scheme
32  (chicken base)
33  (chicken fixnum)
34  (chicken gc)
35  (chicken type)
36  (chicken foreign)
37  (only (chicken memory) allocate free)
38  (only type-checks define-check+error-type check-positive-fixnum check-procedure)
39  (only type-errors error-argument-type))
40
41;;; Support
42
43;;
44
45(define (positive-fixnum? obj)
46  (and (fixnum? obj) (positive? obj)) )
47
48(define (primitive-context-info? obj)
49  (or (procedure? obj) (positive-fixnum? obj)) )
50
51(define (primitive-name? obj)
52  (or (symbol? obj) (string? obj)) )
53
54;;; Message Digest Algorithm API
55
56;;
57
58(define-type message-digest-primitive-name (or symbol string))
59
60(define-type message-digest-primitive-context-info (or fixnum procedure))
61
62;(foreign-lambda void ***Update     c-pointer   scheme-pointer  unsigned-int)
63;(foreign-lambda void ***RawUpdate  c-pointer   c-pointer       unsigned-int)
64
65(define-type message-digest-primitive-raw-update (or boolean procedure))
66
67(define-type message-digest-primitive (struct message-digest-primitive))
68
69;assignment of value of type `(procedure
70;message-digest-primitive#*make-message-digest-primitive (* * * * * * * *)
71;(struct message-digest-primitive#message-digest-primitive))' to toplevel
72;variable `message-digest-primitive#*make-message-digest-primitive' does not
73;match declared type `(procedure
74;message-digest-primitive#*make-message-digest-primitive ((or fixnum procedure)
75;fixnum procedure procedure procedure fixnum (or symbol string) (or boolean
76;procedure)) (struct message-digest-primitive))'
77(: *make-message-digest-primitive (message-digest-primitive-context-info fixnum procedure procedure procedure fixnum message-digest-primitive-name message-digest-primitive-raw-update -> message-digest-primitive))
78(: message-digest-primitive? (* -> boolean : message-digest-primitive))
79(: message-digest-primitive-context-info (message-digest-primitive --> message-digest-primitive-context-info))
80(: message-digest-primitive-digest-length (message-digest-primitive --> fixnum))
81(: message-digest-primitive-init (message-digest-primitive --> procedure))
82(: message-digest-primitive-update (message-digest-primitive --> procedure))
83(: message-digest-primitive-final (message-digest-primitive --> procedure))
84(: message-digest-primitive-block-length (message-digest-primitive --> fixnum))
85(: message-digest-primitive-name (message-digest-primitive --> message-digest-primitive-name))
86(: message-digest-primitive-raw-update (message-digest-primitive --> message-digest-primitive-raw-update))
87;
88(define-record-type message-digest-primitive
89  (*make-message-digest-primitive ctxi digest-len init update final block-len name raw-update)
90  message-digest-primitive?
91  (ctxi message-digest-primitive-context-info)
92  (digest-len message-digest-primitive-digest-length)
93  (init message-digest-primitive-init)
94  (update message-digest-primitive-update)
95  (final message-digest-primitive-final)
96  (block-len message-digest-primitive-block-length)
97  (name message-digest-primitive-name)
98  (raw-update message-digest-primitive-raw-update) )
99
100(define-check+error-type message-digest-primitive)
101
102;;
103
104(define-inline (check-message-digest-arguments loc ctx-info digest-len init update final block-len name raw-update)
105  (unless (primitive-context-info? ctx-info)
106    (error-argument-type loc ctx-info "positive-fixnum or procedure" 'context-info) )
107  (check-positive-fixnum loc digest-len 'digest-length)
108  (check-procedure loc init 'digest-initializer)
109  (when update
110    (check-procedure loc update 'digest-updater) )
111  (check-procedure loc final 'digest-finalizer)
112  (check-positive-fixnum loc block-len 'block-length)
113  (unless (primitive-name? name)
114    (error-argument-type loc name "symbol or string" 'name) )
115  (when raw-update
116    (check-procedure loc raw-update 'digest-raw-updater) ) )
117
118;;
119
120;(: scheme-object-data-pointer ())
121(define scheme-object-data-pointer
122  (foreign-lambda* c-pointer ((scheme-pointer psrc)) "C_return( psrc );"))
123
124;;
125
126(define ((make-scheme-object-updater raw-update) ctx-info obj len)
127  (raw-update ctx-info (scheme-object-data-pointer obj) len) )
128
129;;
130
131;assignment of value of type `(procedure message-digest-primitive#make-message-digest-primitive (* * * * * #!rest) (struct message-digest-primitive#message-digest-primitive))' to toplevel variable `message-digest-primitive#make-message-digest-primitive' does not match declared type `(procedure message-digest-primitive#make-message-digest-primitive ((or fixnum procedure) fixnum procedure procedure procedure #!rest *) (struct message-digest-primitive))'
132(: make-message-digest-primitive (message-digest-primitive-context-info fixnum procedure (or boolean procedure) procedure #!rest -> message-digest-primitive))
133;
134(define (make-message-digest-primitive ctx-info digest-len init update final
135            #!key (block-length 4) (name (gensym 'mdp)) (raw-update #f))
136  (check-message-digest-arguments 'make-message-digest-primitive
137    ctx-info digest-len init update final block-length name raw-update)
138  (let (
139    (update (or update (and raw-update (make-scheme-object-updater raw-update)))) )
140    ;we know about raw -> cooked
141    (unless update
142      (error 'make-message-digest-primitive "missing update & raw-update") )
143    (*make-message-digest-primitive
144      ctx-info digest-len init update final block-length name raw-update) ) )
145
146;;
147
148(: make-message-digest-primitive-context (message-digest-primitive -> *))
149;
150(define (make-message-digest-primitive-context mdp)
151  (let (
152    (ctx-info
153      (message-digest-primitive-context-info
154        (check-message-digest-primitive 'make-message-digest-primitive-context mdp))) )
155    (if (procedure? ctx-info)
156      (ctx-info)
157      (set-finalizer! (allocate ctx-info) free) ) ) )
158
159) ;module message-digest-primitive
Note: See TracBrowser for help on using the repository browser.