Basic SHA3 support

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
19 messages Options
Reply | Threaded
Open this post in threaded view
|

Basic SHA3 support

Daniel Loebenberger
Hi everyone,

enclosed you find a patch to add basic SHA3-/Keccak support to OpenBSD.

Changes have been made to libc, and a suite of sha3 checksum tools
were added (sha3-224, sha3-256, sha3-384, sha-512), extending the
existing md5(1) checksum tool.

The SHA3 implementation itself was taken from the reference code written
by the Keccak Team (https://keccak.team/) which is available under public
domain (CC0).

We'd be happy to see this in OpenBSD and appreciate any comments.

Best regards,
Daniel, Stefan and Alexander

--
Dr. Daniel Loebenberger
Evaluation & Research

genua GmbH
Domagkstrasse 7, 85551 Kirchheim bei München
Tel. +49 89 991950-0, Fax -999, www.genua.de
Geschäftsführer: Matthias Ochs, Marc Tesch. Amtsgericht München
HRB 98238.
Die genua GmbH ist ein Unternehmen der Bundesdruckerei-Gruppe.


Index: bin/md5/Makefile
===================================================================
RCS file: /cvs/src/bin/md5/Makefile,v
retrieving revision 1.15
diff -u -p -u -p -r1.15 Makefile
--- bin/md5/Makefile 30 Mar 2016 06:38:40 -0000 1.15
+++ bin/md5/Makefile 9 Jan 2018 15:17:20 -0000
@@ -2,13 +2,20 @@
 
 PROG= md5
 SRCS= crc.c md5.c
-MAN= cksum.1 md5.1
+
 LINKS= ${BINDIR}/md5 ${BINDIR}/sha1 \
+ ${BINDIR}/md5 ${BINDIR}/sha224 \
  ${BINDIR}/md5 ${BINDIR}/sha256 \
+ ${BINDIR}/md5 ${BINDIR}/sha384 \
  ${BINDIR}/md5 ${BINDIR}/sha512 \
+ ${BINDIR}/md5 ${BINDIR}/sha3-224 \
+ ${BINDIR}/md5 ${BINDIR}/sha3-256 \
+ ${BINDIR}/md5 ${BINDIR}/sha3-384 \
+ ${BINDIR}/md5 ${BINDIR}/sha3-512 \
  ${BINDIR}/md5 ${BINDIR}/cksum
 
-CPPFLAGS+= -I${.CURDIR}
+CPPFLAGS+=-I${.CURDIR}
+
 COPTS+= -Wall -Wconversion -Wmissing-prototypes
 
 .include <bsd.prog.mk>
Index: bin/md5/md5.1
===================================================================
RCS file: /cvs/src/bin/md5/md5.1,v
retrieving revision 1.47
diff -u -p -u -p -r1.47 md5.1
--- bin/md5/md5.1 23 Feb 2017 20:46:08 -0000 1.47
+++ bin/md5/md5.1 9 Jan 2018 15:17:20 -0000
@@ -18,14 +18,18 @@
 .\" Agency (DARPA) and Air Force Research Laboratory, Air Force
 .\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
 .\"
-.Dd $Mdocdate: February 23 2017 $
+.Dd $Mdocdate: January 9 2018 $
 .Dt MD5 1
 .Os
 .Sh NAME
 .Nm md5 ,
 .Nm sha1 ,
 .Nm sha256 ,
-.Nm sha512
+.Nm sha512 ,
+.Nm sha3-224 ,
+.Nm sha3-256 ,
+.Nm sha3-384 ,
+.Nm sha3-512
 .Nd calculate a message digest (checksum) for a file
 .Sh SYNOPSIS
 .Nm md5
@@ -52,6 +56,30 @@
 .Op Fl h Ar hashfile
 .Op Fl s Ar string
 .Op Ar
+.Nm sha3-224
+.Op Fl bcpqrtx
+.Op Fl C Ar checklist
+.Op Fl h Ar hashfile
+.Op Fl s Ar string
+.Op Ar
+.Nm sha3-256
+.Op Fl bcpqrtx
+.Op Fl C Ar checklist
+.Op Fl h Ar hashfile
+.Op Fl s Ar string
+.Op Ar
+.Nm sha3-384
+.Op Fl bcpqrtx
+.Op Fl C Ar checklist
+.Op Fl h Ar hashfile
+.Op Fl s Ar string
+.Op Ar
+.Nm sha3-512
+.Op Fl bcpqrtx
+.Op Fl C Ar checklist
+.Op Fl h Ar hashfile
+.Op Fl s Ar string
+.Op Ar
 .Sh DESCRIPTION
 These utilities take as input a message of arbitrary length and produce
 as output a message digest (checksum) of the input.
@@ -136,7 +164,13 @@ and \*(Gt0 if an error occurs.
 .%R RFC 3174
 .%T US Secure Hash Algorithm 1 (SHA1)
 .Re
+.Pp
 .Rs
 .%T Secure Hash Standard
 .%O FIPS PUB 180-2
+.Re
+.Pp
+.Rs
+.%T SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions
+.%O FIPS PUB 202
 .Re
Index: bin/md5/md5.c
===================================================================
RCS file: /cvs/src/bin/md5/md5.c,v
retrieving revision 1.92
diff -u -p -u -p -r1.92 md5.c
--- bin/md5/md5.c 11 Sep 2017 16:35:38 -0000 1.92
+++ bin/md5/md5.c 9 Jan 2018 15:17:20 -0000
@@ -42,6 +42,7 @@
 #include <rmd160.h>
 #include <sha1.h>
 #include <sha2.h>
+#include <sha3.h>
 #include <crc.h>
 
 #define STYLE_MD5 0
@@ -61,6 +62,7 @@ union ANY_CTX {
  SHA1_CTX sha1;
 #endif /* !defined(SHA2_ONLY) */
  SHA2_CTX sha2;
+ SHA3_CTX sha3;
 };
 
 struct hash_function {
@@ -177,6 +179,50 @@ struct hash_function {
  (void (*)(void *, const unsigned char *, size_t))SHA512Update,
  (void (*)(unsigned char *, void *))SHA512Final,
  (char *(*)(void *, char *))SHA512End
+ },
+ {
+ "SHA3-224",
+ SHA3_224_DIGEST_LENGTH,
+ STYLE_MD5,
+ 0,
+ NULL,
+ (void (*)(void *))SHA3_224Init,
+ (void (*)(void *, const unsigned char *, size_t))SHA3_Update,
+ (void (*)(unsigned char *, void *))SHA3_Final,
+ (char *(*)(void *, char *))SHA3_224End
+ },
+ {
+ "SHA3-256",
+ SHA3_256_DIGEST_LENGTH,
+ STYLE_MD5,
+ 0,
+ NULL,
+ (void (*)(void *))SHA3_256Init,
+ (void (*)(void *, const unsigned char *, size_t))SHA3_Update,
+ (void (*)(unsigned char *, void *))SHA3_Final,
+ (char *(*)(void *, char *))SHA3_256End
+ },
+ {
+ "SHA3-384",
+ SHA3_384_DIGEST_LENGTH,
+ STYLE_MD5,
+ 0,
+ NULL,
+ (void (*)(void *))SHA3_384Init,
+ (void (*)(void *, const unsigned char *, size_t))SHA3_Update,
+ (void (*)(unsigned char *, void *))SHA3_Final,
+ (char *(*)(void *, char *))SHA3_384End
+ },
+ {
+ "SHA3-512",
+ SHA3_512_DIGEST_LENGTH,
+ STYLE_MD5,
+ 0,
+ NULL,
+ (void (*)(void *))SHA3_512Init,
+ (void (*)(void *, const unsigned char *, size_t))SHA3_Update,
+ (void (*)(unsigned char *, void *))SHA3_Final,
+ (char *(*)(void *, char *))SHA3_512End
  },
  {
  NULL,
Index: include/Makefile
===================================================================
RCS file: /cvs/src/include/Makefile,v
retrieving revision 1.222
diff -u -p -u -p -r1.222 Makefile
--- include/Makefile 17 Oct 2017 09:34:52 -0000 1.222
+++ include/Makefile 9 Jan 2018 15:17:42 -0000
@@ -23,7 +23,7 @@ FILES= a.out.h ar.h asr.h assert.h \
  ndbm.h netdb.h netgroup.h nlist.h nl_types.h \
  paths.h poll.h pthread.h pthread_np.h pwd.h \
  ranlib.h readpassphrase.h regex.h resolv.h rmd160.h \
- sched.h search.h setjmp.h semaphore.h sha1.h sha2.h \
+ sched.h search.h setjmp.h semaphore.h sha1.h sha2.h sha3.h \
  signal.h siphash.h sndio.h spawn.h stdbool.h stddef.h \
  stdio.h stdlib.h string.h strings.h sysexits.h \
  tar.h tgmath.h tib.h time.h ttyent.h \
Index: include/sha3.h
===================================================================
RCS file: include/sha3.h
diff -N include/sha3.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ include/sha3.h 9 Jan 2018 15:17:42 -0000
@@ -0,0 +1,76 @@
+#ifndef _SHA3_H
+#define _SHA3_H
+
+#define SHA3_224_DIGEST_LENGTH 28
+#define SHA3_224_DIGEST_STRING_LENGTH (SHA3_224_DIGEST_LENGTH * 2 + 1)
+
+#define SHA3_256_DIGEST_LENGTH 32
+#define SHA3_256_DIGEST_STRING_LENGTH (SHA3_256_DIGEST_LENGTH * 2 + 1)
+
+#define SHA3_384_DIGEST_LENGTH 48
+#define SHA3_384_DIGEST_STRING_LENGTH (SHA3_384_DIGEST_LENGTH * 2 + 1)
+
+#define SHA3_512_DIGEST_LENGTH 64
+#define SHA3_512_DIGEST_STRING_LENGTH (SHA3_512_DIGEST_LENGTH * 2 + 1)
+
+#define SHA3_STATE_SIZE 1600 / 8
+
+
+typedef struct _SHA3_CTX {
+ unsigned char state[SHA3_STATE_SIZE];
+ unsigned int rate;
+ unsigned int byteIOIndex;
+ unsigned int fixedOutputLength;
+} SHA3_CTX;
+
+
+void SHA3_224Init(SHA3_CTX *);
+char *SHA3_224End(SHA3_CTX *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH)));
+char *SHA3_224File(const char *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH)));
+char *SHA3_224FileChunk(const char *, char *, off_t, off_t)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH)));
+char *SHA3_224Data(const u_int8_t *, size_t, char *)
+ __attribute__((__bounded__(__string__,1,2)))
+ __attribute__((__bounded__(__minbytes__,3,SHA3_224_DIGEST_STRING_LENGTH)));
+
+void SHA3_256Init(SHA3_CTX *);
+char *SHA3_256End(SHA3_CTX *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH)));
+char *SHA3_256File(const char *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH)));
+char *SHA3_256FileChunk(const char *, char *, off_t, off_t)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH)));
+char *SHA3_256Data(const u_int8_t *, size_t, char *)
+ __attribute__((__bounded__(__string__,1,2)))
+ __attribute__((__bounded__(__minbytes__,3,SHA3_256_DIGEST_STRING_LENGTH)));
+
+void SHA3_384Init(SHA3_CTX *);
+char *SHA3_384End(SHA3_CTX *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH)));
+char *SHA3_384File(const char *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH)));
+char *SHA3_384FileChunk(const char *, char *, off_t, off_t)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH)));
+char *SHA3_384Data(const u_int8_t *, size_t, char *)
+ __attribute__((__bounded__(__string__,1,2)))
+ __attribute__((__bounded__(__minbytes__,3,SHA3_384_DIGEST_STRING_LENGTH)));
+
+void SHA3_512Init(SHA3_CTX *);
+char *SHA3_512End(SHA3_CTX *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH)));
+char *SHA3_512File(const char *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH)));
+char *SHA3_512FileChunk(const char *, char *, off_t, off_t)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH)));
+char *SHA3_512Data(const u_int8_t *, size_t, char *)
+ __attribute__((__bounded__(__string__,1,2)))
+ __attribute__((__bounded__(__minbytes__,3,SHA3_512_DIGEST_STRING_LENGTH)));
+
+void SHA3_Update(SHA3_CTX *, const u_int8_t *, size_t)
+ __attribute__((__bounded__(__string__,2,3)));
+void SHA3_Final(u_int8_t [SHA3_224_DIGEST_LENGTH], SHA3_CTX *)
+ __attribute__((__bounded__(__minbytes__,1,SHA3_224_DIGEST_LENGTH)));
+
+#endif /* _SHA3_H */
Index: lib/libc/shlib_version
===================================================================
RCS file: /cvs/src/lib/libc/shlib_version,v
retrieving revision 1.197
diff -u -p -u -p -r1.197 shlib_version
--- lib/libc/shlib_version 26 Dec 2017 15:11:17 -0000 1.197
+++ lib/libc/shlib_version 9 Jan 2018 15:17:42 -0000
@@ -1,4 +1,4 @@
 major=92
-minor=2
+minor=3
 # note: If changes were made to include/thread_private.h or if system
 # calls were added/changed then librthread/shlib_version also be updated.
Index: lib/libc/hash/Makefile.inc
===================================================================
RCS file: /cvs/src/lib/libc/hash/Makefile.inc,v
retrieving revision 1.24
diff -u -p -u -p -r1.24 Makefile.inc
--- lib/libc/hash/Makefile.inc 3 Sep 2016 16:25:03 -0000 1.24
+++ lib/libc/hash/Makefile.inc 9 Jan 2018 15:17:42 -0000
@@ -3,9 +3,9 @@
 # hash functions
 .PATH: ${LIBCSRCDIR}/hash
 
-HELPER= md5hl.c rmd160hl.c sha1hl.c sha224hl.c sha256hl.c sha384hl.c sha512hl.c sha512_256hl.c
-SRCS+= md5.c rmd160.c sha1.c sha2.c ${HELPER} siphash.c
-MAN+= md5.3 rmd160.3 sha1.3 sha2.3 SipHash24.3
+HELPER= md5hl.c rmd160hl.c sha1hl.c sha224hl.c sha256hl.c sha384hl.c sha512hl.c sha512_256hl.c sha3-224hl.c sha3-256hl.c sha3-384hl.c sha3-512hl.c  
+SRCS+= md5.c rmd160.c sha1.c sha2.c sha3.c ${HELPER} siphash.c
+MAN+= md5.3 rmd160.3 sha1.3 sha2.3 sha3.3 SipHash24.3
 
 CLEANFILES+= ${HELPER}
 
@@ -43,4 +43,32 @@ sha512_256hl.c: helper.c
     -e 's/HASH/SHA512_256/g' \
     -e 's/SHA512_256_CTX/SHA2_CTX/g' $> > $@
 
-beforedepend: md5hl.c rmd160hl.c sha1hl.c sha256hl.c sha384hl.c sha512hl.c sha512_256hl.c
+sha3-224hl.c:   helper.c
+ sed -e 's/hashinc/sha3.h/g' \
+            -e 's/HASH/SHA3_224/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]Update/SHA3_Update/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]Final/SHA3_Final/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]_CTX/SHA3_CTX/g' $> > $@
+
+sha3-256hl.c:   helper.c
+ sed -e 's/hashinc/sha3.h/g' \
+            -e 's/HASH/SHA3_256/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]Update/SHA3_Update/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]Final/SHA3_Final/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]_CTX/SHA3_CTX/g' $> > $@
+
+sha3-384hl.c:   helper.c
+ sed -e 's/hashinc/sha3.h/g' \
+            -e 's/HASH/SHA3_384/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]Update/SHA3_Update/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]Final/SHA3_Final/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]_CTX/SHA3_CTX/g' $> > $@
+
+sha3-512hl.c:   helper.c
+ sed -e 's/hashinc/sha3.h/g' \
+            -e 's/HASH/SHA3_512/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]Update/SHA3_Update/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]Final/SHA3_Final/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]_CTX/SHA3_CTX/g' $> > $@
+
+beforedepend: md5hl.c rmd160hl.c sha1hl.c sha256hl.c sha384hl.c sha512hl.c sha512_256hl.c sha3-224hl.c sha3-256hl.c sha3-384hl.c sha3-512hl.c  
Index: lib/libc/hash/sha3.3
===================================================================
RCS file: lib/libc/hash/sha3.3
diff -N lib/libc/hash/sha3.3
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libc/hash/sha3.3 9 Jan 2018 15:17:42 -0000
@@ -0,0 +1,292 @@
+.\" $OpenBSD: sha2.3,v 1.26 2016/09/04 09:28:12 tedu Exp $
+.\"
+.\" Copyright (c) 2003, 2004 Todd C. Miller <[hidden email]>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" Sponsored in part by the Defense Advanced Research Projects
+.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
+.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
+.\"
+.\" See http://www.nist.gov/sha/ for the detailed standard
+.\"
+.Dd $Mdocdate: January 9 2018 $
+.Dt SHA3INIT 3
+.Os
+.Sh NAME
+.Nm SHA3_224Init ,
+.Nm SHA3_224Update ,
+.Nm SHA3_224Final ,
+.Nm SHA3_224End ,
+.Nm SHA3_224File ,
+.Nm SHA3_224FileChunk ,
+.Nm SHA3_224Data ,
+.Nm SHA3_256Init ,
+.Nm SHA3_256Update ,
+.Nm SHA3_256Final ,
+.Nm SHA3_256End ,
+.Nm SHA3_256File ,
+.Nm SHA3_256FileChunk ,
+.Nm SHA3_256Data ,
+.Nm SHA3_384Init ,
+.Nm SHA3_384Update ,
+.Nm SHA3_384Final ,
+.Nm SHA3_384End ,
+.Nm SHA3_384File ,
+.Nm SHA3_384FileChunk ,
+.Nm SHA3_384Data ,
+.Nm SHA3_512Init ,
+.Nm SHA3_512Update ,
+.Nm SHA3_512Final ,
+.Nm SHA3_512End ,
+.Nm SHA3_512File ,
+.Nm SHA3_512FileChunk ,
+.Nm SHA3_512Data ,
+.Nm SHA3_512_256Init ,
+.Nm SHA3_512_256Update ,
+.Nm SHA3_512_256Final ,
+.Nm SHA3_512_256End ,
+.Nm SHA3_512_256File ,
+.Nm SHA3_512_256FileChunk ,
+.Nm SHA3_512_256Data
+.Nd calculate the NIST Secure Hash Standard (version 3)
+.Sh SYNOPSIS
+.In sys/types.h
+.In sha3.h
+.Ft void
+.Fn SHA3_224Init "SHA3_CTX *context"
+.Ft void
+.Fn SHA3_224Update "SHA3_CTX *context" "const u_int8_t *data" "size_t len"
+.Ft void
+.Fn SHA3_224Final "u_int8_t digest[SHA3_224_DIGEST_LENGTH]" "SHA3_CTX *context"
+.Ft "char *"
+.Fn SHA3_224End "SHA3_CTX *context" "char *buf"
+.Ft "char *"
+.Fn SHA3_224File "const char *filename" "char *buf"
+.Ft "char *"
+.Fn SHA3_224FileChunk "const char *filename" "char *buf" "off_t offset" "off_t length"
+.Ft "char *"
+.Fn SHA3_224Data "const u_int8_t *data" "size_t len" "char *buf"
+.Ft void
+.Fn SHA3_256Init "SHA3_CTX *context"
+.Ft void
+.Fn SHA3_256Update "SHA3_CTX *context" "const u_int8_t *data" "size_t len"
+.Ft void
+.Fn SHA3_256Final "u_int8_t digest[SHA3_256_DIGEST_LENGTH]" "SHA3_CTX *context"
+.Ft "char *"
+.Fn SHA3_256End "SHA3_CTX *context" "char *buf"
+.Ft "char *"
+.Fn SHA3_256File "const char *filename" "char *buf"
+.Ft "char *"
+.Fn SHA3_256FileChunk "const char *filename" "char *buf" "off_t offset" "off_t length"
+.Ft "char *"
+.Fn SHA3_256Data "const u_int8_t *data" "size_t len" "char *buf"
+.Ft void
+.Fn SHA3_384Init "SHA3_CTX *context"
+.Ft void
+.Fn SHA3_384Update "SHA3_CTX *context" "const u_int8_t *data" "size_t len"
+.Ft void
+.Fn SHA3_384Final "u_int8_t digest[SHA3_384_DIGEST_LENGTH]" "SHA3_CTX *context"
+.Ft "char *"
+.Fn SHA3_384End "SHA3_CTX *context" "char *buf"
+.Ft "char *"
+.Fn SHA3_384File "const char *filename" "char *buf"
+.Ft "char *"
+.Fn SHA3_384FileChunk "const char *filename" "char *buf" "off_t offset" "off_t length"
+.Ft "char *"
+.Fn SHA3_384Data "const u_int8_t *data" "size_t len" "char *buf"
+.Ft void
+.Fn SHA3_512Init "SHA3_CTX *context"
+.Ft void
+.Fn SHA3_512Update "SHA3_CTX *context" "const u_int8_t *data" "size_t len"
+.Ft void
+.Fn SHA3_512Final "u_int8_t digest[SHA3_512_DIGEST_LENGTH]" "SHA3_CTX *context"
+.Ft "char *"
+.Fn SHA3_512End "SHA3_CTX *context" "char *buf"
+.Ft "char *"
+.Fn SHA3_512File "const char *filename" "char *buf"
+.Ft "char *"
+.Fn SHA3_512FileChunk "const char *filename" "char *buf" "off_t offset" "off_t length"
+.Ft "char *"
+.Fn SHA3_512Data "const u_int8_t *data" "size_t len" "char *buf"
+.Ft void
+.Fn SHA3_512_256Init "SHA3_CTX *context"
+.Ft void
+.Fn SHA3_512_256Update "SHA3_CTX *context" "const u_int8_t *data" "size_t len"
+.Ft void
+.Fn SHA3_512_256Final "u_int8_t digest[SHA3_512_256_DIGEST_LENGTH]" "SHA3_CTX *context"
+.Ft "char *"
+.Fn SHA3_512_256End "SHA3_CTX *context" "char *buf"
+.Ft "char *"
+.Fn SHA3_512_256File "const char *filename" "char *buf"
+.Ft "char *"
+.Fn SHA3_512_256FileChunk "const char *filename" "char *buf" "off_t offset" "off_t length"
+.Ft "char *"
+.Fn SHA3_512_256Data "const u_int8_t *data" "size_t len" "char *buf"
+.Sh DESCRIPTION
+The SHA-3 functions implement the NIST Secure Hash Standard,
+FIPS PUB 202.
+The SHA-3 functions are used to generate a condensed representation of a
+message called a message digest, suitable for use as a digital signature.
+There are four families of functions, with names corresponding to
+the number of bits in the resulting message digest.
+The functions can process a message of arbitrary length as input.
+.Pp
+The SHA-3 functions are considered to be more secure than the
+.Xr sha1 3
+functions with which they share a similar interface. They are an
+alternative to the
+.Xr sha2 3
+functions.
+The 224, 256, 384, and 512-bit versions of SHA-3 share the same interface.
+For brevity, only the 256-bit variants are described below.
+.Pp
+The
+.Fn SHA3_256Init
+function initializes a SHA3_CTX
+.Fa context
+for use with
+.Fn SHA3_256Update
+and
+.Fn SHA3_256Final .
+The
+.Fn SHA3_256Update
+function adds
+.Fa data
+of length
+.Fa len
+to the SHA3_CTX specified by
+.Fa context .
+.Fn SHA3_256Final
+is called when all data has been added via
+.Fn SHA3_256Update
+and stores a message digest in the
+.Fa digest
+parameter.
+.Pp
+The
+.Fn SHA3_256End
+function is a front end for
+.Fn SHA3_256Final
+which converts the digest into an
+.Tn ASCII
+representation of the digest in hexadecimal.
+.Pp
+The
+.Fn SHA3_256File
+function calculates the digest for a file and returns the result via
+.Fn SHA3_256End .
+If
+.Fn SHA3_256File
+is unable to open the file, a
+.Dv NULL
+pointer is returned.
+.Pp
+.Fn SHA3_256FileChunk
+behaves like
+.Fn SHA3_256File
+but calculates the digest only for that portion of the file starting at
+.Fa offset
+and continuing for
+.Fa length
+bytes or until end of file is reached, whichever comes first.
+A zero
+.Fa length
+can be specified to read until end of file.
+A negative
+.Fa length
+or
+.Fa offset
+will be ignored.
+.Pp
+The
+.Fn SHA3_256Data
+function
+calculates the digest of an arbitrary string and returns the result via
+.Fn SHA3_256End .
+.Pp
+For each of the
+.Fn SHA3_256End ,
+.Fn SHA3_256File ,
+.Fn SHA3_256FileChunk ,
+and
+.Fn SHA3_256Data
+functions the
+.Fa buf
+parameter should either be a string large enough to hold the resulting digest
+(e.g.\&
+.Dv SHA3_224_DIGEST_STRING_LENGTH ,
+.Dv SHA3_256_DIGEST_STRING_LENGTH ,
+.Dv SHA3_384_DIGEST_STRING_LENGTH ,
+.Dv SHA3_512_DIGEST_STRING_LENGTH ,
+or
+.Dv SHA3_512_256_DIGEST_STRING_LENGTH ,
+depending on the function being used)
+or a
+.Dv NULL
+pointer.
+In the latter case, space will be dynamically allocated via
+.Xr malloc 3
+and should be freed using
+.Xr free 3
+when it is no longer needed.
+.Sh EXAMPLES
+The following code fragment will calculate the SHA3-256 digest for the string
+.Qq abc ,
+which is
+.Dq 0x3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532 .
+.Bd -literal -offset indent
+SHA3_CTX ctx;
+u_int8_t results[SHA3_256_DIGEST_LENGTH];
+char *buf;
+int n;
+
+buf = "abc";
+n = strlen(buf);
+SHA3_256Init(&ctx);
+SHA3_256Update(&ctx, (u_int8_t *)buf, n);
+SHA3_256Final(results, &ctx);
+
+/* Print the digest as one long hex value */
+printf("0x");
+for (n = 0; n \*(Lt SHA3_256_DIGEST_LENGTH; n++)
+ printf("%02x", results[n]);
+putchar('\en');
+.Ed
+.Pp
+Alternately, the helper functions could be used in the following way:
+.Bd -literal -offset indent
+u_int8_t output[SHA3_256_DIGEST_STRING_LENGTH];
+char *buf = "abc";
+
+printf("0x%s\en", SHA3_256Data(buf, strlen(buf), output));
+.Ed
+.Sh SEE ALSO
+.Xr cksum 1 ,
+.Xr md5 3 ,
+.Xr rmd160 3 ,
+.Xr sha1 3 ,
+.Xr sha2 3
+.Rs
+.%T SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions
+.%O FIPS PUB 202
+.Re
+.Pp
+The
+.Fn SHA3_256End ,
+.Fn SHA3_256File ,
+.Fn SHA3_256FileChunk ,
+and
+.Fn SHA3_256Data
+helper functions are derived from code written by
+.An Poul-Henning Kamp .
Index: lib/libc/hash/sha3.c
===================================================================
RCS file: lib/libc/hash/sha3.c
diff -N lib/libc/hash/sha3.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libc/hash/sha3.c 9 Jan 2018 15:17:42 -0000
@@ -0,0 +1,756 @@
+/*
+ * Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni,
+ * Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby
+ * denoted as "the implementer".
+ *
+ * For more information, feedback or questions, please refer to our websites:
+ * http://keccak.noekeon.org/
+ * http://keyak.noekeon.org/
+ * http://ketje.noekeon.org/
+ *
+ * Adaptation to OpenBSD in 2017/18 by
+ * Alexander von Gernler, Daniel Loebenberger and Stefan-Lukas Gazdag
+ * https://www.genua.de/
+ * also denoted as "the implementer"
+ *
+ * To the extent possible under law, the implementer has waived all copyright
+ * and related or neighboring rights to the source code in this file.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+#include <assert.h>
+#include <sys/types.h>
+#include <string.h>
+#include <strings.h>
+#include <sha3.h>
+
+typedef unsigned long long tKeccakLane;
+
+#define SHA3_NRROUNDS 24
+#define SHA3_NRLANES 25
+#define SHA3_DELIMITER 0x06
+
+#define index(x, y) (((x)%5)+5*((y)%5))
+
+const tKeccakLane KeccakRoundConstants[SHA3_NRROUNDS] =
+{
+ 0x0000000000000001,
+ 0x0000000000008082,
+ 0x800000000000808a,
+ 0x8000000080008000,
+ 0x000000000000808b,
+ 0x0000000080000001,
+ 0x8000000080008081,
+ 0x8000000000008009,
+ 0x000000000000008a,
+ 0x0000000000000088,
+ 0x0000000080008009,
+ 0x000000008000000a,
+ 0x000000008000808b,
+ 0x800000000000008b,
+ 0x8000000000008089,
+ 0x8000000000008003,
+ 0x8000000000008002,
+ 0x8000000000000080,
+ 0x000000000000800a,
+ 0x800000008000000a,
+ 0x8000000080008081,
+ 0x8000000000008080,
+ 0x0000000080000001,
+ 0x8000000080008008,
+};
+
+const unsigned int KeccakRhoOffsets[SHA3_NRLANES] =
+{
+ 0, 1, 62, 28, 27, 36, 44, 6, 55, 20, 3, 10, 43,
+ 25, 39, 41, 45, 15, 21, 8, 18, 2, 61, 56, 14
+};
+
+/*
+ * unused, but these constance denote the one implementation out of the
+ * Keccak Code Package that was taken here
+ */
+#define KeccakP1600_implementation      "64-bit reference implementation"
+#define KeccakP1600_stateSizeInBytes    200
+#define KeccakP1600_stateAlignment      8
+
+/* prototypes for local functions */
+static void KeccakP1600_AddByte(void *state, unsigned char data,
+    unsigned int offset);
+static void KeccakP1600_AddBytes(void *state, const unsigned char *data,
+    unsigned int offset, unsigned int length);
+static void KeccakP1600_Permute_24rounds(void *state);
+static void KeccakP1600_ExtractBytes(const void *state, unsigned char *data,
+    unsigned int offset, unsigned int length);
+static void Keccak_HashInitialize(SHA3_CTX *, unsigned int, unsigned int);
+
+
+/*
+ * interface functions external use
+ * (rate + capacity) = 1600,
+ * thus the rate specifies the capacity
+ */
+void
+SHA3_224Init(SHA3_CTX *context)
+{
+ /* rate = 1152, output width 224 bit */
+ Keccak_HashInitialize(context, 1152, 224);
+}
+
+void
+SHA3_256Init(SHA3_CTX *context)
+{
+ /* rate = 1088, output width 256 bit */
+ Keccak_HashInitialize(context, 1088, 256);
+}
+
+void
+SHA3_384Init(SHA3_CTX *context)
+{
+ /* rate = 832, output width 384 bit */
+ Keccak_HashInitialize(context, 832, 384);
+}
+
+void
+SHA3_512Init(SHA3_CTX *context)
+{
+ /* rate = 576, output width 512 bit */
+ Keccak_HashInitialize(context, 576, 512);
+}
+
+
+void
+SHA3_Update(SHA3_CTX *context, const u_int8_t *data, size_t len)
+{
+ size_t i, j;
+ unsigned int partialBlock;
+ const unsigned char *curData;
+ unsigned int rateInBytes;
+ rateInBytes = context->rate/8;
+
+ i = 0;
+ curData = data;
+ while(i < len) {
+ if ((context->byteIOIndex == 0) && (len >= (i + rateInBytes))) {
+#ifdef SnP_FastLoop_Absorb
+ /* processing full blocks first */
+ if ((rateInBytes % (KeccakP1600_width/200)) == 0) {
+ /* fast lane: whole lane rate */
+ j = KeccakP1600_FastLoop_Absorb(context->state,
+    rateInBytes/(KeccakP1600_width/200), curData, len - i);
+ i += j;
+ curData += j;
+ }
+ else {
+#endif
+ for(j=len-i; j>=rateInBytes; j-=rateInBytes) {
+ #ifdef KeccakReference
+ displayBytes(1, "Block to be absorbed", curData, rateInBytes);
+ #endif
+ KeccakP1600_AddBytes(context->state, curData, 0, rateInBytes);
+ KeccakP1600_Permute_24rounds(context->state);
+ curData+=rateInBytes;
+ }
+ i = len - j;
+#ifdef SnP_FastLoop_Absorb
+ }
+#endif
+ }
+ else {
+ /* normal lane: using the message queue */
+ partialBlock = (unsigned int)(len - i);
+ if (partialBlock+context->byteIOIndex > rateInBytes)
+ partialBlock = rateInBytes-context->byteIOIndex;
+ #ifdef KeccakReference
+ displayBytes(1, "Block to be absorbed (part)", curData, partialBlock);
+ #endif
+ i += partialBlock;
+
+ KeccakP1600_AddBytes(context->state, curData, context->byteIOIndex, partialBlock);
+ curData += partialBlock;
+ context->byteIOIndex += partialBlock;
+ if (context->byteIOIndex == rateInBytes) {
+ KeccakP1600_Permute_24rounds(context->state);
+ context->byteIOIndex = 0;
+ }
+ }
+ }
+}
+
+void
+SHA3_Final(u_int8_t* digest, SHA3_CTX *context)
+{
+ size_t i, j;
+ unsigned int partialBlock;
+ unsigned char *curData;
+ unsigned int rateInBytes;
+ size_t dataByteLen;
+
+ rateInBytes = context->rate/8;
+ dataByteLen = context->fixedOutputLength/8;
+
+ /* Last few bits, whose delimiter coincides with first bit of padding */
+ KeccakP1600_AddByte(context->state, SHA3_DELIMITER, context->byteIOIndex);
+
+ /*
+ * If the first bit of padding is at position rate-1, we need a whole
+ * new block for the second bit of padding
+ */
+ /* Second bit of padding */
+ KeccakP1600_AddByte(context->state, 0x80, rateInBytes-1);
+
+ KeccakP1600_Permute_24rounds(context->state);
+ context->byteIOIndex = 0;
+
+ /* SQUEEZE */
+ i = 0;
+ curData = digest;
+ while(i < dataByteLen) {
+ if ((context->byteIOIndex == rateInBytes) && (dataByteLen >= (i + rateInBytes))) {
+ for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) {
+ KeccakP1600_Permute_24rounds(context->state);
+ KeccakP1600_ExtractBytes(context->state, curData, 0, rateInBytes);
+ curData+=rateInBytes;
+ }
+ i = dataByteLen - j;
+ }
+ else {
+ /* normal lane: using the message queue */
+ if (context->byteIOIndex == rateInBytes) {
+ KeccakP1600_Permute_24rounds(context->state);
+ context->byteIOIndex = 0;
+ }
+ partialBlock = (unsigned int)(dataByteLen - i);
+ if (partialBlock+context->byteIOIndex > rateInBytes)
+ partialBlock = rateInBytes-context->byteIOIndex;
+ i += partialBlock;
+
+ KeccakP1600_ExtractBytes(context->state, curData, context->byteIOIndex, partialBlock);
+ curData += partialBlock;
+ context->byteIOIndex += partialBlock;
+ }
+ }
+}
+
+/*
+ * internal functions
+ */
+static void
+Keccak_HashInitialize(SHA3_CTX *context, unsigned int rate,
+    unsigned int hashbitlen)
+{
+ bzero(context->state, SHA3_STATE_SIZE);
+ context->rate = rate;
+ context->byteIOIndex = 0;
+ context->fixedOutputLength = hashbitlen;
+}
+
+static void
+KeccakP1600_AddByte(void *state, unsigned char byte, unsigned int offset)
+{
+ assert(offset < 200);
+ ((unsigned char *)state)[offset] ^= byte;
+}
+
+static void
+KeccakP1600_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length)
+{
+ unsigned int i;
+
+ assert(offset < 200);
+ assert(offset+length <= 200);
+ for(i=0; i<length; i++)
+ ((unsigned char *)state)[offset+i] ^= data[i];
+}
+
+#if BYTE_ORDER == BIG_ENDIAN
+static void fromBytesToWords(tKeccakLane *stateAsWords, const unsigned char *state);
+static void fromWordsToBytes(unsigned char *state, const tKeccakLane *stateAsWords);
+#endif
+static void KeccakP1600OnWords(tKeccakLane *state);
+#if BYTE_ORDER == LITTLE_ENDIAN
+static void KeccakP1600QuadRound(tKeccakLane *state, unsigned int indexRound);
+#else
+static void KeccakP1600RoundSlow(tKeccakLane *state, unsigned int indexRound);
+static void theta(tKeccakLane *A);
+static void rho(tKeccakLane *A);
+static void pi(tKeccakLane *A);
+static void chi(tKeccakLane *A);
+static void iota(tKeccakLane *A, unsigned int indexRound);
+#endif
+
+static void
+KeccakP1600_Permute_24rounds(void *state)
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+ KeccakP1600OnWords((tKeccakLane*)state);
+#else
+ tKeccakLane stateAsWords[1600/64];
+
+ fromBytesToWords(stateAsWords, (const unsigned char *)state);
+ KeccakP1600OnWords(stateAsWords);
+ fromWordsToBytes((unsigned char *)state, stateAsWords);
+#endif
+}
+
+#if BYTE_ORDER == BIG_ENDIAN
+static void
+fromBytesToWords(tKeccakLane *stateAsWords, const unsigned char *state)
+{
+ unsigned int i, j;
+
+ for(i=0; i<SHA3_NRLANES; i++) {
+ stateAsWords[i] = 0;
+ for(j=0; j<(64/8); j++)
+ stateAsWords[i] |= (tKeccakLane)(state[i*(64/8)+j]) << (8*j);
+ }
+}
+
+static void
+fromWordsToBytes(unsigned char *state, const tKeccakLane *stateAsWords)
+{
+ unsigned int i, j;
+
+ for(i=0; i<SHA3_NRLANES; i++)
+ for(j=0; j<(64/8); j++)
+ state[i*(64/8)+j] = (unsigned char)((stateAsWords[i] >> (8*j)) & 0xFF);
+}
+#endif
+
+static void
+KeccakP1600OnWords(tKeccakLane *state)
+{
+ unsigned int i;
+
+
+#if BYTE_ORDER == BIG_ENDIAN
+ /*
+ * Use the unoptimized reference implementation when
+ * on big endian machines
+ */
+ for(i=0; i<SHA3_NRROUNDS; i++)
+ KeccakP1600RoundSlow(state, i);
+#else
+ /*
+ * Use the inplace version from the Keccak optimized reference
+ * code of KeccakP1600 on little endian machines
+ * Note that this routine does four rounds in one call.
+ * */
+ for(i=0; i<SHA3_NRROUNDS; i+=4)
+ KeccakP1600QuadRound(state, i);
+#endif
+}
+
+#define ROL64(a, offset) ((offset != 0) ? ((((tKeccakLane)a) << offset) ^ (((tKeccakLane)a) >> (64-offset))) : a)
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+static void
+KeccakP1600QuadRound(tKeccakLane *state, unsigned int indexRound)
+{        
+        /*
+ * Inplace implementation by Ronny Van Keer and the designers
+ * of Keccak from the optimized Keccak reference code
+ */
+
+ tKeccakLane Ba, Be, Bi, Bo, Bu;
+        tKeccakLane Ca, Ce, Ci, Co, Cu;
+        tKeccakLane Da, De, Di, Do, Du;
+
+        #define Aba state[ 0]
+        #define Abe state[ 1]
+        #define Abi state[ 2]
+        #define Abo state[ 3]
+        #define Abu state[ 4]
+        #define Aga state[ 5]
+        #define Age state[ 6]
+        #define Agi state[ 7]
+        #define Ago state[ 8]
+        #define Agu state[ 9]
+        #define Aka state[10]
+        #define Ake state[11]
+        #define Aki state[12]
+        #define Ako state[13]
+        #define Aku state[14]
+        #define Ama state[15]
+        #define Ame state[16]
+        #define Ami state[17]
+        #define Amo state[18]
+        #define Amu state[19]
+        #define Asa state[20]
+        #define Ase state[21]
+        #define Asi state[22]
+        #define Aso state[23]
+        #define Asu state[24]
+
+
+        Ca = Aba^Aga^Aka^Ama^Asa;
+        Ce = Abe^Age^Ake^Ame^Ase;
+        Ci = Abi^Agi^Aki^Ami^Asi;
+        Co = Abo^Ago^Ako^Amo^Aso;
+        Cu = Abu^Agu^Aku^Amu^Asu;
+        Da = Cu^ROL64(Ce, 1);
+        De = Ca^ROL64(Ci, 1);
+        Di = Ce^ROL64(Co, 1);
+        Do = Ci^ROL64(Cu, 1);
+        Du = Co^ROL64(Ca, 1);
+
+        Ba = (Aba^Da);
+        Be = ROL64((Age^De), 44);
+        Bi = ROL64((Aki^Di), 43);
+        Bo = ROL64((Amo^Do), 21);
+        Bu = ROL64((Asu^Du), 14);
+        Aba =   Ba ^((~Be)&  Bi );
+        Aba ^= KeccakRoundConstants[indexRound];
+        Age =   Be ^((~Bi)&  Bo );
+        Aki =   Bi ^((~Bo)&  Bu );
+        Amo =   Bo ^((~Bu)&  Ba );
+        Asu =   Bu ^((~Ba)&  Be );
+
+        Bi = ROL64((Aka^Da), 3);
+        Bo = ROL64((Ame^De), 45);
+        Bu = ROL64((Asi^Di), 61);
+        Ba = ROL64((Abo^Do), 28);
+        Be = ROL64((Agu^Du), 20);
+        Aka =   Ba ^((~Be)&  Bi );
+        Ame =   Be ^((~Bi)&  Bo );
+        Asi =   Bi ^((~Bo)&  Bu );
+        Abo =   Bo ^((~Bu)&  Ba );
+        Agu =   Bu ^((~Ba)&  Be );
+
+        Bu = ROL64((Asa^Da), 18);
+        Ba = ROL64((Abe^De), 1);
+        Be = ROL64((Agi^Di), 6);
+        Bi = ROL64((Ako^Do), 25);
+        Bo = ROL64((Amu^Du), 8);
+        Asa =   Ba ^((~Be)&  Bi );
+        Abe =   Be ^((~Bi)&  Bo );
+        Agi =   Bi ^((~Bo)&  Bu );
+        Ako =   Bo ^((~Bu)&  Ba );
+        Amu =   Bu ^((~Ba)&  Be );
+
+        Be = ROL64((Aga^Da), 36);
+        Bi = ROL64((Ake^De), 10);
+        Bo = ROL64((Ami^Di), 15);
+        Bu = ROL64((Aso^Do), 56);
+        Ba = ROL64((Abu^Du), 27);
+        Aga =   Ba ^((~Be)&  Bi );
+        Ake =   Be ^((~Bi)&  Bo );
+        Ami =   Bi ^((~Bo)&  Bu );
+        Aso =   Bo ^((~Bu)&  Ba );
+        Abu =   Bu ^((~Ba)&  Be );
+
+        Bo = ROL64((Ama^Da), 41);
+        Bu = ROL64((Ase^De), 2);
+        Ba = ROL64((Abi^Di), 62);
+        Be = ROL64((Ago^Do), 55);
+        Bi = ROL64((Aku^Du), 39);
+        Ama =   Ba ^((~Be)&  Bi );
+        Ase =   Be ^((~Bi)&  Bo );
+        Abi =   Bi ^((~Bo)&  Bu );
+        Ago =   Bo ^((~Bu)&  Ba );
+        Aku =   Bu ^((~Ba)&  Be );
+
+        Ca = Aba^Aka^Asa^Aga^Ama;
+        Ce = Age^Ame^Abe^Ake^Ase;
+        Ci = Aki^Asi^Agi^Ami^Abi;
+        Co = Amo^Abo^Ako^Aso^Ago;
+        Cu = Asu^Agu^Amu^Abu^Aku;
+        Da = Cu^ROL64(Ce, 1);
+        De = Ca^ROL64(Ci, 1);
+        Di = Ce^ROL64(Co, 1);
+        Do = Ci^ROL64(Cu, 1);
+        Du = Co^ROL64(Ca, 1);
+
+        Ba = (Aba^Da);
+        Be = ROL64((Ame^De), 44);
+        Bi = ROL64((Agi^Di), 43);
+        Bo = ROL64((Aso^Do), 21);
+        Bu = ROL64((Aku^Du), 14);
+        Aba =   Ba ^((~Be)&  Bi );
+        Aba ^= KeccakRoundConstants[indexRound+1];
+        Ame =   Be ^((~Bi)&  Bo );
+        Agi =   Bi ^((~Bo)&  Bu );
+        Aso =   Bo ^((~Bu)&  Ba );
+        Aku =   Bu ^((~Ba)&  Be );
+
+        Bi = ROL64((Asa^Da), 3);
+        Bo = ROL64((Ake^De), 45);
+        Bu = ROL64((Abi^Di), 61);
+        Ba = ROL64((Amo^Do), 28);
+        Be = ROL64((Agu^Du), 20);
+        Asa =   Ba ^((~Be)&  Bi );
+        Ake =   Be ^((~Bi)&  Bo );
+        Abi =   Bi ^((~Bo)&  Bu );
+        Amo =   Bo ^((~Bu)&  Ba );
+        Agu =   Bu ^((~Ba)&  Be );
+
+        Bu = ROL64((Ama^Da), 18);
+        Ba = ROL64((Age^De), 1);
+        Be = ROL64((Asi^Di), 6);
+        Bi = ROL64((Ako^Do), 25);
+        Bo = ROL64((Abu^Du), 8);
+        Ama =   Ba ^((~Be)&  Bi );
+        Age =   Be ^((~Bi)&  Bo );
+        Asi =   Bi ^((~Bo)&  Bu );
+        Ako =   Bo ^((~Bu)&  Ba );
+        Abu =   Bu ^((~Ba)&  Be );
+
+        Be = ROL64((Aka^Da), 36);
+        Bi = ROL64((Abe^De), 10);
+        Bo = ROL64((Ami^Di), 15);
+        Bu = ROL64((Ago^Do), 56);
+        Ba = ROL64((Asu^Du), 27);
+        Aka =   Ba ^((~Be)&  Bi );
+        Abe =   Be ^((~Bi)&  Bo );
+        Ami =   Bi ^((~Bo)&  Bu );
+        Ago =   Bo ^((~Bu)&  Ba );
+        Asu =   Bu ^((~Ba)&  Be );
+
+        Bo = ROL64((Aga^Da), 41);
+        Bu = ROL64((Ase^De), 2);
+        Ba = ROL64((Aki^Di), 62);
+        Be = ROL64((Abo^Do), 55);
+        Bi = ROL64((Amu^Du), 39);
+        Aga =   Ba ^((~Be)&  Bi );
+        Ase =   Be ^((~Bi)&  Bo );
+        Aki =   Bi ^((~Bo)&  Bu );
+        Abo =   Bo ^((~Bu)&  Ba );
+        Amu =   Bu ^((~Ba)&  Be );
+
+        Ca = Aba^Asa^Ama^Aka^Aga;
+        Ce = Ame^Ake^Age^Abe^Ase;
+        Ci = Agi^Abi^Asi^Ami^Aki;
+        Co = Aso^Amo^Ako^Ago^Abo;
+        Cu = Aku^Agu^Abu^Asu^Amu;
+        Da = Cu^ROL64(Ce, 1);
+        De = Ca^ROL64(Ci, 1);
+        Di = Ce^ROL64(Co, 1);
+        Do = Ci^ROL64(Cu, 1);
+        Du = Co^ROL64(Ca, 1);
+
+        Ba = (Aba^Da);
+        Be = ROL64((Ake^De), 44);
+        Bi = ROL64((Asi^Di), 43);
+        Bo = ROL64((Ago^Do), 21);
+        Bu = ROL64((Amu^Du), 14);
+        Aba =   Ba ^((~Be)&  Bi );
+        Aba ^= KeccakRoundConstants[indexRound+2];
+        Ake =   Be ^((~Bi)&  Bo );
+        Asi =   Bi ^((~Bo)&  Bu );
+        Ago =   Bo ^((~Bu)&  Ba );
+        Amu =   Bu ^((~Ba)&  Be );
+
+        Bi = ROL64((Ama^Da), 3);
+        Bo = ROL64((Abe^De), 45);
+        Bu = ROL64((Aki^Di), 61);
+        Ba = ROL64((Aso^Do), 28);
+        Be = ROL64((Agu^Du), 20);
+        Ama =   Ba ^((~Be)&  Bi );
+        Abe =   Be ^((~Bi)&  Bo );
+        Aki =   Bi ^((~Bo)&  Bu );
+        Aso =   Bo ^((~Bu)&  Ba );
+        Agu =   Bu ^((~Ba)&  Be );
+
+        Bu = ROL64((Aga^Da), 18);
+        Ba = ROL64((Ame^De), 1);
+        Be = ROL64((Abi^Di), 6);
+        Bi = ROL64((Ako^Do), 25);
+        Bo = ROL64((Asu^Du), 8);
+        Aga =   Ba ^((~Be)&  Bi );
+        Ame =   Be ^((~Bi)&  Bo );
+        Abi =   Bi ^((~Bo)&  Bu );
+        Ako =   Bo ^((~Bu)&  Ba );
+        Asu =   Bu ^((~Ba)&  Be );
+
+        Be = ROL64((Asa^Da), 36);
+        Bi = ROL64((Age^De), 10);
+        Bo = ROL64((Ami^Di), 15);
+        Bu = ROL64((Abo^Do), 56);
+        Ba = ROL64((Aku^Du), 27);
+        Asa =   Ba ^((~Be)&  Bi );
+        Age =   Be ^((~Bi)&  Bo );
+        Ami =   Bi ^((~Bo)&  Bu );
+        Abo =   Bo ^((~Bu)&  Ba );
+        Aku =   Bu ^((~Ba)&  Be );
+
+        Bo = ROL64((Aka^Da), 41);
+        Bu = ROL64((Ase^De), 2);
+        Ba = ROL64((Agi^Di), 62);
+        Be = ROL64((Amo^Do), 55);
+        Bi = ROL64((Abu^Du), 39);
+        Aka =   Ba ^((~Be)&  Bi );
+        Ase =   Be ^((~Bi)&  Bo );
+        Agi =   Bi ^((~Bo)&  Bu );
+        Amo =   Bo ^((~Bu)&  Ba );
+        Abu =   Bu ^((~Ba)&  Be );
+
+        Ca = Aba^Ama^Aga^Asa^Aka;
+        Ce = Ake^Abe^Ame^Age^Ase;
+        Ci = Asi^Aki^Abi^Ami^Agi;
+        Co = Ago^Aso^Ako^Abo^Amo;
+        Cu = Amu^Agu^Asu^Aku^Abu;
+        Da = Cu^ROL64(Ce, 1);
+        De = Ca^ROL64(Ci, 1);
+        Di = Ce^ROL64(Co, 1);
+        Do = Ci^ROL64(Cu, 1);
+        Du = Co^ROL64(Ca, 1);
+
+        Ba = (Aba^Da);
+        Be = ROL64((Abe^De), 44);
+        Bi = ROL64((Abi^Di), 43);
+        Bo = ROL64((Abo^Do), 21);
+        Bu = ROL64((Abu^Du), 14);
+        Aba =   Ba ^((~Be)&  Bi );
+        Aba ^= KeccakRoundConstants[indexRound+3];
+        Abe =   Be ^((~Bi)&  Bo );
+        Abi =   Bi ^((~Bo)&  Bu );
+        Abo =   Bo ^((~Bu)&  Ba );
+        Abu =   Bu ^((~Ba)&  Be );
+
+        Bi = ROL64((Aga^Da), 3);
+        Bo = ROL64((Age^De), 45);
+        Bu = ROL64((Agi^Di), 61);
+        Ba = ROL64((Ago^Do), 28);
+        Be = ROL64((Agu^Du), 20);
+        Aga =   Ba ^((~Be)&  Bi );
+        Age =   Be ^((~Bi)&  Bo );
+        Agi =   Bi ^((~Bo)&  Bu );
+        Ago =   Bo ^((~Bu)&  Ba );
+        Agu =   Bu ^((~Ba)&  Be );
+
+        Bu = ROL64((Aka^Da), 18);
+        Ba = ROL64((Ake^De), 1);
+        Be = ROL64((Aki^Di), 6);
+        Bi = ROL64((Ako^Do), 25);
+        Bo = ROL64((Aku^Du), 8);
+        Aka =   Ba ^((~Be)&  Bi );
+        Ake =   Be ^((~Bi)&  Bo );
+        Aki =   Bi ^((~Bo)&  Bu );
+        Ako =   Bo ^((~Bu)&  Ba );
+        Aku =   Bu ^((~Ba)&  Be );
+
+        Be = ROL64((Ama^Da), 36);
+        Bi = ROL64((Ame^De), 10);
+        Bo = ROL64((Ami^Di), 15);
+        Bu = ROL64((Amo^Do), 56);
+        Ba = ROL64((Amu^Du), 27);
+        Ama =   Ba ^((~Be)&  Bi );
+        Ame =   Be ^((~Bi)&  Bo );
+        Ami =   Bi ^((~Bo)&  Bu );
+        Amo =   Bo ^((~Bu)&  Ba );
+        Amu =   Bu ^((~Ba)&  Be );
+
+        Bo = ROL64((Asa^Da), 41);
+        Bu = ROL64((Ase^De), 2);
+        Ba = ROL64((Asi^Di), 62);
+        Be = ROL64((Aso^Do), 55);
+        Bi = ROL64((Asu^Du), 39);
+        Asa =   Ba ^((~Be)&  Bi );
+        Ase =   Be ^((~Bi)&  Bo );
+        Asi =   Bi ^((~Bo)&  Bu );
+        Aso =   Bo ^((~Bu)&  Ba );
+        Asu =   Bu ^((~Ba)&  Be );
+
+ #undef Aba
+        #undef Abe
+        #undef Abi
+        #undef Abo
+        #undef Abu
+        #undef Aga
+        #undef Age
+        #undef Agi
+        #undef Ago
+        #undef Agu
+        #undef Aka
+        #undef Ake
+        #undef Aki
+        #undef Ako
+        #undef Aku
+        #undef Ama
+        #undef Ame
+        #undef Ami
+        #undef Amo
+        #undef Amu
+        #undef Asa
+        #undef Ase
+        #undef Asi
+        #undef Aso
+        #undef Asu
+}
+
+#else /* BYTE_ORDER != BIG_ENDIAN */
+void
+KeccakP1600RoundSlow(tKeccakLane *state, unsigned int indexRound)
+{        
+ theta(state);
+ rho(state);
+ pi(state);
+ chi(state);
+ iota(state, indexRound);
+}
+
+#define ROL64(a, offset) ((offset != 0) ? ((((tKeccakLane)a) << offset) ^ (((tKeccakLane)a) >> (64-offset))) : a)
+
+static void theta(tKeccakLane *A)
+{
+ unsigned int x, y;
+ tKeccakLane C[5], D[5];
+
+ for(x=0; x<5; x++) {
+ C[x] = 0;
+ for(y=0; y<5; y++)
+ C[x] ^= A[index(x, y)];
+ }
+ for(x=0; x<5; x++)
+ D[x] = ROL64(C[(x+1)%5], 1) ^ C[(x+4)%5];
+ for(x=0; x<5; x++)
+ for(y=0; y<5; y++)
+ A[index(x, y)] ^= D[x];
+}
+
+static void rho(tKeccakLane *A)
+{
+ unsigned int x, y;
+
+ for(x=0; x<5; x++) for(y=0; y<5; y++)
+ A[index(x, y)] = ROL64(A[index(x, y)], KeccakRhoOffsets[index(x, y)]);
+}
+
+static void pi(tKeccakLane *A)
+{
+ unsigned int x, y;
+ tKeccakLane tempA[25];
+
+ for(x=0; x<5; x++) for(y=0; y<5; y++)
+ tempA[index(x, y)] = A[index(x, y)];
+ for(x=0; x<5; x++) for(y=0; y<5; y++)
+ A[index(0*x+1*y, 2*x+3*y)] = tempA[index(x, y)];
+}
+
+static void chi(tKeccakLane *A)
+{
+ unsigned int x, y;
+ tKeccakLane C[5];
+
+ for(y=0; y<5; y++) {
+ for(x=0; x<5; x++)
+ C[x] = A[index(x, y)] ^ ((~A[index(x+1, y)]) & A[index(x+2, y)]);
+ for(x=0; x<5; x++)
+ A[index(x, y)] = C[x];
+ }
+}
+
+static void iota(tKeccakLane *A, unsigned int indexRound)
+{
+ A[index(0, 0)] ^= KeccakRoundConstants[indexRound];
+}
+#endif /* BYTE_ORDER != BIG_ENDIAN */
+
+static void
+KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length)
+{
+ assert(offset < 200);
+ assert(offset+length <= 200);
+ memcpy(data, (unsigned char*)state+offset, length);
+}
+
Index: lib/libc/hidden/sha3.h
===================================================================
RCS file: lib/libc/hidden/sha3.h
diff -N lib/libc/hidden/sha3.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libc/hidden/sha3.h 9 Jan 2018 15:17:42 -0000
@@ -0,0 +1,76 @@
+#ifndef _SHA3_H
+#define _SHA3_H
+
+#define SHA3_224_DIGEST_LENGTH 28
+#define SHA3_224_DIGEST_STRING_LENGTH (SHA3_224_DIGEST_LENGTH * 2 + 1)
+
+#define SHA3_256_DIGEST_LENGTH 32
+#define SHA3_256_DIGEST_STRING_LENGTH (SHA3_256_DIGEST_LENGTH * 2 + 1)
+
+#define SHA3_384_DIGEST_LENGTH 48
+#define SHA3_384_DIGEST_STRING_LENGTH (SHA3_384_DIGEST_LENGTH * 2 + 1)
+
+#define SHA3_512_DIGEST_LENGTH 64
+#define SHA3_512_DIGEST_STRING_LENGTH (SHA3_512_DIGEST_LENGTH * 2 + 1)
+
+#define SHA3_STATE_SIZE 1600 / 8
+
+
+typedef struct _SHA3_CTX {
+ unsigned char state[SHA3_STATE_SIZE];
+ unsigned int rate;
+ unsigned int byteIOIndex;
+ unsigned int fixedOutputLength;
+} SHA3_CTX;
+
+
+void SHA3_224Init(SHA3_CTX *);
+char *SHA3_224End(SHA3_CTX *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH)));
+char *SHA3_224File(const char *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH)));
+char *SHA3_224FileChunk(const char *, char *, off_t, off_t)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH)));
+char *SHA3_224Data(const u_int8_t *, size_t, char *)
+ __attribute__((__bounded__(__string__,1,2)))
+ __attribute__((__bounded__(__minbytes__,3,SHA3_224_DIGEST_STRING_LENGTH)));
+
+void SHA3_256Init(SHA3_CTX *);
+char *SHA3_256End(SHA3_CTX *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH)));
+char *SHA3_256File(const char *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH)));
+char *SHA3_256FileChunk(const char *, char *, off_t, off_t)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH)));
+char *SHA3_256Data(const u_int8_t *, size_t, char *)
+ __attribute__((__bounded__(__string__,1,2)))
+ __attribute__((__bounded__(__minbytes__,3,SHA3_256_DIGEST_STRING_LENGTH)));
+
+void SHA3_384Init(SHA3_CTX *);
+char *SHA3_384End(SHA3_CTX *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH)));
+char *SHA3_384File(const char *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH)));
+char *SHA3_384FileChunk(const char *, char *, off_t, off_t)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH)));
+char *SHA3_384Data(const u_int8_t *, size_t, char *)
+ __attribute__((__bounded__(__string__,1,2)))
+ __attribute__((__bounded__(__minbytes__,3,SHA3_384_DIGEST_STRING_LENGTH)));
+
+void SHA3_512Init(SHA3_CTX *);
+char *SHA3_512End(SHA3_CTX *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH)));
+char *SHA3_512File(const char *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH)));
+char *SHA3_512FileChunk(const char *, char *, off_t, off_t)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH)));
+char *SHA3_512Data(const u_int8_t *, size_t, char *)
+ __attribute__((__bounded__(__string__,1,2)))
+ __attribute__((__bounded__(__minbytes__,3,SHA3_512_DIGEST_STRING_LENGTH)));
+
+void SHA3_Update(SHA3_CTX *, const u_int8_t *, size_t)
+ __attribute__((__bounded__(__string__,2,3)));
+void SHA3_Final(u_int8_t [SHA3_224_DIGEST_LENGTH], SHA3_CTX *)
+ __attribute__((__bounded__(__minbytes__,1,SHA3_224_DIGEST_LENGTH)));
+
+#endif /* _SHA3_H */

Reply | Threaded
Open this post in threaded view
|

Re: Basic SHA3 support

Todd C. Miller-2
On Tue, 09 Jan 2018 16:47:18 +0100, Daniel Loebenberger wrote:

> Changes have been made to libc, and a suite of sha3 checksum tools
> were added (sha3-224, sha3-256, sha3-384, sha-512), extending the
> existing md5(1) checksum tool.
>
> The SHA3 implementation itself was taken from the reference code written
> by the Keccak Team (https://keccak.team/) which is available under public
> domain (CC0).
>
> We'd be happy to see this in OpenBSD and appreciate any comments.

Looks good in general, some comments inline.

 - todd

> Index: include/sha3.h
> ===================================================================
> RCS file: include/sha3.h
> diff -N include/sha3.h
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ include/sha3.h 9 Jan 2018 15:17:42 -0000
> @@ -0,0 +1,76 @@
> +#ifndef _SHA3_H
> +#define _SHA3_H
> +
> +#define SHA3_224_DIGEST_LENGTH 28
> +#define SHA3_224_DIGEST_STRING_LENGTH (SHA3_224_DIGEST_LENGTH * 2 + 1
> )
> +
> +#define SHA3_256_DIGEST_LENGTH 32
> +#define SHA3_256_DIGEST_STRING_LENGTH (SHA3_256_DIGEST_LENGTH * 2 + 1
> )
> +
> +#define SHA3_384_DIGEST_LENGTH 48
> +#define SHA3_384_DIGEST_STRING_LENGTH (SHA3_384_DIGEST_LENGTH * 2 + 1
> )
> +
> +#define SHA3_512_DIGEST_LENGTH 64
> +#define SHA3_512_DIGEST_STRING_LENGTH (SHA3_512_DIGEST_LENGTH * 2 + 1
> )
> +
> +#define SHA3_STATE_SIZE 1600 / 8

This should be parenthesized, i.e. (1600 / 8)

> +
> +
> +typedef struct _SHA3_CTX {
> + unsigned char state[SHA3_STATE_SIZE];
> + unsigned int rate;
> + unsigned int byteIOIndex;
> + unsigned int fixedOutputLength;
> +} SHA3_CTX;
> +
> +
> +void SHA3_224Init(SHA3_CTX *);
> +char *SHA3_224End(SHA3_CTX *, char *)
> + __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_224File(const char *, char *)
> + __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_224FileChunk(const char *, char *, off_t, off_t)
> + __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_224Data(const u_int8_t *, size_t, char *)
> + __attribute__((__bounded__(__string__,1,2)))
> + __attribute__((__bounded__(__minbytes__,3,SHA3_224_DIGEST_STRING_LENGTH
> )));
> +
> +void SHA3_256Init(SHA3_CTX *);
> +char *SHA3_256End(SHA3_CTX *, char *)
> + __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_256File(const char *, char *)
> + __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_256FileChunk(const char *, char *, off_t, off_t)
> + __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_256Data(const u_int8_t *, size_t, char *)
> + __attribute__((__bounded__(__string__,1,2)))
> + __attribute__((__bounded__(__minbytes__,3,SHA3_256_DIGEST_STRING_LENGTH
> )));
> +
> +void SHA3_384Init(SHA3_CTX *);
> +char *SHA3_384End(SHA3_CTX *, char *)
> + __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_384File(const char *, char *)
> + __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_384FileChunk(const char *, char *, off_t, off_t)
> + __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_384Data(const u_int8_t *, size_t, char *)
> + __attribute__((__bounded__(__string__,1,2)))
> + __attribute__((__bounded__(__minbytes__,3,SHA3_384_DIGEST_STRING_LENGTH
> )));
> +
> +void SHA3_512Init(SHA3_CTX *);
> +char *SHA3_512End(SHA3_CTX *, char *)
> + __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_512File(const char *, char *)
> + __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_512FileChunk(const char *, char *, off_t, off_t)
> + __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_512Data(const u_int8_t *, size_t, char *)
> + __attribute__((__bounded__(__string__,1,2)))
> + __attribute__((__bounded__(__minbytes__,3,SHA3_512_DIGEST_STRING_LENGTH
> )));
> +
> +void SHA3_Update(SHA3_CTX *, const u_int8_t *, size_t)
> + __attribute__((__bounded__(__string__,2,3)));
> +void SHA3_Final(u_int8_t [SHA3_224_DIGEST_LENGTH], SHA3_CTX *)
> + __attribute__((__bounded__(__minbytes__,1,SHA3_224_DIGEST_LENGTH)));
> +
> +#endif /* _SHA3_H */
> Index: lib/libc/hash/sha3.c
> ===================================================================
> RCS file: lib/libc/hash/sha3.c
> diff -N lib/libc/hash/sha3.c
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ lib/libc/hash/sha3.c 9 Jan 2018 15:17:42 -0000
> @@ -0,0 +1,756 @@
> +/*
> + * Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido
> Bertoni,
> + * Joan Daemen, Micha�l Peeters, Gilles Van Assche and Ronny Van Keer,
> hereby
> + * denoted as "the implementer".
> + *
> + * For more information, feedback or questions, please refer to our
> websites:
> + * http://keccak.noekeon.org/
> + * http://keyak.noekeon.org/
> + * http://ketje.noekeon.org/
> + *
> + * Adaptation to OpenBSD in 2017/18 by
> + * Alexander von Gernler, Daniel Loebenberger and Stefan-Lukas Gazdag
> + * https://www.genua.de/
> + * also denoted as "the implementer"
> + *
> + * To the extent possible under law, the implementer has waived all
> copyright
> + * and related or neighboring rights to the source code in this file.
> + * http://creativecommons.org/publicdomain/zero/1.0/
> + */
> +
> +#include <assert.h>
> +#include <sys/types.h>
> +#include <string.h>
> +#include <strings.h>
> +#include <sha3.h>
> +
> +typedef unsigned long long tKeccakLane;
> +
> +#define SHA3_NRROUNDS 24
> +#define SHA3_NRLANES 25
> +#define SHA3_DELIMITER 0x06
> +
> +#define index(x, y) (((x)%5)+5*((y)%5))
> +
> +const tKeccakLane KeccakRoundConstants[SHA3_NRROUNDS] =
> +{
> + 0x0000000000000001,
> + 0x0000000000008082,
> + 0x800000000000808a,
> + 0x8000000080008000,
> + 0x000000000000808b,
> + 0x0000000080000001,
> + 0x8000000080008081,
> + 0x8000000000008009,
> + 0x000000000000008a,
> + 0x0000000000000088,
> + 0x0000000080008009,
> + 0x000000008000000a,
> + 0x000000008000808b,
> + 0x800000000000008b,
> + 0x8000000000008089,
> + 0x8000000000008003,
> + 0x8000000000008002,
> + 0x8000000000000080,
> + 0x000000000000800a,
> + 0x800000008000000a,
> + 0x8000000080008081,
> + 0x8000000000008080,
> + 0x0000000080000001,
> + 0x8000000080008008,
> +};
> +
> +const unsigned int KeccakRhoOffsets[SHA3_NRLANES] =
> +{
> + 0, 1, 62, 28, 27, 36, 44, 6, 55, 20, 3, 10, 43,
> + 25, 39, 41, 45, 15, 21, 8, 18, 2, 61, 56, 14
> +};
> +
> +/*
> + * unused, but these constance denote the one implementation out of the
> + * Keccak Code Package that was taken here
> + */
> +#define KeccakP1600_implementation      "64-bit reference implementation"
> +#define KeccakP1600_stateSizeInBytes    200
> +#define KeccakP1600_stateAlignment      8
> +
> +/* prototypes for local functions */
> +static void KeccakP1600_AddByte(void *state, unsigned char data,
> +    unsigned int offset);
> +static void KeccakP1600_AddBytes(void *state, const unsigned char *data,
> +    unsigned int offset, unsigned int length);
> +static void KeccakP1600_Permute_24rounds(void *state);
> +static void KeccakP1600_ExtractBytes(const void *state, unsigned char *data,
> +    unsigned int offset, unsigned int length);
> +static void Keccak_HashInitialize(SHA3_CTX *, unsigned int, unsigned int);
> +
> +
> +/*
> + * interface functions external use
> + * (rate + capacity) = 1600,
> + * thus the rate specifies the capacity
> + */
> +void
> +SHA3_224Init(SHA3_CTX *context)
> +{
> + /* rate = 1152, output width 224 bit */
> + Keccak_HashInitialize(context, 1152, 224);
> +}
> +
> +void
> +SHA3_256Init(SHA3_CTX *context)
> +{
> + /* rate = 1088, output width 256 bit */
> + Keccak_HashInitialize(context, 1088, 256);
> +}
> +
> +void
> +SHA3_384Init(SHA3_CTX *context)
> +{
> + /* rate = 832, output width 384 bit */
> + Keccak_HashInitialize(context, 832, 384);
> +}
> +
> +void
> +SHA3_512Init(SHA3_CTX *context)
> +{
> + /* rate = 576, output width 512 bit */
> + Keccak_HashInitialize(context, 576, 512);
> +}
> +
> +
> +void
> +SHA3_Update(SHA3_CTX *context, const u_int8_t *data, size_t len)
> +{
> + size_t i, j;
> + unsigned int partialBlock;
> + const unsigned char *curData;
> + unsigned int rateInBytes;
> + rateInBytes = context->rate/8;
> +
> + i = 0;
> + curData = data;
> + while(i < len) {
> + if ((context->byteIOIndex == 0) && (len >= (i + rateInBytes)))
> {
> +#ifdef SnP_FastLoop_Absorb
> + /* processing full blocks first */
> + if ((rateInBytes % (KeccakP1600_width/200)) == 0) {
> + /* fast lane: whole lane rate */
> + j = KeccakP1600_FastLoop_Absorb(context->state,
> +    rateInBytes/(KeccakP1600_width/200), curDat
> a, len - i);
> + i += j;
> + curData += j;
> + }
> + else {
> +#endif
> + for(j=len-i; j>=rateInBytes; j-=rateInBytes) {
> + #ifdef KeccakReference
> + displayBytes(1, "Block to be absorbed",
>  curData, rateInBytes);
> + #endif

The '#' for the  #ifdef/#endif should be at the start of the line.

> + KeccakP1600_AddBytes(context->state, cu
> rData, 0, rateInBytes);
> + KeccakP1600_Permute_24rounds(context->s
> tate);
> + curData+=rateInBytes;
> + }
> + i = len - j;
> +#ifdef SnP_FastLoop_Absorb
> + }
> +#endif
> + }
> + else {
> + /* normal lane: using the message queue */
> + partialBlock = (unsigned int)(len - i);
> + if (partialBlock+context->byteIOIndex > rateInBytes)
> + partialBlock = rateInBytes-context->byteIOIndex
> ;
> + #ifdef KeccakReference
> + displayBytes(1, "Block to be absorbed (part)", curData,
>  partialBlock);
> + #endif

The '#' for the  #ifdef/#endif should be at the start of the line.

> + i += partialBlock;
> +
> + KeccakP1600_AddBytes(context->state, curData, context->
> byteIOIndex,
> partialBlock);
> + curData += partialBlock;
> + context->byteIOIndex += partialBlock;
> + if (context->byteIOIndex == rateInBytes) {
> + KeccakP1600_Permute_24rounds(context->state);
> + context->byteIOIndex = 0;
> + }
> + }
> + }
> +}
> +
> +void
> +SHA3_Final(u_int8_t* digest, SHA3_CTX *context)
> +{
> + size_t i, j;
> + unsigned int partialBlock;
> + unsigned char *curData;
> + unsigned int rateInBytes;
> + size_t dataByteLen;
> +
> + rateInBytes = context->rate/8;
> + dataByteLen = context->fixedOutputLength/8;
> +
> + /* Last few bits, whose delimiter coincides with first bit of padding *
> /
> + KeccakP1600_AddByte(context->state, SHA3_DELIMITER, context->byteIOInde
> x);
> +
> + /*
> + * If the first bit of padding is at position rate-1, we need a whole
> + * new block for the second bit of padding
> + */
> + /* Second bit of padding */
> + KeccakP1600_AddByte(context->state, 0x80, rateInBytes-1);
> +
> + KeccakP1600_Permute_24rounds(context->state);
> + context->byteIOIndex = 0;
> +
> + /* SQUEEZE */
> + i = 0;
> + curData = digest;
> + while(i < dataByteLen) {
> + if ((context->byteIOIndex == rateInBytes) && (dataByteLen >= (i
>  +
> rateInBytes))) {
> + for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) {
> + KeccakP1600_Permute_24rounds(context->state);
> + KeccakP1600_ExtractBytes(context->state, curDat
> a, 0, rateInBytes);
> + curData+=rateInBytes;
> + }
> + i = dataByteLen - j;
> + }
> + else {
> + /* normal lane: using the message queue */
> + if (context->byteIOIndex == rateInBytes) {
> + KeccakP1600_Permute_24rounds(context->state);
> + context->byteIOIndex = 0;
> + }
> + partialBlock = (unsigned int)(dataByteLen - i);
> + if (partialBlock+context->byteIOIndex > rateInBytes)
> + partialBlock = rateInBytes-context->byteIOIndex
> ;
> + i += partialBlock;
> +
> + KeccakP1600_ExtractBytes(context->state, curData, conte
> xt->byteIOIndex,
> partialBlock);
> + curData += partialBlock;
> + context->byteIOIndex += partialBlock;
> + }
> + }
> +}
> +
> +/*
> + * internal functions
> + */
> +static void
> +Keccak_HashInitialize(SHA3_CTX *context, unsigned int rate,
> +    unsigned int hashbitlen)
> +{
> + bzero(context->state, SHA3_STATE_SIZE);
> + context->rate = rate;
> + context->byteIOIndex = 0;
> + context->fixedOutputLength = hashbitlen;
> +}
> +
> +static void
> +KeccakP1600_AddByte(void *state, unsigned char byte, unsigned int offset)
> +{
> + assert(offset < 200);
> + ((unsigned char *)state)[offset] ^= byte;
> +}
> +
> +static void
> +KeccakP1600_AddBytes(void *state, const unsigned char *data, unsigned int
> offset, unsigned int length)
> +{
> + unsigned int i;
> +
> + assert(offset < 200);
> + assert(offset+length <= 200);
> + for(i=0; i<length; i++)
> + ((unsigned char *)state)[offset+i] ^= data[i];
> +}
> +
> +#if BYTE_ORDER == BIG_ENDIAN
> +static void fromBytesToWords(tKeccakLane *stateAsWords, const unsigned char
> *state);
> +static void fromWordsToBytes(unsigned char *state, const tKeccakLane
> *stateAsWords);
> +#endif
> +static void KeccakP1600OnWords(tKeccakLane *state);
> +#if BYTE_ORDER == LITTLE_ENDIAN
> +static void KeccakP1600QuadRound(tKeccakLane *state, unsigned int
> indexRound);
> +#else
> +static void KeccakP1600RoundSlow(tKeccakLane *state, unsigned int
> indexRound);
> +static void theta(tKeccakLane *A);
> +static void rho(tKeccakLane *A);
> +static void pi(tKeccakLane *A);
> +static void chi(tKeccakLane *A);
> +static void iota(tKeccakLane *A, unsigned int indexRound);
> +#endif
> +
> +static void
> +KeccakP1600_Permute_24rounds(void *state)
> +{
> +#if BYTE_ORDER == LITTLE_ENDIAN
> + KeccakP1600OnWords((tKeccakLane*)state);
> +#else
> + tKeccakLane stateAsWords[1600/64];
> +
> + fromBytesToWords(stateAsWords, (const unsigned char *)state);
> + KeccakP1600OnWords(stateAsWords);
> + fromWordsToBytes((unsigned char *)state, stateAsWords);
> +#endif
> +}
> +
> +#if BYTE_ORDER == BIG_ENDIAN
> +static void
> +fromBytesToWords(tKeccakLane *stateAsWords, const unsigned char *state)
> +{
> + unsigned int i, j;
> +
> + for(i=0; i<SHA3_NRLANES; i++) {
> + stateAsWords[i] = 0;
> + for(j=0; j<(64/8); j++)
> + stateAsWords[i] |= (tKeccakLane)(state[i*(64/8)+j]) <<
> (8*j);
> + }
> +}
> +
> +static void
> +fromWordsToBytes(unsigned char *state, const tKeccakLane *stateAsWords)
> +{
> + unsigned int i, j;
> +
> + for(i=0; i<SHA3_NRLANES; i++)
> + for(j=0; j<(64/8); j++)
> + state[i*(64/8)+j] = (unsigned char)((stateAsWords[i] >>
>  (8*j)) & 0xFF);
> +}
> +#endif
> +
> +static void
> +KeccakP1600OnWords(tKeccakLane *state)
> +{
> + unsigned int i;
> +
> +
> +#if BYTE_ORDER == BIG_ENDIAN
> + /*
> + * Use the unoptimized reference implementation when
> + * on big endian machines
> + */
> + for(i=0; i<SHA3_NRROUNDS; i++)
> + KeccakP1600RoundSlow(state, i);
> +#else
> + /*
> + * Use the inplace version from the Keccak optimized reference
> + * code of KeccakP1600 on little endian machines
> + * Note that this routine does four rounds in one call.
> + * */
> + for(i=0; i<SHA3_NRROUNDS; i+=4)
> + KeccakP1600QuadRound(state, i);
> +#endif
> +}
> +
> +#define ROL64(a, offset) ((offset != 0) ? ((((tKeccakLane)a) << offset) ^
> (((tKeccakLane)a) >> (64-offset))) : a)
> +
> +#if BYTE_ORDER == LITTLE_ENDIAN
> +static void
> +KeccakP1600QuadRound(tKeccakLane *state, unsigned int indexRound)
> +{
> +        /*
> + * Inplace implementation by Ronny Van Keer and the designers
> + * of Keccak from the optimized Keccak reference code
> + */
> +
> + tKeccakLane Ba, Be, Bi, Bo, Bu;
> +        tKeccakLane Ca, Ce, Ci, Co, Cu;
> +        tKeccakLane Da, De, Di, Do, Du;
> +
> +        #define Aba state[ 0]
> +        #define Abe state[ 1]
> +        #define Abi state[ 2]
> +        #define Abo state[ 3]
> +        #define Abu state[ 4]
> +        #define Aga state[ 5]
> +        #define Age state[ 6]
> +        #define Agi state[ 7]
> +        #define Ago state[ 8]
> +        #define Agu state[ 9]
> +        #define Aka state[10]
> +        #define Ake state[11]
> +        #define Aki state[12]
> +        #define Ako state[13]
> +        #define Aku state[14]
> +        #define Ama state[15]
> +        #define Ame state[16]
> +        #define Ami state[17]
> +        #define Amo state[18]
> +        #define Amu state[19]
> +        #define Asa state[20]
> +        #define Ase state[21]
> +        #define Asi state[22]
> +        #define Aso state[23]
> +        #define Asu state[24]

The '#' for the  #defines should be at the start of the line.

> +
> +
> +        Ca = Aba^Aga^Aka^Ama^Asa;
> +        Ce = Abe^Age^Ake^Ame^Ase;
> +        Ci = Abi^Agi^Aki^Ami^Asi;
> +        Co = Abo^Ago^Ako^Amo^Aso;
> +        Cu = Abu^Agu^Aku^Amu^Asu;
> +        Da = Cu^ROL64(Ce, 1);
> +        De = Ca^ROL64(Ci, 1);
> +        Di = Ce^ROL64(Co, 1);
> +        Do = Ci^ROL64(Cu, 1);
> +        Du = Co^ROL64(Ca, 1);
> +
> +        Ba = (Aba^Da);
> +        Be = ROL64((Age^De), 44);
> +        Bi = ROL64((Aki^Di), 43);
> +        Bo = ROL64((Amo^Do), 21);
> +        Bu = ROL64((Asu^Du), 14);
> +        Aba =   Ba ^((~Be)&  Bi );
> +        Aba ^= KeccakRoundConstants[indexRound];
> +        Age =   Be ^((~Bi)&  Bo );
> +        Aki =   Bi ^((~Bo)&  Bu );
> +        Amo =   Bo ^((~Bu)&  Ba );
> +        Asu =   Bu ^((~Ba)&  Be );
> +
> +        Bi = ROL64((Aka^Da), 3);
> +        Bo = ROL64((Ame^De), 45);
> +        Bu = ROL64((Asi^Di), 61);
> +        Ba = ROL64((Abo^Do), 28);
> +        Be = ROL64((Agu^Du), 20);
> +        Aka =   Ba ^((~Be)&  Bi );
> +        Ame =   Be ^((~Bi)&  Bo );
> +        Asi =   Bi ^((~Bo)&  Bu );
> +        Abo =   Bo ^((~Bu)&  Ba );
> +        Agu =   Bu ^((~Ba)&  Be );
> +
> +        Bu = ROL64((Asa^Da), 18);
> +        Ba = ROL64((Abe^De), 1);
> +        Be = ROL64((Agi^Di), 6);
> +        Bi = ROL64((Ako^Do), 25);
> +        Bo = ROL64((Amu^Du), 8);
> +        Asa =   Ba ^((~Be)&  Bi );
> +        Abe =   Be ^((~Bi)&  Bo );
> +        Agi =   Bi ^((~Bo)&  Bu );
> +        Ako =   Bo ^((~Bu)&  Ba );
> +        Amu =   Bu ^((~Ba)&  Be );
> +
> +        Be = ROL64((Aga^Da), 36);
> +        Bi = ROL64((Ake^De), 10);
> +        Bo = ROL64((Ami^Di), 15);
> +        Bu = ROL64((Aso^Do), 56);
> +        Ba = ROL64((Abu^Du), 27);
> +        Aga =   Ba ^((~Be)&  Bi );
> +        Ake =   Be ^((~Bi)&  Bo );
> +        Ami =   Bi ^((~Bo)&  Bu );
> +        Aso =   Bo ^((~Bu)&  Ba );
> +        Abu =   Bu ^((~Ba)&  Be );
> +
> +        Bo = ROL64((Ama^Da), 41);
> +        Bu = ROL64((Ase^De), 2);
> +        Ba = ROL64((Abi^Di), 62);
> +        Be = ROL64((Ago^Do), 55);
> +        Bi = ROL64((Aku^Du), 39);
> +        Ama =   Ba ^((~Be)&  Bi );
> +        Ase =   Be ^((~Bi)&  Bo );
> +        Abi =   Bi ^((~Bo)&  Bu );
> +        Ago =   Bo ^((~Bu)&  Ba );
> +        Aku =   Bu ^((~Ba)&  Be );
> +
> +        Ca = Aba^Aka^Asa^Aga^Ama;
> +        Ce = Age^Ame^Abe^Ake^Ase;
> +        Ci = Aki^Asi^Agi^Ami^Abi;
> +        Co = Amo^Abo^Ako^Aso^Ago;
> +        Cu = Asu^Agu^Amu^Abu^Aku;
> +        Da = Cu^ROL64(Ce, 1);
> +        De = Ca^ROL64(Ci, 1);
> +        Di = Ce^ROL64(Co, 1);
> +        Do = Ci^ROL64(Cu, 1);
> +        Du = Co^ROL64(Ca, 1);
> +
> +        Ba = (Aba^Da);
> +        Be = ROL64((Ame^De), 44);
> +        Bi = ROL64((Agi^Di), 43);
> +        Bo = ROL64((Aso^Do), 21);
> +        Bu = ROL64((Aku^Du), 14);
> +        Aba =   Ba ^((~Be)&  Bi );
> +        Aba ^= KeccakRoundConstants[indexRound+1];
> +        Ame =   Be ^((~Bi)&  Bo );
> +        Agi =   Bi ^((~Bo)&  Bu );
> +        Aso =   Bo ^((~Bu)&  Ba );
> +        Aku =   Bu ^((~Ba)&  Be );
> +
> +        Bi = ROL64((Asa^Da), 3);
> +        Bo = ROL64((Ake^De), 45);
> +        Bu = ROL64((Abi^Di), 61);
> +        Ba = ROL64((Amo^Do), 28);
> +        Be = ROL64((Agu^Du), 20);
> +        Asa =   Ba ^((~Be)&  Bi );
> +        Ake =   Be ^((~Bi)&  Bo );
> +        Abi =   Bi ^((~Bo)&  Bu );
> +        Amo =   Bo ^((~Bu)&  Ba );
> +        Agu =   Bu ^((~Ba)&  Be );
> +
> +        Bu = ROL64((Ama^Da), 18);
> +        Ba = ROL64((Age^De), 1);
> +        Be = ROL64((Asi^Di), 6);
> +        Bi = ROL64((Ako^Do), 25);
> +        Bo = ROL64((Abu^Du), 8);
> +        Ama =   Ba ^((~Be)&  Bi );
> +        Age =   Be ^((~Bi)&  Bo );
> +        Asi =   Bi ^((~Bo)&  Bu );
> +        Ako =   Bo ^((~Bu)&  Ba );
> +        Abu =   Bu ^((~Ba)&  Be );
> +
> +        Be = ROL64((Aka^Da), 36);
> +        Bi = ROL64((Abe^De), 10);
> +        Bo = ROL64((Ami^Di), 15);
> +        Bu = ROL64((Ago^Do), 56);
> +        Ba = ROL64((Asu^Du), 27);
> +        Aka =   Ba ^((~Be)&  Bi );
> +        Abe =   Be ^((~Bi)&  Bo );
> +        Ami =   Bi ^((~Bo)&  Bu );
> +        Ago =   Bo ^((~Bu)&  Ba );
> +        Asu =   Bu ^((~Ba)&  Be );
> +
> +        Bo = ROL64((Aga^Da), 41);
> +        Bu = ROL64((Ase^De), 2);
> +        Ba = ROL64((Aki^Di), 62);
> +        Be = ROL64((Abo^Do), 55);
> +        Bi = ROL64((Amu^Du), 39);
> +        Aga =   Ba ^((~Be)&  Bi );
> +        Ase =   Be ^((~Bi)&  Bo );
> +        Aki =   Bi ^((~Bo)&  Bu );
> +        Abo =   Bo ^((~Bu)&  Ba );
> +        Amu =   Bu ^((~Ba)&  Be );
> +
> +        Ca = Aba^Asa^Ama^Aka^Aga;
> +        Ce = Ame^Ake^Age^Abe^Ase;
> +        Ci = Agi^Abi^Asi^Ami^Aki;
> +        Co = Aso^Amo^Ako^Ago^Abo;
> +        Cu = Aku^Agu^Abu^Asu^Amu;
> +        Da = Cu^ROL64(Ce, 1);
> +        De = Ca^ROL64(Ci, 1);
> +        Di = Ce^ROL64(Co, 1);
> +        Do = Ci^ROL64(Cu, 1);
> +        Du = Co^ROL64(Ca, 1);
> +
> +        Ba = (Aba^Da);
> +        Be = ROL64((Ake^De), 44);
> +        Bi = ROL64((Asi^Di), 43);
> +        Bo = ROL64((Ago^Do), 21);
> +        Bu = ROL64((Amu^Du), 14);
> +        Aba =   Ba ^((~Be)&  Bi );
> +        Aba ^= KeccakRoundConstants[indexRound+2];
> +        Ake =   Be ^((~Bi)&  Bo );
> +        Asi =   Bi ^((~Bo)&  Bu );
> +        Ago =   Bo ^((~Bu)&  Ba );
> +        Amu =   Bu ^((~Ba)&  Be );
> +
> +        Bi = ROL64((Ama^Da), 3);
> +        Bo = ROL64((Abe^De), 45);
> +        Bu = ROL64((Aki^Di), 61);
> +        Ba = ROL64((Aso^Do), 28);
> +        Be = ROL64((Agu^Du), 20);
> +        Ama =   Ba ^((~Be)&  Bi );
> +        Abe =   Be ^((~Bi)&  Bo );
> +        Aki =   Bi ^((~Bo)&  Bu );
> +        Aso =   Bo ^((~Bu)&  Ba );
> +        Agu =   Bu ^((~Ba)&  Be );
> +
> +        Bu = ROL64((Aga^Da), 18);
> +        Ba = ROL64((Ame^De), 1);
> +        Be = ROL64((Abi^Di), 6);
> +        Bi = ROL64((Ako^Do), 25);
> +        Bo = ROL64((Asu^Du), 8);
> +        Aga =   Ba ^((~Be)&  Bi );
> +        Ame =   Be ^((~Bi)&  Bo );
> +        Abi =   Bi ^((~Bo)&  Bu );
> +        Ako =   Bo ^((~Bu)&  Ba );
> +        Asu =   Bu ^((~Ba)&  Be );
> +
> +        Be = ROL64((Asa^Da), 36);
> +        Bi = ROL64((Age^De), 10);
> +        Bo = ROL64((Ami^Di), 15);
> +        Bu = ROL64((Abo^Do), 56);
> +        Ba = ROL64((Aku^Du), 27);
> +        Asa =   Ba ^((~Be)&  Bi );
> +        Age =   Be ^((~Bi)&  Bo );
> +        Ami =   Bi ^((~Bo)&  Bu );
> +        Abo =   Bo ^((~Bu)&  Ba );
> +        Aku =   Bu ^((~Ba)&  Be );
> +
> +        Bo = ROL64((Aka^Da), 41);
> +        Bu = ROL64((Ase^De), 2);
> +        Ba = ROL64((Agi^Di), 62);
> +        Be = ROL64((Amo^Do), 55);
> +        Bi = ROL64((Abu^Du), 39);
> +        Aka =   Ba ^((~Be)&  Bi );
> +        Ase =   Be ^((~Bi)&  Bo );
> +        Agi =   Bi ^((~Bo)&  Bu );
> +        Amo =   Bo ^((~Bu)&  Ba );
> +        Abu =   Bu ^((~Ba)&  Be );
> +
> +        Ca = Aba^Ama^Aga^Asa^Aka;
> +        Ce = Ake^Abe^Ame^Age^Ase;
> +        Ci = Asi^Aki^Abi^Ami^Agi;
> +        Co = Ago^Aso^Ako^Abo^Amo;
> +        Cu = Amu^Agu^Asu^Aku^Abu;
> +        Da = Cu^ROL64(Ce, 1);
> +        De = Ca^ROL64(Ci, 1);
> +        Di = Ce^ROL64(Co, 1);
> +        Do = Ci^ROL64(Cu, 1);
> +        Du = Co^ROL64(Ca, 1);
> +
> +        Ba = (Aba^Da);
> +        Be = ROL64((Abe^De), 44);
> +        Bi = ROL64((Abi^Di), 43);
> +        Bo = ROL64((Abo^Do), 21);
> +        Bu = ROL64((Abu^Du), 14);
> +        Aba =   Ba ^((~Be)&  Bi );
> +        Aba ^= KeccakRoundConstants[indexRound+3];
> +        Abe =   Be ^((~Bi)&  Bo );
> +        Abi =   Bi ^((~Bo)&  Bu );
> +        Abo =   Bo ^((~Bu)&  Ba );
> +        Abu =   Bu ^((~Ba)&  Be );
> +
> +        Bi = ROL64((Aga^Da), 3);
> +        Bo = ROL64((Age^De), 45);
> +        Bu = ROL64((Agi^Di), 61);
> +        Ba = ROL64((Ago^Do), 28);
> +        Be = ROL64((Agu^Du), 20);
> +        Aga =   Ba ^((~Be)&  Bi );
> +        Age =   Be ^((~Bi)&  Bo );
> +        Agi =   Bi ^((~Bo)&  Bu );
> +        Ago =   Bo ^((~Bu)&  Ba );
> +        Agu =   Bu ^((~Ba)&  Be );
> +
> +        Bu = ROL64((Aka^Da), 18);
> +        Ba = ROL64((Ake^De), 1);
> +        Be = ROL64((Aki^Di), 6);
> +        Bi = ROL64((Ako^Do), 25);
> +        Bo = ROL64((Aku^Du), 8);
> +        Aka =   Ba ^((~Be)&  Bi );
> +        Ake =   Be ^((~Bi)&  Bo );
> +        Aki =   Bi ^((~Bo)&  Bu );
> +        Ako =   Bo ^((~Bu)&  Ba );
> +        Aku =   Bu ^((~Ba)&  Be );
> +
> +        Be = ROL64((Ama^Da), 36);
> +        Bi = ROL64((Ame^De), 10);
> +        Bo = ROL64((Ami^Di), 15);
> +        Bu = ROL64((Amo^Do), 56);
> +        Ba = ROL64((Amu^Du), 27);
> +        Ama =   Ba ^((~Be)&  Bi );
> +        Ame =   Be ^((~Bi)&  Bo );
> +        Ami =   Bi ^((~Bo)&  Bu );
> +        Amo =   Bo ^((~Bu)&  Ba );
> +        Amu =   Bu ^((~Ba)&  Be );
> +
> +        Bo = ROL64((Asa^Da), 41);
> +        Bu = ROL64((Ase^De), 2);
> +        Ba = ROL64((Asi^Di), 62);
> +        Be = ROL64((Aso^Do), 55);
> +        Bi = ROL64((Asu^Du), 39);
> +        Asa =   Ba ^((~Be)&  Bi );
> +        Ase =   Be ^((~Bi)&  Bo );
> +        Asi =   Bi ^((~Bo)&  Bu );
> +        Aso =   Bo ^((~Bu)&  Ba );
> +        Asu =   Bu ^((~Ba)&  Be );
> +
> + #undef Aba
> +        #undef Abe
> +        #undef Abi
> +        #undef Abo
> +        #undef Abu
> +        #undef Aga
> +        #undef Age
> +        #undef Agi
> +        #undef Ago
> +        #undef Agu
> +        #undef Aka
> +        #undef Ake
> +        #undef Aki
> +        #undef Ako
> +        #undef Aku
> +        #undef Ama
> +        #undef Ame
> +        #undef Ami
> +        #undef Amo
> +        #undef Amu
> +        #undef Asa
> +        #undef Ase
> +        #undef Asi
> +        #undef Aso
> +        #undef Asu

The '#' for the  #undefs should be at the start of the line.

> +}
> +
> +#else /* BYTE_ORDER != BIG_ENDIAN */
> +void
> +KeccakP1600RoundSlow(tKeccakLane *state, unsigned int indexRound)
> +{
> + theta(state);
> + rho(state);
> + pi(state);
> + chi(state);
> + iota(state, indexRound);
> +}
> +
> +#define ROL64(a, offset) ((offset != 0) ? ((((tKeccakLane)a) << offset) ^
> (((tKeccakLane)a) >> (64-offset))) : a)
> +
> +static void theta(tKeccakLane *A)
> +{
> + unsigned int x, y;
> + tKeccakLane C[5], D[5];
> +
> + for(x=0; x<5; x++) {
> + C[x] = 0;
> + for(y=0; y<5; y++)
> + C[x] ^= A[index(x, y)];
> + }
> + for(x=0; x<5; x++)
> + D[x] = ROL64(C[(x+1)%5], 1) ^ C[(x+4)%5];
> + for(x=0; x<5; x++)
> + for(y=0; y<5; y++)
> + A[index(x, y)] ^= D[x];
> +}
> +
> +static void rho(tKeccakLane *A)
> +{
> + unsigned int x, y;
> +
> + for(x=0; x<5; x++) for(y=0; y<5; y++)
> + A[index(x, y)] = ROL64(A[index(x, y)], KeccakRhoOffsets[index(x
> , y)]);
> +}
> +
> +static void pi(tKeccakLane *A)
> +{
> + unsigned int x, y;
> + tKeccakLane tempA[25];
> +
> + for(x=0; x<5; x++) for(y=0; y<5; y++)
> + tempA[index(x, y)] = A[index(x, y)];
> + for(x=0; x<5; x++) for(y=0; y<5; y++)
> + A[index(0*x+1*y, 2*x+3*y)] = tempA[index(x, y)];
> +}
> +
> +static void chi(tKeccakLane *A)
> +{
> + unsigned int x, y;
> + tKeccakLane C[5];
> +
> + for(y=0; y<5; y++) {
> + for(x=0; x<5; x++)
> + C[x] = A[index(x, y)] ^ ((~A[index(x+1, y)]) & A[index(
> x+2, y)]);
> + for(x=0; x<5; x++)
> + A[index(x, y)] = C[x];
> + }
> +}
> +
> +static void iota(tKeccakLane *A, unsigned int indexRound)
> +{
> + A[index(0, 0)] ^= KeccakRoundConstants[indexRound];
> +}
> +#endif /* BYTE_ORDER != BIG_ENDIAN */
> +
> +static void
> +KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned in
> t
> offset, unsigned int length)
> +{
> + assert(offset < 200);
> + assert(offset+length <= 200);
> + memcpy(data, (unsigned char*)state+offset, length);
> +}
> +
> Index: lib/libc/hidden/sha3.h
> ===================================================================
> RCS file: lib/libc/hidden/sha3.h
> diff -N lib/libc/hidden/sha3.h
> --- /dev/null 1 Jan 1970 00:00:00 -0000
> +++ lib/libc/hidden/sha3.h 9 Jan 2018 15:17:42 -0000
> @@ -0,0 +1,76 @@
> +#ifndef _SHA3_H
> +#define _SHA3_H
> +
> +#define SHA3_224_DIGEST_LENGTH 28
> +#define SHA3_224_DIGEST_STRING_LENGTH (SHA3_224_DIGEST_LENGTH * 2 + 1
> )
> +
> +#define SHA3_256_DIGEST_LENGTH 32
> +#define SHA3_256_DIGEST_STRING_LENGTH (SHA3_256_DIGEST_LENGTH * 2 + 1
> )
> +
> +#define SHA3_384_DIGEST_LENGTH 48
> +#define SHA3_384_DIGEST_STRING_LENGTH (SHA3_384_DIGEST_LENGTH * 2 + 1
> )
> +
> +#define SHA3_512_DIGEST_LENGTH 64
> +#define SHA3_512_DIGEST_STRING_LENGTH (SHA3_512_DIGEST_LENGTH * 2 + 1
> )
> +
> +#define SHA3_STATE_SIZE 1600 / 8
> +
> +
> +typedef struct _SHA3_CTX {
> + unsigned char state[SHA3_STATE_SIZE];
> + unsigned int rate;
> + unsigned int byteIOIndex;
> + unsigned int fixedOutputLength;
> +} SHA3_CTX;
> +
> +
> +void SHA3_224Init(SHA3_CTX *);
> +char *SHA3_224End(SHA3_CTX *, char *)
> + __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_224File(const char *, char *)
> + __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_224FileChunk(const char *, char *, off_t, off_t)
> + __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_224Data(const u_int8_t *, size_t, char *)
> + __attribute__((__bounded__(__string__,1,2)))
> + __attribute__((__bounded__(__minbytes__,3,SHA3_224_DIGEST_STRING_LENGTH
> )));
> +
> +void SHA3_256Init(SHA3_CTX *);
> +char *SHA3_256End(SHA3_CTX *, char *)
> + __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_256File(const char *, char *)
> + __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_256FileChunk(const char *, char *, off_t, off_t)
> + __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_256Data(const u_int8_t *, size_t, char *)
> + __attribute__((__bounded__(__string__,1,2)))
> + __attribute__((__bounded__(__minbytes__,3,SHA3_256_DIGEST_STRING_LENGTH
> )));
> +
> +void SHA3_384Init(SHA3_CTX *);
> +char *SHA3_384End(SHA3_CTX *, char *)
> + __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_384File(const char *, char *)
> + __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_384FileChunk(const char *, char *, off_t, off_t)
> + __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_384Data(const u_int8_t *, size_t, char *)
> + __attribute__((__bounded__(__string__,1,2)))
> + __attribute__((__bounded__(__minbytes__,3,SHA3_384_DIGEST_STRING_LENGTH
> )));
> +
> +void SHA3_512Init(SHA3_CTX *);
> +char *SHA3_512End(SHA3_CTX *, char *)
> + __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_512File(const char *, char *)
> + __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_512FileChunk(const char *, char *, off_t, off_t)
> + __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH
> )));
> +char *SHA3_512Data(const u_int8_t *, size_t, char *)
> + __attribute__((__bounded__(__string__,1,2)))
> + __attribute__((__bounded__(__minbytes__,3,SHA3_512_DIGEST_STRING_LENGTH
> )));
> +
> +void SHA3_Update(SHA3_CTX *, const u_int8_t *, size_t)
> + __attribute__((__bounded__(__string__,2,3)));
> +void SHA3_Final(u_int8_t [SHA3_224_DIGEST_LENGTH], SHA3_CTX *)
> + __attribute__((__bounded__(__minbytes__,1,SHA3_224_DIGEST_LENGTH)));
> +
> +#endif /* _SHA3_H */

The hidden version of sha3.h should include the real sha3.h and
use the PROTO_NORMAL macro for each exported function.

 - todd

Reply | Threaded
Open this post in threaded view
|

Re: Basic SHA3 support

Daniel Loebenberger
Hi Todd,

thank you for your comments!

We have included all the necessary changes in the patch attached.

Best regards,
Daniel, Stefan and Alexander

Index: bin/md5/Makefile
===================================================================
RCS file: /cvs/src/bin/md5/Makefile,v
retrieving revision 1.15
diff -u -p -u -p -r1.15 Makefile
--- bin/md5/Makefile 30 Mar 2016 06:38:40 -0000 1.15
+++ bin/md5/Makefile 10 Jan 2018 13:43:55 -0000
@@ -3,9 +3,16 @@
 PROG= md5
 SRCS= crc.c md5.c
 MAN= cksum.1 md5.1
+
 LINKS= ${BINDIR}/md5 ${BINDIR}/sha1 \
+ ${BINDIR}/md5 ${BINDIR}/sha224 \
  ${BINDIR}/md5 ${BINDIR}/sha256 \
+ ${BINDIR}/md5 ${BINDIR}/sha384 \
  ${BINDIR}/md5 ${BINDIR}/sha512 \
+ ${BINDIR}/md5 ${BINDIR}/sha3-224 \
+ ${BINDIR}/md5 ${BINDIR}/sha3-256 \
+ ${BINDIR}/md5 ${BINDIR}/sha3-384 \
+ ${BINDIR}/md5 ${BINDIR}/sha3-512 \
  ${BINDIR}/md5 ${BINDIR}/cksum
 
 CPPFLAGS+= -I${.CURDIR}
Index: bin/md5/md5.1
===================================================================
RCS file: /cvs/src/bin/md5/md5.1,v
retrieving revision 1.47
diff -u -p -u -p -r1.47 md5.1
--- bin/md5/md5.1 23 Feb 2017 20:46:08 -0000 1.47
+++ bin/md5/md5.1 10 Jan 2018 13:43:55 -0000
@@ -18,14 +18,18 @@
 .\" Agency (DARPA) and Air Force Research Laboratory, Air Force
 .\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
 .\"
-.Dd $Mdocdate: February 23 2017 $
+.Dd $Mdocdate: January 9 2018 $
 .Dt MD5 1
 .Os
 .Sh NAME
 .Nm md5 ,
 .Nm sha1 ,
 .Nm sha256 ,
-.Nm sha512
+.Nm sha512 ,
+.Nm sha3-224 ,
+.Nm sha3-256 ,
+.Nm sha3-384 ,
+.Nm sha3-512
 .Nd calculate a message digest (checksum) for a file
 .Sh SYNOPSIS
 .Nm md5
@@ -52,6 +56,30 @@
 .Op Fl h Ar hashfile
 .Op Fl s Ar string
 .Op Ar
+.Nm sha3-224
+.Op Fl bcpqrtx
+.Op Fl C Ar checklist
+.Op Fl h Ar hashfile
+.Op Fl s Ar string
+.Op Ar
+.Nm sha3-256
+.Op Fl bcpqrtx
+.Op Fl C Ar checklist
+.Op Fl h Ar hashfile
+.Op Fl s Ar string
+.Op Ar
+.Nm sha3-384
+.Op Fl bcpqrtx
+.Op Fl C Ar checklist
+.Op Fl h Ar hashfile
+.Op Fl s Ar string
+.Op Ar
+.Nm sha3-512
+.Op Fl bcpqrtx
+.Op Fl C Ar checklist
+.Op Fl h Ar hashfile
+.Op Fl s Ar string
+.Op Ar
 .Sh DESCRIPTION
 These utilities take as input a message of arbitrary length and produce
 as output a message digest (checksum) of the input.
@@ -136,7 +164,13 @@ and \*(Gt0 if an error occurs.
 .%R RFC 3174
 .%T US Secure Hash Algorithm 1 (SHA1)
 .Re
+.Pp
 .Rs
 .%T Secure Hash Standard
 .%O FIPS PUB 180-2
+.Re
+.Pp
+.Rs
+.%T SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions
+.%O FIPS PUB 202
 .Re
Index: bin/md5/md5.c
===================================================================
RCS file: /cvs/src/bin/md5/md5.c,v
retrieving revision 1.92
diff -u -p -u -p -r1.92 md5.c
--- bin/md5/md5.c 11 Sep 2017 16:35:38 -0000 1.92
+++ bin/md5/md5.c 10 Jan 2018 13:43:55 -0000
@@ -42,6 +42,7 @@
 #include <rmd160.h>
 #include <sha1.h>
 #include <sha2.h>
+#include <sha3.h>
 #include <crc.h>
 
 #define STYLE_MD5 0
@@ -61,6 +62,7 @@ union ANY_CTX {
  SHA1_CTX sha1;
 #endif /* !defined(SHA2_ONLY) */
  SHA2_CTX sha2;
+ SHA3_CTX sha3;
 };
 
 struct hash_function {
@@ -177,6 +179,50 @@ struct hash_function {
  (void (*)(void *, const unsigned char *, size_t))SHA512Update,
  (void (*)(unsigned char *, void *))SHA512Final,
  (char *(*)(void *, char *))SHA512End
+ },
+ {
+ "SHA3-224",
+ SHA3_224_DIGEST_LENGTH,
+ STYLE_MD5,
+ 0,
+ NULL,
+ (void (*)(void *))SHA3_224Init,
+ (void (*)(void *, const unsigned char *, size_t))SHA3_Update,
+ (void (*)(unsigned char *, void *))SHA3_Final,
+ (char *(*)(void *, char *))SHA3_224End
+ },
+ {
+ "SHA3-256",
+ SHA3_256_DIGEST_LENGTH,
+ STYLE_MD5,
+ 0,
+ NULL,
+ (void (*)(void *))SHA3_256Init,
+ (void (*)(void *, const unsigned char *, size_t))SHA3_Update,
+ (void (*)(unsigned char *, void *))SHA3_Final,
+ (char *(*)(void *, char *))SHA3_256End
+ },
+ {
+ "SHA3-384",
+ SHA3_384_DIGEST_LENGTH,
+ STYLE_MD5,
+ 0,
+ NULL,
+ (void (*)(void *))SHA3_384Init,
+ (void (*)(void *, const unsigned char *, size_t))SHA3_Update,
+ (void (*)(unsigned char *, void *))SHA3_Final,
+ (char *(*)(void *, char *))SHA3_384End
+ },
+ {
+ "SHA3-512",
+ SHA3_512_DIGEST_LENGTH,
+ STYLE_MD5,
+ 0,
+ NULL,
+ (void (*)(void *))SHA3_512Init,
+ (void (*)(void *, const unsigned char *, size_t))SHA3_Update,
+ (void (*)(unsigned char *, void *))SHA3_Final,
+ (char *(*)(void *, char *))SHA3_512End
  },
  {
  NULL,
Index: include/Makefile
===================================================================
RCS file: /cvs/src/include/Makefile,v
retrieving revision 1.222
diff -u -p -u -p -r1.222 Makefile
--- include/Makefile 17 Oct 2017 09:34:52 -0000 1.222
+++ include/Makefile 10 Jan 2018 13:44:01 -0000
@@ -23,7 +23,7 @@ FILES= a.out.h ar.h asr.h assert.h \
  ndbm.h netdb.h netgroup.h nlist.h nl_types.h \
  paths.h poll.h pthread.h pthread_np.h pwd.h \
  ranlib.h readpassphrase.h regex.h resolv.h rmd160.h \
- sched.h search.h setjmp.h semaphore.h sha1.h sha2.h \
+ sched.h search.h setjmp.h semaphore.h sha1.h sha2.h sha3.h \
  signal.h siphash.h sndio.h spawn.h stdbool.h stddef.h \
  stdio.h stdlib.h string.h strings.h sysexits.h \
  tar.h tgmath.h tib.h time.h ttyent.h \
Index: include/sha3.h
===================================================================
RCS file: include/sha3.h
diff -N include/sha3.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ include/sha3.h 10 Jan 2018 13:44:01 -0000
@@ -0,0 +1,78 @@
+#ifndef _SHA3_H
+#define _SHA3_H
+
+#define SHA3_224_DIGEST_LENGTH 28
+#define SHA3_224_DIGEST_STRING_LENGTH (SHA3_224_DIGEST_LENGTH * 2 + 1)
+
+#define SHA3_256_DIGEST_LENGTH 32
+#define SHA3_256_DIGEST_STRING_LENGTH (SHA3_256_DIGEST_LENGTH * 2 + 1)
+
+#define SHA3_384_DIGEST_LENGTH 48
+#define SHA3_384_DIGEST_STRING_LENGTH (SHA3_384_DIGEST_LENGTH * 2 + 1)
+
+#define SHA3_512_DIGEST_LENGTH 64
+#define SHA3_512_DIGEST_STRING_LENGTH (SHA3_512_DIGEST_LENGTH * 2 + 1)
+
+#define SHA3_STATE_SIZE (1600 / 8)
+
+
+typedef struct _SHA3_CTX {
+ unsigned char state[SHA3_STATE_SIZE];
+ unsigned int rate;
+ unsigned int byteIOIndex;
+ unsigned int fixedOutputLength;
+} SHA3_CTX;
+
+
+__BEGIN_DECLS
+void SHA3_224Init(SHA3_CTX *);
+char *SHA3_224End(SHA3_CTX *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH)));
+char *SHA3_224File(const char *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH)));
+char *SHA3_224FileChunk(const char *, char *, off_t, off_t)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH)));
+char *SHA3_224Data(const u_int8_t *, size_t, char *)
+ __attribute__((__bounded__(__string__,1,2)))
+ __attribute__((__bounded__(__minbytes__,3,SHA3_224_DIGEST_STRING_LENGTH)));
+
+void SHA3_256Init(SHA3_CTX *);
+char *SHA3_256End(SHA3_CTX *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH)));
+char *SHA3_256File(const char *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH)));
+char *SHA3_256FileChunk(const char *, char *, off_t, off_t)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH)));
+char *SHA3_256Data(const u_int8_t *, size_t, char *)
+ __attribute__((__bounded__(__string__,1,2)))
+ __attribute__((__bounded__(__minbytes__,3,SHA3_256_DIGEST_STRING_LENGTH)));
+
+void SHA3_384Init(SHA3_CTX *);
+char *SHA3_384End(SHA3_CTX *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH)));
+char *SHA3_384File(const char *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH)));
+char *SHA3_384FileChunk(const char *, char *, off_t, off_t)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH)));
+char *SHA3_384Data(const u_int8_t *, size_t, char *)
+ __attribute__((__bounded__(__string__,1,2)))
+ __attribute__((__bounded__(__minbytes__,3,SHA3_384_DIGEST_STRING_LENGTH)));
+
+void SHA3_512Init(SHA3_CTX *);
+char *SHA3_512End(SHA3_CTX *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH)));
+char *SHA3_512File(const char *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH)));
+char *SHA3_512FileChunk(const char *, char *, off_t, off_t)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH)));
+char *SHA3_512Data(const u_int8_t *, size_t, char *)
+ __attribute__((__bounded__(__string__,1,2)))
+ __attribute__((__bounded__(__minbytes__,3,SHA3_512_DIGEST_STRING_LENGTH)));
+
+void SHA3_Update(SHA3_CTX *, const u_int8_t *, size_t)
+ __attribute__((__bounded__(__string__,2,3)));
+void SHA3_Final(u_int8_t [SHA3_224_DIGEST_LENGTH], SHA3_CTX *)
+ __attribute__((__bounded__(__minbytes__,1,SHA3_224_DIGEST_LENGTH)));
+__END_DECLS
+
+#endif /* _SHA3_H */
Index: lib/libc/shlib_version
===================================================================
RCS file: /cvs/src/lib/libc/shlib_version,v
retrieving revision 1.197
diff -u -p -u -p -r1.197 shlib_version
--- lib/libc/shlib_version 26 Dec 2017 15:11:17 -0000 1.197
+++ lib/libc/shlib_version 10 Jan 2018 13:44:01 -0000
@@ -1,4 +1,4 @@
 major=92
-minor=2
+minor=3
 # note: If changes were made to include/thread_private.h or if system
 # calls were added/changed then librthread/shlib_version also be updated.
Index: lib/libc/hash/Makefile.inc
===================================================================
RCS file: /cvs/src/lib/libc/hash/Makefile.inc,v
retrieving revision 1.24
diff -u -p -u -p -r1.24 Makefile.inc
--- lib/libc/hash/Makefile.inc 3 Sep 2016 16:25:03 -0000 1.24
+++ lib/libc/hash/Makefile.inc 10 Jan 2018 13:44:01 -0000
@@ -3,9 +3,9 @@
 # hash functions
 .PATH: ${LIBCSRCDIR}/hash
 
-HELPER= md5hl.c rmd160hl.c sha1hl.c sha224hl.c sha256hl.c sha384hl.c sha512hl.c sha512_256hl.c
-SRCS+= md5.c rmd160.c sha1.c sha2.c ${HELPER} siphash.c
-MAN+= md5.3 rmd160.3 sha1.3 sha2.3 SipHash24.3
+HELPER= md5hl.c rmd160hl.c sha1hl.c sha224hl.c sha256hl.c sha384hl.c sha512hl.c sha512_256hl.c sha3-224hl.c sha3-256hl.c sha3-384hl.c sha3-512hl.c  
+SRCS+= md5.c rmd160.c sha1.c sha2.c sha3.c ${HELPER} siphash.c
+MAN+= md5.3 rmd160.3 sha1.3 sha2.3 sha3.3 SipHash24.3
 
 CLEANFILES+= ${HELPER}
 
@@ -43,4 +43,32 @@ sha512_256hl.c: helper.c
     -e 's/HASH/SHA512_256/g' \
     -e 's/SHA512_256_CTX/SHA2_CTX/g' $> > $@
 
-beforedepend: md5hl.c rmd160hl.c sha1hl.c sha256hl.c sha384hl.c sha512hl.c sha512_256hl.c
+sha3-224hl.c:   helper.c
+ sed -e 's/hashinc/sha3.h/g' \
+            -e 's/HASH/SHA3_224/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]Update/SHA3_Update/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]Final/SHA3_Final/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]_CTX/SHA3_CTX/g' $> > $@
+
+sha3-256hl.c:   helper.c
+ sed -e 's/hashinc/sha3.h/g' \
+            -e 's/HASH/SHA3_256/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]Update/SHA3_Update/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]Final/SHA3_Final/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]_CTX/SHA3_CTX/g' $> > $@
+
+sha3-384hl.c:   helper.c
+ sed -e 's/hashinc/sha3.h/g' \
+            -e 's/HASH/SHA3_384/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]Update/SHA3_Update/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]Final/SHA3_Final/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]_CTX/SHA3_CTX/g' $> > $@
+
+sha3-512hl.c:   helper.c
+ sed -e 's/hashinc/sha3.h/g' \
+            -e 's/HASH/SHA3_512/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]Update/SHA3_Update/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]Final/SHA3_Final/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]_CTX/SHA3_CTX/g' $> > $@
+
+beforedepend: md5hl.c rmd160hl.c sha1hl.c sha256hl.c sha384hl.c sha512hl.c sha512_256hl.c sha3-224hl.c sha3-256hl.c sha3-384hl.c sha3-512hl.c  
Index: lib/libc/hash/sha3.3
===================================================================
RCS file: lib/libc/hash/sha3.3
diff -N lib/libc/hash/sha3.3
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libc/hash/sha3.3 10 Jan 2018 13:44:01 -0000
@@ -0,0 +1,292 @@
+.\" $OpenBSD: sha2.3,v 1.26 2016/09/04 09:28:12 tedu Exp $
+.\"
+.\" Copyright (c) 2003, 2004 Todd C. Miller <[hidden email]>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" Sponsored in part by the Defense Advanced Research Projects
+.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
+.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
+.\"
+.\" See http://www.nist.gov/sha/ for the detailed standard
+.\"
+.Dd $Mdocdate: January 9 2018 $
+.Dt SHA3INIT 3
+.Os
+.Sh NAME
+.Nm SHA3_224Init ,
+.Nm SHA3_224Update ,
+.Nm SHA3_224Final ,
+.Nm SHA3_224End ,
+.Nm SHA3_224File ,
+.Nm SHA3_224FileChunk ,
+.Nm SHA3_224Data ,
+.Nm SHA3_256Init ,
+.Nm SHA3_256Update ,
+.Nm SHA3_256Final ,
+.Nm SHA3_256End ,
+.Nm SHA3_256File ,
+.Nm SHA3_256FileChunk ,
+.Nm SHA3_256Data ,
+.Nm SHA3_384Init ,
+.Nm SHA3_384Update ,
+.Nm SHA3_384Final ,
+.Nm SHA3_384End ,
+.Nm SHA3_384File ,
+.Nm SHA3_384FileChunk ,
+.Nm SHA3_384Data ,
+.Nm SHA3_512Init ,
+.Nm SHA3_512Update ,
+.Nm SHA3_512Final ,
+.Nm SHA3_512End ,
+.Nm SHA3_512File ,
+.Nm SHA3_512FileChunk ,
+.Nm SHA3_512Data ,
+.Nm SHA3_512_256Init ,
+.Nm SHA3_512_256Update ,
+.Nm SHA3_512_256Final ,
+.Nm SHA3_512_256End ,
+.Nm SHA3_512_256File ,
+.Nm SHA3_512_256FileChunk ,
+.Nm SHA3_512_256Data
+.Nd calculate the NIST Secure Hash Standard (version 3)
+.Sh SYNOPSIS
+.In sys/types.h
+.In sha3.h
+.Ft void
+.Fn SHA3_224Init "SHA3_CTX *context"
+.Ft void
+.Fn SHA3_224Update "SHA3_CTX *context" "const u_int8_t *data" "size_t len"
+.Ft void
+.Fn SHA3_224Final "u_int8_t digest[SHA3_224_DIGEST_LENGTH]" "SHA3_CTX *context"
+.Ft "char *"
+.Fn SHA3_224End "SHA3_CTX *context" "char *buf"
+.Ft "char *"
+.Fn SHA3_224File "const char *filename" "char *buf"
+.Ft "char *"
+.Fn SHA3_224FileChunk "const char *filename" "char *buf" "off_t offset" "off_t length"
+.Ft "char *"
+.Fn SHA3_224Data "const u_int8_t *data" "size_t len" "char *buf"
+.Ft void
+.Fn SHA3_256Init "SHA3_CTX *context"
+.Ft void
+.Fn SHA3_256Update "SHA3_CTX *context" "const u_int8_t *data" "size_t len"
+.Ft void
+.Fn SHA3_256Final "u_int8_t digest[SHA3_256_DIGEST_LENGTH]" "SHA3_CTX *context"
+.Ft "char *"
+.Fn SHA3_256End "SHA3_CTX *context" "char *buf"
+.Ft "char *"
+.Fn SHA3_256File "const char *filename" "char *buf"
+.Ft "char *"
+.Fn SHA3_256FileChunk "const char *filename" "char *buf" "off_t offset" "off_t length"
+.Ft "char *"
+.Fn SHA3_256Data "const u_int8_t *data" "size_t len" "char *buf"
+.Ft void
+.Fn SHA3_384Init "SHA3_CTX *context"
+.Ft void
+.Fn SHA3_384Update "SHA3_CTX *context" "const u_int8_t *data" "size_t len"
+.Ft void
+.Fn SHA3_384Final "u_int8_t digest[SHA3_384_DIGEST_LENGTH]" "SHA3_CTX *context"
+.Ft "char *"
+.Fn SHA3_384End "SHA3_CTX *context" "char *buf"
+.Ft "char *"
+.Fn SHA3_384File "const char *filename" "char *buf"
+.Ft "char *"
+.Fn SHA3_384FileChunk "const char *filename" "char *buf" "off_t offset" "off_t length"
+.Ft "char *"
+.Fn SHA3_384Data "const u_int8_t *data" "size_t len" "char *buf"
+.Ft void
+.Fn SHA3_512Init "SHA3_CTX *context"
+.Ft void
+.Fn SHA3_512Update "SHA3_CTX *context" "const u_int8_t *data" "size_t len"
+.Ft void
+.Fn SHA3_512Final "u_int8_t digest[SHA3_512_DIGEST_LENGTH]" "SHA3_CTX *context"
+.Ft "char *"
+.Fn SHA3_512End "SHA3_CTX *context" "char *buf"
+.Ft "char *"
+.Fn SHA3_512File "const char *filename" "char *buf"
+.Ft "char *"
+.Fn SHA3_512FileChunk "const char *filename" "char *buf" "off_t offset" "off_t length"
+.Ft "char *"
+.Fn SHA3_512Data "const u_int8_t *data" "size_t len" "char *buf"
+.Ft void
+.Fn SHA3_512_256Init "SHA3_CTX *context"
+.Ft void
+.Fn SHA3_512_256Update "SHA3_CTX *context" "const u_int8_t *data" "size_t len"
+.Ft void
+.Fn SHA3_512_256Final "u_int8_t digest[SHA3_512_256_DIGEST_LENGTH]" "SHA3_CTX *context"
+.Ft "char *"
+.Fn SHA3_512_256End "SHA3_CTX *context" "char *buf"
+.Ft "char *"
+.Fn SHA3_512_256File "const char *filename" "char *buf"
+.Ft "char *"
+.Fn SHA3_512_256FileChunk "const char *filename" "char *buf" "off_t offset" "off_t length"
+.Ft "char *"
+.Fn SHA3_512_256Data "const u_int8_t *data" "size_t len" "char *buf"
+.Sh DESCRIPTION
+The SHA-3 functions implement the NIST Secure Hash Standard,
+FIPS PUB 202.
+The SHA-3 functions are used to generate a condensed representation of a
+message called a message digest, suitable for use as a digital signature.
+There are four families of functions, with names corresponding to
+the number of bits in the resulting message digest.
+The functions can process a message of arbitrary length as input.
+.Pp
+The SHA-3 functions are considered to be more secure than the
+.Xr sha1 3
+functions with which they share a similar interface. They are an
+alternative to the
+.Xr sha2 3
+functions.
+The 224, 256, 384, and 512-bit versions of SHA-3 share the same interface.
+For brevity, only the 256-bit variants are described below.
+.Pp
+The
+.Fn SHA3_256Init
+function initializes a SHA3_CTX
+.Fa context
+for use with
+.Fn SHA3_256Update
+and
+.Fn SHA3_256Final .
+The
+.Fn SHA3_256Update
+function adds
+.Fa data
+of length
+.Fa len
+to the SHA3_CTX specified by
+.Fa context .
+.Fn SHA3_256Final
+is called when all data has been added via
+.Fn SHA3_256Update
+and stores a message digest in the
+.Fa digest
+parameter.
+.Pp
+The
+.Fn SHA3_256End
+function is a front end for
+.Fn SHA3_256Final
+which converts the digest into an
+.Tn ASCII
+representation of the digest in hexadecimal.
+.Pp
+The
+.Fn SHA3_256File
+function calculates the digest for a file and returns the result via
+.Fn SHA3_256End .
+If
+.Fn SHA3_256File
+is unable to open the file, a
+.Dv NULL
+pointer is returned.
+.Pp
+.Fn SHA3_256FileChunk
+behaves like
+.Fn SHA3_256File
+but calculates the digest only for that portion of the file starting at
+.Fa offset
+and continuing for
+.Fa length
+bytes or until end of file is reached, whichever comes first.
+A zero
+.Fa length
+can be specified to read until end of file.
+A negative
+.Fa length
+or
+.Fa offset
+will be ignored.
+.Pp
+The
+.Fn SHA3_256Data
+function
+calculates the digest of an arbitrary string and returns the result via
+.Fn SHA3_256End .
+.Pp
+For each of the
+.Fn SHA3_256End ,
+.Fn SHA3_256File ,
+.Fn SHA3_256FileChunk ,
+and
+.Fn SHA3_256Data
+functions the
+.Fa buf
+parameter should either be a string large enough to hold the resulting digest
+(e.g.\&
+.Dv SHA3_224_DIGEST_STRING_LENGTH ,
+.Dv SHA3_256_DIGEST_STRING_LENGTH ,
+.Dv SHA3_384_DIGEST_STRING_LENGTH ,
+.Dv SHA3_512_DIGEST_STRING_LENGTH ,
+or
+.Dv SHA3_512_256_DIGEST_STRING_LENGTH ,
+depending on the function being used)
+or a
+.Dv NULL
+pointer.
+In the latter case, space will be dynamically allocated via
+.Xr malloc 3
+and should be freed using
+.Xr free 3
+when it is no longer needed.
+.Sh EXAMPLES
+The following code fragment will calculate the SHA3-256 digest for the string
+.Qq abc ,
+which is
+.Dq 0x3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532 .
+.Bd -literal -offset indent
+SHA3_CTX ctx;
+u_int8_t results[SHA3_256_DIGEST_LENGTH];
+char *buf;
+int n;
+
+buf = "abc";
+n = strlen(buf);
+SHA3_256Init(&ctx);
+SHA3_256Update(&ctx, (u_int8_t *)buf, n);
+SHA3_256Final(results, &ctx);
+
+/* Print the digest as one long hex value */
+printf("0x");
+for (n = 0; n \*(Lt SHA3_256_DIGEST_LENGTH; n++)
+ printf("%02x", results[n]);
+putchar('\en');
+.Ed
+.Pp
+Alternately, the helper functions could be used in the following way:
+.Bd -literal -offset indent
+u_int8_t output[SHA3_256_DIGEST_STRING_LENGTH];
+char *buf = "abc";
+
+printf("0x%s\en", SHA3_256Data(buf, strlen(buf), output));
+.Ed
+.Sh SEE ALSO
+.Xr cksum 1 ,
+.Xr md5 3 ,
+.Xr rmd160 3 ,
+.Xr sha1 3 ,
+.Xr sha2 3
+.Rs
+.%T SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions
+.%O FIPS PUB 202
+.Re
+.Pp
+The
+.Fn SHA3_256End ,
+.Fn SHA3_256File ,
+.Fn SHA3_256FileChunk ,
+and
+.Fn SHA3_256Data
+helper functions are derived from code written by
+.An Poul-Henning Kamp .
Index: lib/libc/hash/sha3.c
===================================================================
RCS file: lib/libc/hash/sha3.c
diff -N lib/libc/hash/sha3.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libc/hash/sha3.c 10 Jan 2018 13:44:01 -0000
@@ -0,0 +1,761 @@
+/*
+ * Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni,
+ * Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby
+ * denoted as "the implementer".
+ *
+ * For more information, feedback or questions, please refer to our websites:
+ * http://keccak.noekeon.org/
+ * http://keyak.noekeon.org/
+ * http://ketje.noekeon.org/
+ *
+ * Adaptation to OpenBSD in 2017/18 by
+ * Stefan-Lukas Gazdag, Alexander von Gernler and Daniel Loebenberger
+ * https://www.genua.de/
+ * also denoted as "the implementer"
+ *
+ * To the extent possible under law, the implementer has waived all copyright
+ * and related or neighboring rights to the source code in this file.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+#include <assert.h>
+#include <sys/types.h>
+#include <string.h>
+#include <strings.h>
+#include <sha3.h>
+
+typedef unsigned long long tKeccakLane;
+
+#define SHA3_NRROUNDS 24
+#define SHA3_NRLANES 25
+#define SHA3_DELIMITER 0x06
+
+#define index(x, y) (((x)%5)+5*((y)%5))
+
+const tKeccakLane KeccakRoundConstants[SHA3_NRROUNDS] =
+{
+ 0x0000000000000001,
+ 0x0000000000008082,
+ 0x800000000000808a,
+ 0x8000000080008000,
+ 0x000000000000808b,
+ 0x0000000080000001,
+ 0x8000000080008081,
+ 0x8000000000008009,
+ 0x000000000000008a,
+ 0x0000000000000088,
+ 0x0000000080008009,
+ 0x000000008000000a,
+ 0x000000008000808b,
+ 0x800000000000008b,
+ 0x8000000000008089,
+ 0x8000000000008003,
+ 0x8000000000008002,
+ 0x8000000000000080,
+ 0x000000000000800a,
+ 0x800000008000000a,
+ 0x8000000080008081,
+ 0x8000000000008080,
+ 0x0000000080000001,
+ 0x8000000080008008,
+};
+
+const unsigned int KeccakRhoOffsets[SHA3_NRLANES] =
+{
+ 0, 1, 62, 28, 27, 36, 44, 6, 55, 20, 3, 10, 43,
+ 25, 39, 41, 45, 15, 21, 8, 18, 2, 61, 56, 14
+};
+
+/*
+ * unused, but these constance denote the one implementation out of the
+ * Keccak Code Package that was taken here
+ */
+#define KeccakP1600_implementation      "64-bit reference implementation"
+#define KeccakP1600_stateSizeInBytes    200
+#define KeccakP1600_stateAlignment      8
+
+/* prototypes for local functions */
+static void KeccakP1600_AddByte(void *state, unsigned char data,
+    unsigned int offset);
+static void KeccakP1600_AddBytes(void *state, const unsigned char *data,
+    unsigned int offset, unsigned int length);
+static void KeccakP1600_Permute_24rounds(void *state);
+static void KeccakP1600_ExtractBytes(const void *state, unsigned char *data,
+    unsigned int offset, unsigned int length);
+static void Keccak_HashInitialize(SHA3_CTX *, unsigned int, unsigned int);
+
+
+/*
+ * interface functions external use
+ * (rate + capacity) = 1600,
+ * thus the rate specifies the capacity
+ */
+void
+SHA3_224Init(SHA3_CTX *context)
+{
+ /* rate = 1152, output width 224 bit */
+ Keccak_HashInitialize(context, 1152, 224);
+}
+DEF_WEAK(SHA3_224Init);
+
+void
+SHA3_256Init(SHA3_CTX *context)
+{
+ /* rate = 1088, output width 256 bit */
+ Keccak_HashInitialize(context, 1088, 256);
+}
+DEF_WEAK(SHA3_256Init);
+
+void
+SHA3_384Init(SHA3_CTX *context)
+{
+ /* rate = 832, output width 384 bit */
+ Keccak_HashInitialize(context, 832, 384);
+}
+DEF_WEAK(SHA3_384Init);
+
+void
+SHA3_512Init(SHA3_CTX *context)
+{
+ /* rate = 576, output width 512 bit */
+ Keccak_HashInitialize(context, 576, 512);
+}
+DEF_WEAK(SHA3_512Init);
+
+
+void
+SHA3_Update(SHA3_CTX *context, const u_int8_t *data, size_t len)
+{
+ size_t i, j;
+ unsigned int partialBlock;
+ const unsigned char *curData;
+ unsigned int rateInBytes;
+ rateInBytes = context->rate/8;
+
+ i = 0;
+ curData = data;
+ while(i < len) {
+ if ((context->byteIOIndex == 0) && (len >= (i + rateInBytes))) {
+#ifdef SnP_FastLoop_Absorb
+ /* processing full blocks first */
+ if ((rateInBytes % (KeccakP1600_width/200)) == 0) {
+ /* fast lane: whole lane rate */
+ j = KeccakP1600_FastLoop_Absorb(context->state,
+    rateInBytes/(KeccakP1600_width/200), curData, len - i);
+ i += j;
+ curData += j;
+ }
+ else {
+#endif
+ for(j=len-i; j>=rateInBytes; j-=rateInBytes) {
+#ifdef KeccakReference
+ displayBytes(1, "Block to be absorbed", curData, rateInBytes);
+#endif
+ KeccakP1600_AddBytes(context->state, curData, 0, rateInBytes);
+ KeccakP1600_Permute_24rounds(context->state);
+ curData+=rateInBytes;
+ }
+ i = len - j;
+#ifdef SnP_FastLoop_Absorb
+ }
+#endif
+ }
+ else {
+ /* normal lane: using the message queue */
+ partialBlock = (unsigned int)(len - i);
+ if (partialBlock+context->byteIOIndex > rateInBytes)
+ partialBlock = rateInBytes-context->byteIOIndex;
+#ifdef KeccakReference
+ displayBytes(1, "Block to be absorbed (part)", curData, partialBlock);
+#endif
+ i += partialBlock;
+
+ KeccakP1600_AddBytes(context->state, curData, context->byteIOIndex, partialBlock);
+ curData += partialBlock;
+ context->byteIOIndex += partialBlock;
+ if (context->byteIOIndex == rateInBytes) {
+ KeccakP1600_Permute_24rounds(context->state);
+ context->byteIOIndex = 0;
+ }
+ }
+ }
+}
+DEF_WEAK(SHA3_Update);
+
+void
+SHA3_Final(u_int8_t* digest, SHA3_CTX *context)
+{
+ size_t i, j;
+ unsigned int partialBlock;
+ unsigned char *curData;
+ unsigned int rateInBytes;
+ size_t dataByteLen;
+
+ rateInBytes = context->rate/8;
+ dataByteLen = context->fixedOutputLength/8;
+
+ /* Last few bits, whose delimiter coincides with first bit of padding */
+ KeccakP1600_AddByte(context->state, SHA3_DELIMITER, context->byteIOIndex);
+
+ /*
+ * If the first bit of padding is at position rate-1, we need a whole
+ * new block for the second bit of padding
+ */
+ /* Second bit of padding */
+ KeccakP1600_AddByte(context->state, 0x80, rateInBytes-1);
+
+ KeccakP1600_Permute_24rounds(context->state);
+ context->byteIOIndex = 0;
+
+ /* SQUEEZE */
+ i = 0;
+ curData = digest;
+ while(i < dataByteLen) {
+ if ((context->byteIOIndex == rateInBytes) && (dataByteLen >= (i + rateInBytes))) {
+ for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) {
+ KeccakP1600_Permute_24rounds(context->state);
+ KeccakP1600_ExtractBytes(context->state, curData, 0, rateInBytes);
+ curData+=rateInBytes;
+ }
+ i = dataByteLen - j;
+ }
+ else {
+ /* normal lane: using the message queue */
+ if (context->byteIOIndex == rateInBytes) {
+ KeccakP1600_Permute_24rounds(context->state);
+ context->byteIOIndex = 0;
+ }
+ partialBlock = (unsigned int)(dataByteLen - i);
+ if (partialBlock+context->byteIOIndex > rateInBytes)
+ partialBlock = rateInBytes-context->byteIOIndex;
+ i += partialBlock;
+
+ KeccakP1600_ExtractBytes(context->state, curData, context->byteIOIndex, partialBlock);
+ curData += partialBlock;
+ context->byteIOIndex += partialBlock;
+ }
+ }
+}
+DEF_WEAK(SHA3_Final);
+
+/*
+ * internal functions
+ */
+static void
+Keccak_HashInitialize(SHA3_CTX *context, unsigned int rate,
+    unsigned int hashbitlen)
+{
+ bzero(context->state, SHA3_STATE_SIZE);
+ context->rate = rate;
+ context->byteIOIndex = 0;
+ context->fixedOutputLength = hashbitlen;
+}
+
+static void
+KeccakP1600_AddByte(void *state, unsigned char byte, unsigned int offset)
+{
+ assert(offset < 200);
+ ((unsigned char *)state)[offset] ^= byte;
+}
+
+static void
+KeccakP1600_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length)
+{
+ unsigned int i;
+
+ assert(offset < 200);
+ assert(offset+length <= 200);
+ for(i=0; i<length; i++)
+ ((unsigned char *)state)[offset+i] ^= data[i];
+}
+
+#if BYTE_ORDER == BIG_ENDIAN
+static void fromBytesToWords(tKeccakLane *stateAsWords, const unsigned char *state);
+static void fromWordsToBytes(unsigned char *state, const tKeccakLane *stateAsWords);
+#endif
+static void KeccakP1600OnWords(tKeccakLane *state);
+#if BYTE_ORDER == LITTLE_ENDIAN
+static void KeccakP1600QuadRound(tKeccakLane *state, unsigned int indexRound);
+#else
+static void KeccakP1600RoundSlow(tKeccakLane *state, unsigned int indexRound);
+static void theta(tKeccakLane *A);
+static void rho(tKeccakLane *A);
+static void pi(tKeccakLane *A);
+static void chi(tKeccakLane *A);
+static void iota(tKeccakLane *A, unsigned int indexRound);
+#endif
+
+static void
+KeccakP1600_Permute_24rounds(void *state)
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+ KeccakP1600OnWords((tKeccakLane*)state);
+#else
+ tKeccakLane stateAsWords[1600/64];
+
+ fromBytesToWords(stateAsWords, (const unsigned char *)state);
+ KeccakP1600OnWords(stateAsWords);
+ fromWordsToBytes((unsigned char *)state, stateAsWords);
+#endif
+}
+
+#if BYTE_ORDER == BIG_ENDIAN
+static void
+fromBytesToWords(tKeccakLane *stateAsWords, const unsigned char *state)
+{
+ unsigned int i, j;
+
+ for(i=0; i<SHA3_NRLANES; i++) {
+ stateAsWords[i] = 0;
+ for(j=0; j<(64/8); j++)
+ stateAsWords[i] |= (tKeccakLane)(state[i*(64/8)+j]) << (8*j);
+ }
+}
+
+static void
+fromWordsToBytes(unsigned char *state, const tKeccakLane *stateAsWords)
+{
+ unsigned int i, j;
+
+ for(i=0; i<SHA3_NRLANES; i++)
+ for(j=0; j<(64/8); j++)
+ state[i*(64/8)+j] = (unsigned char)((stateAsWords[i] >> (8*j)) & 0xFF);
+}
+#endif
+
+static void
+KeccakP1600OnWords(tKeccakLane *state)
+{
+ unsigned int i;
+
+
+#if BYTE_ORDER == BIG_ENDIAN
+ /*
+ * Use the unoptimized reference implementation when
+ * on big endian machines
+ */
+ for(i=0; i<SHA3_NRROUNDS; i++)
+ KeccakP1600RoundSlow(state, i);
+#else
+ /*
+ * Use the inplace version from the Keccak optimized reference
+ * code of KeccakP1600 on little endian machines
+ * Note that this routine does four rounds in one call.
+ * */
+ for(i=0; i<SHA3_NRROUNDS; i+=4)
+ KeccakP1600QuadRound(state, i);
+#endif
+}
+
+#define ROL64(a, offset) ((offset != 0) ? ((((tKeccakLane)a) << offset) ^ (((tKeccakLane)a) >> (64-offset))) : a)
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+static void
+KeccakP1600QuadRound(tKeccakLane *state, unsigned int indexRound)
+{        
+        /*
+ * Inplace implementation by Ronny Van Keer and the designers
+ * of Keccak from the optimized Keccak reference code
+ */
+
+ tKeccakLane Ba, Be, Bi, Bo, Bu;
+        tKeccakLane Ca, Ce, Ci, Co, Cu;
+        tKeccakLane Da, De, Di, Do, Du;
+
+#define Aba state[ 0]
+#define Abe state[ 1]
+#define Abi state[ 2]
+#define Abo state[ 3]
+#define Abu state[ 4]
+#define Aga state[ 5]
+#define Age state[ 6]
+#define Agi state[ 7]
+#define Ago state[ 8]
+#define Agu state[ 9]
+#define Aka state[10]
+#define Ake state[11]
+#define Aki state[12]
+#define Ako state[13]
+#define Aku state[14]
+#define Ama state[15]
+#define Ame state[16]
+#define Ami state[17]
+#define Amo state[18]
+#define Amu state[19]
+#define Asa state[20]
+#define Ase state[21]
+#define Asi state[22]
+#define Aso state[23]
+#define Asu state[24]
+
+        Ca = Aba^Aga^Aka^Ama^Asa;
+        Ce = Abe^Age^Ake^Ame^Ase;
+        Ci = Abi^Agi^Aki^Ami^Asi;
+        Co = Abo^Ago^Ako^Amo^Aso;
+        Cu = Abu^Agu^Aku^Amu^Asu;
+        Da = Cu^ROL64(Ce, 1);
+        De = Ca^ROL64(Ci, 1);
+        Di = Ce^ROL64(Co, 1);
+        Do = Ci^ROL64(Cu, 1);
+        Du = Co^ROL64(Ca, 1);
+
+        Ba = (Aba^Da);
+        Be = ROL64((Age^De), 44);
+        Bi = ROL64((Aki^Di), 43);
+        Bo = ROL64((Amo^Do), 21);
+        Bu = ROL64((Asu^Du), 14);
+        Aba =   Ba ^((~Be)&  Bi );
+        Aba ^= KeccakRoundConstants[indexRound];
+        Age =   Be ^((~Bi)&  Bo );
+        Aki =   Bi ^((~Bo)&  Bu );
+        Amo =   Bo ^((~Bu)&  Ba );
+        Asu =   Bu ^((~Ba)&  Be );
+
+        Bi = ROL64((Aka^Da), 3);
+        Bo = ROL64((Ame^De), 45);
+        Bu = ROL64((Asi^Di), 61);
+        Ba = ROL64((Abo^Do), 28);
+        Be = ROL64((Agu^Du), 20);
+        Aka =   Ba ^((~Be)&  Bi );
+        Ame =   Be ^((~Bi)&  Bo );
+        Asi =   Bi ^((~Bo)&  Bu );
+        Abo =   Bo ^((~Bu)&  Ba );
+        Agu =   Bu ^((~Ba)&  Be );
+
+        Bu = ROL64((Asa^Da), 18);
+        Ba = ROL64((Abe^De), 1);
+        Be = ROL64((Agi^Di), 6);
+        Bi = ROL64((Ako^Do), 25);
+        Bo = ROL64((Amu^Du), 8);
+        Asa =   Ba ^((~Be)&  Bi );
+        Abe =   Be ^((~Bi)&  Bo );
+        Agi =   Bi ^((~Bo)&  Bu );
+        Ako =   Bo ^((~Bu)&  Ba );
+        Amu =   Bu ^((~Ba)&  Be );
+
+        Be = ROL64((Aga^Da), 36);
+        Bi = ROL64((Ake^De), 10);
+        Bo = ROL64((Ami^Di), 15);
+        Bu = ROL64((Aso^Do), 56);
+        Ba = ROL64((Abu^Du), 27);
+        Aga =   Ba ^((~Be)&  Bi );
+        Ake =   Be ^((~Bi)&  Bo );
+        Ami =   Bi ^((~Bo)&  Bu );
+        Aso =   Bo ^((~Bu)&  Ba );
+        Abu =   Bu ^((~Ba)&  Be );
+
+        Bo = ROL64((Ama^Da), 41);
+        Bu = ROL64((Ase^De), 2);
+        Ba = ROL64((Abi^Di), 62);
+        Be = ROL64((Ago^Do), 55);
+        Bi = ROL64((Aku^Du), 39);
+        Ama =   Ba ^((~Be)&  Bi );
+        Ase =   Be ^((~Bi)&  Bo );
+        Abi =   Bi ^((~Bo)&  Bu );
+        Ago =   Bo ^((~Bu)&  Ba );
+        Aku =   Bu ^((~Ba)&  Be );
+
+        Ca = Aba^Aka^Asa^Aga^Ama;
+        Ce = Age^Ame^Abe^Ake^Ase;
+        Ci = Aki^Asi^Agi^Ami^Abi;
+        Co = Amo^Abo^Ako^Aso^Ago;
+        Cu = Asu^Agu^Amu^Abu^Aku;
+        Da = Cu^ROL64(Ce, 1);
+        De = Ca^ROL64(Ci, 1);
+        Di = Ce^ROL64(Co, 1);
+        Do = Ci^ROL64(Cu, 1);
+        Du = Co^ROL64(Ca, 1);
+
+        Ba = (Aba^Da);
+        Be = ROL64((Ame^De), 44);
+        Bi = ROL64((Agi^Di), 43);
+        Bo = ROL64((Aso^Do), 21);
+        Bu = ROL64((Aku^Du), 14);
+        Aba =   Ba ^((~Be)&  Bi );
+        Aba ^= KeccakRoundConstants[indexRound+1];
+        Ame =   Be ^((~Bi)&  Bo );
+        Agi =   Bi ^((~Bo)&  Bu );
+        Aso =   Bo ^((~Bu)&  Ba );
+        Aku =   Bu ^((~Ba)&  Be );
+
+        Bi = ROL64((Asa^Da), 3);
+        Bo = ROL64((Ake^De), 45);
+        Bu = ROL64((Abi^Di), 61);
+        Ba = ROL64((Amo^Do), 28);
+        Be = ROL64((Agu^Du), 20);
+        Asa =   Ba ^((~Be)&  Bi );
+        Ake =   Be ^((~Bi)&  Bo );
+        Abi =   Bi ^((~Bo)&  Bu );
+        Amo =   Bo ^((~Bu)&  Ba );
+        Agu =   Bu ^((~Ba)&  Be );
+
+        Bu = ROL64((Ama^Da), 18);
+        Ba = ROL64((Age^De), 1);
+        Be = ROL64((Asi^Di), 6);
+        Bi = ROL64((Ako^Do), 25);
+        Bo = ROL64((Abu^Du), 8);
+        Ama =   Ba ^((~Be)&  Bi );
+        Age =   Be ^((~Bi)&  Bo );
+        Asi =   Bi ^((~Bo)&  Bu );
+        Ako =   Bo ^((~Bu)&  Ba );
+        Abu =   Bu ^((~Ba)&  Be );
+
+        Be = ROL64((Aka^Da), 36);
+        Bi = ROL64((Abe^De), 10);
+        Bo = ROL64((Ami^Di), 15);
+        Bu = ROL64((Ago^Do), 56);
+        Ba = ROL64((Asu^Du), 27);
+        Aka =   Ba ^((~Be)&  Bi );
+        Abe =   Be ^((~Bi)&  Bo );
+        Ami =   Bi ^((~Bo)&  Bu );
+        Ago =   Bo ^((~Bu)&  Ba );
+        Asu =   Bu ^((~Ba)&  Be );
+
+        Bo = ROL64((Aga^Da), 41);
+        Bu = ROL64((Ase^De), 2);
+        Ba = ROL64((Aki^Di), 62);
+        Be = ROL64((Abo^Do), 55);
+        Bi = ROL64((Amu^Du), 39);
+        Aga =   Ba ^((~Be)&  Bi );
+        Ase =   Be ^((~Bi)&  Bo );
+        Aki =   Bi ^((~Bo)&  Bu );
+        Abo =   Bo ^((~Bu)&  Ba );
+        Amu =   Bu ^((~Ba)&  Be );
+
+        Ca = Aba^Asa^Ama^Aka^Aga;
+        Ce = Ame^Ake^Age^Abe^Ase;
+        Ci = Agi^Abi^Asi^Ami^Aki;
+        Co = Aso^Amo^Ako^Ago^Abo;
+        Cu = Aku^Agu^Abu^Asu^Amu;
+        Da = Cu^ROL64(Ce, 1);
+        De = Ca^ROL64(Ci, 1);
+        Di = Ce^ROL64(Co, 1);
+        Do = Ci^ROL64(Cu, 1);
+        Du = Co^ROL64(Ca, 1);
+
+        Ba = (Aba^Da);
+        Be = ROL64((Ake^De), 44);
+        Bi = ROL64((Asi^Di), 43);
+        Bo = ROL64((Ago^Do), 21);
+        Bu = ROL64((Amu^Du), 14);
+        Aba =   Ba ^((~Be)&  Bi );
+        Aba ^= KeccakRoundConstants[indexRound+2];
+        Ake =   Be ^((~Bi)&  Bo );
+        Asi =   Bi ^((~Bo)&  Bu );
+        Ago =   Bo ^((~Bu)&  Ba );
+        Amu =   Bu ^((~Ba)&  Be );
+
+        Bi = ROL64((Ama^Da), 3);
+        Bo = ROL64((Abe^De), 45);
+        Bu = ROL64((Aki^Di), 61);
+        Ba = ROL64((Aso^Do), 28);
+        Be = ROL64((Agu^Du), 20);
+        Ama =   Ba ^((~Be)&  Bi );
+        Abe =   Be ^((~Bi)&  Bo );
+        Aki =   Bi ^((~Bo)&  Bu );
+        Aso =   Bo ^((~Bu)&  Ba );
+        Agu =   Bu ^((~Ba)&  Be );
+
+        Bu = ROL64((Aga^Da), 18);
+        Ba = ROL64((Ame^De), 1);
+        Be = ROL64((Abi^Di), 6);
+        Bi = ROL64((Ako^Do), 25);
+        Bo = ROL64((Asu^Du), 8);
+        Aga =   Ba ^((~Be)&  Bi );
+        Ame =   Be ^((~Bi)&  Bo );
+        Abi =   Bi ^((~Bo)&  Bu );
+        Ako =   Bo ^((~Bu)&  Ba );
+        Asu =   Bu ^((~Ba)&  Be );
+
+        Be = ROL64((Asa^Da), 36);
+        Bi = ROL64((Age^De), 10);
+        Bo = ROL64((Ami^Di), 15);
+        Bu = ROL64((Abo^Do), 56);
+        Ba = ROL64((Aku^Du), 27);
+        Asa =   Ba ^((~Be)&  Bi );
+        Age =   Be ^((~Bi)&  Bo );
+        Ami =   Bi ^((~Bo)&  Bu );
+        Abo =   Bo ^((~Bu)&  Ba );
+        Aku =   Bu ^((~Ba)&  Be );
+
+        Bo = ROL64((Aka^Da), 41);
+        Bu = ROL64((Ase^De), 2);
+        Ba = ROL64((Agi^Di), 62);
+        Be = ROL64((Amo^Do), 55);
+        Bi = ROL64((Abu^Du), 39);
+        Aka =   Ba ^((~Be)&  Bi );
+        Ase =   Be ^((~Bi)&  Bo );
+        Agi =   Bi ^((~Bo)&  Bu );
+        Amo =   Bo ^((~Bu)&  Ba );
+        Abu =   Bu ^((~Ba)&  Be );
+
+        Ca = Aba^Ama^Aga^Asa^Aka;
+        Ce = Ake^Abe^Ame^Age^Ase;
+        Ci = Asi^Aki^Abi^Ami^Agi;
+        Co = Ago^Aso^Ako^Abo^Amo;
+        Cu = Amu^Agu^Asu^Aku^Abu;
+        Da = Cu^ROL64(Ce, 1);
+        De = Ca^ROL64(Ci, 1);
+        Di = Ce^ROL64(Co, 1);
+        Do = Ci^ROL64(Cu, 1);
+        Du = Co^ROL64(Ca, 1);
+
+        Ba = (Aba^Da);
+        Be = ROL64((Abe^De), 44);
+        Bi = ROL64((Abi^Di), 43);
+        Bo = ROL64((Abo^Do), 21);
+        Bu = ROL64((Abu^Du), 14);
+        Aba =   Ba ^((~Be)&  Bi );
+        Aba ^= KeccakRoundConstants[indexRound+3];
+        Abe =   Be ^((~Bi)&  Bo );
+        Abi =   Bi ^((~Bo)&  Bu );
+        Abo =   Bo ^((~Bu)&  Ba );
+        Abu =   Bu ^((~Ba)&  Be );
+
+        Bi = ROL64((Aga^Da), 3);
+        Bo = ROL64((Age^De), 45);
+        Bu = ROL64((Agi^Di), 61);
+        Ba = ROL64((Ago^Do), 28);
+        Be = ROL64((Agu^Du), 20);
+        Aga =   Ba ^((~Be)&  Bi );
+        Age =   Be ^((~Bi)&  Bo );
+        Agi =   Bi ^((~Bo)&  Bu );
+        Ago =   Bo ^((~Bu)&  Ba );
+        Agu =   Bu ^((~Ba)&  Be );
+
+        Bu = ROL64((Aka^Da), 18);
+        Ba = ROL64((Ake^De), 1);
+        Be = ROL64((Aki^Di), 6);
+        Bi = ROL64((Ako^Do), 25);
+        Bo = ROL64((Aku^Du), 8);
+        Aka =   Ba ^((~Be)&  Bi );
+        Ake =   Be ^((~Bi)&  Bo );
+        Aki =   Bi ^((~Bo)&  Bu );
+        Ako =   Bo ^((~Bu)&  Ba );
+        Aku =   Bu ^((~Ba)&  Be );
+
+        Be = ROL64((Ama^Da), 36);
+        Bi = ROL64((Ame^De), 10);
+        Bo = ROL64((Ami^Di), 15);
+        Bu = ROL64((Amo^Do), 56);
+        Ba = ROL64((Amu^Du), 27);
+        Ama =   Ba ^((~Be)&  Bi );
+        Ame =   Be ^((~Bi)&  Bo );
+        Ami =   Bi ^((~Bo)&  Bu );
+        Amo =   Bo ^((~Bu)&  Ba );
+        Amu =   Bu ^((~Ba)&  Be );
+
+        Bo = ROL64((Asa^Da), 41);
+        Bu = ROL64((Ase^De), 2);
+        Ba = ROL64((Asi^Di), 62);
+        Be = ROL64((Aso^Do), 55);
+        Bi = ROL64((Asu^Du), 39);
+        Asa =   Ba ^((~Be)&  Bi );
+        Ase =   Be ^((~Bi)&  Bo );
+        Asi =   Bi ^((~Bo)&  Bu );
+        Aso =   Bo ^((~Bu)&  Ba );
+        Asu =   Bu ^((~Ba)&  Be );
+
+#undef Aba
+#undef Abe
+#undef Abi
+#undef Abo
+#undef Abu
+#undef Aga
+#undef Age
+#undef Agi
+#undef Ago
+#undef Agu
+#undef Aka
+#undef Ake
+#undef Aki
+#undef Ako
+#undef Aku
+#undef Ama
+#undef Ame
+#undef Ami
+#undef Amo
+#undef Amu
+#undef Asa
+#undef Ase
+#undef Asi
+#undef Aso
+#undef Asu
+}
+
+#else /* BYTE_ORDER != BIG_ENDIAN */
+void
+KeccakP1600RoundSlow(tKeccakLane *state, unsigned int indexRound)
+{        
+ theta(state);
+ rho(state);
+ pi(state);
+ chi(state);
+ iota(state, indexRound);
+}
+
+#define ROL64(a, offset) ((offset != 0) ? ((((tKeccakLane)a) << offset) ^ (((tKeccakLane)a) >> (64-offset))) : a)
+
+static void theta(tKeccakLane *A)
+{
+ unsigned int x, y;
+ tKeccakLane C[5], D[5];
+
+ for(x=0; x<5; x++) {
+ C[x] = 0;
+ for(y=0; y<5; y++)
+ C[x] ^= A[index(x, y)];
+ }
+ for(x=0; x<5; x++)
+ D[x] = ROL64(C[(x+1)%5], 1) ^ C[(x+4)%5];
+ for(x=0; x<5; x++)
+ for(y=0; y<5; y++)
+ A[index(x, y)] ^= D[x];
+}
+
+static void rho(tKeccakLane *A)
+{
+ unsigned int x, y;
+
+ for(x=0; x<5; x++) for(y=0; y<5; y++)
+ A[index(x, y)] = ROL64(A[index(x, y)], KeccakRhoOffsets[index(x, y)]);
+}
+
+static void pi(tKeccakLane *A)
+{
+ unsigned int x, y;
+ tKeccakLane tempA[25];
+
+ for(x=0; x<5; x++) for(y=0; y<5; y++)
+ tempA[index(x, y)] = A[index(x, y)];
+ for(x=0; x<5; x++) for(y=0; y<5; y++)
+ A[index(0*x+1*y, 2*x+3*y)] = tempA[index(x, y)];
+}
+
+static void chi(tKeccakLane *A)
+{
+ unsigned int x, y;
+ tKeccakLane C[5];
+
+ for(y=0; y<5; y++) {
+ for(x=0; x<5; x++)
+ C[x] = A[index(x, y)] ^ ((~A[index(x+1, y)]) & A[index(x+2, y)]);
+ for(x=0; x<5; x++)
+ A[index(x, y)] = C[x];
+ }
+}
+
+static void iota(tKeccakLane *A, unsigned int indexRound)
+{
+ A[index(0, 0)] ^= KeccakRoundConstants[indexRound];
+}
+#endif /* BYTE_ORDER != BIG_ENDIAN */
+
+static void
+KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length)
+{
+ assert(offset < 200);
+ assert(offset+length <= 200);
+ memcpy(data, (unsigned char*)state+offset, length);
+}
+
Index: lib/libc/hidden/sha3.h
===================================================================
RCS file: lib/libc/hidden/sha3.h
diff -N lib/libc/hidden/sha3.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libc/hidden/sha3.h 10 Jan 2018 13:44:01 -0000
@@ -0,0 +1,29 @@
+#ifndef _LIBC_SHA3_H
+#define _LIBC_SHA3_H
+
+#include_next <sha3.h>
+
+PROTO_NORMAL(SHA3_Update);
+PROTO_NORMAL(SHA3_Final);
+PROTO_NORMAL(SHA3_224Data);
+PROTO_NORMAL(SHA3_224End);
+PROTO_NORMAL(SHA3_224File);
+PROTO_NORMAL(SHA3_224FileChunk);
+PROTO_NORMAL(SHA3_224Init);
+PROTO_NORMAL(SHA3_256Data);
+PROTO_NORMAL(SHA3_256End);
+PROTO_NORMAL(SHA3_256File);
+PROTO_NORMAL(SHA3_256FileChunk);
+PROTO_NORMAL(SHA3_256Init);
+PROTO_NORMAL(SHA3_384Data);
+PROTO_NORMAL(SHA3_384End);
+PROTO_NORMAL(SHA3_384File);
+PROTO_NORMAL(SHA3_384FileChunk);
+PROTO_NORMAL(SHA3_384Init);
+PROTO_NORMAL(SHA3_512Data);
+PROTO_NORMAL(SHA3_512End);
+PROTO_NORMAL(SHA3_512File);
+PROTO_NORMAL(SHA3_512FileChunk);
+PROTO_NORMAL(SHA3_512Init);
+
+#endif /* _LIBC_SHA3_H */

Reply | Threaded
Open this post in threaded view
|

Re: Basic SHA3 support

Theo de Raadt-2
I don't think you compiled a ramdisk.

The ramdisk users distrib/special/md5 to build a binary with
fewer included components, otherwise it won't fit on the media.

At least this isn't right:

 #endif /* !defined(SHA2_ONLY) */
        SHA2_CTX sha2;
+       SHA3_CTX sha3;

You can inspect the Makefile there and make the SHA2_ONLY #ifdefs
work right.

Reply | Threaded
Open this post in threaded view
|

Re: Basic SHA3 support

Jeremie Courreges-Anglas-2
In reply to this post by Daniel Loebenberger

Hi,

On Wed, Jan 10 2018, Daniel Loebenberger <[hidden email]> wrote:
> Hi Todd,
>
> thank you for your comments!
>
> We have included all the necessary changes in the patch attached.

One thing caught my eye:

> Best regards,
> Daniel, Stefan and Alexander
>
> Index: bin/md5/Makefile
> ===================================================================
> RCS file: /cvs/src/bin/md5/Makefile,v
> retrieving revision 1.15
> diff -u -p -u -p -r1.15 Makefile
> --- bin/md5/Makefile 30 Mar 2016 06:38:40 -0000 1.15
> +++ bin/md5/Makefile 10 Jan 2018 13:43:55 -0000
> @@ -3,9 +3,16 @@
>  PROG= md5
>  SRCS= crc.c md5.c
>  MAN= cksum.1 md5.1
> +
>  LINKS= ${BINDIR}/md5 ${BINDIR}/sha1 \
> + ${BINDIR}/md5 ${BINDIR}/sha224 \
>   ${BINDIR}/md5 ${BINDIR}/sha256 \
> + ${BINDIR}/md5 ${BINDIR}/sha384 \

Do we really want these?  For SHA-2, sha256 and sha512 are enough IMHO.

>   ${BINDIR}/md5 ${BINDIR}/sha512 \
> + ${BINDIR}/md5 ${BINDIR}/sha3-224 \
> + ${BINDIR}/md5 ${BINDIR}/sha3-256 \
> + ${BINDIR}/md5 ${BINDIR}/sha3-384 \
> + ${BINDIR}/md5 ${BINDIR}/sha3-512 \

Same question but for the SHA-3 version.

[...]

--
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Reply | Threaded
Open this post in threaded view
|

Re: Basic SHA3 support

Theo de Raadt-2
> >  LINKS= ${BINDIR}/md5 ${BINDIR}/sha1 \
> > + ${BINDIR}/md5 ${BINDIR}/sha224 \
> >   ${BINDIR}/md5 ${BINDIR}/sha256 \
> > + ${BINDIR}/md5 ${BINDIR}/sha384 \
>
> Do we really want these?  For SHA-2, sha256 and sha512 are enough IMHO.
>
> >   ${BINDIR}/md5 ${BINDIR}/sha512 \
> > + ${BINDIR}/md5 ${BINDIR}/sha3-224 \
> > + ${BINDIR}/md5 ${BINDIR}/sha3-256 \
> > + ${BINDIR}/md5 ${BINDIR}/sha3-384 \
> > + ${BINDIR}/md5 ${BINDIR}/sha3-512 \
>
> Same question but for the SHA-3 version.

I think this is also a waste of time.

Look, it is the /bin directory.  Look at what is in it now.

Adding 6 commands?  How many people will use them?  shells and
other things cache the existance of these things.

Reply | Threaded
Open this post in threaded view
|

Re: Basic SHA3 support

Todd C. Miller-2
In reply to this post by Jeremie Courreges-Anglas-2
On Wed, 10 Jan 2018 15:59:30 +0100, Jeremie Courreges-Anglas wrote:

> Do we really want these?  For SHA-2, sha256 and sha512 are enough IMHO.

Does anyone actually use the sha512 command?  I'd be fine with
retiring the sha512 link and adding a sha3-256 one.

 - todd

Reply | Threaded
Open this post in threaded view
|

Re: Basic SHA3 support

Tom Cosgrove-2
>>> "Todd C. Miller" 10-Jan-18 16:28 >>>
>
> On Wed, 10 Jan 2018 15:59:30 +0100, Jeremie Courreges-Anglas wrote:
>
> > Do we really want these?  For SHA-2, sha256 and sha512 are enough IMHO.
>
> Does anyone actually use the sha512 command?  I'd be fine with
> retiring the sha512 link and adding a sha3-256 one.
>
>  - todd

I'd like to keep the sha512 link - I do use it.

Tom

Reply | Threaded
Open this post in threaded view
|

Re: Basic SHA3 support

Christian Weisgerber
In reply to this post by Daniel Loebenberger
On 2018-01-09, Daniel Loebenberger <[hidden email]> wrote:

> enclosed you find a patch to add basic SHA3-/Keccak support to OpenBSD.

What do you want to use it for?

I've had something like this on my to-do list for some time and
eventually dropped it because I couldn't think of a compelling use
case.

"Maybe Skip SHA-3"
https://www.imperialviolet.org/2017/05/31/skipsha3.html

Another question raised by a SHA-3 import is whether this should
also be added to LibreSSL and if we want to continue with having
duplicate implementations of hash algorithms in libc and libcrypto.

--
Christian "naddy" Weisgerber                          [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Basic SHA3 support

bytevolcano
In reply to this post by Tom Cosgrove-2
I also use the sha512 command on a regular basis, and notice a
performance improvement (compared to sha256) with amd64 systems.

On Wed, 10 Jan 2018 17:10:40 +0000 (GMT)
Tom Cosgrove <[hidden email]> wrote:

> >>> "Todd C. Miller" 10-Jan-18 16:28 >>>  
> >
> > On Wed, 10 Jan 2018 15:59:30 +0100, Jeremie Courreges-Anglas wrote:
> >  
> > > Do we really want these?  For SHA-2, sha256 and sha512 are enough IMHO.  
> >
> > Does anyone actually use the sha512 command?  I'd be fine with
> > retiring the sha512 link and adding a sha3-256 one.
> >
> >  - todd  
>
> I'd like to keep the sha512 link - I do use it.
>
> Tom
>

Reply | Threaded
Open this post in threaded view
|

Re: Basic SHA3 support

Theo de Raadt-2
> I also use the sha512 command on a regular basis, and notice a
> performance improvement (compared to sha256) with amd64 systems.

But is /bin the place to put a performance improving command?

No.  That isn't the place for putting strange performance commands.
It is a place for putting *interoperating* commands.

I don't think Todd's original question was answered, except along
the lines of "i love features".

Reply | Threaded
Open this post in threaded view
|

Re: Basic SHA3 support

Theo de Raadt-2
In reply to this post by Christian Weisgerber
> Another question raised by a SHA-3 import is whether this should
> also be added to LibreSSL and if we want to continue with having
> duplicate implementations of hash algorithms in libc and libcrypto.

very good question.

Who *crucially* needs this

OpenBSD is intended to be a small operating system.  I don't want
to compile SHA3 stuff every single build unless there is a substantial
and growing userbase for it

Is that the case, or is this fad of the month?

Reply | Threaded
Open this post in threaded view
|

Re: Basic SHA3 support

lists-2
Wed, 10 Jan 2018 20:34:44 -0700 "Theo de Raadt" <[hidden email]>

> > Another question raised by a SHA-3 import is whether this should
> > also be added to LibreSSL and if we want to continue with having
> > duplicate implementations of hash algorithms in libc and libcrypto.  
>
> very good question.
>
> Who *crucially* needs this
>
> OpenBSD is intended to be a small operating system.  I don't want
> to compile SHA3 stuff every single build unless there is a substantial
> and growing userbase for it
>
> Is that the case, or is this fad of the month?
>

Hi tech@,

I won't cry if this became a port instead of importing 'it' in base:

NIST https://en.wikipedia.org/wiki/The_Mist_(film)
MIST https://en.wikipedia.org/wiki/SHA-3#Capacity_change_controversy

I won't have a use for it even in that case, given the above detail.

Kind regards,
Anton Lazarov

Reply | Threaded
Open this post in threaded view
|

Re: Basic SHA3 support

Todd C. Miller-2
In reply to this post by Christian Weisgerber
On Wed, 10 Jan 2018 22:06:37 +0000, Christian Weisgerber wrote:

> I've had something like this on my to-do list for some time and
> eventually dropped it because I couldn't think of a compelling use
> case.
>
> "Maybe Skip SHA-3"
> https://www.imperialviolet.org/2017/05/31/skipsha3.html

That makes a pretty convincing case for *not* inluding sha-3.

I think at this point there needs to be a compelling argument to
include it in libc.  As you say, it is not even present in LibreSSL,
though OpenSSL did eventually add it.

 - todd

Reply | Threaded
Open this post in threaded view
|

Re: Basic SHA3 support

Daniel Loebenberger
In reply to this post by Theo de Raadt-2
Hi,

we thank you for all your comments!

The following contains our answers specific to your technical remarks
on the patch itself. Another email on the cryptographic discussion
will follow.

1.) We agree that six new commands are not a good idea. The minimal
variant would be to include sha3-256. If there is a sha512 command, one
could think of adding -- for the sake of consistency -- sha3-512 as
well.

2.) The issue with the SHA2_ONLY macro is fixed now, we also
crosschecked that in distrib/special/md5 no additional code is included
by our patch.

3.) Concerning the question on whether one should also include the
implementation in LibreSSL, we did not think of such an application in
the first place (and also think that we cannot answer it competently).
This is also the reason for the wording "basic" in our submission.

Attached you find the updated patch.

Best regards,
Daniel, Stefan and Alexander

Index: bin/md5/Makefile
===================================================================
RCS file: /cvs/src/bin/md5/Makefile,v
retrieving revision 1.15
diff -u -p -u -p -r1.15 Makefile
--- bin/md5/Makefile 30 Mar 2016 06:38:40 -0000 1.15
+++ bin/md5/Makefile 11 Jan 2018 09:04:04 -0000
@@ -6,6 +6,8 @@ MAN= cksum.1 md5.1
 LINKS= ${BINDIR}/md5 ${BINDIR}/sha1 \
  ${BINDIR}/md5 ${BINDIR}/sha256 \
  ${BINDIR}/md5 ${BINDIR}/sha512 \
+ ${BINDIR}/md5 ${BINDIR}/sha3-256 \
+ ${BINDIR}/md5 ${BINDIR}/sha3-512 \
  ${BINDIR}/md5 ${BINDIR}/cksum
 
 CPPFLAGS+= -I${.CURDIR}
Index: bin/md5/md5.1
===================================================================
RCS file: /cvs/src/bin/md5/md5.1,v
retrieving revision 1.47
diff -u -p -u -p -r1.47 md5.1
--- bin/md5/md5.1 23 Feb 2017 20:46:08 -0000 1.47
+++ bin/md5/md5.1 11 Jan 2018 09:04:04 -0000
@@ -18,14 +18,18 @@
 .\" Agency (DARPA) and Air Force Research Laboratory, Air Force
 .\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
 .\"
-.Dd $Mdocdate: February 23 2017 $
+.Dd $Mdocdate: January 9 2018 $
 .Dt MD5 1
 .Os
 .Sh NAME
 .Nm md5 ,
 .Nm sha1 ,
 .Nm sha256 ,
-.Nm sha512
+.Nm sha512 ,
+.Nm sha3-224 ,
+.Nm sha3-256 ,
+.Nm sha3-384 ,
+.Nm sha3-512
 .Nd calculate a message digest (checksum) for a file
 .Sh SYNOPSIS
 .Nm md5
@@ -52,6 +56,30 @@
 .Op Fl h Ar hashfile
 .Op Fl s Ar string
 .Op Ar
+.Nm sha3-224
+.Op Fl bcpqrtx
+.Op Fl C Ar checklist
+.Op Fl h Ar hashfile
+.Op Fl s Ar string
+.Op Ar
+.Nm sha3-256
+.Op Fl bcpqrtx
+.Op Fl C Ar checklist
+.Op Fl h Ar hashfile
+.Op Fl s Ar string
+.Op Ar
+.Nm sha3-384
+.Op Fl bcpqrtx
+.Op Fl C Ar checklist
+.Op Fl h Ar hashfile
+.Op Fl s Ar string
+.Op Ar
+.Nm sha3-512
+.Op Fl bcpqrtx
+.Op Fl C Ar checklist
+.Op Fl h Ar hashfile
+.Op Fl s Ar string
+.Op Ar
 .Sh DESCRIPTION
 These utilities take as input a message of arbitrary length and produce
 as output a message digest (checksum) of the input.
@@ -136,7 +164,13 @@ and \*(Gt0 if an error occurs.
 .%R RFC 3174
 .%T US Secure Hash Algorithm 1 (SHA1)
 .Re
+.Pp
 .Rs
 .%T Secure Hash Standard
 .%O FIPS PUB 180-2
+.Re
+.Pp
+.Rs
+.%T SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions
+.%O FIPS PUB 202
 .Re
Index: bin/md5/md5.c
===================================================================
RCS file: /cvs/src/bin/md5/md5.c,v
retrieving revision 1.92
diff -u -p -u -p -r1.92 md5.c
--- bin/md5/md5.c 11 Sep 2017 16:35:38 -0000 1.92
+++ bin/md5/md5.c 11 Jan 2018 09:04:04 -0000
@@ -42,6 +42,7 @@
 #include <rmd160.h>
 #include <sha1.h>
 #include <sha2.h>
+#include <sha3.h>
 #include <crc.h>
 
 #define STYLE_MD5 0
@@ -59,6 +60,7 @@ union ANY_CTX {
  MD5_CTX md5;
  RMD160_CTX rmd160;
  SHA1_CTX sha1;
+ SHA3_CTX sha3;
 #endif /* !defined(SHA2_ONLY) */
  SHA2_CTX sha2;
 };
@@ -178,6 +180,52 @@ struct hash_function {
  (void (*)(unsigned char *, void *))SHA512Final,
  (char *(*)(void *, char *))SHA512End
  },
+#if !defined(SHA2_ONLY)
+ {
+ "SHA3-224",
+ SHA3_224_DIGEST_LENGTH,
+ STYLE_MD5,
+ 0,
+ NULL,
+ (void (*)(void *))SHA3_224Init,
+ (void (*)(void *, const unsigned char *, size_t))SHA3_Update,
+ (void (*)(unsigned char *, void *))SHA3_Final,
+ (char *(*)(void *, char *))SHA3_224End
+ },
+ {
+ "SHA3-256",
+ SHA3_256_DIGEST_LENGTH,
+ STYLE_MD5,
+ 0,
+ NULL,
+ (void (*)(void *))SHA3_256Init,
+ (void (*)(void *, const unsigned char *, size_t))SHA3_Update,
+ (void (*)(unsigned char *, void *))SHA3_Final,
+ (char *(*)(void *, char *))SHA3_256End
+ },
+ {
+ "SHA3-384",
+ SHA3_384_DIGEST_LENGTH,
+ STYLE_MD5,
+ 0,
+ NULL,
+ (void (*)(void *))SHA3_384Init,
+ (void (*)(void *, const unsigned char *, size_t))SHA3_Update,
+ (void (*)(unsigned char *, void *))SHA3_Final,
+ (char *(*)(void *, char *))SHA3_384End
+ },
+ {
+ "SHA3-512",
+ SHA3_512_DIGEST_LENGTH,
+ STYLE_MD5,
+ 0,
+ NULL,
+ (void (*)(void *))SHA3_512Init,
+ (void (*)(void *, const unsigned char *, size_t))SHA3_Update,
+ (void (*)(unsigned char *, void *))SHA3_Final,
+ (char *(*)(void *, char *))SHA3_512End
+ },
+#endif /* !defined(SHA2_ONLY) */
  {
  NULL,
  }
Index: include/Makefile
===================================================================
RCS file: /cvs/src/include/Makefile,v
retrieving revision 1.222
diff -u -p -u -p -r1.222 Makefile
--- include/Makefile 17 Oct 2017 09:34:52 -0000 1.222
+++ include/Makefile 11 Jan 2018 09:04:18 -0000
@@ -23,7 +23,7 @@ FILES= a.out.h ar.h asr.h assert.h \
  ndbm.h netdb.h netgroup.h nlist.h nl_types.h \
  paths.h poll.h pthread.h pthread_np.h pwd.h \
  ranlib.h readpassphrase.h regex.h resolv.h rmd160.h \
- sched.h search.h setjmp.h semaphore.h sha1.h sha2.h \
+ sched.h search.h setjmp.h semaphore.h sha1.h sha2.h sha3.h \
  signal.h siphash.h sndio.h spawn.h stdbool.h stddef.h \
  stdio.h stdlib.h string.h strings.h sysexits.h \
  tar.h tgmath.h tib.h time.h ttyent.h \
Index: include/sha3.h
===================================================================
RCS file: include/sha3.h
diff -N include/sha3.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ include/sha3.h 11 Jan 2018 09:04:18 -0000
@@ -0,0 +1,78 @@
+#ifndef _SHA3_H
+#define _SHA3_H
+
+#define SHA3_224_DIGEST_LENGTH 28
+#define SHA3_224_DIGEST_STRING_LENGTH (SHA3_224_DIGEST_LENGTH * 2 + 1)
+
+#define SHA3_256_DIGEST_LENGTH 32
+#define SHA3_256_DIGEST_STRING_LENGTH (SHA3_256_DIGEST_LENGTH * 2 + 1)
+
+#define SHA3_384_DIGEST_LENGTH 48
+#define SHA3_384_DIGEST_STRING_LENGTH (SHA3_384_DIGEST_LENGTH * 2 + 1)
+
+#define SHA3_512_DIGEST_LENGTH 64
+#define SHA3_512_DIGEST_STRING_LENGTH (SHA3_512_DIGEST_LENGTH * 2 + 1)
+
+#define SHA3_STATE_SIZE (1600 / 8)
+
+
+typedef struct _SHA3_CTX {
+ unsigned char state[SHA3_STATE_SIZE];
+ unsigned int rate;
+ unsigned int byteIOIndex;
+ unsigned int fixedOutputLength;
+} SHA3_CTX;
+
+
+__BEGIN_DECLS
+void SHA3_224Init(SHA3_CTX *);
+char *SHA3_224End(SHA3_CTX *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH)));
+char *SHA3_224File(const char *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH)));
+char *SHA3_224FileChunk(const char *, char *, off_t, off_t)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_224_DIGEST_STRING_LENGTH)));
+char *SHA3_224Data(const u_int8_t *, size_t, char *)
+ __attribute__((__bounded__(__string__,1,2)))
+ __attribute__((__bounded__(__minbytes__,3,SHA3_224_DIGEST_STRING_LENGTH)));
+
+void SHA3_256Init(SHA3_CTX *);
+char *SHA3_256End(SHA3_CTX *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH)));
+char *SHA3_256File(const char *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH)));
+char *SHA3_256FileChunk(const char *, char *, off_t, off_t)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_256_DIGEST_STRING_LENGTH)));
+char *SHA3_256Data(const u_int8_t *, size_t, char *)
+ __attribute__((__bounded__(__string__,1,2)))
+ __attribute__((__bounded__(__minbytes__,3,SHA3_256_DIGEST_STRING_LENGTH)));
+
+void SHA3_384Init(SHA3_CTX *);
+char *SHA3_384End(SHA3_CTX *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH)));
+char *SHA3_384File(const char *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH)));
+char *SHA3_384FileChunk(const char *, char *, off_t, off_t)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_384_DIGEST_STRING_LENGTH)));
+char *SHA3_384Data(const u_int8_t *, size_t, char *)
+ __attribute__((__bounded__(__string__,1,2)))
+ __attribute__((__bounded__(__minbytes__,3,SHA3_384_DIGEST_STRING_LENGTH)));
+
+void SHA3_512Init(SHA3_CTX *);
+char *SHA3_512End(SHA3_CTX *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH)));
+char *SHA3_512File(const char *, char *)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH)));
+char *SHA3_512FileChunk(const char *, char *, off_t, off_t)
+ __attribute__((__bounded__(__minbytes__,2,SHA3_512_DIGEST_STRING_LENGTH)));
+char *SHA3_512Data(const u_int8_t *, size_t, char *)
+ __attribute__((__bounded__(__string__,1,2)))
+ __attribute__((__bounded__(__minbytes__,3,SHA3_512_DIGEST_STRING_LENGTH)));
+
+void SHA3_Update(SHA3_CTX *, const u_int8_t *, size_t)
+ __attribute__((__bounded__(__string__,2,3)));
+void SHA3_Final(u_int8_t [SHA3_224_DIGEST_LENGTH], SHA3_CTX *)
+ __attribute__((__bounded__(__minbytes__,1,SHA3_224_DIGEST_LENGTH)));
+__END_DECLS
+
+#endif /* _SHA3_H */
Index: lib/libc/shlib_version
===================================================================
RCS file: /cvs/src/lib/libc/shlib_version,v
retrieving revision 1.197
diff -u -p -u -p -r1.197 shlib_version
--- lib/libc/shlib_version 26 Dec 2017 15:11:17 -0000 1.197
+++ lib/libc/shlib_version 11 Jan 2018 09:04:18 -0000
@@ -1,4 +1,4 @@
 major=92
-minor=2
+minor=3
 # note: If changes were made to include/thread_private.h or if system
 # calls were added/changed then librthread/shlib_version also be updated.
Index: lib/libc/hash/Makefile.inc
===================================================================
RCS file: /cvs/src/lib/libc/hash/Makefile.inc,v
retrieving revision 1.24
diff -u -p -u -p -r1.24 Makefile.inc
--- lib/libc/hash/Makefile.inc 3 Sep 2016 16:25:03 -0000 1.24
+++ lib/libc/hash/Makefile.inc 11 Jan 2018 09:04:18 -0000
@@ -3,9 +3,9 @@
 # hash functions
 .PATH: ${LIBCSRCDIR}/hash
 
-HELPER= md5hl.c rmd160hl.c sha1hl.c sha224hl.c sha256hl.c sha384hl.c sha512hl.c sha512_256hl.c
-SRCS+= md5.c rmd160.c sha1.c sha2.c ${HELPER} siphash.c
-MAN+= md5.3 rmd160.3 sha1.3 sha2.3 SipHash24.3
+HELPER= md5hl.c rmd160hl.c sha1hl.c sha224hl.c sha256hl.c sha384hl.c sha512hl.c sha512_256hl.c sha3-224hl.c sha3-256hl.c sha3-384hl.c sha3-512hl.c  
+SRCS+= md5.c rmd160.c sha1.c sha2.c sha3.c ${HELPER} siphash.c
+MAN+= md5.3 rmd160.3 sha1.3 sha2.3 sha3.3 SipHash24.3
 
 CLEANFILES+= ${HELPER}
 
@@ -43,4 +43,32 @@ sha512_256hl.c: helper.c
     -e 's/HASH/SHA512_256/g' \
     -e 's/SHA512_256_CTX/SHA2_CTX/g' $> > $@
 
-beforedepend: md5hl.c rmd160hl.c sha1hl.c sha256hl.c sha384hl.c sha512hl.c sha512_256hl.c
+sha3-224hl.c:   helper.c
+ sed -e 's/hashinc/sha3.h/g' \
+            -e 's/HASH/SHA3_224/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]Update/SHA3_Update/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]Final/SHA3_Final/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]_CTX/SHA3_CTX/g' $> > $@
+
+sha3-256hl.c:   helper.c
+ sed -e 's/hashinc/sha3.h/g' \
+            -e 's/HASH/SHA3_256/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]Update/SHA3_Update/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]Final/SHA3_Final/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]_CTX/SHA3_CTX/g' $> > $@
+
+sha3-384hl.c:   helper.c
+ sed -e 's/hashinc/sha3.h/g' \
+            -e 's/HASH/SHA3_384/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]Update/SHA3_Update/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]Final/SHA3_Final/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]_CTX/SHA3_CTX/g' $> > $@
+
+sha3-512hl.c:   helper.c
+ sed -e 's/hashinc/sha3.h/g' \
+            -e 's/HASH/SHA3_512/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]Update/SHA3_Update/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]Final/SHA3_Final/g' \
+            -e 's/SHA3_[0-9][0-9][0-9]_CTX/SHA3_CTX/g' $> > $@
+
+beforedepend: md5hl.c rmd160hl.c sha1hl.c sha256hl.c sha384hl.c sha512hl.c sha512_256hl.c sha3-224hl.c sha3-256hl.c sha3-384hl.c sha3-512hl.c  
Index: lib/libc/hash/sha3.3
===================================================================
RCS file: lib/libc/hash/sha3.3
diff -N lib/libc/hash/sha3.3
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libc/hash/sha3.3 11 Jan 2018 09:04:18 -0000
@@ -0,0 +1,292 @@
+.\" $OpenBSD: sha2.3,v 1.26 2016/09/04 09:28:12 tedu Exp $
+.\"
+.\" Copyright (c) 2003, 2004 Todd C. Miller <[hidden email]>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.\" Sponsored in part by the Defense Advanced Research Projects
+.\" Agency (DARPA) and Air Force Research Laboratory, Air Force
+.\" Materiel Command, USAF, under agreement number F39502-99-1-0512.
+.\"
+.\" See http://www.nist.gov/sha/ for the detailed standard
+.\"
+.Dd $Mdocdate: January 9 2018 $
+.Dt SHA3INIT 3
+.Os
+.Sh NAME
+.Nm SHA3_224Init ,
+.Nm SHA3_224Update ,
+.Nm SHA3_224Final ,
+.Nm SHA3_224End ,
+.Nm SHA3_224File ,
+.Nm SHA3_224FileChunk ,
+.Nm SHA3_224Data ,
+.Nm SHA3_256Init ,
+.Nm SHA3_256Update ,
+.Nm SHA3_256Final ,
+.Nm SHA3_256End ,
+.Nm SHA3_256File ,
+.Nm SHA3_256FileChunk ,
+.Nm SHA3_256Data ,
+.Nm SHA3_384Init ,
+.Nm SHA3_384Update ,
+.Nm SHA3_384Final ,
+.Nm SHA3_384End ,
+.Nm SHA3_384File ,
+.Nm SHA3_384FileChunk ,
+.Nm SHA3_384Data ,
+.Nm SHA3_512Init ,
+.Nm SHA3_512Update ,
+.Nm SHA3_512Final ,
+.Nm SHA3_512End ,
+.Nm SHA3_512File ,
+.Nm SHA3_512FileChunk ,
+.Nm SHA3_512Data ,
+.Nm SHA3_512_256Init ,
+.Nm SHA3_512_256Update ,
+.Nm SHA3_512_256Final ,
+.Nm SHA3_512_256End ,
+.Nm SHA3_512_256File ,
+.Nm SHA3_512_256FileChunk ,
+.Nm SHA3_512_256Data
+.Nd calculate the NIST Secure Hash Standard (version 3)
+.Sh SYNOPSIS
+.In sys/types.h
+.In sha3.h
+.Ft void
+.Fn SHA3_224Init "SHA3_CTX *context"
+.Ft void
+.Fn SHA3_224Update "SHA3_CTX *context" "const u_int8_t *data" "size_t len"
+.Ft void
+.Fn SHA3_224Final "u_int8_t digest[SHA3_224_DIGEST_LENGTH]" "SHA3_CTX *context"
+.Ft "char *"
+.Fn SHA3_224End "SHA3_CTX *context" "char *buf"
+.Ft "char *"
+.Fn SHA3_224File "const char *filename" "char *buf"
+.Ft "char *"
+.Fn SHA3_224FileChunk "const char *filename" "char *buf" "off_t offset" "off_t length"
+.Ft "char *"
+.Fn SHA3_224Data "const u_int8_t *data" "size_t len" "char *buf"
+.Ft void
+.Fn SHA3_256Init "SHA3_CTX *context"
+.Ft void
+.Fn SHA3_256Update "SHA3_CTX *context" "const u_int8_t *data" "size_t len"
+.Ft void
+.Fn SHA3_256Final "u_int8_t digest[SHA3_256_DIGEST_LENGTH]" "SHA3_CTX *context"
+.Ft "char *"
+.Fn SHA3_256End "SHA3_CTX *context" "char *buf"
+.Ft "char *"
+.Fn SHA3_256File "const char *filename" "char *buf"
+.Ft "char *"
+.Fn SHA3_256FileChunk "const char *filename" "char *buf" "off_t offset" "off_t length"
+.Ft "char *"
+.Fn SHA3_256Data "const u_int8_t *data" "size_t len" "char *buf"
+.Ft void
+.Fn SHA3_384Init "SHA3_CTX *context"
+.Ft void
+.Fn SHA3_384Update "SHA3_CTX *context" "const u_int8_t *data" "size_t len"
+.Ft void
+.Fn SHA3_384Final "u_int8_t digest[SHA3_384_DIGEST_LENGTH]" "SHA3_CTX *context"
+.Ft "char *"
+.Fn SHA3_384End "SHA3_CTX *context" "char *buf"
+.Ft "char *"
+.Fn SHA3_384File "const char *filename" "char *buf"
+.Ft "char *"
+.Fn SHA3_384FileChunk "const char *filename" "char *buf" "off_t offset" "off_t length"
+.Ft "char *"
+.Fn SHA3_384Data "const u_int8_t *data" "size_t len" "char *buf"
+.Ft void
+.Fn SHA3_512Init "SHA3_CTX *context"
+.Ft void
+.Fn SHA3_512Update "SHA3_CTX *context" "const u_int8_t *data" "size_t len"
+.Ft void
+.Fn SHA3_512Final "u_int8_t digest[SHA3_512_DIGEST_LENGTH]" "SHA3_CTX *context"
+.Ft "char *"
+.Fn SHA3_512End "SHA3_CTX *context" "char *buf"
+.Ft "char *"
+.Fn SHA3_512File "const char *filename" "char *buf"
+.Ft "char *"
+.Fn SHA3_512FileChunk "const char *filename" "char *buf" "off_t offset" "off_t length"
+.Ft "char *"
+.Fn SHA3_512Data "const u_int8_t *data" "size_t len" "char *buf"
+.Ft void
+.Fn SHA3_512_256Init "SHA3_CTX *context"
+.Ft void
+.Fn SHA3_512_256Update "SHA3_CTX *context" "const u_int8_t *data" "size_t len"
+.Ft void
+.Fn SHA3_512_256Final "u_int8_t digest[SHA3_512_256_DIGEST_LENGTH]" "SHA3_CTX *context"
+.Ft "char *"
+.Fn SHA3_512_256End "SHA3_CTX *context" "char *buf"
+.Ft "char *"
+.Fn SHA3_512_256File "const char *filename" "char *buf"
+.Ft "char *"
+.Fn SHA3_512_256FileChunk "const char *filename" "char *buf" "off_t offset" "off_t length"
+.Ft "char *"
+.Fn SHA3_512_256Data "const u_int8_t *data" "size_t len" "char *buf"
+.Sh DESCRIPTION
+The SHA-3 functions implement the NIST Secure Hash Standard,
+FIPS PUB 202.
+The SHA-3 functions are used to generate a condensed representation of a
+message called a message digest, suitable for use as a digital signature.
+There are four families of functions, with names corresponding to
+the number of bits in the resulting message digest.
+The functions can process a message of arbitrary length as input.
+.Pp
+The SHA-3 functions are considered to be more secure than the
+.Xr sha1 3
+functions with which they share a similar interface. They are an
+alternative to the
+.Xr sha2 3
+functions.
+The 224, 256, 384, and 512-bit versions of SHA-3 share the same interface.
+For brevity, only the 256-bit variants are described below.
+.Pp
+The
+.Fn SHA3_256Init
+function initializes a SHA3_CTX
+.Fa context
+for use with
+.Fn SHA3_256Update
+and
+.Fn SHA3_256Final .
+The
+.Fn SHA3_256Update
+function adds
+.Fa data
+of length
+.Fa len
+to the SHA3_CTX specified by
+.Fa context .
+.Fn SHA3_256Final
+is called when all data has been added via
+.Fn SHA3_256Update
+and stores a message digest in the
+.Fa digest
+parameter.
+.Pp
+The
+.Fn SHA3_256End
+function is a front end for
+.Fn SHA3_256Final
+which converts the digest into an
+.Tn ASCII
+representation of the digest in hexadecimal.
+.Pp
+The
+.Fn SHA3_256File
+function calculates the digest for a file and returns the result via
+.Fn SHA3_256End .
+If
+.Fn SHA3_256File
+is unable to open the file, a
+.Dv NULL
+pointer is returned.
+.Pp
+.Fn SHA3_256FileChunk
+behaves like
+.Fn SHA3_256File
+but calculates the digest only for that portion of the file starting at
+.Fa offset
+and continuing for
+.Fa length
+bytes or until end of file is reached, whichever comes first.
+A zero
+.Fa length
+can be specified to read until end of file.
+A negative
+.Fa length
+or
+.Fa offset
+will be ignored.
+.Pp
+The
+.Fn SHA3_256Data
+function
+calculates the digest of an arbitrary string and returns the result via
+.Fn SHA3_256End .
+.Pp
+For each of the
+.Fn SHA3_256End ,
+.Fn SHA3_256File ,
+.Fn SHA3_256FileChunk ,
+and
+.Fn SHA3_256Data
+functions the
+.Fa buf
+parameter should either be a string large enough to hold the resulting digest
+(e.g.\&
+.Dv SHA3_224_DIGEST_STRING_LENGTH ,
+.Dv SHA3_256_DIGEST_STRING_LENGTH ,
+.Dv SHA3_384_DIGEST_STRING_LENGTH ,
+.Dv SHA3_512_DIGEST_STRING_LENGTH ,
+or
+.Dv SHA3_512_256_DIGEST_STRING_LENGTH ,
+depending on the function being used)
+or a
+.Dv NULL
+pointer.
+In the latter case, space will be dynamically allocated via
+.Xr malloc 3
+and should be freed using
+.Xr free 3
+when it is no longer needed.
+.Sh EXAMPLES
+The following code fragment will calculate the SHA3-256 digest for the string
+.Qq abc ,
+which is
+.Dq 0x3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532 .
+.Bd -literal -offset indent
+SHA3_CTX ctx;
+u_int8_t results[SHA3_256_DIGEST_LENGTH];
+char *buf;
+int n;
+
+buf = "abc";
+n = strlen(buf);
+SHA3_256Init(&ctx);
+SHA3_256Update(&ctx, (u_int8_t *)buf, n);
+SHA3_256Final(results, &ctx);
+
+/* Print the digest as one long hex value */
+printf("0x");
+for (n = 0; n \*(Lt SHA3_256_DIGEST_LENGTH; n++)
+ printf("%02x", results[n]);
+putchar('\en');
+.Ed
+.Pp
+Alternately, the helper functions could be used in the following way:
+.Bd -literal -offset indent
+u_int8_t output[SHA3_256_DIGEST_STRING_LENGTH];
+char *buf = "abc";
+
+printf("0x%s\en", SHA3_256Data(buf, strlen(buf), output));
+.Ed
+.Sh SEE ALSO
+.Xr cksum 1 ,
+.Xr md5 3 ,
+.Xr rmd160 3 ,
+.Xr sha1 3 ,
+.Xr sha2 3
+.Rs
+.%T SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions
+.%O FIPS PUB 202
+.Re
+.Pp
+The
+.Fn SHA3_256End ,
+.Fn SHA3_256File ,
+.Fn SHA3_256FileChunk ,
+and
+.Fn SHA3_256Data
+helper functions are derived from code written by
+.An Poul-Henning Kamp .
Index: lib/libc/hash/sha3.c
===================================================================
RCS file: lib/libc/hash/sha3.c
diff -N lib/libc/hash/sha3.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libc/hash/sha3.c 11 Jan 2018 09:04:18 -0000
@@ -0,0 +1,761 @@
+/*
+ * Implementation by the Keccak, Keyak and Ketje Teams, namely, Guido Bertoni,
+ * Joan Daemen, Michaël Peeters, Gilles Van Assche and Ronny Van Keer, hereby
+ * denoted as "the implementer".
+ *
+ * For more information, feedback or questions, please refer to our websites:
+ * http://keccak.noekeon.org/
+ * http://keyak.noekeon.org/
+ * http://ketje.noekeon.org/
+ *
+ * Adaptation to OpenBSD in 2017/18 by
+ * Stefan-Lukas Gazdag, Alexander von Gernler and Daniel Loebenberger
+ * https://www.genua.de/
+ * also denoted as "the implementer"
+ *
+ * To the extent possible under law, the implementer has waived all copyright
+ * and related or neighboring rights to the source code in this file.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+#include <assert.h>
+#include <sys/types.h>
+#include <string.h>
+#include <strings.h>
+#include <sha3.h>
+
+typedef unsigned long long tKeccakLane;
+
+#define SHA3_NRROUNDS 24
+#define SHA3_NRLANES 25
+#define SHA3_DELIMITER 0x06
+
+#define index(x, y) (((x)%5)+5*((y)%5))
+
+const tKeccakLane KeccakRoundConstants[SHA3_NRROUNDS] =
+{
+ 0x0000000000000001,
+ 0x0000000000008082,
+ 0x800000000000808a,
+ 0x8000000080008000,
+ 0x000000000000808b,
+ 0x0000000080000001,
+ 0x8000000080008081,
+ 0x8000000000008009,
+ 0x000000000000008a,
+ 0x0000000000000088,
+ 0x0000000080008009,
+ 0x000000008000000a,
+ 0x000000008000808b,
+ 0x800000000000008b,
+ 0x8000000000008089,
+ 0x8000000000008003,
+ 0x8000000000008002,
+ 0x8000000000000080,
+ 0x000000000000800a,
+ 0x800000008000000a,
+ 0x8000000080008081,
+ 0x8000000000008080,
+ 0x0000000080000001,
+ 0x8000000080008008,
+};
+
+const unsigned int KeccakRhoOffsets[SHA3_NRLANES] =
+{
+ 0, 1, 62, 28, 27, 36, 44, 6, 55, 20, 3, 10, 43,
+ 25, 39, 41, 45, 15, 21, 8, 18, 2, 61, 56, 14
+};
+
+/*
+ * unused, but these constance denote the one implementation out of the
+ * Keccak Code Package that was taken here
+ */
+#define KeccakP1600_implementation      "64-bit reference implementation"
+#define KeccakP1600_stateSizeInBytes    200
+#define KeccakP1600_stateAlignment      8
+
+/* prototypes for local functions */
+static void KeccakP1600_AddByte(void *state, unsigned char data,
+    unsigned int offset);
+static void KeccakP1600_AddBytes(void *state, const unsigned char *data,
+    unsigned int offset, unsigned int length);
+static void KeccakP1600_Permute_24rounds(void *state);
+static void KeccakP1600_ExtractBytes(const void *state, unsigned char *data,
+    unsigned int offset, unsigned int length);
+static void Keccak_HashInitialize(SHA3_CTX *, unsigned int, unsigned int);
+
+
+/*
+ * interface functions external use
+ * (rate + capacity) = 1600,
+ * thus the rate specifies the capacity
+ */
+void
+SHA3_224Init(SHA3_CTX *context)
+{
+ /* rate = 1152, output width 224 bit */
+ Keccak_HashInitialize(context, 1152, 224);
+}
+DEF_WEAK(SHA3_224Init);
+
+void
+SHA3_256Init(SHA3_CTX *context)
+{
+ /* rate = 1088, output width 256 bit */
+ Keccak_HashInitialize(context, 1088, 256);
+}
+DEF_WEAK(SHA3_256Init);
+
+void
+SHA3_384Init(SHA3_CTX *context)
+{
+ /* rate = 832, output width 384 bit */
+ Keccak_HashInitialize(context, 832, 384);
+}
+DEF_WEAK(SHA3_384Init);
+
+void
+SHA3_512Init(SHA3_CTX *context)
+{
+ /* rate = 576, output width 512 bit */
+ Keccak_HashInitialize(context, 576, 512);
+}
+DEF_WEAK(SHA3_512Init);
+
+
+void
+SHA3_Update(SHA3_CTX *context, const u_int8_t *data, size_t len)
+{
+ size_t i, j;
+ unsigned int partialBlock;
+ const unsigned char *curData;
+ unsigned int rateInBytes;
+ rateInBytes = context->rate/8;
+
+ i = 0;
+ curData = data;
+ while(i < len) {
+ if ((context->byteIOIndex == 0) && (len >= (i + rateInBytes))) {
+#ifdef SnP_FastLoop_Absorb
+ /* processing full blocks first */
+ if ((rateInBytes % (KeccakP1600_width/200)) == 0) {
+ /* fast lane: whole lane rate */
+ j = KeccakP1600_FastLoop_Absorb(context->state,
+    rateInBytes/(KeccakP1600_width/200), curData, len - i);
+ i += j;
+ curData += j;
+ }
+ else {
+#endif
+ for(j=len-i; j>=rateInBytes; j-=rateInBytes) {
+#ifdef KeccakReference
+ displayBytes(1, "Block to be absorbed", curData, rateInBytes);
+#endif
+ KeccakP1600_AddBytes(context->state, curData, 0, rateInBytes);
+ KeccakP1600_Permute_24rounds(context->state);
+ curData+=rateInBytes;
+ }
+ i = len - j;
+#ifdef SnP_FastLoop_Absorb
+ }
+#endif
+ }
+ else {
+ /* normal lane: using the message queue */
+ partialBlock = (unsigned int)(len - i);
+ if (partialBlock+context->byteIOIndex > rateInBytes)
+ partialBlock = rateInBytes-context->byteIOIndex;
+#ifdef KeccakReference
+ displayBytes(1, "Block to be absorbed (part)", curData, partialBlock);
+#endif
+ i += partialBlock;
+
+ KeccakP1600_AddBytes(context->state, curData, context->byteIOIndex, partialBlock);
+ curData += partialBlock;
+ context->byteIOIndex += partialBlock;
+ if (context->byteIOIndex == rateInBytes) {
+ KeccakP1600_Permute_24rounds(context->state);
+ context->byteIOIndex = 0;
+ }
+ }
+ }
+}
+DEF_WEAK(SHA3_Update);
+
+void
+SHA3_Final(u_int8_t* digest, SHA3_CTX *context)
+{
+ size_t i, j;
+ unsigned int partialBlock;
+ unsigned char *curData;
+ unsigned int rateInBytes;
+ size_t dataByteLen;
+
+ rateInBytes = context->rate/8;
+ dataByteLen = context->fixedOutputLength/8;
+
+ /* Last few bits, whose delimiter coincides with first bit of padding */
+ KeccakP1600_AddByte(context->state, SHA3_DELIMITER, context->byteIOIndex);
+
+ /*
+ * If the first bit of padding is at position rate-1, we need a whole
+ * new block for the second bit of padding
+ */
+ /* Second bit of padding */
+ KeccakP1600_AddByte(context->state, 0x80, rateInBytes-1);
+
+ KeccakP1600_Permute_24rounds(context->state);
+ context->byteIOIndex = 0;
+
+ /* SQUEEZE */
+ i = 0;
+ curData = digest;
+ while(i < dataByteLen) {
+ if ((context->byteIOIndex == rateInBytes) && (dataByteLen >= (i + rateInBytes))) {
+ for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) {
+ KeccakP1600_Permute_24rounds(context->state);
+ KeccakP1600_ExtractBytes(context->state, curData, 0, rateInBytes);
+ curData+=rateInBytes;
+ }
+ i = dataByteLen - j;
+ }
+ else {
+ /* normal lane: using the message queue */
+ if (context->byteIOIndex == rateInBytes) {
+ KeccakP1600_Permute_24rounds(context->state);
+ context->byteIOIndex = 0;
+ }
+ partialBlock = (unsigned int)(dataByteLen - i);
+ if (partialBlock+context->byteIOIndex > rateInBytes)
+ partialBlock = rateInBytes-context->byteIOIndex;
+ i += partialBlock;
+
+ KeccakP1600_ExtractBytes(context->state, curData, context->byteIOIndex, partialBlock);
+ curData += partialBlock;
+ context->byteIOIndex += partialBlock;
+ }
+ }
+}
+DEF_WEAK(SHA3_Final);
+
+/*
+ * internal functions
+ */
+static void
+Keccak_HashInitialize(SHA3_CTX *context, unsigned int rate,
+    unsigned int hashbitlen)
+{
+ bzero(context->state, SHA3_STATE_SIZE);
+ context->rate = rate;
+ context->byteIOIndex = 0;
+ context->fixedOutputLength = hashbitlen;
+}
+
+static void
+KeccakP1600_AddByte(void *state, unsigned char byte, unsigned int offset)
+{
+ assert(offset < 200);
+ ((unsigned char *)state)[offset] ^= byte;
+}
+
+static void
+KeccakP1600_AddBytes(void *state, const unsigned char *data, unsigned int offset, unsigned int length)
+{
+ unsigned int i;
+
+ assert(offset < 200);
+ assert(offset+length <= 200);
+ for(i=0; i<length; i++)
+ ((unsigned char *)state)[offset+i] ^= data[i];
+}
+
+#if BYTE_ORDER == BIG_ENDIAN
+static void fromBytesToWords(tKeccakLane *stateAsWords, const unsigned char *state);
+static void fromWordsToBytes(unsigned char *state, const tKeccakLane *stateAsWords);
+#endif
+static void KeccakP1600OnWords(tKeccakLane *state);
+#if BYTE_ORDER == LITTLE_ENDIAN
+static void KeccakP1600QuadRound(tKeccakLane *state, unsigned int indexRound);
+#else
+static void KeccakP1600RoundSlow(tKeccakLane *state, unsigned int indexRound);
+static void theta(tKeccakLane *A);
+static void rho(tKeccakLane *A);
+static void pi(tKeccakLane *A);
+static void chi(tKeccakLane *A);
+static void iota(tKeccakLane *A, unsigned int indexRound);
+#endif
+
+static void
+KeccakP1600_Permute_24rounds(void *state)
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+ KeccakP1600OnWords((tKeccakLane*)state);
+#else
+ tKeccakLane stateAsWords[1600/64];
+
+ fromBytesToWords(stateAsWords, (const unsigned char *)state);
+ KeccakP1600OnWords(stateAsWords);
+ fromWordsToBytes((unsigned char *)state, stateAsWords);
+#endif
+}
+
+#if BYTE_ORDER == BIG_ENDIAN
+static void
+fromBytesToWords(tKeccakLane *stateAsWords, const unsigned char *state)
+{
+ unsigned int i, j;
+
+ for(i=0; i<SHA3_NRLANES; i++) {
+ stateAsWords[i] = 0;
+ for(j=0; j<(64/8); j++)
+ stateAsWords[i] |= (tKeccakLane)(state[i*(64/8)+j]) << (8*j);
+ }
+}
+
+static void
+fromWordsToBytes(unsigned char *state, const tKeccakLane *stateAsWords)
+{
+ unsigned int i, j;
+
+ for(i=0; i<SHA3_NRLANES; i++)
+ for(j=0; j<(64/8); j++)
+ state[i*(64/8)+j] = (unsigned char)((stateAsWords[i] >> (8*j)) & 0xFF);
+}
+#endif
+
+static void
+KeccakP1600OnWords(tKeccakLane *state)
+{
+ unsigned int i;
+
+
+#if BYTE_ORDER == BIG_ENDIAN
+ /*
+ * Use the unoptimized reference implementation when
+ * on big endian machines
+ */
+ for(i=0; i<SHA3_NRROUNDS; i++)
+ KeccakP1600RoundSlow(state, i);
+#else
+ /*
+ * Use the inplace version from the Keccak optimized reference
+ * code of KeccakP1600 on little endian machines
+ * Note that this routine does four rounds in one call.
+ * */
+ for(i=0; i<SHA3_NRROUNDS; i+=4)
+ KeccakP1600QuadRound(state, i);
+#endif
+}
+
+#define ROL64(a, offset) ((offset != 0) ? ((((tKeccakLane)a) << offset) ^ (((tKeccakLane)a) >> (64-offset))) : a)
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+static void
+KeccakP1600QuadRound(tKeccakLane *state, unsigned int indexRound)
+{        
+        /*
+ * Inplace implementation by Ronny Van Keer and the designers
+ * of Keccak from the optimized Keccak reference code
+ */
+
+ tKeccakLane Ba, Be, Bi, Bo, Bu;
+        tKeccakLane Ca, Ce, Ci, Co, Cu;
+        tKeccakLane Da, De, Di, Do, Du;
+
+#define Aba state[ 0]
+#define Abe state[ 1]
+#define Abi state[ 2]
+#define Abo state[ 3]
+#define Abu state[ 4]
+#define Aga state[ 5]
+#define Age state[ 6]
+#define Agi state[ 7]
+#define Ago state[ 8]
+#define Agu state[ 9]
+#define Aka state[10]
+#define Ake state[11]
+#define Aki state[12]
+#define Ako state[13]
+#define Aku state[14]
+#define Ama state[15]
+#define Ame state[16]
+#define Ami state[17]
+#define Amo state[18]
+#define Amu state[19]
+#define Asa state[20]
+#define Ase state[21]
+#define Asi state[22]
+#define Aso state[23]
+#define Asu state[24]
+
+        Ca = Aba^Aga^Aka^Ama^Asa;
+        Ce = Abe^Age^Ake^Ame^Ase;
+        Ci = Abi^Agi^Aki^Ami^Asi;
+        Co = Abo^Ago^Ako^Amo^Aso;
+        Cu = Abu^Agu^Aku^Amu^Asu;
+        Da = Cu^ROL64(Ce, 1);
+        De = Ca^ROL64(Ci, 1);
+        Di = Ce^ROL64(Co, 1);
+        Do = Ci^ROL64(Cu, 1);
+        Du = Co^ROL64(Ca, 1);
+
+        Ba = (Aba^Da);
+        Be = ROL64((Age^De), 44);
+        Bi = ROL64((Aki^Di), 43);
+        Bo = ROL64((Amo^Do), 21);
+        Bu = ROL64((Asu^Du), 14);
+        Aba =   Ba ^((~Be)&  Bi );
+        Aba ^= KeccakRoundConstants[indexRound];
+        Age =   Be ^((~Bi)&  Bo );
+        Aki =   Bi ^((~Bo)&  Bu );
+        Amo =   Bo ^((~Bu)&  Ba );
+        Asu =   Bu ^((~Ba)&  Be );
+
+        Bi = ROL64((Aka^Da), 3);
+        Bo = ROL64((Ame^De), 45);
+        Bu = ROL64((Asi^Di), 61);
+        Ba = ROL64((Abo^Do), 28);
+        Be = ROL64((Agu^Du), 20);
+        Aka =   Ba ^((~Be)&  Bi );
+        Ame =   Be ^((~Bi)&  Bo );
+        Asi =   Bi ^((~Bo)&  Bu );
+        Abo =   Bo ^((~Bu)&  Ba );
+        Agu =   Bu ^((~Ba)&  Be );
+
+        Bu = ROL64((Asa^Da), 18);
+        Ba = ROL64((Abe^De), 1);
+        Be = ROL64((Agi^Di), 6);
+        Bi = ROL64((Ako^Do), 25);
+        Bo = ROL64((Amu^Du), 8);
+        Asa =   Ba ^((~Be)&  Bi );
+        Abe =   Be ^((~Bi)&  Bo );
+        Agi =   Bi ^((~Bo)&  Bu );
+        Ako =   Bo ^((~Bu)&  Ba );
+        Amu =   Bu ^((~Ba)&  Be );
+
+        Be = ROL64((Aga^Da), 36);
+        Bi = ROL64((Ake^De), 10);
+        Bo = ROL64((Ami^Di), 15);
+        Bu = ROL64((Aso^Do), 56);
+        Ba = ROL64((Abu^Du), 27);
+        Aga =   Ba ^((~Be)&  Bi );
+        Ake =   Be ^((~Bi)&  Bo );
+        Ami =   Bi ^((~Bo)&  Bu );
+        Aso =   Bo ^((~Bu)&  Ba );
+        Abu =   Bu ^((~Ba)&  Be );
+
+        Bo = ROL64((Ama^Da), 41);
+        Bu = ROL64((Ase^De), 2);
+        Ba = ROL64((Abi^Di), 62);
+        Be = ROL64((Ago^Do), 55);
+        Bi = ROL64((Aku^Du), 39);
+        Ama =   Ba ^((~Be)&  Bi );
+        Ase =   Be ^((~Bi)&  Bo );
+        Abi =   Bi ^((~Bo)&  Bu );
+        Ago =   Bo ^((~Bu)&  Ba );
+        Aku =   Bu ^((~Ba)&  Be );
+
+        Ca = Aba^Aka^Asa^Aga^Ama;
+        Ce = Age^Ame^Abe^Ake^Ase;
+        Ci = Aki^Asi^Agi^Ami^Abi;
+        Co = Amo^Abo^Ako^Aso^Ago;
+        Cu = Asu^Agu^Amu^Abu^Aku;
+        Da = Cu^ROL64(Ce, 1);
+        De = Ca^ROL64(Ci, 1);
+        Di = Ce^ROL64(Co, 1);
+        Do = Ci^ROL64(Cu, 1);
+        Du = Co^ROL64(Ca, 1);
+
+        Ba = (Aba^Da);
+        Be = ROL64((Ame^De), 44);
+        Bi = ROL64((Agi^Di), 43);
+        Bo = ROL64((Aso^Do), 21);
+        Bu = ROL64((Aku^Du), 14);
+        Aba =   Ba ^((~Be)&  Bi );
+        Aba ^= KeccakRoundConstants[indexRound+1];
+        Ame =   Be ^((~Bi)&  Bo );
+        Agi =   Bi ^((~Bo)&  Bu );
+        Aso =   Bo ^((~Bu)&  Ba );
+        Aku =   Bu ^((~Ba)&  Be );
+
+        Bi = ROL64((Asa^Da), 3);
+        Bo = ROL64((Ake^De), 45);
+        Bu = ROL64((Abi^Di), 61);
+        Ba = ROL64((Amo^Do), 28);
+        Be = ROL64((Agu^Du), 20);
+        Asa =   Ba ^((~Be)&  Bi );
+        Ake =   Be ^((~Bi)&  Bo );
+        Abi =   Bi ^((~Bo)&  Bu );
+        Amo =   Bo ^((~Bu)&  Ba );
+        Agu =   Bu ^((~Ba)&  Be );
+
+        Bu = ROL64((Ama^Da), 18);
+        Ba = ROL64((Age^De), 1);
+        Be = ROL64((Asi^Di), 6);
+        Bi = ROL64((Ako^Do), 25);
+        Bo = ROL64((Abu^Du), 8);
+        Ama =   Ba ^((~Be)&  Bi );
+        Age =   Be ^((~Bi)&  Bo );
+        Asi =   Bi ^((~Bo)&  Bu );
+        Ako =   Bo ^((~Bu)&  Ba );
+        Abu =   Bu ^((~Ba)&  Be );
+
+        Be = ROL64((Aka^Da), 36);
+        Bi = ROL64((Abe^De), 10);
+        Bo = ROL64((Ami^Di), 15);
+        Bu = ROL64((Ago^Do), 56);
+        Ba = ROL64((Asu^Du), 27);
+        Aka =   Ba ^((~Be)&  Bi );
+        Abe =   Be ^((~Bi)&  Bo );
+        Ami =   Bi ^((~Bo)&  Bu );
+        Ago =   Bo ^((~Bu)&  Ba );
+        Asu =   Bu ^((~Ba)&  Be );
+
+        Bo = ROL64((Aga^Da), 41);
+        Bu = ROL64((Ase^De), 2);
+        Ba = ROL64((Aki^Di), 62);
+        Be = ROL64((Abo^Do), 55);
+        Bi = ROL64((Amu^Du), 39);
+        Aga =   Ba ^((~Be)&  Bi );
+        Ase =   Be ^((~Bi)&  Bo );
+        Aki =   Bi ^((~Bo)&  Bu );
+        Abo =   Bo ^((~Bu)&  Ba );
+        Amu =   Bu ^((~Ba)&  Be );
+
+        Ca = Aba^Asa^Ama^Aka^Aga;
+        Ce = Ame^Ake^Age^Abe^Ase;
+        Ci = Agi^Abi^Asi^Ami^Aki;
+        Co = Aso^Amo^Ako^Ago^Abo;
+        Cu = Aku^Agu^Abu^Asu^Amu;
+        Da = Cu^ROL64(Ce, 1);
+        De = Ca^ROL64(Ci, 1);
+        Di = Ce^ROL64(Co, 1);
+        Do = Ci^ROL64(Cu, 1);
+        Du = Co^ROL64(Ca, 1);
+
+        Ba = (Aba^Da);
+        Be = ROL64((Ake^De), 44);
+        Bi = ROL64((Asi^Di), 43);
+        Bo = ROL64((Ago^Do), 21);
+        Bu = ROL64((Amu^Du), 14);
+        Aba =   Ba ^((~Be)&  Bi );
+        Aba ^= KeccakRoundConstants[indexRound+2];
+        Ake =   Be ^((~Bi)&  Bo );
+        Asi =   Bi ^((~Bo)&  Bu );
+        Ago =   Bo ^((~Bu)&  Ba );
+        Amu =   Bu ^((~Ba)&  Be );
+
+        Bi = ROL64((Ama^Da), 3);
+        Bo = ROL64((Abe^De), 45);
+        Bu = ROL64((Aki^Di), 61);
+        Ba = ROL64((Aso^Do), 28);
+        Be = ROL64((Agu^Du), 20);
+        Ama =   Ba ^((~Be)&  Bi );
+        Abe =   Be ^((~Bi)&  Bo );
+        Aki =   Bi ^((~Bo)&  Bu );
+        Aso =   Bo ^((~Bu)&  Ba );
+        Agu =   Bu ^((~Ba)&  Be );
+
+        Bu = ROL64((Aga^Da), 18);
+        Ba = ROL64((Ame^De), 1);
+        Be = ROL64((Abi^Di), 6);
+        Bi = ROL64((Ako^Do), 25);
+        Bo = ROL64((Asu^Du), 8);
+        Aga =   Ba ^((~Be)&  Bi );
+        Ame =   Be ^((~Bi)&  Bo );
+        Abi =   Bi ^((~Bo)&  Bu );
+        Ako =   Bo ^((~Bu)&  Ba );
+        Asu =   Bu ^((~Ba)&  Be );
+
+        Be = ROL64((Asa^Da), 36);
+        Bi = ROL64((Age^De), 10);
+        Bo = ROL64((Ami^Di), 15);
+        Bu = ROL64((Abo^Do), 56);
+        Ba = ROL64((Aku^Du), 27);
+        Asa =   Ba ^((~Be)&  Bi );
+        Age =   Be ^((~Bi)&  Bo );
+        Ami =   Bi ^((~Bo)&  Bu );
+        Abo =   Bo ^((~Bu)&  Ba );
+        Aku =   Bu ^((~Ba)&  Be );
+
+        Bo = ROL64((Aka^Da), 41);
+        Bu = ROL64((Ase^De), 2);
+        Ba = ROL64((Agi^Di), 62);
+        Be = ROL64((Amo^Do), 55);
+        Bi = ROL64((Abu^Du), 39);
+        Aka =   Ba ^((~Be)&  Bi );
+        Ase =   Be ^((~Bi)&  Bo );
+        Agi =   Bi ^((~Bo)&  Bu );
+        Amo =   Bo ^((~Bu)&  Ba );
+        Abu =   Bu ^((~Ba)&  Be );
+
+        Ca = Aba^Ama^Aga^Asa^Aka;
+        Ce = Ake^Abe^Ame^Age^Ase;
+        Ci = Asi^Aki^Abi^Ami^Agi;
+        Co = Ago^Aso^Ako^Abo^Amo;
+        Cu = Amu^Agu^Asu^Aku^Abu;
+        Da = Cu^ROL64(Ce, 1);
+        De = Ca^ROL64(Ci, 1);
+        Di = Ce^ROL64(Co, 1);
+        Do = Ci^ROL64(Cu, 1);
+        Du = Co^ROL64(Ca, 1);
+
+        Ba = (Aba^Da);
+        Be = ROL64((Abe^De), 44);
+        Bi = ROL64((Abi^Di), 43);
+        Bo = ROL64((Abo^Do), 21);
+        Bu = ROL64((Abu^Du), 14);
+        Aba =   Ba ^((~Be)&  Bi );
+        Aba ^= KeccakRoundConstants[indexRound+3];
+        Abe =   Be ^((~Bi)&  Bo );
+        Abi =   Bi ^((~Bo)&  Bu );
+        Abo =   Bo ^((~Bu)&  Ba );
+        Abu =   Bu ^((~Ba)&  Be );
+
+        Bi = ROL64((Aga^Da), 3);
+        Bo = ROL64((Age^De), 45);
+        Bu = ROL64((Agi^Di), 61);
+        Ba = ROL64((Ago^Do), 28);
+        Be = ROL64((Agu^Du), 20);
+        Aga =   Ba ^((~Be)&  Bi );
+        Age =   Be ^((~Bi)&  Bo );
+        Agi =   Bi ^((~Bo)&  Bu );
+        Ago =   Bo ^((~Bu)&  Ba );
+        Agu =   Bu ^((~Ba)&  Be );
+
+        Bu = ROL64((Aka^Da), 18);
+        Ba = ROL64((Ake^De), 1);
+        Be = ROL64((Aki^Di), 6);
+        Bi = ROL64((Ako^Do), 25);
+        Bo = ROL64((Aku^Du), 8);
+        Aka =   Ba ^((~Be)&  Bi );
+        Ake =   Be ^((~Bi)&  Bo );
+        Aki =   Bi ^((~Bo)&  Bu );
+        Ako =   Bo ^((~Bu)&  Ba );
+        Aku =   Bu ^((~Ba)&  Be );
+
+        Be = ROL64((Ama^Da), 36);
+        Bi = ROL64((Ame^De), 10);
+        Bo = ROL64((Ami^Di), 15);
+        Bu = ROL64((Amo^Do), 56);
+        Ba = ROL64((Amu^Du), 27);
+        Ama =   Ba ^((~Be)&  Bi );
+        Ame =   Be ^((~Bi)&  Bo );
+        Ami =   Bi ^((~Bo)&  Bu );
+        Amo =   Bo ^((~Bu)&  Ba );
+        Amu =   Bu ^((~Ba)&  Be );
+
+        Bo = ROL64((Asa^Da), 41);
+        Bu = ROL64((Ase^De), 2);
+        Ba = ROL64((Asi^Di), 62);
+        Be = ROL64((Aso^Do), 55);
+        Bi = ROL64((Asu^Du), 39);
+        Asa =   Ba ^((~Be)&  Bi );
+        Ase =   Be ^((~Bi)&  Bo );
+        Asi =   Bi ^((~Bo)&  Bu );
+        Aso =   Bo ^((~Bu)&  Ba );
+        Asu =   Bu ^((~Ba)&  Be );
+
+#undef Aba
+#undef Abe
+#undef Abi
+#undef Abo
+#undef Abu
+#undef Aga
+#undef Age
+#undef Agi
+#undef Ago
+#undef Agu
+#undef Aka
+#undef Ake
+#undef Aki
+#undef Ako
+#undef Aku
+#undef Ama
+#undef Ame
+#undef Ami
+#undef Amo
+#undef Amu
+#undef Asa
+#undef Ase
+#undef Asi
+#undef Aso
+#undef Asu
+}
+
+#else /* BYTE_ORDER != BIG_ENDIAN */
+void
+KeccakP1600RoundSlow(tKeccakLane *state, unsigned int indexRound)
+{        
+ theta(state);
+ rho(state);
+ pi(state);
+ chi(state);
+ iota(state, indexRound);
+}
+
+#define ROL64(a, offset) ((offset != 0) ? ((((tKeccakLane)a) << offset) ^ (((tKeccakLane)a) >> (64-offset))) : a)
+
+static void theta(tKeccakLane *A)
+{
+ unsigned int x, y;
+ tKeccakLane C[5], D[5];
+
+ for(x=0; x<5; x++) {
+ C[x] = 0;
+ for(y=0; y<5; y++)
+ C[x] ^= A[index(x, y)];
+ }
+ for(x=0; x<5; x++)
+ D[x] = ROL64(C[(x+1)%5], 1) ^ C[(x+4)%5];
+ for(x=0; x<5; x++)
+ for(y=0; y<5; y++)
+ A[index(x, y)] ^= D[x];
+}
+
+static void rho(tKeccakLane *A)
+{
+ unsigned int x, y;
+
+ for(x=0; x<5; x++) for(y=0; y<5; y++)
+ A[index(x, y)] = ROL64(A[index(x, y)], KeccakRhoOffsets[index(x, y)]);
+}
+
+static void pi(tKeccakLane *A)
+{
+ unsigned int x, y;
+ tKeccakLane tempA[25];
+
+ for(x=0; x<5; x++) for(y=0; y<5; y++)
+ tempA[index(x, y)] = A[index(x, y)];
+ for(x=0; x<5; x++) for(y=0; y<5; y++)
+ A[index(0*x+1*y, 2*x+3*y)] = tempA[index(x, y)];
+}
+
+static void chi(tKeccakLane *A)
+{
+ unsigned int x, y;
+ tKeccakLane C[5];
+
+ for(y=0; y<5; y++) {
+ for(x=0; x<5; x++)
+ C[x] = A[index(x, y)] ^ ((~A[index(x+1, y)]) & A[index(x+2, y)]);
+ for(x=0; x<5; x++)
+ A[index(x, y)] = C[x];
+ }
+}
+
+static void iota(tKeccakLane *A, unsigned int indexRound)
+{
+ A[index(0, 0)] ^= KeccakRoundConstants[indexRound];
+}
+#endif /* BYTE_ORDER != BIG_ENDIAN */
+
+static void
+KeccakP1600_ExtractBytes(const void *state, unsigned char *data, unsigned int offset, unsigned int length)
+{
+ assert(offset < 200);
+ assert(offset+length <= 200);
+ memcpy(data, (unsigned char*)state+offset, length);
+}
+
Index: lib/libc/hidden/sha3.h
===================================================================
RCS file: lib/libc/hidden/sha3.h
diff -N lib/libc/hidden/sha3.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lib/libc/hidden/sha3.h 11 Jan 2018 09:04:18 -0000
@@ -0,0 +1,29 @@
+#ifndef _LIBC_SHA3_H
+#define _LIBC_SHA3_H
+
+#include_next <sha3.h>
+
+PROTO_NORMAL(SHA3_Update);
+PROTO_NORMAL(SHA3_Final);
+PROTO_NORMAL(SHA3_224Data);
+PROTO_NORMAL(SHA3_224End);
+PROTO_NORMAL(SHA3_224File);
+PROTO_NORMAL(SHA3_224FileChunk);
+PROTO_NORMAL(SHA3_224Init);
+PROTO_NORMAL(SHA3_256Data);
+PROTO_NORMAL(SHA3_256End);
+PROTO_NORMAL(SHA3_256File);
+PROTO_NORMAL(SHA3_256FileChunk);
+PROTO_NORMAL(SHA3_256Init);
+PROTO_NORMAL(SHA3_384Data);
+PROTO_NORMAL(SHA3_384End);
+PROTO_NORMAL(SHA3_384File);
+PROTO_NORMAL(SHA3_384FileChunk);
+PROTO_NORMAL(SHA3_384Init);
+PROTO_NORMAL(SHA3_512Data);
+PROTO_NORMAL(SHA3_512End);
+PROTO_NORMAL(SHA3_512File);
+PROTO_NORMAL(SHA3_512FileChunk);
+PROTO_NORMAL(SHA3_512Init);
+
+#endif /* _LIBC_SHA3_H */

Reply | Threaded
Open this post in threaded view
|

Re: Basic SHA3 support (cryptographic discussion)

Daniel Loebenberger
In reply to this post by Theo de Raadt-2
Hi,

concerning the question who needs SHA3, we do not agree that SHA3 should
be skipped as a standard. As cryptographers we sincerely believe that
the SHA3 design is superior to the one of SHA256 also due to the process
it was created. We believe that an efficient implementation will trigger
increased use of the standard and hope that its user base will grow
quickly once the commands are simply there.

For the discussion, find here some additional arguments in favor of
SHA3:

- The construction of SHA3 differs considerably from the SHA2
constructions (which covers all variants). Cryptanalytic progress for
SHA2 can destroy all variants at once, but will probably not affect
SHA3.

- SHA3's design principles are far better understood than the ones of
SHA2. The invention of sponge functions is in our opinion one of the
greatest inventions in hash-function design over the past few years. It
is simple and brilliant, and the generic properties of the construction
have appealing properties. - A possible migration away from SHA2 will be
faster when including SHA3 in OpenBSD now if it should happen that major
cryptanalytic advances attacking SHA2 pop up in the future. - The claim
that we now "know" how to build secure hash functions in general seems
problematic. To break a function, substantial cryptanalytic effort must
be made. It is not clear how much of this effort was put in the
presumably secure "newer" functions. - The argument that SHA3 is slow
does at least not apply to the reference code we used: The current
implementation of sha3-256 is indeed [slightly] faster on our machine
than the one of sha256.

Best regards,
Daniel, Stefan and Alexander

Reply | Threaded
Open this post in threaded view
|

Re: Basic SHA3 support

bytevolcano
In reply to this post by Theo de Raadt-2
On Wed, 10 Jan 2018 20:32:30 -0700
"Theo de Raadt" <[hidden email]> wrote:

> > I also use the sha512 command on a regular basis, and notice a
> > performance improvement (compared to sha256) with amd64 systems.  
>
> But is /bin the place to put a performance improving command?
>
> No.  That isn't the place for putting strange performance commands.
> It is a place for putting *interoperating* commands.

It isn't really a "performance improving" command, it's a different
hash. I just mentioned the performance improvement in passing.

>
> I don't think Todd's original question was answered, except along
> the lines of "i love features".
>

His question was "who uses the sha512 link", so I answered. I don't see
where the issue is here.

Though if the link were to go, I would be able to adapt to "cksum -a
sha512 ..."

Reply | Threaded
Open this post in threaded view
|

Re: Basic SHA3 support (cryptographic discussion)

Christian Weisgerber
In reply to this post by Daniel Loebenberger
Daniel Loebenberger:

> - The construction of SHA3 differs considerably from the SHA2
> constructions
> - SHA3's design principles are far better understood than the ones of
> SHA2.

I hear you, but you are missing the point.

> - A possible migration away from SHA2 will be
> faster when including SHA3 in OpenBSD now if it should happen that major
> cryptanalytic advances attacking SHA2 pop up in the future.

You are arguing for cryptographic algorithm agility.  That is a
concept the OpenBSD project has become increasingly critical of,
because it adds complexity and code size for questionable gain.

SHA-2 is baked into numerous protocols.  Off the top of my head:
* signify(1)
* all non-legacy SSH key exchange and authentication methods
* all non-legacy TLS cipher suites and certificates

For all of those, a switchover to SHA-3 would require defining new
protocol variants and then deploying them throughout the ecosystem.
Having a SHA-3 implementation in libc is a rather small part of the
overall effort.  And there is no practical algorithm agility until
you get to the point where you already HAVE deployed the new protocol
variants.

SHA-3 may be better, but so far SHA-2 is good enough.
Algorithm agility is a questionable goal.

So let me repeat the question:
What do you want to USE your SHA-3 implementation for?

--
Christian "naddy" Weisgerber                          [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Basic SHA3 support (cryptographic discussion)

Alexander Bluhm
On Wed, Jan 17, 2018 at 10:20:50PM +0100, Christian Weisgerber wrote:
> What do you want to USE your SHA-3 implementation for?

I would like to have a sha3 command line tool.  Just to have it
there and start using it.  For example adding it to ports distfiles
would be trivial.

Yes, general protocol transition will be hard.  And it will not
happen before sha2 is broken.  And we will live with broken hashes
for a long time.  But I think this is not an argument against sha3.

Of course there is the question whether this should be in libc and
/bin.  But this is independent of adding sha3 and even more relevant
for broken md5 and sha1.  So I would add one sha3 tool there for
consistency.  If we feel it does not belong there and it hurts, all
the hashes could be moved.

bluhm