Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package libkeccak for openSUSE:Factory checked in at 2022-02-14 22:36:06 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/libkeccak (Old) and /work/SRC/openSUSE:Factory/.libkeccak.new.1956 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libkeccak" Mon Feb 14 22:36:06 2022 rev:5 rq:954123 version:1.3.1 Changes: -------- --- /work/SRC/openSUSE:Factory/libkeccak/libkeccak.changes 2021-08-23 10:08:57.756190930 +0200 +++ /work/SRC/openSUSE:Factory/.libkeccak.new.1956/libkeccak.changes 2022-02-14 22:36:47.813511526 +0100 @@ -1,0 +2,6 @@ +Sat Feb 12 17:05:15 UTC 2022 - Andreas Stieger <andreas.stie...@gmx.de> + +- update to 1.3.1: + * add zero copy functions + +------------------------------------------------------------------- Old: ---- 1.2.2.tar.gz New: ---- 1.3.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ libkeccak.spec ++++++ --- /var/tmp/diff_new_pack.tSzCYb/_old 2022-02-14 22:36:48.281512746 +0100 +++ /var/tmp/diff_new_pack.tSzCYb/_new 2022-02-14 22:36:48.281512746 +0100 @@ -1,7 +1,7 @@ # # spec file for package libkeccak # -# Copyright (c) 2021 SUSE LLC +# Copyright (c) 2022 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,13 +18,13 @@ %define lname libkeccak1 Name: libkeccak -Version: 1.2.2 +Version: 1.3.1 Release: 0 Summary: Keccak family hashing library, including SHA-3 License: ISC Group: Development/Libraries/C and C++ URL: https://github.com/maandree/libkeccak -Source: https://github.com/maandree/libkeccak/archive/refs/tags/%{version}.tar.gz +Source: https://github.com/maandree/libkeccak/archive/refs/tags/%version.tar.gz %description libkeccak is a bit-oriented lanewise implementation of the Keccak @@ -35,9 +35,9 @@ A subset of Keccak was specified by NIST as SHA-3 (Secure Hash Algorithm 3). %package devel -Summary: Development files for %{name} +Summary: Development files for %name Group: Development/Libraries/C and C++ -Requires: %lname = %{version} +Requires: %lname = %version %description devel libkeccak is a bit-oriented lanewise implementation of the Keccak @@ -46,7 +46,7 @@ sensitive data, and HMAC. A subset of Keccak was specified by NIST as SHA-3 (Secure Hash Algorithm 3). -This package contains the files required for development with %{name}. +This package contains the files required for development with %name. %package -n %lname Summary: Keccak family hashing library, including SHA-3 @@ -64,17 +64,17 @@ %autosetup -p1 %build -%make_build CFLAGS="%{optflags}" +%make_build CFLAGS="%optflags" %install -mkdir -p %{buildroot}%{_libdir} -%make_install PREFIX=%{_prefix} -find %{buildroot} -type f -iname '*.a' -print -delete -if [ "%{_lib}" != lib ]; then - mv %{buildroot}/%{_libdir}/../lib/* %{buildroot}/%{_libdir}/ +mkdir -p %buildroot%_libdir +%make_install PREFIX=%_prefix +find %buildroot -type f -iname '*.a' -print -delete +if [ "%_lib" != lib ]; then + mv %buildroot/%_libdir/../lib/* %buildroot/%_libdir/ fi # packaged via macro -rm -rvf %{buildroot}%{_datadir}/licenses/%{name} +rm -rvf %buildroot%_datadir/licenses/%name %post -n %lname -p /sbin/ldconfig %postun -n %lname -p /sbin/ldconfig @@ -82,13 +82,13 @@ %files devel %doc DEPENDENCIES README TODO %license LICENSE -%{_libdir}/%{name}.so -%{_includedir}/* -%{_mandir}/man3/*.3%{?ext_man} -%{_mandir}/man7/*.7%{?ext_man} +%_libdir/%name.so +%_includedir/* +%_mandir/man3/*.3%{?ext_man} +%_mandir/man7/*.7%{?ext_man} %files -n %lname %license LICENSE -%{_libdir}/%{name}.so.* +%_libdir/%name.so.* %changelog ++++++ 1.2.2.tar.gz -> 1.3.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkeccak-1.2.2/LICENSE new/libkeccak-1.3.1/LICENSE --- old/libkeccak-1.2.2/LICENSE 2021-07-30 18:59:01.000000000 +0200 +++ new/libkeccak-1.3.1/LICENSE 2022-02-03 22:58:29.000000000 +0100 @@ -1,6 +1,6 @@ ISC License -?? 2014, 2015, 2017, 2019 Mattias Andr??e <maand...@kth.se> +?? 2014, 2015, 2017, 2019, 2021 Mattias Andr??e <maand...@kth.se> Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkeccak-1.2.2/Makefile new/libkeccak-1.3.1/Makefile --- old/libkeccak-1.2.2/Makefile 2021-07-30 18:59:01.000000000 +0200 +++ new/libkeccak-1.3.1/Makefile 2022-02-03 22:58:29.000000000 +0100 @@ -12,7 +12,7 @@ # The version of the library. LIB_MAJOR = 1 -LIB_MINOR = 2 +LIB_MINOR = 3 LIB_VERSION = $(LIB_MAJOR).$(LIB_MINOR) @@ -62,7 +62,8 @@ libkeccak_state_wipe.o\ libkeccak_state_wipe_message.o\ libkeccak_state_wipe_sponge.o\ - libkeccak_unhex.o + libkeccak_unhex.o\ + libkeccak_zerocopy_chunksize.o HDR =\ libkeccak.h\ @@ -121,7 +122,10 @@ libkeccak_state_wipe_message.3\ libkeccak_state_wipe_sponge.3\ libkeccak_unhex.3\ - libkeccak_update.3 + libkeccak_update.3\ + libkeccak_zerocopy_chunksize.3\ + libkeccak_zerocopy_digest.3\ + libkeccak_zerocopy_update.3 MAN7 =\ libkeccak.7 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkeccak-1.2.2/digest.c new/libkeccak-1.3.1/digest.c --- old/libkeccak-1.2.2/digest.c 2021-07-30 18:59:01.000000000 +0200 +++ new/libkeccak-1.3.1/digest.c 2022-02-03 22:58:29.000000000 +0100 @@ -232,51 +232,56 @@ /** - * pad 10*1 + * Right-pad message with a 10*1-pad * - * @param state The hashing state, `state->M` and `state->mptr` will be updated, - * `state->M` should have `state->r / 8` bytes left over at the end - * @param bits The number of bits in the end of the message that does not make a whole byte + * @param r Should be `state->r` where `state` is the hashing state + * @param msg The message to append padding to; should have `r / 8` + * extra bytes allocated at the end for the function to + * write the pad to + * @param msglen The length of the message to append padding to + * @param bits The number of bits in the end of the message that does not make a whole byte + * @return The length of the message after padding */ LIBKECCAK_GCC_ONLY(__attribute__((__nonnull__, __nothrow__, __gnu_inline__))) -static inline void -libkeccak_pad10star1(register struct libkeccak_state *restrict state, register size_t bits) +static inline size_t +libkeccak_pad10star1(register size_t r, unsigned char *msg, size_t msglen, register size_t bits) { - register size_t r = (size_t)(state->r); - register size_t nrf = state->mptr - !!bits; + register size_t nrf = msglen - !!bits; register size_t len = (nrf << 3) | bits; register size_t ll = len % r; - register unsigned char b = (unsigned char)(bits ? (state->M[nrf] | (1 << bits)) : 1); + register unsigned char b = (unsigned char)(bits ? (msg[nrf] | (1 << bits)) : 1); if (r - 8 <= ll && ll <= r - 2) { - state->M[nrf] = (unsigned char)(b ^ 0x80); - state->mptr = nrf + 1; + msg[nrf] = (unsigned char)(b ^ 0x80); + msglen = nrf + 1; } else { len = ++nrf << 3; len = (len - (len % r) + (r - 8)) >> 3; - state->mptr = len + 1; + msglen = len + 1; - state->M[nrf - 1] = b; - __builtin_memset(state->M + nrf, 0, (len - nrf) * sizeof(char)); - state->M[len] = (unsigned char)0x80; + msg[nrf - 1] = b; + __builtin_memset(&msg[nrf], 0, (len - nrf) * sizeof(char)); + msg[len] = (unsigned char)0x80; } + return msglen; } /** * Perform the absorption phase * - * @param state The hashing state - * @param len The number of bytes from `state->M` to absorb + * @param state The hashing state + * @param message The bytes to absorb + * @param len The number of bytes from `message` to absorb */ LIBKECCAK_GCC_ONLY(__attribute__((__nonnull__, __nothrow__))) static void -libkeccak_absorption_phase(register struct libkeccak_state *restrict state, register size_t len) +libkeccak_absorption_phase(register struct libkeccak_state *restrict state, + register const unsigned char *restrict message, register size_t len) { register long int rr = state->r >> 3; register long int ww = state->w >> 3; register long int n = (long)len / rr; - register const unsigned char *restrict message = state->M; if (__builtin_expect(ww >= 8, 1)) { /* ww > 8 is impossible, it is just for optimisation possibilities. */ while (n--) { #define X(N) state->S[N] ^= libkeccak_to_lane64(message, len, rr, (size_t)(LANE_TRANSPOSE_MAP[N] * 8)); @@ -335,6 +340,28 @@ /** * Absorb more of the message to the Keccak sponge + * without copying the data to an internal buffer + * + * It is safe run zero-copy functions before non-zero-copy + * functions for the same state, running zero-copy functions + * after non-zero-copy functions on the other hand can + * cause the message to be misread + * + * @param state The hashing state + * @param msg The partial message + * @param msglen The length of the partial message; must be a + * multiple of `libkeccak_zerocopy_chunksize(state)` + * (undefined behaviour otherwise) + */ +void +libkeccak_zerocopy_update(struct libkeccak_state *restrict state, const void *restrict msg, size_t msglen) +{ + libkeccak_absorption_phase(state, msg, msglen); +} + + +/** + * Absorb more of the message to the Keccak sponge * without wiping sensitive data when possible * * @param state The hashing state @@ -361,10 +388,10 @@ __builtin_memcpy(state->M + state->mptr, msg, msglen * sizeof(char)); state->mptr += msglen; len = state->mptr; - len -= state->mptr % (size_t)((state->r * state->b) >> 3); + len -= state->mptr % (size_t)(state->r >> 3); state->mptr -= len; - libkeccak_absorption_phase(state, len); + libkeccak_absorption_phase(state, state->M, len); __builtin_memmove(state->M, state->M + len, state->mptr * sizeof(char)); return 0; @@ -401,10 +428,10 @@ __builtin_memcpy(state->M + state->mptr, msg, msglen * sizeof(char)); state->mptr += msglen; len = state->mptr; - len -= state->mptr % (size_t)((state->r * state->b) >> 3); + len -= state->mptr % (size_t)(state->r >> 3); state->mptr -= len; - libkeccak_absorption_phase(state, len); + libkeccak_absorption_phase(state, state->M, len); __builtin_memmove(state->M, state->M + len, state->mptr * sizeof(char)); return 0; @@ -413,6 +440,72 @@ /** * Absorb the last part of the message and squeeze the Keccak sponge + * without copying the data to an internal buffer + * + * It is safe run zero-copy functions before non-zero-copy + * functions for the same state, running zero-copy functions + * after non-zero-copy functions on the other hand can + * cause the message to be misread + * + * @param state The hashing state + * @param msg_ The rest of the message; will be edited; extra memory + * shall be allocated such that `suffix` and a 10*1 pad (which + * is at least 2 bits long) can be added in a why the makes it's + * length a multiple of `libkeccak_zerocopy_chunksize(state)` + * @param msglen The length of the partial message + * @param bits The number of bits at the end of the message not covered by `msglen` + * @param suffix The suffix concatenate to the message, only '1':s and '0':s, and NUL-termination + * @param hashsum Output parameter for the hashsum, may be `NULL` + */ +void +libkeccak_zerocopy_digest(struct libkeccak_state *restrict state, void *restrict msg_, size_t msglen, + size_t bits, const char *restrict suffix, void *restrict hashsum) +{ + unsigned char *restrict msg = msg_; + auto unsigned char *restrict new; + register long int rr = state->r >> 3; + auto size_t suffix_len = suffix ? __builtin_strlen(suffix) : 0; + register size_t ext; + register long int i; + + if (!msg) { + msglen = 0; + bits = 0; + } else { + msglen += bits >> 3; + bits &= 7; + } + + if (bits) + msg[msglen] = msg[msglen] & (unsigned char)((1 << bits) - 1); + if (__builtin_expect(!!suffix_len, 1)) { + if (!bits) + msg[msglen] = 0; + while (suffix_len--) { + msg[msglen] |= (unsigned char)((*suffix++ & 1) << bits++); + if (bits == 8) { + bits = 0; + msg[++msglen] = 0; + } + } + } + if (bits) + msglen++; + + msglen = libkeccak_pad10star1((size_t)state->r, msg, msglen, bits); + libkeccak_absorption_phase(state, msg, msglen); + + if (hashsum) { + libkeccak_squeezing_phase(state, rr, (state->n + 7) >> 3, state->w >> 3, hashsum); + } else { + for (i = (state->n - 1) / state->r; i--;) + libkeccak_f(state); + } +} + + +/** + * Absorb the last part of the message and squeeze the Keccak sponge * without wiping sensitive data when possible * * @param state The hashing state @@ -473,8 +566,8 @@ if (bits) state->mptr++; - libkeccak_pad10star1(state, bits); - libkeccak_absorption_phase(state, state->mptr); + state->mptr = libkeccak_pad10star1((size_t)state->r, state->M, state->mptr, bits); + libkeccak_absorption_phase(state, state->M, state->mptr); if (hashsum) { libkeccak_squeezing_phase(state, rr, (state->n + 7) >> 3, state->w >> 3, hashsum); @@ -551,8 +644,8 @@ if (bits) state->mptr++; - libkeccak_pad10star1(state, bits); - libkeccak_absorption_phase(state, state->mptr); + state->mptr = libkeccak_pad10star1((size_t)state->r, state->M, state->mptr, bits); + libkeccak_absorption_phase(state, state->M, state->mptr); if (hashsum) { libkeccak_squeezing_phase(state, rr, (state->n + 7) >> 3, state->w >> 3, hashsum); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkeccak-1.2.2/libkeccak.7 new/libkeccak-1.3.1/libkeccak.7 --- old/libkeccak-1.2.2/libkeccak.7 2021-07-30 18:59:01.000000000 +0200 +++ new/libkeccak-1.3.1/libkeccak.7 2022-02-03 22:58:29.000000000 +0100 @@ -30,8 +30,10 @@ .BR libkeccak_state_marshal (3), .BR libkeccak_state_unmarshal (3), .BR libkeccak_fast_update (3), +.BR libkeccak_zerocopy_update (3), .BR libkeccak_update (3), .BR libkeccak_fast_digest (3), +.BR libkeccak_zerocopy_digest (3), .BR libkeccak_digest (3), .BR libkeccak_simple_squeeze (3), .BR libkeccak_fast_squeeze (3), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkeccak-1.2.2/libkeccak.h new/libkeccak-1.3.1/libkeccak.h --- old/libkeccak-1.2.2/libkeccak.h 2021-07-30 18:59:01.000000000 +0200 +++ new/libkeccak-1.3.1/libkeccak.h 2022-02-03 22:58:29.000000000 +0100 @@ -538,6 +538,38 @@ size_t libkeccak_state_unmarshal(struct libkeccak_state *restrict, const void *restrict); /** + * Get the number of bytes that are absorbed during + * one pass of the absorption phase + * + * @param state The hashing state + * @return The number of bytes absorbed during one pass + */ +LIBKECCAK_GCC_ONLY(__attribute__((__nonnull__, __nothrow__, __warn_unused_result__, __pure__))) +inline size_t +libkeccak_zerocopy_chunksize(struct libkeccak_state *restrict state) +{ + return state->r >> 3; +} + +/** + * Absorb more of the message to the Keccak sponge + * without copying the data to an internal buffer + * + * It is safe run zero-copy functions before non-zero-copy + * functions for the same state, running zero-copy functions + * after non-zero-copy functions on the other hand can + * cause the message to be misread + * + * @param state The hashing state + * @param msg The partial message + * @param msglen The length of the partial message; must be a + * multiple of `libkeccak_zerocopy_chunksize(state)` + * (undefined behaviour otherwise) + */ +LIBKECCAK_GCC_ONLY(__attribute__((__nonnull__, __nothrow__))) +void libkeccak_zerocopy_update(struct libkeccak_state *restrict, const void *restrict, size_t); + +/** * Absorb more of the message to the Keccak sponge * without wiping sensitive data when possible * @@ -561,6 +593,30 @@ LIBKECCAK_GCC_ONLY(__attribute__((__nonnull__))) int libkeccak_update(struct libkeccak_state *restrict, const void *restrict, size_t); + +/** + * Absorb the last part of the message and squeeze the Keccak sponge + * without copying the data to an internal buffer + * + * It is safe run zero-copy functions before non-zero-copy + * functions for the same state, running zero-copy functions + * after non-zero-copy functions on the other hand can + * cause the message to be misread + * + * @param state The hashing state + * @param msg The rest of the message; will be edited; extra memory + * shall be allocated such that `suffix` and a 10*1 pad (which + * is at least 2 bits long) can be added in a why the makes it's + * length a multiple of `libkeccak_zerocopy_chunksize(state)` + * @param msglen The length of the partial message + * @param bits The number of bits at the end of the message not covered by `msglen` + * @param suffix The suffix concatenate to the message, only '1':s and '0':s, and NUL-termination + * @param hashsum Output parameter for the hashsum, may be `NULL` + */ +LIBKECCAK_GCC_ONLY(__attribute__((__nonnull__(1, 2)))) +void libkeccak_zerocopy_digest(struct libkeccak_state *restrict, void *restrict, size_t, + size_t, const char *restrict, void *restrict); + /** * Absorb the last part of the message and squeeze the Keccak sponge * without wiping sensitive data when possible diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkeccak-1.2.2/libkeccak_digest.3 new/libkeccak-1.3.1/libkeccak_digest.3 --- old/libkeccak-1.2.2/libkeccak_digest.3 2021-07-30 18:59:01.000000000 +0200 +++ new/libkeccak-1.3.1/libkeccak_digest.3 2022-02-03 22:58:29.000000000 +0100 @@ -22,9 +22,10 @@ .I msglen parameter. If all of the message has already be processed by calls to the -.BR libkeccak_update (3) -function or the -.BR libkeccak_fast_update (3) +.BR libkeccak_update (3), +.BR libkeccak_fast_update (3), +or +.BR libkeccak_zerocopy_update (3) function (with the same pointer on .IR state ,) .I msg @@ -134,6 +135,7 @@ .BR libkeccak_fast_update (3), .BR libkeccak_update (3), .BR libkeccak_fast_digest (3), +.BR libkeccak_zerocopy_digest (3), .BR libkeccak_simple_squeeze (3), .BR libkeccak_fast_squeeze (3), .BR libkeccak_squeeze (3) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkeccak-1.2.2/libkeccak_fast_digest.3 new/libkeccak-1.3.1/libkeccak_fast_digest.3 --- old/libkeccak-1.2.2/libkeccak_fast_digest.3 2021-07-30 18:59:01.000000000 +0200 +++ new/libkeccak-1.3.1/libkeccak_fast_digest.3 2022-02-03 22:58:29.000000000 +0100 @@ -23,9 +23,10 @@ .I msglen parameter. If all of the message has already be processed by calls to the -.BR libkeccak_update (3) -function or the -.BR libkeccak_fast_update (3) +.BR libkeccak_update (3), +.BR libkeccak_fast_update (3), +or +.BR libkeccak_zerocopy_update (3) function (with the same pointer on .IR state ,) .I msg @@ -134,8 +135,10 @@ .SH SEE ALSO .BR libkeccak_state_initialise (3), .BR libkeccak_fast_update (3), +.BR libkeccak_zerocopy_update (3), .BR libkeccak_update (3), .BR libkeccak_digest (3), +.BR libkeccak_zerocopy_digest (3), .BR libkeccak_simple_squeeze (3), .BR libkeccak_fast_squeeze (3), .BR libkeccak_squeeze (3) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkeccak-1.2.2/libkeccak_fast_squeeze.3 new/libkeccak-1.3.1/libkeccak_fast_squeeze.3 --- old/libkeccak-1.2.2/libkeccak_fast_squeeze.3 2021-07-30 18:59:01.000000000 +0200 +++ new/libkeccak-1.3.1/libkeccak_fast_squeeze.3 2022-02-03 22:58:29.000000000 +0100 @@ -30,5 +30,6 @@ .SH SEE ALSO .BR libkeccak_digest (3), .BR libkeccak_fast_digest (3), +.BR libkeccak_zerocopy_digest (3), .BR libkeccak_simple_squeeze (3), .BR libkeccak_squeeze (3) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkeccak-1.2.2/libkeccak_fast_update.3 new/libkeccak-1.3.1/libkeccak_fast_update.3 --- old/libkeccak-1.2.2/libkeccak_fast_update.3 2021-07-30 18:59:01.000000000 +0200 +++ new/libkeccak-1.3.1/libkeccak_fast_update.3 2022-02-03 22:58:29.000000000 +0100 @@ -85,6 +85,8 @@ .fi .SH SEE ALSO .BR libkeccak_state_initialise (3), +.BR libkeccak_zerocopy_update (3), .BR libkeccak_update (3), .BR libkeccak_fast_digest (3), +.BR libkeccak_zerocopy_digest (3), .BR libkeccak_digest (3) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkeccak-1.2.2/libkeccak_generalised_sum_fd.c new/libkeccak-1.3.1/libkeccak_generalised_sum_fd.c --- old/libkeccak-1.2.2/libkeccak_generalised_sum_fd.c 2021-07-30 18:59:01.000000000 +0200 +++ new/libkeccak-1.3.1/libkeccak_generalised_sum_fd.c 2022-02-03 22:58:29.000000000 +0100 @@ -1,5 +1,6 @@ /* See LICENSE file for copyright and license details. */ #include "common.h" +#include <stdio.h> /** @@ -19,24 +20,45 @@ const char *restrict suffix, void *restrict hashsum) { ssize_t got; + size_t offset; #ifndef _WIN32 struct stat attr; #endif size_t blksize = 4096; - void *restrict chunk; + unsigned char *restrict chunk; + size_t chunksize, extrasize, extrachunks; + size_t chunks, chunkmod; if (libkeccak_state_initialise(state, spec) < 0) return -1; + chunksize = libkeccak_zerocopy_chunksize(state); + extrasize = ((suffix ? strlen(suffix) : 0) + 2 + 7) >> 3; + extrachunks = (extrasize + (chunksize - 1)) / chunksize; + #ifndef _WIN32 if (fstat(fd, &attr) == 0) if (attr.st_blksize > 0) blksize = (size_t)attr.st_blksize; #endif + chunks = blksize / chunksize; + chunkmod = blksize % chunksize; + if (chunkmod) { + blksize -= chunkmod; + blksize += chunksize; + chunks += 1; + } + if (chunks < extrachunks + 1) + blksize = (extrachunks + 1) * chunksize; + #if ALLOCA_LIMIT > 0 - if (blksize > (size_t)ALLOCA_LIMIT) + if (blksize > (size_t)ALLOCA_LIMIT) { blksize = (size_t)ALLOCA_LIMIT; + blksize -= blksize % chunksize; + if (!blksize) + blksize = chunksize; + } # if defined(__clang__) /* We are using a limit so it's just like declaring an array * in a function, except we might use less of the stack. */ @@ -53,8 +75,9 @@ return -1; #endif + offset = 0; for (;;) { - got = read(fd, chunk, blksize); + got = read(fd, &chunk[offset], blksize - offset); if (got <= 0) { if (!got) break; @@ -62,11 +85,22 @@ continue; goto fail; } - if (libkeccak_fast_update(state, chunk, (size_t)got) < 0) - goto fail; + offset += (size_t)got; + if (offset == blksize) { + libkeccak_zerocopy_update(state, chunk, blksize); + offset = 0; + } + } + + if (extrasize > blksize - offset) { + chunkmod = offset % chunksize; + libkeccak_zerocopy_update(state, chunk, offset - chunkmod); + __builtin_memcpy(chunk, &chunk[offset - chunkmod], chunkmod * sizeof(char)); + offset = chunkmod; } - return libkeccak_fast_digest(state, NULL, 0, 0, suffix, hashsum); + libkeccak_zerocopy_digest(state, chunk, offset, 0, suffix, hashsum); + return 0; fail: #if ALLOCA_LIMIT <= 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkeccak-1.2.2/libkeccak_simple_squeeze.3 new/libkeccak-1.3.1/libkeccak_simple_squeeze.3 --- old/libkeccak-1.2.2/libkeccak_simple_squeeze.3 2021-07-30 18:59:01.000000000 +0200 +++ new/libkeccak-1.3.1/libkeccak_simple_squeeze.3 2022-02-03 22:58:29.000000000 +0100 @@ -29,5 +29,6 @@ .SH SEE ALSO .BR libkeccak_digest (3), .BR libkeccak_fast_digest (3), +.BR libkeccak_zerocopy_digest (3), .BR libkeccak_fast_squeeze (3), .BR libkeccak_squeeze (3) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkeccak-1.2.2/libkeccak_squeeze.3 new/libkeccak-1.3.1/libkeccak_squeeze.3 --- old/libkeccak-1.2.2/libkeccak_squeeze.3 2021-07-30 18:59:01.000000000 +0200 +++ new/libkeccak-1.3.1/libkeccak_squeeze.3 2022-02-03 22:58:29.000000000 +0100 @@ -39,5 +39,6 @@ .SH SEE ALSO .BR libkeccak_digest (3), .BR libkeccak_fast_digest (3), +.BR libkeccak_zerocopy_digest (3), .BR libkeccak_simple_squeeze (3), .BR libkeccak_fast_squeeze (3) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkeccak-1.2.2/libkeccak_state_copy.c new/libkeccak-1.3.1/libkeccak_state_copy.c --- old/libkeccak-1.2.2/libkeccak_state_copy.c 2021-07-30 18:59:01.000000000 +0200 +++ new/libkeccak-1.3.1/libkeccak_state_copy.c 2022-02-03 22:58:29.000000000 +0100 @@ -13,9 +13,13 @@ libkeccak_state_copy(struct libkeccak_state *restrict dest, const struct libkeccak_state *restrict src) { memcpy(dest, src, sizeof(struct libkeccak_state)); - dest->M = malloc(src->mlen * sizeof(char)); - if (!dest->M) - return -1; - memcpy(dest->M, src->M, src->mptr * sizeof(char)); + if (src->mlen) { + dest->M = malloc(src->mlen * sizeof(char)); + if (!dest->M) + return -1; + memcpy(dest->M, src->M, src->mptr * sizeof(char)); + } else { + dest->M = NULL; + } return 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkeccak-1.2.2/libkeccak_state_initialise.3 new/libkeccak-1.3.1/libkeccak_state_initialise.3 --- old/libkeccak-1.2.2/libkeccak_state_initialise.3 2021-07-30 18:59:01.000000000 +0200 +++ new/libkeccak-1.3.1/libkeccak_state_initialise.3 2022-02-03 22:58:29.000000000 +0100 @@ -37,8 +37,10 @@ .BR libkeccak_state_fast_destroy (3), .BR libkeccak_state_copy (3), .BR libkeccak_fast_update (3), +.BR libkeccak_zerocopy_update (3), .BR libkeccak_update (3), .BR libkeccak_fast_digest (3), +.BR libkeccak_zerocopy_digest (3), .BR libkeccak_digest (3), .BR libkeccak_generalised_sum_fd (3), .BR libkeccak_keccaksum_fd (3), diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkeccak-1.2.2/libkeccak_state_marshal.c new/libkeccak-1.3.1/libkeccak_state_marshal.c --- old/libkeccak-1.2.2/libkeccak_state_marshal.c 2021-07-30 18:59:01.000000000 +0200 +++ new/libkeccak-1.3.1/libkeccak_state_marshal.c 2022-02-03 22:58:29.000000000 +0100 @@ -17,24 +17,30 @@ size_t libkeccak_state_marshal(const struct libkeccak_state *restrict state, void *restrict data_) { -#define set(type, var) *((type *)data) = state->var, data += sizeof(type) - unsigned char *restrict data = data_; - if (data) { - set(long int, r); - set(long int, c); - set(long int, n); - set(long int, b); - set(long int, w); - set(int64_t, wmod); - set(long int, l); - set(long int, nr); - memcpy(data, state->S, sizeof(state->S)); - data += sizeof(state->S); - set(size_t, mptr); - set(size_t, mlen); - memcpy(data, state->M, state->mptr * sizeof(char)); - data += state->mptr; +#define set(type, var) *(type *)data = state->var, data += sizeof(type) + unsigned char *restrict start = data_; + unsigned char *restrict data = start; + if (!data) { + return 7 * sizeof(long int) + + 1 * sizeof(int64_t) + + sizeof(state->S) + + 2 * sizeof(size_t) + + state->mptr; } - return sizeof(struct libkeccak_state) - sizeof(char *) + state->mptr * sizeof(char); + set(long int, r); + set(long int, c); + set(long int, n); + set(long int, b); + set(long int, w); + set(int64_t, wmod); + set(long int, l); + set(long int, nr); + memcpy(data, state->S, sizeof(state->S)); + data += sizeof(state->S); + set(size_t, mptr); + set(size_t, mlen); + memcpy(data, state->M, state->mptr * sizeof(char)); + data += state->mptr; + return (size_t)(data - start); #undef set } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkeccak-1.2.2/libkeccak_state_unmarshal.c new/libkeccak-1.3.1/libkeccak_state_unmarshal.c --- old/libkeccak-1.2.2/libkeccak_state_unmarshal.c 2021-07-30 18:59:01.000000000 +0200 +++ new/libkeccak-1.3.1/libkeccak_state_unmarshal.c 2022-02-03 22:58:29.000000000 +0100 @@ -18,11 +18,18 @@ size_t libkeccak_state_unmarshal(struct libkeccak_state *restrict state, const void *restrict data_) { -#define get(type, var) state->var = *((const type *)data), data += sizeof(type) - const unsigned char *restrict data = data_; +#define get(type, var) state->var = *(const type *)data, data += sizeof(type) + const unsigned char *restrict start = data_; + const unsigned char *restrict data = start; + size_t mptr; if (!state) { - data += (7 * sizeof(long int) + 26 * sizeof(int64_t)); - return sizeof(struct libkeccak_state) - sizeof(char *) + *(const size_t *)data * sizeof(char); + data += 7 * sizeof(long int); + data += 1 * sizeof(int64_t); + data += sizeof(state->S); + mptr = *(const size_t *)data; + data += 2 * sizeof(size_t); + data += mptr; + return (size_t)(data - start); } get(long int, r); get(long int, c); @@ -36,11 +43,15 @@ data += sizeof(state->S); get(size_t, mptr); get(size_t, mlen); - state->M = malloc(state->mptr * sizeof(char)); - if (!state->M) - return 0; - memcpy(state->M, data, state->mptr * sizeof(char)); - data += state->mptr; - return sizeof(struct libkeccak_state) - sizeof(char *) + state->mptr * sizeof(char); + if (state->mptr) { + state->M = malloc(state->mptr * sizeof(char)); + if (!state->M) + return 0; + memcpy(state->M, data, state->mptr * sizeof(char)); + data += state->mptr; + } else { + state->M = NULL; + } + return (size_t)(data - start); #undef get } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkeccak-1.2.2/libkeccak_update.3 new/libkeccak-1.3.1/libkeccak_update.3 --- old/libkeccak-1.2.2/libkeccak_update.3 2021-07-30 18:59:01.000000000 +0200 +++ new/libkeccak-1.3.1/libkeccak_update.3 2022-02-03 22:58:29.000000000 +0100 @@ -85,5 +85,7 @@ .SH SEE ALSO .BR libkeccak_state_initialise (3), .BR libkeccak_fast_update (3), +.BR libkeccak_zerocopy_update (3), .BR libkeccak_fast_digest (3), +.BR libkeccak_zerocopy_digest (3), .BR libkeccak_digest (3) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkeccak-1.2.2/libkeccak_zerocopy_chunksize.3 new/libkeccak-1.3.1/libkeccak_zerocopy_chunksize.3 --- old/libkeccak-1.2.2/libkeccak_zerocopy_chunksize.3 1970-01-01 01:00:00.000000000 +0100 +++ new/libkeccak-1.3.1/libkeccak_zerocopy_chunksize.3 2022-02-03 22:58:29.000000000 +0100 @@ -0,0 +1,40 @@ +.TH LIBKECCAK_ZEROCOPY_CHUNKSIZE 3 LIBKECCAK +.SH NAME +libkeccak_zerocopy_chunksize - Get chunk size for zero-copy processing +.RB ( ADVANCED ) +.SH SYNOPSIS +.nf +#include <libkeccak.h> + +size_t libkeccak_zerocopy_chunksize(struct libkeccak_state *\fIstate\fP); +.fi +.PP +Link with +.IR -lkeccak . +.SH DESCRIPTION +The +.BR libkeccak_zerocopy_chunksize () +function returns the number of bytes the sponge +in the +.I state +parameter processes per round. Input to the +.BR libkeccak_zerocopy_update (3) +function must be an integer multiple of this +number, and memory allocated for the +.BR libkeccak_zerocopy_digest (3) +function must also be a multiple of this +number (further restrictions apply, see +.BR libkeccak_zerocopy_digest (3) +for more details.) +.SH RETURN VALUES +The +.BR libkeccak_zerocopy_chunksize () +function returns the number of bytes that +the sponge processes per processing round. +.SH ERRORS +The +.BR libkeccak_zerocopy_chunksize () +function cannot fail. +.SH SEE ALSO +.BR libkeccak_zerocopy_update (3), +.BR libkeccak_zerocopy_digest (3) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkeccak-1.2.2/libkeccak_zerocopy_chunksize.c new/libkeccak-1.3.1/libkeccak_zerocopy_chunksize.c --- old/libkeccak-1.2.2/libkeccak_zerocopy_chunksize.c 1970-01-01 01:00:00.000000000 +0100 +++ new/libkeccak-1.3.1/libkeccak_zerocopy_chunksize.c 2022-02-03 22:58:29.000000000 +0100 @@ -0,0 +1,5 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + + +extern inline size_t libkeccak_zerocopy_chunksize(struct libkeccak_state *restrict); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkeccak-1.2.2/libkeccak_zerocopy_digest.3 new/libkeccak-1.3.1/libkeccak_zerocopy_digest.3 --- old/libkeccak-1.2.2/libkeccak_zerocopy_digest.3 1970-01-01 01:00:00.000000000 +0100 +++ new/libkeccak-1.3.1/libkeccak_zerocopy_digest.3 2022-02-03 22:58:29.000000000 +0100 @@ -0,0 +1,120 @@ +.TH LIBKECCAK_ZEROCOPY_DIGEST 3 LIBKECCAK +.SH NAME +libkeccak_zerocopy_digest - Complete the hashing of a message without copying +.RB ( ADVANCED ) +.SH SYNOPSIS +.LP +.nf +#include <libkeccak.h> + +void libkeccak_zerocopy_digest(struct libkeccak_state *\fIstate\fP, void *\fImsg\fP, size_t \fImsglen\fP, + size_t \fIbits\fP, const char *\fIsuffix\fP, void *\fIhashsum\fP); +.fi +.P +Link with +.IR -lkeccak . +.SH DESCRIPTION +The +.BR libkeccak_zerocopy_digest () +function absorbs the last part of (or all of) a message, +and returns the hash of the entire message. The last part +of the message is specified by the +.I msg +parameter, and its byte-size is specified by the +.I msglen +parameter. If all of the message has already be processed +by calls to the +.BR libkeccak_zerocopy_update (3) +function (with the same pointer on +.IR state ,) +.I msg +and +.I msglen +should be set to +.I NULL +and 0, respectively. +.PP +If the message is not comprised a whole number of bytes, +the number of bits, modulus 8, in the message should be +specified in the +.I bits +parameter. +.I msglen +must only count the number of whole bytes, that is, the +floor of the number of bits in the message divided by 8. +.PP +.I suffix +should be a NUL-terminated string of ASCII '1':s and '0':s, +representing the bits that should be appended to the +message. If this string is empty, +.I NULL +may be used instead. This is used to select hash algorithm. +For pure Keccak, +.I NULL +or \(dq\(dq is used. For the other algorithms the constants +.B LIBKECCAK_SHA3_SUFFIX +(for SHA-3), +.B LIBKECCAK_RAWSHAKE_SUFFIX +(for RawSHAKE), and +.B LIBKECCAK_SHAKE_SUFFIX +(for SHAKE) are used. +.PP +The hash of the message will be stored to +.IR hashsum , +unless +.IR hashsum +is +.IR NULL +(which increases the performance of the call.) A total of +.RI (( state->n ++ 7) / 8) bytes will be written to the beginning of +.IR hashsum . +Therefore, +.I hashsum +needs at least an allocation size of that number of bytes. +.PP +.BR libkeccak_zerocopy_digest () +will write at and beyond +.IR &msg[msglen] . +The caller must make sure that enough memory is allocated +for the +.I suffix +as well as padding of at least 2 bits, for +.IR msg . +The sum of +.IR msglen , +the bits specified in +.IR suffix , +and the padded, shall, in bytes, be an integer multiple of +the bitrate divided by eight, which is returned by the +.BR libkeccak_zerocopy_chunksize (3) +function. +.SH RETURN VALUES +The +.BR libkeccak_zerocopy_digest () +function does not return a value. +.SH ERRORS +The +.BR libkeccak_zerocopy_digest () +function cannot fail. +.SH NOTES +Calling the +.BR libkeccak_zerocopy_digest (3) +function after the +.BR libkeccak_update (3) +or +.BR libkeccak_fast_update (3) +functions, with the same +.I state +argument, may cause the message to be misread. +.SH SEE ALSO +.BR libkeccak_state_initialise (3), +.BR libkeccak_zerocopy_chunksize (3), +.BR libkeccak_fast_update (3), +.BR libkeccak_zerocopy_update (3), +.BR libkeccak_update (3), +.BR libkeccak_digest (3), +.BR libkeccak_zerocopy_digest (3), +.BR libkeccak_simple_squeeze (3), +.BR libkeccak_fast_squeeze (3), +.BR libkeccak_squeeze (3) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libkeccak-1.2.2/libkeccak_zerocopy_update.3 new/libkeccak-1.3.1/libkeccak_zerocopy_update.3 --- old/libkeccak-1.2.2/libkeccak_zerocopy_update.3 1970-01-01 01:00:00.000000000 +0100 +++ new/libkeccak-1.3.1/libkeccak_zerocopy_update.3 2022-02-03 22:58:29.000000000 +0100 @@ -0,0 +1,80 @@ +.TH LIBKECCAK_ZEROCOPY_UPDATE 3 LIBKECCAK +.SH NAME +libkeccak_zerocopy_update - Partially hash a message without copying +.RB ( ADVANCED ) +.SH SYNOPSIS +.nf +#include <libkeccak.h> + +void libkeccak_zerocopy_update(struct libkeccak_state *\fIstate\fP, const void *\fImsg\fP, size_t \fImsglen\fP); +.fi +.PP +Link with +.IR -lkeccak . +.SH DESCRIPTION +The +.BR libkeccak_zerocopy_update () +function continues (or starts) hashing a message. +The current state of the hashing is stored in +.IR *state , +and will be updated. The message specified by the +.I msg +parameter with the byte-size specified by the +.I msglen +parameter, will be hashed. +.PP +As a restriction specific to the +.BR libkeccak_zerocopy_update () +function, the +.I msglen +argument must be an integer multiple of the bitrate +divided by eight. This is returned by the +.BR libkeccak_zerocopy_chunksize (3) +function. The +.BR libkeccak_update (3) +or +.BR libkeccak_fast_update (3) +functions can be used to avoid this restriction, +but these, unlike the +.BR libkeccak_zerocopy_update () +function, will copy the message and move around +copied data. +.SH RETURN VALUES +The +.BR libkeccak_zerocopy_update () +function does not return a value. +.SH ERRORS +The +.BR libkeccak_zerocopy_update () +function cannot fail. +.SH NOTES +Neither parameter by be +.I NULL +or 0. +.PP +It is safe call the +.BR libkeccak_zerocopy_update () +function before the +.BR libkeccak_update (3), +.BR libkeccak_fast_update (3) +.BR libkeccak_digest (3) +and +.BR libkeccak_fast_digest (3) +functions with the same +.I state +argument. However, calling the +.BR libkeccak_zerocopy_update () +function after the +.BR libkeccak_update (3) +or +.BR libkeccak_fast_update (3) +functions may cause the message +to be misread. +.SH SEE ALSO +.BR libkeccak_state_initialise (3), +.BR libkeccak_zerocopy_chunksize (3), +.BR libkeccak_fast_update (3), +.BR libkeccak_update (3), +.BR libkeccak_fast_digest (3), +.BR libkeccak_zerocopy_digest (3), +.BR libkeccak_digest (3)