[ prog / sol / mona ]

prog


SchemeBBS [part 2]

9 2020-06-21 23:43

[2/2]

; in  `(file ,path)
; in  `(string ,s)
; out `(file ,path)
; out '(string unpad?)
; ret file: outspec
; ret string: `(string ,s ,length)
(define (medium-mcrypt algo mode padunit ivlen padadd paddel)
   (lambda (inspec outspec key encrypt?)
      (let* ((inwhat  (car inspec))
             (outwhat (car outspec))
             (indata  (cadr inspec))
             (insize  (case inwhat
                         ((file)   (file-length indata))
                         ((string) (string-length indata))
                         (else     'error-inwhat)))
             (mep     (lambda (outport)
                         (mcrypt-encrypt-port
                            algo
                            mode
                            (if encrypt?
                               (port-padder
                                  (current-input-port)
                                  (padadd insize padunit))
                               (current-input-port))
                            outport
                            key
                            (make-string ivlen #\NUL)
                            encrypt?)))
             (doout   (case outwhat
                         ((file)   (lambda () (call-with-output-file (cadr outspec) mep)))
                         ((string) (lambda () (call-with-output-string mep)))
                         (else     'error-outwhat)))
             (doin    (case inwhat
                         ((file)   (lambda () (with-input-from-file indata doout)))
                         ((string) (lambda () (with-input-from-string indata doout)))
                         (else     'error-inwhat)))
             (ret     (doin)))
         (if encrypt?
             (case outwhat
                ((file)   outspec)
                ((string) `(string ,ret ,(string-length ret))))
             (case outwhat
                ((file)   (truncate-padding (cadr outspec) paddel padunit)
                          outspec)
                ((string) (let* ((rlen (string-length ret))
                                 (del  (paddel ret padunit))
                                 (used (- rlen del)))
                             (if (cadr outspec)
                                `(string ,(string-head ret used) ,used)
                                `(string ,ret ,used)))))))))

Here is an AES cbc example with strings:

$ mit-scheme --load test.scm
[...]
  Release 9.1.1     || Microcode 15.3 || Runtime 15.7 || SF 4.41
  LIAR/x86-64 4.118 || Edwin 3.116
;Loading "test.scm"... done

1 ]=> (mcrypt-available?)
;Loading "/usr/lib/x86_64-linux-gnu/mit-scheme/lib/prmcrypt.so"... done
;Value: #t
1 ]=> (define aes (medium-mcrypt "rijndael-128" "cbc" 16 16 padadd-pkcs7 paddel-pkcs7))
;Value: aes
1 ]=> (define key (md5-string "secret key"))
;Loading "/usr/lib/x86_64-linux-gnu/mit-scheme/lib/prmhash.so"... done
;Value: key
1 ]=> (define text "How can I run my own instance of this")
;Value: text

1 ]=> (define enc (aes `(string ,text) '(string #f) key #t))
;Value: enc
1 ]=> (car enc)
;Value: string
1 ]=> (caddr enc)
;Value: 48
1 ]=> (md5-sum->hexadecimal (cadr enc))
;Value 13: "7944266105c58cacba328bb8aa98859ba4eabf4880d4f715890b1b9d8a0237a0434d5e497aaee9d0d9ea114437367dc5"

1 ]=> (define dec (aes `(string ,(cadr enc)) '(string #t) key #f))
;Value: dec
1 ]=> dec
;Value 14: (string "How can I run my own instance of this" 37)
1 ]=> (string=? text (cadr dec))
;Value: #t
1 ]=> 

And here is an example from file to string to file:

1 ]=> (define enc (aes '(file "bbs.scm") '(string #f) key #t))
;Value: enc
1 ]=> (car enc)
;Value: string
1 ]=> (caddr enc)
;Value: 16592

1 ]=> (define dec (aes `(string ,(cadr enc)) '(file "bbs.scm.dec") key #f))
;Value: dec
1 ]=> dec
;Value 15: (file "bbs.scm.dec")
1 ]=> (string=? (md5-file "bbs.scm") (md5-file "bbs.scm.dec"))
;Value: #t
1 ]=> 
$ cmp bbs.scm.dec bbs.scm
$ 

This removes the need to manually fiddle with paddings and ports.

112


VIP:

do not edit these