[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Adding sha256 and sha512 to C?
From: |
Leo |
Subject: |
Re: Adding sha256 and sha512 to C? |
Date: |
Sun, 12 Jun 2011 21:03:19 +0800 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/23.3.50 (Mac OS X 10.6.7) |
On 2011-06-12 00:02 +0800, Paul Eggert wrote:
> On 06/11/11 08:24, Eli Zaretskii wrote:
>
>> Like this:
>>
>> (sha2 OBJECT &optional BEG END BINARY ALGORITHM)
>>
>> where ALGORITHM can be sha-224, sha-256, etc.
>>
>> (We could have ALGORITHM the 3rd argument, if keeping a signature
>> compatible with sha1 is not important.)
>
> Or better yet:
>
> (crypto-hash-function ALGORITHM OBJECT
> &optional START END NOERROR BINARY)
crypto-hash-function is very long to type.
How about export this to elisp:
(sha OBJECT &optional START END BINARY ALGORITHM)
where ALGORITHM can be 1 (default), 224, 256, 384, 512, and make sha1
obsolete? In a sense we unify all SHA functions and leave MD5 as is.
Please review the attached patch. Thank you.
> as was discussed in
> <http://lists.gnu.org/archive/html/emacs-devel/2011-05/msg00872.html>
> and the ensuing thread. The above suggestion removes
> the previously-proposed CODING-SYSTEM argument that Stefan
> didn't think was needed, which means that people who want
> md5's CODING-SYSTEM feature would have to invoke the md5
> function directly.
>
> The advantage of this approach is that we don't pollute
> the Lisp namespace with one function name per algorithm.
>
> Some other comments:
Many thanks for the comments.
> Please modify GNULIB_MODULES in Makefile.in to reflect
> the new dependencies.
This was done in the original patch, no?
> No need to use EMACS_UINT for digest_size. Please use
> plain 'int'. We prefer to not use unsigned types due
> to problems when they're used in comparisons.
fixed.
> No need to use sizeof (char). It is always 1.
I get rid of xmalloc as suggested.
> Please write "F (ARGS)" rather than "F(ARGS)".
Hopefully fixed.
> When creating the digest the code should use make_unibyte_string
> rather than make_string. (This comment applies
> also to the original.)
>
> Please don't cast function pointers to void * and back, as
> that defeats the purpose of the C type checking. Instead,
> just use the unvarnished C types.
fixed.
On 2011-06-12 08:34 +0800, YAMAMOTO Mitsuharu wrote:
[snipped 6 lines]
> And perhaps I would allocate a Lisp string with make_uninit_string and
> then store the result directly into its contents rather than xmalloc -
> make_unibyte_string - xfree, if the size is known in advance.
Thanks.
Leo
=== modified file 'lisp/subr.el'
--- lisp/subr.el 2011-06-02 18:04:44 +0000
+++ lisp/subr.el 2011-06-12 12:08:48 +0000
@@ -1053,6 +1053,7 @@
(define-obsolete-function-alias 'show-buffer 'set-window-buffer "22.1")
(define-obsolete-function-alias 'eval-current-buffer 'eval-buffer "22.1")
(define-obsolete-function-alias 'string-to-int 'string-to-number "22.1")
+(define-obsolete-function-alias 'sha1 'sha "24.1")
(make-obsolete 'forward-point "use (+ (point) N) instead." "23.1")
=== modified file 'src/deps.mk'
--- src/deps.mk 2011-05-24 08:22:58 +0000
+++ src/deps.mk 2011-06-11 05:29:51 +0000
@@ -284,8 +284,8 @@
floatfns.o: floatfns.c syssignal.h lisp.h globals.h $(config_h)
fns.o: fns.c commands.h lisp.h $(config_h) frame.h buffer.h character.h \
keyboard.h keymap.h window.h $(INTERVALS_H) coding.h ../lib/md5.h \
- ../lib/sha1.h blockinput.h atimer.h systime.h xterm.h ../lib/unistd.h \
- globals.h
+ ../lib/sha1.h ../lib/sha256.h ../lib/sha512.h blockinput.h atimer.h \
+ systime.h xterm.h ../lib/unistd.h globals.h
print.o: print.c process.h frame.h window.h buffer.h keyboard.h character.h \
lisp.h globals.h $(config_h) termchar.h $(INTERVALS_H) msdos.h termhooks.h \
blockinput.h atimer.h systime.h font.h charset.h coding.h ccl.h \
=== modified file 'src/fns.c'
--- src/fns.c 2011-06-07 01:39:26 +0000
+++ src/fns.c 2011-06-12 12:32:07 +0000
@@ -4538,21 +4538,23 @@
/************************************************************************
- MD5 and SHA1
+ MD5, SHA-1, and SHA-2
************************************************************************/
#include "md5.h"
#include "sha1.h"
+#include "sha256.h"
+#include "sha512.h"
/* Convert a possibly-signed character to an unsigned character. This is
a bit safer than casting to unsigned char, since it catches some type
errors that the cast doesn't. */
static inline unsigned char to_uchar (char ch) { return ch; }
-/* TYPE: 0 for md5, 1 for sha1. */
+/* ALGORITHM: 0 for md5, 1 for sha1, 224 for sha224 etc. */
static Lisp_Object
-crypto_hash_function (int type, Lisp_Object object, Lisp_Object start,
Lisp_Object end, Lisp_Object coding_system, Lisp_Object noerror, Lisp_Object
binary)
+crypto_hash_function (int algorithm, Lisp_Object object, Lisp_Object start,
Lisp_Object end, Lisp_Object coding_system, Lisp_Object noerror, Lisp_Object
binary)
{
int i;
EMACS_INT size;
@@ -4562,7 +4564,9 @@
register EMACS_INT b, e;
register struct buffer *bp;
EMACS_INT temp;
- Lisp_Object res=Qnil;
+ int digest_size;
+ void *(*hash_func) (const char *, size_t, void *);
+ Lisp_Object digest;
if (STRINGP (object))
{
@@ -4733,47 +4737,51 @@
object = code_convert_string (object, coding_system, Qnil, 1, 0, 0);
}
- switch (type)
- {
- case 0: /* MD5 */
- {
- char digest[16];
- md5_buffer (SSDATA (object) + start_byte,
- SBYTES (object) - (size_byte - end_byte),
- digest);
-
- if (NILP (binary))
- {
- char value[33];
- for (i = 0; i < 16; i++)
- sprintf (&value[2 * i], "%02x", to_uchar (digest[i]));
- res = make_string (value, 32);
- }
- else
- res = make_string (digest, 16);
- break;
- }
-
- case 1: /* SHA1 */
- {
- char digest[20];
- sha1_buffer (SSDATA (object) + start_byte,
- SBYTES (object) - (size_byte - end_byte),
- digest);
- if (NILP (binary))
- {
- char value[41];
- for (i = 0; i < 20; i++)
- sprintf (&value[2 * i], "%02x", to_uchar (digest[i]));
- res = make_string (value, 40);
- }
- else
- res = make_string (digest, 20);
- break;
- }
- }
-
- return res;
+ switch (algorithm)
+ {
+ case 0:
+ digest_size = MD5_DIGEST_SIZE;
+ hash_func = &md5_buffer;
+ break;
+ case 1:
+ digest_size = SHA1_DIGEST_SIZE;
+ hash_func = &sha1_buffer;
+ break;
+ case 224:
+ digest_size = SHA224_DIGEST_SIZE;
+ hash_func = &sha224_buffer;
+ break;
+ case 256:
+ digest_size = SHA256_DIGEST_SIZE;
+ hash_func = &sha256_buffer;
+ break;
+ case 384:
+ digest_size = SHA384_DIGEST_SIZE;
+ hash_func = &sha384_buffer;
+ break;
+ case 512:
+ digest_size = SHA512_DIGEST_SIZE;
+ hash_func = &sha512_buffer;
+ break;
+ default:
+ error ("Invalid ALGORITHM argument");
+ }
+
+ digest = make_uninit_string (digest_size);
+
+ hash_func (SSDATA (object) + start_byte,
+ SBYTES (object) - (size_byte - end_byte),
+ SSDATA (digest));
+
+ if (NILP (binary))
+ {
+ Lisp_Object value = make_uninit_string (2 * digest_size);
+ for (i = 0; i < digest_size; i++)
+ sprintf (&SSDATA (value)[2 * i], "%02x", to_uchar (SSDATA (digest)[i]));
+ return value;
+ }
+ else
+ return digest;
}
DEFUN ("md5", Fmd5, Smd5, 1, 5, 0,
@@ -4808,18 +4816,26 @@
return crypto_hash_function (0, object, start, end, coding_system, noerror,
Qnil);
}
-DEFUN ("sha1", Fsha1, Ssha1, 1, 4, 0,
- doc: /* Return the SHA-1 (Secure Hash Algorithm) of an OBJECT.
-
-OBJECT is either a string or a buffer. Optional arguments START and
-END are character positions specifying which portion of OBJECT for
-computing the hash. If BINARY is non-nil, return a string in binary
-form. */)
- (Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object
binary)
+DEFUN ("sha", Fsha, Ssha, 1, 5, 0,
+ doc: /* Return the SHA (Secure Hash Algorithm) checksums of an OBJECT.
+
+ALGORITHM is an integer specifying the algorithm number. It can be 1
+(default), 224, 256, 384 or 512 for SHA-1, SHA-224, SHA-256, SHA-384
+or SHA-512, respectively.
+
+OBJECT is either a string or a buffer.
+
+Optional arguments START and END are character positions specifying
+which portion of OBJECT for computing the hash. If BINARY is non-nil,
+return a string in binary form. */)
+ (Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object binary,
Lisp_Object algorithm)
{
- return crypto_hash_function (1, object, start, end, Qnil, Qnil, binary);
+ if (NILP (algorithm))
+ XSETFASTINT (algorithm, 1);
+
+ CHECK_NATNUM (algorithm);
+ return crypto_hash_function (XFASTINT (algorithm), object, start, end, Qnil,
Qnil, binary);
}
-
void
syms_of_fns (void)
@@ -4992,7 +5008,7 @@
defsubr (&Sbase64_encode_string);
defsubr (&Sbase64_decode_string);
defsubr (&Smd5);
- defsubr (&Ssha1);
+ defsubr (&Ssha);
defsubr (&Slocale_info);
}
=== modified file 'src/makefile.w32-in'
--- src/makefile.w32-in 2011-05-31 17:03:24 +0000
+++ src/makefile.w32-in 2011-06-11 05:30:23 +0000
@@ -869,6 +869,8 @@
$(EMACS_ROOT)/nt/inc/sys/time.h \
$(EMACS_ROOT)/lib/md5.h \
$(EMACS_ROOT)/lib/sha1.h \
+ $(EMACS_ROOT)/lib/sha256.h \
+ $(EMACS_ROOT)/lib/sha512.h \
$(LISP_H) \
$(SRC)/atimer.h \
$(SRC)/blockinput.h \
- Re: Adding sha256 and sha512 to C?, Leo, 2011/06/11
- Re: Adding sha256 and sha512 to C?, Eli Zaretskii, 2011/06/11
- Re: Adding sha256 and sha512 to C?, Leo, 2011/06/11
- Re: Adding sha256 and sha512 to C?, Eli Zaretskii, 2011/06/11
- Re: Adding sha256 and sha512 to C?, Paul Eggert, 2011/06/11
- Re: Adding sha256 and sha512 to C?, Juanma Barranquero, 2011/06/11
- Re: Adding sha256 and sha512 to C?, YAMAMOTO Mitsuharu, 2011/06/11
- Re: Adding sha256 and sha512 to C?,
Leo <=
- Re: Adding sha256 and sha512 to C?, Thien-Thi Nguyen, 2011/06/12
- Re: Adding sha256 and sha512 to C?, Deniz Dogan, 2011/06/12
- Re: Adding sha256 and sha512 to C?, Richard Riley, 2011/06/12
- Re: Adding sha256 and sha512 to C?, Paul Eggert, 2011/06/12
- Re: Adding sha256 and sha512 to C?, Leo, 2011/06/19