From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: <gentoo-commits+bounces-1676237-garchives=archives.gentoo.org@lists.gentoo.org> Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id 1214C15808B for <garchives@archives.gentoo.org>; Sat, 5 Oct 2024 04:15:27 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 3C9C7E29E4; Sat, 5 Oct 2024 04:15:26 +0000 (UTC) Received: from smtp.gentoo.org (woodpecker.gentoo.org [140.211.166.183]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id E534AE29E4 for <gentoo-commits@lists.gentoo.org>; Sat, 5 Oct 2024 04:15:25 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 09298340C42 for <gentoo-commits@lists.gentoo.org>; Sat, 5 Oct 2024 04:15:25 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 1D72C22D7 for <gentoo-commits@lists.gentoo.org>; Sat, 5 Oct 2024 04:15:22 +0000 (UTC) From: "Sam James" <sam@gentoo.org> To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Sam James" <sam@gentoo.org> Message-ID: <1724243779.b51db5ffb23808dcddf93bdbdfaf3a5ee0e391cc.sam@gentoo> Subject: [gentoo-commits] proj/gentoo-functions:master commit in: / X-VCS-Repository: proj/gentoo-functions X-VCS-Files: functions.sh X-VCS-Directories: / X-VCS-Committer: sam X-VCS-Committer-Name: Sam James X-VCS-Revision: b51db5ffb23808dcddf93bdbdfaf3a5ee0e391cc X-VCS-Branch: master Date: Sat, 5 Oct 2024 04:15:22 +0000 (UTC) Precedence: bulk List-Post: <mailto:gentoo-commits@lists.gentoo.org> List-Help: <mailto:gentoo-commits+help@lists.gentoo.org> List-Unsubscribe: <mailto:gentoo-commits+unsubscribe@lists.gentoo.org> List-Subscribe: <mailto:gentoo-commits+subscribe@lists.gentoo.org> List-Id: Gentoo Linux mail <gentoo-commits.gentoo.org> X-BeenThere: gentoo-commits@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Archives-Salt: 0d74e058-4390-4a66-aa7a-93107c1c80ac X-Archives-Hash: a6052ce8b74ba627a6d58e321e29e87b commit: b51db5ffb23808dcddf93bdbdfaf3a5ee0e391cc Author: Kerin Millar <kfm <AT> plushkava <DOT> net> AuthorDate: Tue Aug 13 02:08:59 2024 +0000 Commit: Sam James <sam <AT> gentoo <DOT> org> CommitDate: Wed Aug 21 12:36:19 2024 +0000 URL: https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=b51db5ff Reduce the two non-bash srandom() implementations to just one The implementation of srandom() that was written with mksh first and foremost in mind is no longer as slow as it was. I decided to benchmark 30,000 iterations of both of the non-bash implementations with varying maximal pool sizes. The results are beneath. Note that both "dash/1" and "mksh/1" refer to the mksh-targeting implementation. Pool Size dash/1 dash/2 mksh/1 48 B 6.67s 5.57s 58.84s 64 B 5.39s 4.78s 58.20s 96 B 5.49s 4.36s 58.13s 128 B 5.87s 4.63s 59.94s 160 B 5.93s 5.46s 64.64s These figures demonstrate that the optimal pool size is roughly between 64 and 96 bytes, and that the performance of both implementations is now comparable. In addition to testing Linux (6.6) on x86_64 hardware, I experimented with the pool size on macOS Sonoma (using an Apple M1 CPU) and found a value of 64 to be close to optimal. In view of these findings, have _collect_entropy() collect 64 bytes at a time and remove the marginally faster implementation. That is, the one that depended on being able to perform arithmetic on a number as high as 2^32-1 without overflowing. Additionally, increase the maximum number of times that the remaining implementation tries to find a suitable sequence of hex digits from 2 to 3. Finally, remove the overflow check, for it is no longer required. Signed-off-by: Kerin Millar <kfm <AT> plushkava.net> functions.sh | 53 ++++++++++++----------------------------------------- 1 file changed, 12 insertions(+), 41 deletions(-) diff --git a/functions.sh b/functions.sh index 4598c5b..37ac8c2 100644 --- a/functions.sh +++ b/functions.sh @@ -580,12 +580,9 @@ srandom() { printf '%d\n' "$(( SRANDOM >> 1 ))" } - elif [ -c /dev/urandom ] && [ "$(( 1 << 31 == -2147483648 ))" -eq 1 ]; then - # The shell implements integers as signed int rather than - # signed long, contrary to the specification. Therefore, bit - # shifting cannot be a viable strategy. Instead, try to discern - # a suitably constrained sequence of 8 hex digits. - + elif [ -c /dev/urandom ]; then + # Employ a method which entails searching for 8 consecutive hex + # digits, where the first is between 0 and 7. genfun_int32_pat='[0-7][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]]' unset -v genfun_entropy @@ -594,7 +591,7 @@ srandom() local hex i slice # If the shell has forked, or if it cannot be determined - # whether it has done so, repopulate the pool with 256 + # whether it has done so, populate the pool with 64 # bytes worth of fresh entropy. if ! _update_pid; then _collect_entropy @@ -603,7 +600,7 @@ srandom() eval "genfun_pool_${genfun_pid}=1" fi || return - for i in 1 2; do + for i in 1 2 3; do # shellcheck disable=2295 slice=${genfun_entropy%${genfun_int32_pat}*} if [ "${#slice}" -ne "${#genfun_entropy}" ]; then @@ -613,10 +610,9 @@ srandom() hex=${hex%?} done break - elif [ "$i" -eq 1 ]; then - # The pool is too small to contain a - # suitable sequence. Refill then try - # again. + elif [ "$i" -lt 3 ]; then + # The pool does not contain a suitable + # sequence. Refill it then try again. _collect_entropy else false @@ -624,31 +620,6 @@ srandom() done && printf '%d\n' "0x${hex}" } - elif [ -c /dev/urandom ]; then - unset -v genfun_entropy - - srandom() - { - local hex - - if ! _update_pid; then - # It cannot be determined whether the shell has - # forked. Generate a number from 4 bytes worth - # of fresh entropy. - hex=$(LC_ALL=C od -vAn -N4 -tx1 /dev/urandom | tr -d '[:space:]') - test "${#hex}" -eq 8 && printf '%d\n' "$(( 0x${hex} >> 1 ))" - return - elif [ "${#genfun_entropy}" -lt 8 ] || ! eval "test \"\${genfun_pool_${genfun_pid}+set}\""; then - # Either the pool is too small or the shell has - # forked. Repopulate the pool with 256 bytes - # worth of fresh entropy. - _collect_entropy || return - eval "genfun_pool_${genfun_pid}=1" - fi - hex=${genfun_entropy} - genfun_entropy=${genfun_entropy%????????} - printf '%d\n' "$(( 0x${hex#"$genfun_entropy"} >> 1 ))" - } else warn "srandom: /dev/urandom doesn't exist as a character device" return 1 @@ -799,12 +770,12 @@ whenceforth() #------------------------------------------------------------------------------# # -# Collects 256 bytes worth of entropy from /dev/urandom and assigns it to the -# genfun_entropy variable in the form of 512 hex digits. +# Collects 64 bytes worth of entropy from /dev/urandom and assigns it to the +# genfun_entropy variable in the form of 128 hex digits. # _collect_entropy() { - genfun_entropy=$(LC_ALL=C od -vAn -N256 -tx1 /dev/urandom | tr -d '[:space:]') - test "${#genfun_entropy}" -eq 512 + genfun_entropy=$(LC_ALL=C od -vAn -N64 -tx1 /dev/urandom | tr -d '[:space:]') + test "${#genfun_entropy}" -eq 128 } #