From a15e3a93a9ce170b7fb4b85e84c721c672984b43 Mon Sep 17 00:00:00 2001 From: Paul Miller Date: Sat, 31 Dec 2022 09:00:29 +0000 Subject: [PATCH] Docs --- README.md | 61 ++++++++++++++++++++++++++++++++--- src/abstract/hash-to-curve.ts | 17 +++++----- 2 files changed, 65 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 1e55c62..21e3901 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,8 @@ Minimal, auditable JS implementation of elliptic curve cryptography. - [hash to curve](https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/) for encoding or hashing an arbitrary string to a point on an elliptic curve - Auditable, [fast](#speed) -- 🔻 Tree-shaking-friendly: there is no entry point, which ensures small size of your app - 🔍 Unique tests ensure correctness. Wycheproof vectors included +- 🔻 Tree-shaking-friendly: there is no entry point, which ensures small size of your app There are two parts of the package: @@ -87,6 +87,7 @@ To define a custom curve, check out API below. - [abstract/edwards: Twisted Edwards curve](#abstract/edwards-twisted-edwards-curve) - [abstract/montgomery: Montgomery curve](#abstract/montgomery-montgomery-curve) - [abstract/weierstrass: Short Weierstrass curve](#abstract/weierstrass-short-weierstrass-curve) +- [abstract/hash-to-curve: Hashing strings to curve points](#abstracthash-to-curve-hashing-arbitrary-strings-to-curve-points) - [abstract/modular](#abstract/modular) - [abstract/utils](#abstract/utils) @@ -324,20 +325,70 @@ export type CurveFn = { }; ``` +### abstract/hash-to-curve: Hashing strings to curve points + +The module allows to hash arbitrary strings to elliptic curve points. + +- `expand_message_xmd` [(spec)](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-5.4.1) produces a uniformly random byte string using a cryptographic hash function H that outputs b bits.. + + ```ts + function expand_message_xmd( + msg: Uint8Array, DST: Uint8Array, lenInBytes: number, H: CHash + ): Uint8Array; + function expand_message_xof( + msg: Uint8Array, DST: Uint8Array, lenInBytes: number, k: number, H: CHash + ): Uint8Array; + ``` + +- `hash_to_field(msg, count, options)` [(spec)](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-5.3) +hashes arbitrary-length byte strings to a list of one or more elements of a finite field F. + * `msg` a byte string containing the message to hash + * `count` the number of elements of F to output + * `options` `{DST: string, p: bigint, m: number, k: number, expand: 'xmd' | 'xof', hash: H}` + * Returns `[u_0, ..., u_(count - 1)]`, a list of field elements. + + ```ts + function hash_to_field(msg: Uint8Array, count: number, options: htfOpts): bigint[][]; + type htfOpts = { + // DST: a domain separation tag + // defined in section 2.2.5 + DST: string; + // p: the characteristic of F + // where F is a finite field of characteristic p and order q = p^m + p: bigint; + // m: the extension degree of F, m >= 1 + // where F is a finite field of characteristic p and order q = p^m + m: number; + // k: the target security level for the suite in bits + // defined in section 5.1 + k: number; + // option to use a message that has already been processed by + // expand_message_xmd + expand?: 'xmd' | 'xof'; + // Hash functions for: expand_message_xmd is appropriate for use with a + // wide range of hash functions, including SHA-2, SHA-3, BLAKE2, and others. + // BBS+ uses blake2: https://github.com/hyperledger/aries-framework-go/issues/2247 + // TODO: verify that hash is shake if expand==='xof' via types + hash: CHash; + }; + ``` + ### abstract/modular Modular arithmetics utilities. ```typescript -import { mod, invert, div, invertBatch, sqrt, Fp } from '@noble/curves/abstract/modular'; +import { Fp, mod, invert, div, invertBatch, sqrt } from '@noble/curves/abstract/modular'; +const fp = Fp(2n ** 255n - 19n); // Finite field over 2^255-19 +fp.mul(591n, 932n); +fp.pow(481n, 11024858120n); + +// Generic non-FP utils are also available mod(21n, 10n); // 21 mod 10 == 1n; fixed version of 21 % 10 invert(17n, 10n); // invert(17) mod 10; modular multiplicative inverse div(5n, 17n, 10n); // 5/17 mod 10 == 5 * invert(17) mod 10; division invertBatch([1n, 2n, 4n], 21n); // => [1n, 11n, 16n] in one inversion sqrt(21n, 73n); // √21 mod 73; square root -const fp = Fp(2n ** 255n - 19n); // Finite field over 2^255-19 -fp.mul(591n, 932n); -fp.pow(481n, 11024858120n); ``` ### abstract/utils diff --git a/src/abstract/hash-to-curve.ts b/src/abstract/hash-to-curve.ts index 84ab51c..95685ea 100644 --- a/src/abstract/hash-to-curve.ts +++ b/src/abstract/hash-to-curve.ts @@ -109,7 +109,7 @@ export function expand_message_xof( lenInBytes: number, k: number, H: CHash -) { +): Uint8Array { // https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16#section-5.3.3 // DST = H('H2C-OVERSIZE-DST-' || a_very_long_DST, Math.ceil((lenInBytes * k) / 8)); if (DST.length > 255) { @@ -129,13 +129,14 @@ export function expand_message_xof( ); } -// hashes arbitrary-length byte strings to a list of one or more elements of a finite field F -// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-5.3 -// Inputs: -// msg - a byte string containing the message to hash. -// count - the number of elements of F to output. -// Outputs: -// [u_0, ..., u_(count - 1)], a list of field elements. +/** + * Hashes arbitrary-length byte strings to a list of one or more elements of a finite field F + * https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-5.3 + * @param msg a byte string containing the message to hash + * @param count the number of elements of F to output + * @param options `{DST: string, p: bigint, m: number, k: number, expand: 'xmd' | 'xof', hash: H}` + * @returns [u_0, ..., u_(count - 1)], a list of field elements. + */ export function hash_to_field(msg: Uint8Array, count: number, options: htfOpts): bigint[][] { // if options is provided but incomplete, fill any missing fields with the // value in hftDefaults (ie hash to G2).