unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Adding sha256 and sha512 to C?
@ 2011-05-28  3:18 sand
  2011-05-28  3:58 ` Paul Eggert
  0 siblings, 1 reply; 19+ messages in thread
From: sand @ 2011-05-28  3:18 UTC (permalink / raw)
  To: emacs-devel

Leo (sdl.web at gmail.com) recently added the gnulib "sha1" function to
Emacs' C code.  The gnulib crypto library also has sha256 and sha512
functions; is there any objection to adding those as well?  Researchers
discovered better-than-brute-force attacks against SHA-1 back in 2005
(http://www.schneier.com/blog/archives/2005/02/cryptanalysis_o.html).
Because of this, in 2006 the NIST recommended that application and
protocol designers switch to SHA-2 family hash functions by 2011
(http://csrc.nist.gov/groups/ST/hash/policy.html).  Providing C
versions of the SHA-2 functions will make it easier for developers to
use the those stronger functions in new applications.

Thanks,

Derek

-- 
Derek Upham
sand@blarg.net



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Adding sha256 and sha512 to C?
  2011-05-28  3:18 Adding sha256 and sha512 to C? sand
@ 2011-05-28  3:58 ` Paul Eggert
  2011-05-28  7:25   ` Eli Zaretskii
  2011-05-29  4:22   ` Leo
  0 siblings, 2 replies; 19+ messages in thread
From: Paul Eggert @ 2011-05-28  3:58 UTC (permalink / raw)
  To: sand; +Cc: emacs-devel

On 05/27/11 20:18, sand@blarg.net wrote:
> The gnulib crypto library also has sha256 and sha512
> functions; is there any objection to adding those as well?

Sounds good, but rather than continue to add crypto functions
wouldn't it be better to have a single function parameterized by the
algorithm name?  Something like the following signature:

 (crypto-hash-function ALGORITHM OBJECT
    &optional START END CODING-SYSTEM NOERROR BINARY)

Then, we could implement the existing functions this way:

(defun md5 (object &optional start end coding-system noerror)
   (crypto-hash-function 'md5 object start end coding-system noerror nil))

(define sha1 (object &optional start end binary)
   (crypto-hash-function 'sha1 object start end nil nil binary))




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Adding sha256 and sha512 to C?
  2011-05-28  3:58 ` Paul Eggert
@ 2011-05-28  7:25   ` Eli Zaretskii
  2011-05-30  4:06     ` Stefan Monnier
  2011-05-29  4:22   ` Leo
  1 sibling, 1 reply; 19+ messages in thread
From: Eli Zaretskii @ 2011-05-28  7:25 UTC (permalink / raw)
  To: Paul Eggert; +Cc: sand, emacs-devel

> Date: Fri, 27 May 2011 20:58:38 -0700
> From: Paul Eggert <eggert@cs.ucla.edu>
> Cc: emacs-devel@gnu.org
> 
> On 05/27/11 20:18, sand@blarg.net wrote:
> > The gnulib crypto library also has sha256 and sha512
> > functions; is there any objection to adding those as well?
> 
> Sounds good, but rather than continue to add crypto functions
> wouldn't it be better to have a single function parameterized by the
> algorithm name?

I agree with Paul: the API he proposes makes much more sense.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Adding sha256 and sha512 to C?
  2011-05-28  3:58 ` Paul Eggert
  2011-05-28  7:25   ` Eli Zaretskii
@ 2011-05-29  4:22   ` Leo
  2011-05-29  5:18     ` Paul Eggert
  1 sibling, 1 reply; 19+ messages in thread
From: Leo @ 2011-05-29  4:22 UTC (permalink / raw)
  To: emacs-devel

On 2011-05-28 11:58 +0800, Paul Eggert wrote:
> Sounds good, but rather than continue to add crypto functions
> wouldn't it be better to have a single function parameterized by the
> algorithm name?  Something like the following signature:
>
>  (crypto-hash-function ALGORITHM OBJECT
>     &optional START END CODING-SYSTEM NOERROR BINARY)

I like this too.

> Then, we could implement the existing functions this way:
>
> (defun md5 (object &optional start end coding-system noerror)
>    (crypto-hash-function 'md5 object start end coding-system noerror nil))
>
> (define sha1 (object &optional start end binary)
>    (crypto-hash-function 'sha1 object start end nil nil binary))

I think we should have a consistent signature for all these functions. I
propose:

  (OBJECT &optional START END CODING-SYSTEM BINARY)

omitting the NOERROR arg to make the functions easier to call.

Leo




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Adding sha256 and sha512 to C?
  2011-05-29  4:22   ` Leo
@ 2011-05-29  5:18     ` Paul Eggert
  0 siblings, 0 replies; 19+ messages in thread
From: Paul Eggert @ 2011-05-29  5:18 UTC (permalink / raw)
  To: Leo; +Cc: emacs-devel

On 05/28/11 21:22, Leo wrote:
> I think we should have a consistent signature for all these functions.

The idea of changing the signatures for md5 and sha1 got shot down,
though, due to backward compatibility concerns.
<http://lists.gnu.org/archive/html/emacs-devel/2011-05/msg00818.html>

Perhaps we can revisit that idea later, after crypto-hash-function
is added.  It is a separate issue, and can be treated separately.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Adding sha256 and sha512 to C?
  2011-05-28  7:25   ` Eli Zaretskii
@ 2011-05-30  4:06     ` Stefan Monnier
  2011-06-11  5:43       ` Leo
  0 siblings, 1 reply; 19+ messages in thread
From: Stefan Monnier @ 2011-05-30  4:06 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Paul Eggert, sand, emacs-devel

>> > The gnulib crypto library also has sha256 and sha512
>> > functions; is there any objection to adding those as well?
>> Sounds good, but rather than continue to add crypto functions
>> wouldn't it be better to have a single function parameterized by the
>> algorithm name?
> I agree with Paul: the API he proposes makes much more sense.

I'm not sue the CODING-SYSTEM argument is a good idea.  Other than that,
I wouldn't object, although really I don't see the advantage either.
I'd argue you could define:

  (defalias 'crypto-hash-function #'apply)

and still call (crypto-hash-function 'md5 object start end).


        Stefan



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Adding sha256 and sha512 to C?
  2011-05-30  4:06     ` Stefan Monnier
@ 2011-06-11  5:43       ` Leo
  2011-06-11  8:00         ` Eli Zaretskii
  0 siblings, 1 reply; 19+ messages in thread
From: Leo @ 2011-06-11  5:43 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: Eli Zaretskii, Paul Eggert, sand, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 87 bytes --]

Could people comment on the attached patch which implements sha-2?
Thanks in advance.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: sha.diff --]
[-- Type: text/x-diff, Size: 6464 bytes --]

=== 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-11 05:41:20 +0000
@@ -4538,21 +4538,21 @@
 
 \f
 /************************************************************************
-			     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. */
-
 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 (void (*hash_func) (const char *buffer, size_t len, void *resblock), EMACS_UINT digest_size, 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,6 +4562,7 @@
   register EMACS_INT b, e;
   register struct buffer *bp;
   EMACS_INT temp;
+  char *digest;
   Lisp_Object res=Qnil;
 
   if (STRINGP (object))
@@ -4733,46 +4734,24 @@
 	object = code_convert_string (object, coding_system, Qnil, 1, 0, 0);
     }
 
-  switch (type)
+  digest = xmalloc(digest_size * sizeof(char));
+
+  hash_func(SSDATA (object) + start_byte,
+	    SBYTES (object) - (size_byte - end_byte),
+	    digest);
+
+  if (NILP(binary))
     {
-    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;
-      }
+      char *value = xmalloc((2 * digest_size + 1) * sizeof(char));
+      for (i = 0; i < digest_size; i++)
+	sprintf (&value[2 * i], "%02x", to_uchar (digest[i]));
+      res = make_string(value, digest_size * 2);
+      xfree(value);
     }
+  else
+    res = make_string(digest, digest_size);
 
+  xfree(digest);
   return res;
 }
 
@@ -4805,7 +4784,7 @@
 guesswork fails.  Normally, an error is signaled in such case.  */)
   (Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object coding_system, Lisp_Object noerror)
 {
-  return crypto_hash_function (0, object, start, end, coding_system, noerror, Qnil);
+  return crypto_hash_function ((void *) &md5_buffer, MD5_DIGEST_SIZE, object, start, end, coding_system, noerror, Qnil);
 }
 
 DEFUN ("sha1", Fsha1, Ssha1, 1, 4, 0,
@@ -4817,7 +4796,39 @@
 form.  */)
      (Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object binary)
 {
-  return crypto_hash_function (1, object, start, end, Qnil, Qnil, binary);
+  return crypto_hash_function ((void *) &sha1_buffer, SHA1_DIGEST_SIZE, object, start, end, Qnil, Qnil, binary);
+}
+
+DEFUN ("sha224", Fsha224, Ssha224, 1, 4, 0,
+       doc: /* Return the SHA-224 (Secure Hash Algorithm) of an OBJECT.
+See `sha1' for explanation of the arguments.  */)
+  (Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object binary)
+{
+  return crypto_hash_function ((void *) &sha224_buffer, SHA224_DIGEST_SIZE, object, start, end, Qnil, Qnil, binary);
+}
+
+DEFUN ("sha256", Fsha256, Ssha256, 1, 4, 0,
+       doc: /* Return the SHA-256 (Secure Hash Algorithm) of an OBJECT.
+See `sha1' for explanation of the arguments.  */)
+  (Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object binary)
+{
+  return crypto_hash_function ((void *) &sha256_buffer, SHA256_DIGEST_SIZE, object, start, end, Qnil, Qnil, binary);
+}
+
+DEFUN ("sha384", Fsha384, Ssha384, 1, 4, 0,
+       doc: /* Return the SHA-384 (Secure Hash Algorithm) of an OBJECT.
+See `sha1' for explanation of the arguments.  */)
+  (Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object binary)
+{
+  return crypto_hash_function ((void *) &sha384_buffer, SHA384_DIGEST_SIZE, object, start, end, Qnil, Qnil, binary);
+}
+
+DEFUN ("sha512", Fsha512, Ssha512, 1, 4, 0,
+       doc: /* Return the SHA-512 (Secure Hash Algorithm) of an OBJECT.
+See `sha1' for explanation of the arguments.  */)
+  (Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object binary)
+{
+  return crypto_hash_function ((void *) &sha512_buffer, SHA512_DIGEST_SIZE, object, start, end, Qnil, Qnil, binary);
 }
 
 \f
@@ -4993,6 +5004,10 @@
   defsubr (&Sbase64_decode_string);
   defsubr (&Smd5);
   defsubr (&Ssha1);
+  defsubr (&Ssha224);
+  defsubr (&Ssha256);
+  defsubr (&Ssha384);
+  defsubr (&Ssha512);
   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 \


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Adding sha256 and sha512 to C?
  2011-06-11  5:43       ` Leo
@ 2011-06-11  8:00         ` Eli Zaretskii
  2011-06-11 12:37           ` Leo
  0 siblings, 1 reply; 19+ messages in thread
From: Eli Zaretskii @ 2011-06-11  8:00 UTC (permalink / raw)
  To: Leo; +Cc: eggert, emacs-devel, monnier, sand

> From: Leo <sdl.web@gmail.com>
> Date: Sat, 11 Jun 2011 13:43:00 +0800
> Cc: Eli Zaretskii <eliz@gnu.org>, Paul Eggert <eggert@cs.ucla.edu>,
> 	sand@blarg.net, emacs-devel@gnu.org
> 
> Could people comment on the attached patch which implements sha-2?

Why 3 different functions?  Why not one?



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Adding sha256 and sha512 to C?
  2011-06-11  8:00         ` Eli Zaretskii
@ 2011-06-11 12:37           ` Leo
  2011-06-11 15:24             ` Eli Zaretskii
  0 siblings, 1 reply; 19+ messages in thread
From: Leo @ 2011-06-11 12:37 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: sand, eggert, monnier, emacs-devel

On 2011-06-11 16:00 +0800, Eli Zaretskii wrote:
[snipped 5 lines]
>> Could people comment on the attached patch which implements sha-2?
>
> Why 3 different functions?  Why not one?

How do you mean?

Leo



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Adding sha256 and sha512 to C?
  2011-06-11 12:37           ` Leo
@ 2011-06-11 15:24             ` Eli Zaretskii
  2011-06-11 16:02               ` Paul Eggert
  0 siblings, 1 reply; 19+ messages in thread
From: Eli Zaretskii @ 2011-06-11 15:24 UTC (permalink / raw)
  To: Leo; +Cc: sand, eggert, monnier, emacs-devel

> From: Leo <sdl.web@gmail.com>
> Cc: eggert@cs.ucla.edu,  emacs-devel@gnu.org,  monnier@iro.umontreal.ca,  sand@blarg.net
> Date: Sat, 11 Jun 2011 20:37:36 +0800
> 
> On 2011-06-11 16:00 +0800, Eli Zaretskii wrote:
> [snipped 5 lines]
> >> Could people comment on the attached patch which implements sha-2?
> >
> > Why 3 different functions?  Why not one?
> 
> How do you mean?

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.)



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Adding sha256 and sha512 to C?
  2011-06-11 15:24             ` Eli Zaretskii
@ 2011-06-11 16:02               ` Paul Eggert
  2011-06-11 20:36                 ` Juanma Barranquero
                                   ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Paul Eggert @ 2011-06-11 16:02 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: sand, Leo, monnier, emacs-devel

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)

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:

Please modify GNULIB_MODULES in Makefile.in to reflect
the new dependencies.

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.

No need to use sizeof (char).  It is always 1.

Please write "F (ARGS)" rather than "F(ARGS)".

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.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Adding sha256 and sha512 to C?
  2011-06-11 16:02               ` Paul Eggert
@ 2011-06-11 20:36                 ` Juanma Barranquero
  2011-06-12  0:34                 ` YAMAMOTO Mitsuharu
  2011-06-12 13:03                 ` Leo
  2 siblings, 0 replies; 19+ messages in thread
From: Juanma Barranquero @ 2011-06-11 20:36 UTC (permalink / raw)
  To: Paul Eggert; +Cc: Eli Zaretskii, emacs-devel, sand, monnier, Leo

On Sat, Jun 11, 2011 at 18:02, Paul Eggert <eggert@cs.ucla.edu> wrote:

> The advantage of this approach is that we don't pollute
> the Lisp namespace with one function name per algorithm.

I think generalization is a good argument, but "don't pollute the
namespace" is not. Interesting, widely used cryptographically secure
hash functions (which, I suppose, are the target of
crypto-hash-function) are introduced at a rate of one every X years, X
>> 1. (md5 is from 1992, sha-1 is from 1995, sha-2 is from 2001).

 I'm pretty sure we "pollute the namespace" with all kind of functiosn
at a rate several orders of magnitude bigger than that ;-)

    Juanma



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Adding sha256 and sha512 to C?
  2011-06-11 16:02               ` Paul Eggert
  2011-06-11 20:36                 ` Juanma Barranquero
@ 2011-06-12  0:34                 ` YAMAMOTO Mitsuharu
  2011-06-12 13:03                 ` Leo
  2 siblings, 0 replies; 19+ messages in thread
From: YAMAMOTO Mitsuharu @ 2011-06-12  0:34 UTC (permalink / raw)
  To: Paul Eggert; +Cc: Eli Zaretskii, emacs-devel, sand, monnier, Leo

>>>>> On Sat, 11 Jun 2011 09:02:36 -0700, Paul Eggert <eggert@cs.ucla.edu> said:

> When creating the digest the code should use make_unibyte_string
> rather than make_string.  (This comment applies also to the
> original.)

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.

				     YAMAMOTO Mitsuharu
				mituharu@math.s.chiba-u.ac.jp



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Adding sha256 and sha512 to C?
  2011-06-11 16:02               ` Paul Eggert
  2011-06-11 20:36                 ` Juanma Barranquero
  2011-06-12  0:34                 ` YAMAMOTO Mitsuharu
@ 2011-06-12 13:03                 ` Leo
  2011-06-12 14:05                   ` Thien-Thi Nguyen
                                     ` (2 more replies)
  2 siblings, 3 replies; 19+ messages in thread
From: Leo @ 2011-06-12 13:03 UTC (permalink / raw)
  To: Paul Eggert; +Cc: Eli Zaretskii, emacs-devel, sand, YAMAMOTO Mitsuharu, monnier

[-- Attachment #1: Type: text/plain, Size: 2329 bytes --]

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

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: sha-2.diff --]
[-- Type: text/x-diff, Size: 6872 bytes --]

=== 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 @@
 
 \f
 /************************************************************************
-			     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);
 }
-
 \f
 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 \


^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Adding sha256 and sha512 to C?
  2011-06-12 13:03                 ` Leo
@ 2011-06-12 14:05                   ` Thien-Thi Nguyen
  2011-06-12 15:48                   ` Deniz Dogan
  2011-06-12 22:37                   ` Paul Eggert
  2 siblings, 0 replies; 19+ messages in thread
From: Thien-Thi Nguyen @ 2011-06-12 14:05 UTC (permalink / raw)
  To: Leo; +Cc: emacs-devel

() Leo <sdl.web@gmail.com>
() Sun, 12 Jun 2011 21:03:19 +0800

   crypto-hash-function is very long to type.

What does typing have to do w/ Emacs?  :-)

I think more important than the name itself is the
name's prefix, to be shared w/ other related funcs / vars.
For that, "crypto" seems about as good as any.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Adding sha256 and sha512 to C?
  2011-06-12 13:03                 ` Leo
  2011-06-12 14:05                   ` Thien-Thi Nguyen
@ 2011-06-12 15:48                   ` Deniz Dogan
  2011-06-12 17:06                     ` Richard Riley
  2011-06-12 22:37                   ` Paul Eggert
  2 siblings, 1 reply; 19+ messages in thread
From: Deniz Dogan @ 2011-06-12 15:48 UTC (permalink / raw)
  To: emacs-devel

On 2011-06-12 15:03, Leo wrote:
> crypto-hash-function is very long to type.
>

Not as long as `thing-at-point-bounds-of-list-at-point'!



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Adding sha256 and sha512 to C?
  2011-06-12 15:48                   ` Deniz Dogan
@ 2011-06-12 17:06                     ` Richard Riley
  0 siblings, 0 replies; 19+ messages in thread
From: Richard Riley @ 2011-06-12 17:06 UTC (permalink / raw)
  To: emacs-devel

Deniz Dogan <deniz@dogan.se> writes:

> On 2011-06-12 15:03, Leo wrote:
>> crypto-hash-function is very long to type.
>>
>
> Not as long as `thing-at-point-bounds-of-list-at-point'!
>
>
>

Thank the lord for auto-complete.




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Adding sha256 and sha512 to C?
  2011-06-12 13:03                 ` Leo
  2011-06-12 14:05                   ` Thien-Thi Nguyen
  2011-06-12 15:48                   ` Deniz Dogan
@ 2011-06-12 22:37                   ` Paul Eggert
  2011-06-19 16:08                     ` Leo
  2 siblings, 1 reply; 19+ messages in thread
From: Paul Eggert @ 2011-06-12 22:37 UTC (permalink / raw)
  To: Leo; +Cc: Eli Zaretskii, emacs-devel, sand, YAMAMOTO Mitsuharu, monnier

On 06/12/11 06:03, Leo wrote:

> (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.

That's better, thanks, but I still have two qualms.  First, the name
"sha" is confusing at the Emacs Lisp level: it feels too much like
"ash".  It's not like programmers will be using crypto functions in
every expression; their names need not be *that* short.  How about the
name "secure-hash" instead?  That's pretty short.

Second, naming algorithms via bit counts doesn't sound
forward-looking.  SHA-3 is likely to have a 512-bit variant, for
example.  How about using atoms to name the algorithms, e.g., SHA-1,
SHA-224, SHA-256, etc.?  This is more likely to be robust after SHA-3
comes out, not to mention SHA-4 etc.

+      hash_func	  = &md5_buffer;

There's no need for the "&" here, or in similar assignments to
hash_func.  (And there's no need for multiple spaces before the "=".)

+  digest = make_uninit_string (digest_size);
...
+      Lisp_Object value = make_uninit_string (2 * digest_size);

There's no need to call make_uninit_string twice, as only one
string is being returned.  Any temporary buffer for the digest can
be put into the C stack.  Or, perhaps better, use the same
uninitialized string for both the binary digest and the text
digest, and run the binary-to-text loop backwards (and without
using sprintf) so that the loop doesn't stomp on its own work.
Something like this:

      unsigned char *p = SDATA (digest);
      for (i = digest_size - 1; i >= 0; i--)
	{
	  static char const hexdigit[16] = "0123456789abcdef";
	  int p_i = p[i];
	  p[2 * i] = hexdigit[p_i >> 4];
	  p[2 * i + 1] = hexdigit[p_i & 0xf];
	}

The text-vs-binary checksum thing seems to be enough of a hassle that
perhaps it should be pulled out into a separate function, rather than
as a flag to the sha/secure-hash function.  That is, secure-hash could
always return the text form, and if someone wants a binary form they
could call the text-to-binary converter.

Won't there need to be changes to the Emacs Lisp reference manual, and
to NEWS?




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Adding sha256 and sha512 to C?
  2011-06-12 22:37                   ` Paul Eggert
@ 2011-06-19 16:08                     ` Leo
  0 siblings, 0 replies; 19+ messages in thread
From: Leo @ 2011-06-19 16:08 UTC (permalink / raw)
  To: Paul Eggert; +Cc: Eli Zaretskii, monnier, sand, YAMAMOTO Mitsuharu, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 2197 bytes --]

Sorry for the delay.

On 2011-06-13 06:37 +0800, Paul Eggert wrote:
> That's better, thanks, but I still have two qualms.  First, the name
> "sha" is confusing at the Emacs Lisp level: it feels too much like
> "ash".  It's not like programmers will be using crypto functions in
> every expression; their names need not be *that* short.  How about the
> name "secure-hash" instead?  That's pretty short.

Sounds good.

> Second, naming algorithms via bit counts doesn't sound
> forward-looking.  SHA-3 is likely to have a 512-bit variant, for
> example.  How about using atoms to name the algorithms, e.g., SHA-1,
> SHA-224, SHA-256, etc.?  This is more likely to be robust after SHA-3
> comes out, not to mention SHA-4 etc.
>
> +      hash_func	  = &md5_buffer;
>
> There's no need for the "&" here, or in similar assignments to
> hash_func.  (And there's no need for multiple spaces before the "=".)
>
> +  digest = make_uninit_string (digest_size);
> ...
> +      Lisp_Object value = make_uninit_string (2 * digest_size);
>
> There's no need to call make_uninit_string twice, as only one
> string is being returned.  Any temporary buffer for the digest can
> be put into the C stack.  Or, perhaps better, use the same
> uninitialized string for both the binary digest and the text
> digest, and run the binary-to-text loop backwards (and without
> using sprintf) so that the loop doesn't stomp on its own work.
> Something like this:
>
>       unsigned char *p = SDATA (digest);
>       for (i = digest_size - 1; i >= 0; i--)
> 	{
> 	  static char const hexdigit[16] = "0123456789abcdef";
> 	  int p_i = p[i];
> 	  p[2 * i] = hexdigit[p_i >> 4];
> 	  p[2 * i + 1] = hexdigit[p_i & 0xf];
> 	}

Thanks for the suggestion.

> The text-vs-binary checksum thing seems to be enough of a hassle that
> perhaps it should be pulled out into a separate function, rather than
> as a flag to the sha/secure-hash function.  That is, secure-hash could
> always return the text form, and if someone wants a binary form they
> could call the text-to-binary converter.
>
> Won't there need to be changes to the Emacs Lisp reference manual, and
> to NEWS?

Will take care of the NEWS entry when committing.

Leo


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: sha-2.diff --]
[-- Type: text/x-diff, Size: 7995 bytes --]

=== modified file 'lisp/subr.el'
--- lisp/subr.el	2011-06-15 17:30:41 +0000
+++ lisp/subr.el	2011-06-19 16:06:58 +0000
@@ -2600,6 +2600,14 @@
 	(get-char-property (1- (field-end pos)) 'field)
       raw-field)))
 
+(defun sha1 (object &optional start end binary)
+  "Return the SHA1 (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."
+  (secure-hash 'sha1 object start end binary))
+
 \f
 ;;;; Support for yanking and text properties.
 

=== modified file 'src/deps.mk'
--- src/deps.mk	2011-05-24 08:22:58 +0000
+++ src/deps.mk	2011-06-19 15:46:13 +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-17 15:18:54 +0000
+++ src/fns.c	2011-06-19 15:46:13 +0000
@@ -51,6 +51,8 @@
 static Lisp_Object Qwidget_type;
 static Lisp_Object Qcodeset, Qdays, Qmonths, Qpaper;
 
+static Lisp_Object Qmd5, Qsha1, Qsha224, Qsha256, Qsha384, Qsha512;
+
 static int internal_equal (Lisp_Object , Lisp_Object, int, int);
 
 #ifndef HAVE_UNISTD_H
@@ -4550,21 +4552,18 @@
 
 \f
 /************************************************************************
-			     MD5 and SHA1
+			MD5, SHA-1, and SHA-2
  ************************************************************************/
 
 #include "md5.h"
 #include "sha1.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. */
+#include "sha256.h"
+#include "sha512.h"
+
+/* ALGORITHM is a symbol: md5, sha1, sha224 and so on. */
 
 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)
+secure_hash (Lisp_Object 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;
@@ -4574,7 +4573,11 @@
   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;
+
+  CHECK_SYMBOL (algorithm);
 
   if (STRINGP (object))
     {
@@ -4745,47 +4748,61 @@
 	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;
+  if (EQ (algorithm, Qmd5))
+    {
+      digest_size = MD5_DIGEST_SIZE;
+      hash_func	  = md5_buffer;
+    }
+  else if (EQ (algorithm, Qsha1))
+    {
+      digest_size = SHA1_DIGEST_SIZE;
+      hash_func	  = sha1_buffer;
+    }
+  else if (EQ (algorithm, Qsha224))
+    {
+      digest_size = SHA224_DIGEST_SIZE;
+      hash_func	  = sha224_buffer;
+    }
+  else if (EQ (algorithm, Qsha256))
+    {
+      digest_size = SHA256_DIGEST_SIZE;
+      hash_func	  = sha256_buffer;
+    }
+  else if (EQ (algorithm, Qsha384))
+    {
+      digest_size = SHA384_DIGEST_SIZE;
+      hash_func	  = sha384_buffer;
+    }
+  else if (EQ (algorithm, Qsha512))
+    {
+      digest_size = SHA512_DIGEST_SIZE;
+      hash_func	  = sha512_buffer;
+    }
+  else
+    error ("Invalid algorithm arg: %s", SDATA (Fsymbol_name (algorithm)));
+
+  /* allocate 2 times the size of digest_size so that it can be
+     re-used to hold the hexified value */
+  digest = make_uninit_string (digest_size * 2);
+
+  hash_func (SSDATA (object) + start_byte,
+	     SBYTES (object) - (size_byte - end_byte),
+	     SSDATA (digest));
+
+  if (NILP (binary))
+    {
+      unsigned char *p = SDATA (digest);
+      for (i = digest_size - 1; i >= 0; i--)
+	{
+	  static char const hexdigit[16] = "0123456789abcdef";
+	  int p_i = p[i];
+	  p[2 * i] = hexdigit[p_i >> 4];
+	  p[2 * i + 1] = hexdigit[p_i & 0xf];
+	}
+      return digest;
+    }
+  else
+    return make_unibyte_string (SDATA (digest), digest_size);
 }
 
 DEFUN ("md5", Fmd5, Smd5, 1, 5, 0,
@@ -4817,25 +4834,31 @@
 guesswork fails.  Normally, an error is signaled in such case.  */)
   (Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object coding_system, Lisp_Object noerror)
 {
-  return crypto_hash_function (0, object, start, end, coding_system, noerror, Qnil);
+  return secure_hash (Qmd5, 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 ("secure-hash", Fsecure_hash, Ssecure_hash, 2, 5, 0,
+       doc: /* Return the secure hash of an OBJECT.
+ALGORITHM is a symbol: md5, sha1, sha224, sha256, sha384 or sha512.
+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 algorithm, Lisp_Object object, Lisp_Object start, Lisp_Object end, Lisp_Object binary)
 {
-  return crypto_hash_function (1, object, start, end, Qnil, Qnil, binary);
+  return secure_hash (algorithm, object, start, end, Qnil, Qnil, binary);
 }
-
 \f
 void
 syms_of_fns (void)
 {
+  DEFSYM (Qmd5,    "md5");
+  DEFSYM (Qsha1,   "sha1");
+  DEFSYM (Qsha224, "sha224");
+  DEFSYM (Qsha256, "sha256");
+  DEFSYM (Qsha384, "sha384");
+  DEFSYM (Qsha512, "sha512");
+
   /* Hash table stuff.  */
   Qhash_table_p = intern_c_string ("hash-table-p");
   staticpro (&Qhash_table_p);
@@ -5004,7 +5027,7 @@
   defsubr (&Sbase64_encode_string);
   defsubr (&Sbase64_decode_string);
   defsubr (&Smd5);
-  defsubr (&Ssha1);
+  defsubr (&Ssecure_hash);
   defsubr (&Slocale_info);
 }
 

=== modified file 'src/makefile.w32-in'
--- src/makefile.w32-in	2011-06-12 02:48:18 +0000
+++ src/makefile.w32-in	2011-06-19 15:46:13 +0000
@@ -867,6 +867,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 \


^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2011-06-19 16:08 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-28  3:18 Adding sha256 and sha512 to C? sand
2011-05-28  3:58 ` Paul Eggert
2011-05-28  7:25   ` Eli Zaretskii
2011-05-30  4:06     ` Stefan Monnier
2011-06-11  5:43       ` Leo
2011-06-11  8:00         ` Eli Zaretskii
2011-06-11 12:37           ` Leo
2011-06-11 15:24             ` Eli Zaretskii
2011-06-11 16:02               ` Paul Eggert
2011-06-11 20:36                 ` Juanma Barranquero
2011-06-12  0:34                 ` YAMAMOTO Mitsuharu
2011-06-12 13:03                 ` Leo
2011-06-12 14:05                   ` Thien-Thi Nguyen
2011-06-12 15:48                   ` Deniz Dogan
2011-06-12 17:06                     ` Richard Riley
2011-06-12 22:37                   ` Paul Eggert
2011-06-19 16:08                     ` Leo
2011-05-29  4:22   ` Leo
2011-05-29  5:18     ` Paul Eggert

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).