all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Leo <sdl.web@gmail.com>
To: Paul Eggert <eggert@cs.ucla.edu>
Cc: Eli Zaretskii <eliz@gnu.org>,
	emacs-devel@gnu.org, sand@blarg.net,
	YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>,
	monnier@iro.umontreal.ca
Subject: Re: Adding sha256 and sha512 to C?
Date: Sun, 12 Jun 2011 21:03:19 +0800	[thread overview]
Message-ID: <m1d3ij2odk.fsf@th041141.ip.tsinghua.edu.cn> (raw)
In-Reply-To: <4DF3919C.9070907@cs.ucla.edu> (Paul Eggert's message of "Sat, 11 Jun 2011 09:02:36 -0700")

[-- 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 \


  parent reply	other threads:[~2011-06-12 13:03 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=m1d3ij2odk.fsf@th041141.ip.tsinghua.edu.cn \
    --to=sdl.web@gmail.com \
    --cc=eggert@cs.ucla.edu \
    --cc=eliz@gnu.org \
    --cc=emacs-devel@gnu.org \
    --cc=mituharu@math.s.chiba-u.ac.jp \
    --cc=monnier@iro.umontreal.ca \
    --cc=sand@blarg.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.