Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add spec text to be compatible with WebCrypto #2

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 48 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@
# 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` or `DataView` with cryptographically secure pseudo-random number values.
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][WebCrypto]:

> The [Web Cryptography API][WebCrypto] is Copyright © 2018 [World Wide Web Consortium](http://www.w3.org/), ([MIT](http://www.csail.mit.edu/),
[ERCIM](http://www.ercim.org/), [Keio](http://www.keio.ac.jp/), [Beihang](http://ev.buaa.edu.cn/)). http://www.w3.org/Consortium/Legal/2015/doc-license
>
> The [Web Cryptography API][WebCrypto] is an Editors Draft, per the [February 2018 W3C Process Document](https://www.w3.org/2018/Process-20180201/).

Portions of this proposal are derived from the [Web Cryptography API](https://w3c.github.io/webcrypto/#Crypto-method-getRandomValues)
<!--#endregion:intro-->

<!--#region:status-->
Expand All @@ -13,7 +19,7 @@ Portions of this proposal are derived from the [Web Cryptography API](https://w3
**Stage:** 1
**Champion:** Ron Buckton (@rbuckton)

_For detailed status of this proposal see [TODO](#todo), below._
_For detailed status of this proposal see [TODO][], below._
<!--#endregion:status-->

<!--#region:authors-->
Expand All @@ -28,13 +34,13 @@ _For detailed status of this proposal see [TODO](#todo), below._
One of the [key issues](https://github.com/tc39/proposal-uuid/issues/37) 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](https://github.com/tc39/proposal-uuid).
language itself has no mechanism for supplying a CSPRNG that can be used by proposed APIs such as [UUID][].

### Goals

* Provide a single "source of truth" for generating cryptographically secure pseudo-random values within the language.
* Provide a single "source of truth" for generating cryptographically secure pseudo-random number values within the language.
* Provide a single location for mocking the CSPRNG, vs a method on each `TypedArray` prototype.
* If introducing a new `crypto` global namespace for cryptography-related APIs in ECMA-262, we should ensure that the Web cryptography APIs could be layered on top.
* If introducing a new `crypto` global namespace for cryptography-related APIs in ECMA-262, we should ensure that the Web Cryptography APIs could be layered on top.
<!--#endregion:motivations-->

<!--#region:prior-art-->
Expand Down Expand Up @@ -64,44 +70,56 @@ language itself has no mechanism for supplying a CSPRNG that can be used by prop
<!--#endregion:semantics-->

<!--#region:examples-->
<!--
# Examples

> TODO: Provide examples of the proposal.
```js
const array = new Uint8Array(16);
crypto.getRandomValues(array); // returns `array`
```

-->
<!--#endregion:examples-->

<!--#region:api-->
# 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](#fillrandomvalues-view) abstract operation, below.
# The `crypto` Object

This proposal introduces a global `crypto` object that is intended to be compatible with the implementation in the [Web Cryptography API][WebCrypto].
As such, the global `crypto` object is defined as being a reference to a built-in %crypto% object, which in turn has its \[\[Prototype]] internal slot that points to a built-in %CryptoPrototype% object to which API methods are attached. This is intended to preserve the prototype hierarchy inherent in the WebIDL
definition for the [Crypto interface](https://w3c.github.io/webcrypto/#crypto-interface).

To support spec layering with the Web Cryptography API, WebIDL attributes like `subtle` can be defined by a host to exist on the %crypto% built-in object, and additional members of the Crypto interface could be defined on the %CryptoPrototype% built-in object.

The Stage 0 API proposal exposed this as a static `ArrayBuffer.fillRandom` method, although we are continuing to investigate this space.
## Properties of the %CryptoPrototype% object

# Abstract Operations
The %CryptoPrototype% object is intended to represent the minimal subset of the [Crypto interface](https://w3c.github.io/webcrypto/#crypto-interface) from the [Web Cryptography API][WebCrypto] necessary to implement this proposal. This would allow the Web Cryptography API to layer its implementation on top of the specification in this proposal in a web-compatible
way.

## FillRandomValues (view)
### %CryptoPrototype%.getRandomValues ( array )

When abstract operation FillRandomValues is called with argument _view_, the following steps are taken:
When getRandomValues is called with argument _array_, the following steps are taken:

1. Perform ? RequireInternalSlot(_view_, \[\[TypedArrayName]]).
1. Assert: _view_ has the \[\[ViewedArrayBuffer]], \[\[ByteLength]], and \[\[ByteOffset\]\] internal slots.
1. If _view_.\[\[TypedArrayName]] is not one of `"Int8Array"`, `"Uint8Array"`, `"Uint8ClampedArray"`, `"Int16Array"`, `"Uint16Array"`, `"Int32Array"`, `"Uint32Array"`, `"BigInt64Array"`, or `"BigUint64Array"`, throw a **TypeError** exception.
1. Let _buffer_ be _view_.\[\[ViewedArrayBuffer]].
1. Perform ? RequireInternalSlot(_array_, \[\[TypedArrayName]]).
1. Assert: _array_ has the \[\[ViewedArrayBuffer]], \[\[ByteLength]], and \[\[ByteOffset\]\] internal slots.
1. If _array_.\[\[TypedArrayName]] is not one of `"Int8Array"`, `"Uint8Array"`, `"Uint8ClampedArray"`, `"Int16Array"`, `"Uint16Array"`, `"Int32Array"`, `"Uint32Array"`, `"BigInt64Array"`, or `"BigUint64Array"`, throw a **TypeError** exception.
1. Let _buffer_ be _array_.\[\[ViewedArrayBuffer]].
1. If ! IsDetachedBuffer(_buffer_) is **true**, throw a **TypeError** exception.
1. Let _byteLength_ be _view_.\[\[ByteLength]].
1. Let _byteLength_ be _array_.\[\[ByteLength]].
1. If _byteLength_ is greater than 65536, throw a **RangeError** exception.
1. Let _byteOffset_ be _view_.\[\[ByteOffset]].
1. Let _byteOffset_ be _array_.\[\[ByteOffset]].
1. Let _byteEndOffset_ be _byteOffset_ + _byteLength_.
1. Overwrite the elements of _buffer_ from index _byteOffset_ (inclusive) through index _byteEndOffset_ (exclusive) with cryptographically secure random values.
1. Return _view_.
1. Return _array_.

> **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.

### %CryptoPrototype% [ @@toStringTag ]

The initial value of the \@\@toStringTag property of %CryptoPrototype% is the String value `"Crypto"`.
<!--#endregion:api-->

<!--#region:grammar-->
Expand All @@ -119,15 +137,16 @@ When abstract operation FillRandomValues is called with argument _view_, the fol
<!--#region:references-->
# References

* [Web Cryptography API](https://w3c.github.io/webcrypto/#Crypto-method-getRandomValues)
* [UUID Proposal](https://github.com/tc39/proposal-uuid)
* [Original Strawman](https://gist.github.com/rbuckton/0777210dc3086e1a90375354b045a3a7)
* [Web Cryptography API][WebCrypto] ([GitHub](https://github.com/w3c/webcrypto))
* [UUID Proposal][UUID]
<!--#endregion:references-->

<!--#region:prior-discussion-->
# Prior Discussion

* *Separate proposal for CSPRNG "source of truth"*: https://github.com/tc39/proposal-uuid/issues/37
* *Math.urandom() in ECMAScript*: https://github.com/tc39/proposal-uuid/issues/31
* *Using Math.getRandomValues()*: https://github.com/w3c/webcrypto/issues/227
<!--#endregion:prior-discussion-->

<!--#region:todo-->
Expand All @@ -144,8 +163,8 @@ The following is a high-level list of tasks to progress through each stage of th

### Stage 2 Entrance Criteria

* [ ] [Initial specification text][Specification].
* [ ] [Transpiler support][Transpiler] (_Optional_).
* [x] [Initial specification text][Specification].
* [ ] ~~[Transpiler support][Transpiler] (_Optional_).~~

### Stage 3 Entrance Criteria

Expand All @@ -168,6 +187,7 @@ The following is a high-level list of tasks to progress through each stage of th
[Prose]: #motivations
[Examples]: #examples
[API]: #api
[TODO]: #todo
[Specification]: #todo
[Transpiler]: #todo
[Stage3ReviewerSignOff]: #todo
Expand All @@ -176,3 +196,5 @@ The following is a high-level list of tasks to progress through each stage of th
[Implementation1]: #todo
[Implementation2]: #todo
[Ecma262PullRequest]: #todo
[WebCrypto]: https://w3c.github.io/webcrypto/
[UUID]: https://github.com/tc39/proposal-uuid
Loading