[prev in list] [next in list] [prev in thread] [next in thread]
List: openbsd-tech
Subject: Basic SHA3 support
From: Daniel Loebenberger <daniel_loebenberger () genua ! de>
Date: 2018-01-09 15:47:18
Message-ID: 20180109154718.GA26307 () pantakel ! genua ! de
[Download RAW message or body]
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 <Todd.Miller@courtesan.com>
+.\"
+.\" 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 */
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic