Update of /project/crypticl/cvsroot/crypticl/src
In directory clnet:/tmp/cvs-serv24210
Modified Files:
sha256.lisp sha.lisp load.lisp common.lisp
Log Message:
Load sha256 correctly. Refactor commom code in sha-1 and sha-256.
--- /project/crypticl/cvsroot/crypticl/src/sha256.lisp 2007/01/16 23:43:12 1.6
+++ /project/crypticl/cvsroot/crypticl/src/sha256.lisp 2007/01/18 21:37:02 1.7
@@ -18,101 +18,6 @@
(in-package crypticl)
-;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;;
-;;; Low-level function API
-;;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(defun sha-256-on-octet-vector (octet-vector)
- "Return SHA-256 hash of byte array/octet vector"
- (sha-256-encode
- (make-buffer-filler
- (make-byte-array-reader-function octet-vector))))
-
-(defun sha-256-on-string (string)
- "Return SHA-256 hash of a string.
-
-NB! With this function the hash value depends on the encoding of string
-and implementation specific details of the Common Lisp distribution you
-are using (see make-string-reader-function and its' use of char-code
-for more details). For more control, decode the string to a byte array
-yourself and use the byte array interface sha-256-on-octet-vector instead.
-"
- (sha-256-encode
- (make-buffer-filler
- (make-string-reader-function string))))
-
-(defun sha-256-on-octet-stream (stream)
- "Return SHA-256 hash of stream."
- (sha-256-encode
- (make-buffer-filler #'(lambda () (read-byte stream nil)))))
-
-(defun sha-256-file (path)
- "Return SHA-256 hash of a file."
- (with-open-file (str path)
- (sha-256-on-octet-stream str)))
-
-
-;;;;;;;;;;;;;
-;;;
-;;; CLOS API
-;;;
-;;;;;;;;;;;;;
-(defun make-SHA-256 ()
- "Constructor for the SHA-256 class"
- (let ((obj (make-instance 'SHA-256 :algorithm "SHA-256")))
- (reset obj)
- obj))
-
-(defmethod reset ((obj SHA-256))
- (initial-sha-256-hash-value (a obj) (b obj) (c obj) (d obj)
- (e obj) (f obj) (g obj) (h obj))
- (setf (octet-count obj) 0
- (leftover-count obj) 0
- (called-hash obj) nil
- (fresh obj) t))
-
-(defmethod hash ((obj SHA-256) &optional data (start 0) (end (length data)))
- "Return SHA-256 hash of all bytes added so far.
-
-Note that calling hash on an empty object object makes no sense but the spec
-seems to be that we run algorithm on the initial state and return a full
-256 bits hash even when the message length is 0.
-
-Calling it a second time without adding data returns the previous value.
-"
- (when (and (not data) (called-hash obj))
- ;; Return previous hash value when we have one and no data has been
- ;; added since last call to hash.
- (return-from hash (sha-256-make-octet-vector
- (a obj) (b obj) (c obj) (d obj)
- (e obj) (f obj) (g obj) (h obj))))
- (when data
- (typecase data
- (vector (sha-256-add-octet-vector obj data start end))
- (otherwise
- (error "Hash on data type ~A not implemented." (type-of data)))))
-
- (setf (called-hash obj) t)
- (sha-256-final obj))
-
-(defmethod update ((obj SHA-256) (octet-vector vector)
- &optional (start 0) (end (length octet-vector)))
- "Add bytes to SHA-256 hash object.
-
-Will compute the intermediate hash value and not store the input. Useful
-for hashing a large file that doesn't fit in memory or a data stream.
-
-When all bytes have been added you get the hash value by calling the
-hash method."
- ;; Reset object if we have called hash
- (when (called-hash obj)
- (reset obj))
-
- (sha-256-add-octet-vector obj octet-vector start end)
- (setf (fresh obj) nil))
-
-
;;;;;;;;;;;;;;;;;;;
;;;
;;; Implementation
@@ -215,30 +120,8 @@
h (32-add h hh))))
;; Return hash value as array.
- (sha-256-make-octet-vector a b c d e f g h)))
-
-(defmacro sha-256-make-octet-vector (a b c d e f g h)
- "Make byte-vector from 5 32 bits integers.
-
-Note that SHA uses the big-endian convention so the least significant byte
-of an integer is stored in the rightmost position in the byte array.
-This is the opposite of MD5."
- (flet ((bytes (num32)
- `((ldb (byte 8 24) ,num32)
- (ldb (byte 8 16) ,num32)
- (ldb (byte 8 8) ,num32)
- (ldb (byte 8 0) ,num32))))
- `(let ((a ,a) (b ,b) (c ,c) (d ,d) (e ,e) (f ,f) (g ,g) (h ,h))
- (vector ,@(bytes 'a)
- ,@(bytes 'b)
- ,@(bytes 'c)
- ,@(bytes 'd)
- ,@(bytes 'e)
- ,@(bytes 'f)
- ,@(bytes 'g)
- ,@(bytes 'h)
- ))))
-
+ (int32s-to-octet-vector a b c d e f g h)))
+
(defun do-sha-256-message-block (a b c d e f g h mb)
"Hash one 512 bits sha-256 message block.
@@ -368,7 +251,7 @@
(sha-256-encode-block obj vec))
;; Return hash.
- (sha-256-make-octet-vector (a obj) (b obj) (c obj) (d obj)
+ (int32s-to-octet-vector (a obj) (b obj) (c obj) (d obj)
(e obj) (f obj) (g obj) (h obj))))
@@ -430,6 +313,101 @@
(+ start used)))
+;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
+;;; Low-level function API
+;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defun sha-256-on-octet-vector (octet-vector)
+ "Return SHA-256 hash of byte array/octet vector"
+ (sha-256-encode
+ (make-buffer-filler
+ (make-byte-array-reader-function octet-vector))))
+
+(defun sha-256-on-string (string)
+ "Return SHA-256 hash of a string.
+
+NB! With this function the hash value depends on the encoding of string
+and implementation specific details of the Common Lisp distribution you
+are using (see make-string-reader-function and its' use of char-code
+for more details). For more control, decode the string to a byte array
+yourself and use the byte array interface sha-256-on-octet-vector instead.
+"
+ (sha-256-encode
+ (make-buffer-filler
+ (make-string-reader-function string))))
+
+(defun sha-256-on-octet-stream (stream)
+ "Return SHA-256 hash of stream."
+ (sha-256-encode
+ (make-buffer-filler #'(lambda () (read-byte stream nil)))))
+
+(defun sha-256-file (path)
+ "Return SHA-256 hash of a file."
+ (with-open-file (str path)
+ (sha-256-on-octet-stream str)))
+
+
+;;;;;;;;;;;;;
+;;;
+;;; CLOS API
+;;;
+;;;;;;;;;;;;;
+(defun make-SHA-256 ()
+ "Constructor for the SHA-256 class"
+ (let ((obj (make-instance 'SHA-256 :algorithm "SHA-256")))
+ (reset obj)
+ obj))
+
+(defmethod reset ((obj SHA-256))
+ (initial-sha-256-hash-value (a obj) (b obj) (c obj) (d obj)
+ (e obj) (f obj) (g obj) (h obj))
+ (setf (octet-count obj) 0
+ (leftover-count obj) 0
+ (called-hash obj) nil
+ (fresh obj) t))
+
+(defmethod hash ((obj SHA-256) &optional data (start 0) (end (length data)))
+ "Return SHA-256 hash of all bytes added so far.
+
+Note that calling hash on an empty object object makes no sense but the spec
+seems to be that we run algorithm on the initial state and return a full
+256 bits hash even when the message length is 0.
+
+Calling it a second time without adding data returns the previous value.
+"
+ (when (and (not data) (called-hash obj))
+ ;; Return previous hash value when we have one and no data has been
+ ;; added since last call to hash.
+ (return-from hash (int32s-to-octet-vector
+ (a obj) (b obj) (c obj) (d obj)
+ (e obj) (f obj) (g obj) (h obj))))
+ (when data
+ (typecase data
+ (vector (sha-256-add-octet-vector obj data start end))
+ (otherwise
+ (error "Hash on data type ~A not implemented." (type-of data)))))
+
+ (setf (called-hash obj) t)
+ (sha-256-final obj))
+
+(defmethod update ((obj SHA-256) (octet-vector vector)
+ &optional (start 0) (end (length octet-vector)))
+ "Add bytes to SHA-256 hash object.
+
+Will compute the intermediate hash value and not store the input. Useful
+for hashing a large file that doesn't fit in memory or a data stream.
+
+When all bytes have been added you get the hash value by calling the
+hash method."
+ ;; Reset object if we have called hash
+ (when (called-hash obj)
+ (reset obj))
+
+ (sha-256-add-octet-vector obj octet-vector start end)
+ (setf (fresh obj) nil))
+
+
;;;;;;;;;;;;;;;;;;
;;;;
;;;; Tests
--- /project/crypticl/cvsroot/crypticl/src/sha.lisp 2007/01/16 23:45:21 1.7
+++ /project/crypticl/cvsroot/crypticl/src/sha.lisp 2007/01/18 21:37:02 1.8
@@ -26,25 +26,6 @@
,d #x10325476
,e #xc3d2e1f0))
-(defmacro sha1-make-octet-vector (a b c d e)
- "Make byte-vector from 5 32 bits integers.
-
-Note that SHA-1 uses the big-endian convention so the least significant byte
-of an integer is stored in the rightmost position in the byte array.
-This is the opposite of MD5."
- (flet ((bytes (num32)
- `((ldb (byte 8 24) ,num32)
- (ldb (byte 8 16) ,num32)
- (ldb (byte 8 8) ,num32)
- (ldb (byte 8 0) ,num32))))
- `(let ((a ,a) (b ,b) (c ,c) (d ,d) (e ,e))
- (vector ,@(bytes 'a)
- ,@(bytes 'b)
- ,@(bytes 'c)
- ,@(bytes 'd)
- ,@(bytes 'e)))))
-
-
(defun sha1-length64 (message-length-in-bits)
"Returns input integer as two 32-bit words, high order bits first."
(values (ldb (byte 32 32) message-length-in-bits)
@@ -211,7 +192,7 @@
d (32-add d dd)
e (32-add e ee))))
;; Return hash value.
- (sha1-make-octet-vector a b c d e)))
+ (int32s-to-octet-vector a b c d e)))
@@ -325,7 +306,7 @@
(sha1-round obj vec))
;; Reset object and return hash.
- (prog1 (sha1-make-octet-vector (a obj) (b obj) (c obj) (d obj) (e obj))
+ (prog1 (int32s-to-octet-vector (a obj) (b obj) (c obj) (d obj) (e obj))
(reset obj))))
--- /project/crypticl/cvsroot/crypticl/src/load.lisp 2007/01/17 22:00:52 1.7
+++ /project/crypticl/cvsroot/crypticl/src/load.lisp 2007/01/18 21:37:02 1.8
@@ -25,6 +25,7 @@
"random"
"keygenerator"
"md5" "aes" "idea" "dsa" "rsa" "diffie-hellman"
+ "sha256"
"keystore"
"test")))
(format t "Loading the Crypticl library...")
--- /project/crypticl/cvsroot/crypticl/src/common.lisp 2007/01/17 22:00:52 1.7
+++ /project/crypticl/cvsroot/crypticl/src/common.lisp 2007/01/18 21:37:02 1.8
@@ -95,9 +95,25 @@
-;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;
;;; Common functionality for hash functions.
-
+;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+(defun int32s-to-octet-vector (&rest int32s)
+ "Make octet vector (byte array in C terms) from 32 bits integers.
+
+Note that SHA uses the big-endian convention so the least significant byte
+of an integer is stored in the rightmost position in the byte array.
+This is the opposite of MD5."
+ (let ((res (make-array (* 4 (length int32s))
+ :element-type '(unsigned-byte 8)
+ :fill-pointer 0)))
+ (dolist (int32 int32s res)
+ (vector-push (ldb (byte 8 24) int32) res)
+ (vector-push (ldb (byte 8 16) int32) res)
+ (vector-push (ldb (byte 8 8) int32) res)
+ (vector-push (ldb (byte 8 0) int32) res))))
(defun 32-add (&rest args)
"Adds a 32-bit number modulo (expt 2 32)"