w3c / w3c/webcrypto

Add support for BLAKE2 (RFC7693)

Open
#313 2 comments 4 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
HTML
Stars
294
Forks
78
PR merge metrics
No merged PRs in 30d

Description

Description

BLAKE2 is a fast software friendly hash function.
It is also a SHA3 finalist.

I would like to add it to as an optional part of the webcrypto API.

Spec

it can be found here:

Tests

There is an extensive test vector list available here https://github.com/BLAKE2/BLAKE2/tree/master/testvectors (CC0 1.0 Universal license).

Support

It is already supported into many cryptographic libraries, and implementing it is really easy, so it shouldn't be lots of work to implement for vendors.

Reasons BLAKE2 is a usefull hash function
  • It's fast (BLAKE2b is ~2.3x times faster than SHA256 according to www.blake2.net's benchmarks)
  • It's fast on lowpower hardware, making it nice when you need it to work on things like embeded devices, phones, ...
  • It's fast even implemented on software. (in other words, it does not require hardware accelerators like custom CPU extensions to achieve it's great speed)
  • It support an optional key field, allowing for HMAC like patterns without using HMAC (it's builtin in the algorithm).

JS API

Using it would be similar to the current SHA extension.
Consumers would call crypto.subtle.digest with the name, data and optionally the key and get returned a promise, that when resolved would return the digest body.

Name and variants
BLAKE2{s,b}-$SIZE
  • s or b refer to the word size, 32 or 64bits respectively, that also affects the blocksize (which is made of 16 words), keysize, constants used and the number of rounds.
  • $SIZE, even tho internally the hashing will always happen in 64 or 128 bytes blocks, BLAKE2 supports arbitrary sized digests as long it follows 0 < x <= (blocksize/2) bytes, for convinience and following convention it would be expressed in bits.

(note this proposal doesn't include BLAKE2x (arbitrarily sizable digests) or BLAKE2{s,b}p (parallel variant with reduced block depency for increased performance), this proposal stick to RFC7693)

So that allows you to combine them to make the name to pass to digest.
For example:

  • BLAKE2b-256 indicates 64bits words with a 32 bytes digest size.
  • BLAKE2s-16 indicates 32bits words, with a 2 bytes digest size.

Vendors are allowed to only support either of the variant if they wish too.

Normative restriction on variant support

If a vendor support any digest size of a variant, they must also support all other available digest sizes.
So supporting BLAKE2b-512 require you to also supports BLAKE2b-8, BLAKE2b-16, ...

The reason to do this is that the digest size is not actually part of the algorithm, but only a parameter.

Optional key parameter

Unlike SHA, BLAKE2 accepts a key (bytes) that is 0 <= x <= (blocksize/2) big.
This can be passed as an optional third parameter to digest.

If the key is undefined, then assume a 0 sized key.
Else if the type does not match BufferSource throw with TypeError.
Else if the key is bigger than allowed throw with DataError.

Note the optional here, means optional to consumers, not vendors, vendors MUST support the key parameter if they want to support BLAKE2.

Return value

An ArrayBuffer containing the resulting digest, and sized matching the size parameter.

Usage example

function buf2hex(b) { return [...new Uint8Array(b)].map(x => x.toString(16).padStart(2, '0')).join('') }

const body = new TextEncoder("utf-8").encode("hello")
const h1 = crypto.subtle.digest("BLAKE2b-256", body)

const key = new TextEncoder("utf-8").encode("world")
const h2 = crypto.subtle.digest("BLAKE2s-128", body, key)

console.log(buf2hex(await h1)) // 324dcf027dd4a30a932c441f365a25e86b173defa4b8e58948253471b81b72cf
console.log(buf2hex(await h2)) // d956ebc7895f6f2f0d00b5ad04b10749

Implementation interest

I currently have personal interest into getting this added.
I can draft a spec PR and make a W3C's testsuite friendly version of the already existing test cases if reception seems positive.
I'm also interested into implementing this into the major engines.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the Web Cryptography API's crypto.subtle.digest operation and RFC 7693, then review the linked BLAKE2 test vectors. Define how the proposed BLAKE2s/BLAKE2b names, digest sizes, and optional key parameter fit the API, and adapt the vectors for the W3C testsuite. Done means the specification and interoperability tests cover the supported variants and validation errors.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
api, cryptography
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.