Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2bd5e9ac16 | ||
|
|
6890c26091 | ||
|
|
a15e3a93a9 | ||
|
|
910c508da9 | ||
|
|
12da04a2bb | ||
|
|
cc2c84f040 | ||
|
|
5d42549acc | ||
|
|
65d7256b9e | ||
|
|
d77a98a7aa | ||
|
|
1bfab42620 | ||
|
|
f1ab259941 | ||
|
|
242ee620c5 | ||
|
|
d837831d22 | ||
|
|
cae888d942 | ||
|
|
1ab77b95dd | ||
|
|
8b5819b12d | ||
|
|
4b5560ab4b | ||
|
|
ba121ff24c | ||
|
|
0277c01efd | ||
|
|
6ffe656871 | ||
|
|
135e69bd7b | ||
|
|
7a34c16c2b | ||
|
|
458cddcc7f | ||
|
|
ccfb8695d5 |
3
.github/workflows/nodejs.yml
vendored
3
.github/workflows/nodejs.yml
vendored
@@ -13,6 +13,5 @@ jobs:
|
|||||||
node-version: 18
|
node-version: 18
|
||||||
- run: npm install
|
- run: npm install
|
||||||
- run: npm run build --if-present
|
- run: npm run build --if-present
|
||||||
- run: cd curve-definitions; npm install; npm run build --if-present
|
|
||||||
- run: npm test
|
|
||||||
- run: npm run lint --if-present
|
- run: npm run lint --if-present
|
||||||
|
- run: npm test
|
||||||
|
|||||||
408
README.md
408
README.md
@@ -1,38 +1,44 @@
|
|||||||
# noble-curves
|
# noble-curves
|
||||||
|
|
||||||
Minimal, zero-dependency JS implementation of elliptic curve cryptography.
|
Minimal, auditable JS implementation of elliptic curve cryptography.
|
||||||
|
|
||||||
- Short Weierstrass curve with ECDSA signatures
|
- Short Weierstrass, Edwards, Montgomery curves
|
||||||
- Twisted Edwards curve with EdDSA signatures
|
- ECDSA, EdDSA, Schnorr, BLS signature schemes, ECDH key agreement
|
||||||
- Montgomery curve for ECDH key agreement
|
- [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)
|
||||||
|
- 🔍 Unique tests ensure correctness. Wycheproof vectors included
|
||||||
|
- 🔻 Tree-shaking-friendly: there is no entry point, which ensures small size of your app
|
||||||
|
|
||||||
To keep the package minimal, no curve definitions are provided out-of-box. Use `micro-curve-definitions` module:
|
There are two parts of the package:
|
||||||
|
|
||||||
- It provides P192, P224, P256, P384, P521, secp256k1, stark curve, bn254, pasta (pallas/vesta) short weierstrass curves
|
1. `abstract/` directory specifies zero-dependency EC algorithms
|
||||||
- It also provides ed25519 and ed448 twisted edwards curves
|
2. root directory utilizes one dependency `@noble/hashes` and provides ready-to-use:
|
||||||
- Main reason for separate package is the fact hashing library (like `@noble/hashes`) is required for full functionality
|
- NIST curves secp192r1/P192, secp224r1/P224, secp256r1/P256, secp384r1/P384, secp521r1/P521
|
||||||
- We may reconsider merging packages in future, when a stable version would be ready
|
- SECG curve secp256k1
|
||||||
|
- pairing-friendly curves bls12-381, bn254
|
||||||
|
- ed25519/curve25519/x25519/ristretto, edwards448/curve448/x448 RFC7748 / RFC8032 / ZIP215 stuff
|
||||||
|
|
||||||
Future plans:
|
Curves incorporate work from previous noble packages
|
||||||
|
([secp256k1](https://github.com/paulmillr/noble-secp256k1),
|
||||||
- hash to curve standard
|
[ed25519](https://github.com/paulmillr/noble-ed25519),
|
||||||
- point indistinguishability
|
[bls12-381](https://github.com/paulmillr/noble-bls12-381)),
|
||||||
- pairings
|
which had security audits and were developed from 2019 to 2022.
|
||||||
|
The goal is to replace them with lean UMD builds based on single-codebase noble-curves.
|
||||||
|
|
||||||
### This library belongs to _noble_ crypto
|
### This library belongs to _noble_ crypto
|
||||||
|
|
||||||
> **noble-crypto** — high-security, easily auditable set of contained cryptographic libraries and tools.
|
> **noble-crypto** — high-security, easily auditable set of contained cryptographic libraries and tools.
|
||||||
|
|
||||||
- No dependencies, small files
|
- Minimal dependencies, small files
|
||||||
- Easily auditable TypeScript/JS code
|
- Easily auditable TypeScript/JS code
|
||||||
- Supported in all major browsers and stable node.js versions
|
- Supported in all major browsers and stable node.js versions
|
||||||
- All releases are signed with PGP keys
|
- All releases are signed with PGP keys
|
||||||
- Check out [homepage](https://paulmillr.com/noble/) & all libraries:
|
- Check out [homepage](https://paulmillr.com/noble/) & all libraries:
|
||||||
[secp256k1](https://github.com/paulmillr/noble-secp256k1),
|
[curves](https://github.com/paulmillr/noble-curves) ([secp256k1](https://github.com/paulmillr/noble-secp256k1),
|
||||||
[ed25519](https://github.com/paulmillr/noble-ed25519),
|
[ed25519](https://github.com/paulmillr/noble-ed25519),
|
||||||
[bls12-381](https://github.com/paulmillr/noble-bls12-381),
|
[bls12-381](https://github.com/paulmillr/noble-bls12-381)),
|
||||||
[hashes](https://github.com/paulmillr/noble-hashes),
|
[hashes](https://github.com/paulmillr/noble-hashes)
|
||||||
[curves](https://github.com/paulmillr/noble-curves)
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
@@ -44,82 +50,123 @@ Use NPM in node.js / browser, or include single file from
|
|||||||
The library does not have an entry point. It allows you to select specific primitives and drop everything else. If you only want to use secp256k1, just use the library with rollup or other bundlers. This is done to make your bundles tiny.
|
The library does not have an entry point. It allows you to select specific primitives and drop everything else. If you only want to use secp256k1, just use the library with rollup or other bundlers. This is done to make your bundles tiny.
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import { weierstrass } from '@noble/curves/weierstrass'; // Short Weierstrass curve
|
// Common.js and ECMAScript Modules (ESM)
|
||||||
import { sha256 } from '@noble/hashes/sha256';
|
import { secp256k1 } from '@noble/curves/secp256k1';
|
||||||
|
|
||||||
|
const key = secp256k1.utils.randomPrivateKey();
|
||||||
|
const pub = secp256k1.getPublicKey(key);
|
||||||
|
const msg = new Uint8Array(32).fill(1);
|
||||||
|
const sig = secp256k1.sign(msg, key);
|
||||||
|
secp256k1.verify(sig, msg, pub) === true;
|
||||||
|
sig.recoverPublicKey(msg) === pub;
|
||||||
|
const someonesPub = secp256k1.getPublicKey(secp256k1.utils.randomPrivateKey());
|
||||||
|
const shared = secp256k1.getSharedSecret(key, someonesPub);
|
||||||
|
```
|
||||||
|
|
||||||
|
All curves:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { secp256k1 } from '@noble/curves/secp256k1';
|
||||||
|
import { ed25519, ed25519ph, ed25519ctx, x25519, RistrettoPoint } from '@noble/curves/ed25519';
|
||||||
|
import { ed448, ed448ph, ed448ctx, x448 } from '@noble/curves/ed448';
|
||||||
|
import { p256 } from '@noble/curves/p256';
|
||||||
|
import { p384 } from '@noble/curves/p384';
|
||||||
|
import { p521 } from '@noble/curves/p521';
|
||||||
|
import { pallas, vesta } from '@noble/curves/pasta';
|
||||||
|
import * as stark from '@noble/curves/stark';
|
||||||
|
import { bls12_381 } from '@noble/curves/bls12-381';
|
||||||
|
import { bn254 } from '@noble/curves/bn';
|
||||||
|
import { jubjub } from '@noble/curves/jubjub';
|
||||||
|
```
|
||||||
|
|
||||||
|
To define a custom curve, check out API below.
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
- [Overview](#overview)
|
||||||
|
- [abstract/edwards: Twisted Edwards curve](#abstractedwards-twisted-edwards-curve)
|
||||||
|
- [abstract/montgomery: Montgomery curve](#abstractmontgomery-montgomery-curve)
|
||||||
|
- [abstract/weierstrass: Short Weierstrass curve](#abstractweierstrass-short-weierstrass-curve)
|
||||||
|
- [abstract/hash-to-curve: Hashing strings to curve points](#abstracthash-to-curve-hashing-strings-to-curve-points)
|
||||||
|
- [abstract/modular](#abstractmodular)
|
||||||
|
- [abstract/utils](#abstractutils)
|
||||||
|
|
||||||
|
### Overview
|
||||||
|
|
||||||
|
There are following zero-dependency abstract algorithms:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { bls } from '@noble/curves/abstract/bls';
|
||||||
|
import { twistedEdwards } from '@noble/curves/abstract/edwards';
|
||||||
|
import { montgomery } from '@noble/curves/abstract/montgomery';
|
||||||
|
import { weierstrass } from '@noble/curves/abstract/weierstrass';
|
||||||
|
import * as mod from '@noble/curves/abstract/modular';
|
||||||
|
import * as utils from '@noble/curves/abstract/utils';
|
||||||
|
```
|
||||||
|
|
||||||
|
They allow to define a new curve in a few lines of code:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { Fp } from '@noble/curves/abstract/modular';
|
||||||
|
import { weierstrass } from '@noble/curves/abstract/weierstrass';
|
||||||
import { hmac } from '@noble/hashes/hmac';
|
import { hmac } from '@noble/hashes/hmac';
|
||||||
|
import { sha256 } from '@noble/hashes/sha256';
|
||||||
import { concatBytes, randomBytes } from '@noble/hashes/utils';
|
import { concatBytes, randomBytes } from '@noble/hashes/utils';
|
||||||
|
|
||||||
const secp256k1 = weierstrass({
|
const secp256k1 = weierstrass({
|
||||||
a: 0n,
|
a: 0n,
|
||||||
b: 7n,
|
b: 7n,
|
||||||
P: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn,
|
Fp: Fp(2n ** 256n - 2n ** 32n - 2n ** 9n - 2n ** 8n - 2n ** 7n - 2n ** 6n - 2n ** 4n - 1n),
|
||||||
n: 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n,
|
n: 2n ** 256n - 432420386565659656852420866394968145599n,
|
||||||
Gx: 55066263022277343669578718895168534326250603453777594175500187360389116729240n,
|
Gx: 55066263022277343669578718895168534326250603453777594175500187360389116729240n,
|
||||||
Gy: 32670510020758816978083085130507043184471273380659243275938904335757337482424n,
|
Gy: 32670510020758816978083085130507043184471273380659243275938904335757337482424n,
|
||||||
hash: sha256,
|
hash: sha256,
|
||||||
hmac: (k: Uint8Array, ...msgs: Uint8Array[]) => hmac(sha256, key, concatBytes(...msgs)),
|
hmac: (key: Uint8Array, ...msgs: Uint8Array[]) => hmac(sha256, key, concatBytes(...msgs)),
|
||||||
|
randomBytes,
|
||||||
});
|
});
|
||||||
|
|
||||||
const key = secp256k1.utils.randomPrivateKey();
|
|
||||||
const pub = secp256k1.getPublicKey(key);
|
|
||||||
const msg = randomBytes(32);
|
|
||||||
const sig = secp256k1.sign(msg, key);
|
|
||||||
secp256k1.verify(sig, msg, pub); // true
|
|
||||||
sig.recoverPublicKey(msg); // == pub
|
|
||||||
const someonesPubkey = secp256k1.getPublicKey(secp256k1.utils.randomPrivateKey());
|
|
||||||
const shared = secp256k1.getSharedSecret(key, someonesPubkey);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## API
|
- To initialize new curve, you must specify its variables, order (number of points on curve), field prime (over which the modular division would be done)
|
||||||
|
- All curves expose same generic interface:
|
||||||
- [Overview](#overview)
|
- `getPublicKey()`, `sign()`, `verify()` functions
|
||||||
- [edwards: Twisted Edwards curve](#edwards-twisted-edwards-curve)
|
- `Point` conforming to `Group` interface with add/multiply/double/negate/add/equals methods
|
||||||
- [montgomery: Montgomery curve](#montgomery-montgomery-curve)
|
- `CURVE` object with curve variables like `Gx`, `Gy`, `Fp` (field), `n` (order)
|
||||||
- [weierstrass: Short Weierstrass curve](#weierstrass-short-weierstrass-curve)
|
- `utils` object with `randomPrivateKey()`, `mod()`, `invert()` methods (`mod CURVE.P`)
|
||||||
- [modular](#modular)
|
- All arithmetics is done with JS bigints over finite fields, which is defined from `modular` sub-module
|
||||||
- [utils](#utils)
|
- Many features require hashing, which is not provided. `@noble/hashes` can be used for this purpose.
|
||||||
|
|
||||||
### Overview
|
|
||||||
|
|
||||||
* To initialize new curve, you must specify its variables, order (number of points on curve), field prime (over which the modular division would be done)
|
|
||||||
* All curves expose same generic interface:
|
|
||||||
* `getPublicKey()`, `sign()`, `verify()` functions
|
|
||||||
* `Point` conforming to `Group` interface with add/multiply/double/negate/add/equals methods
|
|
||||||
* `CURVE` object with curve variables like `Gx`, `Gy`, `P` (field), `n` (order)
|
|
||||||
* `utils` object with `randomPrivateKey()`, `mod()`, `invert()` methods (`mod CURVE.P`)
|
|
||||||
* All arithmetics is done with JS bigints over finite fields
|
|
||||||
* Many features require hashing, which is not provided. `@noble/hashes` can be used for this purpose.
|
|
||||||
Any other library must conform to the CHash interface:
|
Any other library must conform to the CHash interface:
|
||||||
```ts
|
```ts
|
||||||
export type CHash = {
|
export type CHash = {
|
||||||
(message: Uint8Array): Uint8Array;
|
(message: Uint8Array): Uint8Array;
|
||||||
blockLen: number; outputLen: number; create(): any;
|
blockLen: number;
|
||||||
};
|
outputLen: number;
|
||||||
```
|
create(): any;
|
||||||
* w-ary non-adjacent form (wNAF) method with constant-time adjustments is used for point multiplication.
|
};
|
||||||
|
```
|
||||||
|
- w-ary non-adjacent form (wNAF) method with constant-time adjustments is used for point multiplication.
|
||||||
It is possible to enable precomputes for edwards & weierstrass curves.
|
It is possible to enable precomputes for edwards & weierstrass curves.
|
||||||
Precomputes are calculated once (takes ~20-40ms), after that most `G` multiplications
|
Precomputes are calculated once (takes ~20-40ms), after that most `G` base point multiplications:
|
||||||
- for example, `getPublicKey()`, `sign()` and similar methods - would be much faster.
|
for example, `getPublicKey()`, `sign()` and similar methods - would be much faster.
|
||||||
Use `curve.utils.precompute()`
|
Use `curve.utils.precompute()` to adjust precomputation window size
|
||||||
* Special params that tune performance can be optionally provided. For example:
|
- You could use optional special params to tune performance:
|
||||||
* `sqrtMod` square root calculation, used for point decompression
|
- `Fp({sqrt})` square root calculation, used for point decompression
|
||||||
* `endo` endomorphism options for Koblitz curves
|
- `endo` endomorphism options for Koblitz curves
|
||||||
|
|
||||||
### edwards: Twisted Edwards curve
|
### abstract/edwards: Twisted Edwards curve
|
||||||
|
|
||||||
Twisted Edwards curve's formula is: ax² + y² = 1 + dx²y².
|
Twisted Edwards curve's formula is: ax² + y² = 1 + dx²y².
|
||||||
|
|
||||||
* You must specify curve params `a`, `d`, field `P`, order `n`, cofactor `h`, and coordinates `Gx`, `Gy` of generator point.
|
- You must specify curve params `a`, `d`, field `Fp`, order `n`, cofactor `h` and coordinates `Gx`, `Gy` of generator point
|
||||||
* For EdDSA signatures, params `hash` is also required. `adjustScalarBytes` which instructs how to change private scalars could be specified.
|
- For EdDSA signatures, params `hash` is also required. `adjustScalarBytes` which instructs how to change private scalars could be specified
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { twistedEdwards } from '@noble/curves/edwards'; // Twisted Edwards curve
|
import { twistedEdwards } from '@noble/curves/abstract/edwards';
|
||||||
|
import { div } from '@noble/curves/abstract/modular';
|
||||||
import { sha512 } from '@noble/hashes/sha512';
|
import { sha512 } from '@noble/hashes/sha512';
|
||||||
import * as mod from '@noble/curves/modular';
|
|
||||||
|
|
||||||
const ed25519 = twistedEdwards({
|
const ed25519 = twistedEdwards({
|
||||||
a: -1n,
|
a: -1n,
|
||||||
d: mod.div(-121665n, 121666n, 2n ** 255n - 19n), // -121665n/121666n
|
d: div(-121665n, 121666n, 2n ** 255n - 19n), // -121665n/121666n
|
||||||
P: 2n ** 255n - 19n,
|
P: 2n ** 255n - 19n,
|
||||||
n: 2n ** 252n + 27742317777372353535851937790883648493n,
|
n: 2n ** 252n + 27742317777372353535851937790883648493n,
|
||||||
h: 8n,
|
h: 8n,
|
||||||
@@ -127,14 +174,19 @@ const ed25519 = twistedEdwards({
|
|||||||
Gy: 46316835694926478169428394003475163141307993866256225615783033603165251855960n,
|
Gy: 46316835694926478169428394003475163141307993866256225615783033603165251855960n,
|
||||||
hash: sha512,
|
hash: sha512,
|
||||||
randomBytes,
|
randomBytes,
|
||||||
adjustScalarBytes(bytes) { // optional
|
adjustScalarBytes(bytes) {
|
||||||
|
// optional in general, mandatory in ed25519
|
||||||
bytes[0] &= 248;
|
bytes[0] &= 248;
|
||||||
bytes[31] &= 127;
|
bytes[31] &= 127;
|
||||||
bytes[31] |= 64;
|
bytes[31] |= 64;
|
||||||
return bytes;
|
return bytes;
|
||||||
},
|
},
|
||||||
} as const);
|
} as const);
|
||||||
ed25519.getPublicKey(ed25519.utils.randomPrivateKey());
|
const key = ed25519.utils.randomPrivateKey();
|
||||||
|
const pub = ed25519.getPublicKey(key);
|
||||||
|
const msg = new TextEncoder().encode('hello world'); // strings not accepted, must be Uint8Array
|
||||||
|
const sig = ed25519.sign(msg, key);
|
||||||
|
ed25519.verify(sig, msg, pub) === true;
|
||||||
```
|
```
|
||||||
|
|
||||||
`twistedEdwards()` returns `CurveFn` of following type:
|
`twistedEdwards()` returns `CurveFn` of following type:
|
||||||
@@ -163,7 +215,7 @@ export type CurveFn = {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
### montgomery: Montgomery curve
|
### abstract/montgomery: Montgomery curve
|
||||||
|
|
||||||
For now the module only contains methods for x-only ECDH on Curve25519 / Curve448 from RFC7748.
|
For now the module only contains methods for x-only ECDH on Curve25519 / Curve448 from RFC7748.
|
||||||
|
|
||||||
@@ -172,6 +224,8 @@ Proper Elliptic Curve Points are not implemented yet.
|
|||||||
You must specify curve field, `a24` special variable, `montgomeryBits`, `nByteLength`, and coordinate `u` of generator point.
|
You must specify curve field, `a24` special variable, `montgomeryBits`, `nByteLength`, and coordinate `u` of generator point.
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
|
import { montgomery } from '@noble/curves/abstract/montgomery';
|
||||||
|
|
||||||
const x25519 = montgomery({
|
const x25519 = montgomery({
|
||||||
P: 2n ** 255n - 19n,
|
P: 2n ** 255n - 19n,
|
||||||
a24: 121665n, // TODO: change to a
|
a24: 121665n, // TODO: change to a
|
||||||
@@ -180,7 +234,9 @@ const x25519 = montgomery({
|
|||||||
Gu: '0900000000000000000000000000000000000000000000000000000000000000',
|
Gu: '0900000000000000000000000000000000000000000000000000000000000000',
|
||||||
|
|
||||||
// Optional params
|
// Optional params
|
||||||
powPminus2: (x: bigint): bigint => { return mod.pow(x, P-2, P); },
|
powPminus2: (x: bigint): bigint => {
|
||||||
|
return mod.pow(x, P - 2, P);
|
||||||
|
},
|
||||||
adjustScalarBytes(bytes) {
|
adjustScalarBytes(bytes) {
|
||||||
bytes[0] &= 248;
|
bytes[0] &= 248;
|
||||||
bytes[31] &= 127;
|
bytes[31] &= 127;
|
||||||
@@ -190,27 +246,27 @@ const x25519 = montgomery({
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
### weierstrass: Short Weierstrass curve
|
### abstract/weierstrass: Short Weierstrass curve
|
||||||
|
|
||||||
Short Weierstrass curve's formula is: y² = x³ + ax + b. Uses deterministic ECDSA from RFC6979. You can also specify `extraEntropy` in `sign()`.
|
Short Weierstrass curve's formula is: y² = x³ + ax + b. Uses deterministic ECDSA from RFC6979. You can also specify `extraEntropy` in `sign()`.
|
||||||
|
|
||||||
* You must specify curve params: `a`, `b`; field `P`; curve order `n`; coordinates `Gx`, `Gy` of generator point
|
- You must specify curve params: `a`, `b`, field `Fp`, order `n`, cofactor `h` and coordinates `Gx`, `Gy` of generator point
|
||||||
* For ECDSA, you must specify `hash`, `hmac`. It is also possible to recover keys from signatures
|
- For ECDSA, you must specify `hash`, `hmac`. It is also possible to recover keys from signatures
|
||||||
* For ECDH, use `getSharedSecret(privKeyA, pubKeyB)`
|
- For ECDH, use `getSharedSecret(privKeyA, pubKeyB)`
|
||||||
* Optional params are `lowS` (default value), `sqrtMod` (square root chain) and `endo` (endomorphism)
|
- Optional params are `lowS` (default value) and `endo` (endomorphism)
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import { weierstrass } from '@noble/curves/weierstrass'; // Short Weierstrass curve
|
import { Fp } from '@noble/curves/abstract/modular';
|
||||||
|
import { weierstrass } from '@noble/curves/abstract/weierstrass'; // Short Weierstrass curve
|
||||||
import { sha256 } from '@noble/hashes/sha256';
|
import { sha256 } from '@noble/hashes/sha256';
|
||||||
import { hmac } from '@noble/hashes/hmac';
|
import { hmac } from '@noble/hashes/hmac';
|
||||||
import { concatBytes, randomBytes } from '@noble/hashes/utils';
|
import { concatBytes, randomBytes } from '@noble/hashes/utils';
|
||||||
|
|
||||||
const secp256k1 = weierstrass({
|
const secp256k1 = weierstrass({
|
||||||
// Required params
|
|
||||||
a: 0n,
|
a: 0n,
|
||||||
b: 7n,
|
b: 7n,
|
||||||
P: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn,
|
Fp: Fp(2n ** 256n - 2n ** 32n - 2n ** 9n - 2n ** 8n - 2n ** 7n - 2n ** 6n - 2n ** 4n - 1n),
|
||||||
n: 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n,
|
n: 2n ** 256n - 432420386565659656852420866394968145599n,
|
||||||
Gx: 55066263022277343669578718895168534326250603453777594175500187360389116729240n,
|
Gx: 55066263022277343669578718895168534326250603453777594175500187360389116729240n,
|
||||||
Gy: 32670510020758816978083085130507043184471273380659243275938904335757337482424n,
|
Gy: 32670510020758816978083085130507043184471273380659243275938904335757337482424n,
|
||||||
hash: sha256,
|
hash: sha256,
|
||||||
@@ -218,19 +274,15 @@ const secp256k1 = weierstrass({
|
|||||||
randomBytes,
|
randomBytes,
|
||||||
|
|
||||||
// Optional params
|
// Optional params
|
||||||
// Cofactor
|
h: 1n, // Cofactor
|
||||||
h: BigInt(1),
|
lowS: true, // Allow only low-S signatures by default in sign() and verify()
|
||||||
// Allow only low-S signatures by default in sign() and verify()
|
|
||||||
lowS: true,
|
|
||||||
// More efficient curve-specific implementation of square root
|
|
||||||
sqrtMod(y: bigint) { return sqrt(y); },
|
|
||||||
// Endomorphism options
|
|
||||||
endo: {
|
endo: {
|
||||||
|
// Endomorphism options for Koblitz curve
|
||||||
// Beta param
|
// Beta param
|
||||||
beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),
|
beta: 0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501een,
|
||||||
// Split scalar k into k1, k2
|
// Split scalar k into k1, k2
|
||||||
splitScalar: (k: bigint) => {
|
splitScalar: (k: bigint) => {
|
||||||
return { k1neg: true, k1: 512n, k2neg: false, k2: 448n };
|
// return { k1neg: true, k1: 512n, k2neg: false, k2: 448n };
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -255,14 +307,17 @@ export type CurveFn = {
|
|||||||
getSharedSecret: (privateA: PrivKey, publicB: PubKey, isCompressed?: boolean) => Uint8Array;
|
getSharedSecret: (privateA: PrivKey, publicB: PubKey, isCompressed?: boolean) => Uint8Array;
|
||||||
sign: (msgHash: Hex, privKey: PrivKey, opts?: SignOpts) => SignatureType;
|
sign: (msgHash: Hex, privKey: PrivKey, opts?: SignOpts) => SignatureType;
|
||||||
verify: (
|
verify: (
|
||||||
signature: Hex | SignatureType, msgHash: Hex, publicKey: PubKey, opts?: {lowS?: boolean;}
|
signature: Hex | SignatureType,
|
||||||
|
msgHash: Hex,
|
||||||
|
publicKey: PubKey,
|
||||||
|
opts?: { lowS?: boolean }
|
||||||
) => boolean;
|
) => boolean;
|
||||||
Point: PointConstructor;
|
Point: PointConstructor;
|
||||||
JacobianPoint: JacobianPointConstructor;
|
ProjectivePoint: ProjectivePointConstructor;
|
||||||
Signature: SignatureConstructor;
|
Signature: SignatureConstructor;
|
||||||
utils: {
|
utils: {
|
||||||
mod: (a: bigint, b?: bigint) => bigint;
|
mod: (a: bigint) => bigint;
|
||||||
invert: (number: bigint, modulo?: bigint) => bigint;
|
invert: (number: bigint) => bigint;
|
||||||
isValidPrivateKey(privateKey: PrivKey): boolean;
|
isValidPrivateKey(privateKey: PrivKey): boolean;
|
||||||
hashToPrivateKey: (hash: Hex) => Uint8Array;
|
hashToPrivateKey: (hash: Hex) => Uint8Array;
|
||||||
randomPrivateKey: () => Uint8Array;
|
randomPrivateKey: () => Uint8Array;
|
||||||
@@ -270,23 +325,76 @@ export type CurveFn = {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
### modular
|
### 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.
|
Modular arithmetics utilities.
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import * as mod from '@noble/curves/modular';
|
import { Fp, mod, invert, div, invertBatch, sqrt } from '@noble/curves/abstract/modular';
|
||||||
mod.mod(21n, 10n); // 21 mod 10 == 1n; fixed version of 21 % 10
|
const fp = Fp(2n ** 255n - 19n); // Finite field over 2^255-19
|
||||||
mod.invert(17n, 10n); // invert(17) mod 10; modular multiplicative inverse
|
fp.mul(591n, 932n);
|
||||||
mod.div(5n, 17n, 10n); // 5/17 mod 10 == 5 * invert(17) mod 10; division
|
fp.pow(481n, 11024858120n);
|
||||||
mod.invertBatch([1n, 2n, 4n], 21n); // => [1n, 11n, 16n] in one inversion
|
|
||||||
mod.sqrt(21n, 73n); // sqrt(21) mod 73; square root
|
// 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
|
||||||
```
|
```
|
||||||
|
|
||||||
### utils
|
### abstract/utils
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
import * as utils from '@noble/curves/utils';
|
import * as utils from '@noble/curves/abstract/utils';
|
||||||
|
|
||||||
utils.bytesToHex(Uint8Array.from([0xde, 0xad, 0xbe, 0xef]));
|
utils.bytesToHex(Uint8Array.from([0xde, 0xad, 0xbe, 0xef]));
|
||||||
utils.hexToBytes('deadbeef');
|
utils.hexToBytes('deadbeef');
|
||||||
@@ -315,59 +423,43 @@ We consider infrastructure attacks like rogue NPM modules very important; that's
|
|||||||
Benchmark results on Apple M2 with node v18.10:
|
Benchmark results on Apple M2 with node v18.10:
|
||||||
|
|
||||||
```
|
```
|
||||||
==== secp256k1 ====
|
getPublicKey
|
||||||
- getPublicKey1 (samples: 10000)
|
secp256k1 x 5,241 ops/sec @ 190μs/op
|
||||||
noble_old x 8,131 ops/sec @ 122μs/op
|
P256 x 7,993 ops/sec @ 125μs/op
|
||||||
secp256k1 x 7,374 ops/sec @ 135μs/op
|
P384 x 3,819 ops/sec @ 261μs/op
|
||||||
- getPublicKey255 (samples: 10000)
|
P521 x 2,074 ops/sec @ 481μs/op
|
||||||
noble_old x 7,894 ops/sec @ 126μs/op
|
ed25519 x 8,390 ops/sec @ 119μs/op
|
||||||
secp256k1 x 7,327 ops/sec @ 136μs/op
|
ed448 x 3,224 ops/sec @ 310μs/op
|
||||||
- sign (samples: 5000)
|
sign
|
||||||
noble_old x 5,243 ops/sec @ 190μs/op
|
secp256k1 x 3,934 ops/sec @ 254μs/op
|
||||||
secp256k1 x 4,834 ops/sec @ 206μs/op
|
P256 x 5,327 ops/sec @ 187μs/op
|
||||||
- getSharedSecret (samples: 1000)
|
P384 x 2,728 ops/sec @ 366μs/op
|
||||||
noble_old x 653 ops/sec @ 1ms/op
|
P521 x 1,594 ops/sec @ 626μs/op
|
||||||
secp256k1 x 634 ops/sec @ 1ms/op
|
ed25519 x 4,233 ops/sec @ 236μs/op
|
||||||
- verify (samples: 1000)
|
ed448 x 1,561 ops/sec @ 640μs/op
|
||||||
secp256k1_old x 1,038 ops/sec @ 962μs/op
|
verify
|
||||||
secp256k1 x 1,009 ops/sec @ 990μs/op
|
secp256k1 x 731 ops/sec @ 1ms/op
|
||||||
==== ed25519 ====
|
P256 x 806 ops/sec @ 1ms/op
|
||||||
- getPublicKey (samples: 10000)
|
P384 x 353 ops/sec @ 2ms/op
|
||||||
old x 8,632 ops/sec @ 115μs/op
|
P521 x 171 ops/sec @ 5ms/op
|
||||||
noble x 8,390 ops/sec @ 119μs/op
|
ed25519 x 860 ops/sec @ 1ms/op
|
||||||
- sign (samples: 5000)
|
ed448 x 313 ops/sec @ 3ms/op
|
||||||
old x 4,376 ops/sec @ 228μs/op
|
getSharedSecret
|
||||||
noble x 4,233 ops/sec @ 236μs/op
|
secp256k1 x 445 ops/sec @ 2ms/op
|
||||||
- verify (samples: 1000)
|
recoverPublicKey
|
||||||
old x 865 ops/sec @ 1ms/op
|
secp256k1 x 732 ops/sec @ 1ms/op
|
||||||
noble x 860 ops/sec @ 1ms/op
|
==== bls12-381 ====
|
||||||
==== ed448 ====
|
getPublicKey x 817 ops/sec @ 1ms/op
|
||||||
- getPublicKey (samples: 5000)
|
sign x 50 ops/sec @ 19ms/op
|
||||||
noble x 3,224 ops/sec @ 310μs/op
|
verify x 34 ops/sec @ 28ms/op
|
||||||
- sign (samples: 2500)
|
pairing x 89 ops/sec @ 11ms/op
|
||||||
noble x 1,561 ops/sec @ 640μs/op
|
|
||||||
- verify (samples: 500)
|
|
||||||
noble x 313 ops/sec @ 3ms/op
|
|
||||||
==== nist ====
|
|
||||||
- getPublicKey (samples: 2500)
|
|
||||||
P256 x 7,993 ops/sec @ 125μs/op
|
|
||||||
P384 x 3,819 ops/sec @ 261μs/op
|
|
||||||
P521 x 2,074 ops/sec @ 481μs/op
|
|
||||||
- sign (samples: 1000)
|
|
||||||
P256 x 5,327 ops/sec @ 187μs/op
|
|
||||||
P384 x 2,728 ops/sec @ 366μs/op
|
|
||||||
P521 x 1,594 ops/sec @ 626μs/op
|
|
||||||
- verify (samples: 250)
|
|
||||||
P256 x 806 ops/sec @ 1ms/op
|
|
||||||
P384 x 353 ops/sec @ 2ms/op
|
|
||||||
P521 x 171 ops/sec @ 5ms/op
|
|
||||||
==== stark ====
|
==== stark ====
|
||||||
- pedersen (samples: 500)
|
pedersen
|
||||||
old x 85 ops/sec @ 11ms/op
|
old x 85 ops/sec @ 11ms/op
|
||||||
noble x 1,216 ops/sec @ 822μs/op
|
noble x 1,216 ops/sec @ 822μs/op
|
||||||
- verify (samples: 500)
|
verify
|
||||||
old x 302 ops/sec @ 3ms/op
|
old x 302 ops/sec @ 3ms/op
|
||||||
noble x 698 ops/sec @ 1ms/op
|
noble x 698 ops/sec @ 1ms/op
|
||||||
```
|
```
|
||||||
|
|
||||||
## Contributing & testing
|
## Contributing & testing
|
||||||
|
|||||||
18
SECURITY.md
Normal file
18
SECURITY.md
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Security Policy
|
||||||
|
|
||||||
|
## Supported Versions
|
||||||
|
|
||||||
|
| Version | Supported |
|
||||||
|
| ------- | ------------------ |
|
||||||
|
| >=0.5.0 | :white_check_mark: |
|
||||||
|
| <0.5.0 | :x: |
|
||||||
|
|
||||||
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
|
Use maintainer's email specified at https://github.com/paulmillr.
|
||||||
|
|
||||||
|
It's preferred that you use
|
||||||
|
PGP key from [pgp proof](https://paulmillr.com/pgp_proof.txt) (current is [697079DA6878B89B](https://paulmillr.com/pgp_proof.txt)).
|
||||||
|
Ensure the pgp proof page has maintainer's site/github specified.
|
||||||
|
|
||||||
|
You will get an update as soon as the email is read; a "Security vulnerability" phrase in email's title would help.
|
||||||
@@ -96,6 +96,10 @@ export const CURVES = {
|
|||||||
old_secp.recoverPublicKey(msg, new old_secp.Signature(sig.r, sig.s), sig.recovery),
|
old_secp.recoverPublicKey(msg, new old_secp.Signature(sig.r, sig.s), sig.recovery),
|
||||||
secp256k1: ({ sig, msg }) => sig.recoverPublicKey(msg),
|
secp256k1: ({ sig, msg }) => sig.recoverPublicKey(msg),
|
||||||
},
|
},
|
||||||
|
hashToCurve: {
|
||||||
|
samples: 500,
|
||||||
|
noble: () => secp256k1.Point.hashToCurve('abcd'),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
ed25519: {
|
ed25519: {
|
||||||
data: () => {
|
data: () => {
|
||||||
@@ -124,6 +128,10 @@ export const CURVES = {
|
|||||||
old: ({ sig, msg, pub }) => noble_ed25519.sync.verify(sig, msg, pub),
|
old: ({ sig, msg, pub }) => noble_ed25519.sync.verify(sig, msg, pub),
|
||||||
noble: ({ sig, msg, pub }) => ed25519.verify(sig, msg, pub),
|
noble: ({ sig, msg, pub }) => ed25519.verify(sig, msg, pub),
|
||||||
},
|
},
|
||||||
|
hashToCurve: {
|
||||||
|
samples: 500,
|
||||||
|
noble: () => ed25519.Point.hashToCurve('abcd'),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
ed448: {
|
ed448: {
|
||||||
data: () => {
|
data: () => {
|
||||||
@@ -145,6 +153,10 @@ export const CURVES = {
|
|||||||
samples: 500,
|
samples: 500,
|
||||||
noble: ({ sig, msg, pub }) => ed448.verify(sig, msg, pub),
|
noble: ({ sig, msg, pub }) => ed448.verify(sig, msg, pub),
|
||||||
},
|
},
|
||||||
|
hashToCurve: {
|
||||||
|
samples: 500,
|
||||||
|
noble: () => ed448.Point.hashToCurve('abcd'),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
nist: {
|
nist: {
|
||||||
data: () => {
|
data: () => {
|
||||||
@@ -168,6 +180,12 @@ export const CURVES = {
|
|||||||
P384: ({ p384: { sig, msg, pub } }) => P384.verify(sig, msg, pub),
|
P384: ({ p384: { sig, msg, pub } }) => P384.verify(sig, msg, pub),
|
||||||
P521: ({ p521: { sig, msg, pub } }) => P521.verify(sig, msg, pub),
|
P521: ({ p521: { sig, msg, pub } }) => P521.verify(sig, msg, pub),
|
||||||
},
|
},
|
||||||
|
hashToCurve: {
|
||||||
|
samples: 500,
|
||||||
|
P256: () => P256.Point.hashToCurve('abcd'),
|
||||||
|
P384: () => P384.Point.hashToCurve('abcd'),
|
||||||
|
P521: () => P521.Point.hashToCurve('abcd'),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
stark: {
|
stark: {
|
||||||
data: () => {
|
data: () => {
|
||||||
@@ -304,6 +322,17 @@ export const CURVES = {
|
|||||||
old: () => old_bls.pairing(oldp1, oldp2),
|
old: () => old_bls.pairing(oldp1, oldp2),
|
||||||
noble: () => bls.pairing(p1, p2),
|
noble: () => bls.pairing(p1, p2),
|
||||||
},
|
},
|
||||||
|
'hashToCurve/G1': {
|
||||||
|
samples: 500,
|
||||||
|
old: () => old_bls.PointG1.hashToCurve('abcd'),
|
||||||
|
noble: () => bls.G1.Point.hashToCurve('abcd'),
|
||||||
|
},
|
||||||
|
'hashToCurve/G2': {
|
||||||
|
samples: 200,
|
||||||
|
old: () => old_bls.PointG2.hashToCurve('abcd'),
|
||||||
|
noble: () => bls.G2.Point.hashToCurve('abcd'),
|
||||||
|
},
|
||||||
|
// SLOW PART
|
||||||
// Requires points which we cannot init before (data fn same for all)
|
// Requires points which we cannot init before (data fn same for all)
|
||||||
// await mark('sign/nc', 30, () => bls.sign(msgp, priv));
|
// await mark('sign/nc', 30, () => bls.sign(msgp, priv));
|
||||||
// await mark('verify/nc', 30, () => bls.verify(sigp, msgp, pubp));
|
// await mark('verify/nc', 30, () => bls.verify(sigp, msgp, pubp));
|
||||||
@@ -357,16 +386,6 @@ export const CURVES = {
|
|||||||
old: ({ sig2048 }) => old_bls.aggregateSignatures(sig2048.map(old_bls.PointG2.fromSignature)),
|
old: ({ sig2048 }) => old_bls.aggregateSignatures(sig2048.map(old_bls.PointG2.fromSignature)),
|
||||||
noble: ({ sig2048 }) => bls.aggregateSignatures(sig2048.map(bls.Signature.decode)),
|
noble: ({ sig2048 }) => bls.aggregateSignatures(sig2048.map(bls.Signature.decode)),
|
||||||
},
|
},
|
||||||
'hashToCurve/G1': {
|
|
||||||
samples: 500,
|
|
||||||
old: () => old_bls.PointG1.hashToCurve('abcd'),
|
|
||||||
noble: () => bls.G1.Point.hashToCurve('abcd'),
|
|
||||||
},
|
|
||||||
'hashToCurve/G2': {
|
|
||||||
samples: 200,
|
|
||||||
old: () => old_bls.PointG2.hashToCurve('abcd'),
|
|
||||||
noble: () => bls.G2.Point.hashToCurve('abcd'),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -12,12 +12,15 @@
|
|||||||
"author": "",
|
"author": "",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"micro-bmark": "0.2.0"
|
"micro-bmark": "0.2.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@noble/bls12-381": "^1.4.0",
|
"@noble/bls12-381": "^1.4.0",
|
||||||
"@noble/ed25519": "^1.7.1",
|
"@noble/ed25519": "^1.7.1",
|
||||||
|
"@noble/hashes": "^1.1.5",
|
||||||
"@noble/secp256k1": "^1.7.0",
|
"@noble/secp256k1": "^1.7.0",
|
||||||
"@starkware-industries/starkware-crypto-utils": "^0.0.2"
|
"@starkware-industries/starkware-crypto-utils": "^0.0.2",
|
||||||
|
"calculate-correlation": "^1.2.3",
|
||||||
|
"elliptic": "^6.5.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2022 Paul Miller (https://paulmillr.com)
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the “Software”), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
# micro-curve-definitions
|
|
||||||
|
|
||||||
Elliptic curves implementations. `@noble/curves` is zero-dependency library for internal arithmetics.
|
|
||||||
|
|
||||||
`micro-curve-definitions` is the actual implementations. Current functionality:
|
|
||||||
|
|
||||||
- NIST curves: P192, P224, P256, P384, P521 (ECDSA)
|
|
||||||
- secp256k1 (ECDSA, without Schnorr)
|
|
||||||
- stark curve
|
|
||||||
- bn254
|
|
||||||
|
|
||||||
Pairings are not implemented.
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm install micro-curve-definitions
|
|
||||||
```
|
|
||||||
|
|
||||||
```ts
|
|
||||||
import * as nist from 'micro-curve-definitions';
|
|
||||||
|
|
||||||
// P192, P224, P256, P384, P521, bn254
|
|
||||||
```
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
MIT (c) Paul Miller [(https://paulmillr.com)](https://paulmillr.com), see LICENSE file.
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "micro-curve-definitions",
|
|
||||||
"version": "0.4.0",
|
|
||||||
"description": "Curve definitions for @noble/curves",
|
|
||||||
"files": [
|
|
||||||
"lib"
|
|
||||||
],
|
|
||||||
"main": "lib/index.js",
|
|
||||||
"module": "lib/index.js",
|
|
||||||
"types": "lib/index.d.ts",
|
|
||||||
"dependencies": {
|
|
||||||
"@noble/curves": "0.4.0",
|
|
||||||
"@noble/hashes": "1.1.5"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@scure/base": "~1.1.0",
|
|
||||||
"@scure/bip32": "^1.1.1",
|
|
||||||
"@scure/bip39": "^1.1.0",
|
|
||||||
"@types/node": "18.11.3",
|
|
||||||
"fast-check": "3.0.0",
|
|
||||||
"micro-should": "0.2.0",
|
|
||||||
"prettier": "2.6.2",
|
|
||||||
"typescript": "4.7.3"
|
|
||||||
},
|
|
||||||
"author": "Paul Miller (https://paulmillr.com)",
|
|
||||||
"license": "MIT",
|
|
||||||
"homepage": "https://github.com/paulmillr/noble-curves",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/paulmillr/noble-curves.git"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"build": "tsc && tsc -p tsconfig.esm.json",
|
|
||||||
"lint": "prettier --check src",
|
|
||||||
"test": "node test/index.test.js"
|
|
||||||
},
|
|
||||||
"keywords": [
|
|
||||||
"secp192r1",
|
|
||||||
"secp224r1",
|
|
||||||
"secp256r1",
|
|
||||||
"secp384r1",
|
|
||||||
"secp521r1",
|
|
||||||
"NIST P192",
|
|
||||||
"NIST P224",
|
|
||||||
"NIST P256",
|
|
||||||
"NIST P384",
|
|
||||||
"NIST P521",
|
|
||||||
"NIST curves",
|
|
||||||
"EC",
|
|
||||||
"elliptic curves"
|
|
||||||
],
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "individual",
|
|
||||||
"url": "https://paulmillr.com/funding/"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,146 +0,0 @@
|
|||||||
/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
||||||
import { shake256 } from '@noble/hashes/sha3';
|
|
||||||
import { concatBytes, randomBytes, utf8ToBytes, wrapConstructor } from '@noble/hashes/utils';
|
|
||||||
import { twistedEdwards } from '@noble/curves/edwards';
|
|
||||||
import { mod, pow2, Fp } from '@noble/curves/modular';
|
|
||||||
import { montgomery } from '../../lib/montgomery.js';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Edwards448 (not Ed448-Goldilocks) curve with following addons:
|
|
||||||
* * X448 ECDH
|
|
||||||
* Conforms to RFC 8032 https://www.rfc-editor.org/rfc/rfc8032.html#section-5.2
|
|
||||||
*/
|
|
||||||
|
|
||||||
const shake256_114 = wrapConstructor(() => shake256.create({ dkLen: 114 }));
|
|
||||||
const shake256_64 = wrapConstructor(() => shake256.create({ dkLen: 64 }));
|
|
||||||
const ed448P = BigInt(
|
|
||||||
'726838724295606890549323807888004534353641360687318060281490199180612328166730772686396383698676545930088884461843637361053498018365439'
|
|
||||||
);
|
|
||||||
|
|
||||||
// powPminus3div4 calculates z = x^k mod p, where k = (p-3)/4.
|
|
||||||
function ed448_pow_Pminus3div4(x: bigint): bigint {
|
|
||||||
const P = ed448P;
|
|
||||||
// prettier-ignore
|
|
||||||
let [_1n, _2n, _3n, _11n, _22n, _44n, _88n, _223n] = [1, 2, 3, 11, 22, 44, 88, 223]
|
|
||||||
.map(n => BigInt(n));
|
|
||||||
// x ** ((P - 3n)/4n) % P
|
|
||||||
// [223 of 1, 0, 222 of 1], almost same as secp!
|
|
||||||
const b2 = (x * x * x) % P;
|
|
||||||
const b3 = (b2 * b2 * x) % P;
|
|
||||||
const b6 = (pow2(b3, _3n, P) * b3) % P;
|
|
||||||
const b9 = (pow2(b6, _3n, P) * b3) % P;
|
|
||||||
const b11 = (pow2(b9, _2n, P) * b2) % P;
|
|
||||||
const b22 = (pow2(b11, _11n, P) * b11) % P;
|
|
||||||
const b44 = (pow2(b22, _22n, P) * b22) % P;
|
|
||||||
const b88 = (pow2(b44, _44n, P) * b44) % P;
|
|
||||||
const b176 = (pow2(b88, _88n, P) * b88) % P;
|
|
||||||
const b220 = (pow2(b176, _44n, P) * b44) % P;
|
|
||||||
const b222 = (pow2(b220, _2n, P) * b2) % P;
|
|
||||||
const b223 = (pow2(b222, _1n, P) * x) % P;
|
|
||||||
return (pow2(b223, _223n, P) * b222) % P;
|
|
||||||
}
|
|
||||||
|
|
||||||
function adjustScalarBytes(bytes: Uint8Array): Uint8Array {
|
|
||||||
// Section 5: Likewise, for X448, set the two least significant bits of the first byte to 0, and the most
|
|
||||||
// significant bit of the last byte to 1.
|
|
||||||
bytes[0] &= 252; // 0b11111100
|
|
||||||
// and the most significant bit of the last byte to 1.
|
|
||||||
bytes[55] |= 128; // 0b10000000
|
|
||||||
// NOTE: is is NOOP for 56 bytes scalars (X25519/X448)
|
|
||||||
bytes[56] = 0; // Byte outside of group (456 buts vs 448 bits)
|
|
||||||
return bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ED448_DEF = {
|
|
||||||
// Param: a
|
|
||||||
a: BigInt(1),
|
|
||||||
// -39081. Negative number is P - number
|
|
||||||
d: BigInt(
|
|
||||||
'726838724295606890549323807888004534353641360687318060281490199180612328166730772686396383698676545930088884461843637361053498018326358'
|
|
||||||
),
|
|
||||||
// Finite field 𝔽p over which we'll do calculations; 2n ** 448n - 2n ** 224n - 1n
|
|
||||||
Fp: Fp(ed448P, 456),
|
|
||||||
// Subgroup order: how many points ed448 has; 2n**446n - 13818066809895115352007386748515426880336692474882178609894547503885n
|
|
||||||
n: BigInt(
|
|
||||||
'181709681073901722637330951972001133588410340171829515070372549795146003961539585716195755291692375963310293709091662304773755859649779'
|
|
||||||
),
|
|
||||||
nBitLength: 456,
|
|
||||||
// Cofactor
|
|
||||||
h: BigInt(4),
|
|
||||||
// Base point (x, y) aka generator point
|
|
||||||
Gx: BigInt(
|
|
||||||
'224580040295924300187604334099896036246789641632564134246125461686950415467406032909029192869357953282578032075146446173674602635247710'
|
|
||||||
),
|
|
||||||
Gy: BigInt(
|
|
||||||
'298819210078481492676017930443930673437544040154080242095928241372331506189835876003536878655418784733982303233503462500531545062832660'
|
|
||||||
),
|
|
||||||
// SHAKE256(dom4(phflag,context)||x, 114)
|
|
||||||
hash: shake256_114,
|
|
||||||
randomBytes,
|
|
||||||
adjustScalarBytes,
|
|
||||||
// dom4
|
|
||||||
domain: (data: Uint8Array, ctx: Uint8Array, phflag: boolean) => {
|
|
||||||
if (ctx.length > 255) throw new Error(`Context is too big: ${ctx.length}`);
|
|
||||||
return concatBytes(
|
|
||||||
utf8ToBytes('SigEd448'),
|
|
||||||
new Uint8Array([phflag ? 1 : 0, ctx.length]),
|
|
||||||
ctx,
|
|
||||||
data
|
|
||||||
);
|
|
||||||
},
|
|
||||||
// Constant-time ratio of u to v. Allows to combine inversion and square root u/√v.
|
|
||||||
// Uses algo from RFC8032 5.1.3.
|
|
||||||
uvRatio: (u: bigint, v: bigint): { isValid: boolean; value: bigint } => {
|
|
||||||
const P = ed448P;
|
|
||||||
// https://datatracker.ietf.org/doc/html/rfc8032#section-5.2.3
|
|
||||||
// To compute the square root of (u/v), the first step is to compute the
|
|
||||||
// candidate root x = (u/v)^((p+1)/4). This can be done using the
|
|
||||||
// following trick, to use a single modular powering for both the
|
|
||||||
// inversion of v and the square root:
|
|
||||||
// (p+1)/4 3 (p-3)/4
|
|
||||||
// x = (u/v) = u v (u^5 v^3) (mod p)
|
|
||||||
const u2v = mod(u * u * v, P);
|
|
||||||
const u3v = mod(u2v * u, P); // u^2v
|
|
||||||
const u5v3 = mod(u3v * u2v * v, P); // u^5v^3
|
|
||||||
const root = ed448_pow_Pminus3div4(u5v3);
|
|
||||||
const x = mod(u3v * root, P);
|
|
||||||
// Verify that root is exists
|
|
||||||
const x2 = mod(x * x, P); // x^2
|
|
||||||
// If v * x^2 = u, the recovered x-coordinate is x. Otherwise, no
|
|
||||||
// square root exists, and the decoding fails.
|
|
||||||
return { isValid: mod(x2 * v, P) === u, value: x };
|
|
||||||
},
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export const ed448 = twistedEdwards(ED448_DEF);
|
|
||||||
// NOTE: there is no ed448ctx, since ed448 supports ctx by default
|
|
||||||
export const ed448ph = twistedEdwards({ ...ED448_DEF, preHash: shake256_64 });
|
|
||||||
|
|
||||||
export const x448 = montgomery({
|
|
||||||
a24: BigInt(39081),
|
|
||||||
montgomeryBits: 448,
|
|
||||||
nByteLength: 57,
|
|
||||||
P: ed448P,
|
|
||||||
Gu: '0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
|
|
||||||
powPminus2: (x: bigint): bigint => {
|
|
||||||
const P = ed448P;
|
|
||||||
const Pminus3div4 = ed448_pow_Pminus3div4(x);
|
|
||||||
const Pminus3 = pow2(Pminus3div4, BigInt(2), P);
|
|
||||||
return mod(Pminus3 * x, P); // Pminus3 * x = Pminus2
|
|
||||||
},
|
|
||||||
adjustScalarBytes,
|
|
||||||
// The 4-isogeny maps between the Montgomery curve and this Edwards
|
|
||||||
// curve are:
|
|
||||||
// (u, v) = (y^2/x^2, (2 - x^2 - y^2)*y/x^3)
|
|
||||||
// (x, y) = (4*v*(u^2 - 1)/(u^4 - 2*u^2 + 4*v^2 + 1),
|
|
||||||
// -(u^5 - 2*u^3 - 4*u*v^2 + u)/
|
|
||||||
// (u^5 - 2*u^2*v^2 - 2*u^3 - 2*v^2 + u))
|
|
||||||
// xyToU: (p: PointType) => {
|
|
||||||
// const P = ed448P;
|
|
||||||
// const { x, y } = p;
|
|
||||||
// if (x === _0n) throw new Error(`Point with x=0 doesn't have mapping`);
|
|
||||||
// const invX = invert(x * x, P); // x^2
|
|
||||||
// const u = mod(y * y * invX, P); // (y^2/x^2)
|
|
||||||
// return numberToBytesLE(u, 56);
|
|
||||||
// },
|
|
||||||
});
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
||||||
import { createCurve } from './_shortw_utils.js';
|
|
||||||
import { sha256 } from '@noble/hashes/sha256';
|
|
||||||
import { Fp } from '@noble/curves/modular';
|
|
||||||
|
|
||||||
// NIST secp256r1 aka P256
|
|
||||||
// https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/nist/P-256
|
|
||||||
export const P256 = createCurve(
|
|
||||||
{
|
|
||||||
// Params: a, b
|
|
||||||
a: BigInt('0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc'),
|
|
||||||
b: BigInt('0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b'),
|
|
||||||
// Field over which we'll do calculations; 2n**224n * (2n**32n-1n) + 2n**192n + 2n**96n-1n
|
|
||||||
Fp: Fp(BigInt('0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff')),
|
|
||||||
// Curve order, total count of valid points in the field
|
|
||||||
n: BigInt('0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551'),
|
|
||||||
// Base point (x, y) aka generator point
|
|
||||||
Gx: BigInt('0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296'),
|
|
||||||
Gy: BigInt('0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5'),
|
|
||||||
h: BigInt(1),
|
|
||||||
lowS: false,
|
|
||||||
} as const,
|
|
||||||
sha256
|
|
||||||
);
|
|
||||||
export const secp256r1 = P256;
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
||||||
import { createCurve } from './_shortw_utils.js';
|
|
||||||
import { sha384 } from '@noble/hashes/sha512';
|
|
||||||
import { Fp } from '@noble/curves/modular';
|
|
||||||
|
|
||||||
// NIST secp384r1 aka P384
|
|
||||||
// https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/nist/P-384
|
|
||||||
// prettier-ignore
|
|
||||||
export const P384 = createCurve({
|
|
||||||
// Params: a, b
|
|
||||||
a: BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffc'),
|
|
||||||
b: BigInt('0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef'),
|
|
||||||
// Field over which we'll do calculations. 2n**384n - 2n**128n - 2n**96n + 2n**32n - 1n
|
|
||||||
Fp: Fp(BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff')),
|
|
||||||
// Curve order, total count of valid points in the field.
|
|
||||||
n: BigInt('0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973'),
|
|
||||||
// Base point (x, y) aka generator point
|
|
||||||
Gx: BigInt('0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7'),
|
|
||||||
Gy: BigInt('0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f'),
|
|
||||||
h: BigInt(1),
|
|
||||||
lowS: false,
|
|
||||||
} as const, sha384);
|
|
||||||
export const secp384r1 = P384;
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "module",
|
|
||||||
"browser": {
|
|
||||||
"crypto": false,
|
|
||||||
"./crypto": "./esm/cryptoBrowser.js"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"strict": true,
|
|
||||||
"declaration": true,
|
|
||||||
"declarationMap": true,
|
|
||||||
"target": "es2020",
|
|
||||||
"lib": [
|
|
||||||
"es2020",
|
|
||||||
"dom"
|
|
||||||
],
|
|
||||||
"module": "es6",
|
|
||||||
"moduleResolution": "node16",
|
|
||||||
"outDir": "lib/esm",
|
|
||||||
"noImplicitAny": true,
|
|
||||||
"preserveConstEnums": true,
|
|
||||||
"baseUrl": ".",
|
|
||||||
},
|
|
||||||
"include": [
|
|
||||||
"src",
|
|
||||||
],
|
|
||||||
"exclude": [
|
|
||||||
"node_modules",
|
|
||||||
"lib"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"strict": true,
|
|
||||||
"declaration": true,
|
|
||||||
"declarationMap": true,
|
|
||||||
"target": "es2020",
|
|
||||||
"lib": [
|
|
||||||
"es2020",
|
|
||||||
"dom"
|
|
||||||
],
|
|
||||||
"module": "commonjs",
|
|
||||||
"moduleResolution": "node16",
|
|
||||||
"outDir": "lib",
|
|
||||||
"noImplicitAny": true,
|
|
||||||
"preserveConstEnums": true,
|
|
||||||
"baseUrl": ".",
|
|
||||||
},
|
|
||||||
"include": [
|
|
||||||
"src",
|
|
||||||
],
|
|
||||||
"exclude": [
|
|
||||||
"node_modules",
|
|
||||||
"lib"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
182
package.json
182
package.json
@@ -1,19 +1,17 @@
|
|||||||
{
|
{
|
||||||
"name": "@noble/curves",
|
"name": "@noble/curves",
|
||||||
"version": "0.4.0",
|
"version": "0.5.1",
|
||||||
"description": "Minimal, zero-dependency JS implementation of elliptic curve cryptography",
|
"description": "Minimal, auditable JS implementation of elliptic curve cryptography",
|
||||||
"files": [
|
"files": [
|
||||||
"index.js",
|
"lib"
|
||||||
"lib",
|
|
||||||
"lib/esm"
|
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"bench": "node curve-definitions/benchmark/index.js",
|
"bench": "node benchmark/index.js",
|
||||||
"build": "tsc && tsc -p tsconfig.esm.json",
|
"build": "tsc && tsc -p tsconfig.esm.json",
|
||||||
"build:release": "rollup -c rollup.config.js",
|
"build:release": "rollup -c rollup.config.js",
|
||||||
"lint": "prettier --check 'src/**/*.{js,ts}' 'curve-definitions/src/**/*.{js,ts}'",
|
"lint": "prettier --check 'src/**/*.{js,ts}' 'test/*.js'",
|
||||||
"format": "prettier --write 'src/**/*.{js,ts}' 'curve-definitions/src/**/*.{js,ts}'",
|
"format": "prettier --write 'src/**/*.{js,ts}' 'test/*.js'",
|
||||||
"test": "cd curve-definitions; node test/index.test.js"
|
"test": "node test/index.test.js"
|
||||||
},
|
},
|
||||||
"author": "Paul Miller (https://paulmillr.com)",
|
"author": "Paul Miller (https://paulmillr.com)",
|
||||||
"homepage": "https://paulmillr.com/noble/",
|
"homepage": "https://paulmillr.com/noble/",
|
||||||
@@ -22,8 +20,16 @@
|
|||||||
"url": "https://github.com/paulmillr/noble-curves.git"
|
"url": "https://github.com/paulmillr/noble-curves.git"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@noble/hashes": "1.1.5"
|
||||||
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rollup/plugin-node-resolve": "13.3.0",
|
"@rollup/plugin-node-resolve": "13.3.0",
|
||||||
|
"@scure/base": "~1.1.1",
|
||||||
|
"@scure/bip32": "~1.1.1",
|
||||||
|
"@scure/bip39": "~1.1.0",
|
||||||
|
"@types/node": "18.11.3",
|
||||||
|
"fast-check": "3.0.0",
|
||||||
"micro-bmark": "0.2.0",
|
"micro-bmark": "0.2.0",
|
||||||
"micro-should": "0.2.0",
|
"micro-should": "0.2.0",
|
||||||
"prettier": "2.6.2",
|
"prettier": "2.6.2",
|
||||||
@@ -32,55 +38,145 @@
|
|||||||
},
|
},
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"exports": {
|
"exports": {
|
||||||
"./edwards": {
|
".": {
|
||||||
"types": "./lib/edwards.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
"import": "./lib/esm/edwards.js",
|
"import": "./lib/esm/index.js",
|
||||||
"default": "./lib/edwards.js"
|
"default": "./lib/index.js"
|
||||||
},
|
},
|
||||||
"./modular": {
|
"./abstract/edwards": {
|
||||||
"types": "./lib/modular.d.ts",
|
"types": "./lib/abstract/edwards.d.ts",
|
||||||
"import": "./lib/esm/modular.js",
|
"import": "./lib/esm/abstract/edwards.js",
|
||||||
"default": "./lib/modular.js"
|
"default": "./lib/abstract/edwards.js"
|
||||||
},
|
},
|
||||||
"./montgomery": {
|
"./abstract/modular": {
|
||||||
"types": "./lib/montgomery.d.ts",
|
"types": "./lib/abstract/modular.d.ts",
|
||||||
"import": "./lib/esm/montgomery.js",
|
"import": "./lib/esm/abstract/modular.js",
|
||||||
"default": "./lib/montgomery.js"
|
"default": "./lib/abstract/modular.js"
|
||||||
},
|
},
|
||||||
"./weierstrass": {
|
"./abstract/montgomery": {
|
||||||
"types": "./lib/weierstrass.d.ts",
|
"types": "./lib/abstract/montgomery.d.ts",
|
||||||
"import": "./lib/esm/weierstrass.js",
|
"import": "./lib/esm/abstract/montgomery.js",
|
||||||
"default": "./lib/weierstrass.js"
|
"default": "./lib/abstract/montgomery.js"
|
||||||
},
|
},
|
||||||
"./bls": {
|
"./abstract/weierstrass": {
|
||||||
"types": "./lib/bls.d.ts",
|
"types": "./lib/abstract/weierstrass.d.ts",
|
||||||
"import": "./lib/esm/bls.js",
|
"import": "./lib/esm/abstract/weierstrass.js",
|
||||||
"default": "./lib/bls.js"
|
"default": "./lib/abstract/weierstrass.js"
|
||||||
},
|
},
|
||||||
"./hashToCurve": {
|
"./abstract/bls": {
|
||||||
"types": "./lib/hashToCurve.d.ts",
|
"types": "./lib/abstract/bls.d.ts",
|
||||||
"import": "./lib/esm/hashToCurve.js",
|
"import": "./lib/esm/abstract/bls.js",
|
||||||
"default": "./lib/hashToCurve.js"
|
"default": "./lib/abstract/bls.js"
|
||||||
},
|
},
|
||||||
"./group": {
|
"./abstract/hash-to-curve": {
|
||||||
"types": "./lib/group.d.ts",
|
"types": "./lib/abstract/hash-to-curve.d.ts",
|
||||||
"import": "./lib/esm/group.js",
|
"import": "./lib/esm/abstract/hash-to-curve.js",
|
||||||
"default": "./lib/group.js"
|
"default": "./lib/abstract/hash-to-curve.js"
|
||||||
},
|
},
|
||||||
"./utils": {
|
"./abstract/group": {
|
||||||
"types": "./lib/utils.d.ts",
|
"types": "./lib/abstract/group.d.ts",
|
||||||
"import": "./lib/esm/utils.js",
|
"import": "./lib/esm/abstract/group.js",
|
||||||
"default": "./lib/utils.js"
|
"default": "./lib/abstract/group.js"
|
||||||
|
},
|
||||||
|
"./abstract/utils": {
|
||||||
|
"types": "./lib/abstract/utils.d.ts",
|
||||||
|
"import": "./lib/esm/abstract/utils.js",
|
||||||
|
"default": "./lib/abstract/utils.js"
|
||||||
|
},
|
||||||
|
"./_shortw_utils": {
|
||||||
|
"types": "./lib/_shortw_utils.d.ts",
|
||||||
|
"import": "./lib/esm/_shortw_utils.js",
|
||||||
|
"default": "./lib/_shortw_utils.js"
|
||||||
|
},
|
||||||
|
"./bls12-381": {
|
||||||
|
"types": "./lib/bls12-381.d.ts",
|
||||||
|
"import": "./lib/esm/bls12-381.js",
|
||||||
|
"default": "./lib/bls12-381.js"
|
||||||
|
},
|
||||||
|
"./bn": {
|
||||||
|
"types": "./lib/bn.d.ts",
|
||||||
|
"import": "./lib/esm/bn.js",
|
||||||
|
"default": "./lib/bn.js"
|
||||||
|
},
|
||||||
|
"./ed25519": {
|
||||||
|
"types": "./lib/ed25519.d.ts",
|
||||||
|
"import": "./lib/esm/ed25519.js",
|
||||||
|
"default": "./lib/ed25519.js"
|
||||||
|
},
|
||||||
|
"./ed448": {
|
||||||
|
"types": "./lib/ed448.d.ts",
|
||||||
|
"import": "./lib/esm/ed448.js",
|
||||||
|
"default": "./lib/ed448.js"
|
||||||
|
},
|
||||||
|
"./index": {
|
||||||
|
"types": "./lib/index.d.ts",
|
||||||
|
"import": "./lib/esm/index.js",
|
||||||
|
"default": "./lib/index.js"
|
||||||
|
},
|
||||||
|
"./jubjub": {
|
||||||
|
"types": "./lib/jubjub.d.ts",
|
||||||
|
"import": "./lib/esm/jubjub.js",
|
||||||
|
"default": "./lib/jubjub.js"
|
||||||
|
},
|
||||||
|
"./p192": {
|
||||||
|
"types": "./lib/p192.d.ts",
|
||||||
|
"import": "./lib/esm/p192.js",
|
||||||
|
"default": "./lib/p192.js"
|
||||||
|
},
|
||||||
|
"./p224": {
|
||||||
|
"types": "./lib/p224.d.ts",
|
||||||
|
"import": "./lib/esm/p224.js",
|
||||||
|
"default": "./lib/p224.js"
|
||||||
|
},
|
||||||
|
"./p256": {
|
||||||
|
"types": "./lib/p256.d.ts",
|
||||||
|
"import": "./lib/esm/p256.js",
|
||||||
|
"default": "./lib/p256.js"
|
||||||
|
},
|
||||||
|
"./p384": {
|
||||||
|
"types": "./lib/p384.d.ts",
|
||||||
|
"import": "./lib/esm/p384.js",
|
||||||
|
"default": "./lib/p384.js"
|
||||||
|
},
|
||||||
|
"./p521": {
|
||||||
|
"types": "./lib/p521.d.ts",
|
||||||
|
"import": "./lib/esm/p521.js",
|
||||||
|
"default": "./lib/p521.js"
|
||||||
|
},
|
||||||
|
"./pasta": {
|
||||||
|
"types": "./lib/pasta.d.ts",
|
||||||
|
"import": "./lib/esm/pasta.js",
|
||||||
|
"default": "./lib/pasta.js"
|
||||||
|
},
|
||||||
|
"./secp256k1": {
|
||||||
|
"types": "./lib/secp256k1.d.ts",
|
||||||
|
"import": "./lib/esm/secp256k1.js",
|
||||||
|
"default": "./lib/secp256k1.js"
|
||||||
|
},
|
||||||
|
"./stark": {
|
||||||
|
"types": "./lib/stark.d.ts",
|
||||||
|
"import": "./lib/esm/stark.js",
|
||||||
|
"default": "./lib/stark.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"elliptic",
|
"elliptic",
|
||||||
"curve",
|
"curve",
|
||||||
"cryptography",
|
"cryptography",
|
||||||
"hyperelliptic",
|
"weierstrass",
|
||||||
|
"montgomery",
|
||||||
|
"edwards",
|
||||||
"p256",
|
"p256",
|
||||||
"p384",
|
"p384",
|
||||||
"p521",
|
"p521",
|
||||||
|
"secp256r1",
|
||||||
|
"secp256k1",
|
||||||
|
"ed25519",
|
||||||
|
"ed448",
|
||||||
|
"bls12-381",
|
||||||
|
"bn254",
|
||||||
|
"pasta",
|
||||||
|
"bls",
|
||||||
"nist",
|
"nist",
|
||||||
"ecc",
|
"ecc",
|
||||||
"ecdsa",
|
"ecdsa",
|
||||||
@@ -93,4 +189,4 @@
|
|||||||
"url": "https://paulmillr.com/funding/"
|
"url": "https://paulmillr.com/funding/"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||||
import { hmac } from '@noble/hashes/hmac';
|
import { hmac } from '@noble/hashes/hmac';
|
||||||
import { concatBytes, randomBytes } from '@noble/hashes/utils';
|
import { concatBytes, randomBytes } from '@noble/hashes/utils';
|
||||||
import { weierstrass, CurveType } from '@noble/curves/weierstrass';
|
import { weierstrass, CurveType } from './abstract/weierstrass.js';
|
||||||
import { CHash } from '@noble/curves/utils';
|
import { CHash } from './abstract/utils.js';
|
||||||
|
|
||||||
export function getHash(hash: CHash) {
|
export function getHash(hash: CHash) {
|
||||||
return {
|
return {
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||||
// Barreto-Lynn-Scott Curves. A family of pairing friendly curves, with embedding degree = 12 or 24
|
// Barreto-Lynn-Scott Curves. A family of pairing friendly curves, with embedding degree = 12 or 24
|
||||||
// NOTE: only 12 supported for now
|
// NOTE: only 12 supported for now
|
||||||
// Constructed from pair of weierstrass curves, based pairing logic
|
// Constructed from pair of weierstrass curves, based pairing logic
|
||||||
@@ -6,7 +7,7 @@ import { ensureBytes, numberToBytesBE, bytesToNumberBE, bitLen, bitGet } from '.
|
|||||||
import * as utils from './utils.js';
|
import * as utils from './utils.js';
|
||||||
// Types
|
// Types
|
||||||
import { hexToBytes, bytesToHex, Hex, PrivKey } from './utils.js';
|
import { hexToBytes, bytesToHex, Hex, PrivKey } from './utils.js';
|
||||||
import { htfOpts, stringToBytes, hash_to_field, expand_message_xmd } from './hashToCurve.js';
|
import { htfOpts, stringToBytes, hash_to_field, expand_message_xmd } from './hash-to-curve.js';
|
||||||
import { CurvePointsType, PointType, CurvePointsRes, weierstrassPoints } from './weierstrass.js';
|
import { CurvePointsType, PointType, CurvePointsRes, weierstrassPoints } from './weierstrass.js';
|
||||||
|
|
||||||
type Fp = bigint; // Can be different field?
|
type Fp = bigint; // Can be different field?
|
||||||
@@ -113,33 +114,33 @@ export function bls<Fp2, Fp6, Fp12>(
|
|||||||
// Double
|
// Double
|
||||||
let t0 = Fp2.square(Ry); // Ry²
|
let t0 = Fp2.square(Ry); // Ry²
|
||||||
let t1 = Fp2.square(Rz); // Rz²
|
let t1 = Fp2.square(Rz); // Rz²
|
||||||
let t2 = Fp2.multiplyByB(Fp2.multiply(t1, 3n)); // 3 * T1 * B
|
let t2 = Fp2.multiplyByB(Fp2.mul(t1, 3n)); // 3 * T1 * B
|
||||||
let t3 = Fp2.multiply(t2, 3n); // 3 * T2
|
let t3 = Fp2.mul(t2, 3n); // 3 * T2
|
||||||
let t4 = Fp2.subtract(Fp2.subtract(Fp2.square(Fp2.add(Ry, Rz)), t1), t0); // (Ry + Rz)² - T1 - T0
|
let t4 = Fp2.sub(Fp2.sub(Fp2.square(Fp2.add(Ry, Rz)), t1), t0); // (Ry + Rz)² - T1 - T0
|
||||||
ell_coeff.push([
|
ell_coeff.push([
|
||||||
Fp2.subtract(t2, t0), // T2 - T0
|
Fp2.sub(t2, t0), // T2 - T0
|
||||||
Fp2.multiply(Fp2.square(Rx), 3n), // 3 * Rx²
|
Fp2.mul(Fp2.square(Rx), 3n), // 3 * Rx²
|
||||||
Fp2.negate(t4), // -T4
|
Fp2.negate(t4), // -T4
|
||||||
]);
|
]);
|
||||||
Rx = Fp2.div(Fp2.multiply(Fp2.multiply(Fp2.subtract(t0, t3), Rx), Ry), 2n); // ((T0 - T3) * Rx * Ry) / 2
|
Rx = Fp2.div(Fp2.mul(Fp2.mul(Fp2.sub(t0, t3), Rx), Ry), 2n); // ((T0 - T3) * Rx * Ry) / 2
|
||||||
Ry = Fp2.subtract(Fp2.square(Fp2.div(Fp2.add(t0, t3), 2n)), Fp2.multiply(Fp2.square(t2), 3n)); // ((T0 + T3) / 2)² - 3 * T2²
|
Ry = Fp2.sub(Fp2.square(Fp2.div(Fp2.add(t0, t3), 2n)), Fp2.mul(Fp2.square(t2), 3n)); // ((T0 + T3) / 2)² - 3 * T2²
|
||||||
Rz = Fp2.multiply(t0, t4); // T0 * T4
|
Rz = Fp2.mul(t0, t4); // T0 * T4
|
||||||
if (bitGet(CURVE.x, i)) {
|
if (bitGet(CURVE.x, i)) {
|
||||||
// Addition
|
// Addition
|
||||||
let t0 = Fp2.subtract(Ry, Fp2.multiply(Qy, Rz)); // Ry - Qy * Rz
|
let t0 = Fp2.sub(Ry, Fp2.mul(Qy, Rz)); // Ry - Qy * Rz
|
||||||
let t1 = Fp2.subtract(Rx, Fp2.multiply(Qx, Rz)); // Rx - Qx * Rz
|
let t1 = Fp2.sub(Rx, Fp2.mul(Qx, Rz)); // Rx - Qx * Rz
|
||||||
ell_coeff.push([
|
ell_coeff.push([
|
||||||
Fp2.subtract(Fp2.multiply(t0, Qx), Fp2.multiply(t1, Qy)), // T0 * Qx - T1 * Qy
|
Fp2.sub(Fp2.mul(t0, Qx), Fp2.mul(t1, Qy)), // T0 * Qx - T1 * Qy
|
||||||
Fp2.negate(t0), // -T0
|
Fp2.negate(t0), // -T0
|
||||||
t1, // T1
|
t1, // T1
|
||||||
]);
|
]);
|
||||||
let t2 = Fp2.square(t1); // T1²
|
let t2 = Fp2.square(t1); // T1²
|
||||||
let t3 = Fp2.multiply(t2, t1); // T2 * T1
|
let t3 = Fp2.mul(t2, t1); // T2 * T1
|
||||||
let t4 = Fp2.multiply(t2, Rx); // T2 * Rx
|
let t4 = Fp2.mul(t2, Rx); // T2 * Rx
|
||||||
let t5 = Fp2.add(Fp2.subtract(t3, Fp2.multiply(t4, 2n)), Fp2.multiply(Fp2.square(t0), Rz)); // T3 - 2 * T4 + T0² * Rz
|
let t5 = Fp2.add(Fp2.sub(t3, Fp2.mul(t4, 2n)), Fp2.mul(Fp2.square(t0), Rz)); // T3 - 2 * T4 + T0² * Rz
|
||||||
Rx = Fp2.multiply(t1, t5); // T1 * T5
|
Rx = Fp2.mul(t1, t5); // T1 * T5
|
||||||
Ry = Fp2.subtract(Fp2.multiply(Fp2.subtract(t4, t5), t0), Fp2.multiply(t3, Ry)); // (T4 - T5) * T0 - T3 * Ry
|
Ry = Fp2.sub(Fp2.mul(Fp2.sub(t4, t5), t0), Fp2.mul(t3, Ry)); // (T4 - T5) * T0 - T3 * Ry
|
||||||
Rz = Fp2.multiply(Rz, t3); // Rz * T3
|
Rz = Fp2.mul(Rz, t3); // Rz * T3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ell_coeff;
|
return ell_coeff;
|
||||||
@@ -151,11 +152,11 @@ export function bls<Fp2, Fp6, Fp12>(
|
|||||||
let f12 = Fp12.ONE;
|
let f12 = Fp12.ONE;
|
||||||
for (let j = 0, i = BLS_X_LEN - 2; i >= 0; i--, j++) {
|
for (let j = 0, i = BLS_X_LEN - 2; i >= 0; i--, j++) {
|
||||||
const E = ell[j];
|
const E = ell[j];
|
||||||
f12 = Fp12.multiplyBy014(f12, E[0], Fp2.multiply(E[1], Px), Fp2.multiply(E[2], Py));
|
f12 = Fp12.multiplyBy014(f12, E[0], Fp2.mul(E[1], Px), Fp2.mul(E[2], Py));
|
||||||
if (bitGet(CURVE.x, i)) {
|
if (bitGet(CURVE.x, i)) {
|
||||||
j += 1;
|
j += 1;
|
||||||
const F = ell[j];
|
const F = ell[j];
|
||||||
f12 = Fp12.multiplyBy014(f12, F[0], Fp2.multiply(F[1], Px), Fp2.multiply(F[2], Py));
|
f12 = Fp12.multiplyBy014(f12, F[0], Fp2.mul(F[1], Px), Fp2.mul(F[2], Py));
|
||||||
}
|
}
|
||||||
if (i !== 0) f12 = Fp12.square(f12);
|
if (i !== 0) f12 = Fp12.square(f12);
|
||||||
}
|
}
|
||||||
@@ -324,7 +325,7 @@ export function bls<Fp2, Fp6, Fp12>(
|
|||||||
// and do one exp after multiplying 2 points.
|
// and do one exp after multiplying 2 points.
|
||||||
const ePHm = pairing(P.negate(), Hm, false);
|
const ePHm = pairing(P.negate(), Hm, false);
|
||||||
const eGS = pairing(G, S, false);
|
const eGS = pairing(G, S, false);
|
||||||
const exp = Fp12.finalExponentiate(Fp12.multiply(eGS, ePHm));
|
const exp = Fp12.finalExponentiate(Fp12.mul(eGS, ePHm));
|
||||||
return Fp12.equals(exp, Fp12.ONE);
|
return Fp12.equals(exp, Fp12.ONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,7 +337,7 @@ export function bls<Fp2, Fp6, Fp12>(
|
|||||||
if (!publicKeys.length) throw new Error('Expected non-empty array');
|
if (!publicKeys.length) throw new Error('Expected non-empty array');
|
||||||
const agg = publicKeys
|
const agg = publicKeys
|
||||||
.map(normP1)
|
.map(normP1)
|
||||||
.reduce((sum, p) => sum.add(G1.JacobianPoint.fromAffine(p)), G1.JacobianPoint.ZERO);
|
.reduce((sum, p) => sum.add(G1.ProjectivePoint.fromAffine(p)), G1.ProjectivePoint.ZERO);
|
||||||
const aggAffine = agg.toAffine();
|
const aggAffine = agg.toAffine();
|
||||||
if (publicKeys[0] instanceof G1.Point) {
|
if (publicKeys[0] instanceof G1.Point) {
|
||||||
aggAffine.assertValidity();
|
aggAffine.assertValidity();
|
||||||
@@ -353,7 +354,7 @@ export function bls<Fp2, Fp6, Fp12>(
|
|||||||
if (!signatures.length) throw new Error('Expected non-empty array');
|
if (!signatures.length) throw new Error('Expected non-empty array');
|
||||||
const agg = signatures
|
const agg = signatures
|
||||||
.map(normP2)
|
.map(normP2)
|
||||||
.reduce((sum, s) => sum.add(G2.JacobianPoint.fromAffine(s)), G2.JacobianPoint.ZERO);
|
.reduce((sum, s) => sum.add(G2.ProjectivePoint.fromAffine(s)), G2.ProjectivePoint.ZERO);
|
||||||
const aggAffine = agg.toAffine();
|
const aggAffine = agg.toAffine();
|
||||||
if (signatures[0] instanceof G2.Point) {
|
if (signatures[0] instanceof G2.Point) {
|
||||||
aggAffine.assertValidity();
|
aggAffine.assertValidity();
|
||||||
@@ -384,7 +385,7 @@ export function bls<Fp2, Fp6, Fp12>(
|
|||||||
paired.push(pairing(groupPublicKey, message, false));
|
paired.push(pairing(groupPublicKey, message, false));
|
||||||
}
|
}
|
||||||
paired.push(pairing(G1.Point.BASE.negate(), sig, false));
|
paired.push(pairing(G1.Point.BASE.negate(), sig, false));
|
||||||
const product = paired.reduce((a, b) => Fp12.multiply(a, b), Fp12.ONE);
|
const product = paired.reduce((a, b) => Fp12.mul(a, b), Fp12.ONE);
|
||||||
const exp = Fp12.finalExponentiate(product);
|
const exp = Fp12.finalExponentiate(product);
|
||||||
return Fp12.equals(exp, Fp12.ONE);
|
return Fp12.equals(exp, Fp12.ONE);
|
||||||
} catch {
|
} catch {
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||||
// Implementation of Twisted Edwards curve. The formula is: ax² + y² = 1 + dx²y²
|
// Twisted Edwards curve. The formula is: ax² + y² = 1 + dx²y²
|
||||||
|
|
||||||
// Differences from @noble/ed25519 1.7:
|
// Differences from @noble/ed25519 1.7:
|
||||||
// 1. Different field element lengths in ed448:
|
// 1. Different field element lengths in ed448:
|
||||||
@@ -23,6 +23,7 @@ import {
|
|||||||
PrivKey,
|
PrivKey,
|
||||||
} from './utils.js'; // TODO: import * as u from './utils.js'?
|
} from './utils.js'; // TODO: import * as u from './utils.js'?
|
||||||
import { Group, GroupConstructor, wNAF } from './group.js';
|
import { Group, GroupConstructor, wNAF } from './group.js';
|
||||||
|
import { hash_to_field, htfOpts, validateHTFOpts } from './hash-to-curve.js';
|
||||||
|
|
||||||
// Be friendly to bad ECMAScript parsers by not using bigint literals like 123n
|
// Be friendly to bad ECMAScript parsers by not using bigint literals like 123n
|
||||||
const _0n = BigInt(0);
|
const _0n = BigInt(0);
|
||||||
@@ -48,6 +49,10 @@ export type CurveType = BasicCurve<bigint> & {
|
|||||||
domain?: (data: Uint8Array, ctx: Uint8Array, phflag: boolean) => Uint8Array;
|
domain?: (data: Uint8Array, ctx: Uint8Array, phflag: boolean) => Uint8Array;
|
||||||
uvRatio?: (u: bigint, v: bigint) => { isValid: boolean; value: bigint };
|
uvRatio?: (u: bigint, v: bigint) => { isValid: boolean; value: bigint };
|
||||||
preHash?: CHash;
|
preHash?: CHash;
|
||||||
|
clearCofactor?: (c: ExtendedPointConstructor, point: ExtendedPointType) => ExtendedPointType;
|
||||||
|
// Hash to field opts
|
||||||
|
htfDefaults?: htfOpts;
|
||||||
|
mapToCurve?: (scalar: bigint[]) => { x: bigint; y: bigint };
|
||||||
};
|
};
|
||||||
|
|
||||||
// Should be separate from overrides, since overrides can use information about curve (for example nBits)
|
// Should be separate from overrides, since overrides can use information about curve (for example nBits)
|
||||||
@@ -62,10 +67,17 @@ function validateOpts(curve: CurveType) {
|
|||||||
for (const fn of ['randomBytes'] as const) {
|
for (const fn of ['randomBytes'] as const) {
|
||||||
if (typeof opts[fn] !== 'function') throw new Error(`Invalid ${fn} function`);
|
if (typeof opts[fn] !== 'function') throw new Error(`Invalid ${fn} function`);
|
||||||
}
|
}
|
||||||
for (const fn of ['adjustScalarBytes', 'domain', 'uvRatio'] as const) {
|
for (const fn of [
|
||||||
|
'adjustScalarBytes',
|
||||||
|
'domain',
|
||||||
|
'uvRatio',
|
||||||
|
'mapToCurve',
|
||||||
|
'clearCofactor',
|
||||||
|
] as const) {
|
||||||
if (opts[fn] === undefined) continue; // Optional
|
if (opts[fn] === undefined) continue; // Optional
|
||||||
if (typeof opts[fn] !== 'function') throw new Error(`Invalid ${fn} function`);
|
if (typeof opts[fn] !== 'function') throw new Error(`Invalid ${fn} function`);
|
||||||
}
|
}
|
||||||
|
if (opts.htfDefaults !== undefined) validateHTFOpts(opts.htfDefaults);
|
||||||
// Set defaults
|
// Set defaults
|
||||||
return Object.freeze({ ...opts } as const);
|
return Object.freeze({ ...opts } as const);
|
||||||
}
|
}
|
||||||
@@ -95,6 +107,7 @@ export interface ExtendedPointType extends Group<ExtendedPointType> {
|
|||||||
isSmallOrder(): boolean;
|
isSmallOrder(): boolean;
|
||||||
isTorsionFree(): boolean;
|
isTorsionFree(): boolean;
|
||||||
toAffine(invZ?: bigint): PointType;
|
toAffine(invZ?: bigint): PointType;
|
||||||
|
clearCofactor(): ExtendedPointType;
|
||||||
}
|
}
|
||||||
// Static methods
|
// Static methods
|
||||||
export interface ExtendedPointConstructor extends GroupConstructor<ExtendedPointType> {
|
export interface ExtendedPointConstructor extends GroupConstructor<ExtendedPointType> {
|
||||||
@@ -112,12 +125,15 @@ export interface PointType extends Group<PointType> {
|
|||||||
toRawBytes(isCompressed?: boolean): Uint8Array;
|
toRawBytes(isCompressed?: boolean): Uint8Array;
|
||||||
toHex(isCompressed?: boolean): string;
|
toHex(isCompressed?: boolean): string;
|
||||||
isTorsionFree(): boolean;
|
isTorsionFree(): boolean;
|
||||||
|
clearCofactor(): PointType;
|
||||||
}
|
}
|
||||||
// Static methods
|
// Static methods
|
||||||
export interface PointConstructor extends GroupConstructor<PointType> {
|
export interface PointConstructor extends GroupConstructor<PointType> {
|
||||||
new (x: bigint, y: bigint): PointType;
|
new (x: bigint, y: bigint): PointType;
|
||||||
fromHex(hex: Hex): PointType;
|
fromHex(hex: Hex): PointType;
|
||||||
fromPrivateKey(privateKey: PrivKey): PointType;
|
fromPrivateKey(privateKey: PrivKey): PointType;
|
||||||
|
hashToCurve(msg: Hex, options?: Partial<htfOpts>): PointType;
|
||||||
|
encodeToCurve(msg: Hex, options?: Partial<htfOpts>): PointType;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PubKey = Hex | PointType;
|
export type PubKey = Hex | PointType;
|
||||||
@@ -263,7 +279,7 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
|||||||
const A = modP((Y1 - X1) * (Y2 + X2));
|
const A = modP((Y1 - X1) * (Y2 + X2));
|
||||||
const B = modP((Y1 + X1) * (Y2 - X2));
|
const B = modP((Y1 + X1) * (Y2 - X2));
|
||||||
const F = modP(B - A);
|
const F = modP(B - A);
|
||||||
if (F === _0n) return this.double(); // Same point.
|
if (F === _0n) return this.double(); // Same point. Tests say it doesn't affect timing
|
||||||
const C = modP(Z1 * _2n * T2);
|
const C = modP(Z1 * _2n * T2);
|
||||||
const D = modP(T1 * _2n * Z2);
|
const D = modP(T1 * _2n * Z2);
|
||||||
const E = D + C;
|
const E = D + C;
|
||||||
@@ -280,7 +296,6 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
|||||||
const C = modP(T1 * d * T2); // C = T1*d*T2
|
const C = modP(T1 * d * T2); // C = T1*d*T2
|
||||||
const D = modP(Z1 * Z2); // D = Z1*Z2
|
const D = modP(Z1 * Z2); // D = Z1*Z2
|
||||||
const E = modP((X1 + Y1) * (X2 + Y2) - A - B); // E = (X1+Y1)*(X2+Y2)-A-B
|
const E = modP((X1 + Y1) * (X2 + Y2) - A - B); // E = (X1+Y1)*(X2+Y2)-A-B
|
||||||
// TODO: do we need to check for same point here? Looks like working without it
|
|
||||||
const F = D - C; // F = D-C
|
const F = D - C; // F = D-C
|
||||||
const G = D + C; // G = D+C
|
const G = D + C; // G = D+C
|
||||||
const H = modP(B - a * A); // H = B-a*A
|
const H = modP(B - a * A); // H = B-a*A
|
||||||
@@ -355,6 +370,13 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
|||||||
if (zz !== _1n) throw new Error('invZ was invalid');
|
if (zz !== _1n) throw new Error('invZ was invalid');
|
||||||
return new Point(ax, ay);
|
return new Point(ax, ay);
|
||||||
}
|
}
|
||||||
|
clearCofactor(): ExtendedPoint {
|
||||||
|
if (CURVE.h === _1n) return this; // Fast-path
|
||||||
|
// clear_cofactor(P) := h_eff * P
|
||||||
|
// hEff = h for ed25519/ed448. Maybe worth moving to params?
|
||||||
|
if (CURVE.clearCofactor) return CURVE.clearCofactor(ExtendedPoint, this) as ExtendedPoint;
|
||||||
|
return this.multiplyUnsafe(CURVE.h);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const wnaf = wNAF(ExtendedPoint, groupLen * 8);
|
const wnaf = wNAF(ExtendedPoint, groupLen * 8);
|
||||||
|
|
||||||
@@ -480,6 +502,29 @@ export function twistedEdwards(curveDef: CurveType): CurveFn {
|
|||||||
multiply(scalar: number | bigint): Point {
|
multiply(scalar: number | bigint): Point {
|
||||||
return ExtendedPoint.fromAffine(this).multiply(scalar, this).toAffine();
|
return ExtendedPoint.fromAffine(this).multiply(scalar, this).toAffine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clearCofactor() {
|
||||||
|
return ExtendedPoint.fromAffine(this).clearCofactor().toAffine();
|
||||||
|
}
|
||||||
|
// Encodes byte string to elliptic curve
|
||||||
|
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-3
|
||||||
|
static hashToCurve(msg: Hex, options?: Partial<htfOpts>) {
|
||||||
|
if (!CURVE.mapToCurve) throw new Error('No mapToCurve defined for curve');
|
||||||
|
msg = ensureBytes(msg);
|
||||||
|
const u = hash_to_field(msg, 2, { ...CURVE.htfDefaults, ...options } as htfOpts);
|
||||||
|
const { x: x0, y: y0 } = CURVE.mapToCurve(u[0]);
|
||||||
|
const { x: x1, y: y1 } = CURVE.mapToCurve(u[1]);
|
||||||
|
const p = new Point(x0, y0).add(new Point(x1, y1)).clearCofactor();
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-16#section-3
|
||||||
|
static encodeToCurve(msg: Hex, options?: Partial<htfOpts>) {
|
||||||
|
if (!CURVE.mapToCurve) throw new Error('No mapToCurve defined for curve');
|
||||||
|
msg = ensureBytes(msg);
|
||||||
|
const u = hash_to_field(msg, 1, { ...CURVE.htfDefaults, ...options } as htfOpts);
|
||||||
|
const { x, y } = CURVE.mapToCurve(u[0]);
|
||||||
|
return new Point(x, y).clearCofactor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||||
// Default group related functions
|
// Abelian group utilities
|
||||||
const _0n = BigInt(0);
|
const _0n = BigInt(0);
|
||||||
const _1n = BigInt(1);
|
const _1n = BigInt(1);
|
||||||
|
|
||||||
@@ -67,8 +67,9 @@ export function wNAF<T extends Group<T>>(c: GroupConstructor<T>, bits: number) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements w-ary non-adjacent form for calculating ec multiplication.
|
* Implements w-ary non-adjacent form for calculating ec multiplication.
|
||||||
* @param n
|
* @param W window size
|
||||||
* @param affinePoint optional 2d point to save cached precompute windows on it.
|
* @param affinePoint optional 2d point to save cached precompute windows on it.
|
||||||
|
* @param n bits
|
||||||
* @returns real and fake (for const-time) points
|
* @returns real and fake (for const-time) points
|
||||||
*/
|
*/
|
||||||
wNAF(W: number, precomputes: T[], n: bigint): { p: T; f: T } {
|
wNAF(W: number, precomputes: T[], n: bigint): { p: T; f: T } {
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||||
import { CHash, concatBytes } from './utils.js';
|
import { CHash, concatBytes } from './utils.js';
|
||||||
import * as mod from './modular.js';
|
import * as mod from './modular.js';
|
||||||
|
|
||||||
@@ -16,10 +17,11 @@ export type htfOpts = {
|
|||||||
k: number;
|
k: number;
|
||||||
// option to use a message that has already been processed by
|
// option to use a message that has already been processed by
|
||||||
// expand_message_xmd
|
// expand_message_xmd
|
||||||
expand: boolean;
|
expand?: 'xmd' | 'xof';
|
||||||
// Hash functions for: expand_message_xmd is appropriate for use with a
|
// 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.
|
// 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
|
// 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;
|
hash: CHash;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -28,12 +30,14 @@ export function validateHTFOpts(opts: htfOpts) {
|
|||||||
if (typeof opts.p !== 'bigint') throw new Error('Invalid htf/p');
|
if (typeof opts.p !== 'bigint') throw new Error('Invalid htf/p');
|
||||||
if (typeof opts.m !== 'number') throw new Error('Invalid htf/m');
|
if (typeof opts.m !== 'number') throw new Error('Invalid htf/m');
|
||||||
if (typeof opts.k !== 'number') throw new Error('Invalid htf/k');
|
if (typeof opts.k !== 'number') throw new Error('Invalid htf/k');
|
||||||
if (typeof opts.expand !== 'boolean') throw new Error('Invalid htf/expand');
|
if (opts.expand !== 'xmd' && opts.expand !== 'xof' && opts.expand !== undefined)
|
||||||
|
throw new Error('Invalid htf/expand');
|
||||||
if (typeof opts.hash !== 'function' || !Number.isSafeInteger(opts.hash.outputLen))
|
if (typeof opts.hash !== 'function' || !Number.isSafeInteger(opts.hash.outputLen))
|
||||||
throw new Error('Invalid htf/hash function');
|
throw new Error('Invalid htf/hash function');
|
||||||
}
|
}
|
||||||
|
|
||||||
// UTF8 to ui8a
|
// UTF8 to ui8a
|
||||||
|
// TODO: looks broken, ASCII only, why not TextEncoder/TextDecoder? it is in hashes anyway
|
||||||
export function stringToBytes(str: string) {
|
export function stringToBytes(str: string) {
|
||||||
const bytes = new Uint8Array(str.length);
|
const bytes = new Uint8Array(str.length);
|
||||||
for (let i = 0; i < str.length; i++) bytes[i] = str.charCodeAt(i);
|
for (let i = 0; i < str.length; i++) bytes[i] = str.charCodeAt(i);
|
||||||
@@ -82,7 +86,7 @@ export function expand_message_xmd(
|
|||||||
// 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
|
||||||
if (DST.length > 255) DST = H(concatBytes(stringToBytes('H2C-OVERSIZE-DST-'), DST));
|
if (DST.length > 255) DST = H(concatBytes(stringToBytes('H2C-OVERSIZE-DST-'), DST));
|
||||||
const b_in_bytes = H.outputLen;
|
const b_in_bytes = H.outputLen;
|
||||||
const r_in_bytes = b_in_bytes * 2;
|
const r_in_bytes = H.blockLen;
|
||||||
const ell = Math.ceil(lenInBytes / b_in_bytes);
|
const ell = Math.ceil(lenInBytes / b_in_bytes);
|
||||||
if (ell > 255) throw new Error('Invalid xmd length');
|
if (ell > 255) throw new Error('Invalid xmd length');
|
||||||
const DST_prime = concatBytes(DST, i2osp(DST.length, 1));
|
const DST_prime = concatBytes(DST, i2osp(DST.length, 1));
|
||||||
@@ -99,13 +103,40 @@ export function expand_message_xmd(
|
|||||||
return pseudo_random_bytes.slice(0, lenInBytes);
|
return pseudo_random_bytes.slice(0, lenInBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
// hashes arbitrary-length byte strings to a list of one or more elements of a finite field F
|
export function expand_message_xof(
|
||||||
// https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#section-5.3
|
msg: Uint8Array,
|
||||||
// Inputs:
|
DST: Uint8Array,
|
||||||
// msg - a byte string containing the message to hash.
|
lenInBytes: number,
|
||||||
// count - the number of elements of F to output.
|
k: number,
|
||||||
// Outputs:
|
H: CHash
|
||||||
// [u_0, ..., u_(count - 1)], a list of field elements.
|
): 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) {
|
||||||
|
const dkLen = Math.ceil((2 * k) / 8);
|
||||||
|
DST = H.create({ dkLen }).update(stringToBytes('H2C-OVERSIZE-DST-')).update(DST).digest();
|
||||||
|
}
|
||||||
|
if (lenInBytes > 65535 || DST.length > 255)
|
||||||
|
throw new Error('expand_message_xof: invalid lenInBytes');
|
||||||
|
return (
|
||||||
|
H.create({ dkLen: lenInBytes })
|
||||||
|
.update(msg)
|
||||||
|
.update(i2osp(lenInBytes, 2))
|
||||||
|
// 2. DST_prime = DST || I2OSP(len(DST), 1)
|
||||||
|
.update(DST)
|
||||||
|
.update(i2osp(DST.length, 1))
|
||||||
|
.digest()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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[][] {
|
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).
|
||||||
@@ -114,8 +145,10 @@ export function hash_to_field(msg: Uint8Array, count: number, options: htfOpts):
|
|||||||
const len_in_bytes = count * options.m * L;
|
const len_in_bytes = count * options.m * L;
|
||||||
const DST = stringToBytes(options.DST);
|
const DST = stringToBytes(options.DST);
|
||||||
let pseudo_random_bytes = msg;
|
let pseudo_random_bytes = msg;
|
||||||
if (options.expand) {
|
if (options.expand === 'xmd') {
|
||||||
pseudo_random_bytes = expand_message_xmd(msg, DST, len_in_bytes, options.hash);
|
pseudo_random_bytes = expand_message_xmd(msg, DST, len_in_bytes, options.hash);
|
||||||
|
} else if (options.expand === 'xof') {
|
||||||
|
pseudo_random_bytes = expand_message_xof(msg, DST, len_in_bytes, options.k, options.hash);
|
||||||
}
|
}
|
||||||
const u = new Array(count);
|
const u = new Array(count);
|
||||||
for (let i = 0; i < count; i++) {
|
for (let i = 0; i < count; i++) {
|
||||||
@@ -129,3 +162,16 @@ export function hash_to_field(msg: Uint8Array, count: number, options: htfOpts):
|
|||||||
}
|
}
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isogenyMap<T, F extends mod.Field<T>>(field: F, map: [T[], T[], T[], T[]]) {
|
||||||
|
// Make same order as in spec
|
||||||
|
const COEFF = map.map((i) => Array.from(i).reverse());
|
||||||
|
return (x: T, y: T) => {
|
||||||
|
const [xNum, xDen, yNum, yDen] = COEFF.map((val) =>
|
||||||
|
val.reduce((acc, i) => field.add(field.mul(acc, x), i))
|
||||||
|
);
|
||||||
|
x = field.div(xNum, xDen); // xNum / xDen
|
||||||
|
y = field.mul(y, field.div(yNum, yDen)); // y * (yNum / yDev)
|
||||||
|
return { x, y };
|
||||||
|
};
|
||||||
|
}
|
||||||
382
src/abstract/modular.ts
Normal file
382
src/abstract/modular.ts
Normal file
@@ -0,0 +1,382 @@
|
|||||||
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||||
|
// TODO: remove circular imports
|
||||||
|
import * as utils from './utils.js';
|
||||||
|
// Utilities for modular arithmetics and finite fields
|
||||||
|
// prettier-ignore
|
||||||
|
const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3);
|
||||||
|
// prettier-ignore
|
||||||
|
const _4n = BigInt(4), _5n = BigInt(5), _8n = BigInt(8);
|
||||||
|
// prettier-ignore
|
||||||
|
const _9n = BigInt(9), _16n = BigInt(16);
|
||||||
|
|
||||||
|
// Calculates a modulo b
|
||||||
|
export function mod(a: bigint, b: bigint): bigint {
|
||||||
|
const result = a % b;
|
||||||
|
return result >= _0n ? result : b + result;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Efficiently exponentiate num to power and do modular division.
|
||||||
|
* Unsafe in some contexts: uses ladder, so can expose bigint bits.
|
||||||
|
* @example
|
||||||
|
* powMod(2n, 6n, 11n) // 64n % 11n == 9n
|
||||||
|
*/
|
||||||
|
// TODO: use field version && remove
|
||||||
|
export function pow(num: bigint, power: bigint, modulo: bigint): bigint {
|
||||||
|
if (modulo <= _0n || power < _0n) throw new Error('Expected power/modulo > 0');
|
||||||
|
if (modulo === _1n) return _0n;
|
||||||
|
let res = _1n;
|
||||||
|
while (power > _0n) {
|
||||||
|
if (power & _1n) res = (res * num) % modulo;
|
||||||
|
num = (num * num) % modulo;
|
||||||
|
power >>= _1n;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Does x ^ (2 ^ power) mod p. pow2(30, 4) == 30 ^ (2 ^ 4)
|
||||||
|
// TODO: Fp version?
|
||||||
|
export function pow2(x: bigint, power: bigint, modulo: bigint): bigint {
|
||||||
|
let res = x;
|
||||||
|
while (power-- > _0n) {
|
||||||
|
res *= res;
|
||||||
|
res %= modulo;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inverses number over modulo
|
||||||
|
export function invert(number: bigint, modulo: bigint): bigint {
|
||||||
|
if (number === _0n || modulo <= _0n) {
|
||||||
|
throw new Error(`invert: expected positive integers, got n=${number} mod=${modulo}`);
|
||||||
|
}
|
||||||
|
// Eucledian GCD https://brilliant.org/wiki/extended-euclidean-algorithm/
|
||||||
|
let a = mod(number, modulo);
|
||||||
|
let b = modulo;
|
||||||
|
// prettier-ignore
|
||||||
|
let x = _0n, y = _1n, u = _1n, v = _0n;
|
||||||
|
while (a !== _0n) {
|
||||||
|
const q = b / a;
|
||||||
|
const r = b % a;
|
||||||
|
const m = x - u * q;
|
||||||
|
const n = y - v * q;
|
||||||
|
// prettier-ignore
|
||||||
|
b = a, a = r, x = u, y = v, u = m, v = n;
|
||||||
|
}
|
||||||
|
const gcd = b;
|
||||||
|
if (gcd !== _1n) throw new Error('invert: does not exist');
|
||||||
|
return mod(x, modulo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tonelli-Shanks algorithm
|
||||||
|
// https://eprint.iacr.org/2012/685.pdf (page 12)
|
||||||
|
export function tonelliShanks(P: bigint) {
|
||||||
|
// Legendre constant: used to calculate Legendre symbol (a | p),
|
||||||
|
// which denotes the value of a^((p-1)/2) (mod p).
|
||||||
|
// (a | p) ≡ 1 if a is a square (mod p)
|
||||||
|
// (a | p) ≡ -1 if a is not a square (mod p)
|
||||||
|
// (a | p) ≡ 0 if a ≡ 0 (mod p)
|
||||||
|
const legendreC = (P - _1n) / _2n;
|
||||||
|
|
||||||
|
let Q: bigint, S: number, Z: bigint;
|
||||||
|
// Step 1: By factoring out powers of 2 from p - 1,
|
||||||
|
// find q and s such that p - 1 = q2s with q odd
|
||||||
|
for (Q = P - _1n, S = 0; Q % _2n === _0n; Q /= _2n, S++);
|
||||||
|
|
||||||
|
// Step 2: Select a non-square z such that (z | p) ≡ -1 and set c ≡ zq
|
||||||
|
for (Z = _2n; Z < P && pow(Z, legendreC, P) !== P - _1n; Z++);
|
||||||
|
|
||||||
|
// Fast-path
|
||||||
|
if (S === 1) {
|
||||||
|
const p1div4 = (P + _1n) / _4n;
|
||||||
|
return function tonelliFast<T>(Fp: Field<T>, n: T) {
|
||||||
|
const root = Fp.pow(n, p1div4);
|
||||||
|
if (!Fp.equals(Fp.square(root), n)) throw new Error('Cannot find square root');
|
||||||
|
return root;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slow-path
|
||||||
|
const Q1div2 = (Q + _1n) / _2n;
|
||||||
|
return function tonelliSlow<T>(Fp: Field<T>, n: T): T {
|
||||||
|
// Step 0: Check that n is indeed a square: (n | p) must be ≡ 1
|
||||||
|
if (Fp.pow(n, legendreC) !== Fp.ONE) throw new Error('Cannot find square root');
|
||||||
|
let s = S;
|
||||||
|
|
||||||
|
let c = pow(Z, Q, P);
|
||||||
|
let r = Fp.pow(n, Q1div2);
|
||||||
|
let t = Fp.pow(n, Q);
|
||||||
|
|
||||||
|
let t2 = Fp.ZERO;
|
||||||
|
while (!Fp.equals(Fp.sub(t, Fp.ONE), Fp.ZERO)) {
|
||||||
|
t2 = Fp.square(t);
|
||||||
|
let i;
|
||||||
|
for (i = 1; i < s; i++) {
|
||||||
|
// stop if t2-1 == 0
|
||||||
|
if (Fp.equals(Fp.sub(t2, Fp.ONE), Fp.ZERO)) break;
|
||||||
|
// t2 *= t2
|
||||||
|
t2 = Fp.square(t2);
|
||||||
|
}
|
||||||
|
let b = pow(c, BigInt(1 << (s - i - 1)), P);
|
||||||
|
r = Fp.mul(r, b);
|
||||||
|
c = mod(b * b, P);
|
||||||
|
t = Fp.mul(t, c);
|
||||||
|
s = i;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function FpSqrt(P: bigint) {
|
||||||
|
// NOTE: different algorithms can give different roots, it is up to user to decide which one they want.
|
||||||
|
// For example there is FpSqrtOdd/FpSqrtEven to choice root based on oddness (used for hash-to-curve).
|
||||||
|
|
||||||
|
// P ≡ 3 (mod 4)
|
||||||
|
// √n = n^((P+1)/4)
|
||||||
|
if (P % _4n === _3n) {
|
||||||
|
// Not all roots possible!
|
||||||
|
// const ORDER =
|
||||||
|
// 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaabn;
|
||||||
|
// const NUM = 72057594037927816n;
|
||||||
|
const p1div4 = (P + _1n) / _4n;
|
||||||
|
return function sqrt3mod4<T>(Fp: Field<T>, n: T) {
|
||||||
|
const root = Fp.pow(n, p1div4);
|
||||||
|
// Throw if root**2 != n
|
||||||
|
if (!Fp.equals(Fp.square(root), n)) throw new Error('Cannot find square root');
|
||||||
|
return root;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Atkin algorithm for q ≡ 5 (mod 8), https://eprint.iacr.org/2012/685.pdf (page 10)
|
||||||
|
if (P % _8n === _5n) {
|
||||||
|
const c1 = (P - _5n) / _8n;
|
||||||
|
return function sqrt5mod8<T>(Fp: Field<T>, n: T) {
|
||||||
|
const n2 = Fp.mul(n, _2n);
|
||||||
|
const v = Fp.pow(n2, c1);
|
||||||
|
const nv = Fp.mul(n, v);
|
||||||
|
const i = Fp.mul(Fp.mul(nv, _2n), v);
|
||||||
|
const root = Fp.mul(nv, Fp.sub(i, Fp.ONE));
|
||||||
|
if (!Fp.equals(Fp.square(root), n)) throw new Error('Cannot find square root');
|
||||||
|
return root;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// P ≡ 9 (mod 16)
|
||||||
|
if (P % _16n === _9n) {
|
||||||
|
// NOTE: tonelli is too slow for bls-Fp2 calculations even on start
|
||||||
|
// Means we cannot use sqrt for constants at all!
|
||||||
|
//
|
||||||
|
// const c1 = Fp.sqrt(Fp.negate(Fp.ONE)); // 1. c1 = sqrt(-1) in F, i.e., (c1^2) == -1 in F
|
||||||
|
// const c2 = Fp.sqrt(c1); // 2. c2 = sqrt(c1) in F, i.e., (c2^2) == c1 in F
|
||||||
|
// const c3 = Fp.sqrt(Fp.negate(c1)); // 3. c3 = sqrt(-c1) in F, i.e., (c3^2) == -c1 in F
|
||||||
|
// const c4 = (P + _7n) / _16n; // 4. c4 = (q + 7) / 16 # Integer arithmetic
|
||||||
|
// sqrt = (x) => {
|
||||||
|
// let tv1 = Fp.pow(x, c4); // 1. tv1 = x^c4
|
||||||
|
// let tv2 = Fp.mul(c1, tv1); // 2. tv2 = c1 * tv1
|
||||||
|
// const tv3 = Fp.mul(c2, tv1); // 3. tv3 = c2 * tv1
|
||||||
|
// let tv4 = Fp.mul(c3, tv1); // 4. tv4 = c3 * tv1
|
||||||
|
// const e1 = Fp.equals(Fp.square(tv2), x); // 5. e1 = (tv2^2) == x
|
||||||
|
// const e2 = Fp.equals(Fp.square(tv3), x); // 6. e2 = (tv3^2) == x
|
||||||
|
// tv1 = Fp.cmov(tv1, tv2, e1); // 7. tv1 = CMOV(tv1, tv2, e1) # Select tv2 if (tv2^2) == x
|
||||||
|
// tv2 = Fp.cmov(tv4, tv3, e2); // 8. tv2 = CMOV(tv4, tv3, e2) # Select tv3 if (tv3^2) == x
|
||||||
|
// const e3 = Fp.equals(Fp.square(tv2), x); // 9. e3 = (tv2^2) == x
|
||||||
|
// return Fp.cmov(tv1, tv2, e3); // 10. z = CMOV(tv1, tv2, e3) # Select the sqrt from tv1 and tv2
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Other cases: Tonelli-Shanks algorithm
|
||||||
|
return tonelliShanks(P);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Little-endian check for first LE bit (last BE bit);
|
||||||
|
export const isNegativeLE = (num: bigint, modulo: bigint) => (mod(num, modulo) & _1n) === _1n;
|
||||||
|
|
||||||
|
// Currently completly inconsistent naming:
|
||||||
|
// - readable: add, mul, sqr, sqrt, inv, div, pow, eq, sub
|
||||||
|
// - unreadable mess: addition, multiply, square, squareRoot, inversion, divide, power, equals, subtract
|
||||||
|
|
||||||
|
// Field is not always over prime, Fp2 for example has ORDER(q)=p^m
|
||||||
|
export interface Field<T> {
|
||||||
|
ORDER: bigint;
|
||||||
|
BYTES: number;
|
||||||
|
BITS: number;
|
||||||
|
MASK: bigint;
|
||||||
|
ZERO: T;
|
||||||
|
ONE: T;
|
||||||
|
// 1-arg
|
||||||
|
create: (num: T) => T;
|
||||||
|
isValid: (num: T) => boolean;
|
||||||
|
isZero: (num: T) => boolean;
|
||||||
|
negate(num: T): T;
|
||||||
|
invert(num: T): T;
|
||||||
|
sqrt(num: T): T;
|
||||||
|
square(num: T): T;
|
||||||
|
// 2-args
|
||||||
|
equals(lhs: T, rhs: T): boolean;
|
||||||
|
add(lhs: T, rhs: T): T;
|
||||||
|
sub(lhs: T, rhs: T): T;
|
||||||
|
mul(lhs: T, rhs: T | bigint): T;
|
||||||
|
pow(lhs: T, power: bigint): T;
|
||||||
|
div(lhs: T, rhs: T | bigint): T;
|
||||||
|
// N for NonNormalized (for now)
|
||||||
|
addN(lhs: T, rhs: T): T;
|
||||||
|
subN(lhs: T, rhs: T): T;
|
||||||
|
mulN(lhs: T, rhs: T | bigint): T;
|
||||||
|
squareN(num: T): T;
|
||||||
|
|
||||||
|
// Optional
|
||||||
|
// Should be same as sgn0 function in https://datatracker.ietf.org/doc/draft-irtf-cfrg-hash-to-curve/
|
||||||
|
// NOTE: sgn0 is 'negative in LE', which is same as odd. And negative in LE is kinda strange definition anyway.
|
||||||
|
isOdd?(num: T): boolean; // Odd instead of even since we have it for Fp2
|
||||||
|
legendre?(num: T): T;
|
||||||
|
pow(lhs: T, power: bigint): T;
|
||||||
|
invertBatch: (lst: T[]) => T[];
|
||||||
|
toBytes(num: T): Uint8Array;
|
||||||
|
fromBytes(bytes: Uint8Array): T;
|
||||||
|
// If c is False, CMOV returns a, otherwise it returns b.
|
||||||
|
cmov(a: T, b: T, c: boolean): T;
|
||||||
|
}
|
||||||
|
// prettier-ignore
|
||||||
|
const FIELD_FIELDS = [
|
||||||
|
'create', 'isValid', 'isZero', 'negate', 'invert', 'sqrt', 'square',
|
||||||
|
'equals', 'add', 'sub', 'mul', 'pow', 'div',
|
||||||
|
'addN', 'subN', 'mulN', 'squareN'
|
||||||
|
] as const;
|
||||||
|
export function validateField<T>(field: Field<T>) {
|
||||||
|
for (const i of ['ORDER', 'MASK'] as const) {
|
||||||
|
if (typeof field[i] !== 'bigint')
|
||||||
|
throw new Error(`Invalid field param ${i}=${field[i]} (${typeof field[i]})`);
|
||||||
|
}
|
||||||
|
for (const i of ['BYTES', 'BITS'] as const) {
|
||||||
|
if (typeof field[i] !== 'number')
|
||||||
|
throw new Error(`Invalid field param ${i}=${field[i]} (${typeof field[i]})`);
|
||||||
|
}
|
||||||
|
for (const i of FIELD_FIELDS) {
|
||||||
|
if (typeof field[i] !== 'function')
|
||||||
|
throw new Error(`Invalid field param ${i}=${field[i]} (${typeof field[i]})`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generic field functions
|
||||||
|
export function FpPow<T>(f: Field<T>, num: T, power: bigint): T {
|
||||||
|
// Should have same speed as pow for bigints
|
||||||
|
// TODO: benchmark!
|
||||||
|
if (power < _0n) throw new Error('Expected power > 0');
|
||||||
|
if (power === _0n) return f.ONE;
|
||||||
|
if (power === _1n) return num;
|
||||||
|
let p = f.ONE;
|
||||||
|
let d = num;
|
||||||
|
while (power > _0n) {
|
||||||
|
if (power & _1n) p = f.mul(p, d);
|
||||||
|
d = f.square(d);
|
||||||
|
power >>= 1n;
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function FpInvertBatch<T>(f: Field<T>, nums: T[]): T[] {
|
||||||
|
const tmp = new Array(nums.length);
|
||||||
|
// Walk from first to last, multiply them by each other MOD p
|
||||||
|
const lastMultiplied = nums.reduce((acc, num, i) => {
|
||||||
|
if (f.isZero(num)) return acc;
|
||||||
|
tmp[i] = acc;
|
||||||
|
return f.mul(acc, num);
|
||||||
|
}, f.ONE);
|
||||||
|
// Invert last element
|
||||||
|
const inverted = f.invert(lastMultiplied);
|
||||||
|
// Walk from last to first, multiply them by inverted each other MOD p
|
||||||
|
nums.reduceRight((acc, num, i) => {
|
||||||
|
if (f.isZero(num)) return acc;
|
||||||
|
tmp[i] = f.mul(acc, tmp[i]);
|
||||||
|
return f.mul(acc, num);
|
||||||
|
}, inverted);
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function FpDiv<T>(f: Field<T>, lhs: T, rhs: T | bigint): T {
|
||||||
|
return f.mul(lhs, typeof rhs === 'bigint' ? invert(rhs, f.ORDER) : f.invert(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function returns True whenever the value x is a square in the field F.
|
||||||
|
export function FpIsSquare<T>(f: Field<T>) {
|
||||||
|
const legendreConst = (f.ORDER - _1n) / _2n; // Integer arithmetic
|
||||||
|
return (x: T): boolean => {
|
||||||
|
const p = f.pow(x, legendreConst);
|
||||||
|
return f.equals(p, f.ZERO) || f.equals(p, f.ONE);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: very fragile, always bench. Major performance points:
|
||||||
|
// - NonNormalized ops
|
||||||
|
// - Object.freeze
|
||||||
|
// - same shape of object (don't add/remove keys)
|
||||||
|
type FpField = Field<bigint> & Required<Pick<Field<bigint>, 'isOdd'>>;
|
||||||
|
export function Fp(
|
||||||
|
ORDER: bigint,
|
||||||
|
bitLen?: number,
|
||||||
|
isLE = false,
|
||||||
|
redef: Partial<Field<bigint>> = {}
|
||||||
|
): Readonly<FpField> {
|
||||||
|
if (ORDER <= _0n) throw new Error(`Expected Fp ORDER > 0, got ${ORDER}`);
|
||||||
|
const { nBitLength: BITS, nByteLength: BYTES } = utils.nLength(ORDER, bitLen);
|
||||||
|
if (BYTES > 2048) throw new Error('Field lengths over 2048 bytes are not supported');
|
||||||
|
const sqrtP = FpSqrt(ORDER);
|
||||||
|
const f: Readonly<FpField> = Object.freeze({
|
||||||
|
ORDER,
|
||||||
|
BITS,
|
||||||
|
BYTES,
|
||||||
|
MASK: utils.bitMask(BITS),
|
||||||
|
ZERO: _0n,
|
||||||
|
ONE: _1n,
|
||||||
|
create: (num) => mod(num, ORDER),
|
||||||
|
isValid: (num) => {
|
||||||
|
if (typeof num !== 'bigint')
|
||||||
|
throw new Error(`Invalid field element: expected bigint, got ${typeof num}`);
|
||||||
|
return _0n <= num && num < ORDER;
|
||||||
|
},
|
||||||
|
isZero: (num) => num === _0n,
|
||||||
|
isOdd: (num) => (num & _1n) === _1n,
|
||||||
|
negate: (num) => mod(-num, ORDER),
|
||||||
|
equals: (lhs, rhs) => lhs === rhs,
|
||||||
|
|
||||||
|
square: (num) => mod(num * num, ORDER),
|
||||||
|
add: (lhs, rhs) => mod(lhs + rhs, ORDER),
|
||||||
|
sub: (lhs, rhs) => mod(lhs - rhs, ORDER),
|
||||||
|
mul: (lhs, rhs) => mod(lhs * rhs, ORDER),
|
||||||
|
pow: (num, power) => FpPow(f, num, power),
|
||||||
|
div: (lhs, rhs) => mod(lhs * invert(rhs, ORDER), ORDER),
|
||||||
|
|
||||||
|
// Same as above, but doesn't normalize
|
||||||
|
squareN: (num) => num * num,
|
||||||
|
addN: (lhs, rhs) => lhs + rhs,
|
||||||
|
subN: (lhs, rhs) => lhs - rhs,
|
||||||
|
mulN: (lhs, rhs) => lhs * rhs,
|
||||||
|
|
||||||
|
invert: (num) => invert(num, ORDER),
|
||||||
|
sqrt: redef.sqrt || ((n) => sqrtP(f, n)),
|
||||||
|
invertBatch: (lst) => FpInvertBatch(f, lst),
|
||||||
|
// TODO: do we really need constant cmov?
|
||||||
|
// We don't have const-time bigints anyway, so probably will be not very useful
|
||||||
|
cmov: (a, b, c) => (c ? b : a),
|
||||||
|
toBytes: (num) =>
|
||||||
|
isLE ? utils.numberToBytesLE(num, BYTES) : utils.numberToBytesBE(num, BYTES),
|
||||||
|
|
||||||
|
fromBytes: (bytes) => {
|
||||||
|
if (bytes.length !== BYTES)
|
||||||
|
throw new Error(`Fp.fromBytes: expected ${BYTES}, got ${bytes.length}`);
|
||||||
|
return isLE ? utils.bytesToNumberLE(bytes) : utils.bytesToNumberBE(bytes);
|
||||||
|
},
|
||||||
|
} as FpField);
|
||||||
|
return Object.freeze(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function FpSqrtOdd<T>(Fp: Field<T>, elm: T) {
|
||||||
|
if (!Fp.isOdd) throw new Error(`Field doesn't have isOdd`);
|
||||||
|
const root = Fp.sqrt(elm);
|
||||||
|
return Fp.isOdd(root) ? root : Fp.negate(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function FpSqrtEven<T>(Fp: Field<T>, elm: T) {
|
||||||
|
if (!Fp.isOdd) throw new Error(`Field doesn't have isOdd`);
|
||||||
|
const root = Fp.sqrt(elm);
|
||||||
|
return Fp.isOdd(root) ? Fp.negate(root) : root;
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||||
import * as mod from './modular.js';
|
import * as mod from './modular.js';
|
||||||
import {
|
import {
|
||||||
ensureBytes,
|
ensureBytes,
|
||||||
@@ -23,8 +24,9 @@ export type CurveType = {
|
|||||||
Gu: string;
|
Gu: string;
|
||||||
};
|
};
|
||||||
export type CurveFn = {
|
export type CurveFn = {
|
||||||
scalarMult: (u: Hex, scalar: Hex) => Uint8Array;
|
scalarMult: (scalar: Hex, u: Hex) => Uint8Array;
|
||||||
scalarMultBase: (scalar: Hex) => Uint8Array;
|
scalarMultBase: (scalar: Hex) => Uint8Array;
|
||||||
|
getSharedSecret: (privateKeyA: Hex, publicKeyB: Hex) => Uint8Array;
|
||||||
getPublicKey: (privateKey: Hex) => Uint8Array;
|
getPublicKey: (privateKey: Hex) => Uint8Array;
|
||||||
Gu: string;
|
Gu: string;
|
||||||
};
|
};
|
||||||
@@ -86,7 +88,7 @@ export function montgomery(curveDef: CurveType): CurveFn {
|
|||||||
|
|
||||||
// cswap from RFC7748
|
// cswap from RFC7748
|
||||||
// NOTE: cswap is not from RFC7748!
|
// NOTE: cswap is not from RFC7748!
|
||||||
/*
|
/*
|
||||||
cswap(swap, x_2, x_3):
|
cswap(swap, x_2, x_3):
|
||||||
dummy = mask(swap) AND (x_2 XOR x_3)
|
dummy = mask(swap) AND (x_2 XOR x_3)
|
||||||
x_2 = x_2 XOR dummy
|
x_2 = x_2 XOR dummy
|
||||||
@@ -185,8 +187,14 @@ export function montgomery(curveDef: CurveType): CurveFn {
|
|||||||
throw new Error(`Expected ${montgomeryBytes} or ${fieldLen} bytes, got ${bytes.length}`);
|
throw new Error(`Expected ${montgomeryBytes} or ${fieldLen} bytes, got ${bytes.length}`);
|
||||||
return bytesToNumberLE(adjustScalarBytes(bytes));
|
return bytesToNumberLE(adjustScalarBytes(bytes));
|
||||||
}
|
}
|
||||||
// Multiply point u by scalar
|
/**
|
||||||
function scalarMult(u: Hex, scalar: Hex): Uint8Array {
|
* Computes shared secret between private key "scalar" and public key's "u" (x) coordinate.
|
||||||
|
* We can get 'y' coordinate from 'u',
|
||||||
|
* but Point.fromHex also wants 'x' coordinate oddity flag,
|
||||||
|
* and we cannot get 'x' without knowing 'v'.
|
||||||
|
* Need to add generic conversion between twisted edwards and complimentary curve for JubJub.
|
||||||
|
*/
|
||||||
|
function scalarMult(scalar: Hex, u: Hex): Uint8Array {
|
||||||
const pointU = decodeUCoordinate(u);
|
const pointU = decodeUCoordinate(u);
|
||||||
const _scalar = decodeScalar(scalar);
|
const _scalar = decodeScalar(scalar);
|
||||||
const pu = montgomeryLadder(pointU, _scalar);
|
const pu = montgomeryLadder(pointU, _scalar);
|
||||||
@@ -195,18 +203,20 @@ export function montgomery(curveDef: CurveType): CurveFn {
|
|||||||
if (pu === _0n) throw new Error('Invalid private or public key received');
|
if (pu === _0n) throw new Error('Invalid private or public key received');
|
||||||
return encodeUCoordinate(pu);
|
return encodeUCoordinate(pu);
|
||||||
}
|
}
|
||||||
// Multiply base point by scalar
|
/**
|
||||||
|
* Computes public key from private.
|
||||||
|
* Executes scalar multiplication of curve's base point by scalar.
|
||||||
|
* @param scalar private key
|
||||||
|
* @returns new public key
|
||||||
|
*/
|
||||||
function scalarMultBase(scalar: Hex): Uint8Array {
|
function scalarMultBase(scalar: Hex): Uint8Array {
|
||||||
return scalarMult(CURVE.Gu, scalar);
|
return scalarMult(scalar, CURVE.Gu);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// NOTE: we can get 'y' coordinate from 'u', but Point.fromHex also wants 'x' coordinate oddity flag, and we cannot get 'x' without knowing 'v'
|
|
||||||
// Need to add generic conversion between twisted edwards and complimentary curve for JubJub
|
|
||||||
scalarMult,
|
scalarMult,
|
||||||
scalarMultBase,
|
scalarMultBase,
|
||||||
// NOTE: these function work on complimentary montgomery curve
|
getSharedSecret: (privateKey: Hex, publicKey: Hex) => scalarMult(privateKey, publicKey),
|
||||||
// getSharedSecret: (privateKey: Hex, publicKey: Hex) => scalarMult(publicKey, privateKey),
|
|
||||||
getPublicKey: (privateKey: Hex): Uint8Array => scalarMultBase(privateKey),
|
getPublicKey: (privateKey: Hex): Uint8Array => scalarMultBase(privateKey),
|
||||||
Gu: CURVE.Gu,
|
Gu: CURVE.Gu,
|
||||||
};
|
};
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||||
import * as mod from './modular.js';
|
import * as mod from './modular.js';
|
||||||
const _0n = BigInt(0);
|
const _0n = BigInt(0);
|
||||||
const _1n = BigInt(1);
|
const _1n = BigInt(1);
|
||||||
@@ -12,7 +12,7 @@ export type CHash = {
|
|||||||
(message: Uint8Array | string): Uint8Array;
|
(message: Uint8Array | string): Uint8Array;
|
||||||
blockLen: number;
|
blockLen: number;
|
||||||
outputLen: number;
|
outputLen: number;
|
||||||
create(): any;
|
create(opts?: { dkLen?: number }): any; // For shake
|
||||||
};
|
};
|
||||||
|
|
||||||
// NOTE: these are generic, even if curve is on some polynominal field (bls), it will still have P/n/h
|
// NOTE: these are generic, even if curve is on some polynominal field (bls), it will still have P/n/h
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||||
// Implementation of Short Weierstrass curve. The formula is: y² = x³ + ax + b
|
// Short Weierstrass curve. The formula is: y² = x³ + ax + b
|
||||||
|
|
||||||
// TODO: sync vs async naming
|
// TODO: sync vs async naming
|
||||||
// TODO: default randomBytes
|
// TODO: default randomBytes
|
||||||
@@ -23,7 +23,7 @@ import {
|
|||||||
PrivKey,
|
PrivKey,
|
||||||
} from './utils.js';
|
} from './utils.js';
|
||||||
import * as utils from './utils.js';
|
import * as utils from './utils.js';
|
||||||
import { hash_to_field, htfOpts, validateHTFOpts } from './hashToCurve.js';
|
import { hash_to_field, htfOpts, validateHTFOpts } from './hash-to-curve.js';
|
||||||
import { Group, GroupConstructor, wNAF } from './group.js';
|
import { Group, GroupConstructor, wNAF } from './group.js';
|
||||||
|
|
||||||
type HmacFnSync = (key: Uint8Array, ...messages: Uint8Array[]) => Uint8Array;
|
type HmacFnSync = (key: Uint8Array, ...messages: Uint8Array[]) => Uint8Array;
|
||||||
@@ -41,8 +41,11 @@ export type BasicCurve<T> = utils.BasicCurve<T> & {
|
|||||||
// Endomorphism options for Koblitz curves
|
// Endomorphism options for Koblitz curves
|
||||||
endo?: EndomorphismOpts;
|
endo?: EndomorphismOpts;
|
||||||
// Torsions, can be optimized via endomorphisms
|
// Torsions, can be optimized via endomorphisms
|
||||||
isTorsionFree?: (c: JacobianConstructor<T>, point: JacobianPointType<T>) => boolean;
|
isTorsionFree?: (c: ProjectiveConstructor<T>, point: ProjectivePointType<T>) => boolean;
|
||||||
clearCofactor?: (c: JacobianConstructor<T>, point: JacobianPointType<T>) => JacobianPointType<T>;
|
clearCofactor?: (
|
||||||
|
c: ProjectiveConstructor<T>,
|
||||||
|
point: ProjectivePointType<T>
|
||||||
|
) => ProjectivePointType<T>;
|
||||||
// Hash to field opts
|
// Hash to field opts
|
||||||
htfDefaults?: htfOpts;
|
htfDefaults?: htfOpts;
|
||||||
mapToCurve?: (scalar: bigint[]) => { x: T; y: T };
|
mapToCurve?: (scalar: bigint[]) => { x: T; y: T };
|
||||||
@@ -94,9 +97,7 @@ function parseDERSignature(data: Uint8Array) {
|
|||||||
// Be friendly to bad ECMAScript parsers by not using bigint literals like 123n
|
// Be friendly to bad ECMAScript parsers by not using bigint literals like 123n
|
||||||
const _0n = BigInt(0);
|
const _0n = BigInt(0);
|
||||||
const _1n = BigInt(1);
|
const _1n = BigInt(1);
|
||||||
const _2n = BigInt(2);
|
|
||||||
const _3n = BigInt(3);
|
const _3n = BigInt(3);
|
||||||
const _8n = BigInt(8);
|
|
||||||
|
|
||||||
type Entropy = Hex | true;
|
type Entropy = Hex | true;
|
||||||
type SignOpts = { lowS?: boolean; extraEntropy?: Entropy };
|
type SignOpts = { lowS?: boolean; extraEntropy?: Entropy };
|
||||||
@@ -124,20 +125,20 @@ type SignOpts = { lowS?: boolean; extraEntropy?: Entropy };
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Instance
|
// Instance
|
||||||
export interface JacobianPointType<T> extends Group<JacobianPointType<T>> {
|
export interface ProjectivePointType<T> extends Group<ProjectivePointType<T>> {
|
||||||
readonly x: T;
|
readonly x: T;
|
||||||
readonly y: T;
|
readonly y: T;
|
||||||
readonly z: T;
|
readonly z: T;
|
||||||
multiply(scalar: number | bigint, affinePoint?: PointType<T>): JacobianPointType<T>;
|
multiply(scalar: number | bigint, affinePoint?: PointType<T>): ProjectivePointType<T>;
|
||||||
multiplyUnsafe(scalar: bigint): JacobianPointType<T>;
|
multiplyUnsafe(scalar: bigint): ProjectivePointType<T>;
|
||||||
toAffine(invZ?: T): PointType<T>;
|
toAffine(invZ?: T): PointType<T>;
|
||||||
}
|
}
|
||||||
// Static methods
|
// Static methods
|
||||||
export interface JacobianConstructor<T> extends GroupConstructor<JacobianPointType<T>> {
|
export interface ProjectiveConstructor<T> extends GroupConstructor<ProjectivePointType<T>> {
|
||||||
new (x: T, y: T, z: T): JacobianPointType<T>;
|
new (x: T, y: T, z: T): ProjectivePointType<T>;
|
||||||
fromAffine(p: PointType<T>): JacobianPointType<T>;
|
fromAffine(p: PointType<T>): ProjectivePointType<T>;
|
||||||
toAffineBatch(points: JacobianPointType<T>[]): PointType<T>[];
|
toAffineBatch(points: ProjectivePointType<T>[]): PointType<T>[];
|
||||||
normalizeZ(points: JacobianPointType<T>[]): JacobianPointType<T>[];
|
normalizeZ(points: ProjectivePointType<T>[]): ProjectivePointType<T>[];
|
||||||
}
|
}
|
||||||
// Instance
|
// Instance
|
||||||
export interface PointType<T> extends Group<PointType<T>> {
|
export interface PointType<T> extends Group<PointType<T>> {
|
||||||
@@ -199,7 +200,7 @@ function validatePointOpts<T>(curve: CurvePointsType<T>) {
|
|||||||
|
|
||||||
export type CurvePointsRes<T> = {
|
export type CurvePointsRes<T> = {
|
||||||
Point: PointConstructor<T>;
|
Point: PointConstructor<T>;
|
||||||
JacobianPoint: JacobianConstructor<T>;
|
ProjectivePoint: ProjectiveConstructor<T>;
|
||||||
normalizePrivateKey: (key: PrivKey) => bigint;
|
normalizePrivateKey: (key: PrivKey) => bigint;
|
||||||
weierstrassEquation: (x: T) => T;
|
weierstrassEquation: (x: T) => T;
|
||||||
isWithinCurveOrder: (num: bigint) => boolean;
|
isWithinCurveOrder: (num: bigint) => boolean;
|
||||||
@@ -229,8 +230,8 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
|||||||
function weierstrassEquation(x: T): T {
|
function weierstrassEquation(x: T): T {
|
||||||
const { a, b } = CURVE;
|
const { a, b } = CURVE;
|
||||||
const x2 = Fp.square(x); // x * x
|
const x2 = Fp.square(x); // x * x
|
||||||
const x3 = Fp.multiply(x2, x); // x2 * x
|
const x3 = Fp.mul(x2, x); // x2 * x
|
||||||
return Fp.add(Fp.add(x3, Fp.multiply(x, a)), b); // x3 + a * x + b
|
return Fp.add(Fp.add(x3, Fp.mul(x, a)), b); // x3 + a * x + b
|
||||||
}
|
}
|
||||||
|
|
||||||
function isWithinCurveOrder(num: bigint): boolean {
|
function isWithinCurveOrder(num: bigint): boolean {
|
||||||
@@ -267,130 +268,160 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Jacobian Point works in 3d / jacobi coordinates: (x, y, z) ∋ (x=x/z², y=y/z³)
|
* Projective Point works in 3d / projective (homogeneous) coordinates: (x, y, z) ∋ (x=x/z, y=y/z)
|
||||||
* Default Point works in 2d / affine coordinates: (x, y)
|
* Default Point works in 2d / affine coordinates: (x, y)
|
||||||
* We're doing calculations in jacobi, because its operations don't require costly inversion.
|
* We're doing calculations in projective, because its operations don't require costly inversion.
|
||||||
*/
|
*/
|
||||||
class JacobianPoint implements JacobianPointType<T> {
|
class ProjectivePoint implements ProjectivePointType<T> {
|
||||||
constructor(readonly x: T, readonly y: T, readonly z: T) {}
|
constructor(readonly x: T, readonly y: T, readonly z: T) {}
|
||||||
|
|
||||||
static readonly BASE = new JacobianPoint(CURVE.Gx, CURVE.Gy, Fp.ONE);
|
static readonly BASE = new ProjectivePoint(CURVE.Gx, CURVE.Gy, Fp.ONE);
|
||||||
static readonly ZERO = new JacobianPoint(Fp.ZERO, Fp.ONE, Fp.ZERO);
|
static readonly ZERO = new ProjectivePoint(Fp.ZERO, Fp.ONE, Fp.ZERO);
|
||||||
|
|
||||||
static fromAffine(p: Point): JacobianPoint {
|
static fromAffine(p: Point): ProjectivePoint {
|
||||||
if (!(p instanceof Point)) {
|
if (!(p instanceof Point)) {
|
||||||
throw new TypeError('JacobianPoint#fromAffine: expected Point');
|
throw new TypeError('ProjectivePoint#fromAffine: expected Point');
|
||||||
}
|
}
|
||||||
// fromAffine(x:0, y:0) would produce (x:0, y:0, z:1), but we need (x:0, y:1, z:0)
|
// fromAffine(x:0, y:0) would produce (x:0, y:0, z:1), but we need (x:0, y:1, z:0)
|
||||||
if (p.equals(Point.ZERO)) return JacobianPoint.ZERO;
|
if (p.equals(Point.ZERO)) return ProjectivePoint.ZERO;
|
||||||
return new JacobianPoint(p.x, p.y, Fp.ONE);
|
return new ProjectivePoint(p.x, p.y, Fp.ONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes a bunch of Jacobian Points but executes only one
|
* Takes a bunch of Projective Points but executes only one
|
||||||
* invert on all of them. invert is very slow operation,
|
* invert on all of them. invert is very slow operation,
|
||||||
* so this improves performance massively.
|
* so this improves performance massively.
|
||||||
*/
|
*/
|
||||||
static toAffineBatch(points: JacobianPoint[]): Point[] {
|
static toAffineBatch(points: ProjectivePoint[]): Point[] {
|
||||||
const toInv = Fp.invertBatch(points.map((p) => p.z));
|
const toInv = Fp.invertBatch(points.map((p) => p.z));
|
||||||
return points.map((p, i) => p.toAffine(toInv[i]));
|
return points.map((p, i) => p.toAffine(toInv[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
static normalizeZ(points: JacobianPoint[]): JacobianPoint[] {
|
static normalizeZ(points: ProjectivePoint[]): ProjectivePoint[] {
|
||||||
return JacobianPoint.toAffineBatch(points).map(JacobianPoint.fromAffine);
|
return ProjectivePoint.toAffineBatch(points).map(ProjectivePoint.fromAffine);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare one point to another.
|
* Compare one point to another.
|
||||||
*/
|
*/
|
||||||
equals(other: JacobianPoint): boolean {
|
equals(other: ProjectivePoint): boolean {
|
||||||
if (!(other instanceof JacobianPoint)) throw new TypeError('JacobianPoint expected');
|
assertPrjPoint(other);
|
||||||
const { x: X1, y: Y1, z: Z1 } = this;
|
const { x: X1, y: Y1, z: Z1 } = this;
|
||||||
const { x: X2, y: Y2, z: Z2 } = other;
|
const { x: X2, y: Y2, z: Z2 } = other;
|
||||||
const Z1Z1 = Fp.square(Z1); // Z1 * Z1
|
const U1 = Fp.equals(Fp.mul(X1, Z2), Fp.mul(X2, Z1));
|
||||||
const Z2Z2 = Fp.square(Z2); // Z2 * Z2
|
const U2 = Fp.equals(Fp.mul(Y1, Z2), Fp.mul(Y2, Z1));
|
||||||
const U1 = Fp.multiply(X1, Z2Z2); // X1 * Z2Z2
|
return U1 && U2;
|
||||||
const U2 = Fp.multiply(X2, Z1Z1); // X2 * Z1Z1
|
|
||||||
const S1 = Fp.multiply(Fp.multiply(Y1, Z2), Z2Z2); // Y1 * Z2 * Z2Z2
|
|
||||||
const S2 = Fp.multiply(Fp.multiply(Y2, Z1), Z1Z1); // Y2 * Z1 * Z1Z1
|
|
||||||
return Fp.equals(U1, U2) && Fp.equals(S1, S2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flips point to one corresponding to (x, -y) in Affine coordinates.
|
* Flips point to one corresponding to (x, -y) in Affine coordinates.
|
||||||
*/
|
*/
|
||||||
negate(): JacobianPoint {
|
negate(): ProjectivePoint {
|
||||||
return new JacobianPoint(this.x, Fp.negate(this.y), this.z);
|
return new ProjectivePoint(this.x, Fp.negate(this.y), this.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fast algo for doubling 2 Jacobian Points.
|
doubleAdd(): ProjectivePoint {
|
||||||
// From: https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-2007-bl
|
return this.add(this);
|
||||||
// Cost: 1M + 8S + 1*a + 10add + 2*2 + 1*3 + 1*8.
|
}
|
||||||
double(): JacobianPoint {
|
|
||||||
|
// Renes-Costello-Batina exception-free doubling formula.
|
||||||
|
// There is 30% faster Jacobian formula, but it is not complete.
|
||||||
|
// https://eprint.iacr.org/2015/1060, algorithm 3
|
||||||
|
// Cost: 8M + 3S + 3*a + 2*b3 + 15add.
|
||||||
|
double() {
|
||||||
|
const { a, b } = CURVE;
|
||||||
|
const b3 = Fp.mul(b, 3n);
|
||||||
const { x: X1, y: Y1, z: Z1 } = this;
|
const { x: X1, y: Y1, z: Z1 } = this;
|
||||||
const { a } = CURVE;
|
let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; // prettier-ignore
|
||||||
// Faster algorithm: when a=0
|
let t0 = Fp.mul(X1, X1); // step 1
|
||||||
// From: https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
|
let t1 = Fp.mul(Y1, Y1);
|
||||||
// Cost: 2M + 5S + 6add + 3*2 + 1*3 + 1*8.
|
let t2 = Fp.mul(Z1, Z1);
|
||||||
if (Fp.isZero(a)) {
|
let t3 = Fp.mul(X1, Y1);
|
||||||
const A = Fp.square(X1); // X1 * X1
|
t3 = Fp.add(t3, t3); // step 5
|
||||||
const B = Fp.square(Y1); // Y1 * Y1
|
Z3 = Fp.mul(X1, Z1);
|
||||||
const C = Fp.square(B); // B * B
|
Z3 = Fp.add(Z3, Z3);
|
||||||
const x1b = Fp.addN(X1, B); // X1 + B
|
X3 = Fp.mul(a, Z3);
|
||||||
const D = Fp.multiply(Fp.subtractN(Fp.subtractN(Fp.square(x1b), A), C), _2n); // ((x1b * x1b) - A - C) * 2
|
Y3 = Fp.mul(b3, t2);
|
||||||
const E = Fp.multiply(A, _3n); // A * 3
|
Y3 = Fp.add(X3, Y3); // step 10
|
||||||
const F = Fp.square(E); // E * E
|
X3 = Fp.sub(t1, Y3);
|
||||||
const X3 = Fp.subtract(F, Fp.multiplyN(D, _2n)); // F - 2 * D
|
Y3 = Fp.add(t1, Y3);
|
||||||
const Y3 = Fp.subtract(Fp.multiplyN(E, Fp.subtractN(D, X3)), Fp.multiplyN(C, _8n)); // E * (D - X3) - 8 * C;
|
Y3 = Fp.mul(X3, Y3);
|
||||||
const Z3 = Fp.multiply(Fp.multiplyN(Y1, _2n), Z1); // 2 * Y1 * Z1
|
X3 = Fp.mul(t3, X3);
|
||||||
return new JacobianPoint(X3, Y3, Z3);
|
Z3 = Fp.mul(b3, Z3); // step 15
|
||||||
}
|
t2 = Fp.mul(a, t2);
|
||||||
const XX = Fp.square(X1); // X1 * X1
|
t3 = Fp.sub(t0, t2);
|
||||||
const YY = Fp.square(Y1); // Y1 * Y1
|
t3 = Fp.mul(a, t3);
|
||||||
const YYYY = Fp.square(YY); // YY * YY
|
t3 = Fp.add(t3, Z3);
|
||||||
const ZZ = Fp.square(Z1); // Z1 * Z1
|
Z3 = Fp.add(t0, t0); // step 20
|
||||||
const tmp1 = Fp.add(X1, YY); // X1 + YY
|
t0 = Fp.add(Z3, t0);
|
||||||
const S = Fp.multiply(Fp.subtractN(Fp.subtractN(Fp.square(tmp1), XX), YYYY), _2n); // 2*((X1+YY)^2-XX-YYYY)
|
t0 = Fp.add(t0, t2);
|
||||||
const M = Fp.add(Fp.multiplyN(XX, _3n), Fp.multiplyN(Fp.square(ZZ), a)); // 3 * XX + a * ZZ^2
|
t0 = Fp.mul(t0, t3);
|
||||||
const T = Fp.subtract(Fp.square(M), Fp.multiplyN(S, _2n)); // M^2-2*S
|
Y3 = Fp.add(Y3, t0);
|
||||||
const X3 = T;
|
t2 = Fp.mul(Y1, Z1); // step 25
|
||||||
const Y3 = Fp.subtract(Fp.multiplyN(M, Fp.subtractN(S, T)), Fp.multiplyN(YYYY, _8n)); // M*(S-T)-8*YYYY
|
t2 = Fp.add(t2, t2);
|
||||||
const y1az1 = Fp.add(Y1, Z1); // (Y1+Z1)
|
t0 = Fp.mul(t2, t3);
|
||||||
const Z3 = Fp.subtract(Fp.subtractN(Fp.square(y1az1), YY), ZZ); // (Y1+Z1)^2-YY-ZZ
|
X3 = Fp.sub(X3, t0);
|
||||||
return new JacobianPoint(X3, Y3, Z3);
|
Z3 = Fp.mul(t2, t1);
|
||||||
|
Z3 = Fp.add(Z3, Z3); // step 30
|
||||||
|
Z3 = Fp.add(Z3, Z3);
|
||||||
|
return new ProjectivePoint(X3, Y3, Z3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fast algo for adding 2 Jacobian Points.
|
// Renes-Costello-Batina exception-free addition formula.
|
||||||
// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#addition-add-1998-cmo-2
|
// There is 30% faster Jacobian formula, but it is not complete.
|
||||||
// Cost: 12M + 4S + 6add + 1*2
|
// https://eprint.iacr.org/2015/1060, algorithm 1
|
||||||
// Note: 2007 Bernstein-Lange (11M + 5S + 9add + 4*2) is actually 10% slower.
|
// Cost: 12M + 0S + 3*a + 3*b3 + 23add.
|
||||||
add(other: JacobianPoint): JacobianPoint {
|
add(other: ProjectivePoint): ProjectivePoint {
|
||||||
if (!(other instanceof JacobianPoint)) throw new TypeError('JacobianPoint expected');
|
assertPrjPoint(other);
|
||||||
const { x: X1, y: Y1, z: Z1 } = this;
|
const { x: X1, y: Y1, z: Z1 } = this;
|
||||||
const { x: X2, y: Y2, z: Z2 } = other;
|
const { x: X2, y: Y2, z: Z2 } = other;
|
||||||
if (Fp.isZero(X2) || Fp.isZero(Y2)) return this;
|
let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; // prettier-ignore
|
||||||
if (Fp.isZero(X1) || Fp.isZero(Y1)) return other;
|
const a = CURVE.a;
|
||||||
// We're using same code in equals()
|
const b3 = Fp.mul(CURVE.b, 3n);
|
||||||
const Z1Z1 = Fp.square(Z1); // Z1Z1 = Z1^2
|
let t0 = Fp.mul(X1, X2); // step 1
|
||||||
const Z2Z2 = Fp.square(Z2); // Z2Z2 = Z2^2;
|
let t1 = Fp.mul(Y1, Y2);
|
||||||
const U1 = Fp.multiply(X1, Z2Z2); // X1 * Z2Z2
|
let t2 = Fp.mul(Z1, Z2);
|
||||||
const U2 = Fp.multiply(X2, Z1Z1); // X2 * Z1Z1
|
let t3 = Fp.add(X1, Y1);
|
||||||
const S1 = Fp.multiply(Fp.multiply(Y1, Z2), Z2Z2); // Y1 * Z2 * Z2Z2
|
let t4 = Fp.add(X2, Y2); // step 5
|
||||||
const S2 = Fp.multiply(Fp.multiply(Y2, Z1), Z1Z1); // Y2 * Z1 * Z1Z1
|
t3 = Fp.mul(t3, t4);
|
||||||
const H = Fp.subtractN(U2, U1); // H = U2 - U1
|
t4 = Fp.add(t0, t1);
|
||||||
const r = Fp.subtractN(S2, S1); // S2 - S1
|
t3 = Fp.sub(t3, t4);
|
||||||
// H = 0 meaning it's the same point.
|
t4 = Fp.add(X1, Z1);
|
||||||
if (Fp.isZero(H)) return Fp.isZero(r) ? this.double() : JacobianPoint.ZERO;
|
let t5 = Fp.add(X2, Z2); // step 10
|
||||||
const HH = Fp.square(H); // HH = H2
|
t4 = Fp.mul(t4, t5);
|
||||||
const HHH = Fp.multiply(H, HH); // HHH = H * HH
|
t5 = Fp.add(t0, t2);
|
||||||
const V = Fp.multiply(U1, HH); // V = U1 * HH
|
t4 = Fp.sub(t4, t5);
|
||||||
const X3 = Fp.subtract(Fp.subtractN(Fp.squareN(r), HHH), Fp.multiplyN(V, _2n)); // X3 = r^2 - HHH - 2 * V;
|
t5 = Fp.add(Y1, Z1);
|
||||||
const Y3 = Fp.subtract(Fp.multiplyN(r, Fp.subtractN(V, X3)), Fp.multiplyN(S1, HHH)); // Y3 = r * (V - X3) - S1 * HHH;
|
X3 = Fp.add(Y2, Z2); // step 15
|
||||||
const Z3 = Fp.multiply(Fp.multiply(Z1, Z2), H); // Z3 = Z1 * Z2 * H;
|
t5 = Fp.mul(t5, X3);
|
||||||
return new JacobianPoint(X3, Y3, Z3);
|
X3 = Fp.add(t1, t2);
|
||||||
|
t5 = Fp.sub(t5, X3);
|
||||||
|
Z3 = Fp.mul(a, t4);
|
||||||
|
X3 = Fp.mul(b3, t2); // step 20
|
||||||
|
Z3 = Fp.add(X3, Z3);
|
||||||
|
X3 = Fp.sub(t1, Z3);
|
||||||
|
Z3 = Fp.add(t1, Z3);
|
||||||
|
Y3 = Fp.mul(X3, Z3);
|
||||||
|
t1 = Fp.add(t0, t0); // step 25
|
||||||
|
t1 = Fp.add(t1, t0);
|
||||||
|
t2 = Fp.mul(a, t2);
|
||||||
|
t4 = Fp.mul(b3, t4);
|
||||||
|
t1 = Fp.add(t1, t2);
|
||||||
|
t2 = Fp.sub(t0, t2); // step 30
|
||||||
|
t2 = Fp.mul(a, t2);
|
||||||
|
t4 = Fp.add(t4, t2);
|
||||||
|
t0 = Fp.mul(t1, t4);
|
||||||
|
Y3 = Fp.add(Y3, t0);
|
||||||
|
t0 = Fp.mul(t5, t4); // step 35
|
||||||
|
X3 = Fp.mul(t3, X3);
|
||||||
|
X3 = Fp.sub(X3, t0);
|
||||||
|
t0 = Fp.mul(t3, t1);
|
||||||
|
Z3 = Fp.mul(t5, Z3);
|
||||||
|
Z3 = Fp.add(Z3, t0); // step 40
|
||||||
|
return new ProjectivePoint(X3, Y3, Z3);
|
||||||
}
|
}
|
||||||
|
|
||||||
subtract(other: JacobianPoint) {
|
subtract(other: ProjectivePoint) {
|
||||||
return this.add(other.negate());
|
return this.add(other.negate());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -399,8 +430,8 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
|||||||
* It's faster, but should only be used when you don't care about
|
* It's faster, but should only be used when you don't care about
|
||||||
* an exposed private key e.g. sig verification, which works over *public* keys.
|
* an exposed private key e.g. sig verification, which works over *public* keys.
|
||||||
*/
|
*/
|
||||||
multiplyUnsafe(scalar: bigint): JacobianPoint {
|
multiplyUnsafe(scalar: bigint): ProjectivePoint {
|
||||||
const P0 = JacobianPoint.ZERO;
|
const P0 = ProjectivePoint.ZERO;
|
||||||
if (typeof scalar === 'bigint' && scalar === _0n) return P0;
|
if (typeof scalar === 'bigint' && scalar === _0n) return P0;
|
||||||
// Will throw on 0
|
// Will throw on 0
|
||||||
let n = normalizeScalar(scalar);
|
let n = normalizeScalar(scalar);
|
||||||
@@ -412,7 +443,7 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
|||||||
let { k1neg, k1, k2neg, k2 } = CURVE.endo.splitScalar(n);
|
let { k1neg, k1, k2neg, k2 } = CURVE.endo.splitScalar(n);
|
||||||
let k1p = P0;
|
let k1p = P0;
|
||||||
let k2p = P0;
|
let k2p = P0;
|
||||||
let d: JacobianPoint = this;
|
let d: ProjectivePoint = this;
|
||||||
while (k1 > _0n || k2 > _0n) {
|
while (k1 > _0n || k2 > _0n) {
|
||||||
if (k1 & _1n) k1p = k1p.add(d);
|
if (k1 & _1n) k1p = k1p.add(d);
|
||||||
if (k2 & _1n) k2p = k2p.add(d);
|
if (k2 & _1n) k2p = k2p.add(d);
|
||||||
@@ -422,22 +453,22 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
|||||||
}
|
}
|
||||||
if (k1neg) k1p = k1p.negate();
|
if (k1neg) k1p = k1p.negate();
|
||||||
if (k2neg) k2p = k2p.negate();
|
if (k2neg) k2p = k2p.negate();
|
||||||
k2p = new JacobianPoint(Fp.multiply(k2p.x, CURVE.endo.beta), k2p.y, k2p.z);
|
k2p = new ProjectivePoint(Fp.mul(k2p.x, CURVE.endo.beta), k2p.y, k2p.z);
|
||||||
return k1p.add(k2p);
|
return k1p.add(k2p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements w-ary non-adjacent form for calculating ec multiplication.
|
* Implements w-ary non-adjacent form for calculating ec multiplication.
|
||||||
*/
|
*/
|
||||||
private wNAF(n: bigint, affinePoint?: Point): { p: JacobianPoint; f: JacobianPoint } {
|
private wNAF(n: bigint, affinePoint?: Point): { p: ProjectivePoint; f: ProjectivePoint } {
|
||||||
if (!affinePoint && this.equals(JacobianPoint.BASE)) affinePoint = Point.BASE;
|
if (!affinePoint && this.equals(ProjectivePoint.BASE)) affinePoint = Point.BASE;
|
||||||
const W = (affinePoint && affinePoint._WINDOW_SIZE) || 1;
|
const W = (affinePoint && affinePoint._WINDOW_SIZE) || 1;
|
||||||
// Calculate precomputes on a first run, reuse them after
|
// Calculate precomputes on a first run, reuse them after
|
||||||
let precomputes = affinePoint && pointPrecomputes.get(affinePoint);
|
let precomputes = affinePoint && pointPrecomputes.get(affinePoint);
|
||||||
if (!precomputes) {
|
if (!precomputes) {
|
||||||
precomputes = wnaf.precomputeWindow(this, W) as JacobianPoint[];
|
precomputes = wnaf.precomputeWindow(this, W) as ProjectivePoint[];
|
||||||
if (affinePoint && W !== 1) {
|
if (affinePoint && W !== 1) {
|
||||||
precomputes = JacobianPoint.normalizeZ(precomputes);
|
precomputes = ProjectivePoint.normalizeZ(precomputes);
|
||||||
pointPrecomputes.set(affinePoint, precomputes);
|
pointPrecomputes.set(affinePoint, precomputes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -452,20 +483,20 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
|||||||
* @param affinePoint optional point ot save cached precompute windows on it
|
* @param affinePoint optional point ot save cached precompute windows on it
|
||||||
* @returns New point
|
* @returns New point
|
||||||
*/
|
*/
|
||||||
multiply(scalar: number | bigint, affinePoint?: Point): JacobianPoint {
|
multiply(scalar: number | bigint, affinePoint?: Point): ProjectivePoint {
|
||||||
let n = normalizeScalar(scalar);
|
let n = normalizeScalar(scalar);
|
||||||
|
|
||||||
// Real point.
|
// Real point.
|
||||||
let point: JacobianPoint;
|
let point: ProjectivePoint;
|
||||||
// Fake point, we use it to achieve constant-time multiplication.
|
// Fake point, we use it to achieve constant-time multiplication.
|
||||||
let fake: JacobianPoint;
|
let fake: ProjectivePoint;
|
||||||
if (CURVE.endo) {
|
if (CURVE.endo) {
|
||||||
const { k1neg, k1, k2neg, k2 } = CURVE.endo.splitScalar(n);
|
const { k1neg, k1, k2neg, k2 } = CURVE.endo.splitScalar(n);
|
||||||
let { p: k1p, f: f1p } = this.wNAF(k1, affinePoint);
|
let { p: k1p, f: f1p } = this.wNAF(k1, affinePoint);
|
||||||
let { p: k2p, f: f2p } = this.wNAF(k2, affinePoint);
|
let { p: k2p, f: f2p } = this.wNAF(k2, affinePoint);
|
||||||
k1p = wnaf.constTimeNegate(k1neg, k1p);
|
k1p = wnaf.constTimeNegate(k1neg, k1p);
|
||||||
k2p = wnaf.constTimeNegate(k2neg, k2p);
|
k2p = wnaf.constTimeNegate(k2neg, k2p);
|
||||||
k2p = new JacobianPoint(Fp.multiply(k2p.x, CURVE.endo.beta), k2p.y, k2p.z);
|
k2p = new ProjectivePoint(Fp.mul(k2p.x, CURVE.endo.beta), k2p.y, k2p.z);
|
||||||
point = k1p.add(k2p);
|
point = k1p.add(k2p);
|
||||||
fake = f1p.add(f2p);
|
fake = f1p.add(f2p);
|
||||||
} else {
|
} else {
|
||||||
@@ -474,46 +505,46 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
|||||||
fake = f;
|
fake = f;
|
||||||
}
|
}
|
||||||
// Normalize `z` for both points, but return only real one
|
// Normalize `z` for both points, but return only real one
|
||||||
return JacobianPoint.normalizeZ([point, fake])[0];
|
return ProjectivePoint.normalizeZ([point, fake])[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts Jacobian point to affine (x, y) coordinates.
|
// Converts Projective point to affine (x, y) coordinates.
|
||||||
// Can accept precomputed Z^-1 - for example, from invertBatch.
|
// Can accept precomputed Z^-1 - for example, from invertBatch.
|
||||||
// (x, y, z) ∋ (x=x/z², y=y/z³)
|
// (x, y, z) ∋ (x=x/z, y=y/z)
|
||||||
// https://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#scaling-z
|
|
||||||
toAffine(invZ?: T): Point {
|
toAffine(invZ?: T): Point {
|
||||||
const { x, y, z } = this;
|
const { x, y, z } = this;
|
||||||
const is0 = this.equals(JacobianPoint.ZERO);
|
const is0 = this.equals(ProjectivePoint.ZERO);
|
||||||
// If invZ was 0, we return zero point. However we still want to execute
|
// If invZ was 0, we return zero point. However we still want to execute
|
||||||
// all operations, so we replace invZ with a random number, 1.
|
// all operations, so we replace invZ with a random number, 1.
|
||||||
if (invZ == null) invZ = is0 ? Fp.ONE : Fp.invert(z);
|
if (invZ == null) invZ = is0 ? Fp.ONE : Fp.invert(z);
|
||||||
const iz1 = invZ;
|
const ax = Fp.mul(x, invZ);
|
||||||
const iz2 = Fp.square(iz1); // iz1 * iz1
|
const ay = Fp.mul(y, invZ);
|
||||||
const iz3 = Fp.multiply(iz2, iz1); // iz2 * iz1
|
const zz = Fp.mul(z, invZ);
|
||||||
const ax = Fp.multiply(x, iz2); // x * iz2
|
|
||||||
const ay = Fp.multiply(y, iz3); // y * iz3
|
|
||||||
const zz = Fp.multiply(z, iz1); // z * iz1
|
|
||||||
if (is0) return Point.ZERO;
|
if (is0) return Point.ZERO;
|
||||||
if (!Fp.equals(zz, Fp.ONE)) throw new Error('invZ was invalid');
|
if (!Fp.equals(zz, Fp.ONE)) throw new Error('invZ was invalid');
|
||||||
return new Point(ax, ay);
|
return new Point(ax, ay);
|
||||||
}
|
}
|
||||||
isTorsionFree(): boolean {
|
isTorsionFree(): boolean {
|
||||||
if (CURVE.h === _1n) return true; // No subgroups, always torsion fee
|
if (CURVE.h === _1n) return true; // No subgroups, always torsion fee
|
||||||
if (CURVE.isTorsionFree) return CURVE.isTorsionFree(JacobianPoint, this);
|
if (CURVE.isTorsionFree) return CURVE.isTorsionFree(ProjectivePoint, this);
|
||||||
// is multiplyUnsafe(CURVE.n) is always ok, same as for edwards?
|
// is multiplyUnsafe(CURVE.n) is always ok, same as for edwards?
|
||||||
throw new Error('Unsupported!');
|
throw new Error('Unsupported!');
|
||||||
}
|
}
|
||||||
// Clear cofactor of G1
|
// Clear cofactor of G1
|
||||||
// https://eprint.iacr.org/2019/403
|
// https://eprint.iacr.org/2019/403
|
||||||
clearCofactor(): JacobianPoint {
|
clearCofactor(): ProjectivePoint {
|
||||||
if (CURVE.h === _1n) return this; // Fast-path
|
if (CURVE.h === _1n) return this; // Fast-path
|
||||||
if (CURVE.clearCofactor) return CURVE.clearCofactor(JacobianPoint, this) as JacobianPoint;
|
if (CURVE.clearCofactor) return CURVE.clearCofactor(ProjectivePoint, this) as ProjectivePoint;
|
||||||
return this.multiplyUnsafe(CURVE.h);
|
return this.multiplyUnsafe(CURVE.h);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const wnaf = wNAF(JacobianPoint, CURVE.endo ? nBitLength / 2 : nBitLength);
|
const wnaf = wNAF(ProjectivePoint, CURVE.endo ? nBitLength / 2 : nBitLength);
|
||||||
|
|
||||||
|
function assertPrjPoint(other: unknown) {
|
||||||
|
if (!(other instanceof ProjectivePoint)) throw new TypeError('ProjectivePoint expected');
|
||||||
|
}
|
||||||
// Stores precomputed values for points.
|
// Stores precomputed values for points.
|
||||||
const pointPrecomputes = new WeakMap<Point, JacobianPoint[]>();
|
const pointPrecomputes = new WeakMap<Point, ProjectivePoint[]>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default Point works in default aka affine coordinates: (x, y)
|
* Default Point works in default aka affine coordinates: (x, y)
|
||||||
@@ -601,12 +632,12 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
|||||||
|
|
||||||
// Adds point to itself
|
// Adds point to itself
|
||||||
double() {
|
double() {
|
||||||
return JacobianPoint.fromAffine(this).double().toAffine();
|
return ProjectivePoint.fromAffine(this).double().toAffine();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds point to other point
|
// Adds point to other point
|
||||||
add(other: Point) {
|
add(other: Point) {
|
||||||
return JacobianPoint.fromAffine(this).add(JacobianPoint.fromAffine(other)).toAffine();
|
return ProjectivePoint.fromAffine(this).add(ProjectivePoint.fromAffine(other)).toAffine();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subtracts other point from the point
|
// Subtracts other point from the point
|
||||||
@@ -615,18 +646,18 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
multiply(scalar: number | bigint) {
|
multiply(scalar: number | bigint) {
|
||||||
return JacobianPoint.fromAffine(this).multiply(scalar, this).toAffine();
|
return ProjectivePoint.fromAffine(this).multiply(scalar, this).toAffine();
|
||||||
}
|
}
|
||||||
|
|
||||||
multiplyUnsafe(scalar: bigint) {
|
multiplyUnsafe(scalar: bigint) {
|
||||||
return JacobianPoint.fromAffine(this).multiplyUnsafe(scalar).toAffine();
|
return ProjectivePoint.fromAffine(this).multiplyUnsafe(scalar).toAffine();
|
||||||
}
|
}
|
||||||
clearCofactor() {
|
clearCofactor() {
|
||||||
return JacobianPoint.fromAffine(this).clearCofactor().toAffine();
|
return ProjectivePoint.fromAffine(this).clearCofactor().toAffine();
|
||||||
}
|
}
|
||||||
|
|
||||||
isTorsionFree(): boolean {
|
isTorsionFree(): boolean {
|
||||||
return JacobianPoint.fromAffine(this).isTorsionFree();
|
return ProjectivePoint.fromAffine(this).isTorsionFree();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -636,12 +667,12 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
|||||||
* @returns non-zero affine point
|
* @returns non-zero affine point
|
||||||
*/
|
*/
|
||||||
multiplyAndAddUnsafe(Q: Point, a: bigint, b: bigint): Point | undefined {
|
multiplyAndAddUnsafe(Q: Point, a: bigint, b: bigint): Point | undefined {
|
||||||
const P = JacobianPoint.fromAffine(this);
|
const P = ProjectivePoint.fromAffine(this);
|
||||||
const aP =
|
const aP =
|
||||||
a === _0n || a === _1n || this !== Point.BASE ? P.multiplyUnsafe(a) : P.multiply(a);
|
a === _0n || a === _1n || this !== Point.BASE ? P.multiplyUnsafe(a) : P.multiply(a);
|
||||||
const bQ = JacobianPoint.fromAffine(Q).multiplyUnsafe(b);
|
const bQ = ProjectivePoint.fromAffine(Q).multiplyUnsafe(b);
|
||||||
const sum = aP.add(bQ);
|
const sum = aP.add(bQ);
|
||||||
return sum.equals(JacobianPoint.ZERO) ? undefined : sum.toAffine();
|
return sum.equals(ProjectivePoint.ZERO) ? undefined : sum.toAffine();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encodes byte string to elliptic curve
|
// Encodes byte string to elliptic curve
|
||||||
@@ -666,7 +697,7 @@ export function weierstrassPoints<T>(opts: CurvePointsType<T>) {
|
|||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
Point: Point as PointConstructor<T>,
|
Point: Point as PointConstructor<T>,
|
||||||
JacobianPoint: JacobianPoint as JacobianConstructor<T>,
|
ProjectivePoint: ProjectivePoint as ProjectiveConstructor<T>,
|
||||||
normalizePrivateKey,
|
normalizePrivateKey,
|
||||||
weierstrassEquation,
|
weierstrassEquation,
|
||||||
isWithinCurveOrder,
|
isWithinCurveOrder,
|
||||||
@@ -732,7 +763,7 @@ export type CurveFn = {
|
|||||||
}
|
}
|
||||||
) => boolean;
|
) => boolean;
|
||||||
Point: PointConstructor<bigint>;
|
Point: PointConstructor<bigint>;
|
||||||
JacobianPoint: JacobianConstructor<bigint>;
|
ProjectivePoint: ProjectiveConstructor<bigint>;
|
||||||
Signature: SignatureConstructor;
|
Signature: SignatureConstructor;
|
||||||
utils: {
|
utils: {
|
||||||
mod: (a: bigint, b?: bigint) => bigint;
|
mod: (a: bigint, b?: bigint) => bigint;
|
||||||
@@ -812,7 +843,7 @@ export function weierstrass(curveDef: CurveType): CurveFn {
|
|||||||
return _0n < num && num < Fp.ORDER;
|
return _0n < num && num < Fp.ORDER;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { Point, JacobianPoint, normalizePrivateKey, weierstrassEquation, isWithinCurveOrder } =
|
const { Point, ProjectivePoint, normalizePrivateKey, weierstrassEquation, isWithinCurveOrder } =
|
||||||
weierstrassPoints({
|
weierstrassPoints({
|
||||||
...CURVE,
|
...CURVE,
|
||||||
toBytes(c, point, isCompressed: boolean): Uint8Array {
|
toBytes(c, point, isCompressed: boolean): Uint8Array {
|
||||||
@@ -1132,16 +1163,17 @@ export function weierstrass(curveDef: CurveType): CurveFn {
|
|||||||
* @returns Signature with its point on curve Q OR undefined if params were invalid
|
* @returns Signature with its point on curve Q OR undefined if params were invalid
|
||||||
*/
|
*/
|
||||||
function kmdToSig(kBytes: Uint8Array, m: bigint, d: bigint, lowS = true): Signature | undefined {
|
function kmdToSig(kBytes: Uint8Array, m: bigint, d: bigint, lowS = true): Signature | undefined {
|
||||||
|
const { n } = CURVE;
|
||||||
const k = truncateHash(kBytes, true);
|
const k = truncateHash(kBytes, true);
|
||||||
if (!isWithinCurveOrder(k)) return;
|
if (!isWithinCurveOrder(k)) return;
|
||||||
// Important: all mod() calls in the function must be done over `n`
|
// Important: all mod() calls in the function must be done over `n`
|
||||||
const { n } = CURVE;
|
const kinv = mod.invert(k, n);
|
||||||
const q = Point.BASE.multiply(k);
|
const q = Point.BASE.multiply(k);
|
||||||
// r = x mod n
|
// r = x mod n
|
||||||
const r = mod.mod(q.x, n);
|
const r = mod.mod(q.x, n);
|
||||||
if (r === _0n) return;
|
if (r === _0n) return;
|
||||||
// s = (1/k * (m + dr) mod n
|
// s = (1/k * (m + dr) mod n
|
||||||
const s = mod.mod(mod.invert(k, n) * mod.mod(m + d * r, n), n);
|
const s = mod.mod(kinv * mod.mod(m + mod.mod(d * r, n), n), n);
|
||||||
if (s === _0n) return;
|
if (s === _0n) return;
|
||||||
let recovery = (q.x === r ? 0 : 2) | Number(q.y & _1n);
|
let recovery = (q.x === r ? 0 : 2) | Number(q.y & _1n);
|
||||||
let normS = s;
|
let normS = s;
|
||||||
@@ -1221,7 +1253,7 @@ export function weierstrass(curveDef: CurveType): CurveFn {
|
|||||||
const u1 = mod.mod(h * sinv, n);
|
const u1 = mod.mod(h * sinv, n);
|
||||||
const u2 = mod.mod(r * sinv, n);
|
const u2 = mod.mod(r * sinv, n);
|
||||||
|
|
||||||
// Some implementations compare R.x in jacobian, without inversion.
|
// Some implementations compare R.x in projective, without inversion.
|
||||||
// The speed-up is <5%, so we don't complicate the code.
|
// The speed-up is <5%, so we don't complicate the code.
|
||||||
const R = Point.BASE.multiplyAndAddUnsafe(P, u1, u2);
|
const R = Point.BASE.multiplyAndAddUnsafe(P, u1, u2);
|
||||||
if (!R) return false;
|
if (!R) return false;
|
||||||
@@ -1235,8 +1267,124 @@ export function weierstrass(curveDef: CurveType): CurveFn {
|
|||||||
sign,
|
sign,
|
||||||
verify,
|
verify,
|
||||||
Point,
|
Point,
|
||||||
JacobianPoint,
|
ProjectivePoint,
|
||||||
Signature,
|
Signature,
|
||||||
utils,
|
utils,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Implementation of the Shallue and van de Woestijne method for any Weierstrass curve
|
||||||
|
|
||||||
|
// TODO: check if there is a way to merge this with uvRation in Edwards && move to modular?
|
||||||
|
// b = True and y = sqrt(u / v) if (u / v) is square in F, and
|
||||||
|
// b = False and y = sqrt(Z * (u / v)) otherwise.
|
||||||
|
export function SWUFpSqrtRatio<T>(Fp: mod.Field<T>, Z: T) {
|
||||||
|
// Generic implementation
|
||||||
|
const q = Fp.ORDER;
|
||||||
|
let l = 0n;
|
||||||
|
for (let o = q - 1n; o % 2n === 0n; o /= 2n) l += 1n;
|
||||||
|
const c1 = l; // 1. c1, the largest integer such that 2^c1 divides q - 1.
|
||||||
|
const c2 = (q - 1n) / 2n ** c1; // 2. c2 = (q - 1) / (2^c1) # Integer arithmetic
|
||||||
|
const c3 = (c2 - 1n) / 2n; // 3. c3 = (c2 - 1) / 2 # Integer arithmetic
|
||||||
|
const c4 = 2n ** c1 - 1n; // 4. c4 = 2^c1 - 1 # Integer arithmetic
|
||||||
|
const c5 = 2n ** (c1 - 1n); // 5. c5 = 2^(c1 - 1) # Integer arithmetic
|
||||||
|
const c6 = Fp.pow(Z, c2); // 6. c6 = Z^c2
|
||||||
|
const c7 = Fp.pow(Z, (c2 + 1n) / 2n); // 7. c7 = Z^((c2 + 1) / 2)
|
||||||
|
let sqrtRatio = (u: T, v: T): { isValid: boolean; value: T } => {
|
||||||
|
let tv1 = c6; // 1. tv1 = c6
|
||||||
|
let tv2 = Fp.pow(v, c4); // 2. tv2 = v^c4
|
||||||
|
let tv3 = Fp.square(tv2); // 3. tv3 = tv2^2
|
||||||
|
tv3 = Fp.mul(tv3, v); // 4. tv3 = tv3 * v
|
||||||
|
let tv5 = Fp.mul(u, tv3); // 5. tv5 = u * tv3
|
||||||
|
tv5 = Fp.pow(tv5, c3); // 6. tv5 = tv5^c3
|
||||||
|
tv5 = Fp.mul(tv5, tv2); // 7. tv5 = tv5 * tv2
|
||||||
|
tv2 = Fp.mul(tv5, v); // 8. tv2 = tv5 * v
|
||||||
|
tv3 = Fp.mul(tv5, u); // 9. tv3 = tv5 * u
|
||||||
|
let tv4 = Fp.mul(tv3, tv2); // 10. tv4 = tv3 * tv2
|
||||||
|
tv5 = Fp.pow(tv4, c5); // 11. tv5 = tv4^c5
|
||||||
|
let isQR = Fp.equals(tv5, Fp.ONE); // 12. isQR = tv5 == 1
|
||||||
|
tv2 = Fp.mul(tv3, c7); // 13. tv2 = tv3 * c7
|
||||||
|
tv5 = Fp.mul(tv4, tv1); // 14. tv5 = tv4 * tv1
|
||||||
|
tv3 = Fp.cmov(tv2, tv3, isQR); // 15. tv3 = CMOV(tv2, tv3, isQR)
|
||||||
|
tv4 = Fp.cmov(tv5, tv4, isQR); // 16. tv4 = CMOV(tv5, tv4, isQR)
|
||||||
|
// 17. for i in (c1, c1 - 1, ..., 2):
|
||||||
|
for (let i = c1; i > 1; i--) {
|
||||||
|
let tv5 = 2n ** (i - 2n); // 18. tv5 = i - 2; 19. tv5 = 2^tv5
|
||||||
|
let tvv5 = Fp.pow(tv4, tv5); // 20. tv5 = tv4^tv5
|
||||||
|
const e1 = Fp.equals(tvv5, Fp.ONE); // 21. e1 = tv5 == 1
|
||||||
|
tv2 = Fp.mul(tv3, tv1); // 22. tv2 = tv3 * tv1
|
||||||
|
tv1 = Fp.mul(tv1, tv1); // 23. tv1 = tv1 * tv1
|
||||||
|
tvv5 = Fp.mul(tv4, tv1); // 24. tv5 = tv4 * tv1
|
||||||
|
tv3 = Fp.cmov(tv2, tv3, e1); // 25. tv3 = CMOV(tv2, tv3, e1)
|
||||||
|
tv4 = Fp.cmov(tvv5, tv4, e1); // 26. tv4 = CMOV(tv5, tv4, e1)
|
||||||
|
}
|
||||||
|
return { isValid: isQR, value: tv3 };
|
||||||
|
};
|
||||||
|
if (Fp.ORDER % 4n === 3n) {
|
||||||
|
// sqrt_ratio_3mod4(u, v)
|
||||||
|
const c1 = (Fp.ORDER - 3n) / 4n; // 1. c1 = (q - 3) / 4 # Integer arithmetic
|
||||||
|
const c2 = Fp.sqrt(Fp.negate(Z)); // 2. c2 = sqrt(-Z)
|
||||||
|
sqrtRatio = (u: T, v: T) => {
|
||||||
|
let tv1 = Fp.square(v); // 1. tv1 = v^2
|
||||||
|
const tv2 = Fp.mul(u, v); // 2. tv2 = u * v
|
||||||
|
tv1 = Fp.mul(tv1, tv2); // 3. tv1 = tv1 * tv2
|
||||||
|
let y1 = Fp.pow(tv1, c1); // 4. y1 = tv1^c1
|
||||||
|
y1 = Fp.mul(y1, tv2); // 5. y1 = y1 * tv2
|
||||||
|
const y2 = Fp.mul(y1, c2); // 6. y2 = y1 * c2
|
||||||
|
const tv3 = Fp.mul(Fp.square(y1), v); // 7. tv3 = y1^2; 8. tv3 = tv3 * v
|
||||||
|
const isQR = Fp.equals(tv3, u); // 9. isQR = tv3 == u
|
||||||
|
let y = Fp.cmov(y2, y1, isQR); // 10. y = CMOV(y2, y1, isQR)
|
||||||
|
return { isValid: isQR, value: y }; // 11. return (isQR, y) isQR ? y : y*c2
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// No curves uses that
|
||||||
|
// if (Fp.ORDER % 8n === 5n) // sqrt_ratio_5mod8
|
||||||
|
return sqrtRatio;
|
||||||
|
}
|
||||||
|
// From draft-irtf-cfrg-hash-to-curve-16
|
||||||
|
export function mapToCurveSimpleSWU<T>(
|
||||||
|
Fp: mod.Field<T>,
|
||||||
|
opts: {
|
||||||
|
A: T;
|
||||||
|
B: T;
|
||||||
|
Z: T;
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
mod.validateField(Fp);
|
||||||
|
if (!Fp.isValid(opts.A) || !Fp.isValid(opts.B) || !Fp.isValid(opts.Z))
|
||||||
|
throw new Error('mapToCurveSimpleSWU: invalid opts');
|
||||||
|
const sqrtRatio = SWUFpSqrtRatio(Fp, opts.Z);
|
||||||
|
if (!Fp.isOdd) throw new Error('Fp.isOdd is not implemented!');
|
||||||
|
// Input: u, an element of F.
|
||||||
|
// Output: (x, y), a point on E.
|
||||||
|
return (u: T): { x: T; y: T } => {
|
||||||
|
// prettier-ignore
|
||||||
|
let tv1, tv2, tv3, tv4, tv5, tv6, x, y;
|
||||||
|
tv1 = Fp.square(u); // 1. tv1 = u^2
|
||||||
|
tv1 = Fp.mul(tv1, opts.Z); // 2. tv1 = Z * tv1
|
||||||
|
tv2 = Fp.square(tv1); // 3. tv2 = tv1^2
|
||||||
|
tv2 = Fp.add(tv2, tv1); // 4. tv2 = tv2 + tv1
|
||||||
|
tv3 = Fp.add(tv2, Fp.ONE); // 5. tv3 = tv2 + 1
|
||||||
|
tv3 = Fp.mul(tv3, opts.B); // 6. tv3 = B * tv3
|
||||||
|
tv4 = Fp.cmov(opts.Z, Fp.negate(tv2), !Fp.equals(tv2, Fp.ZERO)); // 7. tv4 = CMOV(Z, -tv2, tv2 != 0)
|
||||||
|
tv4 = Fp.mul(tv4, opts.A); // 8. tv4 = A * tv4
|
||||||
|
tv2 = Fp.square(tv3); // 9. tv2 = tv3^2
|
||||||
|
tv6 = Fp.square(tv4); // 10. tv6 = tv4^2
|
||||||
|
tv5 = Fp.mul(tv6, opts.A); // 11. tv5 = A * tv6
|
||||||
|
tv2 = Fp.add(tv2, tv5); // 12. tv2 = tv2 + tv5
|
||||||
|
tv2 = Fp.mul(tv2, tv3); // 13. tv2 = tv2 * tv3
|
||||||
|
tv6 = Fp.mul(tv6, tv4); // 14. tv6 = tv6 * tv4
|
||||||
|
tv5 = Fp.mul(tv6, opts.B); // 15. tv5 = B * tv6
|
||||||
|
tv2 = Fp.add(tv2, tv5); // 16. tv2 = tv2 + tv5
|
||||||
|
x = Fp.mul(tv1, tv3); // 17. x = tv1 * tv3
|
||||||
|
const { isValid, value } = sqrtRatio(tv2, tv6); // 18. (is_gx1_square, y1) = sqrt_ratio(tv2, tv6)
|
||||||
|
y = Fp.mul(tv1, u); // 19. y = tv1 * u -> Z * u^3 * y1
|
||||||
|
y = Fp.mul(y, value); // 20. y = y * y1
|
||||||
|
x = Fp.cmov(x, tv3, isValid); // 21. x = CMOV(x, tv3, is_gx1_square)
|
||||||
|
y = Fp.cmov(y, value, isValid); // 22. y = CMOV(y, y1, is_gx1_square)
|
||||||
|
const e1 = Fp.isOdd!(u) === Fp.isOdd!(y); // 23. e1 = sgn0(u) == sgn0(y)
|
||||||
|
y = Fp.cmov(Fp.negate(y), y, e1); // 24. y = CMOV(-y, y, e1)
|
||||||
|
x = Fp.div(x, tv4); // 25. x = x / tv4
|
||||||
|
return { x, y };
|
||||||
|
};
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,8 @@
|
|||||||
/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||||
import { weierstrass } from '@noble/curves/weierstrass';
|
import { weierstrass } from './abstract/weierstrass.js';
|
||||||
import { sha256 } from '@noble/hashes/sha256';
|
import { sha256 } from '@noble/hashes/sha256';
|
||||||
import { getHash } from './_shortw_utils.js';
|
import { getHash } from './_shortw_utils.js';
|
||||||
import { Fp } from '@noble/curves/modular';
|
import { Fp } from './abstract/modular.js';
|
||||||
/**
|
/**
|
||||||
* bn254 pairing-friendly curve.
|
* bn254 pairing-friendly curve.
|
||||||
* Previously known as alt_bn_128, when it had 128-bit security.
|
* Previously known as alt_bn_128, when it had 128-bit security.
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||||
import { sha512 } from '@noble/hashes/sha512';
|
import { sha512 } from '@noble/hashes/sha512';
|
||||||
import { concatBytes, randomBytes, utf8ToBytes } from '@noble/hashes/utils';
|
import { concatBytes, randomBytes, utf8ToBytes } from '@noble/hashes/utils';
|
||||||
import { twistedEdwards, ExtendedPointType } from '@noble/curves/edwards';
|
import { twistedEdwards, ExtendedPointType } from './abstract/edwards.js';
|
||||||
import { montgomery } from '@noble/curves/montgomery';
|
import { montgomery } from './abstract/montgomery.js';
|
||||||
import { mod, pow2, isNegativeLE, Fp as FpFn } from '@noble/curves/modular';
|
import { mod, pow2, isNegativeLE, Fp as Field, FpSqrtEven } from './abstract/modular.js';
|
||||||
import {
|
import {
|
||||||
ensureBytes,
|
ensureBytes,
|
||||||
equalBytes,
|
equalBytes,
|
||||||
@@ -11,7 +11,7 @@ import {
|
|||||||
bytesToNumberLE,
|
bytesToNumberLE,
|
||||||
numberToBytesLE,
|
numberToBytesLE,
|
||||||
Hex,
|
Hex,
|
||||||
} from '@noble/curves/utils';
|
} from './abstract/utils.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ed25519 Twisted Edwards curve with following addons:
|
* ed25519 Twisted Edwards curve with following addons:
|
||||||
@@ -91,6 +91,81 @@ export const ED25519_TORSION_SUBGROUP = [
|
|||||||
'c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa',
|
'c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const Fp = Field(ED25519_P, undefined, true);
|
||||||
|
|
||||||
|
// Hash To Curve Elligator2 Map (NOTE: different from ristretto255 elligator)
|
||||||
|
// NOTE: very important part is usage of FpSqrtEven for ELL2_C1_EDWARDS, since
|
||||||
|
// SageMath returns different root first and everything falls apart
|
||||||
|
|
||||||
|
const ELL2_C1 = (Fp.ORDER + BigInt(3)) / BigInt(8); // 1. c1 = (q + 3) / 8 # Integer arithmetic
|
||||||
|
|
||||||
|
const ELL2_C2 = Fp.pow(_2n, ELL2_C1); // 2. c2 = 2^c1
|
||||||
|
const ELL2_C3 = Fp.sqrt(Fp.negate(Fp.ONE)); // 3. c3 = sqrt(-1)
|
||||||
|
const ELL2_C4 = (Fp.ORDER - BigInt(5)) / BigInt(8); // 4. c4 = (q - 5) / 8 # Integer arithmetic
|
||||||
|
const ELL2_J = BigInt(486662);
|
||||||
|
|
||||||
|
// prettier-ignore
|
||||||
|
function map_to_curve_elligator2_curve25519(u: bigint) {
|
||||||
|
let tv1 = Fp.square(u); // 1. tv1 = u^2
|
||||||
|
tv1 = Fp.mul(tv1, _2n); // 2. tv1 = 2 * tv1
|
||||||
|
let xd = Fp.add(tv1, Fp.ONE); // 3. xd = tv1 + 1 # Nonzero: -1 is square (mod p), tv1 is not
|
||||||
|
let x1n = Fp.negate(ELL2_J); // 4. x1n = -J # x1 = x1n / xd = -J / (1 + 2 * u^2)
|
||||||
|
let tv2 = Fp.square(xd); // 5. tv2 = xd^2
|
||||||
|
let gxd = Fp.mul(tv2, xd); // 6. gxd = tv2 * xd # gxd = xd^3
|
||||||
|
let gx1 = Fp.mul(tv1, ELL2_J); // 7. gx1 = J * tv1 # x1n + J * xd
|
||||||
|
gx1 = Fp.mul(gx1, x1n); // 8. gx1 = gx1 * x1n # x1n^2 + J * x1n * xd
|
||||||
|
gx1 = Fp.add(gx1, tv2); // 9. gx1 = gx1 + tv2 # x1n^2 + J * x1n * xd + xd^2
|
||||||
|
gx1 = Fp.mul(gx1, x1n); // 10. gx1 = gx1 * x1n # x1n^3 + J * x1n^2 * xd + x1n * xd^2
|
||||||
|
let tv3 = Fp.square(gxd); // 11. tv3 = gxd^2
|
||||||
|
tv2 = Fp.square(tv3); // 12. tv2 = tv3^2 # gxd^4
|
||||||
|
tv3 = Fp.mul(tv3, gxd); // 13. tv3 = tv3 * gxd # gxd^3
|
||||||
|
tv3 = Fp.mul(tv3, gx1); // 14. tv3 = tv3 * gx1 # gx1 * gxd^3
|
||||||
|
tv2 = Fp.mul(tv2, tv3); // 15. tv2 = tv2 * tv3 # gx1 * gxd^7
|
||||||
|
let y11 = Fp.pow(tv2, ELL2_C4); // 16. y11 = tv2^c4 # (gx1 * gxd^7)^((p - 5) / 8)
|
||||||
|
y11 = Fp.mul(y11, tv3); // 17. y11 = y11 * tv3 # gx1*gxd^3*(gx1*gxd^7)^((p-5)/8)
|
||||||
|
let y12 = Fp.mul(y11, ELL2_C3); // 18. y12 = y11 * c3
|
||||||
|
tv2 = Fp.square(y11); // 19. tv2 = y11^2
|
||||||
|
tv2 = Fp.mul(tv2, gxd); // 20. tv2 = tv2 * gxd
|
||||||
|
let e1 = Fp.equals(tv2, gx1); // 21. e1 = tv2 == gx1
|
||||||
|
let y1 = Fp.cmov(y12, y11, e1); // 22. y1 = CMOV(y12, y11, e1) # If g(x1) is square, this is its sqrt
|
||||||
|
let x2n = Fp.mul(x1n, tv1); // 23. x2n = x1n * tv1 # x2 = x2n / xd = 2 * u^2 * x1n / xd
|
||||||
|
let y21 = Fp.mul(y11, u); // 24. y21 = y11 * u
|
||||||
|
y21 = Fp.mul(y21, ELL2_C2); // 25. y21 = y21 * c2
|
||||||
|
let y22 = Fp.mul(y21, ELL2_C3); // 26. y22 = y21 * c3
|
||||||
|
let gx2 = Fp.mul(gx1, tv1); // 27. gx2 = gx1 * tv1 # g(x2) = gx2 / gxd = 2 * u^2 * g(x1)
|
||||||
|
tv2 = Fp.square(y21); // 28. tv2 = y21^2
|
||||||
|
tv2 = Fp.mul(tv2, gxd); // 29. tv2 = tv2 * gxd
|
||||||
|
let e2 = Fp.equals(tv2, gx2); // 30. e2 = tv2 == gx2
|
||||||
|
let y2 = Fp.cmov(y22, y21, e2); // 31. y2 = CMOV(y22, y21, e2) # If g(x2) is square, this is its sqrt
|
||||||
|
tv2 = Fp.square(y1); // 32. tv2 = y1^2
|
||||||
|
tv2 = Fp.mul(tv2, gxd); // 33. tv2 = tv2 * gxd
|
||||||
|
let e3 = Fp.equals(tv2, gx1); // 34. e3 = tv2 == gx1
|
||||||
|
let xn = Fp.cmov(x2n, x1n, e3); // 35. xn = CMOV(x2n, x1n, e3) # If e3, x = x1, else x = x2
|
||||||
|
let y = Fp.cmov(y2, y1, e3); // 36. y = CMOV(y2, y1, e3) # If e3, y = y1, else y = y2
|
||||||
|
let e4 = Fp.isOdd(y); // 37. e4 = sgn0(y) == 1 # Fix sign of y
|
||||||
|
y = Fp.cmov(y, Fp.negate(y), e3 !== e4); // 38. y = CMOV(y, -y, e3 XOR e4)
|
||||||
|
return { xMn: xn, xMd: xd, yMn: y, yMd: 1n }; // 39. return (xn, xd, y, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
const ELL2_C1_EDWARDS = FpSqrtEven(Fp, Fp.negate(BigInt(486664))); // sgn0(c1) MUST equal 0
|
||||||
|
function map_to_curve_elligator2_edwards25519(u: bigint) {
|
||||||
|
const { xMn, xMd, yMn, yMd } = map_to_curve_elligator2_curve25519(u); // 1. (xMn, xMd, yMn, yMd) = map_to_curve_elligator2_curve25519(u)
|
||||||
|
let xn = Fp.mul(xMn, yMd); // 2. xn = xMn * yMd
|
||||||
|
xn = Fp.mul(xn, ELL2_C1_EDWARDS); // 3. xn = xn * c1
|
||||||
|
let xd = Fp.mul(xMd, yMn); // 4. xd = xMd * yMn # xn / xd = c1 * xM / yM
|
||||||
|
let yn = Fp.sub(xMn, xMd); // 5. yn = xMn - xMd
|
||||||
|
let yd = Fp.add(xMn, xMd); // 6. yd = xMn + xMd # (n / d - 1) / (n / d + 1) = (n - d) / (n + d)
|
||||||
|
let tv1 = Fp.mul(xd, yd); // 7. tv1 = xd * yd
|
||||||
|
let e = Fp.equals(tv1, Fp.ZERO); // 8. e = tv1 == 0
|
||||||
|
xn = Fp.cmov(xn, Fp.ZERO, e); // 9. xn = CMOV(xn, 0, e)
|
||||||
|
xd = Fp.cmov(xd, Fp.ONE, e); // 10. xd = CMOV(xd, 1, e)
|
||||||
|
yn = Fp.cmov(yn, Fp.ONE, e); // 11. yn = CMOV(yn, 1, e)
|
||||||
|
yd = Fp.cmov(yd, Fp.ONE, e); // 12. yd = CMOV(yd, 1, e)
|
||||||
|
|
||||||
|
const inv = Fp.invertBatch([xd, yd]); // batch division
|
||||||
|
return { x: Fp.mul(xn, inv[0]), y: Fp.mul(yn, inv[1]) }; // 13. return (xn, xd, yn, yd)
|
||||||
|
}
|
||||||
|
|
||||||
const ED25519_DEF = {
|
const ED25519_DEF = {
|
||||||
// Param: a
|
// Param: a
|
||||||
a: BigInt(-1),
|
a: BigInt(-1),
|
||||||
@@ -98,7 +173,7 @@ const ED25519_DEF = {
|
|||||||
// Negative number is P - number, and division is invert(number, P)
|
// Negative number is P - number, and division is invert(number, P)
|
||||||
d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),
|
d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),
|
||||||
// Finite field 𝔽p over which we'll do calculations; 2n ** 255n - 19n
|
// Finite field 𝔽p over which we'll do calculations; 2n ** 255n - 19n
|
||||||
Fp: FpFn(ED25519_P),
|
Fp,
|
||||||
// Subgroup order: how many points ed25519 has
|
// Subgroup order: how many points ed25519 has
|
||||||
// 2n ** 252n + 27742317777372353535851937790883648493n;
|
// 2n ** 252n + 27742317777372353535851937790883648493n;
|
||||||
n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
|
n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
|
||||||
@@ -114,6 +189,15 @@ const ED25519_DEF = {
|
|||||||
// Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.
|
// Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.
|
||||||
// Constant-time, u/√v
|
// Constant-time, u/√v
|
||||||
uvRatio,
|
uvRatio,
|
||||||
|
htfDefaults: {
|
||||||
|
DST: 'edwards25519_XMD:SHA-512_ELL2_RO_',
|
||||||
|
p: Fp.ORDER,
|
||||||
|
m: 1,
|
||||||
|
k: 128,
|
||||||
|
expand: 'xmd',
|
||||||
|
hash: sha512,
|
||||||
|
},
|
||||||
|
mapToCurve: (scalars: bigint[]) => map_to_curve_elligator2_edwards25519(scalars[0]),
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const ed25519 = twistedEdwards(ED25519_DEF);
|
export const ed25519 = twistedEdwards(ED25519_DEF);
|
||||||
@@ -180,6 +264,30 @@ const bytes255ToNumberLE = (bytes: Uint8Array) =>
|
|||||||
|
|
||||||
type ExtendedPoint = ExtendedPointType;
|
type ExtendedPoint = ExtendedPointType;
|
||||||
|
|
||||||
|
// Computes Elligator map for Ristretto
|
||||||
|
// https://ristretto.group/formulas/elligator.html
|
||||||
|
function calcElligatorRistrettoMap(r0: bigint): ExtendedPoint {
|
||||||
|
const { d } = ed25519.CURVE;
|
||||||
|
const P = ed25519.CURVE.Fp.ORDER;
|
||||||
|
const { mod } = ed25519.utils;
|
||||||
|
const r = mod(SQRT_M1 * r0 * r0); // 1
|
||||||
|
const Ns = mod((r + _1n) * ONE_MINUS_D_SQ); // 2
|
||||||
|
let c = BigInt(-1); // 3
|
||||||
|
const D = mod((c - d * r) * mod(r + d)); // 4
|
||||||
|
let { isValid: Ns_D_is_sq, value: s } = uvRatio(Ns, D); // 5
|
||||||
|
let s_ = mod(s * r0); // 6
|
||||||
|
if (!isNegativeLE(s_, P)) s_ = mod(-s_);
|
||||||
|
if (!Ns_D_is_sq) s = s_; // 7
|
||||||
|
if (!Ns_D_is_sq) c = r; // 8
|
||||||
|
const Nt = mod(c * (r - _1n) * D_MINUS_ONE_SQ - D); // 9
|
||||||
|
const s2 = s * s;
|
||||||
|
const W0 = mod((s + s) * D); // 10
|
||||||
|
const W1 = mod(Nt * SQRT_AD_MINUS_ONE); // 11
|
||||||
|
const W2 = mod(_1n - s2); // 12
|
||||||
|
const W3 = mod(_1n + s2); // 13
|
||||||
|
return new ed25519.ExtendedPoint(mod(W0 * W3), mod(W2 * W1), mod(W1 * W3), mod(W0 * W2));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Each ed25519/ExtendedPoint has 8 different equivalent points. This can be
|
* Each ed25519/ExtendedPoint has 8 different equivalent points. This can be
|
||||||
* a source of bugs for protocols like ring signatures. Ristretto was created to solve this.
|
* a source of bugs for protocols like ring signatures. Ristretto was created to solve this.
|
||||||
@@ -194,31 +302,6 @@ export class RistrettoPoint {
|
|||||||
// Private property to discourage combining ExtendedPoint + RistrettoPoint
|
// Private property to discourage combining ExtendedPoint + RistrettoPoint
|
||||||
// Always use Ristretto encoding/decoding instead.
|
// Always use Ristretto encoding/decoding instead.
|
||||||
constructor(private readonly ep: ExtendedPoint) {}
|
constructor(private readonly ep: ExtendedPoint) {}
|
||||||
|
|
||||||
// Computes Elligator map for Ristretto
|
|
||||||
// https://ristretto.group/formulas/elligator.html
|
|
||||||
private static calcElligatorRistrettoMap(r0: bigint): ExtendedPoint {
|
|
||||||
const { d } = ed25519.CURVE;
|
|
||||||
const P = ed25519.CURVE.Fp.ORDER;
|
|
||||||
const { mod } = ed25519.utils;
|
|
||||||
const r = mod(SQRT_M1 * r0 * r0); // 1
|
|
||||||
const Ns = mod((r + _1n) * ONE_MINUS_D_SQ); // 2
|
|
||||||
let c = BigInt(-1); // 3
|
|
||||||
const D = mod((c - d * r) * mod(r + d)); // 4
|
|
||||||
let { isValid: Ns_D_is_sq, value: s } = uvRatio(Ns, D); // 5
|
|
||||||
let s_ = mod(s * r0); // 6
|
|
||||||
if (!isNegativeLE(s_, P)) s_ = mod(-s_);
|
|
||||||
if (!Ns_D_is_sq) s = s_; // 7
|
|
||||||
if (!Ns_D_is_sq) c = r; // 8
|
|
||||||
const Nt = mod(c * (r - _1n) * D_MINUS_ONE_SQ - D); // 9
|
|
||||||
const s2 = s * s;
|
|
||||||
const W0 = mod((s + s) * D); // 10
|
|
||||||
const W1 = mod(Nt * SQRT_AD_MINUS_ONE); // 11
|
|
||||||
const W2 = mod(_1n - s2); // 12
|
|
||||||
const W3 = mod(_1n + s2); // 13
|
|
||||||
return new ed25519.ExtendedPoint(mod(W0 * W3), mod(W2 * W1), mod(W1 * W3), mod(W0 * W2));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes uniform output of 64-bit hash function like sha512 and converts it to `RistrettoPoint`.
|
* Takes uniform output of 64-bit hash function like sha512 and converts it to `RistrettoPoint`.
|
||||||
* The hash-to-group operation applies Elligator twice and adds the results.
|
* The hash-to-group operation applies Elligator twice and adds the results.
|
||||||
@@ -229,9 +312,9 @@ export class RistrettoPoint {
|
|||||||
static hashToCurve(hex: Hex): RistrettoPoint {
|
static hashToCurve(hex: Hex): RistrettoPoint {
|
||||||
hex = ensureBytes(hex, 64);
|
hex = ensureBytes(hex, 64);
|
||||||
const r1 = bytes255ToNumberLE(hex.slice(0, 32));
|
const r1 = bytes255ToNumberLE(hex.slice(0, 32));
|
||||||
const R1 = this.calcElligatorRistrettoMap(r1);
|
const R1 = calcElligatorRistrettoMap(r1);
|
||||||
const r2 = bytes255ToNumberLE(hex.slice(32, 64));
|
const r2 = bytes255ToNumberLE(hex.slice(32, 64));
|
||||||
const R2 = this.calcElligatorRistrettoMap(r2);
|
const R2 = calcElligatorRistrettoMap(r2);
|
||||||
return new RistrettoPoint(R1.add(R2));
|
return new RistrettoPoint(R1.add(R2));
|
||||||
}
|
}
|
||||||
|
|
||||||
233
src/ed448.ts
Normal file
233
src/ed448.ts
Normal file
@@ -0,0 +1,233 @@
|
|||||||
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||||
|
import { shake256 } from '@noble/hashes/sha3';
|
||||||
|
import { concatBytes, randomBytes, utf8ToBytes, wrapConstructor } from '@noble/hashes/utils';
|
||||||
|
import { twistedEdwards } from './abstract/edwards.js';
|
||||||
|
import { mod, pow2, Fp as Field } from './abstract/modular.js';
|
||||||
|
import { montgomery } from './abstract/montgomery.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Edwards448 (not Ed448-Goldilocks) curve with following addons:
|
||||||
|
* * X448 ECDH
|
||||||
|
* Conforms to RFC 8032 https://www.rfc-editor.org/rfc/rfc8032.html#section-5.2
|
||||||
|
*/
|
||||||
|
|
||||||
|
const shake256_114 = wrapConstructor(() => shake256.create({ dkLen: 114 }));
|
||||||
|
const shake256_64 = wrapConstructor(() => shake256.create({ dkLen: 64 }));
|
||||||
|
const ed448P = BigInt(
|
||||||
|
'726838724295606890549323807888004534353641360687318060281490199180612328166730772686396383698676545930088884461843637361053498018365439'
|
||||||
|
);
|
||||||
|
|
||||||
|
// powPminus3div4 calculates z = x^k mod p, where k = (p-3)/4.
|
||||||
|
// Used for efficient square root calculation.
|
||||||
|
// ((P-3)/4).toString(2) would produce bits [223x 1, 0, 222x 1]
|
||||||
|
function ed448_pow_Pminus3div4(x: bigint): bigint {
|
||||||
|
const P = ed448P;
|
||||||
|
// prettier-ignore
|
||||||
|
const _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3), _11n = BigInt(11);
|
||||||
|
// prettier-ignore
|
||||||
|
const _22n = BigInt(22), _44n = BigInt(44), _88n = BigInt(88), _223n = BigInt(223);
|
||||||
|
const b2 = (x * x * x) % P;
|
||||||
|
const b3 = (b2 * b2 * x) % P;
|
||||||
|
const b6 = (pow2(b3, _3n, P) * b3) % P;
|
||||||
|
const b9 = (pow2(b6, _3n, P) * b3) % P;
|
||||||
|
const b11 = (pow2(b9, _2n, P) * b2) % P;
|
||||||
|
const b22 = (pow2(b11, _11n, P) * b11) % P;
|
||||||
|
const b44 = (pow2(b22, _22n, P) * b22) % P;
|
||||||
|
const b88 = (pow2(b44, _44n, P) * b44) % P;
|
||||||
|
const b176 = (pow2(b88, _88n, P) * b88) % P;
|
||||||
|
const b220 = (pow2(b176, _44n, P) * b44) % P;
|
||||||
|
const b222 = (pow2(b220, _2n, P) * b2) % P;
|
||||||
|
const b223 = (pow2(b222, _1n, P) * x) % P;
|
||||||
|
return (pow2(b223, _223n, P) * b222) % P;
|
||||||
|
}
|
||||||
|
|
||||||
|
function adjustScalarBytes(bytes: Uint8Array): Uint8Array {
|
||||||
|
// Section 5: Likewise, for X448, set the two least significant bits of the first byte to 0, and the most
|
||||||
|
// significant bit of the last byte to 1.
|
||||||
|
bytes[0] &= 252; // 0b11111100
|
||||||
|
// and the most significant bit of the last byte to 1.
|
||||||
|
bytes[55] |= 128; // 0b10000000
|
||||||
|
// NOTE: is is NOOP for 56 bytes scalars (X25519/X448)
|
||||||
|
bytes[56] = 0; // Byte outside of group (456 buts vs 448 bits)
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Fp = Field(ed448P, 456, true);
|
||||||
|
|
||||||
|
// Hash To Curve Elligator2 Map
|
||||||
|
const ELL2_C1 = (Fp.ORDER - BigInt(3)) / BigInt(4); // 1. c1 = (q - 3) / 4 # Integer arithmetic
|
||||||
|
const ELL2_J = BigInt(156326);
|
||||||
|
function map_to_curve_elligator2_curve448(u: bigint) {
|
||||||
|
let tv1 = Fp.square(u); // 1. tv1 = u^2
|
||||||
|
let e1 = Fp.equals(tv1, Fp.ONE); // 2. e1 = tv1 == 1
|
||||||
|
tv1 = Fp.cmov(tv1, Fp.ZERO, e1); // 3. tv1 = CMOV(tv1, 0, e1) # If Z * u^2 == -1, set tv1 = 0
|
||||||
|
let xd = Fp.sub(Fp.ONE, tv1); // 4. xd = 1 - tv1
|
||||||
|
let x1n = Fp.negate(ELL2_J); // 5. x1n = -J
|
||||||
|
let tv2 = Fp.square(xd); // 6. tv2 = xd^2
|
||||||
|
let gxd = Fp.mul(tv2, xd); // 7. gxd = tv2 * xd # gxd = xd^3
|
||||||
|
let gx1 = Fp.mul(tv1, Fp.negate(ELL2_J)); // 8. gx1 = -J * tv1 # x1n + J * xd
|
||||||
|
gx1 = Fp.mul(gx1, x1n); // 9. gx1 = gx1 * x1n # x1n^2 + J * x1n * xd
|
||||||
|
gx1 = Fp.add(gx1, tv2); // 10. gx1 = gx1 + tv2 # x1n^2 + J * x1n * xd + xd^2
|
||||||
|
gx1 = Fp.mul(gx1, x1n); // 11. gx1 = gx1 * x1n # x1n^3 + J * x1n^2 * xd + x1n * xd^2
|
||||||
|
let tv3 = Fp.square(gxd); // 12. tv3 = gxd^2
|
||||||
|
tv2 = Fp.mul(gx1, gxd); // 13. tv2 = gx1 * gxd # gx1 * gxd
|
||||||
|
tv3 = Fp.mul(tv3, tv2); // 14. tv3 = tv3 * tv2 # gx1 * gxd^3
|
||||||
|
let y1 = Fp.pow(tv3, ELL2_C1); // 15. y1 = tv3^c1 # (gx1 * gxd^3)^((p - 3) / 4)
|
||||||
|
y1 = Fp.mul(y1, tv2); // 16. y1 = y1 * tv2 # gx1 * gxd * (gx1 * gxd^3)^((p - 3) / 4)
|
||||||
|
let x2n = Fp.mul(x1n, Fp.negate(tv1)); // 17. x2n = -tv1 * x1n # x2 = x2n / xd = -1 * u^2 * x1n / xd
|
||||||
|
let y2 = Fp.mul(y1, u); // 18. y2 = y1 * u
|
||||||
|
y2 = Fp.cmov(y2, Fp.ZERO, e1); // 19. y2 = CMOV(y2, 0, e1)
|
||||||
|
tv2 = Fp.square(y1); // 20. tv2 = y1^2
|
||||||
|
tv2 = Fp.mul(tv2, gxd); // 21. tv2 = tv2 * gxd
|
||||||
|
let e2 = Fp.equals(tv2, gx1); // 22. e2 = tv2 == gx1
|
||||||
|
let xn = Fp.cmov(x2n, x1n, e2); // 23. xn = CMOV(x2n, x1n, e2) # If e2, x = x1, else x = x2
|
||||||
|
let y = Fp.cmov(y2, y1, e2); // 24. y = CMOV(y2, y1, e2) # If e2, y = y1, else y = y2
|
||||||
|
let e3 = Fp.isOdd(y); // 25. e3 = sgn0(y) == 1 # Fix sign of y
|
||||||
|
y = Fp.cmov(y, Fp.negate(y), e2 !== e3); // 26. y = CMOV(y, -y, e2 XOR e3)
|
||||||
|
return { xn, xd, yn: y, yd: Fp.ONE }; // 27. return (xn, xd, y, 1)
|
||||||
|
}
|
||||||
|
function map_to_curve_elligator2_edwards448(u: bigint) {
|
||||||
|
let { xn, xd, yn, yd } = map_to_curve_elligator2_curve448(u); // 1. (xn, xd, yn, yd) = map_to_curve_elligator2_curve448(u)
|
||||||
|
let xn2 = Fp.square(xn); // 2. xn2 = xn^2
|
||||||
|
let xd2 = Fp.square(xd); // 3. xd2 = xd^2
|
||||||
|
let xd4 = Fp.square(xd2); // 4. xd4 = xd2^2
|
||||||
|
let yn2 = Fp.square(yn); // 5. yn2 = yn^2
|
||||||
|
let yd2 = Fp.square(yd); // 6. yd2 = yd^2
|
||||||
|
let xEn = Fp.sub(xn2, xd2); // 7. xEn = xn2 - xd2
|
||||||
|
let tv2 = Fp.sub(xEn, xd2); // 8. tv2 = xEn - xd2
|
||||||
|
xEn = Fp.mul(xEn, xd2); // 9. xEn = xEn * xd2
|
||||||
|
xEn = Fp.mul(xEn, yd); // 10. xEn = xEn * yd
|
||||||
|
xEn = Fp.mul(xEn, yn); // 11. xEn = xEn * yn
|
||||||
|
xEn = Fp.mul(xEn, 4n); // 12. xEn = xEn * 4
|
||||||
|
tv2 = Fp.mul(tv2, xn2); // 13. tv2 = tv2 * xn2
|
||||||
|
tv2 = Fp.mul(tv2, yd2); // 14. tv2 = tv2 * yd2
|
||||||
|
let tv3 = Fp.mul(yn2, 4n); // 15. tv3 = 4 * yn2
|
||||||
|
let tv1 = Fp.add(tv3, yd2); // 16. tv1 = tv3 + yd2
|
||||||
|
tv1 = Fp.mul(tv1, xd4); // 17. tv1 = tv1 * xd4
|
||||||
|
let xEd = Fp.add(tv1, tv2); // 18. xEd = tv1 + tv2
|
||||||
|
tv2 = Fp.mul(tv2, xn); // 19. tv2 = tv2 * xn
|
||||||
|
let tv4 = Fp.mul(xn, xd4); // 20. tv4 = xn * xd4
|
||||||
|
let yEn = Fp.sub(tv3, yd2); // 21. yEn = tv3 - yd2
|
||||||
|
yEn = Fp.mul(yEn, tv4); // 22. yEn = yEn * tv4
|
||||||
|
yEn = Fp.sub(yEn, tv2); // 23. yEn = yEn - tv2
|
||||||
|
tv1 = Fp.add(xn2, xd2); // 24. tv1 = xn2 + xd2
|
||||||
|
tv1 = Fp.mul(tv1, xd2); // 25. tv1 = tv1 * xd2
|
||||||
|
tv1 = Fp.mul(tv1, xd); // 26. tv1 = tv1 * xd
|
||||||
|
tv1 = Fp.mul(tv1, yn2); // 27. tv1 = tv1 * yn2
|
||||||
|
tv1 = Fp.mul(tv1, BigInt(-2)); // 28. tv1 = -2 * tv1
|
||||||
|
let yEd = Fp.add(tv2, tv1); // 29. yEd = tv2 + tv1
|
||||||
|
tv4 = Fp.mul(tv4, yd2); // 30. tv4 = tv4 * yd2
|
||||||
|
yEd = Fp.add(yEd, tv4); // 31. yEd = yEd + tv4
|
||||||
|
tv1 = Fp.mul(xEd, yEd); // 32. tv1 = xEd * yEd
|
||||||
|
let e = Fp.equals(tv1, Fp.ZERO); // 33. e = tv1 == 0
|
||||||
|
xEn = Fp.cmov(xEn, Fp.ZERO, e); // 34. xEn = CMOV(xEn, 0, e)
|
||||||
|
xEd = Fp.cmov(xEd, Fp.ONE, e); // 35. xEd = CMOV(xEd, 1, e)
|
||||||
|
yEn = Fp.cmov(yEn, Fp.ONE, e); // 36. yEn = CMOV(yEn, 1, e)
|
||||||
|
yEd = Fp.cmov(yEd, Fp.ONE, e); // 37. yEd = CMOV(yEd, 1, e)
|
||||||
|
|
||||||
|
const inv = Fp.invertBatch([xEd, yEd]); // batch division
|
||||||
|
return { x: Fp.mul(xEn, inv[0]), y: Fp.mul(yEn, inv[1]) }; // 38. return (xEn, xEd, yEn, yEd)
|
||||||
|
}
|
||||||
|
|
||||||
|
const ED448_DEF = {
|
||||||
|
// Param: a
|
||||||
|
a: BigInt(1),
|
||||||
|
// -39081. Negative number is P - number
|
||||||
|
d: BigInt(
|
||||||
|
'726838724295606890549323807888004534353641360687318060281490199180612328166730772686396383698676545930088884461843637361053498018326358'
|
||||||
|
),
|
||||||
|
// Finite field 𝔽p over which we'll do calculations; 2n ** 448n - 2n ** 224n - 1n
|
||||||
|
Fp,
|
||||||
|
// Subgroup order: how many points ed448 has; 2n**446n - 13818066809895115352007386748515426880336692474882178609894547503885n
|
||||||
|
n: BigInt(
|
||||||
|
'181709681073901722637330951972001133588410340171829515070372549795146003961539585716195755291692375963310293709091662304773755859649779'
|
||||||
|
),
|
||||||
|
nBitLength: 456,
|
||||||
|
// Cofactor
|
||||||
|
h: BigInt(4),
|
||||||
|
// Base point (x, y) aka generator point
|
||||||
|
Gx: BigInt(
|
||||||
|
'224580040295924300187604334099896036246789641632564134246125461686950415467406032909029192869357953282578032075146446173674602635247710'
|
||||||
|
),
|
||||||
|
Gy: BigInt(
|
||||||
|
'298819210078481492676017930443930673437544040154080242095928241372331506189835876003536878655418784733982303233503462500531545062832660'
|
||||||
|
),
|
||||||
|
// SHAKE256(dom4(phflag,context)||x, 114)
|
||||||
|
hash: shake256_114,
|
||||||
|
randomBytes,
|
||||||
|
adjustScalarBytes,
|
||||||
|
// dom4
|
||||||
|
domain: (data: Uint8Array, ctx: Uint8Array, phflag: boolean) => {
|
||||||
|
if (ctx.length > 255) throw new Error(`Context is too big: ${ctx.length}`);
|
||||||
|
return concatBytes(
|
||||||
|
utf8ToBytes('SigEd448'),
|
||||||
|
new Uint8Array([phflag ? 1 : 0, ctx.length]),
|
||||||
|
ctx,
|
||||||
|
data
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Constant-time ratio of u to v. Allows to combine inversion and square root u/√v.
|
||||||
|
// Uses algo from RFC8032 5.1.3.
|
||||||
|
uvRatio: (u: bigint, v: bigint): { isValid: boolean; value: bigint } => {
|
||||||
|
const P = ed448P;
|
||||||
|
// https://datatracker.ietf.org/doc/html/rfc8032#section-5.2.3
|
||||||
|
// To compute the square root of (u/v), the first step is to compute the
|
||||||
|
// candidate root x = (u/v)^((p+1)/4). This can be done using the
|
||||||
|
// following trick, to use a single modular powering for both the
|
||||||
|
// inversion of v and the square root:
|
||||||
|
// x = (u/v)^((p+1)/4) = u³v(u⁵v³)^((p-3)/4) (mod p)
|
||||||
|
const u2v = mod(u * u * v, P); // u²v
|
||||||
|
const u3v = mod(u2v * u, P); // u³v
|
||||||
|
const u5v3 = mod(u3v * u2v * v, P); // u⁵v³
|
||||||
|
const root = ed448_pow_Pminus3div4(u5v3);
|
||||||
|
const x = mod(u3v * root, P);
|
||||||
|
// Verify that root is exists
|
||||||
|
const x2 = mod(x * x, P); // x²
|
||||||
|
// If vx² = u, the recovered x-coordinate is x. Otherwise, no
|
||||||
|
// square root exists, and the decoding fails.
|
||||||
|
return { isValid: mod(x2 * v, P) === u, value: x };
|
||||||
|
},
|
||||||
|
htfDefaults: {
|
||||||
|
DST: 'edwards448_XOF:SHAKE256_ELL2_RO_',
|
||||||
|
p: Fp.ORDER,
|
||||||
|
m: 1,
|
||||||
|
k: 224,
|
||||||
|
expand: 'xof',
|
||||||
|
hash: shake256,
|
||||||
|
},
|
||||||
|
mapToCurve: (scalars: bigint[]) => map_to_curve_elligator2_edwards448(scalars[0]),
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export const ed448 = twistedEdwards(ED448_DEF);
|
||||||
|
// NOTE: there is no ed448ctx, since ed448 supports ctx by default
|
||||||
|
export const ed448ph = twistedEdwards({ ...ED448_DEF, preHash: shake256_64 });
|
||||||
|
|
||||||
|
export const x448 = montgomery({
|
||||||
|
a24: BigInt(39081),
|
||||||
|
montgomeryBits: 448,
|
||||||
|
nByteLength: 57,
|
||||||
|
P: ed448P,
|
||||||
|
Gu: '0500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
|
||||||
|
powPminus2: (x: bigint): bigint => {
|
||||||
|
const P = ed448P;
|
||||||
|
const Pminus3div4 = ed448_pow_Pminus3div4(x);
|
||||||
|
const Pminus3 = pow2(Pminus3div4, BigInt(2), P);
|
||||||
|
return mod(Pminus3 * x, P); // Pminus3 * x = Pminus2
|
||||||
|
},
|
||||||
|
adjustScalarBytes,
|
||||||
|
// The 4-isogeny maps between the Montgomery curve and this Edwards
|
||||||
|
// curve are:
|
||||||
|
// (u, v) = (y^2/x^2, (2 - x^2 - y^2)*y/x^3)
|
||||||
|
// (x, y) = (4*v*(u^2 - 1)/(u^4 - 2*u^2 + 4*v^2 + 1),
|
||||||
|
// -(u^5 - 2*u^3 - 4*u*v^2 + u)/
|
||||||
|
// (u^5 - 2*u^2*v^2 - 2*u^3 - 2*v^2 + u))
|
||||||
|
// xyToU: (p: PointType) => {
|
||||||
|
// const P = ed448P;
|
||||||
|
// const { x, y } = p;
|
||||||
|
// if (x === _0n) throw new Error(`Point with x=0 doesn't have mapping`);
|
||||||
|
// const invX = invert(x * x, P); // x^2
|
||||||
|
// const u = mod(y * y * invX, P); // (y^2/x^2)
|
||||||
|
// return numberToBytesLE(u, 56);
|
||||||
|
// },
|
||||||
|
});
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||||
import { sha256 } from '@noble/hashes/sha256';
|
import { sha256 } from '@noble/hashes/sha256';
|
||||||
import { concatBytes, randomBytes, utf8ToBytes } from '@noble/hashes/utils';
|
import { concatBytes, randomBytes, utf8ToBytes } from '@noble/hashes/utils';
|
||||||
import { twistedEdwards } from '@noble/curves/edwards';
|
import { twistedEdwards } from './abstract/edwards.js';
|
||||||
import { blake2s } from '@noble/hashes/blake2s';
|
import { blake2s } from '@noble/hashes/blake2s';
|
||||||
import { Fp } from '@noble/curves/modular';
|
import { Fp } from './abstract/modular.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* jubjub Twisted Edwards curve.
|
* jubjub Twisted Edwards curve.
|
||||||
301
src/modular.ts
301
src/modular.ts
@@ -1,301 +0,0 @@
|
|||||||
/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
||||||
import * as utils from './utils.js';
|
|
||||||
// Utilities for modular arithmetics
|
|
||||||
const _0n = BigInt(0);
|
|
||||||
const _1n = BigInt(1);
|
|
||||||
const _2n = BigInt(2);
|
|
||||||
|
|
||||||
// Calculates a modulo b
|
|
||||||
export function mod(a: bigint, b: bigint): bigint {
|
|
||||||
const result = a % b;
|
|
||||||
return result >= _0n ? result : b + result;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Efficiently exponentiate num to power and do modular division.
|
|
||||||
* Unsafe in some contexts: uses ladder, so can expose bigint bits.
|
|
||||||
* @example
|
|
||||||
* powMod(2n, 6n, 11n) // 64n % 11n == 9n
|
|
||||||
*/
|
|
||||||
// TODO: use field version && remove
|
|
||||||
export function pow(num: bigint, power: bigint, modulo: bigint): bigint {
|
|
||||||
if (modulo <= _0n || power < _0n) throw new Error('Expected power/modulo > 0');
|
|
||||||
if (modulo === _1n) return _0n;
|
|
||||||
let res = _1n;
|
|
||||||
while (power > _0n) {
|
|
||||||
if (power & _1n) res = (res * num) % modulo;
|
|
||||||
num = (num * num) % modulo;
|
|
||||||
power >>= _1n;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Does x ^ (2 ^ power) mod p. pow2(30, 4) == 30 ^ (2 ^ 4)
|
|
||||||
// TODO: Fp version?
|
|
||||||
export function pow2(x: bigint, power: bigint, modulo: bigint): bigint {
|
|
||||||
let res = x;
|
|
||||||
while (power-- > _0n) {
|
|
||||||
res *= res;
|
|
||||||
res %= modulo;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inverses number over modulo
|
|
||||||
export function invert(number: bigint, modulo: bigint): bigint {
|
|
||||||
if (number === _0n || modulo <= _0n) {
|
|
||||||
throw new Error(`invert: expected positive integers, got n=${number} mod=${modulo}`);
|
|
||||||
}
|
|
||||||
// Eucledian GCD https://brilliant.org/wiki/extended-euclidean-algorithm/
|
|
||||||
let a = mod(number, modulo);
|
|
||||||
let b = modulo;
|
|
||||||
// prettier-ignore
|
|
||||||
let x = _0n, y = _1n, u = _1n, v = _0n;
|
|
||||||
while (a !== _0n) {
|
|
||||||
const q = b / a;
|
|
||||||
const r = b % a;
|
|
||||||
const m = x - u * q;
|
|
||||||
const n = y - v * q;
|
|
||||||
// prettier-ignore
|
|
||||||
b = a, a = r, x = u, y = v, u = m, v = n;
|
|
||||||
}
|
|
||||||
const gcd = b;
|
|
||||||
if (gcd !== _1n) throw new Error('invert: does not exist');
|
|
||||||
return mod(x, modulo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates Legendre symbol (a | p), which denotes the value of a^((p-1)/2) (mod p).
|
|
||||||
* * (a | p) ≡ 1 if a is a square (mod p)
|
|
||||||
* * (a | p) ≡ -1 if a is not a square (mod p)
|
|
||||||
* * (a | p) ≡ 0 if a ≡ 0 (mod p)
|
|
||||||
*/
|
|
||||||
export function legendre(num: bigint, fieldPrime: bigint): bigint {
|
|
||||||
return pow(num, (fieldPrime - _1n) / _2n, fieldPrime);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates square root of a number in a finite field.
|
|
||||||
*/
|
|
||||||
// TODO: rewrite as generic Fp function && remove bls versions
|
|
||||||
export function sqrt(number: bigint, modulo: bigint): bigint {
|
|
||||||
// prettier-ignore
|
|
||||||
const _3n = BigInt(3), _4n = BigInt(4), _5n = BigInt(5), _8n = BigInt(8);
|
|
||||||
const n = number;
|
|
||||||
const P = modulo;
|
|
||||||
const p1div4 = (P + _1n) / _4n;
|
|
||||||
|
|
||||||
// P ≡ 3 (mod 4)
|
|
||||||
// sqrt n = n^((P+1)/4)
|
|
||||||
if (P % _4n === _3n) {
|
|
||||||
// Not all roots possible!
|
|
||||||
// const ORDER =
|
|
||||||
// 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaabn;
|
|
||||||
// const NUM = 72057594037927816n;
|
|
||||||
// TODO: fix sqrtMod in secp256k1
|
|
||||||
const root = pow(n, p1div4, P);
|
|
||||||
if (mod(root * root, modulo) !== number) throw new Error('Cannot find square root');
|
|
||||||
return root;
|
|
||||||
}
|
|
||||||
|
|
||||||
// P ≡ 5 (mod 8)
|
|
||||||
if (P % _8n === _5n) {
|
|
||||||
const n2 = mod(n * _2n, P);
|
|
||||||
const v = pow(n2, (P - _5n) / _8n, P);
|
|
||||||
const nv = mod(n * v, P);
|
|
||||||
const i = mod(_2n * nv * v, P);
|
|
||||||
const r = mod(nv * (i - _1n), P);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Other cases: Tonelli-Shanks algorithm
|
|
||||||
if (legendre(n, P) !== _1n) throw new Error('Cannot find square root');
|
|
||||||
let q: bigint, s: number, z: bigint;
|
|
||||||
for (q = P - _1n, s = 0; q % _2n === _0n; q /= _2n, s++);
|
|
||||||
if (s === 1) return pow(n, p1div4, P);
|
|
||||||
for (z = _2n; z < P && legendre(z, P) !== P - _1n; z++);
|
|
||||||
|
|
||||||
let c = pow(z, q, P);
|
|
||||||
let r = pow(n, (q + _1n) / _2n, P);
|
|
||||||
let t = pow(n, q, P);
|
|
||||||
|
|
||||||
let t2 = _0n;
|
|
||||||
while (mod(t - _1n, P) !== _0n) {
|
|
||||||
t2 = mod(t * t, P);
|
|
||||||
let i;
|
|
||||||
for (i = 1; i < s; i++) {
|
|
||||||
if (mod(t2 - _1n, P) === _0n) break;
|
|
||||||
t2 = mod(t2 * t2, P);
|
|
||||||
}
|
|
||||||
let b = pow(c, BigInt(1 << (s - i - 1)), P);
|
|
||||||
r = mod(r * b, P);
|
|
||||||
c = mod(b * b, P);
|
|
||||||
t = mod(t * c, P);
|
|
||||||
s = i;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Little-endian check for first LE bit (last BE bit);
|
|
||||||
export const isNegativeLE = (num: bigint, modulo: bigint) => (mod(num, modulo) & _1n) === _1n;
|
|
||||||
|
|
||||||
// Currently completly inconsistent naming:
|
|
||||||
// - readable: add, mul, sqr, sqrt, inv, div, pow, eq, sub
|
|
||||||
// - unreadable mess: addition, multiply, square, squareRoot, inversion, divide, power, equals, subtract
|
|
||||||
|
|
||||||
export interface Field<T> {
|
|
||||||
ORDER: bigint;
|
|
||||||
BYTES: number;
|
|
||||||
BITS: number;
|
|
||||||
MASK: bigint;
|
|
||||||
ZERO: T;
|
|
||||||
ONE: T;
|
|
||||||
// 1-arg
|
|
||||||
create: (num: T) => T;
|
|
||||||
isValid: (num: T) => boolean;
|
|
||||||
isZero: (num: T) => boolean;
|
|
||||||
negate(num: T): T;
|
|
||||||
invert(num: T): T;
|
|
||||||
sqrt(num: T): T;
|
|
||||||
square(num: T): T;
|
|
||||||
// 2-args
|
|
||||||
equals(lhs: T, rhs: T): boolean;
|
|
||||||
add(lhs: T, rhs: T): T;
|
|
||||||
subtract(lhs: T, rhs: T): T;
|
|
||||||
multiply(lhs: T, rhs: T | bigint): T;
|
|
||||||
pow(lhs: T, power: bigint): T;
|
|
||||||
div(lhs: T, rhs: T | bigint): T;
|
|
||||||
// N for NonNormalized (for now)
|
|
||||||
addN(lhs: T, rhs: T): T;
|
|
||||||
subtractN(lhs: T, rhs: T): T;
|
|
||||||
multiplyN(lhs: T, rhs: T | bigint): T;
|
|
||||||
squareN(num: T): T;
|
|
||||||
|
|
||||||
// Optional
|
|
||||||
isOdd?(num: T): boolean; // Odd instead of even since we have it for Fp2
|
|
||||||
legendre?(num: T): T;
|
|
||||||
pow(lhs: T, power: bigint): T;
|
|
||||||
invertBatch: (lst: T[]) => T[];
|
|
||||||
toBytes(num: T): Uint8Array;
|
|
||||||
fromBytes(bytes: Uint8Array): T;
|
|
||||||
}
|
|
||||||
// prettier-ignore
|
|
||||||
const FIELD_FIELDS = [
|
|
||||||
'create', 'isValid', 'isZero', 'negate', 'invert', 'sqrt', 'square',
|
|
||||||
'equals', 'add', 'subtract', 'multiply', 'pow', 'div',
|
|
||||||
'addN', 'subtractN', 'multiplyN', 'squareN'
|
|
||||||
] as const;
|
|
||||||
export function validateField<T>(field: Field<T>) {
|
|
||||||
for (const i of ['ORDER', 'MASK'] as const) {
|
|
||||||
if (typeof field[i] !== 'bigint')
|
|
||||||
throw new Error(`Invalid field param ${i}=${field[i]} (${typeof field[i]})`);
|
|
||||||
}
|
|
||||||
for (const i of ['BYTES', 'BITS'] as const) {
|
|
||||||
if (typeof field[i] !== 'number')
|
|
||||||
throw new Error(`Invalid field param ${i}=${field[i]} (${typeof field[i]})`);
|
|
||||||
}
|
|
||||||
for (const i of FIELD_FIELDS) {
|
|
||||||
if (typeof field[i] !== 'function')
|
|
||||||
throw new Error(`Invalid field param ${i}=${field[i]} (${typeof field[i]})`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generic field functions
|
|
||||||
export function FpPow<T>(f: Field<T>, num: T, power: bigint): T {
|
|
||||||
// Should have same speed as pow for bigints
|
|
||||||
// TODO: benchmark!
|
|
||||||
if (power < _0n) throw new Error('Expected power > 0');
|
|
||||||
if (power === _0n) return f.ONE;
|
|
||||||
if (power === _1n) return num;
|
|
||||||
let p = f.ONE;
|
|
||||||
let d = num;
|
|
||||||
while (power > _0n) {
|
|
||||||
if (power & _1n) p = f.multiply(p, d);
|
|
||||||
d = f.square(d);
|
|
||||||
power >>= 1n;
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function FpInvertBatch<T>(f: Field<T>, nums: T[]): T[] {
|
|
||||||
const tmp = new Array(nums.length);
|
|
||||||
// Walk from first to last, multiply them by each other MOD p
|
|
||||||
const lastMultiplied = nums.reduce((acc, num, i) => {
|
|
||||||
if (f.isZero(num)) return acc;
|
|
||||||
tmp[i] = acc;
|
|
||||||
return f.multiply(acc, num);
|
|
||||||
}, f.ONE);
|
|
||||||
// Invert last element
|
|
||||||
const inverted = f.invert(lastMultiplied);
|
|
||||||
// Walk from last to first, multiply them by inverted each other MOD p
|
|
||||||
nums.reduceRight((acc, num, i) => {
|
|
||||||
if (f.isZero(num)) return acc;
|
|
||||||
tmp[i] = f.multiply(acc, tmp[i]);
|
|
||||||
return f.multiply(acc, num);
|
|
||||||
}, inverted);
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function FpDiv<T>(f: Field<T>, lhs: T, rhs: T | bigint): T {
|
|
||||||
return f.multiply(lhs, typeof rhs === 'bigint' ? invert(rhs, f.ORDER) : f.invert(rhs));
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: very fragile, always bench. Major performance points:
|
|
||||||
// - NonNormalized ops
|
|
||||||
// - Object.freeze
|
|
||||||
// - same shape of object (don't add/remove keys)
|
|
||||||
export function Fp(
|
|
||||||
ORDER: bigint,
|
|
||||||
bitLen?: number,
|
|
||||||
isLE = false,
|
|
||||||
redef: Partial<Field<bigint>> = {}
|
|
||||||
): Readonly<Field<bigint>> {
|
|
||||||
if (ORDER <= _0n) throw new Error(`Expected Fp ORDER > 0, got ${ORDER}`);
|
|
||||||
const { nBitLength: BITS, nByteLength: BYTES } = utils.nLength(ORDER, bitLen);
|
|
||||||
if (BYTES > 2048) throw new Error('Field lengths over 2048 bytes are not supported');
|
|
||||||
const sqrtP = (num: bigint) => sqrt(num, ORDER);
|
|
||||||
const f: Field<bigint> = Object.freeze({
|
|
||||||
ORDER,
|
|
||||||
BITS,
|
|
||||||
BYTES,
|
|
||||||
MASK: utils.bitMask(BITS),
|
|
||||||
ZERO: _0n,
|
|
||||||
ONE: _1n,
|
|
||||||
create: (num) => mod(num, ORDER),
|
|
||||||
isValid: (num) => {
|
|
||||||
if (typeof num !== 'bigint')
|
|
||||||
throw new Error(`Invalid field element: expected bigint, got ${typeof num}`);
|
|
||||||
return _0n <= num && num < ORDER;
|
|
||||||
},
|
|
||||||
isZero: (num) => num === _0n,
|
|
||||||
isOdd: (num) => (num & _1n) === _1n,
|
|
||||||
negate: (num) => mod(-num, ORDER),
|
|
||||||
equals: (lhs, rhs) => lhs === rhs,
|
|
||||||
|
|
||||||
square: (num) => mod(num * num, ORDER),
|
|
||||||
add: (lhs, rhs) => mod(lhs + rhs, ORDER),
|
|
||||||
subtract: (lhs, rhs) => mod(lhs - rhs, ORDER),
|
|
||||||
multiply: (lhs, rhs) => mod(lhs * rhs, ORDER),
|
|
||||||
pow: (num, power) => FpPow(f, num, power),
|
|
||||||
div: (lhs, rhs) => mod(lhs * invert(rhs, ORDER), ORDER),
|
|
||||||
|
|
||||||
// Same as above, but doesn't normalize
|
|
||||||
squareN: (num) => num * num,
|
|
||||||
addN: (lhs, rhs) => lhs + rhs,
|
|
||||||
subtractN: (lhs, rhs) => lhs - rhs,
|
|
||||||
multiplyN: (lhs, rhs) => lhs * rhs,
|
|
||||||
|
|
||||||
invert: (num) => invert(num, ORDER),
|
|
||||||
sqrt: redef.sqrt || sqrtP,
|
|
||||||
invertBatch: (lst) => FpInvertBatch(f, lst),
|
|
||||||
|
|
||||||
toBytes: (num) =>
|
|
||||||
isLE ? utils.numberToBytesLE(num, BYTES) : utils.numberToBytesBE(num, BYTES),
|
|
||||||
|
|
||||||
fromBytes: (bytes) => {
|
|
||||||
if (bytes.length !== BYTES)
|
|
||||||
throw new Error(`Fp.fromBytes: expected ${BYTES}, got ${bytes.length}`);
|
|
||||||
return isLE ? utils.bytesToNumberLE(bytes) : utils.bytesToNumberBE(bytes);
|
|
||||||
},
|
|
||||||
} as Field<bigint>);
|
|
||||||
return Object.freeze(f);
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||||
import { createCurve } from './_shortw_utils.js';
|
import { createCurve } from './_shortw_utils.js';
|
||||||
import { sha256 } from '@noble/hashes/sha256';
|
import { sha256 } from '@noble/hashes/sha256';
|
||||||
import { Fp } from '@noble/curves/modular';
|
import { Fp } from './abstract/modular.js';
|
||||||
|
|
||||||
// NIST secp192r1 aka P192
|
// NIST secp192r1 aka P192
|
||||||
// https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/secg/secp192r1
|
// https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/secg/secp192r1
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||||
import { createCurve } from './_shortw_utils.js';
|
import { createCurve } from './_shortw_utils.js';
|
||||||
import { sha256 } from '@noble/hashes/sha256';
|
import { sha224 } from '@noble/hashes/sha256';
|
||||||
import { Fp } from '@noble/curves/modular';
|
import { Fp } from './abstract/modular.js';
|
||||||
|
|
||||||
// NIST secp224r1 aka P224
|
// NIST secp224r1 aka P224
|
||||||
// https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/nist/P-224
|
// https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/nist/P-224
|
||||||
@@ -20,6 +20,6 @@ export const P224 = createCurve(
|
|||||||
h: BigInt(1),
|
h: BigInt(1),
|
||||||
lowS: false,
|
lowS: false,
|
||||||
} as const,
|
} as const,
|
||||||
sha256 // TODO: replace with sha224 when new @noble/hashes released
|
sha224
|
||||||
);
|
);
|
||||||
export const secp224r1 = P224;
|
export const secp224r1 = P224;
|
||||||
46
src/p256.ts
Normal file
46
src/p256.ts
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||||
|
import { createCurve } from './_shortw_utils.js';
|
||||||
|
import { sha256 } from '@noble/hashes/sha256';
|
||||||
|
import { Fp as Field } from './abstract/modular.js';
|
||||||
|
import { mapToCurveSimpleSWU } from './abstract/weierstrass.js';
|
||||||
|
|
||||||
|
// NIST secp256r1 aka P256
|
||||||
|
// https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/nist/P-256
|
||||||
|
|
||||||
|
// Field over which we'll do calculations; 2n**224n * (2n**32n-1n) + 2n**192n + 2n**96n-1n
|
||||||
|
const Fp = Field(BigInt('0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff'));
|
||||||
|
const CURVE_A = Fp.create(BigInt('-3'));
|
||||||
|
const CURVE_B = BigInt('0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b');
|
||||||
|
|
||||||
|
const mapSWU = mapToCurveSimpleSWU(Fp, {
|
||||||
|
A: CURVE_A,
|
||||||
|
B: CURVE_B,
|
||||||
|
Z: Fp.create(BigInt('-10')),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const P256 = createCurve(
|
||||||
|
{
|
||||||
|
// Params: a, b
|
||||||
|
a: CURVE_A,
|
||||||
|
b: CURVE_B,
|
||||||
|
Fp,
|
||||||
|
// Curve order, total count of valid points in the field
|
||||||
|
n: BigInt('0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551'),
|
||||||
|
// Base point (x, y) aka generator point
|
||||||
|
Gx: BigInt('0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296'),
|
||||||
|
Gy: BigInt('0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5'),
|
||||||
|
h: BigInt(1),
|
||||||
|
lowS: false,
|
||||||
|
mapToCurve: (scalars: bigint[]) => mapSWU(scalars[0]),
|
||||||
|
htfDefaults: {
|
||||||
|
DST: 'P256_XMD:SHA-256_SSWU_RO_',
|
||||||
|
p: Fp.ORDER,
|
||||||
|
m: 1,
|
||||||
|
k: 128,
|
||||||
|
expand: 'xmd',
|
||||||
|
hash: sha256,
|
||||||
|
},
|
||||||
|
} as const,
|
||||||
|
sha256
|
||||||
|
);
|
||||||
|
export const secp256r1 = P256;
|
||||||
50
src/p384.ts
Normal file
50
src/p384.ts
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||||
|
import { createCurve } from './_shortw_utils.js';
|
||||||
|
import { sha384 } from '@noble/hashes/sha512';
|
||||||
|
import { Fp as Field } from './abstract/modular.js';
|
||||||
|
import { mapToCurveSimpleSWU } from './abstract/weierstrass.js';
|
||||||
|
|
||||||
|
// NIST secp384r1 aka P384
|
||||||
|
// https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/nist/P-384
|
||||||
|
|
||||||
|
// Field over which we'll do calculations. 2n**384n - 2n**128n - 2n**96n + 2n**32n - 1n
|
||||||
|
// prettier-ignore
|
||||||
|
const P = BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff');
|
||||||
|
const Fp = Field(P);
|
||||||
|
const CURVE_A = Fp.create(BigInt('-3'));
|
||||||
|
// prettier-ignore
|
||||||
|
const CURVE_B = BigInt('0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef');
|
||||||
|
|
||||||
|
const mapSWU = mapToCurveSimpleSWU(Fp, {
|
||||||
|
A: CURVE_A,
|
||||||
|
B: CURVE_B,
|
||||||
|
Z: Fp.create(BigInt('-12')),
|
||||||
|
});
|
||||||
|
|
||||||
|
// prettier-ignore
|
||||||
|
export const P384 = createCurve({
|
||||||
|
// Params: a, b
|
||||||
|
a: CURVE_A,
|
||||||
|
b: CURVE_B,
|
||||||
|
// Field over which we'll do calculations. 2n**384n - 2n**128n - 2n**96n + 2n**32n - 1n
|
||||||
|
Fp,
|
||||||
|
// Curve order, total count of valid points in the field.
|
||||||
|
n: BigInt('0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973'),
|
||||||
|
// Base point (x, y) aka generator point
|
||||||
|
Gx: BigInt('0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7'),
|
||||||
|
Gy: BigInt('0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f'),
|
||||||
|
h: BigInt(1),
|
||||||
|
lowS: false,
|
||||||
|
mapToCurve: (scalars: bigint[]) => mapSWU(scalars[0]),
|
||||||
|
htfDefaults: {
|
||||||
|
DST: 'P384_XMD:SHA-384_SSWU_RO_',
|
||||||
|
p: Fp.ORDER,
|
||||||
|
m: 1,
|
||||||
|
k: 192,
|
||||||
|
expand: 'xmd',
|
||||||
|
hash: sha384,
|
||||||
|
},
|
||||||
|
} as const,
|
||||||
|
sha384
|
||||||
|
);
|
||||||
|
export const secp384r1 = P384;
|
||||||
@@ -1,19 +1,35 @@
|
|||||||
/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||||
import { createCurve } from './_shortw_utils.js';
|
import { createCurve } from './_shortw_utils.js';
|
||||||
import { Fp } from '@noble/curves/modular';
|
|
||||||
import { sha512 } from '@noble/hashes/sha512';
|
import { sha512 } from '@noble/hashes/sha512';
|
||||||
import { bytesToHex, PrivKey } from '@noble/curves/utils';
|
import { bytesToHex, PrivKey } from './abstract/utils.js';
|
||||||
|
import { Fp as Field } from './abstract/modular.js';
|
||||||
|
import { mapToCurveSimpleSWU } from './abstract/weierstrass.js';
|
||||||
|
|
||||||
// NIST secp521r1 aka P521
|
// NIST secp521r1 aka P521
|
||||||
// Note that it's 521, which differs from 512 of its hash function.
|
// Note that it's 521, which differs from 512 of its hash function.
|
||||||
// https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/nist/P-521
|
// https://www.secg.org/sec2-v2.pdf, https://neuromancer.sk/std/nist/P-521
|
||||||
|
|
||||||
|
// Field over which we'll do calculations; 2n**521n - 1n
|
||||||
|
// prettier-ignore
|
||||||
|
const P = BigInt('0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff');
|
||||||
|
const Fp = Field(P);
|
||||||
|
|
||||||
|
const CURVE_A = Fp.create(BigInt('-3'));
|
||||||
|
// prettier-ignore
|
||||||
|
const CURVE_B = BigInt('0x0051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00');
|
||||||
|
|
||||||
|
const mapSWU = mapToCurveSimpleSWU(Fp, {
|
||||||
|
A: CURVE_A,
|
||||||
|
B: CURVE_B,
|
||||||
|
Z: Fp.create(BigInt('-4')),
|
||||||
|
});
|
||||||
|
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
export const P521 = createCurve({
|
export const P521 = createCurve({
|
||||||
// Params: a, b
|
// Params: a, b
|
||||||
a: BigInt('0x01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc'),
|
a: CURVE_A,
|
||||||
b: BigInt('0x0051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00'),
|
b: CURVE_B,
|
||||||
// Field over which we'll do calculations; 2n**521n - 1n
|
Fp,
|
||||||
Fp: Fp(BigInt('0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff')),
|
|
||||||
// Curve order, total count of valid points in the field
|
// Curve order, total count of valid points in the field
|
||||||
n: BigInt('0x01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409'),
|
n: BigInt('0x01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409'),
|
||||||
// Base point (x, y) aka generator point
|
// Base point (x, y) aka generator point
|
||||||
@@ -21,6 +37,9 @@ export const P521 = createCurve({
|
|||||||
Gy: BigInt('0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650'),
|
Gy: BigInt('0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650'),
|
||||||
h: BigInt(1),
|
h: BigInt(1),
|
||||||
lowS: false,
|
lowS: false,
|
||||||
|
// P521 keys could be 130, 131, 132 bytes - which doesn't play nicely.
|
||||||
|
// We ensure all keys are 132 bytes.
|
||||||
|
// Does not replace validation; invalid keys would still be rejected.
|
||||||
normalizePrivateKey(key: PrivKey) {
|
normalizePrivateKey(key: PrivKey) {
|
||||||
if (typeof key === 'bigint') return key;
|
if (typeof key === 'bigint') return key;
|
||||||
if (key instanceof Uint8Array) key = bytesToHex(key);
|
if (key instanceof Uint8Array) key = bytesToHex(key);
|
||||||
@@ -28,6 +47,15 @@ export const P521 = createCurve({
|
|||||||
throw new Error('Invalid key');
|
throw new Error('Invalid key');
|
||||||
}
|
}
|
||||||
return key.padStart(66 * 2, '0');
|
return key.padStart(66 * 2, '0');
|
||||||
}
|
},
|
||||||
|
mapToCurve: (scalars: bigint[]) => mapSWU(scalars[0]),
|
||||||
|
htfDefaults: {
|
||||||
|
DST: 'P521_XMD:SHA-512_SSWU_RO_',
|
||||||
|
p: Fp.ORDER,
|
||||||
|
m: 1,
|
||||||
|
k: 256,
|
||||||
|
expand: 'xmd',
|
||||||
|
hash: sha512,
|
||||||
|
},
|
||||||
} as const, sha512);
|
} as const, sha512);
|
||||||
export const secp521r1 = P521;
|
export const secp521r1 = P521;
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||||
import { sha256 } from '@noble/hashes/sha256';
|
import { sha256 } from '@noble/hashes/sha256';
|
||||||
import { weierstrass } from '@noble/curves/weierstrass';
|
import { weierstrass } from './abstract/weierstrass.js';
|
||||||
import { getHash } from './_shortw_utils.js';
|
import { getHash } from './_shortw_utils.js';
|
||||||
import * as mod from '@noble/curves/modular';
|
import * as mod from './abstract/modular.js';
|
||||||
|
|
||||||
const p = BigInt('0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001');
|
export const p = BigInt('0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001');
|
||||||
const q = BigInt('0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001');
|
export const q = BigInt('0x40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001');
|
||||||
|
|
||||||
// https://neuromancer.sk/std/other/Pallas
|
// https://neuromancer.sk/std/other/Pallas
|
||||||
export const pallas = weierstrass({
|
export const pallas = weierstrass({
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||||
import { sha256 } from '@noble/hashes/sha256';
|
import { sha256 } from '@noble/hashes/sha256';
|
||||||
import { Fp as FpFn, mod, pow2 } from '@noble/curves/modular';
|
import { Fp as Field, mod, pow2 } from './abstract/modular.js';
|
||||||
import { createCurve } from './_shortw_utils.js';
|
import { createCurve } from './_shortw_utils.js';
|
||||||
import { PointType } from '@noble/curves/weierstrass';
|
import { PointType, mapToCurveSimpleSWU } from './abstract/weierstrass.js';
|
||||||
import {
|
import {
|
||||||
ensureBytes,
|
ensureBytes,
|
||||||
concatBytes,
|
concatBytes,
|
||||||
@@ -10,15 +10,16 @@ import {
|
|||||||
hexToBytes,
|
hexToBytes,
|
||||||
bytesToNumberBE,
|
bytesToNumberBE,
|
||||||
PrivKey,
|
PrivKey,
|
||||||
} from '@noble/curves/utils';
|
} from './abstract/utils.js';
|
||||||
import { randomBytes } from '@noble/hashes/utils';
|
import { randomBytes } from '@noble/hashes/utils';
|
||||||
|
import { isogenyMap } from './abstract/hash-to-curve.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* secp256k1 belongs to Koblitz curves: it has
|
* secp256k1 belongs to Koblitz curves: it has
|
||||||
* efficiently computable Frobenius endomorphism.
|
* efficiently computable Frobenius endomorphism.
|
||||||
* Endomorphism improves efficiency:
|
* Endomorphism improves efficiency:
|
||||||
* Uses 2x less RAM, speeds up precomputation by 2x and ECDH / sign key recovery by 20%.
|
* Uses 2x less RAM, speeds up precomputation by 2x and ECDH / sign key recovery by 20%.
|
||||||
* Should always be used for Jacobian's double-and-add multiplication.
|
* Should always be used for Projective's double-and-add multiplication.
|
||||||
* For affines cached multiplication, it trades off 1/2 init time & 1/3 ram for 20% perf hit.
|
* For affines cached multiplication, it trades off 1/2 init time & 1/3 ram for 20% perf hit.
|
||||||
* https://gist.github.com/paulmillr/eb670806793e84df628a7c434a873066
|
* https://gist.github.com/paulmillr/eb670806793e84df628a7c434a873066
|
||||||
*/
|
*/
|
||||||
@@ -36,10 +37,11 @@ const divNearest = (a: bigint, b: bigint) => (a + b / _2n) / b;
|
|||||||
* We are unwrapping the loop and multiplying it bit-by-bit.
|
* We are unwrapping the loop and multiplying it bit-by-bit.
|
||||||
* (P+1n/4n).toString(2) would produce bits [223x 1, 0, 22x 1, 4x 0, 11, 00]
|
* (P+1n/4n).toString(2) would produce bits [223x 1, 0, 22x 1, 4x 0, 11, 00]
|
||||||
*/
|
*/
|
||||||
// prettier-ignore
|
|
||||||
function sqrtMod(y: bigint): bigint {
|
function sqrtMod(y: bigint): bigint {
|
||||||
const P = secp256k1P;
|
const P = secp256k1P;
|
||||||
const _3n = BigInt(3), _6n = BigInt(6), _11n = BigInt(11); const _22n = BigInt(22);
|
// prettier-ignore
|
||||||
|
const _3n = BigInt(3), _6n = BigInt(6), _11n = BigInt(11), _22n = BigInt(22);
|
||||||
|
// prettier-ignore
|
||||||
const _23n = BigInt(23), _44n = BigInt(44), _88n = BigInt(88);
|
const _23n = BigInt(23), _44n = BigInt(44), _88n = BigInt(88);
|
||||||
const b2 = (y * y * y) % P; // x^3, 11
|
const b2 = (y * y * y) % P; // x^3, 11
|
||||||
const b3 = (b2 * b2 * y) % P; // x^7
|
const b3 = (b2 * b2 * y) % P; // x^7
|
||||||
@@ -54,10 +56,52 @@ function sqrtMod(y: bigint): bigint {
|
|||||||
const b223 = (pow2(b220, _3n, P) * b3) % P;
|
const b223 = (pow2(b220, _3n, P) * b3) % P;
|
||||||
const t1 = (pow2(b223, _23n, P) * b22) % P;
|
const t1 = (pow2(b223, _23n, P) * b22) % P;
|
||||||
const t2 = (pow2(t1, _6n, P) * b2) % P;
|
const t2 = (pow2(t1, _6n, P) * b2) % P;
|
||||||
return pow2(t2, _2n, P);
|
const root = pow2(t2, _2n, P);
|
||||||
|
if (!Fp.equals(Fp.square(root), y)) throw new Error('Cannot find square root');
|
||||||
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Fp = FpFn(secp256k1P, undefined, undefined, { sqrt: sqrtMod });
|
const Fp = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });
|
||||||
|
type Fp = bigint;
|
||||||
|
|
||||||
|
const isoMap = isogenyMap(
|
||||||
|
Fp,
|
||||||
|
[
|
||||||
|
// xNum
|
||||||
|
[
|
||||||
|
'0x8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38daaaaa8c7',
|
||||||
|
'0x7d3d4c80bc321d5b9f315cea7fd44c5d595d2fc0bf63b92dfff1044f17c6581',
|
||||||
|
'0x534c328d23f234e6e2a413deca25caece4506144037c40314ecbd0b53d9dd262',
|
||||||
|
'0x8e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38e38daaaaa88c',
|
||||||
|
],
|
||||||
|
// xDen
|
||||||
|
[
|
||||||
|
'0xd35771193d94918a9ca34ccbb7b640dd86cd409542f8487d9fe6b745781eb49b',
|
||||||
|
'0xedadc6f64383dc1df7c4b2d51b54225406d36b641f5e41bbc52a56612a8c6d14',
|
||||||
|
'0x0000000000000000000000000000000000000000000000000000000000000001', // LAST 1
|
||||||
|
],
|
||||||
|
// yNum
|
||||||
|
[
|
||||||
|
'0x4bda12f684bda12f684bda12f684bda12f684bda12f684bda12f684b8e38e23c',
|
||||||
|
'0xc75e0c32d5cb7c0fa9d0a54b12a0a6d5647ab046d686da6fdffc90fc201d71a3',
|
||||||
|
'0x29a6194691f91a73715209ef6512e576722830a201be2018a765e85a9ecee931',
|
||||||
|
'0x2f684bda12f684bda12f684bda12f684bda12f684bda12f684bda12f38e38d84',
|
||||||
|
],
|
||||||
|
// yDen
|
||||||
|
[
|
||||||
|
'0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffff93b',
|
||||||
|
'0x7a06534bb8bdb49fd5e9e6632722c2989467c1bfc8e8d978dfb425d2685c2573',
|
||||||
|
'0x6484aa716545ca2cf3a70c3fa8fe337e0a3d21162f0d6299a7bf8192bfd2a76f',
|
||||||
|
'0x0000000000000000000000000000000000000000000000000000000000000001', // LAST 1
|
||||||
|
],
|
||||||
|
].map((i) => i.map((j) => BigInt(j))) as [Fp[], Fp[], Fp[], Fp[]]
|
||||||
|
);
|
||||||
|
|
||||||
|
const mapSWU = mapToCurveSimpleSWU(Fp, {
|
||||||
|
A: BigInt('0x3f8731abdd661adca08a5558f0f5d272e953d363cb6f0e5d405447c01a444533'),
|
||||||
|
B: BigInt('1771'),
|
||||||
|
Z: Fp.create(BigInt('-11')),
|
||||||
|
});
|
||||||
|
|
||||||
export const secp256k1 = createCurve(
|
export const secp256k1 = createCurve(
|
||||||
{
|
{
|
||||||
@@ -101,6 +145,18 @@ export const secp256k1 = createCurve(
|
|||||||
return { k1neg, k1, k2neg, k2 };
|
return { k1neg, k1, k2neg, k2 };
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
mapToCurve: (scalars: bigint[]) => {
|
||||||
|
const { x, y } = mapSWU(Fp.create(scalars[0]));
|
||||||
|
return isoMap(x, y);
|
||||||
|
},
|
||||||
|
htfDefaults: {
|
||||||
|
DST: 'secp256k1_XMD:SHA-256_SSWU_RO_',
|
||||||
|
p: Fp.ORDER,
|
||||||
|
m: 1,
|
||||||
|
k: 128,
|
||||||
|
expand: 'xmd',
|
||||||
|
hash: sha256,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
sha256
|
sha256
|
||||||
);
|
);
|
||||||
@@ -1,14 +1,12 @@
|
|||||||
/*! @noble/curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||||
import { keccak_256 } from '@noble/hashes/sha3';
|
import { keccak_256 } from '@noble/hashes/sha3';
|
||||||
import { sha256 } from '@noble/hashes/sha256';
|
import { sha256 } from '@noble/hashes/sha256';
|
||||||
import { hmac } from '@noble/hashes/hmac';
|
import { weierstrass, ProjectivePointType } from './abstract/weierstrass.js';
|
||||||
import { concatBytes, randomBytes } from '@noble/hashes/utils';
|
import * as cutils from './abstract/utils.js';
|
||||||
import { weierstrass, JacobianPointType } from '@noble/curves/weierstrass';
|
import { Fp } from './abstract/modular.js';
|
||||||
import * as cutils from '@noble/curves/utils';
|
|
||||||
import { Fp } from '@noble/curves/modular';
|
|
||||||
import { getHash } from './_shortw_utils.js';
|
import { getHash } from './_shortw_utils.js';
|
||||||
|
|
||||||
type JacobianPoint = JacobianPointType<bigint>;
|
type ProjectivePoint = ProjectivePointType<bigint>;
|
||||||
// Stark-friendly elliptic curve
|
// Stark-friendly elliptic curve
|
||||||
// https://docs.starkware.co/starkex/stark-curve.html
|
// https://docs.starkware.co/starkex/stark-curve.html
|
||||||
|
|
||||||
@@ -99,7 +97,7 @@ function getSharedSecret0x(privKeyA: Hex, pubKeyB: Hex) {
|
|||||||
return starkCurve.getSharedSecret(normalizePrivateKey(privKeyA), pubKeyB);
|
return starkCurve.getSharedSecret(normalizePrivateKey(privKeyA), pubKeyB);
|
||||||
}
|
}
|
||||||
|
|
||||||
function sign0x(msgHash: Hex, privKey: Hex, opts: any) {
|
function sign0x(msgHash: Hex, privKey: Hex, opts?: any) {
|
||||||
if (typeof privKey === 'string') privKey = strip0x(privKey).padStart(64, '0');
|
if (typeof privKey === 'string') privKey = strip0x(privKey).padStart(64, '0');
|
||||||
return starkCurve.sign(ensureBytes0x(msgHash), normalizePrivateKey(privKey), opts);
|
return starkCurve.sign(ensureBytes0x(msgHash), normalizePrivateKey(privKey), opts);
|
||||||
}
|
}
|
||||||
@@ -108,13 +106,13 @@ function verify0x(signature: Hex, msgHash: Hex, pubKey: Hex) {
|
|||||||
return starkCurve.verify(sig, ensureBytes0x(msgHash), ensureBytes0x(pubKey));
|
return starkCurve.verify(sig, ensureBytes0x(msgHash), ensureBytes0x(pubKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
const { CURVE, Point, JacobianPoint, Signature } = starkCurve;
|
const { CURVE, Point, ProjectivePoint, Signature } = starkCurve;
|
||||||
export const utils = starkCurve.utils;
|
export const utils = starkCurve.utils;
|
||||||
export {
|
export {
|
||||||
CURVE,
|
CURVE,
|
||||||
Point,
|
Point,
|
||||||
Signature,
|
Signature,
|
||||||
JacobianPoint,
|
ProjectivePoint,
|
||||||
getPublicKey0x as getPublicKey,
|
getPublicKey0x as getPublicKey,
|
||||||
getSharedSecret0x as getSharedSecret,
|
getSharedSecret0x as getSharedSecret,
|
||||||
sign0x as sign,
|
sign0x as sign,
|
||||||
@@ -173,7 +171,7 @@ export function getAccountPath(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// https://docs.starkware.co/starkex/pedersen-hash-function.html
|
// https://docs.starkware.co/starkex/pedersen-hash-function.html
|
||||||
const PEDERSEN_POINTS = [
|
const PEDERSEN_POINTS_AFFINE = [
|
||||||
new Point(
|
new Point(
|
||||||
2089986280348253421170679821480865132823066470938446095505822317253594081284n,
|
2089986280348253421170679821480865132823066470938446095505822317253594081284n,
|
||||||
1713931329540660377023406109199410414810705867260802078187082345529207694986n
|
1713931329540660377023406109199410414810705867260802078187082345529207694986n
|
||||||
@@ -196,15 +194,17 @@ const PEDERSEN_POINTS = [
|
|||||||
),
|
),
|
||||||
];
|
];
|
||||||
// for (const p of PEDERSEN_POINTS) p._setWindowSize(8);
|
// for (const p of PEDERSEN_POINTS) p._setWindowSize(8);
|
||||||
const PEDERSEN_POINTS_JACOBIAN = PEDERSEN_POINTS.map(JacobianPoint.fromAffine);
|
const PEDERSEN_POINTS = PEDERSEN_POINTS_AFFINE.map(ProjectivePoint.fromAffine);
|
||||||
|
|
||||||
function pedersenPrecompute(p1: JacobianPoint, p2: JacobianPoint): JacobianPoint[] {
|
function pedersenPrecompute(p1: ProjectivePoint, p2: ProjectivePoint): ProjectivePoint[] {
|
||||||
const out: JacobianPoint[] = [];
|
const out: ProjectivePoint[] = [];
|
||||||
let p = p1;
|
let p = p1;
|
||||||
for (let i = 0; i < 248; i++) {
|
for (let i = 0; i < 248; i++) {
|
||||||
out.push(p);
|
out.push(p);
|
||||||
p = p.double();
|
p = p.double();
|
||||||
}
|
}
|
||||||
|
// NOTE: we cannot use wNAF here, because last 4 bits will require full 248 bits multiplication
|
||||||
|
// We can add support for this to wNAF, but it will complicate wNAF.
|
||||||
p = p2;
|
p = p2;
|
||||||
for (let i = 0; i < 4; i++) {
|
for (let i = 0; i < 4; i++) {
|
||||||
out.push(p);
|
out.push(p);
|
||||||
@@ -212,14 +212,8 @@ function pedersenPrecompute(p1: JacobianPoint, p2: JacobianPoint): JacobianPoint
|
|||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
const PEDERSEN_POINTS1 = pedersenPrecompute(
|
const PEDERSEN_POINTS1 = pedersenPrecompute(PEDERSEN_POINTS[1], PEDERSEN_POINTS[2]);
|
||||||
PEDERSEN_POINTS_JACOBIAN[1],
|
const PEDERSEN_POINTS2 = pedersenPrecompute(PEDERSEN_POINTS[3], PEDERSEN_POINTS[4]);
|
||||||
PEDERSEN_POINTS_JACOBIAN[2]
|
|
||||||
);
|
|
||||||
const PEDERSEN_POINTS2 = pedersenPrecompute(
|
|
||||||
PEDERSEN_POINTS_JACOBIAN[3],
|
|
||||||
PEDERSEN_POINTS_JACOBIAN[4]
|
|
||||||
);
|
|
||||||
|
|
||||||
type PedersenArg = Hex | bigint | number;
|
type PedersenArg = Hex | bigint | number;
|
||||||
function pedersenArg(arg: PedersenArg): bigint {
|
function pedersenArg(arg: PedersenArg): bigint {
|
||||||
@@ -235,7 +229,7 @@ function pedersenArg(arg: PedersenArg): bigint {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function pedersenSingle(point: JacobianPoint, value: PedersenArg, constants: JacobianPoint[]) {
|
function pedersenSingle(point: ProjectivePoint, value: PedersenArg, constants: ProjectivePoint[]) {
|
||||||
let x = pedersenArg(value);
|
let x = pedersenArg(value);
|
||||||
for (let j = 0; j < 252; j++) {
|
for (let j = 0; j < 252; j++) {
|
||||||
const pt = constants[j];
|
const pt = constants[j];
|
||||||
@@ -248,7 +242,7 @@ function pedersenSingle(point: JacobianPoint, value: PedersenArg, constants: Jac
|
|||||||
|
|
||||||
// shift_point + x_low * P_0 + x_high * P1 + y_low * P2 + y_high * P3
|
// shift_point + x_low * P_0 + x_high * P1 + y_low * P2 + y_high * P3
|
||||||
export function pedersen(x: PedersenArg, y: PedersenArg) {
|
export function pedersen(x: PedersenArg, y: PedersenArg) {
|
||||||
let point: JacobianPoint = PEDERSEN_POINTS_JACOBIAN[0];
|
let point: ProjectivePoint = PEDERSEN_POINTS[0];
|
||||||
point = pedersenSingle(point, x, PEDERSEN_POINTS1);
|
point = pedersenSingle(point, x, PEDERSEN_POINTS1);
|
||||||
point = pedersenSingle(point, y, PEDERSEN_POINTS2);
|
point = pedersenSingle(point, y, PEDERSEN_POINTS2);
|
||||||
return bytesToHexEth(point.toAffine().toRawBytes(true).slice(1));
|
return bytesToHexEth(point.toAffine().toRawBytes(true).slice(1));
|
||||||
@@ -1,22 +1,266 @@
|
|||||||
import { deepStrictEqual, throws } from 'assert';
|
import { deepStrictEqual, throws } from 'assert';
|
||||||
import { should } from 'micro-should';
|
import { should } from 'micro-should';
|
||||||
import * as fc from 'fast-check';
|
import * as fc from 'fast-check';
|
||||||
import * as mod from '@noble/curves/modular';
|
import * as mod from '../lib/esm/abstract/modular.js';
|
||||||
import { randomBytes } from '@noble/hashes/utils';
|
|
||||||
// Generic tests for all curves in package
|
// Generic tests for all curves in package
|
||||||
import { secp192r1 } from '../lib/p192.js';
|
import { secp192r1 } from '../lib/esm/p192.js';
|
||||||
import { secp224r1 } from '../lib/p224.js';
|
import { secp224r1 } from '../lib/esm/p224.js';
|
||||||
import { secp256r1 } from '../lib/p256.js';
|
import { secp256r1 } from '../lib/esm/p256.js';
|
||||||
import { secp384r1 } from '../lib/p384.js';
|
import { secp384r1 } from '../lib/esm/p384.js';
|
||||||
import { secp521r1 } from '../lib/p521.js';
|
import { secp521r1 } from '../lib/esm/p521.js';
|
||||||
import { secp256k1 } from '../lib/secp256k1.js';
|
import { secp256k1 } from '../lib/esm/secp256k1.js';
|
||||||
import { ed25519, ed25519ctx, ed25519ph } from '../lib/ed25519.js';
|
import { ed25519, ed25519ctx, ed25519ph } from '../lib/esm/ed25519.js';
|
||||||
import { ed448, ed448ph } from '../lib/ed448.js';
|
import { ed448, ed448ph } from '../lib/esm/ed448.js';
|
||||||
import { starkCurve } from '../lib/stark.js';
|
import { starkCurve } from '../lib/esm/stark.js';
|
||||||
import { pallas, vesta } from '../lib/pasta.js';
|
import { pallas, vesta } from '../lib/esm/pasta.js';
|
||||||
import { bn254 } from '../lib/bn.js';
|
import { bn254 } from '../lib/esm/bn.js';
|
||||||
import { jubjub } from '../lib/jubjub.js';
|
import { jubjub } from '../lib/esm/jubjub.js';
|
||||||
|
import { bls12_381 } from '../lib/esm/bls12-381.js';
|
||||||
|
|
||||||
|
// Fields tests
|
||||||
|
const FIELDS = {
|
||||||
|
secp192r1: { Fp: [secp192r1.CURVE.Fp] },
|
||||||
|
secp224r1: { Fp: [secp224r1.CURVE.Fp] },
|
||||||
|
secp256r1: { Fp: [secp256r1.CURVE.Fp] },
|
||||||
|
secp521r1: { Fp: [secp521r1.CURVE.Fp] },
|
||||||
|
secp256k1: { Fp: [secp256k1.CURVE.Fp] },
|
||||||
|
stark: { Fp: [starkCurve.CURVE.Fp] },
|
||||||
|
jubjub: { Fp: [jubjub.CURVE.Fp] },
|
||||||
|
ed25519: { Fp: [ed25519.CURVE.Fp] },
|
||||||
|
ed448: { Fp: [ed448.CURVE.Fp] },
|
||||||
|
bn254: { Fp: [bn254.CURVE.Fp] },
|
||||||
|
pallas: { Fp: [pallas.CURVE.Fp] },
|
||||||
|
vesta: { Fp: [vesta.CURVE.Fp] },
|
||||||
|
bls12: {
|
||||||
|
Fp: [bls12_381.CURVE.Fp],
|
||||||
|
Fp2: [
|
||||||
|
bls12_381.CURVE.Fp2,
|
||||||
|
fc.array(fc.bigInt(1n, bls12_381.CURVE.Fp.ORDER - 1n), {
|
||||||
|
minLength: 2,
|
||||||
|
maxLength: 2,
|
||||||
|
}),
|
||||||
|
(Fp2, num) => Fp2.fromBigTuple([num[0], num[1]]),
|
||||||
|
],
|
||||||
|
// Fp6: [bls12_381.CURVE.Fp6],
|
||||||
|
Fp12: [
|
||||||
|
bls12_381.CURVE.Fp12,
|
||||||
|
fc.array(fc.bigInt(1n, bls12_381.CURVE.Fp.ORDER - 1n), {
|
||||||
|
minLength: 12,
|
||||||
|
maxLength: 12,
|
||||||
|
}),
|
||||||
|
(Fp12, num) => Fp12.fromBigTwelve(num),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const c in FIELDS) {
|
||||||
|
const curve = FIELDS[c];
|
||||||
|
for (const f in curve) {
|
||||||
|
const Fp = curve[f][0];
|
||||||
|
const name = `${c}/${f}:`;
|
||||||
|
const FC_BIGINT = curve[f][1] ? curve[f][1] : fc.bigInt(1n, Fp.ORDER - 1n);
|
||||||
|
|
||||||
|
const create = curve[f][2] ? curve[f][2].bind(null, Fp) : (num) => Fp.create(num);
|
||||||
|
should(`${name} equality`, () => {
|
||||||
|
fc.assert(
|
||||||
|
fc.property(FC_BIGINT, (num) => {
|
||||||
|
const a = create(num);
|
||||||
|
const b = create(num);
|
||||||
|
deepStrictEqual(Fp.equals(a, b), true);
|
||||||
|
deepStrictEqual(Fp.equals(b, a), true);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
should(`${name} non-equality`, () => {
|
||||||
|
fc.assert(
|
||||||
|
fc.property(FC_BIGINT, FC_BIGINT, (num1, num2) => {
|
||||||
|
const a = create(num1);
|
||||||
|
const b = create(num2);
|
||||||
|
deepStrictEqual(Fp.equals(a, b), num1 === num2);
|
||||||
|
deepStrictEqual(Fp.equals(b, a), num1 === num2);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
should(`${name} add/subtract/commutativity`, () => {
|
||||||
|
fc.assert(
|
||||||
|
fc.property(FC_BIGINT, FC_BIGINT, (num1, num2) => {
|
||||||
|
const a = create(num1);
|
||||||
|
const b = create(num2);
|
||||||
|
deepStrictEqual(Fp.add(a, b), Fp.add(b, a));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
should(`${name} add/subtract/associativity`, () => {
|
||||||
|
fc.assert(
|
||||||
|
fc.property(FC_BIGINT, FC_BIGINT, FC_BIGINT, (num1, num2, num3) => {
|
||||||
|
const a = create(num1);
|
||||||
|
const b = create(num2);
|
||||||
|
const c = create(num3);
|
||||||
|
deepStrictEqual(Fp.add(a, Fp.add(b, c)), Fp.add(Fp.add(a, b), c));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
should(`${name} add/subtract/x+0=x`, () => {
|
||||||
|
fc.assert(
|
||||||
|
fc.property(FC_BIGINT, (num) => {
|
||||||
|
const a = create(num);
|
||||||
|
deepStrictEqual(Fp.add(a, Fp.ZERO), a);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
should(`${name} add/subtract/x-0=x`, () => {
|
||||||
|
fc.assert(
|
||||||
|
fc.property(FC_BIGINT, (num) => {
|
||||||
|
const a = create(num);
|
||||||
|
deepStrictEqual(Fp.sub(a, Fp.ZERO), a);
|
||||||
|
deepStrictEqual(Fp.sub(a, a), Fp.ZERO);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
should(`${name} add/subtract/negate equality`, () => {
|
||||||
|
fc.assert(
|
||||||
|
fc.property(FC_BIGINT, (num1) => {
|
||||||
|
const a = create(num1);
|
||||||
|
const b = create(num1);
|
||||||
|
deepStrictEqual(Fp.sub(Fp.ZERO, a), Fp.negate(a));
|
||||||
|
deepStrictEqual(Fp.sub(a, b), Fp.add(a, Fp.negate(b)));
|
||||||
|
deepStrictEqual(Fp.sub(a, b), Fp.add(a, Fp.mul(b, Fp.create(-1n))));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
should(`${name} add/subtract/negate`, () => {
|
||||||
|
fc.assert(
|
||||||
|
fc.property(FC_BIGINT, (num) => {
|
||||||
|
const a = create(num);
|
||||||
|
deepStrictEqual(Fp.negate(a), Fp.sub(Fp.ZERO, a));
|
||||||
|
deepStrictEqual(Fp.negate(a), Fp.mul(a, Fp.create(-1n)));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
should(`${name} multiply/commutativity`, () => {
|
||||||
|
fc.assert(
|
||||||
|
fc.property(FC_BIGINT, FC_BIGINT, (num1, num2) => {
|
||||||
|
const a = create(num1);
|
||||||
|
const b = create(num2);
|
||||||
|
deepStrictEqual(Fp.mul(a, b), Fp.mul(b, a));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
should(`${name} multiply/associativity`, () => {
|
||||||
|
fc.assert(
|
||||||
|
fc.property(FC_BIGINT, FC_BIGINT, FC_BIGINT, (num1, num2, num3) => {
|
||||||
|
const a = create(num1);
|
||||||
|
const b = create(num2);
|
||||||
|
const c = create(num3);
|
||||||
|
deepStrictEqual(Fp.mul(a, Fp.mul(b, c)), Fp.mul(Fp.mul(a, b), c));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
should(`${name} multiply/distributivity`, () => {
|
||||||
|
fc.assert(
|
||||||
|
fc.property(FC_BIGINT, FC_BIGINT, FC_BIGINT, (num1, num2, num3) => {
|
||||||
|
const a = create(num1);
|
||||||
|
const b = create(num2);
|
||||||
|
const c = create(num3);
|
||||||
|
deepStrictEqual(Fp.mul(a, Fp.add(b, c)), Fp.add(Fp.mul(b, a), Fp.mul(c, a)));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
should(`${name} multiply/add equality`, () => {
|
||||||
|
fc.assert(
|
||||||
|
fc.property(FC_BIGINT, (num) => {
|
||||||
|
const a = create(num);
|
||||||
|
deepStrictEqual(Fp.mul(a, 0n), Fp.ZERO);
|
||||||
|
deepStrictEqual(Fp.mul(a, Fp.ZERO), Fp.ZERO);
|
||||||
|
deepStrictEqual(Fp.mul(a, 1n), a);
|
||||||
|
deepStrictEqual(Fp.mul(a, Fp.ONE), a);
|
||||||
|
deepStrictEqual(Fp.mul(a, 2n), Fp.add(a, a));
|
||||||
|
deepStrictEqual(Fp.mul(a, 3n), Fp.add(Fp.add(a, a), a));
|
||||||
|
deepStrictEqual(Fp.mul(a, 4n), Fp.add(Fp.add(Fp.add(a, a), a), a));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
should(`${name} multiply/square equality`, () => {
|
||||||
|
fc.assert(
|
||||||
|
fc.property(FC_BIGINT, (num) => {
|
||||||
|
const a = create(num);
|
||||||
|
deepStrictEqual(Fp.square(a), Fp.mul(a, a));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
should(`${name} multiply/pow equality`, () => {
|
||||||
|
fc.assert(
|
||||||
|
fc.property(FC_BIGINT, (num) => {
|
||||||
|
const a = create(num);
|
||||||
|
deepStrictEqual(Fp.pow(a, 0n), Fp.ONE);
|
||||||
|
deepStrictEqual(Fp.pow(a, 1n), a);
|
||||||
|
deepStrictEqual(Fp.pow(a, 2n), Fp.mul(a, a));
|
||||||
|
deepStrictEqual(Fp.pow(a, 3n), Fp.mul(Fp.mul(a, a), a));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
const isSquare = mod.FpIsSquare(Fp);
|
||||||
|
should(`${name} multiply/sqrt`, () => {
|
||||||
|
if (Fp === bls12_381.CURVE.Fp12) return; // Not implemented
|
||||||
|
fc.assert(
|
||||||
|
fc.property(FC_BIGINT, (num) => {
|
||||||
|
const a = create(num);
|
||||||
|
let root;
|
||||||
|
try {
|
||||||
|
root = Fp.sqrt(a);
|
||||||
|
} catch (e) {
|
||||||
|
deepStrictEqual(isSquare(a), false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
deepStrictEqual(isSquare(a), true);
|
||||||
|
deepStrictEqual(Fp.equals(Fp.square(root), a), true, 'sqrt(a)^2 == a');
|
||||||
|
deepStrictEqual(Fp.equals(Fp.square(Fp.negate(root)), a), true, '(-sqrt(a))^2 == a');
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
should(`${name} div/division by one equality`, () => {
|
||||||
|
fc.assert(
|
||||||
|
fc.property(FC_BIGINT, (num) => {
|
||||||
|
const a = create(num);
|
||||||
|
if (Fp.equals(a, Fp.ZERO)) return; // No division by zero
|
||||||
|
deepStrictEqual(Fp.div(a, Fp.ONE), a);
|
||||||
|
deepStrictEqual(Fp.div(a, a), Fp.ONE);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
should(`${name} zero division equality`, () => {
|
||||||
|
fc.assert(
|
||||||
|
fc.property(FC_BIGINT, (num) => {
|
||||||
|
const a = create(num);
|
||||||
|
deepStrictEqual(Fp.div(Fp.ZERO, a), Fp.ZERO);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
should(`${name} div/division distributivity`, () => {
|
||||||
|
fc.assert(
|
||||||
|
fc.property(FC_BIGINT, FC_BIGINT, FC_BIGINT, (num1, num2, num3) => {
|
||||||
|
const a = create(num1);
|
||||||
|
const b = create(num2);
|
||||||
|
const c = create(num3);
|
||||||
|
deepStrictEqual(Fp.div(Fp.add(a, b), c), Fp.add(Fp.div(a, c), Fp.div(b, c)));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
should(`${name} div/division and multiplication equality`, () => {
|
||||||
|
fc.assert(
|
||||||
|
fc.property(FC_BIGINT, FC_BIGINT, (num1, num2) => {
|
||||||
|
const a = create(num1);
|
||||||
|
const b = create(num2);
|
||||||
|
deepStrictEqual(Fp.div(a, b), Fp.mul(a, Fp.invert(b)));
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Group tests
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
const CURVES = {
|
const CURVES = {
|
||||||
secp192r1, secp224r1, secp256r1, secp384r1, secp521r1,
|
secp192r1, secp224r1, secp256r1, secp384r1, secp521r1,
|
||||||
@@ -30,6 +274,7 @@ const CURVES = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const NUM_RUNS = 5;
|
const NUM_RUNS = 5;
|
||||||
|
|
||||||
const getXY = (p) => ({ x: p.x, y: p.y });
|
const getXY = (p) => ({ x: p.x, y: p.y });
|
||||||
|
|
||||||
function equal(a, b, comment) {
|
function equal(a, b, comment) {
|
||||||
@@ -51,7 +296,7 @@ for (const name in CURVES) {
|
|||||||
const O = name === 'secp256k1' ? secp256r1 : secp256k1;
|
const O = name === 'secp256k1' ? secp256r1 : secp256k1;
|
||||||
const POINTS = {};
|
const POINTS = {};
|
||||||
const OTHER_POINTS = {};
|
const OTHER_POINTS = {};
|
||||||
for (const name of ['Point', 'JacobianPoint', 'ExtendedPoint', 'ProjectivePoint']) {
|
for (const name of ['Point', 'ProjectivePoint', 'ExtendedPoint', 'ProjectivePoint']) {
|
||||||
POINTS[name] = C[name];
|
POINTS[name] = C[name];
|
||||||
OTHER_POINTS[name] = O[name];
|
OTHER_POINTS[name] = O[name];
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { bls12_381 } from '../lib/bls12-381.js';
|
import { bls12_381 } from '../lib/esm/bls12-381.js';
|
||||||
import { should } from 'micro-should';
|
import { should } from 'micro-should';
|
||||||
import { deepStrictEqual, notDeepStrictEqual, throws } from 'assert';
|
import { deepStrictEqual, notDeepStrictEqual, throws } from 'assert';
|
||||||
import { sha512 } from '@noble/hashes/sha512';
|
import { sha512 } from '@noble/hashes/sha512';
|
||||||
@@ -6,7 +6,7 @@ import * as fc from 'fast-check';
|
|||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
import zkVectors from './bls12-381/zkcrypto/converted.json' assert { type: 'json' };
|
import zkVectors from './bls12-381/zkcrypto/converted.json' assert { type: 'json' };
|
||||||
import pairingVectors from './bls12-381/go_pairing_vectors/pairing.json' assert { type: 'json' };
|
import pairingVectors from './bls12-381/go_pairing_vectors/pairing.json' assert { type: 'json' };
|
||||||
import { wNAF } from '@noble/curves/group';
|
import { wNAF } from '../lib/esm/abstract/group.js';
|
||||||
const bls = bls12_381;
|
const bls = bls12_381;
|
||||||
const { Fp2 } = bls;
|
const { Fp2 } = bls;
|
||||||
|
|
||||||
@@ -41,145 +41,7 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
|||||||
{
|
{
|
||||||
const Fp = bls.Fp;
|
const Fp = bls.Fp;
|
||||||
const FC_BIGINT = fc.bigInt(1n, Fp.ORDER - 1n);
|
const FC_BIGINT = fc.bigInt(1n, Fp.ORDER - 1n);
|
||||||
should('bls12-381/Fp/equality', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT, (num) => {
|
|
||||||
const a = Fp.create(num);
|
|
||||||
const b = Fp.create(num);
|
|
||||||
deepStrictEqual(Fp.equals(a, b), true);
|
|
||||||
deepStrictEqual(Fp.equals(b, a), true);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381/Fp/non-equality', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT, FC_BIGINT, (num1, num2) => {
|
|
||||||
const a = Fp.create(num1);
|
|
||||||
const b = Fp.create(num2);
|
|
||||||
deepStrictEqual(Fp.equals(a, b), num1 === num2);
|
|
||||||
deepStrictEqual(Fp.equals(b, a), num1 === num2);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381/Fp/add/subtract/commutativity', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT, FC_BIGINT, (num1, num2) => {
|
|
||||||
const a = Fp.create(num1);
|
|
||||||
const b = Fp.create(num2);
|
|
||||||
deepStrictEqual(Fp.add(a, b), Fp.add(b, a));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381/Fp/add/subtract/associativity', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT, FC_BIGINT, FC_BIGINT, (num1, num2, num3) => {
|
|
||||||
const a = Fp.create(num1);
|
|
||||||
const b = Fp.create(num2);
|
|
||||||
const c = Fp.create(num3);
|
|
||||||
deepStrictEqual(Fp.add(a, Fp.add(b, c)), Fp.add(Fp.add(a, b), c));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381/Fp/add/subtract/x+0=x', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT, (num) => {
|
|
||||||
const a = Fp.create(num);
|
|
||||||
deepStrictEqual(Fp.add(a, Fp.ZERO), a);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381/Fp/add/subtract/x-0=x', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT, (num) => {
|
|
||||||
const a = Fp.create(num);
|
|
||||||
deepStrictEqual(Fp.subtract(a, Fp.ZERO), a);
|
|
||||||
deepStrictEqual(Fp.subtract(a, a), Fp.ZERO);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381/Fp/add/subtract/negate equality', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT, (num1) => {
|
|
||||||
const a = Fp.create(num1);
|
|
||||||
const b = Fp.create(num1);
|
|
||||||
deepStrictEqual(Fp.subtract(Fp.ZERO, a), Fp.negate(a));
|
|
||||||
deepStrictEqual(Fp.subtract(a, b), Fp.add(a, Fp.negate(b)));
|
|
||||||
deepStrictEqual(Fp.subtract(a, b), Fp.add(a, Fp.multiply(b, Fp.create(-1n))));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381/Fp/add/subtract/negate', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT, (num) => {
|
|
||||||
const a = Fp.create(num);
|
|
||||||
deepStrictEqual(Fp.negate(a), Fp.subtract(Fp.ZERO, a));
|
|
||||||
deepStrictEqual(Fp.negate(a), Fp.multiply(a, Fp.create(-1n)));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
should('bls12-381/Fp/multiply/commutativity', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT, FC_BIGINT, (num1, num2) => {
|
|
||||||
const a = Fp.create(num1);
|
|
||||||
const b = Fp.create(num2);
|
|
||||||
deepStrictEqual(Fp.multiply(a, b), Fp.multiply(b, a));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381/Fp/multiply/associativity', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT, FC_BIGINT, FC_BIGINT, (num1, num2, num3) => {
|
|
||||||
const a = Fp.create(num1);
|
|
||||||
const b = Fp.create(num2);
|
|
||||||
const c = Fp.create(num3);
|
|
||||||
deepStrictEqual(Fp.multiply(a, Fp.multiply(b, c)), Fp.multiply(Fp.multiply(a, b), c));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381/Fp/multiply/distributivity', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT, FC_BIGINT, FC_BIGINT, (num1, num2, num3) => {
|
|
||||||
const a = Fp.create(num1);
|
|
||||||
const b = Fp.create(num2);
|
|
||||||
const c = Fp.create(num3);
|
|
||||||
deepStrictEqual(Fp.multiply(a, Fp.add(b, c)), Fp.add(Fp.multiply(b, a), Fp.multiply(c, a)));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381/Fp/multiply/add equality', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT, (num) => {
|
|
||||||
const a = Fp.create(num);
|
|
||||||
deepStrictEqual(Fp.multiply(a, Fp.create(0n)), Fp.ZERO);
|
|
||||||
deepStrictEqual(Fp.multiply(a, Fp.ZERO), Fp.ZERO);
|
|
||||||
deepStrictEqual(Fp.multiply(a, Fp.create(1n)), a);
|
|
||||||
deepStrictEqual(Fp.multiply(a, Fp.ONE), a);
|
|
||||||
deepStrictEqual(Fp.multiply(a, Fp.create(2n)), Fp.add(a, a));
|
|
||||||
deepStrictEqual(Fp.multiply(a, Fp.create(3n)), Fp.add(Fp.add(a, a), a));
|
|
||||||
deepStrictEqual(Fp.multiply(a, Fp.create(4n)), Fp.add(Fp.add(Fp.add(a, a), a), a));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381/Fp/multiply/square equality', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT, (num) => {
|
|
||||||
const a = Fp.create(num);
|
|
||||||
deepStrictEqual(Fp.square(a), Fp.multiply(a, a));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381/Fp/multiply/pow equality', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT, (num) => {
|
|
||||||
const a = Fp.create(num);
|
|
||||||
deepStrictEqual(Fp.pow(a, 0n), Fp.ONE);
|
|
||||||
deepStrictEqual(Fp.pow(a, 1n), a);
|
|
||||||
deepStrictEqual(Fp.pow(a, 2n), Fp.multiply(a, a));
|
|
||||||
deepStrictEqual(Fp.pow(a, 3n), Fp.multiply(Fp.multiply(a, a), a));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381/Fp/multiply/sqrt', () => {
|
should('bls12-381/Fp/multiply/sqrt', () => {
|
||||||
let sqr1 = Fp.sqrt(Fp.create(300855555557n));
|
let sqr1 = Fp.sqrt(Fp.create(300855555557n));
|
||||||
deepStrictEqual(
|
deepStrictEqual(
|
||||||
@@ -188,43 +50,6 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
|||||||
);
|
);
|
||||||
throws(() => Fp.sqrt(Fp.create(72057594037927816n)));
|
throws(() => Fp.sqrt(Fp.create(72057594037927816n)));
|
||||||
});
|
});
|
||||||
|
|
||||||
should('bls12-381/Fp/div/division by one equality', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(fc.bigInt(1n, Fp.ORDER - 1n), (num) => {
|
|
||||||
const a = Fp.create(num);
|
|
||||||
deepStrictEqual(Fp.div(a, Fp.ONE), a);
|
|
||||||
deepStrictEqual(Fp.div(a, a), Fp.ONE);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381/Fp/div/division by zero equality', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT, (num) => {
|
|
||||||
const a = Fp.create(num);
|
|
||||||
deepStrictEqual(Fp.div(Fp.ZERO, a), Fp.ZERO);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381/Fp/div/division distributivity', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT, FC_BIGINT, FC_BIGINT, (num1, num2, num3) => {
|
|
||||||
const a = Fp.create(num1);
|
|
||||||
const b = Fp.create(num2);
|
|
||||||
const c = Fp.create(num3);
|
|
||||||
deepStrictEqual(Fp.div(Fp.add(a, b), c), Fp.add(Fp.div(a, c), Fp.div(b, c)));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381/Fp/div/division and multiplication equality', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT, FC_BIGINT, (num1, num2) => {
|
|
||||||
const a = Fp.create(num1);
|
|
||||||
const b = Fp.create(num2);
|
|
||||||
deepStrictEqual(Fp.div(a, b), Fp.multiply(a, Fp.invert(b)));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fp2
|
// Fp2
|
||||||
@@ -234,16 +59,6 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
|||||||
const FC_BIGINT = fc.bigInt(1n, Fp.ORDER - 1n);
|
const FC_BIGINT = fc.bigInt(1n, Fp.ORDER - 1n);
|
||||||
const FC_BIGINT_2 = fc.array(FC_BIGINT, { minLength: 2, maxLength: 2 });
|
const FC_BIGINT_2 = fc.array(FC_BIGINT, { minLength: 2, maxLength: 2 });
|
||||||
|
|
||||||
should('bls12-381 Fp2/equality', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_2, (num) => {
|
|
||||||
const a = Fp2.fromBigTuple([num[0], num[1]]);
|
|
||||||
const b = Fp2.fromBigTuple([num[0], num[1]]);
|
|
||||||
deepStrictEqual(Fp2.equals(a, b), true);
|
|
||||||
deepStrictEqual(Fp2.equals(b, a), true);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp2/non-equality', () => {
|
should('bls12-381 Fp2/non-equality', () => {
|
||||||
fc.assert(
|
fc.assert(
|
||||||
fc.property(FC_BIGINT_2, FC_BIGINT_2, (num1, num2) => {
|
fc.property(FC_BIGINT_2, FC_BIGINT_2, (num1, num2) => {
|
||||||
@@ -254,139 +69,7 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
should('bls12-381 Fp2/add/subtract/commutativity', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_2, FC_BIGINT_2, (num1, num2) => {
|
|
||||||
const a = Fp2.fromBigTuple([num1[0], num1[1]]);
|
|
||||||
const b = Fp2.fromBigTuple([num2[0], num2[1]]);
|
|
||||||
deepStrictEqual(Fp2.add(a, b), Fp2.add(b, a));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp2/add/subtract/associativity', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_2, FC_BIGINT_2, FC_BIGINT_2, (num1, num2, num3) => {
|
|
||||||
const a = Fp2.fromBigTuple([num1[0], num1[1]]);
|
|
||||||
const b = Fp2.fromBigTuple([num2[0], num2[1]]);
|
|
||||||
const c = Fp2.fromBigTuple([num3[0], num3[1]]);
|
|
||||||
deepStrictEqual(Fp2.add(a, Fp2.add(b, c)), Fp2.add(Fp2.add(a, b), c));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp2/add/subtract/x+0=x', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_2, (num) => {
|
|
||||||
const a = Fp2.fromBigTuple([num[0], num[1]]);
|
|
||||||
deepStrictEqual(Fp2.add(a, Fp2.ZERO), a);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp2/add/subtract/x-0=x', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_2, (num) => {
|
|
||||||
const a = Fp2.fromBigTuple([num[0], num[1]]);
|
|
||||||
deepStrictEqual(Fp2.subtract(a, Fp2.ZERO), a);
|
|
||||||
deepStrictEqual(Fp2.subtract(a, a), Fp2.ZERO);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp2/add/subtract/negate equality', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_2, (num1) => {
|
|
||||||
const a = Fp2.fromBigTuple([num1[0], num1[1]]);
|
|
||||||
const b = Fp2.fromBigTuple([num1[0], num1[1]]);
|
|
||||||
deepStrictEqual(Fp2.subtract(Fp2.ZERO, a), Fp2.negate(a));
|
|
||||||
deepStrictEqual(Fp2.subtract(a, b), Fp2.add(a, Fp2.negate(b)));
|
|
||||||
deepStrictEqual(Fp2.subtract(a, b), Fp2.add(a, Fp2.multiply(b, -1n)));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp2/add/subtract/negate', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_2, (num) => {
|
|
||||||
const a = Fp2.fromBigTuple([num[0], num[1]]);
|
|
||||||
deepStrictEqual(Fp2.negate(a), Fp2.subtract(Fp2.ZERO, a));
|
|
||||||
deepStrictEqual(Fp2.negate(a), Fp2.multiply(a, -1n));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
should('bls12-381 Fp2/multiply/commutativity', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_2, FC_BIGINT_2, (num1, num2) => {
|
|
||||||
const a = Fp2.fromBigTuple([num1[0], num1[1]]);
|
|
||||||
const b = Fp2.fromBigTuple([num2[0], num2[1]]);
|
|
||||||
deepStrictEqual(Fp2.multiply(a, b), Fp2.multiply(b, a));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp2/multiply/associativity', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_2, FC_BIGINT_2, FC_BIGINT_2, (num1, num2, num3) => {
|
|
||||||
const a = Fp2.fromBigTuple([num1[0], num1[1]]);
|
|
||||||
const b = Fp2.fromBigTuple([num2[0], num2[1]]);
|
|
||||||
const c = Fp2.fromBigTuple([num3[0], num3[1]]);
|
|
||||||
deepStrictEqual(Fp2.multiply(a, Fp2.multiply(b, c)), Fp2.multiply(Fp2.multiply(a, b), c));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp2/multiply/distributivity', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_2, FC_BIGINT_2, FC_BIGINT_2, (num1, num2, num3) => {
|
|
||||||
const a = Fp2.fromBigTuple([num1[0], num1[1]]);
|
|
||||||
const b = Fp2.fromBigTuple([num2[0], num2[1]]);
|
|
||||||
const c = Fp2.fromBigTuple([num3[0], num3[1]]);
|
|
||||||
deepStrictEqual(
|
|
||||||
Fp2.multiply(a, Fp2.add(b, c)),
|
|
||||||
Fp2.add(Fp2.multiply(b, a), Fp2.multiply(c, a))
|
|
||||||
);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp2/multiply/add equality', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_2, (num) => {
|
|
||||||
const a = Fp2.fromBigTuple([num[0], num[1]]);
|
|
||||||
deepStrictEqual(Fp2.multiply(a, 0n), Fp2.ZERO);
|
|
||||||
deepStrictEqual(Fp2.multiply(a, Fp2.ZERO), Fp2.ZERO);
|
|
||||||
deepStrictEqual(Fp2.multiply(a, 1n), a);
|
|
||||||
deepStrictEqual(Fp2.multiply(a, Fp2.ONE), a);
|
|
||||||
deepStrictEqual(Fp2.multiply(a, 2n), Fp2.add(a, a));
|
|
||||||
deepStrictEqual(Fp2.multiply(a, 3n), Fp2.add(Fp2.add(a, a), a));
|
|
||||||
deepStrictEqual(Fp2.multiply(a, 4n), Fp2.add(Fp2.add(Fp2.add(a, a), a), a));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp2/multiply/square equality', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_2, (num) => {
|
|
||||||
const a = Fp2.fromBigTuple([num[0], num[1]]);
|
|
||||||
deepStrictEqual(Fp2.square(a), Fp2.multiply(a, a));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp2/multiply/pow equality', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_2, (num) => {
|
|
||||||
const a = Fp2.fromBigTuple([num[0], num[1]]);
|
|
||||||
deepStrictEqual(Fp2.pow(a, 0n), Fp2.ONE);
|
|
||||||
deepStrictEqual(Fp2.pow(a, 1n), a);
|
|
||||||
deepStrictEqual(Fp2.pow(a, 2n), Fp2.multiply(a, a));
|
|
||||||
deepStrictEqual(Fp2.pow(a, 3n), Fp2.multiply(Fp2.multiply(a, a), a));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
should('bls12-381 Fp2/div/distributivity', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_2, FC_BIGINT_2, FC_BIGINT_2, (num1, num2, num3) => {
|
|
||||||
const a = Fp2.fromBigTuple([num1[0], num1[1]]);
|
|
||||||
const b = Fp2.fromBigTuple([num2[0], num2[1]]);
|
|
||||||
const c = Fp2.fromBigTuple([num3[0], num3[1]]);
|
|
||||||
deepStrictEqual(Fp2.div(Fp2.add(a, b), c), Fp2.add(Fp2.div(a, c), Fp2.div(b, c)));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp2/div/x/1=x', () => {
|
should('bls12-381 Fp2/div/x/1=x', () => {
|
||||||
fc.assert(
|
fc.assert(
|
||||||
fc.property(FC_BIGINT_2, (num) => {
|
fc.property(FC_BIGINT_2, (num) => {
|
||||||
@@ -397,23 +80,6 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
should('bls12-381 Fp2/div/ x/0=0', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_2, (num) => {
|
|
||||||
const a = Fp2.fromBigTuple([num[0], num[1]]);
|
|
||||||
deepStrictEqual(Fp2.div(Fp2.ZERO, a), Fp2.ZERO);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp2/div/ multiply equality', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_2, FC_BIGINT_2, (num1, num2) => {
|
|
||||||
const a = Fp2.fromBigTuple([num1[0], num1[1]]);
|
|
||||||
const b = Fp2.fromBigTuple([num2[0], num2[1]]);
|
|
||||||
deepStrictEqual(Fp2.div(a, b), Fp2.multiply(a, Fp2.invert(b)));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
should('bls12-381 Fp2/frobenius', () => {
|
should('bls12-381 Fp2/frobenius', () => {
|
||||||
// expect(Fp2.FROBENIUS_COEFFICIENTS[0].equals(Fp.ONE)).toBe(true);
|
// expect(Fp2.FROBENIUS_COEFFICIENTS[0].equals(Fp.ONE)).toBe(true);
|
||||||
@@ -475,201 +141,6 @@ const getPubKey = (priv) => bls.getPublicKey(priv);
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fp12
|
|
||||||
{
|
|
||||||
const Fp = bls.Fp;
|
|
||||||
const Fp12 = bls.Fp12;
|
|
||||||
const FC_BIGINT = fc.bigInt(1n, Fp.ORDER - 1n);
|
|
||||||
const FC_BIGINT_12 = fc.array(FC_BIGINT, {
|
|
||||||
minLength: 12,
|
|
||||||
maxLength: 12,
|
|
||||||
});
|
|
||||||
|
|
||||||
should('bls12-381 Fp12/equality', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_12, (num) => {
|
|
||||||
const a = Fp12.fromBigTwelve(num);
|
|
||||||
const b = Fp12.fromBigTwelve(num);
|
|
||||||
deepStrictEqual(Fp12.equals(a, b), true);
|
|
||||||
deepStrictEqual(Fp12.equals(b, a), true);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp12/non-equality', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_12, FC_BIGINT_12, (num1, num2) => {
|
|
||||||
const a = Fp12.fromBigTwelve(num1);
|
|
||||||
const b = Fp12.fromBigTwelve(num2);
|
|
||||||
deepStrictEqual(Fp12.equals(a, b), num1[0] === num2[0] && num1[1] === num2[1]);
|
|
||||||
deepStrictEqual(Fp12.equals(b, a), num1[0] === num2[0] && num1[1] === num2[1]);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp12/add/subtract/commutativuty', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_12, FC_BIGINT_12, (num1, num2) => {
|
|
||||||
const a = Fp12.fromBigTwelve(num1);
|
|
||||||
const b = Fp12.fromBigTwelve(num2);
|
|
||||||
deepStrictEqual(Fp12.add(a, b), Fp12.add(b, a));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp12/add/subtract/associativity', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_12, FC_BIGINT_12, FC_BIGINT_12, (num1, num2, num3) => {
|
|
||||||
const a = Fp12.fromBigTwelve(num1);
|
|
||||||
const b = Fp12.fromBigTwelve(num2);
|
|
||||||
const c = Fp12.fromBigTwelve(num3);
|
|
||||||
deepStrictEqual(Fp12.add(a, Fp12.add(b, c)), Fp12.add(Fp12.add(a, b), c));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp12/add/subtract/x+0=x', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_12, (num) => {
|
|
||||||
const a = Fp12.fromBigTwelve(num);
|
|
||||||
deepStrictEqual(Fp12.add(a, Fp12.ZERO), a);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp12/add/subtract/x-0=x', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_12, (num) => {
|
|
||||||
const a = Fp12.fromBigTwelve(num);
|
|
||||||
deepStrictEqual(Fp12.subtract(a, Fp12.ZERO), a);
|
|
||||||
deepStrictEqual(Fp12.subtract(a, a), Fp12.ZERO);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp12/add/subtract/negate equality', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_12, (num1) => {
|
|
||||||
const a = Fp12.fromBigTwelve(num1);
|
|
||||||
const b = Fp12.fromBigTwelve(num1);
|
|
||||||
deepStrictEqual(Fp12.subtract(Fp12.ZERO, a), Fp12.negate(a));
|
|
||||||
deepStrictEqual(Fp12.subtract(a, b), Fp12.add(a, Fp12.negate(b)));
|
|
||||||
deepStrictEqual(Fp12.subtract(a, b), Fp12.add(a, Fp12.multiply(b, -1n)));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp12/add/subtract/negate', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_12, (num) => {
|
|
||||||
const a = Fp12.fromBigTwelve(num);
|
|
||||||
deepStrictEqual(Fp12.negate(a), Fp12.subtract(Fp12.ZERO, a));
|
|
||||||
deepStrictEqual(Fp12.negate(a), Fp12.multiply(a, -1n));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
should('bls12-381 Fp12/multiply/commutativity', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_12, FC_BIGINT_12, (num1, num2) => {
|
|
||||||
const a = Fp12.fromBigTwelve(num1);
|
|
||||||
const b = Fp12.fromBigTwelve(num2);
|
|
||||||
deepStrictEqual(Fp12.multiply(a, b), Fp12.multiply(b, a));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp12/multiply/associativity', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_12, FC_BIGINT_12, FC_BIGINT_12, (num1, num2, num3) => {
|
|
||||||
const a = Fp12.fromBigTwelve(num1);
|
|
||||||
const b = Fp12.fromBigTwelve(num2);
|
|
||||||
const c = Fp12.fromBigTwelve(num3);
|
|
||||||
deepStrictEqual(
|
|
||||||
Fp12.multiply(a, Fp12.multiply(b, c)),
|
|
||||||
Fp12.multiply(Fp12.multiply(a, b), c)
|
|
||||||
);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp12/multiply/distributivity', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_12, FC_BIGINT_12, FC_BIGINT_12, (num1, num2, num3) => {
|
|
||||||
const a = Fp12.fromBigTwelve(num1);
|
|
||||||
const b = Fp12.fromBigTwelve(num2);
|
|
||||||
const c = Fp12.fromBigTwelve(num3);
|
|
||||||
deepStrictEqual(
|
|
||||||
Fp12.multiply(a, Fp12.add(b, c)),
|
|
||||||
Fp12.add(Fp12.multiply(b, a), Fp12.multiply(c, a))
|
|
||||||
);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp12/multiply/add equality', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_12, (num) => {
|
|
||||||
const a = Fp12.fromBigTwelve(num);
|
|
||||||
deepStrictEqual(Fp12.multiply(a, 0n), Fp12.ZERO);
|
|
||||||
deepStrictEqual(Fp12.multiply(a, Fp12.ZERO), Fp12.ZERO);
|
|
||||||
deepStrictEqual(Fp12.multiply(a, 1n), a);
|
|
||||||
deepStrictEqual(Fp12.multiply(a, Fp12.ONE), a);
|
|
||||||
deepStrictEqual(Fp12.multiply(a, 2n), Fp12.add(a, a));
|
|
||||||
deepStrictEqual(Fp12.multiply(a, 3n), Fp12.add(Fp12.add(a, a), a));
|
|
||||||
deepStrictEqual(Fp12.multiply(a, 4n), Fp12.add(Fp12.add(Fp12.add(a, a), a), a));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp12/multiply/square equality', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_12, (num) => {
|
|
||||||
const a = Fp12.fromBigTwelve(num);
|
|
||||||
deepStrictEqual(Fp12.square(a), Fp12.multiply(a, a));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp12/multiply/pow equality', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_12, (num) => {
|
|
||||||
const a = Fp12.fromBigTwelve(num);
|
|
||||||
deepStrictEqual(Fp12.pow(a, 0n), Fp12.ONE);
|
|
||||||
deepStrictEqual(Fp12.pow(a, 1n), a);
|
|
||||||
deepStrictEqual(Fp12.pow(a, 2n), Fp12.multiply(a, a));
|
|
||||||
deepStrictEqual(Fp12.pow(a, 3n), Fp12.multiply(Fp12.multiply(a, a), a));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
should('bls12-381 Fp12/div/x/1=x', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_12, (num) => {
|
|
||||||
const a = Fp12.fromBigTwelve(num);
|
|
||||||
deepStrictEqual(Fp12.div(a, 1n), a);
|
|
||||||
deepStrictEqual(Fp12.div(a, Fp12.ONE), a);
|
|
||||||
deepStrictEqual(Fp12.div(a, a), Fp12.ONE);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp12/div/x/0=0', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_12, (num) => {
|
|
||||||
const a = Fp12.fromBigTwelve(num);
|
|
||||||
deepStrictEqual(Fp12.div(Fp12.ZERO, a), Fp12.ZERO);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp12/div/distributivity', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_12, FC_BIGINT_12, FC_BIGINT_12, (num1, num2, num3) => {
|
|
||||||
const a = Fp12.fromBigTwelve(num1);
|
|
||||||
const b = Fp12.fromBigTwelve(num2);
|
|
||||||
const c = Fp12.fromBigTwelve(num3);
|
|
||||||
deepStrictEqual(Fp12.div(Fp12.add(a, b), c), Fp12.add(Fp12.div(a, c), Fp12.div(b, c)));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
should('bls12-381 Fp12/div/multiply equality', () => {
|
|
||||||
fc.assert(
|
|
||||||
fc.property(FC_BIGINT_12, FC_BIGINT_12, (num1, num2) => {
|
|
||||||
const a = Fp12.fromBigTwelve(num1);
|
|
||||||
const b = Fp12.fromBigTwelve(num2);
|
|
||||||
deepStrictEqual(Fp12.div(a, b), Fp12.multiply(a, Fp12.invert(b)));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Point
|
// Point
|
||||||
{
|
{
|
||||||
const Fp = bls.Fp;
|
const Fp = bls.Fp;
|
||||||
@@ -1519,7 +990,7 @@ should('bls12-381/basic/should not verify wrong multi-signature as simple signat
|
|||||||
should('pairing/creates negative G1 pairing', () => {
|
should('pairing/creates negative G1 pairing', () => {
|
||||||
const p1 = pairing(G1, G2);
|
const p1 = pairing(G1, G2);
|
||||||
const p2 = pairing(G1.negate(), G2);
|
const p2 = pairing(G1.negate(), G2);
|
||||||
deepStrictEqual(Fp12.multiply(p1, p2), Fp12.ONE);
|
deepStrictEqual(Fp12.mul(p1, p2), Fp12.ONE);
|
||||||
});
|
});
|
||||||
should('pairing/creates negative G2 pairing', () => {
|
should('pairing/creates negative G2 pairing', () => {
|
||||||
const p2 = pairing(G1.negate(), G2);
|
const p2 = pairing(G1.negate(), G2);
|
||||||
@@ -1534,7 +1005,7 @@ should('bls12-381/basic/should not verify wrong multi-signature as simple signat
|
|||||||
should('pairing/G1 billinearity', () => {
|
should('pairing/G1 billinearity', () => {
|
||||||
const p1 = pairing(G1, G2);
|
const p1 = pairing(G1, G2);
|
||||||
const p2 = pairing(G1.multiply(2n), G2);
|
const p2 = pairing(G1.multiply(2n), G2);
|
||||||
deepStrictEqual(Fp12.multiply(p1, p1), p2);
|
deepStrictEqual(Fp12.mul(p1, p1), p2);
|
||||||
});
|
});
|
||||||
should('pairing/should not degenerate', () => {
|
should('pairing/should not degenerate', () => {
|
||||||
const p1 = pairing(G1, G2);
|
const p1 = pairing(G1, G2);
|
||||||
@@ -1547,7 +1018,7 @@ should('bls12-381/basic/should not verify wrong multi-signature as simple signat
|
|||||||
should('pairing/G2 billinearity', () => {
|
should('pairing/G2 billinearity', () => {
|
||||||
const p1 = pairing(G1, G2);
|
const p1 = pairing(G1, G2);
|
||||||
const p2 = pairing(G1, G2.multiply(2n));
|
const p2 = pairing(G1, G2.multiply(2n));
|
||||||
deepStrictEqual(Fp12.multiply(p1, p1), p2);
|
deepStrictEqual(Fp12.mul(p1, p1), p2);
|
||||||
});
|
});
|
||||||
should('pairing/proper pairing composite check', () => {
|
should('pairing/proper pairing composite check', () => {
|
||||||
const p1 = pairing(G1.multiply(37n), G2.multiply(27n));
|
const p1 = pairing(G1.multiply(37n), G2.multiply(27n));
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
import { deepStrictEqual, throws } from 'assert';
|
import { deepStrictEqual, throws } from 'assert';
|
||||||
import { should } from 'micro-should';
|
import { should } from 'micro-should';
|
||||||
import * as fc from 'fast-check';
|
import * as fc from 'fast-check';
|
||||||
import { ed25519, ed25519ctx, ed25519ph, x25519, RistrettoPoint } from '../lib/ed25519.js';
|
import { ed25519, ed25519ctx, ed25519ph, x25519, RistrettoPoint } from '../lib/esm/ed25519.js';
|
||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
import { default as zip215 } from './ed25519/zip215.json' assert { type: 'json' };
|
import { default as zip215 } from './ed25519/zip215.json' assert { type: 'json' };
|
||||||
import { hexToBytes, bytesToHex, randomBytes } from '@noble/hashes/utils';
|
import { hexToBytes, bytesToHex, randomBytes } from '@noble/hashes/utils';
|
||||||
import { numberToBytesLE } from '@noble/curves/utils';
|
import { numberToBytesLE } from '../lib/esm/abstract/utils.js';
|
||||||
import { sha512 } from '@noble/hashes/sha512';
|
import { sha512 } from '@noble/hashes/sha512';
|
||||||
import { default as ed25519vectors } from './wycheproof/eddsa_test.json' assert { type: 'json' };
|
import { default as ed25519vectors } from './wycheproof/eddsa_test.json' assert { type: 'json' };
|
||||||
import { default as x25519vectors } from './wycheproof/x25519_test.json' assert { type: 'json' };
|
import { default as x25519vectors } from './wycheproof/x25519_test.json' assert { type: 'json' };
|
||||||
@@ -346,7 +346,7 @@ should('ristretto255/should not convert bad bytes encoding', () => {
|
|||||||
'47cfc5497c53dc8e61c91d17fd626ffb1c49e2bca94eed052281b510b1117a24',
|
'47cfc5497c53dc8e61c91d17fd626ffb1c49e2bca94eed052281b510b1117a24',
|
||||||
'f1c6165d33367351b0da8f6e4511010c68174a03b6581212c71c0e1d026c3c72',
|
'f1c6165d33367351b0da8f6e4511010c68174a03b6581212c71c0e1d026c3c72',
|
||||||
'87260f7a2f12495118360f02c26a470f450dadf34a413d21042b43b9d93e1309',
|
'87260f7a2f12495118360f02c26a470f450dadf34a413d21042b43b9d93e1309',
|
||||||
// These are all bad because they give a nonsquare x^2.
|
// These are all bad because they give a nonsquare x².
|
||||||
'26948d35ca62e643e26a83177332e6b6afeb9d08e4268b650f1f5bbd8d81d371',
|
'26948d35ca62e643e26a83177332e6b6afeb9d08e4268b650f1f5bbd8d81d371',
|
||||||
'4eac077a713c57b4f4397629a4145982c661f48044dd3f96427d40b147d9742f',
|
'4eac077a713c57b4f4397629a4145982c661f48044dd3f96427d40b147d9742f',
|
||||||
'de6a7b00deadc788eb6b6c8d20c0ae96c2f2019078fa604fee5b87d6e989ad7b',
|
'de6a7b00deadc788eb6b6c8d20c0ae96c2f2019078fa604fee5b87d6e989ad7b',
|
||||||
@@ -454,7 +454,7 @@ const rfc7748Mul = [
|
|||||||
for (let i = 0; i < rfc7748Mul.length; i++) {
|
for (let i = 0; i < rfc7748Mul.length; i++) {
|
||||||
const v = rfc7748Mul[i];
|
const v = rfc7748Mul[i];
|
||||||
should(`RFC7748: scalarMult (${i})`, () => {
|
should(`RFC7748: scalarMult (${i})`, () => {
|
||||||
deepStrictEqual(hex(x25519.scalarMult(v.u, v.scalar)), v.outputU);
|
deepStrictEqual(hex(x25519.scalarMult(v.scalar, v.u)), v.outputU);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -467,7 +467,7 @@ for (let i = 0; i < rfc7748Iter.length; i++) {
|
|||||||
const { scalar, iters } = rfc7748Iter[i];
|
const { scalar, iters } = rfc7748Iter[i];
|
||||||
should(`RFC7748: scalarMult iteration (${i})`, () => {
|
should(`RFC7748: scalarMult iteration (${i})`, () => {
|
||||||
let k = x25519.Gu;
|
let k = x25519.Gu;
|
||||||
for (let i = 0, u = k; i < iters; i++) [k, u] = [x25519.scalarMult(u, k), k];
|
for (let i = 0, u = k; i < iters; i++) [k, u] = [x25519.scalarMult(k, u), k];
|
||||||
deepStrictEqual(hex(k), scalar);
|
deepStrictEqual(hex(k), scalar);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -480,8 +480,8 @@ should('RFC7748 getSharedKey', () => {
|
|||||||
const shared = '4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742';
|
const shared = '4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742';
|
||||||
deepStrictEqual(alicePublic, hex(x25519.getPublicKey(alicePrivate)));
|
deepStrictEqual(alicePublic, hex(x25519.getPublicKey(alicePrivate)));
|
||||||
deepStrictEqual(bobPublic, hex(x25519.getPublicKey(bobPrivate)));
|
deepStrictEqual(bobPublic, hex(x25519.getPublicKey(bobPrivate)));
|
||||||
deepStrictEqual(hex(x25519.scalarMult(bobPublic, alicePrivate)), shared);
|
deepStrictEqual(hex(x25519.scalarMult(alicePrivate, bobPublic)), shared);
|
||||||
deepStrictEqual(hex(x25519.scalarMult(alicePublic, bobPrivate)), shared);
|
deepStrictEqual(hex(x25519.scalarMult(bobPrivate, alicePublic)), shared);
|
||||||
});
|
});
|
||||||
|
|
||||||
// should('X25519/getSharedSecret() should be commutative', () => {
|
// should('X25519/getSharedSecret() should be commutative', () => {
|
||||||
@@ -514,7 +514,7 @@ should('RFC7748 getSharedKey', () => {
|
|||||||
const comment = `(${i}, ${v.result}) ${v.comment}`;
|
const comment = `(${i}, ${v.result}) ${v.comment}`;
|
||||||
if (v.result === 'valid' || v.result === 'acceptable') {
|
if (v.result === 'valid' || v.result === 'acceptable') {
|
||||||
try {
|
try {
|
||||||
const shared = hex(x25519.scalarMult(v.public, v.private));
|
const shared = hex(x25519.scalarMult(v.private, v.public));
|
||||||
deepStrictEqual(shared, v.shared, comment);
|
deepStrictEqual(shared, v.shared, comment);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// We are more strict
|
// We are more strict
|
||||||
@@ -525,7 +525,7 @@ should('RFC7748 getSharedKey', () => {
|
|||||||
} else if (v.result === 'invalid') {
|
} else if (v.result === 'invalid') {
|
||||||
let failed = false;
|
let failed = false;
|
||||||
try {
|
try {
|
||||||
x25519.scalarMult(v.public, v.private);
|
x25519.scalarMult(v.private, v.public);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
import { deepStrictEqual, throws } from 'assert';
|
import { deepStrictEqual, throws } from 'assert';
|
||||||
import { should } from 'micro-should';
|
import { should } from 'micro-should';
|
||||||
import * as fc from 'fast-check';
|
import * as fc from 'fast-check';
|
||||||
import { ed448, ed448ph, x448 } from '../lib/ed448.js';
|
import { ed448, ed448ph, x448 } from '../lib/esm/ed448.js';
|
||||||
import { hexToBytes, bytesToHex, randomBytes } from '@noble/hashes/utils';
|
import { hexToBytes, bytesToHex, randomBytes } from '@noble/hashes/utils';
|
||||||
import { numberToBytesLE } from '@noble/curves/utils';
|
import { numberToBytesLE } from '../lib/esm/abstract/utils.js';
|
||||||
import { default as ed448vectors } from './wycheproof/ed448_test.json' assert { type: 'json' };
|
import { default as ed448vectors } from './wycheproof/ed448_test.json' assert { type: 'json' };
|
||||||
import { default as x448vectors } from './wycheproof/x448_test.json' assert { type: 'json' };
|
import { default as x448vectors } from './wycheproof/x448_test.json' assert { type: 'json' };
|
||||||
|
|
||||||
@@ -480,7 +480,7 @@ const rfc7748Mul = [
|
|||||||
for (let i = 0; i < rfc7748Mul.length; i++) {
|
for (let i = 0; i < rfc7748Mul.length; i++) {
|
||||||
const v = rfc7748Mul[i];
|
const v = rfc7748Mul[i];
|
||||||
should(`RFC7748: scalarMult (${i})`, () => {
|
should(`RFC7748: scalarMult (${i})`, () => {
|
||||||
deepStrictEqual(hex(x448.scalarMult(v.u, v.scalar)), v.outputU);
|
deepStrictEqual(hex(x448.scalarMult(v.scalar, v.u)), v.outputU);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -501,7 +501,7 @@ for (let i = 0; i < rfc7748Iter.length; i++) {
|
|||||||
const { scalar, iters } = rfc7748Iter[i];
|
const { scalar, iters } = rfc7748Iter[i];
|
||||||
should(`RFC7748: scalarMult iteration (${i})`, () => {
|
should(`RFC7748: scalarMult iteration (${i})`, () => {
|
||||||
let k = x448.Gu;
|
let k = x448.Gu;
|
||||||
for (let i = 0, u = k; i < iters; i++) [k, u] = [x448.scalarMult(u, k), k];
|
for (let i = 0, u = k; i < iters; i++) [k, u] = [x448.scalarMult(k, u), k];
|
||||||
deepStrictEqual(hex(k), scalar);
|
deepStrictEqual(hex(k), scalar);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -519,8 +519,8 @@ should('RFC7748 getSharedKey', () => {
|
|||||||
'07fff4181ac6cc95ec1c16a94a0f74d12da232ce40a77552281d282bb60c0b56fd2464c335543936521c24403085d59a449a5037514a879d';
|
'07fff4181ac6cc95ec1c16a94a0f74d12da232ce40a77552281d282bb60c0b56fd2464c335543936521c24403085d59a449a5037514a879d';
|
||||||
deepStrictEqual(alicePublic, hex(x448.getPublicKey(alicePrivate)));
|
deepStrictEqual(alicePublic, hex(x448.getPublicKey(alicePrivate)));
|
||||||
deepStrictEqual(bobPublic, hex(x448.getPublicKey(bobPrivate)));
|
deepStrictEqual(bobPublic, hex(x448.getPublicKey(bobPrivate)));
|
||||||
deepStrictEqual(hex(x448.scalarMult(bobPublic, alicePrivate)), shared);
|
deepStrictEqual(hex(x448.scalarMult(alicePrivate, bobPublic)), shared);
|
||||||
deepStrictEqual(hex(x448.scalarMult(alicePublic, bobPrivate)), shared);
|
deepStrictEqual(hex(x448.scalarMult(bobPrivate, alicePublic)), shared);
|
||||||
});
|
});
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -531,7 +531,7 @@ should('RFC7748 getSharedKey', () => {
|
|||||||
const index = `(${i}, ${v.result}) ${v.comment}`;
|
const index = `(${i}, ${v.result}) ${v.comment}`;
|
||||||
if (v.result === 'valid' || v.result === 'acceptable') {
|
if (v.result === 'valid' || v.result === 'acceptable') {
|
||||||
try {
|
try {
|
||||||
const shared = hex(x448.scalarMult(v.public, v.private));
|
const shared = hex(x448.scalarMult(v.private, v.public));
|
||||||
deepStrictEqual(shared, v.shared, index);
|
deepStrictEqual(shared, v.shared, index);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// We are more strict
|
// We are more strict
|
||||||
@@ -543,7 +543,7 @@ should('RFC7748 getSharedKey', () => {
|
|||||||
} else if (v.result === 'invalid') {
|
} else if (v.result === 'invalid') {
|
||||||
let failed = false;
|
let failed = false;
|
||||||
try {
|
try {
|
||||||
x448.scalarMult(v.public, v.private);
|
x448.scalarMult(v.private, v.public);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
@@ -652,8 +652,8 @@ for (let i = 0; i < VECTORS_RFC8032_PH.length; i++) {
|
|||||||
should('X448 base point', () => {
|
should('X448 base point', () => {
|
||||||
const { x, y } = ed448.Point.BASE;
|
const { x, y } = ed448.Point.BASE;
|
||||||
const { P } = ed448.CURVE;
|
const { P } = ed448.CURVE;
|
||||||
const invX = ed448.utils.invert(x * x, P); // x^2
|
const invX = ed448.utils.invert(x * x, P); // x²
|
||||||
const u = ed448.utils.mod(y * y * invX, P); // (y^2/x^2)
|
const u = ed448.utils.mod(y * y * invX, P); // (y²/x²)
|
||||||
deepStrictEqual(hex(numberToBytesLE(u, 56)), x448.Gu);
|
deepStrictEqual(hex(numberToBytesLE(u, 56)), x448.Gu);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -28,16 +28,16 @@
|
|||||||
"Uy": "EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A",
|
"Uy": "EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A",
|
||||||
"cases": [
|
"cases": [
|
||||||
{
|
{
|
||||||
"k": "AD3029E0278F80643DE33917CE6908C70A8FF50A411F06E41DEDFCDC",
|
"k": "C1D1F2F10881088301880506805FEB4825FE09ACB6816C36991AA06D",
|
||||||
"message": "sample",
|
"message": "sample",
|
||||||
"r": "61AA3DA010E8E8406C656BC477A7A7189895E7E840CDFE8FF42307BA",
|
"r": "1CDFE6662DDE1E4A1EC4CDEDF6A1F5A2FB7FBD9145C12113E6ABFD3E",
|
||||||
"s": "BC814050DAB5D23770879494F9E0A680DC1AF7161991BDE692B10101"
|
"s": "A6694FD7718A21053F225D3F46197CA699D45006C06F871808F43EBC"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"k": "FF86F57924DA248D6E44E8154EB69F0AE2AEBAEE9931D0B5A969F904",
|
"k": "DF8B38D40DCA3E077D0AC520BF56B6D565134D9B5F2EAE0D34900524",
|
||||||
"message": "test",
|
"message": "test",
|
||||||
"r": "AD04DDE87B84747A243A631EA47A1BA6D1FAA059149AD2440DE6FBA6",
|
"r": "C441CE8E261DED634E4CF84910E4C5D1D22C5CF3B732BB204DBEF019",
|
||||||
"s": "178D49B1AE90E3D8B629BE3DB5683915F4E8C99FDF6E666CF37ADCFD"
|
"s": "902F42847A63BDC5F6046ADA114953120F99442D76510150F372A3F4"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
138
test/hash-to-curve.test.js
Normal file
138
test/hash-to-curve.test.js
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
import { deepStrictEqual } from 'assert';
|
||||||
|
import { should } from 'micro-should';
|
||||||
|
import { bytesToHex } from '@noble/hashes/utils';
|
||||||
|
// Generic tests for all curves in package
|
||||||
|
import { sha256 } from '@noble/hashes/sha256';
|
||||||
|
import { sha512 } from '@noble/hashes/sha512';
|
||||||
|
import { shake128, shake256 } from '@noble/hashes/sha3';
|
||||||
|
import { secp256r1 } from '../lib/esm/p256.js';
|
||||||
|
import { secp384r1 } from '../lib/esm/p384.js';
|
||||||
|
import { secp521r1 } from '../lib/esm/p521.js';
|
||||||
|
import { ed25519 } from '../lib/esm/ed25519.js';
|
||||||
|
import { ed448 } from '../lib/esm/ed448.js';
|
||||||
|
import { secp256k1 } from '../lib/esm/secp256k1.js';
|
||||||
|
import { bls12_381 } from '../lib/esm/bls12-381.js';
|
||||||
|
import {
|
||||||
|
stringToBytes,
|
||||||
|
expand_message_xmd,
|
||||||
|
expand_message_xof,
|
||||||
|
} from '../lib/esm/abstract/hash-to-curve.js';
|
||||||
|
// XMD
|
||||||
|
import { default as xmd_sha256_38 } from './hash-to-curve/expand_message_xmd_SHA256_38.json' assert { type: 'json' };
|
||||||
|
import { default as xmd_sha256_256 } from './hash-to-curve/expand_message_xmd_SHA256_256.json' assert { type: 'json' };
|
||||||
|
import { default as xmd_sha512_38 } from './hash-to-curve/expand_message_xmd_SHA512_38.json' assert { type: 'json' };
|
||||||
|
// XOF
|
||||||
|
import { default as xof_shake128_36 } from './hash-to-curve/expand_message_xof_SHAKE128_36.json' assert { type: 'json' };
|
||||||
|
import { default as xof_shake128_256 } from './hash-to-curve/expand_message_xof_SHAKE128_256.json' assert { type: 'json' };
|
||||||
|
import { default as xof_shake256_36 } from './hash-to-curve/expand_message_xof_SHAKE256_36.json' assert { type: 'json' };
|
||||||
|
// P256
|
||||||
|
import { default as p256_ro } from './hash-to-curve/P256_XMD:SHA-256_SSWU_RO_.json' assert { type: 'json' };
|
||||||
|
import { default as p256_nu } from './hash-to-curve/P256_XMD:SHA-256_SSWU_NU_.json' assert { type: 'json' };
|
||||||
|
// P384
|
||||||
|
import { default as p384_ro } from './hash-to-curve/P384_XMD:SHA-384_SSWU_RO_.json' assert { type: 'json' };
|
||||||
|
import { default as p384_nu } from './hash-to-curve/P384_XMD:SHA-384_SSWU_NU_.json' assert { type: 'json' };
|
||||||
|
// P521
|
||||||
|
import { default as p521_ro } from './hash-to-curve/P521_XMD:SHA-512_SSWU_RO_.json' assert { type: 'json' };
|
||||||
|
import { default as p521_nu } from './hash-to-curve/P521_XMD:SHA-512_SSWU_NU_.json' assert { type: 'json' };
|
||||||
|
// secp256k1
|
||||||
|
import { default as secp256k1_ro } from './hash-to-curve/secp256k1_XMD:SHA-256_SSWU_RO_.json' assert { type: 'json' };
|
||||||
|
import { default as secp256k1_nu } from './hash-to-curve/secp256k1_XMD:SHA-256_SSWU_NU_.json' assert { type: 'json' };
|
||||||
|
// bls-G1
|
||||||
|
import { default as g1_ro } from './hash-to-curve/BLS12381G1_XMD:SHA-256_SSWU_RO_.json' assert { type: 'json' };
|
||||||
|
import { default as g1_nu } from './hash-to-curve/BLS12381G1_XMD:SHA-256_SSWU_NU_.json' assert { type: 'json' };
|
||||||
|
// bls-G2
|
||||||
|
import { default as g2_ro } from './hash-to-curve/BLS12381G2_XMD:SHA-256_SSWU_RO_.json' assert { type: 'json' };
|
||||||
|
import { default as g2_nu } from './hash-to-curve/BLS12381G2_XMD:SHA-256_SSWU_NU_.json' assert { type: 'json' };
|
||||||
|
// ed25519
|
||||||
|
import { default as ed25519_ro } from './hash-to-curve/edwards25519_XMD:SHA-512_ELL2_RO_.json' assert { type: 'json' };
|
||||||
|
import { default as ed25519_nu } from './hash-to-curve/edwards25519_XMD:SHA-512_ELL2_NU_.json' assert { type: 'json' };
|
||||||
|
// ed448
|
||||||
|
import { default as ed448_ro } from './hash-to-curve/edwards448_XOF:SHAKE256_ELL2_RO_.json' assert { type: 'json' };
|
||||||
|
import { default as ed448_nu } from './hash-to-curve/edwards448_XOF:SHAKE256_ELL2_NU_.json' assert { type: 'json' };
|
||||||
|
|
||||||
|
function testExpandXMD(hash, vectors) {
|
||||||
|
for (let i = 0; i < vectors.tests.length; i++) {
|
||||||
|
const t = vectors.tests[i];
|
||||||
|
should(`expand_message_xmd/${vectors.hash}/${vectors.DST.length}/${i}`, () => {
|
||||||
|
const p = expand_message_xmd(
|
||||||
|
stringToBytes(t.msg),
|
||||||
|
stringToBytes(vectors.DST),
|
||||||
|
t.len_in_bytes,
|
||||||
|
hash
|
||||||
|
);
|
||||||
|
deepStrictEqual(bytesToHex(p), t.uniform_bytes);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testExpandXMD(sha256, xmd_sha256_38);
|
||||||
|
testExpandXMD(sha256, xmd_sha256_256);
|
||||||
|
testExpandXMD(sha512, xmd_sha512_38);
|
||||||
|
|
||||||
|
function testExpandXOF(hash, vectors) {
|
||||||
|
for (let i = 0; i < vectors.tests.length; i++) {
|
||||||
|
const t = vectors.tests[i];
|
||||||
|
should(`expand_message_xof/${vectors.hash}/${vectors.DST.length}/${i}`, () => {
|
||||||
|
const p = expand_message_xof(
|
||||||
|
stringToBytes(t.msg),
|
||||||
|
stringToBytes(vectors.DST),
|
||||||
|
+t.len_in_bytes,
|
||||||
|
vectors.k,
|
||||||
|
hash
|
||||||
|
);
|
||||||
|
deepStrictEqual(bytesToHex(p), t.uniform_bytes);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testExpandXOF(shake128, xof_shake128_36);
|
||||||
|
testExpandXOF(shake128, xof_shake128_256);
|
||||||
|
testExpandXOF(shake256, xof_shake256_36);
|
||||||
|
|
||||||
|
function stringToFp(s) {
|
||||||
|
// bls-G2 support
|
||||||
|
if (s.includes(',')) {
|
||||||
|
const [c0, c1] = s.split(',').map(BigInt);
|
||||||
|
return { c0, c1 };
|
||||||
|
}
|
||||||
|
return BigInt(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCurve(curve, ro, nu) {
|
||||||
|
for (let i = 0; i < ro.vectors.length; i++) {
|
||||||
|
const t = ro.vectors[i];
|
||||||
|
should(`${ro.curve}/${ro.ciphersuite}(${i})`, () => {
|
||||||
|
const p = curve.Point.hashToCurve(stringToBytes(t.msg), {
|
||||||
|
DST: ro.dst,
|
||||||
|
});
|
||||||
|
deepStrictEqual(p.x, stringToFp(t.P.x), 'Px');
|
||||||
|
deepStrictEqual(p.y, stringToFp(t.P.y), 'Py');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
for (let i = 0; i < nu.vectors.length; i++) {
|
||||||
|
const t = nu.vectors[i];
|
||||||
|
should(`${nu.curve}/${nu.ciphersuite}(${i})`, () => {
|
||||||
|
const p = curve.Point.encodeToCurve(stringToBytes(t.msg), {
|
||||||
|
DST: nu.dst,
|
||||||
|
});
|
||||||
|
deepStrictEqual(p.x, stringToFp(t.P.x), 'Px');
|
||||||
|
deepStrictEqual(p.y, stringToFp(t.P.y), 'Py');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testCurve(secp256r1, p256_ro, p256_nu);
|
||||||
|
testCurve(secp384r1, p384_ro, p384_nu);
|
||||||
|
testCurve(secp521r1, p521_ro, p521_nu);
|
||||||
|
// TODO: remove same tests from bls12
|
||||||
|
testCurve(bls12_381.G1, g1_ro, g1_nu);
|
||||||
|
testCurve(bls12_381.G2, g2_ro, g2_nu);
|
||||||
|
testCurve(secp256k1, secp256k1_ro, secp256k1_nu);
|
||||||
|
testCurve(ed25519, ed25519_ro, ed25519_nu);
|
||||||
|
testCurve(ed448, ed448_ro, ed448_nu);
|
||||||
|
|
||||||
|
// ESM is broken.
|
||||||
|
import url from 'url';
|
||||||
|
if (import.meta.url === url.pathToFileURL(process.argv[1]).href) {
|
||||||
|
should.run();
|
||||||
|
}
|
||||||
90
test/hash-to-curve/BLS12381G1_XMD:SHA-256_SSWU_NU_.json
Normal file
90
test/hash-to-curve/BLS12381G1_XMD:SHA-256_SSWU_NU_.json
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
{
|
||||||
|
"L": "0x40",
|
||||||
|
"Z": "0xb",
|
||||||
|
"ciphersuite": "BLS12381G1_XMD:SHA-256_SSWU_NU_",
|
||||||
|
"curve": "BLS12-381 G1",
|
||||||
|
"dst": "QUUX-V01-CS02-with-BLS12381G1_XMD:SHA-256_SSWU_NU_",
|
||||||
|
"expand": "XMD",
|
||||||
|
"field": {
|
||||||
|
"m": "0x1",
|
||||||
|
"p": "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab"
|
||||||
|
},
|
||||||
|
"hash": "sha256",
|
||||||
|
"k": "0x80",
|
||||||
|
"map": {
|
||||||
|
"name": "SSWU"
|
||||||
|
},
|
||||||
|
"randomOracle": false,
|
||||||
|
"vectors": [
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x184bb665c37ff561a89ec2122dd343f20e0f4cbcaec84e3c3052ea81d1834e192c426074b02ed3dca4e7676ce4ce48ba",
|
||||||
|
"y": "0x04407b8d35af4dacc809927071fc0405218f1401a6d15af775810e4e460064bcc9468beeba82fdc751be70476c888bf3"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x11398d3b324810a1b093f8e35aa8571cced95858207e7f49c4fd74656096d61d8a2f9a23cdb18a4dd11cd1d66f41f709",
|
||||||
|
"y": "0x19316b6fb2ba7717355d5d66a361899057e1e84a6823039efc7beccefe09d023fb2713b1c415fcf278eb0c39a89b4f72"
|
||||||
|
},
|
||||||
|
"msg": "",
|
||||||
|
"u": [
|
||||||
|
"0x156c8a6a2c184569d69a76be144b5cdc5141d2d2ca4fe341f011e25e3969c55ad9e9b9ce2eb833c81a908e5fa4ac5f03"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x009769f3ab59bfd551d53a5f846b9984c59b97d6842b20a2c565baa167945e3d026a3755b6345df8ec7e6acb6868ae6d",
|
||||||
|
"y": "0x1532c00cf61aa3d0ce3e5aa20c3b531a2abd2c770a790a2613818303c6b830ffc0ecf6c357af3317b9575c567f11cd2c"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x1998321bc27ff6d71df3051b5aec12ff47363d81a5e9d2dff55f444f6ca7e7d6af45c56fd029c58237c266ef5cda5254",
|
||||||
|
"y": "0x034d274476c6307ae584f951c82e7ea85b84f72d28f4d6471732356121af8d62a49bc263e8eb913a6cf6f125995514ee"
|
||||||
|
},
|
||||||
|
"msg": "abc",
|
||||||
|
"u": [
|
||||||
|
"0x147e1ed29f06e4c5079b9d14fc89d2820d32419b990c1c7bb7dbea2a36a045124b31ffbde7c99329c05c559af1c6cc82"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x1974dbb8e6b5d20b84df7e625e2fbfecb2cdb5f77d5eae5fb2955e5ce7313cae8364bc2fff520a6c25619739c6bdcb6a",
|
||||||
|
"y": "0x15f9897e11c6441eaa676de141c8d83c37aab8667173cbe1dfd6de74d11861b961dccebcd9d289ac633455dfcc7013a3"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x17d502fa43bd6a4cad2859049a0c3ecefd60240d129be65da271a4c03a9c38fa78163b9d2a919d2beb57df7d609b4919",
|
||||||
|
"y": "0x109019902ae93a8732abecf2ff7fecd2e4e305eb91f41c9c3267f16b6c19de138c7272947f25512745da6c466cdfd1ac"
|
||||||
|
},
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"u": [
|
||||||
|
"0x04090815ad598a06897dd89bcda860f25837d54e897298ce31e6947378134d3761dc59a572154963e8c954919ecfa82d"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x0a7a047c4a8397b3446450642c2ac64d7239b61872c9ae7a59707a8f4f950f101e766afe58223b3bff3a19a7f754027c",
|
||||||
|
"y": "0x1383aebba1e4327ccff7cf9912bda0dbc77de048b71ef8c8a81111d71dc33c5e3aa6edee9cf6f5fe525d50cc50b77cc9"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x112eb92dd2b3aa9cd38b08de4bef603f2f9fb0ca226030626a9a2e47ad1e9847fe0a5ed13766c339e38f514bba143b21",
|
||||||
|
"y": "0x17542ce2f8d0a54f2c5ba8c4b14e10b22d5bcd7bae2af3c965c8c872b571058c720eac448276c99967ded2bf124490e1"
|
||||||
|
},
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"u": [
|
||||||
|
"0x08dccd088ca55b8bfbc96fb50bb25c592faa867a8bb78d4e94a8cc2c92306190244532e91feba2b7fed977e3c3bb5a1f"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x0e7a16a975904f131682edbb03d9560d3e48214c9986bd50417a77108d13dc957500edf96462a3d01e62dc6cd468ef11",
|
||||||
|
"y": "0x0ae89e677711d05c30a48d6d75e76ca9fb70fe06c6dd6ff988683d89ccde29ac7d46c53bb97a59b1901abf1db66052db"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x1775d400a1bacc1c39c355da7e96d2d1c97baa9430c4a3476881f8521c09a01f921f592607961efc99c4cd46bd78ca19",
|
||||||
|
"y": "0x1109b5d59f65964315de65a7a143e86eabc053104ed289cf480949317a5685fad7254ff8e7fe6d24d3104e5d55ad6370"
|
||||||
|
},
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"u": [
|
||||||
|
"0x0dd824886d2123a96447f6c56e3a3fa992fbfefdba17b6673f9f630ff19e4d326529db37e1c1be43f905bf9202e0278d"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
115
test/hash-to-curve/BLS12381G1_XMD:SHA-256_SSWU_RO_.json
Normal file
115
test/hash-to-curve/BLS12381G1_XMD:SHA-256_SSWU_RO_.json
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
{
|
||||||
|
"L": "0x40",
|
||||||
|
"Z": "0xb",
|
||||||
|
"ciphersuite": "BLS12381G1_XMD:SHA-256_SSWU_RO_",
|
||||||
|
"curve": "BLS12-381 G1",
|
||||||
|
"dst": "QUUX-V01-CS02-with-BLS12381G1_XMD:SHA-256_SSWU_RO_",
|
||||||
|
"expand": "XMD",
|
||||||
|
"field": {
|
||||||
|
"m": "0x1",
|
||||||
|
"p": "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab"
|
||||||
|
},
|
||||||
|
"hash": "sha256",
|
||||||
|
"k": "0x80",
|
||||||
|
"map": {
|
||||||
|
"name": "SSWU"
|
||||||
|
},
|
||||||
|
"randomOracle": true,
|
||||||
|
"vectors": [
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x052926add2207b76ca4fa57a8734416c8dc95e24501772c814278700eed6d1e4e8cf62d9c09db0fac349612b759e79a1",
|
||||||
|
"y": "0x08ba738453bfed09cb546dbb0783dbb3a5f1f566ed67bb6be0e8c67e2e81a4cc68ee29813bb7994998f3eae0c9c6a265"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x11a3cce7e1d90975990066b2f2643b9540fa40d6137780df4e753a8054d07580db3b7f1f03396333d4a359d1fe3766fe",
|
||||||
|
"y": "0x0eeaf6d794e479e270da10fdaf768db4c96b650a74518fc67b04b03927754bac66f3ac720404f339ecdcc028afa091b7"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x160003aaf1632b13396dbad518effa00fff532f604de1a7fc2082ff4cb0afa2d63b2c32da1bef2bf6c5ca62dc6b72f9c",
|
||||||
|
"y": "0x0d8bb2d14e20cf9f6036152ed386d79189415b6d015a20133acb4e019139b94e9c146aaad5817f866c95d609a361735e"
|
||||||
|
},
|
||||||
|
"msg": "",
|
||||||
|
"u": [
|
||||||
|
"0x0ba14bd907ad64a016293ee7c2d276b8eae71f25a4b941eece7b0d89f17f75cb3ae5438a614fb61d6835ad59f29c564f",
|
||||||
|
"0x019b9bd7979f12657976de2884c7cce192b82c177c80e0ec604436a7f538d231552f0d96d9f7babe5fa3b19b3ff25ac9"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x03567bc5ef9c690c2ab2ecdf6a96ef1c139cc0b2f284dca0a9a7943388a49a3aee664ba5379a7655d3c68900be2f6903",
|
||||||
|
"y": "0x0b9c15f3fe6e5cf4211f346271d7b01c8f3b28be689c8429c85b67af215533311f0b8dfaaa154fa6b88176c229f2885d"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x125435adce8e1cbd1c803e7123f45392dc6e326d292499c2c45c5865985fd74fe8f042ecdeeec5ecac80680d04317d80",
|
||||||
|
"y": "0x0e8828948c989126595ee30e4f7c931cbd6f4570735624fd25aef2fa41d3f79cfb4b4ee7b7e55a8ce013af2a5ba20bf2"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x11def93719829ecda3b46aa8c31fc3ac9c34b428982b898369608e4f042babee6c77ab9218aad5c87ba785481eff8ae4",
|
||||||
|
"y": "0x0007c9cef122ccf2efd233d6eb9bfc680aa276652b0661f4f820a653cec1db7ff69899f8e52b8e92b025a12c822a6ce6"
|
||||||
|
},
|
||||||
|
"msg": "abc",
|
||||||
|
"u": [
|
||||||
|
"0x0d921c33f2bad966478a03ca35d05719bdf92d347557ea166e5bba579eea9b83e9afa5c088573c2281410369fbd32951",
|
||||||
|
"0x003574a00b109ada2f26a37a91f9d1e740dffd8d69ec0c35e1e9f4652c7dba61123e9dd2e76c655d956e2b3462611139"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x11e0b079dea29a68f0383ee94fed1b940995272407e3bb916bbf268c263ddd57a6a27200a784cbc248e84f357ce82d98",
|
||||||
|
"y": "0x03a87ae2caf14e8ee52e51fa2ed8eefe80f02457004ba4d486d6aa1f517c0889501dc7413753f9599b099ebcbbd2d709"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x08834484878c217682f6d09a4b51444802fdba3d7f2df9903a0ddadb92130ebbfa807fffa0eabf257d7b48272410afff",
|
||||||
|
"y": "0x0b318f7ecf77f45a0f038e62d7098221d2dbbca2a394164e2e3fe953dc714ac2cde412d8f2d7f0c03b259e6795a2508e"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x158418ed6b27e2549f05531a8281b5822b31c3bf3144277fbb977f8d6e2694fedceb7011b3c2b192f23e2a44b2bd106e",
|
||||||
|
"y": "0x1879074f344471fac5f839e2b4920789643c075792bec5af4282c73f7941cda5aa77b00085eb10e206171b9787c4169f"
|
||||||
|
},
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"u": [
|
||||||
|
"0x062d1865eb80ebfa73dcfc45db1ad4266b9f3a93219976a3790ab8d52d3e5f1e62f3b01795e36834b17b70e7b76246d4",
|
||||||
|
"0x0cdc3e2f271f29c4ff75020857ce6c5d36008c9b48385ea2f2bf6f96f428a3deb798aa033cd482d1cdc8b30178b08e3a"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x15f68eaa693b95ccb85215dc65fa81038d69629f70aeee0d0f677cf22285e7bf58d7cb86eefe8f2e9bc3f8cb84fac488",
|
||||||
|
"y": "0x1807a1d50c29f430b8cafc4f8638dfeeadf51211e1602a5f184443076715f91bb90a48ba1e370edce6ae1062f5e6dd38"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x0cbd7f84ad2c99643fea7a7ac8f52d63d66cefa06d9a56148e58b984b3dd25e1f41ff47154543343949c64f88d48a710",
|
||||||
|
"y": "0x052c00e4ed52d000d94881a5638ae9274d3efc8bc77bc0e5c650de04a000b2c334a9e80b85282a00f3148dfdface0865"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x06493fb68f0d513af08be0372f849436a787e7b701ae31cb964d968021d6ba6bd7d26a38aaa5a68e8c21a6b17dc8b579",
|
||||||
|
"y": "0x02e98f2ccf5802b05ffaac7c20018bc0c0b2fd580216c4aa2275d2909dc0c92d0d0bdc979226adeb57a29933536b6bb4"
|
||||||
|
},
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"u": [
|
||||||
|
"0x010476f6a060453c0b1ad0b628f3e57c23039ee16eea5e71bb87c3b5419b1255dc0e5883322e563b84a29543823c0e86",
|
||||||
|
"0x0b1a912064fb0554b180e07af7e787f1f883a0470759c03c1b6509eb8ce980d1670305ae7b928226bb58fdc0a419f46e"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x082aabae8b7dedb0e78aeb619ad3bfd9277a2f77ba7fad20ef6aabdc6c31d19ba5a6d12283553294c1825c4b3ca2dcfe",
|
||||||
|
"y": "0x05b84ae5a942248eea39e1d91030458c40153f3b654ab7872d779ad1e942856a20c438e8d99bc8abfbf74729ce1f7ac8"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x0cf97e6dbd0947857f3e578231d07b309c622ade08f2c08b32ff372bd90db19467b2563cc997d4407968d4ac80e154f8",
|
||||||
|
"y": "0x127f0cddf2613058101a5701f4cb9d0861fd6c2a1b8e0afe194fccf586a3201a53874a2761a9ab6d7220c68661a35ab3"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x092f1acfa62b05f95884c6791fba989bbe58044ee6355d100973bf9553ade52b47929264e6ae770fb264582d8dce512a",
|
||||||
|
"y": "0x028e6d0169a72cfedb737be45db6c401d3adfb12c58c619c82b93a5dfcccef12290de530b0480575ddc8397cda0bbebf"
|
||||||
|
},
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"u": [
|
||||||
|
"0x0a8ffa7447f6be1c5a2ea4b959c9454b431e29ccc0802bc052413a9c5b4f9aac67a93431bd480d15be1e057c8a08e8c6",
|
||||||
|
"0x05d487032f602c90fa7625dbafe0f4a49ef4a6b0b33d7bb349ff4cf5410d297fd6241876e3e77b651cfc8191e40a68b7"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
90
test/hash-to-curve/BLS12381G2_XMD:SHA-256_SSWU_NU_.json
Normal file
90
test/hash-to-curve/BLS12381G2_XMD:SHA-256_SSWU_NU_.json
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
{
|
||||||
|
"L": "0x40",
|
||||||
|
"Z": "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaa9,0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa",
|
||||||
|
"ciphersuite": "BLS12381G2_XMD:SHA-256_SSWU_NU_",
|
||||||
|
"curve": "BLS12-381 G2",
|
||||||
|
"dst": "QUUX-V01-CS02-with-BLS12381G2_XMD:SHA-256_SSWU_NU_",
|
||||||
|
"expand": "XMD",
|
||||||
|
"field": {
|
||||||
|
"m": "0x2",
|
||||||
|
"p": "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab"
|
||||||
|
},
|
||||||
|
"hash": "sha256",
|
||||||
|
"k": "0x80",
|
||||||
|
"map": {
|
||||||
|
"name": "SSWU"
|
||||||
|
},
|
||||||
|
"randomOracle": false,
|
||||||
|
"vectors": [
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x00e7f4568a82b4b7dc1f14c6aaa055edf51502319c723c4dc2688c7fe5944c213f510328082396515734b6612c4e7bb7,0x126b855e9e69b1f691f816e48ac6977664d24d99f8724868a184186469ddfd4617367e94527d4b74fc86413483afb35b",
|
||||||
|
"y": "0x0caead0fd7b6176c01436833c79d305c78be307da5f6af6c133c47311def6ff1e0babf57a0fb5539fce7ee12407b0a42,0x1498aadcf7ae2b345243e281ae076df6de84455d766ab6fcdaad71fab60abb2e8b980a440043cd305db09d283c895e3d"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x18ed3794ad43c781816c523776188deafba67ab773189b8f18c49bc7aa841cd81525171f7a5203b2a340579192403bef,0x0727d90785d179e7b5732c8a34b660335fed03b913710b60903cf4954b651ed3466dc3728e21855ae822d4a0f1d06587",
|
||||||
|
"y": "0x00764a5cf6c5f61c52c838523460eb2168b5a5b43705e19cb612e006f29b717897facfd15dd1c8874c915f6d53d0342d,0x19290bb9797c12c1d275817aa2605ebe42275b66860f0e4d04487ebc2e47c50b36edd86c685a60c20a2bd584a82b011a"
|
||||||
|
},
|
||||||
|
"msg": "",
|
||||||
|
"u": [
|
||||||
|
"0x07355d25caf6e7f2f0cb2812ca0e513bd026ed09dda65b177500fa31714e09ea0ded3a078b526bed3307f804d4b93b04,0x02829ce3c021339ccb5caf3e187f6370e1e2a311dec9b75363117063ab2015603ff52c3d3b98f19c2f65575e99e8b78c"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x108ed59fd9fae381abfd1d6bce2fd2fa220990f0f837fa30e0f27914ed6e1454db0d1ee957b219f61da6ff8be0d6441f,0x0296238ea82c6d4adb3c838ee3cb2346049c90b96d602d7bb1b469b905c9228be25c627bffee872def773d5b2a2eb57d",
|
||||||
|
"y": "0x033f90f6057aadacae7963b0a0b379dd46750c1c94a6357c99b65f63b79e321ff50fe3053330911c56b6ceea08fee656,0x153606c417e59fb331b7ae6bce4fbf7c5190c33ce9402b5ebe2b70e44fca614f3f1382a3625ed5493843d0b0a652fc3f"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x0f40e1d5025ecef0d850aa0bb7bbeceab21a3d4e85e6bee857805b09693051f5b25428c6be343edba5f14317fcc30143,0x02e0d261f2b9fee88b82804ec83db330caa75fbb12719cfa71ccce1c532dc4e1e79b0a6a281ed8d3817524286c8bc04c",
|
||||||
|
"y": "0x0cf4a4adc5c66da0bca4caddc6a57ecd97c8252d7526a8ff478e0dfed816c4d321b5c3039c6683ae9b1e6a3a38c9c0ae,0x11cad1646bb3768c04be2ab2bbe1f80263b7ff6f8f9488f5bc3b6850e5a3e97e20acc583613c69cf3d2bfe8489744ebb"
|
||||||
|
},
|
||||||
|
"msg": "abc",
|
||||||
|
"u": [
|
||||||
|
"0x138879a9559e24cecee8697b8b4ad32cced053138ab913b99872772dc753a2967ed50aabc907937aefb2439ba06cc50c,0x0a1ae7999ea9bab1dcc9ef8887a6cb6e8f1e22566015428d220b7eec90ffa70ad1f624018a9ad11e78d588bd3617f9f2"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x038af300ef34c7759a6caaa4e69363cafeed218a1f207e93b2c70d91a1263d375d6730bd6b6509dcac3ba5b567e85bf3,0x0da75be60fb6aa0e9e3143e40c42796edf15685cafe0279afd2a67c3dff1c82341f17effd402e4f1af240ea90f4b659b",
|
||||||
|
"y": "0x19b148cbdf163cf0894f29660d2e7bfb2b68e37d54cc83fd4e6e62c020eaa48709302ef8e746736c0e19342cc1ce3df4,0x0492f4fed741b073e5a82580f7c663f9b79e036b70ab3e51162359cec4e77c78086fe879b65ca7a47d34374c8315ac5e"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x13a9d4a738a85c9f917c7be36b240915434b58679980010499b9ae8d7a1bf7fbe617a15b3cd6060093f40d18e0f19456,0x16fa88754e7670366a859d6f6899ad765bf5a177abedb2740aacc9252c43f90cd0421373fbd5b2b76bb8f5c4886b5d37",
|
||||||
|
"y": "0x0a7fa7d82c46797039398253e8765a4194100b330dfed6d7fbb46d6fbf01e222088779ac336e3675c7a7a0ee05bbb6e3,0x0c6ee170ab766d11fa9457cef53253f2628010b2cffc102b3b28351eb9df6c281d3cfc78e9934769d661b72a5265338d"
|
||||||
|
},
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"u": [
|
||||||
|
"0x18c16fe362b7dbdfa102e42bdfd3e2f4e6191d479437a59db4eb716986bf08ee1f42634db66bde97d6c16bbfd342b3b8,0x0e37812ce1b146d998d5f92bdd5ada2a31bfd63dfe18311aa91637b5f279dd045763166aa1615e46a50d8d8f475f184e"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x0c5ae723be00e6c3f0efe184fdc0702b64588fe77dda152ab13099a3bacd3876767fa7bbad6d6fd90b3642e902b208f9,0x12c8c05c1d5fc7bfa847f4d7d81e294e66b9a78bc9953990c358945e1f042eedafce608b67fdd3ab0cb2e6e263b9b1ad",
|
||||||
|
"y": "0x04e77ddb3ede41b5ec4396b7421dd916efc68a358a0d7425bddd253547f2fb4830522358491827265dfc5bcc1928a569,0x11c624c56dbe154d759d021eec60fab3d8b852395a89de497e48504366feedd4662d023af447d66926a28076813dd646"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x0a08b2f639855dfdeaaed972702b109e2241a54de198b2b4cd12ad9f88fa419a6086a58d91fc805de812ea29bee427c2,0x04a7442e4cb8b42ef0f41dac9ee74e65ecad3ce0851f0746dc47568b0e7a8134121ed09ba054509232c49148aef62cda",
|
||||||
|
"y": "0x05d60b1f04212b2c87607458f71d770f43973511c260f0540eef3a565f42c7ce59aa1cea684bb2a7bcab84acd2f36c8c,0x1017aa5747ba15505ece266a86b0ca9c712f41a254b76ca04094ca442ce45ecd224bd5544cd16685d0d1b9d156dd0531"
|
||||||
|
},
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"u": [
|
||||||
|
"0x08d4a0997b9d52fecf99427abb721f0fa779479963315fe21c6445250de7183e3f63bfdf86570da8929489e421d4ee95,0x16cb4ccad91ec95aab070f22043916cd6a59c4ca94097f7f510043d48515526dc8eaaea27e586f09151ae613688d5a89"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x0ea4e7c33d43e17cc516a72f76437c4bf81d8f4eac69ac355d3bf9b71b8138d55dc10fd458be115afa798b55dac34be1,0x1565c2f625032d232f13121d3cfb476f45275c303a037faa255f9da62000c2c864ea881e2bcddd111edc4a3c0da3e88d",
|
||||||
|
"y": "0x043b6f5fe4e52c839148dc66f2b3751e69a0f6ebb3d056d6465d50d4108543ecd956e10fa1640dfd9bc0030cc2558d28,0x0f8991d2a1ad662e7b6f58ab787947f1fa607fce12dde171bc17903b012091b657e15333e11701edcf5b63ba2a561247"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x19592c812d5a50c5601062faba14c7d670711745311c879de1235a0a11c75aab61327bf2d1725db07ec4d6996a682886,0x0eef4fa41ddc17ed47baf447a2c498548f3c72a02381313d13bef916e240b61ce125539090d62d9fbb14a900bf1b8e90",
|
||||||
|
"y": "0x1260d6e0987eae96af9ebe551e08de22b37791d53f4db9e0d59da736e66699735793e853e26362531fe4adf99c1883e3,0x0dbace5df0a4ac4ac2f45d8fdf8aee45484576fdd6efc4f98ab9b9f4112309e628255e183022d98ea5ed6e47ca00306c"
|
||||||
|
},
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"u": [
|
||||||
|
"0x03f80ce4ff0ca2f576d797a3660e3f65b274285c054feccc3215c879e2c0589d376e83ede13f93c32f05da0f68fd6a10,0x006488a837c5413746d868d1efb7232724da10eca410b07d8b505b9363bdccf0a1fc0029bad07d65b15ccfe6dd25e20d"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
115
test/hash-to-curve/BLS12381G2_XMD:SHA-256_SSWU_RO_.json
Normal file
115
test/hash-to-curve/BLS12381G2_XMD:SHA-256_SSWU_RO_.json
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
{
|
||||||
|
"L": "0x40",
|
||||||
|
"Z": "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaa9,0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa",
|
||||||
|
"ciphersuite": "BLS12381G2_XMD:SHA-256_SSWU_RO_",
|
||||||
|
"curve": "BLS12-381 G2",
|
||||||
|
"dst": "QUUX-V01-CS02-with-BLS12381G2_XMD:SHA-256_SSWU_RO_",
|
||||||
|
"expand": "XMD",
|
||||||
|
"field": {
|
||||||
|
"m": "0x2",
|
||||||
|
"p": "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab"
|
||||||
|
},
|
||||||
|
"hash": "sha256",
|
||||||
|
"k": "0x80",
|
||||||
|
"map": {
|
||||||
|
"name": "SSWU"
|
||||||
|
},
|
||||||
|
"randomOracle": true,
|
||||||
|
"vectors": [
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x0141ebfbdca40eb85b87142e130ab689c673cf60f1a3e98d69335266f30d9b8d4ac44c1038e9dcdd5393faf5c41fb78a,0x05cb8437535e20ecffaef7752baddf98034139c38452458baeefab379ba13dff5bf5dd71b72418717047f5b0f37da03d",
|
||||||
|
"y": "0x0503921d7f6a12805e72940b963c0cf3471c7b2a524950ca195d11062ee75ec076daf2d4bc358c4b190c0c98064fdd92,0x12424ac32561493f3fe3c260708a12b7c620e7be00099a974e259ddc7d1f6395c3c811cdd19f1e8dbf3e9ecfdcbab8d6"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x019ad3fc9c72425a998d7ab1ea0e646a1f6093444fc6965f1cad5a3195a7b1e099c050d57f45e3fa191cc6d75ed7458c,0x171c88b0b0efb5eb2b88913a9e74fe111a4f68867b59db252ce5868af4d1254bfab77ebde5d61cd1a86fb2fe4a5a1c1d",
|
||||||
|
"y": "0x0ba10604e62bdd9eeeb4156652066167b72c8d743b050fb4c1016c31b505129374f76e03fa127d6a156213576910fef3,0x0eb22c7a543d3d376e9716a49b72e79a89c9bfe9feee8533ed931cbb5373dde1fbcd7411d8052e02693654f71e15410a"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x113d2b9cd4bd98aee53470b27abc658d91b47a78a51584f3d4b950677cfb8a3e99c24222c406128c91296ef6b45608be,0x13855912321c5cb793e9d1e88f6f8d342d49c0b0dbac613ee9e17e3c0b3c97dfbb5a49cc3fb45102fdbaf65e0efe2632",
|
||||||
|
"y": "0x0fd3def0b7574a1d801be44fde617162aa2e89da47f464317d9bb5abc3a7071763ce74180883ad7ad9a723a9afafcdca,0x056f617902b3c0d0f78a9a8cbda43a26b65f602f8786540b9469b060db7b38417915b413ca65f875c130bebfaa59790c"
|
||||||
|
},
|
||||||
|
"msg": "",
|
||||||
|
"u": [
|
||||||
|
"0x03dbc2cce174e91ba93cbb08f26b917f98194a2ea08d1cce75b2b9cc9f21689d80bd79b594a613d0a68eb807dfdc1cf8,0x05a2acec64114845711a54199ea339abd125ba38253b70a92c876df10598bd1986b739cad67961eb94f7076511b3b39a",
|
||||||
|
"0x02f99798e8a5acdeed60d7e18e9120521ba1f47ec090984662846bc825de191b5b7641148c0dbc237726a334473eee94,0x145a81e418d4010cc027a68f14391b30074e89e60ee7a22f87217b2f6eb0c4b94c9115b436e6fa4607e95a98de30a435"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x02c2d18e033b960562aae3cab37a27ce00d80ccd5ba4b7fe0e7a210245129dbec7780ccc7954725f4168aff2787776e6,0x139cddbccdc5e91b9623efd38c49f81a6f83f175e80b06fc374de9eb4b41dfe4ca3a230ed250fbe3a2acf73a41177fd8",
|
||||||
|
"y": "0x1787327b68159716a37440985269cf584bcb1e621d3a7202be6ea05c4cfe244aeb197642555a0645fb87bf7466b2ba48,0x00aa65dae3c8d732d10ecd2c50f8a1baf3001578f71c694e03866e9f3d49ac1e1ce70dd94a733534f106d4cec0eddd16"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x12b2e525281b5f4d2276954e84ac4f42cf4e13b6ac4228624e17760faf94ce5706d53f0ca1952f1c5ef75239aeed55ad,0x05d8a724db78e570e34100c0bc4a5fa84ad5839359b40398151f37cff5a51de945c563463c9efbdda569850ee5a53e77",
|
||||||
|
"y": "0x02eacdc556d0bdb5d18d22f23dcb086dd106cad713777c7e6407943edbe0b3d1efe391eedf11e977fac55f9b94f2489c,0x04bbe48bfd5814648d0b9e30f0717b34015d45a861425fabc1ee06fdfce36384ae2c808185e693ae97dcde118f34de41"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x19f18cc5ec0c2f055e47c802acc3b0e40c337256a208001dde14b25afced146f37ea3d3ce16834c78175b3ed61f3c537,0x15b0dadc256a258b4c68ea43605dffa6d312eef215c19e6474b3e101d33b661dfee43b51abbf96fee68fc6043ac56a58",
|
||||||
|
"y": "0x05e47c1781286e61c7ade887512bd9c2cb9f640d3be9cf87ea0bad24bd0ebfe946497b48a581ab6c7d4ca74b5147287f,0x19f98db2f4a1fcdf56a9ced7b320ea9deecf57c8e59236b0dc21f6ee7229aa9705ce9ac7fe7a31c72edca0d92370c096"
|
||||||
|
},
|
||||||
|
"msg": "abc",
|
||||||
|
"u": [
|
||||||
|
"0x15f7c0aa8f6b296ab5ff9c2c7581ade64f4ee6f1bf18f55179ff44a2cf355fa53dd2a2158c5ecb17d7c52f63e7195771,0x01c8067bf4c0ba709aa8b9abc3d1cef589a4758e09ef53732d670fd8739a7274e111ba2fcaa71b3d33df2a3a0c8529dd",
|
||||||
|
"0x187111d5e088b6b9acfdfad078c4dacf72dcd17ca17c82be35e79f8c372a693f60a033b461d81b025864a0ad051a06e4,0x08b852331c96ed983e497ebc6dee9b75e373d923b729194af8e72a051ea586f3538a6ebb1e80881a082fa2b24df9f566"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x121982811d2491fde9ba7ed31ef9ca474f0e1501297f68c298e9f4c0028add35aea8bb83d53c08cfc007c1e005723cd0,0x190d119345b94fbd15497bcba94ecf7db2cbfd1e1fe7da034d26cbba169fb3968288b3fafb265f9ebd380512a71c3f2c",
|
||||||
|
"y": "0x05571a0f8d3c08d094576981f4a3b8eda0a8e771fcdcc8ecceaf1356a6acf17574518acb506e435b639353c2e14827c8,0x0bb5e7572275c567462d91807de765611490205a941a5a6af3b1691bfe596c31225d3aabdf15faff860cb4ef17c7c3be"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x0f48f1ea1318ddb713697708f7327781fb39718971d72a9245b9731faaca4dbaa7cca433d6c434a820c28b18e20ea208,0x06051467c8f85da5ba2540974758f7a1e0239a5981de441fdd87680a995649c211054869c50edbac1f3a86c561ba3162",
|
||||||
|
"y": "0x168b3d6df80069dbbedb714d41b32961ad064c227355e1ce5fac8e105de5e49d77f0c64867f3834848f152497eb76333,0x134e0e8331cee8cb12f9c2d0742714ed9eee78a84d634c9a95f6a7391b37125ed48bfc6e90bf3546e99930ff67cc97bc"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x004fd03968cd1c99a0dd84551f44c206c84dcbdb78076c5bfee24e89a92c8508b52b88b68a92258403cbe1ea2da3495f,0x1674338ea298281b636b2eb0fe593008d03171195fd6dcd4531e8a1ed1f02a72da238a17a635de307d7d24aa2d969a47",
|
||||||
|
"y": "0x0dc7fa13fff6b12558419e0a1e94bfc3cfaf67238009991c5f24ee94b632c3d09e27eca329989aee348a67b50d5e236c,0x169585e164c131103d85324f2d7747b23b91d66ae5d947c449c8194a347969fc6bbd967729768da485ba71868df8aed2"
|
||||||
|
},
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"u": [
|
||||||
|
"0x0313d9325081b415bfd4e5364efaef392ecf69b087496973b229303e1816d2080971470f7da112c4eb43053130b785e1,0x062f84cb21ed89406890c051a0e8b9cf6c575cf6e8e18ecf63ba86826b0ae02548d83b483b79e48512b82a6c0686df8f",
|
||||||
|
"0x1739123845406baa7be5c5dc74492051b6d42504de008c635f3535bb831d478a341420e67dcc7b46b2e8cba5379cca97,0x01897665d9cb5db16a27657760bbea7951f67ad68f8d55f7113f24ba6ddd82caef240a9bfa627972279974894701d975"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x19a84dd7248a1066f737cc34502ee5555bd3c19f2ecdb3c7d9e24dc65d4e25e50d83f0f77105e955d78f4762d33c17da,0x0934aba516a52d8ae479939a91998299c76d39cc0c035cd18813bec433f587e2d7a4fef038260eef0cef4d02aae3eb91",
|
||||||
|
"y": "0x14f81cd421617428bc3b9fe25afbb751d934a00493524bc4e065635b0555084dd54679df1536101b2c979c0152d09192,0x09bcccfa036b4847c9950780733633f13619994394c23ff0b32fa6b795844f4a0673e20282d07bc69641cee04f5e5662"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x09eccbc53df677f0e5814e3f86e41e146422834854a224bf5a83a50e4cc0a77bfc56718e8166ad180f53526ea9194b57,0x0c3633943f91daee715277bd644fba585168a72f96ded64fc5a384cce4ec884a4c3c30f08e09cd2129335dc8f67840ec",
|
||||||
|
"y": "0x0eb6186a0457d5b12d132902d4468bfeb7315d83320b6c32f1c875f344efcba979952b4aa418589cb01af712f98cc555,0x119e3cf167e69eb16c1c7830e8df88856d48be12e3ff0a40791a5cd2f7221311d4bf13b1847f371f467357b3f3c0b4c7"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x0eb3aabc1ddfce17ff18455fcc7167d15ce6b60ddc9eb9b59f8d40ab49420d35558686293d046fc1e42f864b7f60e381,0x198bdfb19d7441ebcca61e8ff774b29d17da16547d2c10c273227a635cacea3f16826322ae85717630f0867539b5ed8b",
|
||||||
|
"y": "0x0aaf1dee3adf3ed4c80e481c09b57ea4c705e1b8d25b897f0ceeec3990748716575f92abff22a1c8f4582aff7b872d52,0x0d058d9061ed27d4259848a06c96c5ca68921a5d269b078650c882cb3c2bd424a8702b7a6ee4e0ead9982baf6843e924"
|
||||||
|
},
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"u": [
|
||||||
|
"0x025820cefc7d06fd38de7d8e370e0da8a52498be9b53cba9927b2ef5c6de1e12e12f188bbc7bc923864883c57e49e253,0x034147b77ce337a52e5948f66db0bab47a8d038e712123bb381899b6ab5ad20f02805601e6104c29df18c254b8618c7b",
|
||||||
|
"0x0930315cae1f9a6017c3f0c8f2314baa130e1cf13f6532bff0a8a1790cd70af918088c3db94bda214e896e1543629795,0x10c4df2cacf67ea3cb3108b00d4cbd0b3968031ebc8eac4b1ebcefe84d6b715fde66bef0219951ece29d1facc8a520ef"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x01a6ba2f9a11fa5598b2d8ace0fbe0a0eacb65deceb476fbbcb64fd24557c2f4b18ecfc5663e54ae16a84f5ab7f62534,0x11fca2ff525572795a801eed17eb12785887c7b63fb77a42be46ce4a34131d71f7a73e95fee3f812aea3de78b4d01569",
|
||||||
|
"y": "0x0b6798718c8aed24bc19cb27f866f1c9effcdbf92397ad6448b5c9db90d2b9da6cbabf48adc1adf59a1a28344e79d57e,0x03a47f8e6d1763ba0cad63d6114c0accbef65707825a511b251a660a9b3994249ae4e63fac38b23da0c398689ee2ab52"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x17cadf8d04a1a170f8347d42856526a24cc466cb2ddfd506cff01191666b7f944e31244d662c904de5440516a2b09004,0x0d13ba91f2a8b0051cf3279ea0ee63a9f19bc9cb8bfcc7d78b3cbd8cc4fc43ba726774b28038213acf2b0095391c523e",
|
||||||
|
"y": "0x17ef19497d6d9246fa94d35575c0f8d06ee02f21a284dbeaa78768cb1e25abd564e3381de87bda26acd04f41181610c5,0x12c3c913ba4ed03c24f0721a81a6be7430f2971ffca8fd1729aafe496bb725807531b44b34b59b3ae5495e5a2dcbd5c8"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x16ec57b7fe04c71dfe34fb5ad84dbce5a2dbbd6ee085f1d8cd17f45e8868976fc3c51ad9eeda682c7869024d24579bfd,0x13103f7aace1ae1420d208a537f7d3a9679c287208026e4e3439ab8cd534c12856284d95e27f5e1f33eec2ce656533b0",
|
||||||
|
"y": "0x0958b2c4c2c10fcef5a6c59b9e92c4a67b0fae3e2e0f1b6b5edad9c940b8f3524ba9ebbc3f2ceb3cfe377655b3163bd7,0x0ccb594ed8bd14ca64ed9cb4e0aba221be540f25dd0d6ba15a4a4be5d67bcf35df7853b2d8dad3ba245f1ea3697f66aa"
|
||||||
|
},
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"u": [
|
||||||
|
"0x190b513da3e66fc9a3587b78c76d1d132b1152174d0b83e3c1114066392579a45824c5fa17649ab89299ddd4bda54935,0x12ab625b0fe0ebd1367fe9fac57bb1168891846039b4216b9d94007b674de2d79126870e88aeef54b2ec717a887dcf39",
|
||||||
|
"0x0e6a42010cf435fb5bacc156a585e1ea3294cc81d0ceb81924d95040298380b164f702275892cedd81b62de3aba3f6b5,0x117d9a0defc57a33ed208428cb84e54c85a6840e7648480ae428838989d25d97a0af8e3255be62b25c2a85630d2dddd8"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
90
test/hash-to-curve/P256_XMD:SHA-256_SSWU_NU_.json
Normal file
90
test/hash-to-curve/P256_XMD:SHA-256_SSWU_NU_.json
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
{
|
||||||
|
"L": "0x30",
|
||||||
|
"Z": "0xffffffff00000001000000000000000000000000fffffffffffffffffffffff5",
|
||||||
|
"ciphersuite": "P256_XMD:SHA-256_SSWU_NU_",
|
||||||
|
"curve": "NIST P-256",
|
||||||
|
"dst": "QUUX-V01-CS02-with-P256_XMD:SHA-256_SSWU_NU_",
|
||||||
|
"expand": "XMD",
|
||||||
|
"field": {
|
||||||
|
"m": "0x1",
|
||||||
|
"p": "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff"
|
||||||
|
},
|
||||||
|
"hash": "sha256",
|
||||||
|
"k": "0x80",
|
||||||
|
"map": {
|
||||||
|
"name": "SSWU"
|
||||||
|
},
|
||||||
|
"randomOracle": false,
|
||||||
|
"vectors": [
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0xf871caad25ea3b59c16cf87c1894902f7e7b2c822c3d3f73596c5ace8ddd14d1",
|
||||||
|
"y": "0x87b9ae23335bee057b99bac1e68588b18b5691af476234b8971bc4f011ddc99b"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0xf871caad25ea3b59c16cf87c1894902f7e7b2c822c3d3f73596c5ace8ddd14d1",
|
||||||
|
"y": "0x87b9ae23335bee057b99bac1e68588b18b5691af476234b8971bc4f011ddc99b"
|
||||||
|
},
|
||||||
|
"msg": "",
|
||||||
|
"u": [
|
||||||
|
"0xb22d487045f80e9edcb0ecc8d4bf77833e2bf1f3a54004d7df1d57f4802d311f"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0xfc3f5d734e8dce41ddac49f47dd2b8a57257522a865c124ed02b92b5237befa4",
|
||||||
|
"y": "0xfe4d197ecf5a62645b9690599e1d80e82c500b22ac705a0b421fac7b47157866"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0xfc3f5d734e8dce41ddac49f47dd2b8a57257522a865c124ed02b92b5237befa4",
|
||||||
|
"y": "0xfe4d197ecf5a62645b9690599e1d80e82c500b22ac705a0b421fac7b47157866"
|
||||||
|
},
|
||||||
|
"msg": "abc",
|
||||||
|
"u": [
|
||||||
|
"0xc7f96eadac763e176629b09ed0c11992225b3a5ae99479760601cbd69c221e58"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0xf164c6674a02207e414c257ce759d35eddc7f55be6d7f415e2cc177e5d8faa84",
|
||||||
|
"y": "0x3aa274881d30db70485368c0467e97da0e73c18c1d00f34775d012b6fcee7f97"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0xf164c6674a02207e414c257ce759d35eddc7f55be6d7f415e2cc177e5d8faa84",
|
||||||
|
"y": "0x3aa274881d30db70485368c0467e97da0e73c18c1d00f34775d012b6fcee7f97"
|
||||||
|
},
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"u": [
|
||||||
|
"0x314e8585fa92068b3ea2c3bab452d4257b38be1c097d58a21890456c2929614d"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x324532006312be4f162614076460315f7a54a6f85544da773dc659aca0311853",
|
||||||
|
"y": "0x8d8197374bcd52de2acfefc8a54fe2c8d8bebd2a39f16be9b710e4b1af6ef883"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x324532006312be4f162614076460315f7a54a6f85544da773dc659aca0311853",
|
||||||
|
"y": "0x8d8197374bcd52de2acfefc8a54fe2c8d8bebd2a39f16be9b710e4b1af6ef883"
|
||||||
|
},
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"u": [
|
||||||
|
"0x752d8eaa38cd785a799a31d63d99c2ae4261823b4a367b133b2c6627f48858ab"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x5c4bad52f81f39c8e8de1260e9a06d72b8b00a0829a8ea004a610b0691bea5d9",
|
||||||
|
"y": "0xc801e7c0782af1f74f24fc385a8555da0582032a3ce038de637ccdcb16f7ef7b"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x5c4bad52f81f39c8e8de1260e9a06d72b8b00a0829a8ea004a610b0691bea5d9",
|
||||||
|
"y": "0xc801e7c0782af1f74f24fc385a8555da0582032a3ce038de637ccdcb16f7ef7b"
|
||||||
|
},
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"u": [
|
||||||
|
"0x0e1527840b9df2dfbef966678ff167140f2b27c4dccd884c25014dce0e41dfa3"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
115
test/hash-to-curve/P256_XMD:SHA-256_SSWU_RO_.json
Normal file
115
test/hash-to-curve/P256_XMD:SHA-256_SSWU_RO_.json
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
{
|
||||||
|
"L": "0x30",
|
||||||
|
"Z": "0xffffffff00000001000000000000000000000000fffffffffffffffffffffff5",
|
||||||
|
"ciphersuite": "P256_XMD:SHA-256_SSWU_RO_",
|
||||||
|
"curve": "NIST P-256",
|
||||||
|
"dst": "QUUX-V01-CS02-with-P256_XMD:SHA-256_SSWU_RO_",
|
||||||
|
"expand": "XMD",
|
||||||
|
"field": {
|
||||||
|
"m": "0x1",
|
||||||
|
"p": "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff"
|
||||||
|
},
|
||||||
|
"hash": "sha256",
|
||||||
|
"k": "0x80",
|
||||||
|
"map": {
|
||||||
|
"name": "SSWU"
|
||||||
|
},
|
||||||
|
"randomOracle": true,
|
||||||
|
"vectors": [
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x2c15230b26dbc6fc9a37051158c95b79656e17a1a920b11394ca91c44247d3e4",
|
||||||
|
"y": "0x8a7a74985cc5c776cdfe4b1f19884970453912e9d31528c060be9ab5c43e8415"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0xab640a12220d3ff283510ff3f4b1953d09fad35795140b1c5d64f313967934d5",
|
||||||
|
"y": "0xdccb558863804a881d4fff3455716c836cef230e5209594ddd33d85c565b19b1"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x51cce63c50d972a6e51c61334f0f4875c9ac1cd2d3238412f84e31da7d980ef5",
|
||||||
|
"y": "0xb45d1a36d00ad90e5ec7840a60a4de411917fbe7c82c3949a6e699e5a1b66aac"
|
||||||
|
},
|
||||||
|
"msg": "",
|
||||||
|
"u": [
|
||||||
|
"0xad5342c66a6dd0ff080df1da0ea1c04b96e0330dd89406465eeba11582515009",
|
||||||
|
"0x8c0f1d43204bd6f6ea70ae8013070a1518b43873bcd850aafa0a9e220e2eea5a"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x0bb8b87485551aa43ed54f009230450b492fead5f1cc91658775dac4a3388a0f",
|
||||||
|
"y": "0x5c41b3d0731a27a7b14bc0bf0ccded2d8751f83493404c84a88e71ffd424212e"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x5219ad0ddef3cc49b714145e91b2f7de6ce0a7a7dc7406c7726c7e373c58cb48",
|
||||||
|
"y": "0x7950144e52d30acbec7b624c203b1996c99617d0b61c2442354301b191d93ecf"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x019b7cb4efcfeaf39f738fe638e31d375ad6837f58a852d032ff60c69ee3875f",
|
||||||
|
"y": "0x589a62d2b22357fed5449bc38065b760095ebe6aeac84b01156ee4252715446e"
|
||||||
|
},
|
||||||
|
"msg": "abc",
|
||||||
|
"u": [
|
||||||
|
"0xafe47f2ea2b10465cc26ac403194dfb68b7f5ee865cda61e9f3e07a537220af1",
|
||||||
|
"0x379a27833b0bfe6f7bdca08e1e83c760bf9a338ab335542704edcd69ce9e46e0"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x65038ac8f2b1def042a5df0b33b1f4eca6bff7cb0f9c6c1526811864e544ed80",
|
||||||
|
"y": "0xcad44d40a656e7aff4002a8de287abc8ae0482b5ae825822bb870d6df9b56ca3"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0xa17bdf2965eb88074bc01157e644ed409dac97cfcf0c61c998ed0fa45e79e4a2",
|
||||||
|
"y": "0x4f1bc80c70d411a3cc1d67aeae6e726f0f311639fee560c7f5a664554e3c9c2e"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x7da48bb67225c1a17d452c983798113f47e438e4202219dd0715f8419b274d66",
|
||||||
|
"y": "0xb765696b2913e36db3016c47edb99e24b1da30e761a8a3215dc0ec4d8f96e6f9"
|
||||||
|
},
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"u": [
|
||||||
|
"0x0fad9d125a9477d55cf9357105b0eb3a5c4259809bf87180aa01d651f53d312c",
|
||||||
|
"0xb68597377392cd3419d8fcc7d7660948c8403b19ea78bbca4b133c9d2196c0fb"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x4be61ee205094282ba8a2042bcb48d88dfbb609301c49aa8b078533dc65a0b5d",
|
||||||
|
"y": "0x98f8df449a072c4721d241a3b1236d3caccba603f916ca680f4539d2bfb3c29e"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0xc76aaa823aeadeb3f356909cb08f97eee46ecb157c1f56699b5efebddf0e6398",
|
||||||
|
"y": "0x776a6f45f528a0e8d289a4be12c4fab80762386ec644abf2bffb9b627e4352b1"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x418ac3d85a5ccc4ea8dec14f750a3a9ec8b85176c95a7022f391826794eb5a75",
|
||||||
|
"y": "0xfd6604f69e9d9d2b74b072d14ea13050db72c932815523305cb9e807cc900aff"
|
||||||
|
},
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"u": [
|
||||||
|
"0x3bbc30446f39a7befad080f4d5f32ed116b9534626993d2cc5033f6f8d805919",
|
||||||
|
"0x76bb02db019ca9d3c1e02f0c17f8baf617bbdae5c393a81d9ce11e3be1bf1d33"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x457ae2981f70ca85d8e24c308b14db22f3e3862c5ea0f652ca38b5e49cd64bc5",
|
||||||
|
"y": "0xecb9f0eadc9aeed232dabc53235368c1394c78de05dd96893eefa62b0f4757dc"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0xd88b989ee9d1295df413d4456c5c850b8b2fb0f5402cc5c4c7e815412e926db8",
|
||||||
|
"y": "0xbb4a1edeff506cf16def96afff41b16fc74f6dbd55c2210e5b8f011ba32f4f40"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0xa281e34e628f3a4d2a53fa87ff973537d68ad4fbc28d3be5e8d9f6a2571c5a4b",
|
||||||
|
"y": "0xf6ed88a7aab56a488100e6f1174fa9810b47db13e86be999644922961206e184"
|
||||||
|
},
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"u": [
|
||||||
|
"0x4ebc95a6e839b1ae3c63b847798e85cb3c12d3817ec6ebc10af6ee51adb29fec",
|
||||||
|
"0x4e21af88e22ea80156aff790750121035b3eefaa96b425a8716e0d20b4e269ee"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
90
test/hash-to-curve/P384_XMD:SHA-384_SSWU_NU_.json
Normal file
90
test/hash-to-curve/P384_XMD:SHA-384_SSWU_NU_.json
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
{
|
||||||
|
"L": "0x48",
|
||||||
|
"Z": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffff3",
|
||||||
|
"ciphersuite": "P384_XMD:SHA-384_SSWU_NU_",
|
||||||
|
"curve": "NIST P-384",
|
||||||
|
"dst": "QUUX-V01-CS02-with-P384_XMD:SHA-384_SSWU_NU_",
|
||||||
|
"expand": "XMD",
|
||||||
|
"field": {
|
||||||
|
"m": "0x1",
|
||||||
|
"p": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff"
|
||||||
|
},
|
||||||
|
"hash": "sha384",
|
||||||
|
"k": "0xc0",
|
||||||
|
"map": {
|
||||||
|
"name": "SSWU"
|
||||||
|
},
|
||||||
|
"randomOracle": false,
|
||||||
|
"vectors": [
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0xde5a893c83061b2d7ce6a0d8b049f0326f2ada4b966dc7e72927256b033ef61058029a3bfb13c1c7ececd6641881ae20",
|
||||||
|
"y": "0x63f46da6139785674da315c1947e06e9a0867f5608cf24724eb3793a1f5b3809ee28eb21a0c64be3be169afc6cdb38ca"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0xde5a893c83061b2d7ce6a0d8b049f0326f2ada4b966dc7e72927256b033ef61058029a3bfb13c1c7ececd6641881ae20",
|
||||||
|
"y": "0x63f46da6139785674da315c1947e06e9a0867f5608cf24724eb3793a1f5b3809ee28eb21a0c64be3be169afc6cdb38ca"
|
||||||
|
},
|
||||||
|
"msg": "",
|
||||||
|
"u": [
|
||||||
|
"0xbc7dc1b2cdc5d588a66de3276b0f24310d4aca4977efda7d6272e1be25187b001493d267dc53b56183c9e28282368e60"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x1f08108b87e703c86c872ab3eb198a19f2b708237ac4be53d7929fb4bd5194583f40d052f32df66afe5249c9915d139b",
|
||||||
|
"y": "0x1369dc8d5bf038032336b989994874a2270adadb67a7fcc32f0f8824bc5118613f0ac8de04a1041d90ff8a5ad555f96c"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x1f08108b87e703c86c872ab3eb198a19f2b708237ac4be53d7929fb4bd5194583f40d052f32df66afe5249c9915d139b",
|
||||||
|
"y": "0x1369dc8d5bf038032336b989994874a2270adadb67a7fcc32f0f8824bc5118613f0ac8de04a1041d90ff8a5ad555f96c"
|
||||||
|
},
|
||||||
|
"msg": "abc",
|
||||||
|
"u": [
|
||||||
|
"0x9de6cf41e6e41c03e4a7784ac5c885b4d1e49d6de390b3cdd5a1ac5dd8c40afb3dfd7bb2686923bab644134483fc1926"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x4dac31ec8a82ee3c02ba2d7c9fa431f1e59ffe65bf977b948c59e1d813c2d7963c7be81aa6db39e78ff315a10115c0d0",
|
||||||
|
"y": "0x845333cdb5702ad5c525e603f302904d6fc84879f0ef2ee2014a6b13edd39131bfd66f7bd7cdc2d9ccf778f0c8892c3f"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x4dac31ec8a82ee3c02ba2d7c9fa431f1e59ffe65bf977b948c59e1d813c2d7963c7be81aa6db39e78ff315a10115c0d0",
|
||||||
|
"y": "0x845333cdb5702ad5c525e603f302904d6fc84879f0ef2ee2014a6b13edd39131bfd66f7bd7cdc2d9ccf778f0c8892c3f"
|
||||||
|
},
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"u": [
|
||||||
|
"0x84e2d430a5e2543573e58e368af41821ca3ccc97baba7e9aab51a84543d5a0298638a22ceee6090d9d642921112af5b7"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x13c1f8c52a492183f7c28e379b0475486718a7e3ac1dfef39283b9ce5fb02b73f70c6c1f3dfe0c286b03e2af1af12d1d",
|
||||||
|
"y": "0x57e101887e73e40eab8963324ed16c177d55eb89f804ec9df06801579820420b5546b579008df2145fd770f584a1a54c"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x13c1f8c52a492183f7c28e379b0475486718a7e3ac1dfef39283b9ce5fb02b73f70c6c1f3dfe0c286b03e2af1af12d1d",
|
||||||
|
"y": "0x57e101887e73e40eab8963324ed16c177d55eb89f804ec9df06801579820420b5546b579008df2145fd770f584a1a54c"
|
||||||
|
},
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"u": [
|
||||||
|
"0x504e4d5a529333b9205acaa283107bd1bffde753898f7744161f7dd19ba57fbb6a64214a2e00ddd2613d76cd508ddb30"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0xaf129727a4207a8cb9e9dce656d88f79fce25edbcea350499d65e9bf1204537bdde73c7cefb752a6ed5ebcd44e183302",
|
||||||
|
"y": "0xce68a3d5e161b2e6a968e4ddaa9e51504ad1516ec170c7eef3ca6b5327943eca95d90b23b009ba45f58b72906f2a99e2"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0xaf129727a4207a8cb9e9dce656d88f79fce25edbcea350499d65e9bf1204537bdde73c7cefb752a6ed5ebcd44e183302",
|
||||||
|
"y": "0xce68a3d5e161b2e6a968e4ddaa9e51504ad1516ec170c7eef3ca6b5327943eca95d90b23b009ba45f58b72906f2a99e2"
|
||||||
|
},
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"u": [
|
||||||
|
"0x7b01ce9b8c5a60d9fbc202d6dde92822e46915d8c17e03fcb92ece1ed6074d01e149fc9236def40d673de903c1d4c166"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
115
test/hash-to-curve/P384_XMD:SHA-384_SSWU_RO_.json
Normal file
115
test/hash-to-curve/P384_XMD:SHA-384_SSWU_RO_.json
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
{
|
||||||
|
"L": "0x48",
|
||||||
|
"Z": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffff3",
|
||||||
|
"ciphersuite": "P384_XMD:SHA-384_SSWU_RO_",
|
||||||
|
"curve": "NIST P-384",
|
||||||
|
"dst": "QUUX-V01-CS02-with-P384_XMD:SHA-384_SSWU_RO_",
|
||||||
|
"expand": "XMD",
|
||||||
|
"field": {
|
||||||
|
"m": "0x1",
|
||||||
|
"p": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff"
|
||||||
|
},
|
||||||
|
"hash": "sha384",
|
||||||
|
"k": "0xc0",
|
||||||
|
"map": {
|
||||||
|
"name": "SSWU"
|
||||||
|
},
|
||||||
|
"randomOracle": true,
|
||||||
|
"vectors": [
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0xeb9fe1b4f4e14e7140803c1d99d0a93cd823d2b024040f9c067a8eca1f5a2eeac9ad604973527a356f3fa3aeff0e4d83",
|
||||||
|
"y": "0x0c21708cff382b7f4643c07b105c2eaec2cead93a917d825601e63c8f21f6abd9abc22c93c2bed6f235954b25048bb1a"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0xe4717e29eef38d862bee4902a7d21b44efb58c464e3e1f0d03894d94de310f8ffc6de86786dd3e15a1541b18d4eb2846",
|
||||||
|
"y": "0x6b95a6e639822312298a47526bb77d9cd7bcf76244c991c8cd70075e2ee6e8b9a135c4a37e3c0768c7ca871c0ceb53d4"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x509527cfc0750eedc53147e6d5f78596c8a3b7360e0608e2fab0563a1670d58d8ae107c9f04bcf90e89489ace5650efd",
|
||||||
|
"y": "0x33337b13cb35e173fdea4cb9e8cce915d836ff57803dbbeb7998aa49d17df2ff09b67031773039d09fbd9305a1566bc4"
|
||||||
|
},
|
||||||
|
"msg": "",
|
||||||
|
"u": [
|
||||||
|
"0x25c8d7dc1acd4ee617766693f7f8829396065d1b447eedb155871feffd9c6653279ac7e5c46edb7010a0e4ff64c9f3b4",
|
||||||
|
"0x59428be4ed69131df59a0c6a8e188d2d4ece3f1b2a3a02602962b47efa4d7905945b1e2cc80b36aa35c99451073521ac"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0xe02fc1a5f44a7519419dd314e29863f30df55a514da2d655775a81d413003c4d4e7fd59af0826dfaad4200ac6f60abe1",
|
||||||
|
"y": "0x01f638d04d98677d65bef99aef1a12a70a4cbb9270ec55248c04530d8bc1f8f90f8a6a859a7c1f1ddccedf8f96d675f6"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0xfc853b69437aee9a19d5acf96a4ee4c5e04cf7b53406dfaa2afbdd7ad2351b7f554e4bbc6f5db4177d4d44f933a8f6ee",
|
||||||
|
"y": "0x7e042547e01834c9043b10f3a8221c4a879cb156f04f72bfccab0c047a304e30f2aa8b2e260d34c4592c0c33dd0c6482"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x57912293709b3556b43a2dfb137a315d256d573b82ded120ef8c782d607c05d930d958e50cb6dc1cc480b9afc38c45f1",
|
||||||
|
"y": "0xde9387dab0eef0bda219c6f168a92645a84665c4f2137c14270fb424b7532ff84843c3da383ceea24c47fa343c227bb8"
|
||||||
|
},
|
||||||
|
"msg": "abc",
|
||||||
|
"u": [
|
||||||
|
"0x53350214cb6bef0b51abb791b1c4209a2b4c16a0c67e1ab1401017fad774cd3b3f9a8bcdf7f6229dd8dd5a075cb149a0",
|
||||||
|
"0xc0473083898f63e03f26f14877a2407bd60c75ad491e7d26cbc6cc5ce815654075ec6b6898c7a41d74ceaf720a10c02e"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0xbdecc1c1d870624965f19505be50459d363c71a699a496ab672f9a5d6b78676400926fbceee6fcd1780fe86e62b2aa89",
|
||||||
|
"y": "0x57cf1f99b5ee00f3c201139b3bfe4dd30a653193778d89a0accc5e0f47e46e4e4b85a0595da29c9494c1814acafe183c"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x0ceece45b73f89844671df962ad2932122e878ad2259e650626924e4e7f132589341dec1480ebcbbbe3509d11fb570b7",
|
||||||
|
"y": "0xfafd71a3115298f6be4ae5c6dfc96c400cfb55760f185b7b03f3fa45f3f91eb65d27628b3c705cafd0466fafa54883ce"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0xdea1be8d3f9be4cbf4fab9d71d549dde76875b5d9b876832313a083ec81e528cbc2a0a1d0596b3bcb0ba77866b129776",
|
||||||
|
"y": "0xeb15fe71662214fb03b65541f40d3eb0f4cf5c3b559f647da138c9f9b7484c48a08760e02c16f1992762cb7298fa52cf"
|
||||||
|
},
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"u": [
|
||||||
|
"0xaab7fb87238cf6b2ab56cdcca7e028959bb2ea599d34f68484139dde85ec6548a6e48771d17956421bdb7790598ea52e",
|
||||||
|
"0x26e8d833552d7844d167833ca5a87c35bcfaa5a0d86023479fb28e5cd6075c18b168bf1f5d2a0ea146d057971336d8d1"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x03c3a9f401b78c6c36a52f07eeee0ec1289f178adf78448f43a3850e0456f5dd7f7633dd31676d990eda32882ab486c0",
|
||||||
|
"y": "0xcc183d0d7bdfd0a3af05f50e16a3f2de4abbc523215bf57c848d5ea662482b8c1f43dc453a93b94a8026db58f3f5d878"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x051a22105e0817a35d66196338c8d85bd52690d79bba373ead8a86dd9899411513bb9f75273f6483395a7847fb21edb4",
|
||||||
|
"y": "0xf168295c1bbcff5f8b01248e9dbc885335d6d6a04aea960f7384f746ba6502ce477e624151cc1d1392b00df0f5400c06"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x6ad7bc8ed8b841efd8ad0765c8a23d0b968ec9aa360a558ff33500f164faa02bee6c704f5f91507c4c5aad2b0dc5b943",
|
||||||
|
"y": "0x47313cc0a873ade774048338fc34ca5313f96bbf6ae22ac6ef475d85f03d24792dc6afba8d0b4a70170c1b4f0f716629"
|
||||||
|
},
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"u": [
|
||||||
|
"0x04c00051b0de6e726d228c85bf243bf5f4789efb512b22b498cde3821db9da667199b74bd5a09a79583c6d353a3bb41c",
|
||||||
|
"0x97580f218255f899f9204db64cd15e6a312cb4d8182375d1e5157c8f80f41d6a1a4b77fb1ded9dce56c32058b8d5202b"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x7b18d210b1f090ac701f65f606f6ca18fb8d081e3bc6cbd937c5604325f1cdea4c15c10a54ef303aabf2ea58bd9947a4",
|
||||||
|
"y": "0xea857285a33abb516732915c353c75c576bf82ccc96adb63c094dde580021eddeafd91f8c0bfee6f636528f3d0c47fd2"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x42e6666f505e854187186bad3011598d9278b9d6e3e4d2503c3d236381a56748dec5d139c223129b324df53fa147c4df",
|
||||||
|
"y": "0x8ee51dbda46413bf621838cc935d18d617881c6f33f3838a79c767a1e5618e34b22f79142df708d2432f75c7366c8512"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x4ff01ceeba60484fa1bc0d825fe1e5e383d8f79f1e5bb78e5fb26b7a7ef758153e31e78b9d60ce75c5e32e43869d4e12",
|
||||||
|
"y": "0x0f84b978fac8ceda7304b47e229d6037d32062e597dc7a9b95bcd9af441f3c56c619a901d21635f9ec6ab4710b9fcd0e"
|
||||||
|
},
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"u": [
|
||||||
|
"0x480cb3ac2c389db7f9dac9c396d2647ae946db844598971c26d1afd53912a1491199c0a5902811e4b809c26fcd37a014",
|
||||||
|
"0xd28435eb34680e148bf3908536e42231cba9e1f73ae2c6902a222a89db5c49c97db2f8fa4d4cd6e424b17ac60bdb9bb6"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
90
test/hash-to-curve/P521_XMD:SHA-512_SSWU_NU_.json
Normal file
90
test/hash-to-curve/P521_XMD:SHA-512_SSWU_NU_.json
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
{
|
||||||
|
"L": "0x62",
|
||||||
|
"Z": "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb",
|
||||||
|
"ciphersuite": "P521_XMD:SHA-512_SSWU_NU_",
|
||||||
|
"curve": "NIST P-521",
|
||||||
|
"dst": "QUUX-V01-CS02-with-P521_XMD:SHA-512_SSWU_NU_",
|
||||||
|
"expand": "XMD",
|
||||||
|
"field": {
|
||||||
|
"m": "0x1",
|
||||||
|
"p": "0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||||
|
},
|
||||||
|
"hash": "sha512",
|
||||||
|
"k": "0x100",
|
||||||
|
"map": {
|
||||||
|
"name": "SSWU"
|
||||||
|
},
|
||||||
|
"randomOracle": false,
|
||||||
|
"vectors": [
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x01ec604b4e1e3e4c7449b7a41e366e876655538acf51fd40d08b97be066f7d020634e906b1b6942f9174b417027c953d75fb6ec64b8cee2a3672d4f1987d13974705",
|
||||||
|
"y": "0x00944fc439b4aad2463e5c9cfa0b0707af3c9a42e37c5a57bb4ecd12fef9fb21508568aedcdd8d2490472df4bbafd79081c81e99f4da3286eddf19be47e9c4cf0e91"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x01ec604b4e1e3e4c7449b7a41e366e876655538acf51fd40d08b97be066f7d020634e906b1b6942f9174b417027c953d75fb6ec64b8cee2a3672d4f1987d13974705",
|
||||||
|
"y": "0x00944fc439b4aad2463e5c9cfa0b0707af3c9a42e37c5a57bb4ecd12fef9fb21508568aedcdd8d2490472df4bbafd79081c81e99f4da3286eddf19be47e9c4cf0e91"
|
||||||
|
},
|
||||||
|
"msg": "",
|
||||||
|
"u": [
|
||||||
|
"0x01e4947fe62a4e47792cee2798912f672fff820b2556282d9843b4b465940d7683a986f93ccb0e9a191fbc09a6e770a564490d2a4ae51b287ca39f69c3d910ba6a4f"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x00c720ab56aa5a7a4c07a7732a0a4e1b909e32d063ae1b58db5f0eb5e09f08a9884bff55a2bef4668f715788e692c18c1915cd034a6b998311fcf46924ce66a2be9a",
|
||||||
|
"y": "0x003570e87f91a4f3c7a56be2cb2a078ffc153862a53d5e03e5dad5bccc6c529b8bab0b7dbb157499e1949e4edab21cf5d10b782bc1e945e13d7421ad8121dbc72b1d"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x00c720ab56aa5a7a4c07a7732a0a4e1b909e32d063ae1b58db5f0eb5e09f08a9884bff55a2bef4668f715788e692c18c1915cd034a6b998311fcf46924ce66a2be9a",
|
||||||
|
"y": "0x003570e87f91a4f3c7a56be2cb2a078ffc153862a53d5e03e5dad5bccc6c529b8bab0b7dbb157499e1949e4edab21cf5d10b782bc1e945e13d7421ad8121dbc72b1d"
|
||||||
|
},
|
||||||
|
"msg": "abc",
|
||||||
|
"u": [
|
||||||
|
"0x0019b85ef78596efc84783d42799e80d787591fe7432dee1d9fa2b7651891321be732ddf653fa8fefa34d86fb728db569d36b5b6ed3983945854b2fc2dc6a75aa25b"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x00bcaf32a968ff7971b3bbd9ce8edfbee1309e2019d7ff373c38387a782b005dce6ceffccfeda5c6511c8f7f312f343f3a891029c5858f45ee0bf370aba25fc990cc",
|
||||||
|
"y": "0x00923517e767532d82cb8a0b59705eec2b7779ce05f9181c7d5d5e25694ef8ebd4696343f0bc27006834d2517215ecf79482a84111f50c1bae25044fe1dd77744bbd"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x00bcaf32a968ff7971b3bbd9ce8edfbee1309e2019d7ff373c38387a782b005dce6ceffccfeda5c6511c8f7f312f343f3a891029c5858f45ee0bf370aba25fc990cc",
|
||||||
|
"y": "0x00923517e767532d82cb8a0b59705eec2b7779ce05f9181c7d5d5e25694ef8ebd4696343f0bc27006834d2517215ecf79482a84111f50c1bae25044fe1dd77744bbd"
|
||||||
|
},
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"u": [
|
||||||
|
"0x01dba0d7fa26a562ee8a9014ebc2cca4d66fd9de036176aca8fc11ef254cd1bc208847ab7701dbca7af328b3f601b11a1737a899575a5c14f4dca5aaca45e9935e07"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x001ac69014869b6c4ad7aa8c443c255439d36b0e48a0f57b03d6fe9c40a66b4e2eaed2a93390679a5cc44b3a91862b34b673f0e92c83187da02bf3db967d867ce748",
|
||||||
|
"y": "0x00d5603d530e4d62b30fccfa1d90c2206654d74291c1db1c25b86a051ee3fffc294e5d56f2e776853406bd09206c63d40f37ad8829524cf89ad70b5d6e0b4a3b7341"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x001ac69014869b6c4ad7aa8c443c255439d36b0e48a0f57b03d6fe9c40a66b4e2eaed2a93390679a5cc44b3a91862b34b673f0e92c83187da02bf3db967d867ce748",
|
||||||
|
"y": "0x00d5603d530e4d62b30fccfa1d90c2206654d74291c1db1c25b86a051ee3fffc294e5d56f2e776853406bd09206c63d40f37ad8829524cf89ad70b5d6e0b4a3b7341"
|
||||||
|
},
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"u": [
|
||||||
|
"0x00844da980675e1244cb209dcf3ea0aabec23bd54b2cda69fff86eb3acc318bf3d01bae96e9cd6f4c5ceb5539df9a7ad7fcc5e9d54696081ba9782f3a0f6d14987e3"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x01801de044c517a80443d2bd4f503a9e6866750d2f94a22970f62d721f96e4310e4a828206d9cdeaa8f2d476705cc3bbc490a6165c687668f15ec178a17e3d27349b",
|
||||||
|
"y": "0x0068889ea2e1442245fe42bfda9e58266828c0263119f35a61631a3358330f3bb84443fcb54fcd53a1d097fccbe310489b74ee143fc2938959a83a1f7dd4a6fd395b"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x01801de044c517a80443d2bd4f503a9e6866750d2f94a22970f62d721f96e4310e4a828206d9cdeaa8f2d476705cc3bbc490a6165c687668f15ec178a17e3d27349b",
|
||||||
|
"y": "0x0068889ea2e1442245fe42bfda9e58266828c0263119f35a61631a3358330f3bb84443fcb54fcd53a1d097fccbe310489b74ee143fc2938959a83a1f7dd4a6fd395b"
|
||||||
|
},
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"u": [
|
||||||
|
"0x01aab1fb7e5cd44ba4d9f32353a383cb1bb9eb763ed40b32bdd5f666988970205998c0e44af6e2b5f6f8e48e969b3f649cae3c6ab463e1b274d968d91c02f00cce91"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
115
test/hash-to-curve/P521_XMD:SHA-512_SSWU_RO_.json
Normal file
115
test/hash-to-curve/P521_XMD:SHA-512_SSWU_RO_.json
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
{
|
||||||
|
"L": "0x62",
|
||||||
|
"Z": "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb",
|
||||||
|
"ciphersuite": "P521_XMD:SHA-512_SSWU_RO_",
|
||||||
|
"curve": "NIST P-521",
|
||||||
|
"dst": "QUUX-V01-CS02-with-P521_XMD:SHA-512_SSWU_RO_",
|
||||||
|
"expand": "XMD",
|
||||||
|
"field": {
|
||||||
|
"m": "0x1",
|
||||||
|
"p": "0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||||
|
},
|
||||||
|
"hash": "sha512",
|
||||||
|
"k": "0x100",
|
||||||
|
"map": {
|
||||||
|
"name": "SSWU"
|
||||||
|
},
|
||||||
|
"randomOracle": true,
|
||||||
|
"vectors": [
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x00fd767cebb2452030358d0e9cf907f525f50920c8f607889a6a35680727f64f4d66b161fafeb2654bea0d35086bec0a10b30b14adef3556ed9f7f1bc23cecc9c088",
|
||||||
|
"y": "0x0169ba78d8d851e930680322596e39c78f4fe31b97e57629ef6460ddd68f8763fd7bd767a4e94a80d3d21a3c2ee98347e024fc73ee1c27166dc3fe5eeef782be411d"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x00b70ae99b6339fffac19cb9bfde2098b84f75e50ac1e80d6acb954e4534af5f0e9c4a5b8a9c10317b8e6421574bae2b133b4f2b8c6ce4b3063da1d91d34fa2b3a3c",
|
||||||
|
"y": "0x007f368d98a4ddbf381fb354de40e44b19e43bb11a1278759f4ea7b485e1b6db33e750507c071250e3e443c1aaed61f2c28541bb54b1b456843eda1eb15ec2a9b36e"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x01143d0e9cddcdacd6a9aafe1bcf8d218c0afc45d4451239e821f5d2a56df92be942660b532b2aa59a9c635ae6b30e803c45a6ac871432452e685d661cd41cf67214",
|
||||||
|
"y": "0x00ff75515df265e996d702a5380defffab1a6d2bc232234c7bcffa433cd8aa791fbc8dcf667f08818bffa739ae25773b32073213cae9a0f2a917a0b1301a242dda0c"
|
||||||
|
},
|
||||||
|
"msg": "",
|
||||||
|
"u": [
|
||||||
|
"0x01e5f09974e5724f25286763f00ce76238c7a6e03dc396600350ee2c4135fb17dc555be99a4a4bae0fd303d4f66d984ed7b6a3ba386093752a855d26d559d69e7e9e",
|
||||||
|
"0x00ae593b42ca2ef93ac488e9e09a5fe5a2f6fb330d18913734ff602f2a761fcaaf5f596e790bcc572c9140ec03f6cccc38f767f1c1975a0b4d70b392d95a0c7278aa"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x002f89a1677b28054b50d15e1f81ed6669b5a2158211118ebdef8a6efc77f8ccaa528f698214e4340155abc1fa08f8f613ef14a043717503d57e267d57155cf784a4",
|
||||||
|
"y": "0x010e0be5dc8e753da8ce51091908b72396d3deed14ae166f66d8ebf0a4e7059ead169ea4bead0232e9b700dd380b316e9361cfdba55a08c73545563a80966ecbb86d"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x01b254e1c99c835836f0aceebba7d77750c48366ecb07fb658e4f5b76e229ae6ca5d271bb0006ffcc42324e15a6d3daae587f9049de2dbb0494378ffb60279406f56",
|
||||||
|
"y": "0x01845f4af72fc2b1a5a2fe966f6a97298614288b456cfc385a425b686048b25c952fbb5674057e1eb055d04568c0679a8e2dda3158dc16ac598dbb1d006f5ad915b0"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x007f08e813c620e527c961b717ffc74aac7afccb9158cebc347d5715d5c2214f952c97e194f11d114d80d3481ed766ac0a3dba3eb73f6ff9ccb9304ad10bbd7b4a36",
|
||||||
|
"y": "0x0022468f92041f9970a7cc025d71d5b647f822784d29ca7b3bc3b0829d6bb8581e745f8d0cc9dc6279d0450e779ac2275c4c3608064ad6779108a7828ebd9954caeb"
|
||||||
|
},
|
||||||
|
"msg": "abc",
|
||||||
|
"u": [
|
||||||
|
"0x003d00c37e95f19f358adeeaa47288ec39998039c3256e13c2a4c00a7cb61a34c8969472960150a27276f2390eb5e53e47ab193351c2d2d9f164a85c6a5696d94fe8",
|
||||||
|
"0x01f3cbd3df3893a45a2f1fecdac4d525eb16f345b03e2820d69bc580f5cbe9cb89196fdf720ef933c4c0361fcfe29940fd0db0a5da6bafb0bee8876b589c41365f15"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x006e200e276a4a81760099677814d7f8794a4a5f3658442de63c18d2244dcc957c645e94cb0754f95fcf103b2aeaf94411847c24187b89fb7462ad3679066337cbc4",
|
||||||
|
"y": "0x001dd8dfa9775b60b1614f6f169089d8140d4b3e4012949b52f98db2deff3e1d97bf73a1fa4d437d1dcdf39b6360cc518d8ebcc0f899018206fded7617b654f6b168"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x0021482e8622aac14da60e656043f79a6a110cbae5012268a62dd6a152c41594549f373910ebed170ade892dd5a19f5d687fae7095a461d583f8c4295f7aaf8cd7da",
|
||||||
|
"y": "0x0177e2d8c6356b7de06e0b5712d8387d529b848748e54a8bc0ef5f1475aa569f8f492fa85c3ad1c5edc51faf7911f11359bfa2a12d2ef0bd73df9cb5abd1b101c8b1"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x00abeafb16fdbb5eb95095678d5a65c1f293291dfd20a3751dbe05d0a9bfe2d2eef19449fe59ec32cdd4a4adc3411177c0f2dffd0159438706159a1bbd0567d9b3d0",
|
||||||
|
"y": "0x007cc657f847db9db651d91c801741060d63dab4056d0a1d3524e2eb0e819954d8f677aa353bd056244a88f00017e00c3ce8beeedb4382d83d74418bd48930c6c182"
|
||||||
|
},
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"u": [
|
||||||
|
"0x00183ee1a9bbdc37181b09ec336bcaa34095f91ef14b66b1485c166720523dfb81d5c470d44afcb52a87b704dbc5c9bc9d0ef524dec29884a4795f55c1359945baf3",
|
||||||
|
"0x00504064fd137f06c81a7cf0f84aa7e92b6b3d56c2368f0a08f44776aa8930480da1582d01d7f52df31dca35ee0a7876500ece3d8fe0293cd285f790c9881c998d5e"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x01b264a630bd6555be537b000b99a06761a9325c53322b65bdc41bf196711f9708d58d34b3b90faf12640c27b91c70a507998e55940648caa8e71098bf2bc8d24664",
|
||||||
|
"y": "0x01ea9f445bee198b3ee4c812dcf7b0f91e0881f0251aab272a12201fd89b1a95733fd2a699c162b639e9acdcc54fdc2f6536129b6beb0432be01aa8da02df5e59aaa"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x0005eac7b0b81e38727efcab1e375f6779aea949c3e409b53a1d37aa2acbac87a7e6ad24aafbf3c52f82f7f0e21b872e88c55e17b7fa21ce08a94ea2121c42c2eb73",
|
||||||
|
"y": "0x00a173b6a53a7420dbd61d4a21a7c0a52de7a5c6ce05f31403bef747d16cc8604a039a73bdd6e114340e55dacd6bea8e217ffbadfb8c292afa3e1b2afc839a6ce7bb"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x01881e3c193a69e4d88d8180a6879b74782a0bc7e529233e9f84bf7f17d2f319c36920ffba26f9e57a1e045cc7822c834c239593b6e142a694aa00c757b0db79e5e8",
|
||||||
|
"y": "0x01558b16d396d866e476e001f2dd0758927655450b84e12f154032c7c2a6db837942cd9f44b814f79b4d729996ced61eec61d85c675139cbffe3fbf071d2c21cfecb"
|
||||||
|
},
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"u": [
|
||||||
|
"0x0159871e222689aad7694dc4c3480a49807b1eedd9c8cb4ae1b219d5ba51655ea5b38e2e4f56b36bf3e3da44a7b139849d28f598c816fe1bc7ed15893b22f63363c3",
|
||||||
|
"0x004ef0cffd475152f3858c0a8ccbdf7902d8261da92744e98df9b7fadb0a5502f29c5086e76e2cf498f47321434a40b1504911552ce44ad7356a04e08729ad9411f5"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x00c12bc3e28db07b6b4d2a2b1167ab9e26fc2fa85c7b0498a17b0347edf52392856d7e28b8fa7a2dd004611159505835b687ecf1a764857e27e9745848c436ef3925",
|
||||||
|
"y": "0x01cd287df9a50c22a9231beb452346720bb163344a41c5f5a24e8335b6ccc595fd436aea89737b1281aecb411eb835f0b939073fdd1dd4d5a2492e91ef4a3c55bcbd"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x00041f6eb92af8777260718e4c22328a7d74203350c6c8f5794d99d5789766698f459b83d5068276716f01429934e40af3d1111a22780b1e07e72238d2207e5386be",
|
||||||
|
"y": "0x001c712f0182813942b87cab8e72337db017126f52ed797dd234584ac9ae7e80dfe7abea11db02cf1855312eae1447dbaecc9d7e8c880a5e76a39f6258074e1bc2e0"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x0125c0b69bcf55eab49280b14f707883405028e05c927cd7625d4e04115bd0e0e6323b12f5d43d0d6d2eff16dbcf244542f84ec058911260dc3bb6512ab5db285fbd",
|
||||||
|
"y": "0x008bddfb803b3f4c761458eb5f8a0aee3e1f7f68e9d7424405fa69172919899317fb6ac1d6903a432d967d14e0f80af63e7035aaae0c123e56862ce969456f99f102"
|
||||||
|
},
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"u": [
|
||||||
|
"0x0033d06d17bc3b9a3efc081a05d65805a14a3050a0dd4dfb4884618eb5c73980a59c5a246b18f58ad022dd3630faa22889fbb8ba1593466515e6ab4aeb7381c26334",
|
||||||
|
"0x0092290ab99c3fea1a5b8fb2ca49f859994a04faee3301cefab312d34227f6a2d0c3322cf76861c6a3683bdaa2dd2a6daa5d6906c663e065338b2344d20e313f1114"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
90
test/hash-to-curve/curve25519_XMD:SHA-512_ELL2_NU_.json
Normal file
90
test/hash-to-curve/curve25519_XMD:SHA-512_ELL2_NU_.json
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
{
|
||||||
|
"L": "0x30",
|
||||||
|
"Z": "0x2",
|
||||||
|
"ciphersuite": "curve25519_XMD:SHA-512_ELL2_NU_",
|
||||||
|
"curve": "curve25519",
|
||||||
|
"dst": "QUUX-V01-CS02-with-curve25519_XMD:SHA-512_ELL2_NU_",
|
||||||
|
"expand": "XMD",
|
||||||
|
"field": {
|
||||||
|
"m": "0x1",
|
||||||
|
"p": "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed"
|
||||||
|
},
|
||||||
|
"hash": "sha512",
|
||||||
|
"k": "0x80",
|
||||||
|
"map": {
|
||||||
|
"name": "ELL2"
|
||||||
|
},
|
||||||
|
"randomOracle": false,
|
||||||
|
"vectors": [
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x1bb913f0c9daefa0b3375378ffa534bda5526c97391952a7789eb976edfe4d08",
|
||||||
|
"y": "0x4548368f4f983243e747b62a600840ae7c1dab5c723991f85d3a9768479f3ec4"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x51125222da5e763d97f3c10fcc92ea6860b9ccbbd2eb1285728f566721c1e65b",
|
||||||
|
"y": "0x343d2204f812d3dfc5304a5808c6c0d81a903a5d228b342442aa3c9ba5520a3d"
|
||||||
|
},
|
||||||
|
"msg": "",
|
||||||
|
"u": [
|
||||||
|
"0x608d892b641f0328523802a6603427c26e55e6f27e71a91a478148d45b5093cd"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x7c22950b7d900fa866334262fcaea47a441a578df43b894b4625c9b450f9a026",
|
||||||
|
"y": "0x5547bc00e4c09685dcbc6cb6765288b386d8bdcb595fa5a6e3969e08097f0541"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x7d56d1e08cb0ccb92baf069c18c49bb5a0dcd927eff8dcf75ca921ef7f3e6eeb",
|
||||||
|
"y": "0x404d9a7dc25c9c05c44ab9a94590e7c3fe2dcec74533a0b24b188a5d5dacf429"
|
||||||
|
},
|
||||||
|
"msg": "abc",
|
||||||
|
"u": [
|
||||||
|
"0x46f5b22494bfeaa7f232cc8d054be68561af50230234d7d1d63d1d9abeca8da5"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x31ad08a8b0deeb2a4d8b0206ca25f567ab4e042746f792f4b7973f3ae2096c52",
|
||||||
|
"y": "0x405070c28e78b4fa269427c82827261991b9718bd6c6e95d627d701a53c30db1"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x3fbe66b9c9883d79e8407150e7c2a1c8680bee496c62fabe4619a72b3cabe90f",
|
||||||
|
"y": "0x08ec476147c9a0a3ff312d303dbbd076abb7551e5fce82b48ab14b433f8d0a7b"
|
||||||
|
},
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"u": [
|
||||||
|
"0x235fe40c443766ce7e18111c33862d66c3b33267efa50d50f9e8e5d252a40aaa"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x027877759d155b1997d0d84683a313eb78bdb493271d935b622900459d52ceaa",
|
||||||
|
"y": "0x54d691731a53baa30707f4a87121d5169fb5d587d70fb0292b5830dedbec4c18"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x227e0bb89de700385d19ec40e857db6e6a3e634b1c32962f370d26f84ff19683",
|
||||||
|
"y": "0x5f86ff3851d262727326a32c1bf7655a03665830fa7f1b8b1e5a09d85bc66e4a"
|
||||||
|
},
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"u": [
|
||||||
|
"0x001e92a544463bda9bd04ddbe3d6eed248f82de32f522669efc5ddce95f46f5b"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x5fd892c0958d1a75f54c3182a18d286efab784e774d1e017ba2fb252998b5dc1",
|
||||||
|
"y": "0x750af3c66101737423a4519ac792fb93337bd74ee751f19da4cf1e94f4d6d0b8"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x3bcd651ee54d5f7b6013898aab251ee8ecc0688166fce6e9548d38472f6bd196",
|
||||||
|
"y": "0x1bb36ad9197299f111b4ef21271c41f4b7ecf5543db8bb5931307ebdb2eaa465"
|
||||||
|
},
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"u": [
|
||||||
|
"0x1a68a1af9f663592291af987203393f707305c7bac9c8d63d6a729bdc553dc19"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
115
test/hash-to-curve/curve25519_XMD:SHA-512_ELL2_RO_.json
Normal file
115
test/hash-to-curve/curve25519_XMD:SHA-512_ELL2_RO_.json
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
{
|
||||||
|
"L": "0x30",
|
||||||
|
"Z": "0x2",
|
||||||
|
"ciphersuite": "curve25519_XMD:SHA-512_ELL2_RO_",
|
||||||
|
"curve": "curve25519",
|
||||||
|
"dst": "QUUX-V01-CS02-with-curve25519_XMD:SHA-512_ELL2_RO_",
|
||||||
|
"expand": "XMD",
|
||||||
|
"field": {
|
||||||
|
"m": "0x1",
|
||||||
|
"p": "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed"
|
||||||
|
},
|
||||||
|
"hash": "sha512",
|
||||||
|
"k": "0x80",
|
||||||
|
"map": {
|
||||||
|
"name": "ELL2"
|
||||||
|
},
|
||||||
|
"randomOracle": true,
|
||||||
|
"vectors": [
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x2de3780abb67e861289f5749d16d3e217ffa722192d16bbd9d1bfb9d112b98c0",
|
||||||
|
"y": "0x3b5dc2a498941a1033d176567d457845637554a2fe7a3507d21abd1c1bd6e878"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x36b4df0c864c64707cbf6cf36e9ee2c09a6cb93b28313c169be29561bb904f98",
|
||||||
|
"y": "0x6cd59d664fb58c66c892883cd0eb792e52055284dac3907dd756b45d15c3983d"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x3fa114783a505c0b2b2fbeef0102853c0b494e7757f2a089d0daae7ed9a0db2b",
|
||||||
|
"y": "0x76c0fe7fec932aaafb8eefb42d9cbb32eb931158f469ff3050af15cfdbbeff94"
|
||||||
|
},
|
||||||
|
"msg": "",
|
||||||
|
"u": [
|
||||||
|
"0x005fe8a7b8fef0a16c105e6cadf5a6740b3365e18692a9c05bfbb4d97f645a6a",
|
||||||
|
"0x1347edbec6a2b5d8c02e058819819bee177077c9d10a4ce165aab0fd0252261a"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x2b4419f1f2d48f5872de692b0aca72cc7b0a60915dd70bde432e826b6abc526d",
|
||||||
|
"y": "0x1b8235f255a268f0a6fa8763e97eb3d22d149343d495da1160eff9703f2d07dd"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x16b3d86e056b7970fa00165f6f48d90b619ad618791661b7b5e1ec78be10eac1",
|
||||||
|
"y": "0x4ab256422d84c5120b278cbdfc4e1facc5baadffeccecf8ee9bf3946106d50ca"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x7ec29ddbf34539c40adfa98fcb39ec36368f47f30e8f888cc7e86f4d46e0c264",
|
||||||
|
"y": "0x10d1abc1cae2d34c06e247f2141ba897657fb39f1080d54f09ce0af128067c74"
|
||||||
|
},
|
||||||
|
"msg": "abc",
|
||||||
|
"u": [
|
||||||
|
"0x49bed021c7a3748f09fa8cdfcac044089f7829d3531066ac9e74e0994e05bc7d",
|
||||||
|
"0x5c36525b663e63389d886105cee7ed712325d5a97e60e140aba7e2ce5ae851b6"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x68ca1ea5a6acf4e9956daa101709b1eee6c1bb0df1de3b90d4602382a104c036",
|
||||||
|
"y": "0x2a375b656207123d10766e68b938b1812a4a6625ff83cb8d5e86f58a4be08353"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x71de3dadfe268872326c35ac512164850860567aea0e7325e6b91a98f86533ad",
|
||||||
|
"y": "0x26a08b6e9a18084c56f2147bf515414b9b63f1522e1b6c5649f7d4b0324296ec"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x5704069021f61e41779e2ba6b932268316d6d2a6f064f997a22fef16d1eaeaca",
|
||||||
|
"y": "0x50483c7540f64fb4497619c050f2c7fe55454ec0f0e79870bb44302e34232210"
|
||||||
|
},
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"u": [
|
||||||
|
"0x6412b7485ba26d3d1b6c290a8e1435b2959f03721874939b21782df17323d160",
|
||||||
|
"0x24c7b46c1c6d9a21d32f5707be1380ab82db1054fde82865d5c9e3d968f287b2"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x096e9c8bae6c06b554c1ee69383bb0e82267e064236b3a30608d4ed20b73ac5a",
|
||||||
|
"y": "0x1eb5a62612cafb32b16c3329794645b5b948d9f8ffe501d4e26b073fef6de355"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x7a94d45a198fb5daa381f45f2619ab279744efdd8bd8ed587fc5b65d6cea1df0",
|
||||||
|
"y": "0x67d44f85d376e64bb7d713585230cdbfafc8e2676f7568e0b6ee59361116a6e1"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x30506fb7a32136694abd61b6113770270debe593027a968a01f271e146e60c18",
|
||||||
|
"y": "0x7eeee0e706b40c6b5174e551426a67f975ad5a977ee2f01e8e20a6d612458c3b"
|
||||||
|
},
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"u": [
|
||||||
|
"0x5e123990f11bbb5586613ffabdb58d47f64bb5f2fa115f8ea8df0188e0c9e1b5",
|
||||||
|
"0x5e8553eb00438a0bb1e7faa59dec6d8087f9c8011e5fb8ed9df31cb6c0d4ac19"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x1bc61845a138e912f047b5e70ba9606ba2a447a4dade024c8ef3dd42b7bbc5fe",
|
||||||
|
"y": "0x623d05e47b70e25f7f1d51dda6d7c23c9a18ce015fe3548df596ea9e38c69bf1"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x02d606e2699b918ee36f2818f2bc5013e437e673c9f9b9cdc15fd0c5ee913970",
|
||||||
|
"y": "0x29e9dc92297231ef211245db9e31767996c5625dfbf92e1c8107ef887365de1e"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x38920e9b988d1ab7449c0fa9a6058192c0c797bb3d42ac345724341a1aa98745",
|
||||||
|
"y": "0x24dcc1be7c4d591d307e89049fd2ed30aae8911245a9d8554bf6032e5aa40d3d"
|
||||||
|
},
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"u": [
|
||||||
|
"0x20f481e85da7a3bf60ac0fb11ed1d0558fc6f941b3ac5469aa8b56ec883d6d7d",
|
||||||
|
"0x017d57fd257e9a78913999a23b52ca988157a81b09c5442501d07fed20869465"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
90
test/hash-to-curve/curve448_XOF:SHAKE256_ELL2_NU_.json
Normal file
90
test/hash-to-curve/curve448_XOF:SHAKE256_ELL2_NU_.json
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
{
|
||||||
|
"L": "0x54",
|
||||||
|
"Z": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffe",
|
||||||
|
"ciphersuite": "curve448_XOF:SHAKE256_ELL2_NU_",
|
||||||
|
"curve": "curve448",
|
||||||
|
"dst": "QUUX-V01-CS02-with-curve448_XOF:SHAKE256_ELL2_NU_",
|
||||||
|
"expand": "XOF",
|
||||||
|
"field": {
|
||||||
|
"m": "0x1",
|
||||||
|
"p": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||||
|
},
|
||||||
|
"hash": "shake_256",
|
||||||
|
"k": "0xe0",
|
||||||
|
"map": {
|
||||||
|
"name": "ELL2"
|
||||||
|
},
|
||||||
|
"randomOracle": false,
|
||||||
|
"vectors": [
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0xb65e8dbb279fd656f926f68d463b13ca7a982b32f5da9c7cc58afcf6199e4729863fb75ca9ae3c95c6887d95a5102637a1c5c40ff0aafadc",
|
||||||
|
"y": "0xea1ea211cf29eca11c057fe8248181591a19f6ac51d45843a65d4bb8b71bc83a64c771ed7686218a278ef1c5d620f3d26b53162188645453"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0xe6304424de5af3f556d3e645600530c53ad949891c3e60ba041dd5f68a93901beff8440164477d348c13d28e27bfcd360c44c80b4c7d4cea",
|
||||||
|
"y": "0x4160a8f2043a347185406a6a7e50973b98b82edbdfa3209b0e1c90118e10eeb45045b0990d4b2b0708a30eca17df40ad53c9100f20c10b44"
|
||||||
|
},
|
||||||
|
"msg": "",
|
||||||
|
"u": [
|
||||||
|
"0x242c70f74eac8184116c71630d284cf8a742fc463e710545847ff64d8e9161cb9f599728a18a32dbd8b67c3bec5d64c9b1d2f2cde7b5888d"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x51aceca4fa95854bbaba58d8a5e17a86c07acadef32e1188cafda26232131800002cc2f27c7aec454e5e0c615bddffb7df6a5f7f0f14793f",
|
||||||
|
"y": "0xc590c9246eb28b08dee816d608ef233ea5d76e305dc458774a1e1bd880387e6734219e2018e4aa50a49486dce0ba8740065da37e6cf5212c"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0xde0dc93df9ce7953452f20e270699c1e7dacd5d571c226d77f53b7e3053d16f8a81b1601efb362054e973c8e733b663af93f00cb81baf130",
|
||||||
|
"y": "0x8c5bdec6fa6690905f6eff966b0f98f5a8161493bd04976684d4ec1f4512fa8743d86860b2ff2c5d67e9c145fd906f2cb89ff812c6b9883f"
|
||||||
|
},
|
||||||
|
"msg": "abc",
|
||||||
|
"u": [
|
||||||
|
"0xef6dcb75b696d325fb36d66b104700df1480c4c17ea9190d447eee1e7e4c9b7f36bbfb8ba7ba7c4cb6b07fed16531c1ac7a26a3618b40b34"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0xc6d65987f146b8d0cb5d2c44e1872ac3af1f458f6a8bd8c232ffe8b9d09496229a5a27f350eb7d97305bcc4e0f38328718352e8e3129ed71",
|
||||||
|
"y": "0x4d2f901bf333fdc4135b954f20d59207e9f6a4ecf88ce5af11c892b44f79766ec4ecc9f60d669b95ca8940f39b1b7044140ac2040c1bf659"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0xdc29532761f03c24d57f530da4c24acc4c676d185becaa89fcc083266541fb7f10ecec91dac64a34cd988274633ae25c4d784aee52de47a8",
|
||||||
|
"y": "0xa5f6da11259c69f2e07fce6a7b6afec4c25bd2df83426765f9c0704111da24c6a0550d5c7aac7d648d55f7640d50be99c926195e852adaac"
|
||||||
|
},
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"u": [
|
||||||
|
"0x3012ba5d9b3bb648e4613833a26ecaeadb3e8c8bba07fc90ac3da0375769289c44d3dc87474b23df7f45f9a4030892cda689e343aeeea6ad"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x9b8d008863beb4a02fb9e4efefd2eba867307fb1c7ce01746115d32e1db551bb254e8e3e4532d5c74a83949a69a60519ecc9178083cbe943",
|
||||||
|
"y": "0x346a1fca454d1e67c628437c270ec0f0c4256bb774fe6c0e49de7004ff6d9199e2cd99d8f7575a96aafc4dc8db1811ba0a44317581f41371"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x512803d89f59c57376e6570cd54c4e901643e089cd9456f549daa4372b8b52679860b68aa8bedfaa88970f15ab6098d5f252083ac98a58c9",
|
||||||
|
"y": "0x3d9b6593c7941a20d76161c9a171f1e507495a08f03dfcae33a2ac3602698e46a74d1039b583c984036f590eaa43d20ba5aada3ffb552f77"
|
||||||
|
},
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"u": [
|
||||||
|
"0xfe952ac0149f92436bba12ea2e542aa226f4fc074d79ff462c41b327968a649a495a8a93b6c3044af2273456abb5e166ce4fb8c9b10c8c2e"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x8746dc34799112d1f20acda9d7f722c9abb29b1fb6b7e9e566983843c20bd7c9bfad21b45c5166b808d2f5d44e188f1fdaf29cdee8a72e4c",
|
||||||
|
"y": "0x7c1293484c9287c298a1a0600c64347eee8530acf563cd8705e05728274d8cd8101835f8003b6f3b78b5beb28f5be188a3d7bce1ec5a36b1"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x08aed6480793218034fd3b3b0867943d7e0bd1b6f76b4929e0885bd082b84d4449341da6038bb08229ad9eb7d518dff2c7ea50148e70a4db",
|
||||||
|
"y": "0xe00d32244561ebd4b5f4ef70fcac75a06416be0a1c1b304e7bd361a6a6586915bb902a323eaf73cf7738e70d34282f61485395ab2833d2c1"
|
||||||
|
},
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"u": [
|
||||||
|
"0xafd3d7ad9d819be7561706e050d4f30b634b203387ab682739365f62cd7393ca2cf18cd07a3d3af8dd163f043ac7457c2eb145b4a56170a9"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
115
test/hash-to-curve/curve448_XOF:SHAKE256_ELL2_RO_.json
Normal file
115
test/hash-to-curve/curve448_XOF:SHAKE256_ELL2_RO_.json
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
{
|
||||||
|
"L": "0x54",
|
||||||
|
"Z": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffe",
|
||||||
|
"ciphersuite": "curve448_XOF:SHAKE256_ELL2_RO_",
|
||||||
|
"curve": "curve448",
|
||||||
|
"dst": "QUUX-V01-CS02-with-curve448_XOF:SHAKE256_ELL2_RO_",
|
||||||
|
"expand": "XOF",
|
||||||
|
"field": {
|
||||||
|
"m": "0x1",
|
||||||
|
"p": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||||
|
},
|
||||||
|
"hash": "shake_256",
|
||||||
|
"k": "0xe0",
|
||||||
|
"map": {
|
||||||
|
"name": "ELL2"
|
||||||
|
},
|
||||||
|
"randomOracle": true,
|
||||||
|
"vectors": [
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x5ea5ff623d27c75e73717514134e73e419f831a875ca9e82915fdfc7069d0a9f8b532cfb32b1d8dd04ddeedbe3fa1d0d681c01e825d6a9ea",
|
||||||
|
"y": "0xafadd8de789f8f8e3516efbbe313a7eba364c939ecba00dabf4ced5c563b18e70a284c17d8f46b564c4e6ce11784a3825d941116622128c1"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x3ba318806f89c19cc019f51e33eb6b8c038dab892e858ce7c7f2c2ac58618d06146a5fef31e49af49588d4d3db1bcf02bd4e4a733e37065d",
|
||||||
|
"y": "0xb30b4cfc2fd14d9d4b70456c0f5c6f6070be551788893d570e7955675a20f6c286d01d6e90d2fb500d2efb8f4e18db7f8268bb9b7fbc5975"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0xf03a48cf003f63be61ca055fec87c750434da07a15f8aa6210389ff85943b5166484339c8bea1af9fc571313d35ed2fbb779408b760c4cbd",
|
||||||
|
"y": "0x23943a33b2954dc54b76a8222faf5b7e18405a41f5ecc61bf1b8df1f9cbfad057307ed0c7b721f19c0390b8ee3a2dec223671f9ff905fda7"
|
||||||
|
},
|
||||||
|
"msg": "",
|
||||||
|
"u": [
|
||||||
|
"0xc704c7b3d3b36614cf3eedd0324fe6fe7d1402c50efd16cff89ff63f50938506280d3843478c08e24f7842f4e3ef45f6e3c4897f9d976148",
|
||||||
|
"0xc25427dc97fff7a5ad0a78654e2c6c27b1c1127b5b53c7950cd1fd6edd2703646b25f341e73deedfebf022d1d3cecd02b93b4d585ead3ed7"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x9b2f7ce34878d7cebf34c582db14958308ea09366d1ec71f646411d3de0ae564d082b06f40cd30dfc08d9fb7cb21df390cf207806ad9d0e4",
|
||||||
|
"y": "0x138a0eef0a4993ea696152ed7db61f7ddb4e8100573591e7466d61c0c568ecaec939e36a84d276f34c402526d8989a96e99760c4869ed633"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x26714783887ec444fbade9ae350dc13e8d5a64150679232560726a73d36e28bd56766d7d0b0899d79c8d1c889ae333f601c57532ff3c4f09",
|
||||||
|
"y": "0x080e486f8f5740dbbe82305160cab9fac247b0b22a54d961de675037c3036fa68464c8756478c322ae0aeb9ba386fe626cebb0bcca46840c"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x0d9741d10421691a8ebc7778b5f623260fdf8b28ae28d776efcb8e0d5fbb65139a2f828617835f527cb2ca24a8f5fc8e84378343c43d096d",
|
||||||
|
"y": "0x54f4c499bf3d5b154511913f9615bd914969b65cfb74508d7ae5a169e9595b7cbcab9a1485e07b2ce426e4fbed052f03842c4313b7dbe39a"
|
||||||
|
},
|
||||||
|
"msg": "abc",
|
||||||
|
"u": [
|
||||||
|
"0x2dd95593dfee26fe0d218d3d9a0a23d9e1a262fd1d0b602483d08415213e75e2db3c69b0a5bc89e71bcefc8c723d2b6a0cf263f02ad2aa70",
|
||||||
|
"0x272e4c79a1290cc6d2bc4f4f9d31bf7fbe956ca303c04518f117d77c0e9d850796fc3e1e2bcb9c75e8eaaded5e150333cae9931868047c9d"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0xf54ecd14b85a50eeeee0618452df3a75be7bfba11da5118774ae4ea55ac204e153f77285d780c4acee6c96abe3577a0c0b00be6e790cf194",
|
||||||
|
"y": "0x935247a64bf78c107069943c7e3ecc52acb27ce4a3230407c8357341685ea2152e8c3da93f8cd77da1bddb5bb759c6e7ae7d516dced42850"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x946d91bd50c90ef70743e0dd194bddd68bb630f4e67e5b93e15a9b94e62cb85134467993501759525c1f4fdbf06f10ddaf817847d735e062",
|
||||||
|
"y": "0x185cf511262ec1e9b3c3cbdc015ab93df4e71cbe87766917d81c9f3419d480407c1462385122c84982d4dae60c3ae4acce0089e37ad65934"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x01778f4797b717cd6f83c193b2dfb92a1606a36ede941b0f6ab0ac71ad0eac756d17604bf054398887da907e41065d3595f178ae802f2087",
|
||||||
|
"y": "0xb4ca727d0bda895e0eee7eb3cbc28710fa2e90a73b568cae26bd7c2e73b70a9fa0affe1096f0810198890ed65d8935886b6e60dc4c569dc6"
|
||||||
|
},
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"u": [
|
||||||
|
"0x6aab71a38391639f27e49eae8b1cb6b7172a1f478190ece293957e7cdb2391e7cc1c4261970d9c1bbf9c3915438f74fbd7eb5cd4d4d17ace",
|
||||||
|
"0xc80b8380ca47a3bcbf76caa75cef0e09f3d270d5ee8f676cde11aedf41aaca6741bd81a86232bd336ccb42efad39f06542bc06a67b65909e"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x5bd67c4f88adf6beb10f7e0d0054659776a55c97b809ec8b3101729e104fd0f684e103792f267fd87cc4afc25a073956ef4f268fb02824d5",
|
||||||
|
"y": "0xda1f5cb16a352719e4cb064cf47ba72aeba7752d03e8ca2c56229f419b4ef378785a5af1a53dd7ab4d467c1f92f7b139b3752faf29c96432"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0xc2d275826d6ad55e41a22318f6b6240f1f862a2e231120ff41eadbec319756032e8cef2a7ac6c10214fa0608c17fcaf61ec2694a8a2b358b",
|
||||||
|
"y": "0x93d2e092762b135509840e609d413200df800d99da91d8b82840666cac30e7a3520adbaa4b089bfdc86132e42729f651d022f4782502f12c"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x3c0880ece7244036e9a45944a85599f9809d772f770cc237ac41b21aa71615e4f3bb08f64fca618896e4f6cf5bd92e16b89d2cf6e1956bfb",
|
||||||
|
"y": "0x45cce4beb96505cac5976b3d2673641e9bcd18d3462bbb453d293e5282740a6389cfeae610adc7bd425c728541ceec83fcc999164af43fb5"
|
||||||
|
},
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"u": [
|
||||||
|
"0xcb5c27e51f9c18ee8ffdb6be230f4eb4f2c2481963b2293484f08da2241c1ff59f80978e6defe9d70e34abba2fcbe12dc3a1eb2c5d3d2e4a",
|
||||||
|
"0xc895e8afecec5466e126fa70fc4aa784b8009063afb10e3ee06a9b22318256aa8693b0c85b955cf2d6540b8ed71e729af1b8d5ca3b116cd7"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0xea441c10b3636ecedd5c0dfcae96384cc40de8390a0ab648765b4508da12c586d55dc981275776507ebca0e4d1bcaa302bb69dcfa31b3451",
|
||||||
|
"y": "0xfee0192d49bcc0c28d954763c2cbe739b9265c4bebe3883803c64971220cfda60b9ac99ad986cd908c0534b260b5cfca46f6c2b0f3f21bda"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x4321ab02a9849128691e9b80a5c5576793a218de14885fddccb91f17ceb1646ea00a28b69ad211e1f14f17739612dbde3782319bdf009689",
|
||||||
|
"y": "0x1b8a7b539519eec0ea9f7a46a43822e16cba39a439733d6847ac44a806b8adb3e1a75ea48a1228b8937ba85c6cb6ee01046e10cad8953b1e"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x126d744da6a14fddec0f78a9cee4571c1320ac7645b600187812e4d7021f98fc4703732c54daec787206e1f34d9dbbf4b292c68160b8bfbd",
|
||||||
|
"y": "0x136eebe6020f2389d448923899a1a38a4c8ad74254e0686e91c4f93c1f8f8e1bd619ffb7c1281467882a9c957d22d50f65c5b72b2aee11af"
|
||||||
|
},
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"u": [
|
||||||
|
"0x8cba93a007bb2c801b1769e026b1fa1640b14a34cf3029db3c7fd6392745d6fec0f7870b5071d6da4402cedbbde28ae4e50ab30e1049a238",
|
||||||
|
"0x4223746145069e4b8a981acc3404259d1a2c3ecfed5d864798a89d45f81a2c59e2d40eb1d5f0fe11478cbb2bb30246dd388cb932ad7bb330"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
90
test/hash-to-curve/edwards25519_XMD:SHA-512_ELL2_NU_.json
Normal file
90
test/hash-to-curve/edwards25519_XMD:SHA-512_ELL2_NU_.json
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
{
|
||||||
|
"L": "0x30",
|
||||||
|
"Z": "0x2",
|
||||||
|
"ciphersuite": "edwards25519_XMD:SHA-512_ELL2_NU_",
|
||||||
|
"curve": "edwards25519",
|
||||||
|
"dst": "QUUX-V01-CS02-with-edwards25519_XMD:SHA-512_ELL2_NU_",
|
||||||
|
"expand": "XMD",
|
||||||
|
"field": {
|
||||||
|
"m": "0x1",
|
||||||
|
"p": "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed"
|
||||||
|
},
|
||||||
|
"hash": "sha512",
|
||||||
|
"k": "0x80",
|
||||||
|
"map": {
|
||||||
|
"name": "ELL2"
|
||||||
|
},
|
||||||
|
"randomOracle": false,
|
||||||
|
"vectors": [
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x1ff2b70ecf862799e11b7ae744e3489aa058ce805dd323a936375a84695e76da",
|
||||||
|
"y": "0x222e314d04a4d5725e9f2aff9fb2a6b69ef375a1214eb19021ceab2d687f0f9b"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x42836f691d05211ebc65ef8fcf01e0fb6328ec9c4737c26050471e50803022eb",
|
||||||
|
"y": "0x22cb4aaa555e23bd460262d2130d6a3c9207aa8bbb85060928beb263d6d42a95"
|
||||||
|
},
|
||||||
|
"msg": "",
|
||||||
|
"u": [
|
||||||
|
"0x7f3e7fb9428103ad7f52db32f9df32505d7b427d894c5093f7a0f0374a30641d"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x5f13cc69c891d86927eb37bd4afc6672360007c63f68a33ab423a3aa040fd2a8",
|
||||||
|
"y": "0x67732d50f9a26f73111dd1ed5dba225614e538599db58ba30aaea1f5c827fa42"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x333e41b61c6dd43af220c1ac34a3663e1cf537f996bab50ab66e33c4bd8e4e19",
|
||||||
|
"y": "0x51b6f178eb08c4a782c820e306b82c6e273ab22e258d972cd0c511787b2a3443"
|
||||||
|
},
|
||||||
|
"msg": "abc",
|
||||||
|
"u": [
|
||||||
|
"0x09cfa30ad79bd59456594a0f5d3a76f6b71c6787b04de98be5cd201a556e253b"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x1dd2fefce934ecfd7aae6ec998de088d7dd03316aa1847198aecf699ba6613f1",
|
||||||
|
"y": "0x2f8a6c24dd1adde73909cada6a4a137577b0f179d336685c4a955a0a8e1a86fb"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x55186c242c78e7d0ec5b6c9553f04c6aeef64e69ec2e824472394da32647cfc6",
|
||||||
|
"y": "0x5b9ea3c265ee42256a8f724f616307ef38496ef7eba391c08f99f3bea6fa88f0"
|
||||||
|
},
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"u": [
|
||||||
|
"0x475ccff99225ef90d78cc9338e9f6a6bb7b17607c0c4428937de75d33edba941"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x35fbdc5143e8a97afd3096f2b843e07df72e15bfca2eaf6879bf97c5d3362f73",
|
||||||
|
"y": "0x2af6ff6ef5ebba128b0774f4296cb4c2279a074658b083b8dcca91f57a603450"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x024b6e1621606dca8071aa97b43dce4040ca78284f2a527dcf5d0fbfac2b07e7",
|
||||||
|
"y": "0x5102353883d739bdc9f8a3af650342b171217167dcce34f8db57208ec1dfdbf2"
|
||||||
|
},
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"u": [
|
||||||
|
"0x049a1c8bd51bcb2aec339f387d1ff51428b88d0763a91bcdf6929814ac95d03d"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x6e5e1f37e99345887fc12111575fc1c3e36df4b289b8759d23af14d774b66bff",
|
||||||
|
"y": "0x2c90c3d39eb18ff291d33441b35f3262cdd307162cc97c31bfcc7a4245891a37"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x3e6368cff6e88a58e250c54bd27d2c989ae9b3acb6067f2651ad282ab8c21cd9",
|
||||||
|
"y": "0x38fb39f1566ca118ae6c7af42810c0bb9767ae5960abb5a8ca792530bfb9447d"
|
||||||
|
},
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"u": [
|
||||||
|
"0x3cb0178a8137cefa5b79a3a57c858d7eeeaa787b2781be4a362a2f0750d24fa0"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
115
test/hash-to-curve/edwards25519_XMD:SHA-512_ELL2_RO_.json
Normal file
115
test/hash-to-curve/edwards25519_XMD:SHA-512_ELL2_RO_.json
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
{
|
||||||
|
"L": "0x30",
|
||||||
|
"Z": "0x2",
|
||||||
|
"ciphersuite": "edwards25519_XMD:SHA-512_ELL2_RO_",
|
||||||
|
"curve": "edwards25519",
|
||||||
|
"dst": "QUUX-V01-CS02-with-edwards25519_XMD:SHA-512_ELL2_RO_",
|
||||||
|
"expand": "XMD",
|
||||||
|
"field": {
|
||||||
|
"m": "0x1",
|
||||||
|
"p": "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed"
|
||||||
|
},
|
||||||
|
"hash": "sha512",
|
||||||
|
"k": "0x80",
|
||||||
|
"map": {
|
||||||
|
"name": "ELL2"
|
||||||
|
},
|
||||||
|
"randomOracle": true,
|
||||||
|
"vectors": [
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x3c3da6925a3c3c268448dcabb47ccde5439559d9599646a8260e47b1e4822fc6",
|
||||||
|
"y": "0x09a6c8561a0b22bef63124c588ce4c62ea83a3c899763af26d795302e115dc21"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x6549118f65bb617b9e8b438decedc73c496eaed496806d3b2eb9ee60b88e09a7",
|
||||||
|
"y": "0x7315bcc8cf47ed68048d22bad602c6680b3382a08c7c5d3f439a973fb4cf9feb"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x31dcfc5c58aa1bee6e760bf78cbe71c2bead8cebb2e397ece0f37a3da19c9ed2",
|
||||||
|
"y": "0x7876d81474828d8a5928b50c82420b2bd0898d819e9550c5c82c39fc9bafa196"
|
||||||
|
},
|
||||||
|
"msg": "",
|
||||||
|
"u": [
|
||||||
|
"0x03fef4813c8cb5f98c6eef88fae174e6e7d5380de2b007799ac7ee712d203f3a",
|
||||||
|
"0x780bdddd137290c8f589dc687795aafae35f6b674668d92bf92ae793e6a60c75"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x608040b42285cc0d72cbb3985c6b04c935370c7361f4b7fbdb1ae7f8c1a8ecad",
|
||||||
|
"y": "0x1a8395b88338f22e435bbd301183e7f20a5f9de643f11882fb237f88268a5531"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x5c1525bd5d4b4e034512949d187c39d48e8cd84242aa4758956e4adc7d445573",
|
||||||
|
"y": "0x2bf426cf7122d1a90abc7f2d108befc2ef415ce8c2d09695a7407240faa01f29"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x37b03bba828860c6b459ddad476c83e0f9285787a269df2156219b7e5c86210c",
|
||||||
|
"y": "0x285ebf5412f84d0ad7bb4e136729a9ffd2195d5b8e73c0dc85110ce06958f432"
|
||||||
|
},
|
||||||
|
"msg": "abc",
|
||||||
|
"u": [
|
||||||
|
"0x5081955c4141e4e7d02ec0e36becffaa1934df4d7a270f70679c78f9bd57c227",
|
||||||
|
"0x005bdc17a9b378b6272573a31b04361f21c371b256252ae5463119aa0b925b76"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x6d7fabf47a2dc03fe7d47f7dddd21082c5fb8f86743cd020f3fb147d57161472",
|
||||||
|
"y": "0x53060a3d140e7fbcda641ed3cf42c88a75411e648a1add71217f70ea8ec561a6"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x3ac463dd7fddb773b069c5b2b01c0f6b340638f54ee3bd92d452fcec3015b52d",
|
||||||
|
"y": "0x7b03ba1e8db9ec0b390d5c90168a6a0b7107156c994c674b61fe696cbeb46baf"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x0757e7e904f5e86d2d2f4acf7e01c63827fde2d363985aa7432106f1b3a444ec",
|
||||||
|
"y": "0x50026c96930a24961e9d86aa91ea1465398ff8e42015e2ec1fa397d416f6a1c0"
|
||||||
|
},
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"u": [
|
||||||
|
"0x285ebaa3be701b79871bcb6e225ecc9b0b32dff2d60424b4c50642636a78d5b3",
|
||||||
|
"0x2e253e6a0ef658fedb8e4bd6a62d1544fd6547922acb3598ec6b369760b81b31"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x5fb0b92acedd16f3bcb0ef83f5c7b7a9466b5f1e0d8d217421878ea3686f8524",
|
||||||
|
"y": "0x2eca15e355fcfa39d2982f67ddb0eea138e2994f5956ed37b7f72eea5e89d2f7"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x703e69787ea7524541933edf41f94010a201cc841c1cce60205ec38513458872",
|
||||||
|
"y": "0x32bb192c4f89106466f0874f5fd56a0d6b6f101cb714777983336c159a9bec75"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x0c9077c5c31720ed9413abe59bf49ce768506128d810cb882435aa90f713ef6b",
|
||||||
|
"y": "0x7d5aec5210db638c53f050597964b74d6dda4be5b54fa73041bf909ccb3826cb"
|
||||||
|
},
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"u": [
|
||||||
|
"0x4fedd25431c41f2a606952e2945ef5e3ac905a42cf64b8b4d4a83c533bf321af",
|
||||||
|
"0x02f20716a5801b843987097a8276b6d869295b2e11253751ca72c109d37485a9"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x0efcfde5898a839b00997fbe40d2ebe950bc81181afbd5cd6b9618aa336c1e8c",
|
||||||
|
"y": "0x6dc2fc04f266c5c27f236a80b14f92ccd051ef1ff027f26a07f8c0f327d8f995"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x21091b2e3f9258c7dfa075e7ae513325a94a3d8a28e1b1cb3b5b6f5d65675592",
|
||||||
|
"y": "0x41a33d324c89f570e0682cdf7bdb78852295daf8084c669f2cc9692896ab5026"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x4c07ec48c373e39a23bd7954f9e9b66eeab9e5ee1279b867b3d5315aa815454f",
|
||||||
|
"y": "0x67ccac7c3cb8d1381242d8d6585c57eabaddbb5dca5243a68a8aeb5477d94b3a"
|
||||||
|
},
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"u": [
|
||||||
|
"0x6e34e04a5106e9bd59f64aba49601bf09d23b27f7b594e56d5de06df4a4ea33b",
|
||||||
|
"0x1c1c2cb59fc053f44b86c5d5eb8c1954b64976d0302d3729ff66e84068f5fd96"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
90
test/hash-to-curve/edwards448_XOF:SHAKE256_ELL2_NU_.json
Normal file
90
test/hash-to-curve/edwards448_XOF:SHAKE256_ELL2_NU_.json
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
{
|
||||||
|
"L": "0x54",
|
||||||
|
"Z": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffe",
|
||||||
|
"ciphersuite": "edwards448_XOF:SHAKE256_ELL2_NU_",
|
||||||
|
"curve": "edwards448",
|
||||||
|
"dst": "QUUX-V01-CS02-with-edwards448_XOF:SHAKE256_ELL2_NU_",
|
||||||
|
"expand": "XOF",
|
||||||
|
"field": {
|
||||||
|
"m": "0x1",
|
||||||
|
"p": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||||
|
},
|
||||||
|
"hash": "shake_256",
|
||||||
|
"k": "0xe0",
|
||||||
|
"map": {
|
||||||
|
"name": "ELL2"
|
||||||
|
},
|
||||||
|
"randomOracle": false,
|
||||||
|
"vectors": [
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0xeb5a1fc376fd73230af2de0f3374087cc7f279f0460114cf0a6c12d6d044c16de34ec2350c34b26bf110377655ab77936869d085406af71e",
|
||||||
|
"y": "0xdf5dcea6d42e8f494b279a500d09e895d26ac703d75ca6d118e8ca58bf6f608a2a383f292fce1563ff995dce75aede1fdc8e7c0c737ae9ad"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x4b2abf8c0fca49d027c2a81bf73bb5990e05f3e76c7ba137cc0b89415ccd55ce7f191cc0c11b0560c1cdc2a8085dd56996079e05a3cd8dde",
|
||||||
|
"y": "0x82532f5b0cb3bfb8542d3228d055bfe61129dbeae8bace80cf61f17725e8ec8226a24f0e687f78f01da88e3b2715194a03dca7c0a96bbf04"
|
||||||
|
},
|
||||||
|
"msg": "",
|
||||||
|
"u": [
|
||||||
|
"0x1368aefc0416867ea2cfc515416bcbeecc9ec81c4ecbd52ccdb91e06996b3f359bc930eef6743c7a2dd7adb785bc7093ed044efed95086d7"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x4623a64bceaba3202df76cd8b6e3daf70164f3fcbda6d6e340f7fab5cdf89140d955f722524f5fe4d968fef6ba2853ff4ea086c2f67d8110",
|
||||||
|
"y": "0xabaac321a169761a8802ab5b5d10061fec1a83c670ac6bc95954700317ee5f82870120e0e2c5a21b12a0c7ad17ebd343363604c4bcecafd1"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0xb1ca5bef2f157673a210f56c9b0039db8399e4749585abac64f831f74ed1ec5f591928976c687c06d57686bacb98440e77af878349cdf2d2",
|
||||||
|
"y": "0x5bbfd6a3730d517b03c3cd9e2eed94af12891334ec090e0495c2edc588e9e10b6f63b03a62076808cbcd6da95adfb5af76c136b2d42e0dac"
|
||||||
|
},
|
||||||
|
"msg": "abc",
|
||||||
|
"u": [
|
||||||
|
"0xcda3b0ecfe054c4077007d7300969ec24f4c741300b630ec9188ebab31a5ae0065612ee22d9f793733179ffc2e10c53ca5b539057aafdc2f"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0xe9eb562e76db093baa43a31b7edd04ec4aadcef3389a7b9c58a19cf87f8ae3d154e134b6b3ed45847a741e33df51903da681629a4b8bcc2e",
|
||||||
|
"y": "0x0cf6606927ad7eb15dbc193993bc7e4dda744b311a8ec4274c8f738f74f605934582474c79260f60280fe35bd37d4347e59184cbfa12cbc4"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x958a51e2f02e0dfd3930709010d5d16f869adb9d8a8f7c01139911d206c20cdb7bfb40ee33ba30536a99f49362fa7633d0f417fc3914fe21",
|
||||||
|
"y": "0xf4307a36ab6612fa97501497f01afa109733ce85875935551c3ca90f0fa7e0097a8640bb7e5dbcc38ab32b23b748790f2261f2c44c3bf3ba"
|
||||||
|
},
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"u": [
|
||||||
|
"0xd36bae98351512c382c7a3e1eba22497574f11fef9867901b1a2700b39fa2cd0d38ed4380387a99162b7ba0240c743f0532ef60d577c413d"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x122a3234d34b26c69749f23356452bf9501efa2d94859d5ef741fef024156d9d191a03a2ad24c38186f93e02d05572575968b083d8a39738",
|
||||||
|
"y": "0xddf55e74eb4414c2c1fa4aa6bc37c4ab470a3fed6bb5af1e43570309b162fb61879bb15f9ea49c712efd42d0a71666430f9f0d4a20505050"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0xe7e1f2d13548ac2c8fcd346e4c63606545bf93652011721e83ac3b64226f77a8823d3881e164bc6ca45505b236e8e3721c028052fcc9ade5",
|
||||||
|
"y": "0x7e0f340501bf25f018b9d374c2acbdd43c07261d85a6ef3c855113d4e023634db59a87b8fab9efe04ed1fee302c8a4994e83bdda32bd9c0b"
|
||||||
|
},
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"u": [
|
||||||
|
"0x5945744d27122f89da3daf76ab4db9616053df64e25d30ec9a00667ee6710240579c1db8f8ef3386f3f4f413cfb325ac14094d582026a971"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x221704949b1ce1ab8dd174dc9b8c56fcffa27179569ce9219c0c2fe183d3d23343a4c42a0e2e9d6b9d0feb1df3883ec489b6671d1fa64089",
|
||||||
|
"y": "0xebdecfdc87142d1a919034bf22ecfad934c9a85effff14b594ae2c00943ca62a39d6ee3be9df0bb504ce8a9e1669bc6959c42ad6a1d3b686"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x0fd3bb833c1d7a5b319d1d4117406a23b9aece976186ecb18a11a635e6fbdb920d47e04762b1f2a8c59d2f8435d0fdefe501f544cda23dbf",
|
||||||
|
"y": "0xf13b0dad4d5eeb120f2443ac4392f8096a1396f5014ec2a3506a347fef8076a7282035cf619599b1919cf29df5ce87711c11688aab7700a6"
|
||||||
|
},
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"u": [
|
||||||
|
"0x1192e378043f01cedc7ea0209321519213b0184ea0d8575816bcd9182a367823e1eecc2faf1df8f79b24027a4b9bfa208cd320e79bef06ea"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
115
test/hash-to-curve/edwards448_XOF:SHAKE256_ELL2_RO_.json
Normal file
115
test/hash-to-curve/edwards448_XOF:SHAKE256_ELL2_RO_.json
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
{
|
||||||
|
"L": "0x54",
|
||||||
|
"Z": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffe",
|
||||||
|
"ciphersuite": "edwards448_XOF:SHAKE256_ELL2_RO_",
|
||||||
|
"curve": "edwards448",
|
||||||
|
"dst": "QUUX-V01-CS02-with-edwards448_XOF:SHAKE256_ELL2_RO_",
|
||||||
|
"expand": "XOF",
|
||||||
|
"field": {
|
||||||
|
"m": "0x1",
|
||||||
|
"p": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||||
|
},
|
||||||
|
"hash": "shake_256",
|
||||||
|
"k": "0xe0",
|
||||||
|
"map": {
|
||||||
|
"name": "ELL2"
|
||||||
|
},
|
||||||
|
"randomOracle": true,
|
||||||
|
"vectors": [
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x73036d4a88949c032f01507005c133884e2f0d81f9a950826245dda9e844fc78186c39daaa7147ead3e462cff60e9c6340b58134480b4d17",
|
||||||
|
"y": "0x94c1d61b43728e5d784ef4fcb1f38e1075f3aef5e99866911de5a234f1aafdc26b554344742e6ba0420b71b298671bbeb2b7736618634610"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0xc08177330869db17fb81a5e6e53b36d29086d806269760f2e4cabaa4015f5dbadb7ca2ba594d96a89d0ca4f0944489e1ef393d53db85096f",
|
||||||
|
"y": "0x02e894598c050eeb7195f5791f1a5f65da3776b7534be37640bcbf95d4b915bd22333c50387583507169708fbd7bea0d7aa385dcc614be9c"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x770877fd3b6c5503398157b68a9d3609f585f40e1ebebdd69bb0e4d3d9aa811995ce75333fdadfa50db886a35959cc59cffd5c9710daca25",
|
||||||
|
"y": "0xb27fef77aa6231fbbc27538fa90eaca8abd03eb1e62fdae4ec5e828117c3b8b3ff8c34d0a6e6d79fff16d339b94ae8ede33331d5b464c792"
|
||||||
|
},
|
||||||
|
"msg": "",
|
||||||
|
"u": [
|
||||||
|
"0x0847c5ebf957d3370b1f98fde499fb3e659996d9fc9b5707176ade785ba72cd84b8a5597c12b1024be5f510fa5ba99642c4cec7f3f69d3e7",
|
||||||
|
"0xf8cbd8a7ae8c8deed071f3ac4b93e7cfcb8f1eac1645d699fd6d3881cb295a5d3006d9449ed7cad412a77a1fe61e84a9e41d59ef384d6f9a"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x4e0158acacffa545adb818a6ed8e0b870e6abc24dfc1dc45cf9a052e98469275d9ff0c168d6a5ac7ec05b742412ee090581f12aa398f9f8c",
|
||||||
|
"y": "0x894d3fa437b2d2e28cdc3bfaade035430f350ec5239b6b406b5501da6f6d6210ff26719cad83b63e97ab26a12df6dec851d6bf38e294af9a"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x7544612a97f4419c94ab0f621a1ee8ccf46c6657b8e0778ec9718bf4b41bc774487ad87d9b1e617aa49d3a4dd35a3cf57cd390ebf0429952",
|
||||||
|
"y": "0xd3ab703e60267d796b485bb58a28f934bd0133a6d1bbdfeda5277fa293310be262d7f653a5adffa608c37ed45c0e6008e54a16e1a342e4df"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x6262f18d064bc131ade1b8bbcf1cbdf984f4f88153fcc9f94c888af35d5e41aae84c12f169a55d8abf06e6de6c5b23079e587a58cf73303e",
|
||||||
|
"y": "0x6d57589e901abe7d947c93ab02c307ad9093ed9a83eb0b6e829fb7318d590381ca25f3cc628a36a924a9ddfcf3cbedf94edf3b338ea77403"
|
||||||
|
},
|
||||||
|
"msg": "abc",
|
||||||
|
"u": [
|
||||||
|
"0x04d975cd938ab49be3e81703d6a57cca84ed80d2ff6d4756d3f22947fb5b70ab0231f0087cbfb4b7cae73b41b0c9396b356a4831d9a14322",
|
||||||
|
"0x2547ca887ac3db7b5fad3a098aa476e90078afe1358af6c63d677d6edfd2100bc004e0f5db94dd2560fc5b308e223241d00488c9ca6b0ef2"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x2c25b4503fadc94b27391933b557abdecc601c13ed51c5de68389484f93dbd6c22e5f962d9babf7a39f39f994312f8ca23344847e1fbf176",
|
||||||
|
"y": "0xd5e6f5350f430e53a110f5ac7fcc82a96cb865aeca982029522d32601e41c042a9dfbdfbefa2b0bdcdc3bc58cca8a7cd546803083d3a8548"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x1457b60c12e00e47ceb3ce64b57e7c3c61636475443d704a8e2b2ab0a5ac7e4b3909435416784e16e19929c653b1bdcd9478a8e5331ca9ae",
|
||||||
|
"y": "0x935d9f75f7a0babbc39c0a1c3b412518ed8a24bc2c4886722fb4b7d4a747af98e4e2528c75221e2dffd3424abb436e10539a74caaafa3ea3"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0xb44d9e34211b4028f24117e856585ed81448f3c8b934987a1c5939c86048737a08d85934fec6b3c2ef9f09cbd365cf22744f2e4ce69762a4",
|
||||||
|
"y": "0xdc996c1736f4319868f897d9a27c45b02dd3bc6b7ca356a039606e5406e131a0bbe8238208b327b00853e8af84b58b13443e705425563323"
|
||||||
|
},
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"u": [
|
||||||
|
"0x10659ce25588db4e4be6f7c791a79eb21a7f24aaaca76a6ca3b83b80aaf95aa328fe7d569a1ac99f9cd216edf3915d72632f1a8b990e250c",
|
||||||
|
"0x9243e5b6c480683fd533e81f4a778349a309ce00bd163a29eb9fa8dbc8f549242bef33e030db21cffacd408d2c4264b93e476c6a8590e7aa"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0xa1861a9464ae31249a0e60bf38791f3663049a3f5378998499a83292e159a2fecff838eb9bc6939e5c6ae76eb074ad4aae39b55b72ca0b9a",
|
||||||
|
"y": "0x580a2798c5b904f8adfec5bd29fb49b4633cd9f8c2935eb4a0f12e5dfa0285680880296bb729c6405337525fb5ed3dff930c137314f60401"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x9d355251e245e4b13ed4ea3e5a3c55bf9b7211f1704771f2e1d8f1a65610c468b1cf70c6c2ce30dcaad54ad9e5439471ec554b862ec8875a",
|
||||||
|
"y": "0x6689ba36a242af69ac2aadb955d15e982d9b04f5d77f7609ebf7429587feb7e5ce27490b9c72114509f89565122074e46a614d7fd7c800bd"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0xc4b3d3ad4d2d62739a62989532992c1081e9474a201085b4616da5706cab824693b9fb428a201bcd1639a4588cc43b9eb841dbca74219b1f",
|
||||||
|
"y": "0x265286f5dee8f3d894b5649da8565b58e96b4cfd44b462a2883ea64dbcda21a00706ea3fea53fc2d769084b0b74589e91d0384d7118909fb"
|
||||||
|
},
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"u": [
|
||||||
|
"0xc80390020e578f009ead417029eff6cd0926110922db63ab98395e3bdfdd5d8a65b1a2b8d495dc8c5e59b7f3518731f7dfc0f93ace5dee4b",
|
||||||
|
"0x1c4dc6653a445bbef2add81d8e90a6c8591a788deb91d0d3f1519a2e4a460313041b77c1b0817f2e80b388e5c3e49f37d787dc1f85e4324a"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x987c5ac19dd4b47835466a50b2d9feba7c8491b8885a04edf577e15a9f2c98b203ec2cd3e5390b3d20bba0fa6fc3eecefb5029a317234401",
|
||||||
|
"y": "0x5e273fcfff6b007bb6771e90509275a71ff1480c459ded26fc7b10664db0a68aaa98bc7ecb07e49cf05b80ae5ac653fbdd14276bbd35ccbc"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0xd1a5eba4a332514b69760948af09ceaeddbbb9fd4cb1f19b78349c2ee4cf9ee86dbcf9064659a4a0566fe9c34d90aec86f0801edc131ad9b",
|
||||||
|
"y": "0x5d0a75a3014c3269c33b1b5da80706a4f097893461df286353484d8031cd607c98edc2a846c77a841f057c7251eb45077853c7b205957e52"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x69583b00dc6b2aced6ffa44630cc8c8cd0dd0649f57588dd0fb1daad2ce132e281d01e3f25ccd3f405be759975c6484268bfe8f5e5f23c30",
|
||||||
|
"y": "0x8418484035f60bdccf48cb488634c2dfb40272123435f7e654fb6f254c6c42e7e38f1fa79a637a168a28de6c275232b704f9ded0ff76dd94"
|
||||||
|
},
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"u": [
|
||||||
|
"0x163c79ab0210a4b5e4f44fb19437ea965bf5431ab233ef16606f0b03c5f16a3feb7d46a5a675ce8f606e9c2bf74ee5336c54a1e54919f13f",
|
||||||
|
"0xf99666bde4995c4088333d6c2734687e815f80a99c6da02c47df4b51f6c9d9ed466b4fecf7d9884990a8e0d0be6907fa437e0b1a27f49265"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
78
test/hash-to-curve/expand_message_xmd_SHA256_256.json
Normal file
78
test/hash-to-curve/expand_message_xmd_SHA256_256.json
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
{
|
||||||
|
"DST": "QUUX-V01-CS02-with-expander-SHA256-128-long-DST-1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111",
|
||||||
|
"hash": "SHA256",
|
||||||
|
"k": 128,
|
||||||
|
"name": "expand_message_xmd",
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"DST_prime": "412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "",
|
||||||
|
"msg_prime": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620",
|
||||||
|
"uniform_bytes": "e8dc0c8b686b7ef2074086fbdd2f30e3f8bfbd3bdf177f73f04b97ce618a3ed3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "abc",
|
||||||
|
"msg_prime": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000616263002000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620",
|
||||||
|
"uniform_bytes": "52dbf4f36cf560fca57dedec2ad924ee9c266341d8f3d6afe5171733b16bbb12"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"msg_prime": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061626364656630313233343536373839002000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620",
|
||||||
|
"uniform_bytes": "35387dcf22618f3728e6c686490f8b431f76550b0b2c61cbc1ce7001536f4521"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"msg_prime": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000713132385f7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171002000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620",
|
||||||
|
"uniform_bytes": "01b637612bb18e840028be900a833a74414140dde0c4754c198532c3a0ba42bc"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"msg_prime": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000613531325f6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161002000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620",
|
||||||
|
"uniform_bytes": "20cce7033cabc5460743180be6fa8aac5a103f56d481cf369a8accc0c374431b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "",
|
||||||
|
"msg_prime": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620",
|
||||||
|
"uniform_bytes": "14604d85432c68b757e485c8894db3117992fc57e0e136f71ad987f789a0abc287c47876978e2388a02af86b1e8d1342e5ce4f7aaa07a87321e691f6fba7e0072eecc1218aebb89fb14a0662322d5edbd873f0eb35260145cd4e64f748c5dfe60567e126604bcab1a3ee2dc0778102ae8a5cfd1429ebc0fa6bf1a53c36f55dfc"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "abc",
|
||||||
|
"msg_prime": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000616263008000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620",
|
||||||
|
"uniform_bytes": "1a30a5e36fbdb87077552b9d18b9f0aee16e80181d5b951d0471d55b66684914aef87dbb3626eaabf5ded8cd0686567e503853e5c84c259ba0efc37f71c839da2129fe81afdaec7fbdc0ccd4c794727a17c0d20ff0ea55e1389d6982d1241cb8d165762dbc39fb0cee4474d2cbbd468a835ae5b2f20e4f959f56ab24cd6fe267"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"msg_prime": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061626364656630313233343536373839008000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620",
|
||||||
|
"uniform_bytes": "d2ecef3635d2397f34a9f86438d772db19ffe9924e28a1caf6f1c8f15603d4028f40891044e5c7e39ebb9b31339979ff33a4249206f67d4a1e7c765410bcd249ad78d407e303675918f20f26ce6d7027ed3774512ef5b00d816e51bfcc96c3539601fa48ef1c07e494bdc37054ba96ecb9dbd666417e3de289d4f424f502a982"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"msg_prime": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000713132385f7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171008000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620",
|
||||||
|
"uniform_bytes": "ed6e8c036df90111410431431a232d41a32c86e296c05d426e5f44e75b9a50d335b2412bc6c91e0a6dc131de09c43110d9180d0a70f0d6289cb4e43b05f7ee5e9b3f42a1fad0f31bac6a625b3b5c50e3a83316783b649e5ecc9d3b1d9471cb5024b7ccf40d41d1751a04ca0356548bc6e703fca02ab521b505e8e45600508d32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"msg_prime": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000613531325f6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161008000412717974da474d0f8c420f320ff81e8432adb7c927d9bd082b4fb4d16c0a23620",
|
||||||
|
"uniform_bytes": "78b53f2413f3c688f07732c10e5ced29a17c6a16f717179ffbe38d92d6c9ec296502eb9889af83a1928cd162e845b0d3c5424e83280fed3d10cffb2f8431f14e7a23f4c68819d40617589e4c41169d0b56e0e3535be1fd71fbb08bb70c5b5ffed953d6c14bf7618b35fc1f4c4b30538236b4b08c9fbf90462447a8ada60be495"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
78
test/hash-to-curve/expand_message_xmd_SHA256_38.json
Normal file
78
test/hash-to-curve/expand_message_xmd_SHA256_38.json
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
{
|
||||||
|
"DST": "QUUX-V01-CS02-with-expander-SHA256-128",
|
||||||
|
"hash": "SHA256",
|
||||||
|
"k": 128,
|
||||||
|
"name": "expand_message_xmd",
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "",
|
||||||
|
"msg_prime": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826",
|
||||||
|
"uniform_bytes": "68a985b87eb6b46952128911f2a4412bbc302a9d759667f87f7a21d803f07235"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "abc",
|
||||||
|
"msg_prime": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000616263002000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826",
|
||||||
|
"uniform_bytes": "d8ccab23b5985ccea865c6c97b6e5b8350e794e603b4b97902f53a8a0d605615"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"msg_prime": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061626364656630313233343536373839002000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826",
|
||||||
|
"uniform_bytes": "eff31487c770a893cfb36f912fbfcbff40d5661771ca4b2cb4eafe524333f5c1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"msg_prime": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000713132385f7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171002000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826",
|
||||||
|
"uniform_bytes": "b23a1d2b4d97b2ef7785562a7e8bac7eed54ed6e97e29aa51bfe3f12ddad1ff9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"msg_prime": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000613531325f6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161002000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826",
|
||||||
|
"uniform_bytes": "4623227bcc01293b8c130bf771da8c298dede7383243dc0993d2d94823958c4c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "",
|
||||||
|
"msg_prime": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826",
|
||||||
|
"uniform_bytes": "af84c27ccfd45d41914fdff5df25293e221afc53d8ad2ac06d5e3e29485dadbee0d121587713a3e0dd4d5e69e93eb7cd4f5df4cd103e188cf60cb02edc3edf18eda8576c412b18ffb658e3dd6ec849469b979d444cf7b26911a08e63cf31f9dcc541708d3491184472c2c29bb749d4286b004ceb5ee6b9a7fa5b646c993f0ced"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "abc",
|
||||||
|
"msg_prime": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000616263008000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826",
|
||||||
|
"uniform_bytes": "abba86a6129e366fc877aab32fc4ffc70120d8996c88aee2fe4b32d6c7b6437a647e6c3163d40b76a73cf6a5674ef1d890f95b664ee0afa5359a5c4e07985635bbecbac65d747d3d2da7ec2b8221b17b0ca9dc8a1ac1c07ea6a1e60583e2cb00058e77b7b72a298425cd1b941ad4ec65e8afc50303a22c0f99b0509b4c895f40"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"msg_prime": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061626364656630313233343536373839008000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826",
|
||||||
|
"uniform_bytes": "ef904a29bffc4cf9ee82832451c946ac3c8f8058ae97d8d629831a74c6572bd9ebd0df635cd1f208e2038e760c4994984ce73f0d55ea9f22af83ba4734569d4bc95e18350f740c07eef653cbb9f87910d833751825f0ebefa1abe5420bb52be14cf489b37fe1a72f7de2d10be453b2c9d9eb20c7e3f6edc5a60629178d9478df"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"msg_prime": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000713132385f7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171008000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826",
|
||||||
|
"uniform_bytes": "80be107d0884f0d881bb460322f0443d38bd222db8bd0b0a5312a6fedb49c1bbd88fd75d8b9a09486c60123dfa1d73c1cc3169761b17476d3c6b7cbbd727acd0e2c942f4dd96ae3da5de368d26b32286e32de7e5a8cb2949f866a0b80c58116b29fa7fabb3ea7d520ee603e0c25bcaf0b9a5e92ec6a1fe4e0391d1cdbce8c68a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"msg_prime": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000613531325f6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161008000515555582d5630312d435330322d776974682d657870616e6465722d5348413235362d31323826",
|
||||||
|
"uniform_bytes": "546aff5444b5b79aa6148bd81728704c32decb73a3ba76e9e75885cad9def1d06d6792f8a7d12794e90efed817d96920d728896a4510864370c207f99bd4a608ea121700ef01ed879745ee3e4ceef777eda6d9e5e38b90c86ea6fb0b36504ba4a45d22e86f6db5dd43d98a294bebb9125d5b794e9d2a81181066eb954966a487"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
78
test/hash-to-curve/expand_message_xmd_SHA512_38.json
Normal file
78
test/hash-to-curve/expand_message_xmd_SHA512_38.json
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
{
|
||||||
|
"DST": "QUUX-V01-CS02-with-expander-SHA512-256",
|
||||||
|
"hash": "SHA512",
|
||||||
|
"k": 256,
|
||||||
|
"name": "expand_message_xmd",
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "",
|
||||||
|
"msg_prime": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626",
|
||||||
|
"uniform_bytes": "6b9a7312411d92f921c6f68ca0b6380730a1a4d982c507211a90964c394179ba"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "abc",
|
||||||
|
"msg_prime": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000616263002000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626",
|
||||||
|
"uniform_bytes": "0da749f12fbe5483eb066a5f595055679b976e93abe9be6f0f6318bce7aca8dc"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"msg_prime": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061626364656630313233343536373839002000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626",
|
||||||
|
"uniform_bytes": "087e45a86e2939ee8b91100af1583c4938e0f5fc6c9db4b107b83346bc967f58"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"msg_prime": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000713132385f7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171002000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626",
|
||||||
|
"uniform_bytes": "7336234ee9983902440f6bc35b348352013becd88938d2afec44311caf8356b3"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"msg_prime": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000613531325f6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161002000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626",
|
||||||
|
"uniform_bytes": "57b5f7e766d5be68a6bfe1768e3c2b7f1228b3e4b3134956dd73a59b954c66f4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "",
|
||||||
|
"msg_prime": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626",
|
||||||
|
"uniform_bytes": "41b037d1734a5f8df225dd8c7de38f851efdb45c372887be655212d07251b921b052b62eaed99b46f72f2ef4cc96bfaf254ebbbec091e1a3b9e4fb5e5b619d2e0c5414800a1d882b62bb5cd1778f098b8eb6cb399d5d9d18f5d5842cf5d13d7eb00a7cff859b605da678b318bd0e65ebff70bec88c753b159a805d2c89c55961"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "abc",
|
||||||
|
"msg_prime": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000616263008000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626",
|
||||||
|
"uniform_bytes": "7f1dddd13c08b543f2e2037b14cefb255b44c83cc397c1786d975653e36a6b11bdd7732d8b38adb4a0edc26a0cef4bb45217135456e58fbca1703cd6032cb1347ee720b87972d63fbf232587043ed2901bce7f22610c0419751c065922b488431851041310ad659e4b23520e1772ab29dcdeb2002222a363f0c2b1c972b3efe1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"msg_prime": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000061626364656630313233343536373839008000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626",
|
||||||
|
"uniform_bytes": "3f721f208e6199fe903545abc26c837ce59ac6fa45733f1baaf0222f8b7acb0424814fcb5eecf6c1d38f06e9d0a6ccfbf85ae612ab8735dfdf9ce84c372a77c8f9e1c1e952c3a61b7567dd0693016af51d2745822663d0c2367e3f4f0bed827feecc2aaf98c949b5ed0d35c3f1023d64ad1407924288d366ea159f46287e61ac"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"msg_prime": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000713132385f7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171008000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626",
|
||||||
|
"uniform_bytes": "b799b045a58c8d2b4334cf54b78260b45eec544f9f2fb5bd12fb603eaee70db7317bf807c406e26373922b7b8920fa29142703dd52bdf280084fb7ef69da78afdf80b3586395b433dc66cde048a258e476a561e9deba7060af40adf30c64249ca7ddea79806ee5beb9a1422949471d267b21bc88e688e4014087a0b592b695ed"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"msg_prime": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000613531325f6161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161008000515555582d5630312d435330322d776974682d657870616e6465722d5348413531322d32353626",
|
||||||
|
"uniform_bytes": "05b0bfef265dcee87654372777b7c44177e2ae4c13a27f103340d9cd11c86cb2426ffcad5bd964080c2aee97f03be1ca18e30a1f14e27bc11ebbd650f305269cc9fb1db08bf90bfc79b42a952b46daf810359e7bc36452684784a64952c343c52e5124cd1f71d474d5197fefc571a92929c9084ffe1112cf5eea5192ebff330b"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
78
test/hash-to-curve/expand_message_xof_SHAKE128_256.json
Normal file
78
test/hash-to-curve/expand_message_xof_SHAKE128_256.json
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
{
|
||||||
|
"DST": "QUUX-V01-CS02-with-expander-SHAKE128-long-DST-111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111",
|
||||||
|
"hash": "SHAKE128",
|
||||||
|
"k": 128,
|
||||||
|
"name": "expand_message_xof",
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"DST_prime": "acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "",
|
||||||
|
"msg_prime": "0020acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20",
|
||||||
|
"uniform_bytes": "827c6216330a122352312bccc0c8d6e7a146c5257a776dbd9ad9d75cd880fc53"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "abc",
|
||||||
|
"msg_prime": "6162630020acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20",
|
||||||
|
"uniform_bytes": "690c8d82c7213b4282c6cb41c00e31ea1d3e2005f93ad19bbf6da40f15790c5c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"msg_prime": "616263646566303132333435363738390020acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20",
|
||||||
|
"uniform_bytes": "979e3a15064afbbcf99f62cc09fa9c85028afcf3f825eb0711894dcfc2f57057"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"msg_prime": "713132385f71717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171710020acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20",
|
||||||
|
"uniform_bytes": "c5a9220962d9edc212c063f4f65b609755a1ed96e62f9db5d1fd6adb5a8dc52b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"msg_prime": "613531325f61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610020acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20",
|
||||||
|
"uniform_bytes": "f7b96a5901af5d78ce1d071d9c383cac66a1dfadb508300ec6aeaea0d62d5d62"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "",
|
||||||
|
"msg_prime": "0080acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20",
|
||||||
|
"uniform_bytes": "3890dbab00a2830be398524b71c2713bbef5f4884ac2e6f070b092effdb19208c7df943dc5dcbaee3094a78c267ef276632ee2c8ea0c05363c94b6348500fae4208345dd3475fe0c834c2beac7fa7bc181692fb728c0a53d809fc8111495222ce0f38468b11becb15b32060218e285c57a60162c2c8bb5b6bded13973cd41819"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "abc",
|
||||||
|
"msg_prime": "6162630080acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20",
|
||||||
|
"uniform_bytes": "41b7ffa7a301b5c1441495ebb9774e2a53dbbf4e54b9a1af6a20fd41eafd69ef7b9418599c5545b1ee422f363642b01d4a53449313f68da3e49dddb9cd25b97465170537d45dcbdf92391b5bdff344db4bd06311a05bca7dcd360b6caec849c299133e5c9194f4e15e3e23cfaab4003fab776f6ac0bfae9144c6e2e1c62e7d57"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"msg_prime": "616263646566303132333435363738390080acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20",
|
||||||
|
"uniform_bytes": "55317e4a21318472cd2290c3082957e1242241d9e0d04f47026f03401643131401071f01aa03038b2783e795bdfa8a3541c194ad5de7cb9c225133e24af6c86e748deb52e560569bd54ef4dac03465111a3a44b0ea490fb36777ff8ea9f1a8a3e8e0de3cf0880b4b2f8dd37d3a85a8b82375aee4fa0e909f9763319b55778e71"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"msg_prime": "713132385f71717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171710080acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20",
|
||||||
|
"uniform_bytes": "19fdd2639f082e31c77717ac9bb032a22ff0958382b2dbb39020cdc78f0da43305414806abf9a561cb2d0067eb2f7bc544482f75623438ed4b4e39dd9e6e2909dd858bd8f1d57cd0fce2d3150d90aa67b4498bdf2df98c0100dd1a173436ba5d0df6be1defb0b2ce55ccd2f4fc05eb7cb2c019c35d5398b85adc676da4238bc7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"msg_prime": "613531325f61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610080acb9736c0867fdfbd6385519b90fc8c034b5af04a958973212950132d035792f20",
|
||||||
|
"uniform_bytes": "945373f0b3431a103333ba6a0a34f1efab2702efde41754c4cb1d5216d5b0a92a67458d968562bde7fa6310a83f53dda1383680a276a283438d58ceebfa7ab7ba72499d4a3eddc860595f63c93b1c5e823ea41fc490d938398a26db28f61857698553e93f0574eb8c5017bfed6249491f9976aaa8d23d9485339cc85ca329308"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
78
test/hash-to-curve/expand_message_xof_SHAKE128_36.json
Normal file
78
test/hash-to-curve/expand_message_xof_SHAKE128_36.json
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
{
|
||||||
|
"DST": "QUUX-V01-CS02-with-expander-SHAKE128",
|
||||||
|
"hash": "SHAKE128",
|
||||||
|
"k": 128,
|
||||||
|
"name": "expand_message_xof",
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "",
|
||||||
|
"msg_prime": "0020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824",
|
||||||
|
"uniform_bytes": "86518c9cd86581486e9485aa74ab35ba150d1c75c88e26b7043e44e2acd735a2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "abc",
|
||||||
|
"msg_prime": "6162630020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824",
|
||||||
|
"uniform_bytes": "8696af52a4d862417c0763556073f47bc9b9ba43c99b505305cb1ec04a9ab468"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"msg_prime": "616263646566303132333435363738390020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824",
|
||||||
|
"uniform_bytes": "912c58deac4821c3509dbefa094df54b34b8f5d01a191d1d3108a2c89077acca"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"msg_prime": "713132385f71717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171710020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824",
|
||||||
|
"uniform_bytes": "1adbcc448aef2a0cebc71dac9f756b22e51839d348e031e63b33ebb50faeaf3f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"msg_prime": "613531325f61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824",
|
||||||
|
"uniform_bytes": "df3447cc5f3e9a77da10f819218ddf31342c310778e0e4ef72bbaecee786a4fe"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "",
|
||||||
|
"msg_prime": "0080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824",
|
||||||
|
"uniform_bytes": "7314ff1a155a2fb99a0171dc71b89ab6e3b2b7d59e38e64419b8b6294d03ffee42491f11370261f436220ef787f8f76f5b26bdcd850071920ce023f3ac46847744f4612b8714db8f5db83205b2e625d95afd7d7b4d3094d3bdde815f52850bb41ead9822e08f22cf41d615a303b0d9dde73263c049a7b9898208003a739a2e57"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "abc",
|
||||||
|
"msg_prime": "6162630080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824",
|
||||||
|
"uniform_bytes": "c952f0c8e529ca8824acc6a4cab0e782fc3648c563ddb00da7399f2ae35654f4860ec671db2356ba7baa55a34a9d7f79197b60ddae6e64768a37d699a78323496db3878c8d64d909d0f8a7de4927dcab0d3dbbc26cb20a49eceb0530b431cdf47bc8c0fa3e0d88f53b318b6739fbed7d7634974f1b5c386d6230c76260d5337a"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"msg_prime": "616263646566303132333435363738390080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824",
|
||||||
|
"uniform_bytes": "19b65ee7afec6ac06a144f2d6134f08eeec185f1a890fe34e68f0e377b7d0312883c048d9b8a1d6ecc3b541cb4987c26f45e0c82691ea299b5e6889bbfe589153016d8131717ba26f07c3c14ffbef1f3eff9752e5b6183f43871a78219a75e7000fbac6a7072e2b83c790a3a5aecd9d14be79f9fd4fb180960a3772e08680495"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"msg_prime": "713132385f71717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171710080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824",
|
||||||
|
"uniform_bytes": "ca1b56861482b16eae0f4a26212112362fcc2d76dcc80c93c4182ed66c5113fe41733ed68be2942a3487394317f3379856f4822a611735e50528a60e7ade8ec8c71670fec6661e2c59a09ed36386513221688b35dc47e3c3111ee8c67ff49579089d661caa29db1ef10eb6eace575bf3dc9806e7c4016bd50f3c0e2a6481ee6d"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"msg_prime": "613531325f61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4531323824",
|
||||||
|
"uniform_bytes": "9d763a5ce58f65c91531b4100c7266d479a5d9777ba761693d052acd37d149e7ac91c796a10b919cd74a591a1e38719fb91b7203e2af31eac3bff7ead2c195af7d88b8bc0a8adf3d1e90ab9bed6ddc2b7f655dd86c730bdeaea884e73741097142c92f0e3fc1811b699ba593c7fbd81da288a29d423df831652e3a01a9374999"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
78
test/hash-to-curve/expand_message_xof_SHAKE256_36.json
Normal file
78
test/hash-to-curve/expand_message_xof_SHAKE256_36.json
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
{
|
||||||
|
"DST": "QUUX-V01-CS02-with-expander-SHAKE256",
|
||||||
|
"hash": "SHAKE256",
|
||||||
|
"k": 256,
|
||||||
|
"name": "expand_message_xof",
|
||||||
|
"tests": [
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "",
|
||||||
|
"msg_prime": "0020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624",
|
||||||
|
"uniform_bytes": "2ffc05c48ed32b95d72e807f6eab9f7530dd1c2f013914c8fed38c5ccc15ad76"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "abc",
|
||||||
|
"msg_prime": "6162630020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624",
|
||||||
|
"uniform_bytes": "b39e493867e2767216792abce1f2676c197c0692aed061560ead251821808e07"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"msg_prime": "616263646566303132333435363738390020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624",
|
||||||
|
"uniform_bytes": "245389cf44a13f0e70af8665fe5337ec2dcd138890bb7901c4ad9cfceb054b65"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"msg_prime": "713132385f71717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171710020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624",
|
||||||
|
"uniform_bytes": "719b3911821e6428a5ed9b8e600f2866bcf23c8f0515e52d6c6c019a03f16f0e"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624",
|
||||||
|
"len_in_bytes": "0x20",
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"msg_prime": "613531325f61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610020515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624",
|
||||||
|
"uniform_bytes": "9181ead5220b1963f1b5951f35547a5ea86a820562287d6ca4723633d17ccbbc"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "",
|
||||||
|
"msg_prime": "0080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624",
|
||||||
|
"uniform_bytes": "7a1361d2d7d82d79e035b8880c5a3c86c5afa719478c007d96e6c88737a3f631dd74a2c88df79a4cb5e5d9f7504957c70d669ec6bfedc31e01e2bacc4ff3fdf9b6a00b17cc18d9d72ace7d6b81c2e481b4f73f34f9a7505dccbe8f5485f3d20c5409b0310093d5d6492dea4e18aa6979c23c8ea5de01582e9689612afbb353df"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "abc",
|
||||||
|
"msg_prime": "6162630080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624",
|
||||||
|
"uniform_bytes": "a54303e6b172909783353ab05ef08dd435a558c3197db0c132134649708e0b9b4e34fb99b92a9e9e28fc1f1d8860d85897a8e021e6382f3eea10577f968ff6df6c45fe624ce65ca25932f679a42a404bc3681efe03fcd45ef73bb3a8f79ba784f80f55ea8a3c367408f30381299617f50c8cf8fbb21d0f1e1d70b0131a7b6fbe"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"msg_prime": "616263646566303132333435363738390080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624",
|
||||||
|
"uniform_bytes": "e42e4d9538a189316e3154b821c1bafb390f78b2f010ea404e6ac063deb8c0852fcd412e098e231e43427bd2be1330bb47b4039ad57b30ae1fc94e34993b162ff4d695e42d59d9777ea18d3848d9d336c25d2acb93adcad009bcfb9cde12286df267ada283063de0bb1505565b2eb6c90e31c48798ecdc71a71756a9110ff373"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"msg_prime": "713132385f71717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171710080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624",
|
||||||
|
"uniform_bytes": "4ac054dda0a38a65d0ecf7afd3c2812300027c8789655e47aecf1ecc1a2426b17444c7482c99e5907afd9c25b991990490bb9c686f43e79b4471a23a703d4b02f23c669737a886a7ec28bddb92c3a98de63ebf878aa363a501a60055c048bea11840c4717beae7eee28c3cfa42857b3d130188571943a7bd747de831bd6444e0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DST_prime": "515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624",
|
||||||
|
"len_in_bytes": "0x80",
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"msg_prime": "613531325f61616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161610080515555582d5630312d435330322d776974682d657870616e6465722d5348414b4532353624",
|
||||||
|
"uniform_bytes": "09afc76d51c2cccbc129c2315df66c2be7295a231203b8ab2dd7f95c2772c68e500bc72e20c602abc9964663b7a03a389be128c56971ce81001a0b875e7fd17822db9d69792ddf6a23a151bf470079c518279aef3e75611f8f828994a9988f4a8a256ddb8bae161e658d5a2a09bcfe839c6396dc06ee5c8ff3c22d3b1f9deb7e"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
90
test/hash-to-curve/secp256k1_XMD:SHA-256_SSWU_NU_.json
Normal file
90
test/hash-to-curve/secp256k1_XMD:SHA-256_SSWU_NU_.json
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
{
|
||||||
|
"L": "0x30",
|
||||||
|
"Z": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc24",
|
||||||
|
"ciphersuite": "secp256k1_XMD:SHA-256_SSWU_NU_",
|
||||||
|
"curve": "secp256k1",
|
||||||
|
"dst": "QUUX-V01-CS02-with-secp256k1_XMD:SHA-256_SSWU_NU_",
|
||||||
|
"expand": "XMD",
|
||||||
|
"field": {
|
||||||
|
"m": "0x1",
|
||||||
|
"p": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"
|
||||||
|
},
|
||||||
|
"hash": "sha256",
|
||||||
|
"k": "0x80",
|
||||||
|
"map": {
|
||||||
|
"name": "SSWU"
|
||||||
|
},
|
||||||
|
"randomOracle": false,
|
||||||
|
"vectors": [
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0xa4792346075feae77ac3b30026f99c1441b4ecf666ded19b7522cf65c4c55c5b",
|
||||||
|
"y": "0x62c59e2a6aeed1b23be5883e833912b08ba06be7f57c0e9cdc663f31639ff3a7"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0xa4792346075feae77ac3b30026f99c1441b4ecf666ded19b7522cf65c4c55c5b",
|
||||||
|
"y": "0x62c59e2a6aeed1b23be5883e833912b08ba06be7f57c0e9cdc663f31639ff3a7"
|
||||||
|
},
|
||||||
|
"msg": "",
|
||||||
|
"u": [
|
||||||
|
"0x0137fcd23bc3da962e8808f97474d097a6c8aa2881fceef4514173635872cf3b"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x3f3b5842033fff837d504bb4ce2a372bfeadbdbd84a1d2b678b6e1d7ee426b9d",
|
||||||
|
"y": "0x902910d1fef15d8ae2006fc84f2a5a7bda0e0407dc913062c3a493c4f5d876a5"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x3f3b5842033fff837d504bb4ce2a372bfeadbdbd84a1d2b678b6e1d7ee426b9d",
|
||||||
|
"y": "0x902910d1fef15d8ae2006fc84f2a5a7bda0e0407dc913062c3a493c4f5d876a5"
|
||||||
|
},
|
||||||
|
"msg": "abc",
|
||||||
|
"u": [
|
||||||
|
"0xe03f894b4d7caf1a50d6aa45cac27412c8867a25489e32c5ddeb503229f63a2e"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x07644fa6281c694709f53bdd21bed94dab995671e4a8cd1904ec4aa50c59bfdf",
|
||||||
|
"y": "0xc79f8d1dad79b6540426922f7fbc9579c3018dafeffcd4552b1626b506c21e7b"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x07644fa6281c694709f53bdd21bed94dab995671e4a8cd1904ec4aa50c59bfdf",
|
||||||
|
"y": "0xc79f8d1dad79b6540426922f7fbc9579c3018dafeffcd4552b1626b506c21e7b"
|
||||||
|
},
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"u": [
|
||||||
|
"0xe7a6525ae7069ff43498f7f508b41c57f80563c1fe4283510b322446f32af41b"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0xb734f05e9b9709ab631d960fa26d669c4aeaea64ae62004b9d34f483aa9acc33",
|
||||||
|
"y": "0x03fc8a4a5a78632e2eb4d8460d69ff33c1d72574b79a35e402e801f2d0b1d6ee"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0xb734f05e9b9709ab631d960fa26d669c4aeaea64ae62004b9d34f483aa9acc33",
|
||||||
|
"y": "0x03fc8a4a5a78632e2eb4d8460d69ff33c1d72574b79a35e402e801f2d0b1d6ee"
|
||||||
|
},
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"u": [
|
||||||
|
"0xd97cf3d176a2f26b9614a704d7d434739d194226a706c886c5c3c39806bc323c"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x17d22b867658977b5002dbe8d0ee70a8cfddec3eec50fb93f36136070fd9fa6c",
|
||||||
|
"y": "0xe9178ff02f4dab73480f8dd590328aea99856a7b6cc8e5a6cdf289ecc2a51718"
|
||||||
|
},
|
||||||
|
"Q": {
|
||||||
|
"x": "0x17d22b867658977b5002dbe8d0ee70a8cfddec3eec50fb93f36136070fd9fa6c",
|
||||||
|
"y": "0xe9178ff02f4dab73480f8dd590328aea99856a7b6cc8e5a6cdf289ecc2a51718"
|
||||||
|
},
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"u": [
|
||||||
|
"0xa9ffbeee1d6e41ac33c248fb3364612ff591b502386c1bf6ac4aaf1ea51f8c3b"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
115
test/hash-to-curve/secp256k1_XMD:SHA-256_SSWU_RO_.json
Normal file
115
test/hash-to-curve/secp256k1_XMD:SHA-256_SSWU_RO_.json
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
{
|
||||||
|
"L": "0x30",
|
||||||
|
"Z": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc24",
|
||||||
|
"ciphersuite": "secp256k1_XMD:SHA-256_SSWU_RO_",
|
||||||
|
"curve": "secp256k1",
|
||||||
|
"dst": "QUUX-V01-CS02-with-secp256k1_XMD:SHA-256_SSWU_RO_",
|
||||||
|
"expand": "XMD",
|
||||||
|
"field": {
|
||||||
|
"m": "0x1",
|
||||||
|
"p": "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"
|
||||||
|
},
|
||||||
|
"hash": "sha256",
|
||||||
|
"k": "0x80",
|
||||||
|
"map": {
|
||||||
|
"name": "SSWU"
|
||||||
|
},
|
||||||
|
"randomOracle": true,
|
||||||
|
"vectors": [
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0xc1cae290e291aee617ebaef1be6d73861479c48b841eaba9b7b5852ddfeb1346",
|
||||||
|
"y": "0x64fa678e07ae116126f08b022a94af6de15985c996c3a91b64c406a960e51067"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x74519ef88b32b425a095e4ebcc84d81b64e9e2c2675340a720bb1a1857b99f1e",
|
||||||
|
"y": "0xc174fa322ab7c192e11748beed45b508e9fdb1ce046dee9c2cd3a2a86b410936"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x44548adb1b399263ded3510554d28b4bead34b8cf9a37b4bd0bd2ba4db87ae63",
|
||||||
|
"y": "0x96eb8e2faf05e368efe5957c6167001760233e6dd2487516b46ae725c4cce0c6"
|
||||||
|
},
|
||||||
|
"msg": "",
|
||||||
|
"u": [
|
||||||
|
"0x6b0f9910dd2ba71c78f2ee9f04d73b5f4c5f7fc773a701abea1e573cab002fb3",
|
||||||
|
"0x1ae6c212e08fe1a5937f6202f929a2cc8ef4ee5b9782db68b0d5799fd8f09e16"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0x3377e01eab42db296b512293120c6cee72b6ecf9f9205760bd9ff11fb3cb2c4b",
|
||||||
|
"y": "0x7f95890f33efebd1044d382a01b1bee0900fb6116f94688d487c6c7b9c8371f6"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x07dd9432d426845fb19857d1b3a91722436604ccbbbadad8523b8fc38a5322d7",
|
||||||
|
"y": "0x604588ef5138cffe3277bbd590b8550bcbe0e523bbaf1bed4014a467122eb33f"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0xe9ef9794d15d4e77dde751e06c182782046b8dac05f8491eb88764fc65321f78",
|
||||||
|
"y": "0xcb07ce53670d5314bf236ee2c871455c562dd76314aa41f012919fe8e7f717b3"
|
||||||
|
},
|
||||||
|
"msg": "abc",
|
||||||
|
"u": [
|
||||||
|
"0x128aab5d3679a1f7601e3bdf94ced1f43e491f544767e18a4873f397b08a2b61",
|
||||||
|
"0x5897b65da3b595a813d0fdcc75c895dc531be76a03518b044daaa0f2e4689e00"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0xbac54083f293f1fe08e4a70137260aa90783a5cb84d3f35848b324d0674b0e3a",
|
||||||
|
"y": "0x4436476085d4c3c4508b60fcf4389c40176adce756b398bdee27bca19758d828"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x576d43ab0260275adf11af990d130a5752704f79478628761720808862544b5d",
|
||||||
|
"y": "0x643c4a7fb68ae6cff55edd66b809087434bbaff0c07f3f9ec4d49bb3c16623c3"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0xf89d6d261a5e00fe5cf45e827b507643e67c2a947a20fd9ad71039f8b0e29ff8",
|
||||||
|
"y": "0xb33855e0cc34a9176ead91c6c3acb1aacb1ce936d563bc1cee1dcffc806caf57"
|
||||||
|
},
|
||||||
|
"msg": "abcdef0123456789",
|
||||||
|
"u": [
|
||||||
|
"0xea67a7c02f2cd5d8b87715c169d055a22520f74daeb080e6180958380e2f98b9",
|
||||||
|
"0x7434d0d1a500d38380d1f9615c021857ac8d546925f5f2355319d823a478da18"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0xe2167bc785333a37aa562f021f1e881defb853839babf52a7f72b102e41890e9",
|
||||||
|
"y": "0xf2401dd95cc35867ffed4f367cd564763719fbc6a53e969fb8496a1e6685d873"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0x9c91513ccfe9520c9c645588dff5f9b4e92eaf6ad4ab6f1cd720d192eb58247a",
|
||||||
|
"y": "0xc7371dcd0134412f221e386f8d68f49e7fa36f9037676e163d4a063fbf8a1fb8"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x10fee3284d7be6bd5912503b972fc52bf4761f47141a0015f1c6ae36848d869b",
|
||||||
|
"y": "0x0b163d9b4bf21887364332be3eff3c870fa053cf508732900fc69a6eb0e1b672"
|
||||||
|
},
|
||||||
|
"msg": "q128_qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq",
|
||||||
|
"u": [
|
||||||
|
"0xeda89a5024fac0a8207a87e8cc4e85aa3bce10745d501a30deb87341b05bcdf5",
|
||||||
|
"0xdfe78cd116818fc2c16f3837fedbe2639fab012c407eac9dfe9245bf650ac51d"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"P": {
|
||||||
|
"x": "0xe3c8d35aaaf0b9b647e88a0a0a7ee5d5bed5ad38238152e4e6fd8c1f8cb7c998",
|
||||||
|
"y": "0x8446eeb6181bf12f56a9d24e262221cc2f0c4725c7e3803024b5888ee5823aa6"
|
||||||
|
},
|
||||||
|
"Q0": {
|
||||||
|
"x": "0xb32b0ab55977b936f1e93fdc68cec775e13245e161dbfe556bbb1f72799b4181",
|
||||||
|
"y": "0x2f5317098360b722f132d7156a94822641b615c91f8663be69169870a12af9e8"
|
||||||
|
},
|
||||||
|
"Q1": {
|
||||||
|
"x": "0x148f98780f19388b9fa93e7dc567b5a673e5fca7079cd9cdafd71982ec4c5e12",
|
||||||
|
"y": "0x3989645d83a433bc0c001f3dac29af861f33a6fd1e04f4b36873f5bff497298a"
|
||||||
|
},
|
||||||
|
"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||||
|
"u": [
|
||||||
|
"0x8d862e7e7e23d7843fe16d811d46d7e6480127a6b78838c277bca17df6900e9f",
|
||||||
|
"0x68071d2530f040f081ba818d3c7188a94c900586761e9115efa47ae9bd847938"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -9,5 +9,6 @@ import './secp256k1.test.js';
|
|||||||
import './stark/stark.test.js';
|
import './stark/stark.test.js';
|
||||||
import './jubjub.test.js';
|
import './jubjub.test.js';
|
||||||
import './bls12-381.test.js';
|
import './bls12-381.test.js';
|
||||||
|
import './hash-to-curve.test.js';
|
||||||
|
|
||||||
should.run();
|
should.run();
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { jubjub, findGroupHash } from '../lib/jubjub.js';
|
import { jubjub, findGroupHash } from '../lib/esm/jubjub.js';
|
||||||
import { should } from 'micro-should';
|
import { should } from 'micro-should';
|
||||||
import { deepStrictEqual, throws } from 'assert';
|
import { deepStrictEqual, throws } from 'assert';
|
||||||
import { hexToBytes, bytesToHex } from '@noble/hashes/utils';
|
import { hexToBytes, bytesToHex } from '@noble/hashes/utils';
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
import { deepStrictEqual, throws } from 'assert';
|
import { deepStrictEqual, throws } from 'assert';
|
||||||
import { should } from 'micro-should';
|
import { should } from 'micro-should';
|
||||||
import { secp192r1, P192 } from '../lib/p192.js';
|
import { secp192r1, P192 } from '../lib/esm/p192.js';
|
||||||
import { secp224r1, P224 } from '../lib/p224.js';
|
import { secp224r1, P224 } from '../lib/esm/p224.js';
|
||||||
import { secp256r1, P256 } from '../lib/p256.js';
|
import { secp256r1, P256 } from '../lib/esm/p256.js';
|
||||||
import { secp384r1, P384 } from '../lib/p384.js';
|
import { secp384r1, P384 } from '../lib/esm/p384.js';
|
||||||
import { secp521r1, P521 } from '../lib/p521.js';
|
import { secp521r1, P521 } from '../lib/esm/p521.js';
|
||||||
import { secp256k1 } from '../lib/secp256k1.js';
|
import { secp256k1 } from '../lib/esm/secp256k1.js';
|
||||||
import { hexToBytes, bytesToHex } from '@noble/curves/utils';
|
import { hexToBytes, bytesToHex } from '../lib/esm/abstract/utils.js';
|
||||||
import { default as ecdsa } from './wycheproof/ecdsa_test.json' assert { type: 'json' };
|
import { default as ecdsa } from './wycheproof/ecdsa_test.json' assert { type: 'json' };
|
||||||
import { default as ecdh } from './wycheproof/ecdh_test.json' assert { type: 'json' };
|
import { default as ecdh } from './wycheproof/ecdh_test.json' assert { type: 'json' };
|
||||||
import { default as rfc6979 } from './fixtures/rfc6979.json' assert { type: 'json' };
|
import { default as rfc6979 } from './fixtures/rfc6979.json' assert { type: 'json' };
|
||||||
@@ -41,10 +41,11 @@ should('wychenproof ECDSA vectors', () => {
|
|||||||
for (const group of ecdsa.testGroups) {
|
for (const group of ecdsa.testGroups) {
|
||||||
// Tested in secp256k1.test.js
|
// Tested in secp256k1.test.js
|
||||||
if (group.key.curve === 'secp256k1') continue;
|
if (group.key.curve === 'secp256k1') continue;
|
||||||
// We don't have SHA-224
|
let CURVE = NIST[group.key.curve];
|
||||||
if (group.key.curve === 'secp224r1' && group.sha === 'SHA-224') continue;
|
|
||||||
const CURVE = NIST[group.key.curve];
|
|
||||||
if (!CURVE) continue;
|
if (!CURVE) continue;
|
||||||
|
if (group.key.curve === 'secp224r1' && group.sha !== 'SHA-224') {
|
||||||
|
if (group.sha === 'SHA-256') CURVE = CURVE.create(sha256);
|
||||||
|
}
|
||||||
const pubKey = CURVE.Point.fromHex(group.key.uncompressed);
|
const pubKey = CURVE.Point.fromHex(group.key.uncompressed);
|
||||||
deepStrictEqual(pubKey.x, BigInt(`0x${group.key.wx}`));
|
deepStrictEqual(pubKey.x, BigInt(`0x${group.key.wx}`));
|
||||||
deepStrictEqual(pubKey.y, BigInt(`0x${group.key.wy}`));
|
deepStrictEqual(pubKey.y, BigInt(`0x${group.key.wy}`));
|
||||||
@@ -196,17 +197,16 @@ import { default as secp521r1_sha512_test } from './wycheproof/ecdsa_secp521r1_s
|
|||||||
|
|
||||||
import { sha3_224, sha3_256, sha3_384, sha3_512 } from '@noble/hashes/sha3';
|
import { sha3_224, sha3_256, sha3_384, sha3_512 } from '@noble/hashes/sha3';
|
||||||
import { sha512, sha384 } from '@noble/hashes/sha512';
|
import { sha512, sha384 } from '@noble/hashes/sha512';
|
||||||
import { sha256 } from '@noble/hashes/sha256';
|
import { sha224, sha256 } from '@noble/hashes/sha256';
|
||||||
|
|
||||||
const WYCHEPROOF_ECDSA = {
|
const WYCHEPROOF_ECDSA = {
|
||||||
P224: {
|
P224: {
|
||||||
curve: P224,
|
curve: P224,
|
||||||
hashes: {
|
hashes: {
|
||||||
// sha224 not released yet
|
sha224: {
|
||||||
// sha224: {
|
hash: sha224,
|
||||||
// hash: sha224,
|
tests: [secp224r1_sha224_test],
|
||||||
// tests: [secp224r1_sha224_test],
|
},
|
||||||
// },
|
|
||||||
sha256: {
|
sha256: {
|
||||||
hash: sha256,
|
hash: sha256,
|
||||||
tests: [secp224r1_sha256_test],
|
tests: [secp224r1_sha256_test],
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as fc from 'fast-check';
|
import * as fc from 'fast-check';
|
||||||
import { secp256k1, schnorr } from '../lib/secp256k1.js';
|
import { secp256k1, schnorr } from '../lib/esm/secp256k1.js';
|
||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
import { default as ecdsa } from './vectors/ecdsa.json' assert { type: 'json' };
|
import { default as ecdsa } from './vectors/ecdsa.json' assert { type: 'json' };
|
||||||
import { default as ecdh } from './vectors/ecdh.json' assert { type: 'json' };
|
import { default as ecdh } from './vectors/ecdh.json' assert { type: 'json' };
|
||||||
@@ -164,15 +164,15 @@ should('secp256k1.Point#multiply(privateKey)', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// multiply() should equal multiplyUnsafe()
|
// multiply() should equal multiplyUnsafe()
|
||||||
// should('JacobianPoint#multiplyUnsafe', () => {
|
// should('ProjectivePoint#multiplyUnsafe', () => {
|
||||||
// const p0 = new secp.JacobianPoint(
|
// const p0 = new secp.ProjectivePoint(
|
||||||
// 55066263022277343669578718895168534326250603453777594175500187360389116729240n,
|
// 55066263022277343669578718895168534326250603453777594175500187360389116729240n,
|
||||||
// 32670510020758816978083085130507043184471273380659243275938904335757337482424n,
|
// 32670510020758816978083085130507043184471273380659243275938904335757337482424n,
|
||||||
// 1n
|
// 1n
|
||||||
// );
|
// );
|
||||||
// const z = 106011723082030650010038151861333186846790370053628296836951575624442507889495n;
|
// const z = 106011723082030650010038151861333186846790370053628296836951575624442507889495n;
|
||||||
// console.log(p0.multiply(z));
|
// console.log(p0.multiply(z));
|
||||||
// console.log(secp.JacobianPoint.normalizeZ([p0.multiplyUnsafe(z)])[0])
|
// console.log(secp.ProjectivePoint.normalizeZ([p0.multiplyUnsafe(z)])[0])
|
||||||
// });
|
// });
|
||||||
|
|
||||||
should('secp256k1.Signature.fromCompactHex() roundtrip', () => {
|
should('secp256k1.Signature.fromCompactHex() roundtrip', () => {
|
||||||
@@ -390,7 +390,6 @@ should('secp256k1.recoverPublicKey()/should handle all-zeros msghash', () => {
|
|||||||
});
|
});
|
||||||
should('secp256k1.recoverPublicKey()/should handle RFC 6979 vectors', () => {
|
should('secp256k1.recoverPublicKey()/should handle RFC 6979 vectors', () => {
|
||||||
for (const vector of ecdsa.valid) {
|
for (const vector of ecdsa.valid) {
|
||||||
if (secp.utils.mod(hexToNumber(vector.m), secp.CURVE.n) === 0n) continue;
|
|
||||||
let usig = secp.sign(vector.m, vector.d);
|
let usig = secp.sign(vector.m, vector.d);
|
||||||
let sig = usig.toDERHex();
|
let sig = usig.toDERHex();
|
||||||
const vpub = secp.getPublicKey(vector.d);
|
const vpub = secp.getPublicKey(vector.d);
|
||||||
@@ -407,8 +406,6 @@ should('secp256k1.getSharedSecret()/should produce correct results', () => {
|
|||||||
// TODO: Once der is there, run all tests.
|
// TODO: Once der is there, run all tests.
|
||||||
for (const vector of ecdh.testGroups[0].tests.slice(0, 230)) {
|
for (const vector of ecdh.testGroups[0].tests.slice(0, 230)) {
|
||||||
if (vector.result === 'invalid' || vector.private.length !== 64) {
|
if (vector.result === 'invalid' || vector.private.length !== 64) {
|
||||||
// We support eth-like hexes
|
|
||||||
if (vector.private.length < 64) continue;
|
|
||||||
throws(() => {
|
throws(() => {
|
||||||
secp.getSharedSecret(vector.private, derToPub(vector.public), true);
|
secp.getSharedSecret(vector.private, derToPub(vector.public), true);
|
||||||
});
|
});
|
||||||
@@ -532,4 +529,8 @@ should('secp256k1.wychenproof vectors', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
should.run();
|
// ESM is broken.
|
||||||
|
import url from 'url';
|
||||||
|
if (import.meta.url === url.pathToFileURL(process.argv[1]).href) {
|
||||||
|
should.run();
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { deepStrictEqual, throws } from 'assert';
|
import { deepStrictEqual, throws } from 'assert';
|
||||||
import { should } from 'micro-should';
|
import { should } from 'micro-should';
|
||||||
import * as starknet from '../../lib/stark.js';
|
import * as starknet from '../../lib/esm/stark.js';
|
||||||
import { default as issue2 } from './fixtures/issue2.json' assert { type: 'json' };
|
import { default as issue2 } from './fixtures/issue2.json' assert { type: 'json' };
|
||||||
|
|
||||||
should('Basic elliptic sanity check', () => {
|
should('Basic elliptic sanity check', () => {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import * as microStark from '../../../lib/stark.js';
|
import * as microStark from '../../../lib/esm/stark.js';
|
||||||
import * as starkwareCrypto from '@starkware-industries/starkware-crypto-utils';
|
import * as starkwareCrypto from '@starkware-industries/starkware-crypto-utils';
|
||||||
import * as bench from 'micro-bmark';
|
import * as bench from 'micro-bmark';
|
||||||
const { run, mark } = bench; // or bench.mark
|
const { run, mark } = bench; // or bench.mark
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { deepStrictEqual, throws } from 'assert';
|
import { deepStrictEqual, throws } from 'assert';
|
||||||
import { should } from 'micro-should';
|
import { should } from 'micro-should';
|
||||||
import * as starknet from '../../lib/stark.js';
|
import * as starknet from '../../lib/esm/stark.js';
|
||||||
import * as fc from 'fast-check';
|
import * as fc from 'fast-check';
|
||||||
|
|
||||||
const FC_BIGINT = fc.bigInt(1n + 1n, starknet.CURVE.n - 1n);
|
const FC_BIGINT = fc.bigInt(1n + 1n, starknet.CURVE.n - 1n);
|
||||||
@@ -3,7 +3,7 @@ import { should } from 'micro-should';
|
|||||||
import { hex, utf8 } from '@scure/base';
|
import { hex, utf8 } from '@scure/base';
|
||||||
import * as bip32 from '@scure/bip32';
|
import * as bip32 from '@scure/bip32';
|
||||||
import * as bip39 from '@scure/bip39';
|
import * as bip39 from '@scure/bip39';
|
||||||
import * as starknet from '../../lib/stark.js';
|
import * as starknet from '../../lib/esm/stark.js';
|
||||||
import { default as sigVec } from './fixtures/rfc6979_signature_test_vector.json' assert { type: 'json' };
|
import { default as sigVec } from './fixtures/rfc6979_signature_test_vector.json' assert { type: 'json' };
|
||||||
import { default as precomputedKeys } from './fixtures/keys_precomputed.json' assert { type: 'json' };
|
import { default as precomputedKeys } from './fixtures/keys_precomputed.json' assert { type: 'json' };
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user