From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: 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 97D4115808B for ; Sat, 5 Oct 2024 04:15:26 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id B8B87E29E0; Sat, 5 Oct 2024 04:15:25 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [IPv6:2001:470:ea4a:1:5054:ff:fec7:86e4]) (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 9B5E2E29E0 for ; 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 DFEB1340813 for ; Sat, 5 Oct 2024 04:15:24 +0000 (UTC) Received: from localhost.localdomain (localhost [IPv6:::1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id EA6F32215 for ; Sat, 5 Oct 2024 04:15:21 +0000 (UTC) From: "Sam James" 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" Message-ID: <1723911396.977cdf1ba863e599abcf2cc80cbd719cb3b0f67e.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: 977cdf1ba863e599abcf2cc80cbd719cb3b0f67e X-VCS-Branch: master Date: Sat, 5 Oct 2024 04:15:21 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Auto-Response-Suppress: DR, RN, NRN, OOF, AutoReply X-Archives-Salt: 7abdbba0-6135-4c9d-bcbc-82c88ef658bb X-Archives-Hash: a6112b58fbe03cd99bbee819b58ce305 commit: 977cdf1ba863e599abcf2cc80cbd719cb3b0f67e Author: Kerin Millar plushkava net> AuthorDate: Mon Aug 12 10:19:10 2024 +0000 Commit: Sam James gentoo org> CommitDate: Sat Aug 17 16:16:36 2024 +0000 URL: https://gitweb.gentoo.org/proj/gentoo-functions.git/commit/?id=977cdf1b Use an entropy pool for the mksh-targeting srandom() implementation The slowest of the the three srandom() implementations is presently selected for shells that overflow numbers at the 2^31 mark. A prominent shell which does so is mksh (even for LP64 architectures). Recently, one of the other srandom() implementations was accelerated by having the shell maintain its own entropy pool of up to 512 hex digits in size. Make it so that the mksh-targeting implementation employs a similar technique. Consider the following benchmark. i=0; while [ $((i += 1)) -le 30000 ]; do srandom; done >/dev/null As conducted with mksh 59c on a system with a 2nd generation Intel Xeon, I obtained the following figures. BEFORE real 0m56.414s user 0m47.043s sys 0m24.751s AFTER real 0m28.900s user 0m22.795s sys 0m6.802s Note that the performance increase cannot be applied in all situations. For further details regarding the constraints, refer to commit 866af9c. Signed-off-by: Kerin Millar plushkava.net> functions.sh | 71 ++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 26 deletions(-) diff --git a/functions.sh b/functions.sh index 406fe7f..454c62d 100644 --- a/functions.sh +++ b/functions.sh @@ -581,30 +581,43 @@ 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, use awk to generate a - # number that is immediately within range. + # 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. + + genfun_int32_pat='[0-7][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]]' + unset -v genfun_entropy + srandom() { - local hex + local hex i slice - hex=$( - export LC_ALL=C - od -vAn -N256 -tx1 /dev/urandom | awk ' - { - gsub(/[[:space:]]/, "") - hex = hex $0 - } - END { - if (match(hex, /[0-7][[:xdigit:]]{7}/)) { - print substr(hex, RSTART, RLENGTH) - } else { - exit 1 - } - } - ' - ) && + # If the shell is understood to have potentially forked + # itself then collect fresh entropy from the outset. + if ! _update_pid || [ "$$" != "${genfun_pid}" ]; then + _collect_entropy + fi + + for i in 1 2; do + # shellcheck disable=2295 + slice=${genfun_entropy%${genfun_int32_pat}*} + if [ "${#slice}" -ne "${#genfun_entropy}" ]; then + hex=${genfun_entropy#"$slice"} + genfun_entropy=${genfun_entropy%"$hex"} + while [ "${#hex}" -gt 8 ]; do + hex=${hex%?} + done + break + elif [ "$i" -eq 1 ]; then + # The pool is too small to contain a + # suitable sequence. Refill then try + # again. + _collect_entropy + else + false + fi + done && printf '%d\n' "0x${hex}" } elif [ -c /dev/urandom ]; then @@ -614,8 +627,8 @@ srandom() { local hex - # If the shell has forked itself, collect 4 bytes worth - # of entropy. + # If the shell is understood to have potentially forked + # itself then collect 4 bytes worth of entropy. if ! _update_pid || [ "$$" != "${genfun_pid}" ]; then hex=$(LC_ALL=C od -vAn -N4 -tx1 /dev/urandom | tr -d '[:space:]') test "${#hex}" -eq 8 && printf '%d\n' "$(( 0x${hex} >> 1 ))" @@ -626,9 +639,7 @@ srandom() # maintains an entropy pool of up to 512 hex digits in # size. if [ "${#genfun_entropy}" -lt 8 ]; then - genfun_entropy=$( - LC_ALL=C od -vAn -N256 -tx1 /dev/urandom | tr -d '[:space:]' - ) + _collect_entropy fi if [ "${#genfun_entropy}" -lt 8 ]; then false @@ -787,6 +798,14 @@ 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. +# +_collect_entropy() { + genfun_entropy=$(LC_ALL=C od -vAn -N256 -tx1 /dev/urandom | tr -d '[:space:]') +} + # # Determines whether the terminal is a dumb one. #