Commits

evhan committed 2580dcd

return a prekeyed hash function when no message is given

This makes the siphash procedures return partially-evaluated functions
when given a key but no message, so that one can build prekeyed hash
functions for repeated use on different messages.

Comments (0)

Files changed (2)

 hashing procedure of that number of compression and finalization rounds,
 respectively.
 
-    (make-siphash c d) => (procedure key message) => integer
+    (make-siphash c d) => (procedure key) => (procedure message) => integer
 
-`siphash-2-4` and `siphash-4-8` are predefined hashing functions.
+`siphash-2-4` and `siphash-4-8` are predefined hashing procedures.
 
-Each takes two bytevectors, the key and message to hash, and returns a
-positive integer. `key` should have a length of 16, while `message` may
-be any length.
+Each takes one or two bytevector arguments, the key and message to hash,
+and returns a positive integer. `key` should have a length of 16, while
+`message` may be any length. If `message` isn't given, a prekeyed
+hashing function is returned.
 
 The SipHash specification recommends SipHash-2-4 for performance and
 SipHash-4-8 for cryptographic security.
 
+    (siphash-2-4 key) => (procedure message) => integer
     (siphash-2-4 key message) => integer
+    (siphash-4-8 key) => (procedure message) => integer
     (siphash-4-8 key message) => integer
 
 Examples
 --------
 
-    > (siphash-2-4
-       (bytevector 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)
-       (string->utf8 "The rain in Spain falls mainly on the plain."))
+    > (define key (bytevector 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15))
+    > (define msg (string->utf8 "The rain in Spain falls mainly on the plain."))
+    > (siphash-2-4 key msg)
     ; => 8751579407287093977
-
-    > (siphash-4-8
-       (bytevector 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)
-       (string->utf8 "In Hertford, Hereford and Hampshire, hurricanes hardly ever happen."))
-    ; => 14358585221060811317
-
-    > ((make-siphash 8 16)
-       (string->utf8 "123456789abcdfgh")
-       (read-bytevector 16 (open-binary-input-file "/etc/motd")))
-    ; => an integer
+    > (let ((hash (siphash-4-8 key)))
+        (hash msg))
+    ; => 13472556437817646137
+    > (define siphash-8-16 (make-siphash 8 16))
+    > (siphash-8-16
+       key
+       (string->utf8
+        "In Hertford, Hereford and Hampshire, hurricanes hardly ever happen."))
+    ; => 9275736844991428064
 
 Notes
 -----
         (m2 (string->number "6c7967656e657261" 16))
         (m3 (string->number "7465646279746573" 16)))
     (lambda (c d)
-      (lambda (k m)
-        (let* ((l  (bytevector-length m))
-               (k0 (bytevector->integer (bytevector-copy k 0 8) 8))
+      (define (siphash-c-d k)
+        (let* ((k0 (bytevector->integer (bytevector-copy k 0 8) 8))
                (k1 (bytevector->integer (bytevector-copy k 8 16) 8))
                (v0 (⊕ k0 m0))
                (v1 (⊕ k1 m1))
                                    (do-times c
                                      (sip-round! v0 v1 v2 v3))
                                    (set! v0 (⊕ v0 mi)))))))
-            (do ((i 0 (+ i 8)))
-                ((> i (- l 8))
-                 (process-message!
-                  (❘ (« (modulo l 256) 56)
-                     (bytevector->integer (bytevector-copy m i l)))))
-              (process-message!
-               (bytevector->integer (bytevector-copy m i (+ i 8)) 8)))
-            (set! v2 (⊕ v2 255))
-            (do-times d
-              (sip-round! v0 v1 v2 v3))
-            (⊕ v0 v1 v2 v3)))))))
+            (lambda (m)
+              (let ((l (bytevector-length m)))
+                (do ((i 0 (+ i 8)))
+                    ((> i (- l 8))
+                     (process-message!
+                      (❘ (« (modulo l 256) 56)
+                         (bytevector->integer (bytevector-copy m i l)))))
+                  (process-message!
+                   (bytevector->integer (bytevector-copy m i (+ i 8)) 8)))
+                (set! v2 (⊕ v2 255))
+                (do-times d
+                  (sip-round! v0 v1 v2 v3))
+                (⊕ v0 v1 v2 v3))))))
+      (case-lambda
+        ((k)
+         (siphash-c-d k))
+        ((k m)
+         ((siphash-c-d k) m))))))
 
 (define siphash-2-4 (make-siphash 2 4))
 (define siphash-4-8 (make-siphash 4 8))