summaryrefslogtreecommitdiff
path: root/benchmark/benchmark-implementation.lisp
blob: a29eec2dcda9416b8b1985a786ec4e2386efcb25 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
(asdf:load-system "ironclad")

(defparameter *file-size*
  #+sbcl (expt 10 8)
  #+(or allegro ccl ecl) (expt 10 7)
  #-(or allegro ccl ecl sbcl) (expt 10 6))
(defparameter *data-file* "/tmp/data-clr")
(defparameter *encrypted-file* "/tmp/data-enc")
(defparameter *implementation-result-file* "benchmark-tmp")
(defparameter *result* (acons "version"
                              (format nil "~a ~a"
                                      (lisp-implementation-type)
                                      (lisp-implementation-version))
                              '()))

(defmacro get-speed (&body body)
  (let ((start-time (gensym))
        (end-time (gensym))
        (result (gensym))
        (duration (gensym))
        (speed (gensym)))
    `(let* ((,start-time (get-internal-real-time))
            (,result ,@body)
            (,end-time (get-internal-real-time))
            (,duration (/ (- ,end-time ,start-time) internal-time-units-per-second))
            (,speed (round *file-size* ,duration)))
       (values ,speed ,result))))

(defun benchmark-ciphers ()
  (let ((speeds '()))
    (dolist (cipher-name (ironclad:list-all-ciphers))
      (with-open-file (plaintext *data-file*
                                 :element-type '(unsigned-byte 8))
        (with-open-file (ciphertext *encrypted-file*
                                    :direction :output
                                    :element-type '(unsigned-byte 8)
                                    :if-exists :supersede)
          (flet ((stream-cipher-p (cipher-name)
                   (= 1 (ironclad:block-length cipher-name))))
            (let* ((key (ironclad:random-data (car (last (ironclad:key-lengths cipher-name)))))
                   (cipher (ironclad:make-cipher cipher-name
                                                 :key key
                                                 :mode (if (stream-cipher-p cipher-name)
                                                           :stream
                                                           :ecb)))
                   (buffer (make-array 32768 :element-type '(unsigned-byte 8)))
                   (speed (get-speed (loop for buffer-length = (read-sequence buffer plaintext)
                                           until (zerop buffer-length)
                                           do (progn
                                                (ironclad:encrypt-in-place cipher buffer :end buffer-length)
                                                (write-sequence buffer ciphertext :end buffer-length))))))
              (setf speeds (acons cipher-name speed speeds)))))))
    (setf *result* (acons "ciphers" speeds *result*))))

(defun benchmark-digests ()
  (let ((speeds '()))
    (dolist (digest-name (ironclad:list-all-digests))
      (with-open-file (plaintext *data-file*
                                 :element-type '(unsigned-byte 8))
        (let* ((digest (ironclad:make-digest digest-name))
               (buffer (make-array 32768 :element-type '(unsigned-byte 8)))
               (speed (get-speed (loop for buffer-length = (read-sequence buffer plaintext)
                                       until (zerop buffer-length)
                                       do (ironclad:update-digest digest buffer :end buffer-length)
                                       finally (ironclad:produce-digest digest)))))
          (setf speeds (acons digest-name speed speeds)))))
    (setf *result* (acons "digests" speeds *result*))))

(defun benchmark-macs ()
  (let ((speeds '()))
    (dolist (mac-name (ironclad:list-all-macs))
      (with-open-file (plaintext *data-file*
                                 :element-type '(unsigned-byte 8))
        (let* ((key-length (ecase mac-name
                             (ironclad:blake2-mac 64)
                             (ironclad:blake2s-mac 32)
                             (ironclad:cmac 32)
                             (ironclad:hmac 32)
                             (ironclad:poly1305 32)
                             (ironclad:skein-mac 64)))
               (key (ironclad:random-data key-length))
               (extra-args (case mac-name
                             (ironclad:cmac '(:aes))
                             (ironclad:hmac '(:sha256))))
               (mac (apply #'ironclad:make-mac mac-name key extra-args))
               (buffer (make-array 32768 :element-type '(unsigned-byte 8)))
               (speed (get-speed (loop for buffer-length = (read-sequence buffer plaintext)
                                       until (zerop buffer-length)
                                       do (ironclad:update-mac mac buffer :end buffer-length)
                                       finally (ironclad:produce-mac mac)))))
          (setf speeds (acons mac-name speed speeds)))))
    (setf *result* (acons "macs" speeds *result*))))

(benchmark-ciphers)
(benchmark-digests)
(benchmark-macs)
(with-open-file (file *implementation-result-file* :direction :output :if-exists :supersede)
  (write *result* :stream file))

#+allegro (exit)
#-allegro (quit)