[PATCH] pgcrypto: implement gen_random_uuid

Started by Oskari Saarenmaaabout 12 years ago5 messages
1 attachment(s)

The only useful feature of the uuid-ossp module in my opinion is the
uuid_generate_v4 function and as uuid-ossp is more or less abandonware
people have had trouble building and installing it. This patch
implements an alternative uuid v4 generation function in pgcrypto which
could be moved to core once there's a core PRNG with large enough
internal state.

On my test system it took 3796 msec to generate a million UUIDs with
pgcrypto while uuid-ossp took 20375 msec.

https://github.com/saaros/postgres/compare/pgcrypto-uuid-v4

contrib/pgcrypto/Makefile | 2 +-
contrib/pgcrypto/pgcrypto--1.0--1.1.sql | 8 ++++++++
contrib/pgcrypto/{pgcrypto--1.0.sql => pgcrypto--1.1.sql} | 7 ++++++-
contrib/pgcrypto/pgcrypto.c | 22
++++++++++++++++++++++
contrib/pgcrypto/pgcrypto.control | 2 +-
contrib/pgcrypto/pgcrypto.h | 1 +
doc/src/sgml/pgcrypto.sgml | 11 +++++++++++

/ Oskari

Attachments:

0001-pgcrypto-implement-gen_random_uuid.patchtext/x-patch; name=0001-pgcrypto-implement-gen_random_uuid.patchDownload
>From 522fef9c3739d4c4f3c107e574e84db67a0c07a2 Mon Sep 17 00:00:00 2001
From: Oskari Saarenmaa <os@ohmu.fi>
Date: Thu, 9 Jan 2014 22:24:36 +0200
Subject: [PATCH] pgcrypto: implement gen_random_uuid

---
 contrib/pgcrypto/Makefile               |   2 +-
 contrib/pgcrypto/pgcrypto--1.0--1.1.sql |   8 ++
 contrib/pgcrypto/pgcrypto--1.0.sql      | 202 -------------------------------
 contrib/pgcrypto/pgcrypto--1.1.sql      | 207 ++++++++++++++++++++++++++++++++
 contrib/pgcrypto/pgcrypto.c             |  22 ++++
 contrib/pgcrypto/pgcrypto.control       |   2 +-
 contrib/pgcrypto/pgcrypto.h             |   1 +
 doc/src/sgml/pgcrypto.sgml              |  11 ++
 8 files changed, 251 insertions(+), 204 deletions(-)
 create mode 100644 contrib/pgcrypto/pgcrypto--1.0--1.1.sql
 delete mode 100644 contrib/pgcrypto/pgcrypto--1.0.sql
 create mode 100644 contrib/pgcrypto/pgcrypto--1.1.sql

diff --git a/contrib/pgcrypto/Makefile b/contrib/pgcrypto/Makefile
index dadec95..1c85c98 100644
--- a/contrib/pgcrypto/Makefile
+++ b/contrib/pgcrypto/Makefile
@@ -26,7 +26,7 @@ MODULE_big	= pgcrypto
 OBJS		= $(SRCS:.c=.o)
 
 EXTENSION = pgcrypto
-DATA = pgcrypto--1.0.sql pgcrypto--unpackaged--1.0.sql
+DATA = pgcrypto--1.1.sql pgcrypto--1.0--1.1.sql pgcrypto--unpackaged--1.0.sql
 
 REGRESS = init md5 sha1 hmac-md5 hmac-sha1 blowfish rijndael \
 	$(CF_TESTS) \
diff --git a/contrib/pgcrypto/pgcrypto--1.0--1.1.sql b/contrib/pgcrypto/pgcrypto--1.0--1.1.sql
new file mode 100644
index 0000000..2601669
--- /dev/null
+++ b/contrib/pgcrypto/pgcrypto--1.0--1.1.sql
@@ -0,0 +1,8 @@
+/* contrib/pgcrypto/pgcrypto--1.0--1.1.sql */
+
+\echo Use "ALTER EXTENSION pgcrypto UPDATE" to load this file. \quit
+
+CREATE FUNCTION gen_random_uuid()
+RETURNS uuid
+AS 'MODULE_PATHNAME', 'pg_random_uuid'
+LANGUAGE C VOLATILE;
diff --git a/contrib/pgcrypto/pgcrypto--1.0.sql b/contrib/pgcrypto/pgcrypto--1.0.sql
deleted file mode 100644
index 347825e..0000000
--- a/contrib/pgcrypto/pgcrypto--1.0.sql
+++ /dev/null
@@ -1,202 +0,0 @@
-/* contrib/pgcrypto/pgcrypto--1.0.sql */
-
--- complain if script is sourced in psql, rather than via CREATE EXTENSION
-\echo Use "CREATE EXTENSION pgcrypto" to load this file. \quit
-
-CREATE FUNCTION digest(text, text)
-RETURNS bytea
-AS 'MODULE_PATHNAME', 'pg_digest'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION digest(bytea, text)
-RETURNS bytea
-AS 'MODULE_PATHNAME', 'pg_digest'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION hmac(text, text, text)
-RETURNS bytea
-AS 'MODULE_PATHNAME', 'pg_hmac'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION hmac(bytea, bytea, text)
-RETURNS bytea
-AS 'MODULE_PATHNAME', 'pg_hmac'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION crypt(text, text)
-RETURNS text
-AS 'MODULE_PATHNAME', 'pg_crypt'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gen_salt(text)
-RETURNS text
-AS 'MODULE_PATHNAME', 'pg_gen_salt'
-LANGUAGE C VOLATILE STRICT;
-
-CREATE FUNCTION gen_salt(text, int4)
-RETURNS text
-AS 'MODULE_PATHNAME', 'pg_gen_salt_rounds'
-LANGUAGE C VOLATILE STRICT;
-
-CREATE FUNCTION encrypt(bytea, bytea, text)
-RETURNS bytea
-AS 'MODULE_PATHNAME', 'pg_encrypt'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION decrypt(bytea, bytea, text)
-RETURNS bytea
-AS 'MODULE_PATHNAME', 'pg_decrypt'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION encrypt_iv(bytea, bytea, bytea, text)
-RETURNS bytea
-AS 'MODULE_PATHNAME', 'pg_encrypt_iv'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION decrypt_iv(bytea, bytea, bytea, text)
-RETURNS bytea
-AS 'MODULE_PATHNAME', 'pg_decrypt_iv'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION gen_random_bytes(int4)
-RETURNS bytea
-AS 'MODULE_PATHNAME', 'pg_random_bytes'
-LANGUAGE C VOLATILE STRICT;
-
---
--- pgp_sym_encrypt(data, key)
---
-CREATE FUNCTION pgp_sym_encrypt(text, text)
-RETURNS bytea
-AS 'MODULE_PATHNAME', 'pgp_sym_encrypt_text'
-LANGUAGE C STRICT;
-
-CREATE FUNCTION pgp_sym_encrypt_bytea(bytea, text)
-RETURNS bytea
-AS 'MODULE_PATHNAME', 'pgp_sym_encrypt_bytea'
-LANGUAGE C STRICT;
-
---
--- pgp_sym_encrypt(data, key, args)
---
-CREATE FUNCTION pgp_sym_encrypt(text, text, text)
-RETURNS bytea
-AS 'MODULE_PATHNAME', 'pgp_sym_encrypt_text'
-LANGUAGE C STRICT;
-
-CREATE FUNCTION pgp_sym_encrypt_bytea(bytea, text, text)
-RETURNS bytea
-AS 'MODULE_PATHNAME', 'pgp_sym_encrypt_bytea'
-LANGUAGE C STRICT;
-
---
--- pgp_sym_decrypt(data, key)
---
-CREATE FUNCTION pgp_sym_decrypt(bytea, text)
-RETURNS text
-AS 'MODULE_PATHNAME', 'pgp_sym_decrypt_text'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION pgp_sym_decrypt_bytea(bytea, text)
-RETURNS bytea
-AS 'MODULE_PATHNAME', 'pgp_sym_decrypt_bytea'
-LANGUAGE C IMMUTABLE STRICT;
-
---
--- pgp_sym_decrypt(data, key, args)
---
-CREATE FUNCTION pgp_sym_decrypt(bytea, text, text)
-RETURNS text
-AS 'MODULE_PATHNAME', 'pgp_sym_decrypt_text'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION pgp_sym_decrypt_bytea(bytea, text, text)
-RETURNS bytea
-AS 'MODULE_PATHNAME', 'pgp_sym_decrypt_bytea'
-LANGUAGE C IMMUTABLE STRICT;
-
---
--- pgp_pub_encrypt(data, key)
---
-CREATE FUNCTION pgp_pub_encrypt(text, bytea)
-RETURNS bytea
-AS 'MODULE_PATHNAME', 'pgp_pub_encrypt_text'
-LANGUAGE C STRICT;
-
-CREATE FUNCTION pgp_pub_encrypt_bytea(bytea, bytea)
-RETURNS bytea
-AS 'MODULE_PATHNAME', 'pgp_pub_encrypt_bytea'
-LANGUAGE C STRICT;
-
---
--- pgp_pub_encrypt(data, key, args)
---
-CREATE FUNCTION pgp_pub_encrypt(text, bytea, text)
-RETURNS bytea
-AS 'MODULE_PATHNAME', 'pgp_pub_encrypt_text'
-LANGUAGE C STRICT;
-
-CREATE FUNCTION pgp_pub_encrypt_bytea(bytea, bytea, text)
-RETURNS bytea
-AS 'MODULE_PATHNAME', 'pgp_pub_encrypt_bytea'
-LANGUAGE C STRICT;
-
---
--- pgp_pub_decrypt(data, key)
---
-CREATE FUNCTION pgp_pub_decrypt(bytea, bytea)
-RETURNS text
-AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_text'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION pgp_pub_decrypt_bytea(bytea, bytea)
-RETURNS bytea
-AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_bytea'
-LANGUAGE C IMMUTABLE STRICT;
-
---
--- pgp_pub_decrypt(data, key, psw)
---
-CREATE FUNCTION pgp_pub_decrypt(bytea, bytea, text)
-RETURNS text
-AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_text'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION pgp_pub_decrypt_bytea(bytea, bytea, text)
-RETURNS bytea
-AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_bytea'
-LANGUAGE C IMMUTABLE STRICT;
-
---
--- pgp_pub_decrypt(data, key, psw, arg)
---
-CREATE FUNCTION pgp_pub_decrypt(bytea, bytea, text, text)
-RETURNS text
-AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_text'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION pgp_pub_decrypt_bytea(bytea, bytea, text, text)
-RETURNS bytea
-AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_bytea'
-LANGUAGE C IMMUTABLE STRICT;
-
---
--- PGP key ID
---
-CREATE FUNCTION pgp_key_id(bytea)
-RETURNS text
-AS 'MODULE_PATHNAME', 'pgp_key_id_w'
-LANGUAGE C IMMUTABLE STRICT;
-
---
--- pgp armor
---
-CREATE FUNCTION armor(bytea)
-RETURNS text
-AS 'MODULE_PATHNAME', 'pg_armor'
-LANGUAGE C IMMUTABLE STRICT;
-
-CREATE FUNCTION dearmor(text)
-RETURNS bytea
-AS 'MODULE_PATHNAME', 'pg_dearmor'
-LANGUAGE C IMMUTABLE STRICT;
diff --git a/contrib/pgcrypto/pgcrypto--1.1.sql b/contrib/pgcrypto/pgcrypto--1.1.sql
new file mode 100644
index 0000000..a260857
--- /dev/null
+++ b/contrib/pgcrypto/pgcrypto--1.1.sql
@@ -0,0 +1,207 @@
+/* contrib/pgcrypto/pgcrypto--1.1.sql */
+
+-- complain if script is sourced in psql, rather than via CREATE EXTENSION
+\echo Use "CREATE EXTENSION pgcrypto" to load this file. \quit
+
+CREATE FUNCTION digest(text, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_digest'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION digest(bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_digest'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION hmac(text, text, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_hmac'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION hmac(bytea, bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_hmac'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION crypt(text, text)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pg_crypt'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gen_salt(text)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pg_gen_salt'
+LANGUAGE C VOLATILE STRICT;
+
+CREATE FUNCTION gen_salt(text, int4)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pg_gen_salt_rounds'
+LANGUAGE C VOLATILE STRICT;
+
+CREATE FUNCTION encrypt(bytea, bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_encrypt'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION decrypt(bytea, bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_decrypt'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION encrypt_iv(bytea, bytea, bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_encrypt_iv'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION decrypt_iv(bytea, bytea, bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_decrypt_iv'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION gen_random_bytes(int4)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_random_bytes'
+LANGUAGE C VOLATILE STRICT;
+
+CREATE FUNCTION gen_random_uuid()
+RETURNS uuid
+AS 'MODULE_PATHNAME', 'pg_random_uuid'
+LANGUAGE C VOLATILE;
+
+--
+-- pgp_sym_encrypt(data, key)
+--
+CREATE FUNCTION pgp_sym_encrypt(text, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_sym_encrypt_text'
+LANGUAGE C STRICT;
+
+CREATE FUNCTION pgp_sym_encrypt_bytea(bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_sym_encrypt_bytea'
+LANGUAGE C STRICT;
+
+--
+-- pgp_sym_encrypt(data, key, args)
+--
+CREATE FUNCTION pgp_sym_encrypt(text, text, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_sym_encrypt_text'
+LANGUAGE C STRICT;
+
+CREATE FUNCTION pgp_sym_encrypt_bytea(bytea, text, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_sym_encrypt_bytea'
+LANGUAGE C STRICT;
+
+--
+-- pgp_sym_decrypt(data, key)
+--
+CREATE FUNCTION pgp_sym_decrypt(bytea, text)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pgp_sym_decrypt_text'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION pgp_sym_decrypt_bytea(bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_sym_decrypt_bytea'
+LANGUAGE C IMMUTABLE STRICT;
+
+--
+-- pgp_sym_decrypt(data, key, args)
+--
+CREATE FUNCTION pgp_sym_decrypt(bytea, text, text)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pgp_sym_decrypt_text'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION pgp_sym_decrypt_bytea(bytea, text, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_sym_decrypt_bytea'
+LANGUAGE C IMMUTABLE STRICT;
+
+--
+-- pgp_pub_encrypt(data, key)
+--
+CREATE FUNCTION pgp_pub_encrypt(text, bytea)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_pub_encrypt_text'
+LANGUAGE C STRICT;
+
+CREATE FUNCTION pgp_pub_encrypt_bytea(bytea, bytea)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_pub_encrypt_bytea'
+LANGUAGE C STRICT;
+
+--
+-- pgp_pub_encrypt(data, key, args)
+--
+CREATE FUNCTION pgp_pub_encrypt(text, bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_pub_encrypt_text'
+LANGUAGE C STRICT;
+
+CREATE FUNCTION pgp_pub_encrypt_bytea(bytea, bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_pub_encrypt_bytea'
+LANGUAGE C STRICT;
+
+--
+-- pgp_pub_decrypt(data, key)
+--
+CREATE FUNCTION pgp_pub_decrypt(bytea, bytea)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_text'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION pgp_pub_decrypt_bytea(bytea, bytea)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_bytea'
+LANGUAGE C IMMUTABLE STRICT;
+
+--
+-- pgp_pub_decrypt(data, key, psw)
+--
+CREATE FUNCTION pgp_pub_decrypt(bytea, bytea, text)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_text'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION pgp_pub_decrypt_bytea(bytea, bytea, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_bytea'
+LANGUAGE C IMMUTABLE STRICT;
+
+--
+-- pgp_pub_decrypt(data, key, psw, arg)
+--
+CREATE FUNCTION pgp_pub_decrypt(bytea, bytea, text, text)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_text'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION pgp_pub_decrypt_bytea(bytea, bytea, text, text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pgp_pub_decrypt_bytea'
+LANGUAGE C IMMUTABLE STRICT;
+
+--
+-- PGP key ID
+--
+CREATE FUNCTION pgp_key_id(bytea)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pgp_key_id_w'
+LANGUAGE C IMMUTABLE STRICT;
+
+--
+-- pgp armor
+--
+CREATE FUNCTION armor(bytea)
+RETURNS text
+AS 'MODULE_PATHNAME', 'pg_armor'
+LANGUAGE C IMMUTABLE STRICT;
+
+CREATE FUNCTION dearmor(text)
+RETURNS bytea
+AS 'MODULE_PATHNAME', 'pg_dearmor'
+LANGUAGE C IMMUTABLE STRICT;
diff --git a/contrib/pgcrypto/pgcrypto.c b/contrib/pgcrypto/pgcrypto.c
index a441ca7..d440068 100644
--- a/contrib/pgcrypto/pgcrypto.c
+++ b/contrib/pgcrypto/pgcrypto.c
@@ -35,6 +35,7 @@
 
 #include "parser/scansup.h"
 #include "utils/builtins.h"
+#include "utils/uuid.h"
 
 #include "px.h"
 #include "px-crypt.h"
@@ -443,6 +444,27 @@ pg_random_bytes(PG_FUNCTION_ARGS)
 	PG_RETURN_BYTEA_P(res);
 }
 
+/* SQL function: pg_random_uuid() returns uuid */
+PG_FUNCTION_INFO_V1(pg_random_uuid);
+
+Datum
+pg_random_uuid(PG_FUNCTION_ARGS)
+{
+	unsigned char *buf = (unsigned char *) palloc(16);
+	/* get 128 random bits */
+	int err = px_get_random_bytes(buf, 16);
+	if (err < 0)
+		ereport(ERROR,
+				(errcode(ERRCODE_EXTERNAL_ROUTINE_INVOCATION_EXCEPTION),
+				 errmsg("Random generator error: %s", px_strerror(err))));
+
+	/* set UUID v4 magic numbers, http://tools.ietf.org/html/rfc4122#section-4.4 */
+	buf[6] = (buf[6] & 0x0f) | 0x40;
+	buf[8] = (buf[8] & 0x3f) | 0x80;
+
+	PG_RETURN_UUID_P(buf);
+}
+
 static void *
 find_provider(text *name,
 			  PFN provider_lookup,
diff --git a/contrib/pgcrypto/pgcrypto.control b/contrib/pgcrypto/pgcrypto.control
index 8375cf9..7f79d04 100644
--- a/contrib/pgcrypto/pgcrypto.control
+++ b/contrib/pgcrypto/pgcrypto.control
@@ -1,5 +1,5 @@
 # pgcrypto extension
 comment = 'cryptographic functions'
-default_version = '1.0'
+default_version = '1.1'
 module_pathname = '$libdir/pgcrypto'
 relocatable = true
diff --git a/contrib/pgcrypto/pgcrypto.h b/contrib/pgcrypto/pgcrypto.h
index 6284ba2..04ea696 100644
--- a/contrib/pgcrypto/pgcrypto.h
+++ b/contrib/pgcrypto/pgcrypto.h
@@ -45,5 +45,6 @@ Datum		pg_decrypt(PG_FUNCTION_ARGS);
 Datum		pg_encrypt_iv(PG_FUNCTION_ARGS);
 Datum		pg_decrypt_iv(PG_FUNCTION_ARGS);
 Datum		pg_random_bytes(PG_FUNCTION_ARGS);
+Datum		pg_random_uuid(PG_FUNCTION_ARGS);
 
 #endif
diff --git a/doc/src/sgml/pgcrypto.sgml b/doc/src/sgml/pgcrypto.sgml
index b99a75c..31dba8c 100644
--- a/doc/src/sgml/pgcrypto.sgml
+++ b/doc/src/sgml/pgcrypto.sgml
@@ -1084,6 +1084,17 @@ gen_random_bytes(count integer) returns bytea
    At most 1024 bytes can be extracted at a time.  This is to avoid
    draining the randomness generator pool.
   </para>
+
+  <indexterm>
+   <primary>gen_random_uuid</primary>
+  </indexterm>
+
+<synopsis>
+gen_random_uuid() returns uuid
+</synopsis>
+  <para>
+   Returns a version 4 (random) UUID.
+  </para>
  </sect2>
 
  <sect2>
-- 
1.8.4.2

#2Wim Lewis
wiml@omnigroup.com
In reply to: Oskari Saarenmaa (#1)
Re: pgcrypto: implement gen_random_uuid

One comment, this:

/* get 128 random bits */
int err = px_get_random_bytes(buf, 16);

might be better to use px_get_pseudo_random_bytes(). UUIDs don't
need to be unguessable or have perfect entropy; they just need to
be collision-resistant. RFC4122 mentions this I think, and if you
look at the ossp-uuid function that this is replacing, it also uses
its internal PRNG for v4 UUIDs rather than strong high-entropy
randomness.

(The downside of requesting strong randomness when you don't need
it is that it can potentially cause the server to block while the
system gathers entropy.)

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

In reply to: Wim Lewis (#2)
Re: pgcrypto: implement gen_random_uuid

13.01.2014 04:35, Wim Lewis kirjoitti:

One comment, this:

/* get 128 random bits */
int err = px_get_random_bytes(buf, 16);

might be better to use px_get_pseudo_random_bytes(). UUIDs don't
need to be unguessable or have perfect entropy; they just need to
be collision-resistant. RFC4122 mentions this I think, and if you
look at the ossp-uuid function that this is replacing, it also uses
its internal PRNG for v4 UUIDs rather than strong high-entropy
randomness.

(The downside of requesting strong randomness when you don't need
it is that it can potentially cause the server to block while the
system gathers entropy.)

pgcrypto's px_get_pseudo_random_bytes is just a wrapper for
px_get_random_bytes which itself calls system_reseed and
fortuna_get_bytes. system_reseed function tries to read from
/dev/urandom, and only uses /dev/random if reading urandom fails, so it
should never block on systems which have urandom.

That said, it may still make sense to use px_get_pseudo_random_bytes
instead just in case it ever gets modified to do something lighter than
px_get_random_bytes.

Thanks for the review,
Oskari

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#4Emre Hasegeli
emre@hasegeli.com
In reply to: Oskari Saarenmaa (#1)
Re: [PATCH] pgcrypto: implement gen_random_uuid

2014/1/9 Oskari Saarenmaa <os@ohmu.fi>:

The only useful feature of the uuid-ossp module in my opinion is the
uuid_generate_v4 function and as uuid-ossp is more or less abandonware
people have had trouble building and installing it. This patch implements
an alternative uuid v4 generation function in pgcrypto which could be moved
to core once there's a core PRNG with large enough internal state.

It is a small but very useful patch. Installing uuid-ossp can be very hard
on some systems. There is not much to review. The patch applies cleanly to
HEAD. The function is generating valid UUID version 4. The code and
the documentation style seems to fit in the pgcrypto extension. I am marking
it as "Ready for Commiter".

The problem is users probably would not look pgcrypto extension for
UUID generator, especially when there is another extension with uuid in
it's name. Also, UUID generator does not sound like a cryptographic function.
It would be much better, if this would be in core with the UUID type. There
is a reference on the UUID Type documentation page to the uuid-ossp
extension. We can add a reference to pgcrypro extension in that page and
consider adding a deprecation note to the uuid-ossp extension, if is is not
possible to add the function to the core, for now.

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#5Tom Lane
tgl@sss.pgh.pa.us
In reply to: Emre Hasegeli (#4)
Re: [PATCH] pgcrypto: implement gen_random_uuid

Emre Hasegeli <emre@hasegeli.com> writes:

2014/1/9 Oskari Saarenmaa <os@ohmu.fi>:

The only useful feature of the uuid-ossp module in my opinion is the
uuid_generate_v4 function and as uuid-ossp is more or less abandonware
people have had trouble building and installing it. This patch implements
an alternative uuid v4 generation function in pgcrypto which could be moved
to core once there's a core PRNG with large enough internal state.

It is a small but very useful patch. Installing uuid-ossp can be very hard
on some systems. There is not much to review. The patch applies cleanly to
HEAD. The function is generating valid UUID version 4. The code and
the documentation style seems to fit in the pgcrypto extension. I am marking
it as "Ready for Commiter".

The problem is users probably would not look pgcrypto extension for
UUID generator, especially when there is another extension with uuid in
it's name. Also, UUID generator does not sound like a cryptographic function.
It would be much better, if this would be in core with the UUID type. There
is a reference on the UUID Type documentation page to the uuid-ossp
extension. We can add a reference to pgcrypro extension in that page and
consider adding a deprecation note to the uuid-ossp extension, if is is not
possible to add the function to the core, for now.

Well, we're not pulling pgcrypto into core in the foreseeable future;
there are legal (export control) issues that make that too risky.
Even aside from that, there was general consensus when type uuid went
in that the various generation algorithms were, how shall I say it, too
intellectually unsatisfying to be part of the core code. So I think from
a code standpoint this solution is just fine. I agree that we need some
extra work on the documentation to point people towards this approach
instead of uuid-ossp, though. I'll take care of that and commit.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers