This commit is contained in:
Paul Miller 2022-12-31 09:00:29 +00:00
parent 910c508da9
commit a15e3a93a9
No known key found for this signature in database
GPG Key ID: 697079DA6878B89B
2 changed files with 65 additions and 13 deletions

@ -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/) - [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 for encoding or hashing an arbitrary string to a point on an elliptic curve
- Auditable, [fast](#speed) - 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 - 🔍 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: 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/edwards: Twisted Edwards curve](#abstract/edwards-twisted-edwards-curve)
- [abstract/montgomery: Montgomery curve](#abstract/montgomery-montgomery-curve) - [abstract/montgomery: Montgomery curve](#abstract/montgomery-montgomery-curve)
- [abstract/weierstrass: Short Weierstrass curve](#abstract/weierstrass-short-weierstrass-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/modular](#abstract/modular)
- [abstract/utils](#abstract/utils) - [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 ### abstract/modular
Modular arithmetics utilities. Modular arithmetics utilities.
```typescript ```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 mod(21n, 10n); // 21 mod 10 == 1n; fixed version of 21 % 10
invert(17n, 10n); // invert(17) mod 10; modular multiplicative inverse invert(17n, 10n); // invert(17) mod 10; modular multiplicative inverse
div(5n, 17n, 10n); // 5/17 mod 10 == 5 * invert(17) mod 10; division 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 invertBatch([1n, 2n, 4n], 21n); // => [1n, 11n, 16n] in one inversion
sqrt(21n, 73n); // √21 mod 73; square root 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 ### abstract/utils

@ -109,7 +109,7 @@ export function expand_message_xof(
lenInBytes: number, lenInBytes: number,
k: number, k: number,
H: CHash H: CHash
) { ): Uint8Array {
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16#section-5.3.3 // 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)); // DST = H('H2C-OVERSIZE-DST-' || a_very_long_DST, Math.ceil((lenInBytes * k) / 8));
if (DST.length > 255) { 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 * Hashes arbitrary-length byte strings to a list of one or more elements of a finite field F
// Inputs: * https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-5.3
// msg - a byte string containing the message to hash. * @param msg a byte string containing the message to hash
// count - the number of elements of F to output. * @param count the number of elements of F to output
// Outputs: * @param options `{DST: string, p: bigint, m: number, k: number, expand: 'xmd' | 'xof', hash: H}`
// [u_0, ..., u_(count - 1)], a list of field elements. * @returns [u_0, ..., u_(count - 1)], a list of field elements.
*/
export function hash_to_field(msg: Uint8Array, count: number, options: htfOpts): bigint[][] { export function hash_to_field(msg: Uint8Array, count: number, options: htfOpts): bigint[][] {
// if options is provided but incomplete, fill any missing fields with the // if options is provided but incomplete, fill any missing fields with the
// value in hftDefaults (ie hash to G2). // value in hftDefaults (ie hash to G2).