HackerTrans
TopNewTrendsCommentsPastAskShowJobs

sdrapkin

no profile record

Submissions

.NET: Avoid Using Guid.CreateVersion7

gist.github.com
2 points·by sdrapkin·8 months ago·1 comments

Fcrand (Go language): drop-in replacement for crypto/rand, up to 10x faster

github.com
14 points·by sdrapkin·12 months ago·6 comments

Fast cryptographically safe GUID generator for Go

github.com
20 points·by sdrapkin·last year·41 comments

comments

sdrapkin
·8 months ago·discuss
Guid.CreateVersion7 in .NET 9+ claims RFC 9562 compliance but violates its big-endian requirement for binary storage. This causes the same database index fragmentation that v7 UUIDs were designed to prevent. Testing with 100K PostgreSQL inserts shows rampant fragmentation (35% larger indexes) versus properly-implemented sequential GUIDs.
sdrapkin
·12 months ago·discuss
fcrand (fast crypto/rand) is a high-performance drop-in replacement for Go's crypto/rand.
sdrapkin
·last year·discuss
No, Guid/uuids are defined as 128-bit labels used to uniquely identify objects in computer systems. This 128-bit/16-byte definition predates any RFCs that one may or may not choose to implement. I'm obviously aware of RFC 9562, and nowhere in the Guid library do I claim implementation of it. RFC 9562 is a choice, and one that should not be made blindly, or for you. It all starts with 16 random bytes. Google's uuid starts that way, and virtually every other Guid/uuid implementation. Then, on top of that building block, one may tweak additional non-random bits if the usecase truly requires it. If it does - you can do it quickly and cheaply on top of 16 random bytes. If the usecase does not require it (99% of cases), you're better off with the foundational 16 random bytes. The perspective of "your 16 random bytes do not implement RFC 9562 - BAD, BAD!" is very myopic. But if wasting bits on versions and variants is something that helps someone sleep better - they can easily and cheaply achieve that with a couple of bit ops. RFC 9562 robs developers of that choice.
sdrapkin
·last year·discuss
Agreed. So at worst they (Golang developers) should be indifferent, and at best they should opt for the faster choice. With serverless code billing by the second, faster choices are directly correlated to lower costs.
sdrapkin
·last year·discuss
Amazon AWS S3 web servers process millions of requests per second, and each response generates a random Request-Id. It’s not exactly 16 bytes, but this is a very realistic scenario where guids are used in hot path. If you are writing a cute-kitten blog, might as well use Python instead..
sdrapkin
·last year·discuss
Guid/uuid is defined as a 16-byte structure. Are you questioning the “byte” part, or the “random” part?
sdrapkin
·last year·discuss
Fast guid/uuid generators are NOT a security risk. You want such generators to be as fast as possible, without compromising cryptographic strength.
sdrapkin
·last year·discuss
The vast majority of Golang developers would benefit from using Guid library instead of UUID library. It’s substantially faster in all cases, more secure (by 2^6) and has more functionality.

For random token-as-string generation Golang developers should be using https://github.com/sdrapkin/randstring instead of crypto/rand.Text (faster and more flexible).
sdrapkin
·last year·discuss
> This shouldn't really matter as your import paths are obviously different.

I'm aware of that, of course. Guid is intentionally named differently from "uuid" (both as a package and as a type) to ensure there is no confusion between them in code. It is not the goal of Guid to mimic/inherit all uuid APIs. Guid is its own package, with a different API surface and roadmap (ie. I'll borrow what makes sense and do things differently when it makes sense).
sdrapkin
·last year·discuss
You are correct - Guid very specifically and intentionally generates a structure of 16 random bytes. In decades of programming I've never needed a random 16-byte structure to have a "internal versioned structure". In very rare cases this is truly needed, bit-twiddling post-generation can cheaply fix it (but not the other way around). Which is why all these "versions" and "variants" in standard universally applicable libraries are a complete waste of entropy and cycles.
sdrapkin
·last year·discuss
Guid package generates guids/uuids. Your linked package generates variable length strings. These are different usecases (oh, and your benchmarks are inferior to https://github.com/sdrapkin/randstring). Nothing to argue about.
sdrapkin
·last year·discuss
cuid2 generates variable-length strings. If you want fast cryptographically strong string generation, I recommend https://github.com/sdrapkin/randstring. It will likely be faster than cuid2.
sdrapkin
·last year·discuss
It's on the roadmap (already implemented in a similar .NET library - https://github.com/sdrapkin/SecurityDriven.FastGuid).
sdrapkin
·last year·discuss
In case you missed it, "guid.Read()" is a much faster alternative to "crypto/rand". https://pkg.go.dev/github.com/sdrapkin/guid#Read
sdrapkin
·last year·discuss
IMHO "Guid" is just as well known (Wikipedia agrees: https://en.wikipedia.org/wiki/Universally_unique_identifier), and "UUID" was already taken by Google.
sdrapkin
·last year·discuss
Thanks for your feedback. If you are skilled in Golang, I suggest you review the code more thoroughly for a more accurate understanding (especially compared to what standard uuid does).
sdrapkin
·last year·discuss
It generates entropy 4kb-at-a-time (instead of on each call), and uses a cache-pool instead of single cache behind a lock (which is what standard uuid does in "RandPool=ON" mode).
sdrapkin
·last year·discuss
Much faster (~10x) than standard github.com/google/uuid package

I'm interested in feedback from the HN community.