tc39 / proposal-csprng

Cryptographically Secure Random Number Generation for ECMAScript
BSD 3-Clause "New" or "Revised" License
70 stars 9 forks source link

Cryptographically Secure Pseudo-Random Number Generation (CSPRNG) for ECMAScript

This proposes the addition of a user-addressable function that can be used to fill the portion of an ArrayBuffer associated with a TypedArray with cryptographically secure pseudo-random number values.

Portions of this proposal are derived from the Web Cryptography API

Status

Stage: 1
Champion: Ron Buckton (@rbuckton)

For detailed status of this proposal see TODO, below.

Authors

Motivations

One of the key issues for https://github.com/tc39/proposal-uuid is the lack of a "source of truth" for cryptographically secure pseudo-random numbers within the ECMAScript language. While hosts such as browsers and NodeJS provide implementations of CSPRNGs (Cryptographically Secure Pseudo-Random Number Generators), the ECMAScript language itself has no mechanism for supplying a CSPRNG that can be used by proposed APIs such as UUID.

Goals

Prior Art

API

We are still investigating the API surface area for this proposal. The intended API would be a user-addressable function that when called executes the FillRandomValues abstract operation, below.

The Stage 0 API proposal exposed this as a static ArrayBuffer.fillRandom method, although we are continuing to investigate this space.

Abstract Operations

FillRandomValues (view)

When abstract operation FillRandomValues is called with argument view, the following steps are taken:

  1. Perform ? RequireInternalSlot(view, [[TypedArrayName]]).
  2. Assert: view has the [[ViewedArrayBuffer]], [[ByteLength]], and [[ByteOffset]] internal slots.
  3. If view.[[TypedArrayName]] is not one of "Int8Array", "Uint8Array", "Uint8ClampedArray", "Int16Array", "Uint16Array", "Int32Array", "Uint32Array", "BigInt64Array", or "BigUint64Array", throw a TypeError exception.
  4. Let buffer be view.[[ViewedArrayBuffer]].
  5. If ! IsDetachedBuffer(buffer) is true, throw a TypeError exception.
  6. Let byteLength be view.[[ByteLength]].
  7. If byteLength is greater than 65536, throw a RangeError exception.
  8. Let byteOffset be view.[[ByteOffset]].
  9. Let byteEndOffset be byteOffset + byteLength.
  10. Overwrite the elements of buffer from index byteOffset (inclusive) through index byteEndOffset (exclusive) with cryptographically secure random values.
  11. Return view.

Note
Implementations should generate cryptographically secure random values using well-established cryptographic pseudo-random number generators seeded with high-quality entropy, such as from an operating-system entropy source (e.g., "/dev/urandom"). This specification provides no lower-bound on the information theoretic entropy present in cryptographically secure random values, but implementations should make a best effort to provide as much entropy as practicable.

Note
This interface defines a synchronous method for obtaining cryptographically secure random values. While some devices and implementations may support truly random cryptographic number generators or provide interfaces that block when there is insufficient entropy, implementations are discouraged from using these sources when implementing getRandomValues, both for performance and to avoid depleting the system of entropy. Instead, these sources should be used to seed a cryptographic pseudo-random number generator that can then return suitable values efficiently.

References

Prior Discussion

TODO

The following is a high-level list of tasks to progress through each stage of the TC39 proposal process:

Stage 1 Entrance Criteria

Stage 2 Entrance Criteria

Stage 3 Entrance Criteria

Stage 4 Entrance Criteria