Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1gcedd-0004G5-7Z for pgsql-hackers@arkaria.postgresql.org; Thu, 27 Dec 2018 23:00:25 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1gcedb-0004DH-Vb for pgsql-hackers@arkaria.postgresql.org; Thu, 27 Dec 2018 23:00:23 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1gcedb-0004CF-Ht for pgsql-hackers@lists.postgresql.org; Thu, 27 Dec 2018 23:00:23 +0000 Received: from sss.pgh.pa.us ([66.207.139.130]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1gcedY-00019e-5i for pgsql-hackers@postgresql.org; Thu, 27 Dec 2018 23:00:22 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.14.4/8.14.4) with ESMTP id wBRN02Cb017236; Thu, 27 Dec 2018 18:00:03 -0500 From: Tom Lane To: Fabien COELHO cc: Alvaro Herrera , Adrien Nayrat , Thomas Munro , Dmitry Dolgov <9erthalion6@gmail.com>, Tomas Vondra , vik.fearing@2ndquadrant.com, Robert Haas , Michael Paquier , David Rowley , Pg Hackers Subject: Re: random() (was Re: New GUC to sample log queries) In-reply-to: References: <20181129214850.kiq6mvofsgplqjdr@alvherre.pgsql> <3859.1545849900@sss.pgh.pa.us> Comments: In-reply-to Fabien COELHO message dated "Thu, 27 Dec 2018 09:36:32 +0100" MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <17234.1545951602.1@sss.pgh.pa.us> Date: Thu, 27 Dec 2018 18:00:02 -0500 Message-ID: <17235.1545951602@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk Fabien COELHO writes: >> Another idea, which would be a lot less prone to breakage by >> add-on code, is to change drandom() and setseed() to themselves >> use pg_erand48() with a private seed. > The pg_erand48 code looks like crumbs from the 70's optimized for 16 bits > architectures (which it is probably not, but why not going to 64 bits or > 128 bits directly looks like a missed opportunity), its internal state is > 48 bits as its name implies, and its period probably around 2**48, which > is 2**12 better than the previous case, not an extraordinary achievement. I can't get terribly excited about rewriting that code. You're arguing from a "one size should fit all" perspective, which is exactly not the design approach we're using. We've already converted security-sensitive PRNG uses to use pg_strong_random (or if we haven't, that's a localized bug in any such places we missed). What remains are places where we are not so concerned about cryptographic strength but rather speed. It does behoove us to ensure that the seed values are unpredictable and that a user-controllable seed isn't used for internal operations, but I don't feel a need for replacing the algorithm. You might argue that the SQL function drandom should be held to a higher standard, but we document exactly this same tradeoff for it. Users who want cryptographic strength are directed to pgcrypto, leaving the audience for drandom being people who want speed. I do notice a couple of things that could be improved about erand48.c: 1. The _rand48_mult and _rand48_add values are constants, but probably few compilers would notice that, given that they're assigned to in pg_srand48. I think we should replace the references to those variables with direct uses of the macros for their values, to save a few cycles in _dorand48. 2. There seems to be a bug in pg_jrand48 (which is relatively new, added in fe0a0b599, without bothering to update the header comment). Per POSIX, The mrand48() and jrand48() functions return signed long integers uniformly distributed over the interval [-2^31, 2^31). However, if "long" is 64 bits what you're actually going to get is unsigned values ranging up to 2^32-1. This doesn't matter to existing callers because they coerce the value to int32 or uint32, but it's going to bite somebody eventually. regards, tom lane