WIP: bootstrap and partial real Solana watcher implementation
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
import { type AffinePoint } from './abstract/curve.ts';
|
||||
import { PrimeEdwardsPoint, type CurveFn, type EdwardsPoint } from './abstract/edwards.ts';
|
||||
import { type H2CHasher, type H2CHasherBase, type H2CMethod, type htfBasicOpts } from './abstract/hash-to-curve.ts';
|
||||
import { type IField } from './abstract/modular.ts';
|
||||
import { type MontgomeryECDH as XCurveFn } from './abstract/montgomery.ts';
|
||||
import { type Hex } from './utils.ts';
|
||||
/**
|
||||
* ed25519 curve with EdDSA signatures.
|
||||
* @example
|
||||
* import { ed25519 } from '@noble/curves/ed25519';
|
||||
* const { secretKey, publicKey } = ed25519.keygen();
|
||||
* const msg = new TextEncoder().encode('hello');
|
||||
* const sig = ed25519.sign(msg, priv);
|
||||
* ed25519.verify(sig, msg, pub); // Default mode: follows ZIP215
|
||||
* ed25519.verify(sig, msg, pub, { zip215: false }); // RFC8032 / FIPS 186-5
|
||||
*/
|
||||
export declare const ed25519: CurveFn;
|
||||
/** Context of ed25519. Uses context for domain separation. */
|
||||
export declare const ed25519ctx: CurveFn;
|
||||
/** Prehashed version of ed25519. Accepts already-hashed messages in sign() and verify(). */
|
||||
export declare const ed25519ph: CurveFn;
|
||||
/**
|
||||
* ECDH using curve25519 aka x25519.
|
||||
* @example
|
||||
* import { x25519 } from '@noble/curves/ed25519';
|
||||
* const priv = 'a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4';
|
||||
* const pub = 'e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c';
|
||||
* x25519.getSharedSecret(priv, pub) === x25519.scalarMult(priv, pub); // aliases
|
||||
* x25519.getPublicKey(priv) === x25519.scalarMultBase(priv);
|
||||
* x25519.getPublicKey(x25519.utils.randomSecretKey());
|
||||
*/
|
||||
export declare const x25519: XCurveFn;
|
||||
/** Hashing to ed25519 points / field. RFC 9380 methods. */
|
||||
export declare const ed25519_hasher: H2CHasher<bigint>;
|
||||
type ExtendedPoint = EdwardsPoint;
|
||||
/**
|
||||
* Wrapper over Edwards Point for ristretto255.
|
||||
*
|
||||
* 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.
|
||||
* Ristretto point operates in X:Y:Z:T extended coordinates like ExtendedPoint,
|
||||
* but it should work in its own namespace: do not combine those two.
|
||||
* See [RFC9496](https://www.rfc-editor.org/rfc/rfc9496).
|
||||
*/
|
||||
declare class _RistrettoPoint extends PrimeEdwardsPoint<_RistrettoPoint> {
|
||||
static BASE: _RistrettoPoint;
|
||||
static ZERO: _RistrettoPoint;
|
||||
static Fp: IField<bigint>;
|
||||
static Fn: IField<bigint>;
|
||||
constructor(ep: ExtendedPoint);
|
||||
static fromAffine(ap: AffinePoint<bigint>): _RistrettoPoint;
|
||||
protected assertSame(other: _RistrettoPoint): void;
|
||||
protected init(ep: EdwardsPoint): _RistrettoPoint;
|
||||
/** @deprecated use `import { ristretto255_hasher } from '@noble/curves/ed25519.js';` */
|
||||
static hashToCurve(hex: Hex): _RistrettoPoint;
|
||||
static fromBytes(bytes: Uint8Array): _RistrettoPoint;
|
||||
/**
|
||||
* Converts ristretto-encoded string to ristretto point.
|
||||
* Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-decode).
|
||||
* @param hex Ristretto-encoded 32 bytes. Not every 32-byte string is valid ristretto encoding
|
||||
*/
|
||||
static fromHex(hex: Hex): _RistrettoPoint;
|
||||
static msm(points: _RistrettoPoint[], scalars: bigint[]): _RistrettoPoint;
|
||||
/**
|
||||
* Encodes ristretto point to Uint8Array.
|
||||
* Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-encode).
|
||||
*/
|
||||
toBytes(): Uint8Array;
|
||||
/**
|
||||
* Compares two Ristretto points.
|
||||
* Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-equals).
|
||||
*/
|
||||
equals(other: _RistrettoPoint): boolean;
|
||||
is0(): boolean;
|
||||
}
|
||||
export declare const ristretto255: {
|
||||
Point: typeof _RistrettoPoint;
|
||||
};
|
||||
/** Hashing to ristretto255 points / field. RFC 9380 methods. */
|
||||
export declare const ristretto255_hasher: H2CHasherBase<bigint>;
|
||||
/**
|
||||
* Weird / bogus points, useful for debugging.
|
||||
* All 8 ed25519 points of 8-torsion subgroup can be generated from the point
|
||||
* T = `26e8958fc2b227b045c3f489f2ef98f0d5dfac05d3c63339b13802886d53fc05`.
|
||||
* ⟨T⟩ = { O, T, 2T, 3T, 4T, 5T, 6T, 7T }
|
||||
*/
|
||||
export declare const ED25519_TORSION_SUBGROUP: string[];
|
||||
/** @deprecated use `ed25519.utils.toMontgomery` */
|
||||
export declare function edwardsToMontgomeryPub(edwardsPub: Hex): Uint8Array;
|
||||
/** @deprecated use `ed25519.utils.toMontgomery` */
|
||||
export declare const edwardsToMontgomery: typeof edwardsToMontgomeryPub;
|
||||
/** @deprecated use `ed25519.utils.toMontgomerySecret` */
|
||||
export declare function edwardsToMontgomeryPriv(edwardsPriv: Uint8Array): Uint8Array;
|
||||
/** @deprecated use `ristretto255.Point` */
|
||||
export declare const RistrettoPoint: typeof _RistrettoPoint;
|
||||
/** @deprecated use `import { ed25519_hasher } from '@noble/curves/ed25519.js';` */
|
||||
export declare const hashToCurve: H2CMethod<bigint>;
|
||||
/** @deprecated use `import { ed25519_hasher } from '@noble/curves/ed25519.js';` */
|
||||
export declare const encodeToCurve: H2CMethod<bigint>;
|
||||
type RistHasher = (msg: Uint8Array, options: htfBasicOpts) => _RistrettoPoint;
|
||||
/** @deprecated use `import { ristretto255_hasher } from '@noble/curves/ed25519.js';` */
|
||||
export declare const hashToRistretto255: RistHasher;
|
||||
/** @deprecated use `import { ristretto255_hasher } from '@noble/curves/ed25519.js';` */
|
||||
export declare const hash_to_ristretto255: RistHasher;
|
||||
export {};
|
||||
//# sourceMappingURL=ed25519.d.ts.map
|
||||
@@ -0,0 +1 @@
|
||||
"use strict";require("../../get-pipe-path-D4YM6rQt.cjs");var r=require("../../register-C557imBs.cjs"),e=require("../../require-DDxgG93A.cjs");require("module"),require("node:path"),require("../../temporary-directory-B83uKxJF.cjs"),require("node:os"),require("node:module"),require("node:url"),require("node:fs"),require("fs"),require("os"),require("path"),require("../../index-6kqi0x0U.cjs"),require("esbuild"),require("node:crypto"),require("../../node-features-CEjg7cMX.cjs"),require("../../client-D3mGB526.cjs"),require("node:net"),require("node:util"),require("../../index-BWFBUo6r.cjs"),exports.register=r.register,exports.require=e.tsxRequire;
|
||||
@@ -0,0 +1,6 @@
|
||||
global.process = { __proto__: process, pid: 123456 }
|
||||
Date.now = function () { return 1459875739796 }
|
||||
require('node:os').hostname = function () { return 'abcdefghijklmnopqr' }
|
||||
const pino = require(require.resolve('./../../'))
|
||||
const asyncLogger = pino(pino.destination({ minLength: 4096, sync: false }))
|
||||
asyncLogger.info('h')
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"nodeBuilderFlags.enum.js","sourceRoot":"","sources":["../../src/enums/nodeBuilderFlags.enum.ts"],"names":[],"mappings":"AAAA,mGAAmG;AAEnG,MAAM,CAAN,IAAY,gBAkCX;AAlCD,WAAY,gBAAgB;IACxB,uDAAQ,CAAA;IACR,uEAAqB,CAAA;IACrB,6FAAgC,CAAA;IAChC,mHAA2C,CAAA;IAC3C,yFAA8B,CAAA;IAC9B,sHAA4C,CAAA;IAC5C,0GAAsC,CAAA;IACtC,0FAA8B,CAAA;IAC9B,+FAAgC,CAAA;IAChC,2FAA8B,CAAA;IAC9B,qHAA2C,CAAA;IAC3C,gGAAiC,CAAA;IACjC,oHAA2C,CAAA;IAC3C,oFAA2B,CAAA;IAC3B,8FAAgC,CAAA;IAChC,uHAA4C,CAAA;IAC5C,6HAA6C,CAAA;IAC7C,qFAAyB,CAAA;IACzB,8GAAqC,CAAA;IACrC,wFAA2B,CAAA;IAC3B,qGAAiC,CAAA;IACjC,mGAAkC,CAAA;IAClC,6HAA+C,CAAA;IAC/C,oGAAkC,CAAA;IAClC,8GAAuC,CAAA;IACvC,kFAAyB,CAAA;IACzB,mGAAiC,CAAA;IACjC,mGAAiC,CAAA;IACjC,gHAAuC,CAAA;IACvC,8EAAsN,CAAA;IACtN,2FAA6B,CAAA;IAC7B,2EAAqB,CAAA;IACrB,4FAA6B,CAAA;AACjC,CAAC,EAlCW,gBAAgB,KAAhB,gBAAgB,QAkC3B"}
|
||||
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "pg-types",
|
||||
"version": "2.2.0",
|
||||
"description": "Query result type converters for node-postgres",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "tape test/*.js | tap-spec && npm run test-ts",
|
||||
"test-ts": "if-node-version '>= 8' tsd"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/brianc/node-pg-types.git"
|
||||
},
|
||||
"keywords": [
|
||||
"postgres",
|
||||
"PostgreSQL",
|
||||
"pg"
|
||||
],
|
||||
"author": "Brian M. Carlson",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/brianc/node-pg-types/issues"
|
||||
},
|
||||
"homepage": "https://github.com/brianc/node-pg-types",
|
||||
"devDependencies": {
|
||||
"if-node-version": "^1.1.1",
|
||||
"pff": "^1.0.0",
|
||||
"tap-spec": "^4.0.0",
|
||||
"tape": "^4.0.0",
|
||||
"tsd": "^0.7.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"pg-int8": "1.0.1",
|
||||
"postgres-array": "~2.0.0",
|
||||
"postgres-bytea": "~1.0.0",
|
||||
"postgres-date": "~1.0.4",
|
||||
"postgres-interval": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
Copyright (c) 2013 Dominic Tarr
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,16 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ripemd160 = exports.RIPEMD160 = void 0;
|
||||
/**
|
||||
* RIPEMD-160 legacy hash function.
|
||||
* https://homes.esat.kuleuven.be/~bosselae/ripemd160.html
|
||||
* https://homes.esat.kuleuven.be/~bosselae/ripemd160/pdf/AB-9601/AB-9601.pdf
|
||||
* @module
|
||||
* @deprecated
|
||||
*/
|
||||
const legacy_ts_1 = require("./legacy.js");
|
||||
/** @deprecated Use import from `noble/hashes/legacy` module */
|
||||
exports.RIPEMD160 = legacy_ts_1.RIPEMD160;
|
||||
/** @deprecated Use import from `noble/hashes/legacy` module */
|
||||
exports.ripemd160 = legacy_ts_1.ripemd160;
|
||||
//# sourceMappingURL=ripemd160.js.map
|
||||
@@ -0,0 +1,161 @@
|
||||
export type Mode = 'text' | 'binary';
|
||||
export type MessageName = 'parseComplete' | 'bindComplete' | 'closeComplete' | 'noData' | 'portalSuspended' | 'replicationStart' | 'emptyQuery' | 'copyDone' | 'copyData' | 'rowDescription' | 'parameterDescription' | 'parameterStatus' | 'backendKeyData' | 'notification' | 'readyForQuery' | 'commandComplete' | 'dataRow' | 'copyInResponse' | 'copyOutResponse' | 'authenticationOk' | 'authenticationMD5Password' | 'authenticationCleartextPassword' | 'authenticationSASL' | 'authenticationSASLContinue' | 'authenticationSASLFinal' | 'error' | 'notice';
|
||||
export interface BackendMessage {
|
||||
name: MessageName;
|
||||
length: number;
|
||||
}
|
||||
export declare const parseComplete: BackendMessage;
|
||||
export declare const bindComplete: BackendMessage;
|
||||
export declare const closeComplete: BackendMessage;
|
||||
export declare const noData: BackendMessage;
|
||||
export declare const portalSuspended: BackendMessage;
|
||||
export declare const replicationStart: BackendMessage;
|
||||
export declare const emptyQuery: BackendMessage;
|
||||
export declare const copyDone: BackendMessage;
|
||||
interface NoticeOrError {
|
||||
message: string | undefined;
|
||||
severity: string | undefined;
|
||||
code: string | undefined;
|
||||
detail: string | undefined;
|
||||
hint: string | undefined;
|
||||
position: string | undefined;
|
||||
internalPosition: string | undefined;
|
||||
internalQuery: string | undefined;
|
||||
where: string | undefined;
|
||||
schema: string | undefined;
|
||||
table: string | undefined;
|
||||
column: string | undefined;
|
||||
dataType: string | undefined;
|
||||
constraint: string | undefined;
|
||||
file: string | undefined;
|
||||
line: string | undefined;
|
||||
routine: string | undefined;
|
||||
}
|
||||
export declare class DatabaseError extends Error implements NoticeOrError {
|
||||
readonly length: number;
|
||||
readonly name: MessageName;
|
||||
severity: string | undefined;
|
||||
code: string | undefined;
|
||||
detail: string | undefined;
|
||||
hint: string | undefined;
|
||||
position: string | undefined;
|
||||
internalPosition: string | undefined;
|
||||
internalQuery: string | undefined;
|
||||
where: string | undefined;
|
||||
schema: string | undefined;
|
||||
table: string | undefined;
|
||||
column: string | undefined;
|
||||
dataType: string | undefined;
|
||||
constraint: string | undefined;
|
||||
file: string | undefined;
|
||||
line: string | undefined;
|
||||
routine: string | undefined;
|
||||
constructor(message: string, length: number, name: MessageName);
|
||||
}
|
||||
export declare class CopyDataMessage {
|
||||
readonly length: number;
|
||||
readonly chunk: Buffer;
|
||||
readonly name = "copyData";
|
||||
constructor(length: number, chunk: Buffer);
|
||||
}
|
||||
export declare class CopyResponse {
|
||||
readonly length: number;
|
||||
readonly name: MessageName;
|
||||
readonly binary: boolean;
|
||||
readonly columnTypes: number[];
|
||||
constructor(length: number, name: MessageName, binary: boolean, columnCount: number);
|
||||
}
|
||||
export declare class Field {
|
||||
readonly name: string;
|
||||
readonly tableID: number;
|
||||
readonly columnID: number;
|
||||
readonly dataTypeID: number;
|
||||
readonly dataTypeSize: number;
|
||||
readonly dataTypeModifier: number;
|
||||
readonly format: Mode;
|
||||
constructor(name: string, tableID: number, columnID: number, dataTypeID: number, dataTypeSize: number, dataTypeModifier: number, format: Mode);
|
||||
}
|
||||
export declare class RowDescriptionMessage {
|
||||
readonly length: number;
|
||||
readonly fieldCount: number;
|
||||
readonly name: MessageName;
|
||||
readonly fields: Field[];
|
||||
constructor(length: number, fieldCount: number);
|
||||
}
|
||||
export declare class ParameterDescriptionMessage {
|
||||
readonly length: number;
|
||||
readonly parameterCount: number;
|
||||
readonly name: MessageName;
|
||||
readonly dataTypeIDs: number[];
|
||||
constructor(length: number, parameterCount: number);
|
||||
}
|
||||
export declare class ParameterStatusMessage {
|
||||
readonly length: number;
|
||||
readonly parameterName: string;
|
||||
readonly parameterValue: string;
|
||||
readonly name: MessageName;
|
||||
constructor(length: number, parameterName: string, parameterValue: string);
|
||||
}
|
||||
export declare class AuthenticationMD5Password implements BackendMessage {
|
||||
readonly length: number;
|
||||
readonly salt: Buffer;
|
||||
readonly name: MessageName;
|
||||
constructor(length: number, salt: Buffer);
|
||||
}
|
||||
export declare class BackendKeyDataMessage {
|
||||
readonly length: number;
|
||||
readonly processID: number;
|
||||
readonly secretKey: number;
|
||||
readonly name: MessageName;
|
||||
constructor(length: number, processID: number, secretKey: number);
|
||||
}
|
||||
export declare class NotificationResponseMessage {
|
||||
readonly length: number;
|
||||
readonly processId: number;
|
||||
readonly channel: string;
|
||||
readonly payload: string;
|
||||
readonly name: MessageName;
|
||||
constructor(length: number, processId: number, channel: string, payload: string);
|
||||
}
|
||||
export declare class ReadyForQueryMessage {
|
||||
readonly length: number;
|
||||
readonly status: string;
|
||||
readonly name: MessageName;
|
||||
constructor(length: number, status: string);
|
||||
}
|
||||
export declare class CommandCompleteMessage {
|
||||
readonly length: number;
|
||||
readonly text: string;
|
||||
readonly name: MessageName;
|
||||
constructor(length: number, text: string);
|
||||
}
|
||||
export declare class DataRowMessage {
|
||||
length: number;
|
||||
fields: any[];
|
||||
readonly fieldCount: number;
|
||||
readonly name: MessageName;
|
||||
constructor(length: number, fields: any[]);
|
||||
}
|
||||
export declare class NoticeMessage implements BackendMessage, NoticeOrError {
|
||||
readonly length: number;
|
||||
readonly message: string | undefined;
|
||||
constructor(length: number, message: string | undefined);
|
||||
readonly name = "notice";
|
||||
severity: string | undefined;
|
||||
code: string | undefined;
|
||||
detail: string | undefined;
|
||||
hint: string | undefined;
|
||||
position: string | undefined;
|
||||
internalPosition: string | undefined;
|
||||
internalQuery: string | undefined;
|
||||
where: string | undefined;
|
||||
schema: string | undefined;
|
||||
table: string | undefined;
|
||||
column: string | undefined;
|
||||
dataType: string | undefined;
|
||||
constraint: string | undefined;
|
||||
file: string | undefined;
|
||||
line: string | undefined;
|
||||
routine: string | undefined;
|
||||
}
|
||||
export {};
|
||||
@@ -0,0 +1,125 @@
|
||||
'use strict'
|
||||
|
||||
var extend = require('xtend/mutable')
|
||||
|
||||
module.exports = PostgresInterval
|
||||
|
||||
function PostgresInterval (raw) {
|
||||
if (!(this instanceof PostgresInterval)) {
|
||||
return new PostgresInterval(raw)
|
||||
}
|
||||
extend(this, parse(raw))
|
||||
}
|
||||
var properties = ['seconds', 'minutes', 'hours', 'days', 'months', 'years']
|
||||
PostgresInterval.prototype.toPostgres = function () {
|
||||
var filtered = properties.filter(this.hasOwnProperty, this)
|
||||
|
||||
// In addition to `properties`, we need to account for fractions of seconds.
|
||||
if (this.milliseconds && filtered.indexOf('seconds') < 0) {
|
||||
filtered.push('seconds')
|
||||
}
|
||||
|
||||
if (filtered.length === 0) return '0'
|
||||
return filtered
|
||||
.map(function (property) {
|
||||
var value = this[property] || 0
|
||||
|
||||
// Account for fractional part of seconds,
|
||||
// remove trailing zeroes.
|
||||
if (property === 'seconds' && this.milliseconds) {
|
||||
value = (value + this.milliseconds / 1000).toFixed(6).replace(/\.?0+$/, '')
|
||||
}
|
||||
|
||||
return value + ' ' + property
|
||||
}, this)
|
||||
.join(' ')
|
||||
}
|
||||
|
||||
var propertiesISOEquivalent = {
|
||||
years: 'Y',
|
||||
months: 'M',
|
||||
days: 'D',
|
||||
hours: 'H',
|
||||
minutes: 'M',
|
||||
seconds: 'S'
|
||||
}
|
||||
var dateProperties = ['years', 'months', 'days']
|
||||
var timeProperties = ['hours', 'minutes', 'seconds']
|
||||
// according to ISO 8601
|
||||
PostgresInterval.prototype.toISOString = PostgresInterval.prototype.toISO = function () {
|
||||
var datePart = dateProperties
|
||||
.map(buildProperty, this)
|
||||
.join('')
|
||||
|
||||
var timePart = timeProperties
|
||||
.map(buildProperty, this)
|
||||
.join('')
|
||||
|
||||
return 'P' + datePart + 'T' + timePart
|
||||
|
||||
function buildProperty (property) {
|
||||
var value = this[property] || 0
|
||||
|
||||
// Account for fractional part of seconds,
|
||||
// remove trailing zeroes.
|
||||
if (property === 'seconds' && this.milliseconds) {
|
||||
value = (value + this.milliseconds / 1000).toFixed(6).replace(/0+$/, '')
|
||||
}
|
||||
|
||||
return value + propertiesISOEquivalent[property]
|
||||
}
|
||||
}
|
||||
|
||||
var NUMBER = '([+-]?\\d+)'
|
||||
var YEAR = NUMBER + '\\s+years?'
|
||||
var MONTH = NUMBER + '\\s+mons?'
|
||||
var DAY = NUMBER + '\\s+days?'
|
||||
var TIME = '([+-])?([\\d]*):(\\d\\d):(\\d\\d)\\.?(\\d{1,6})?'
|
||||
var INTERVAL = new RegExp([YEAR, MONTH, DAY, TIME].map(function (regexString) {
|
||||
return '(' + regexString + ')?'
|
||||
})
|
||||
.join('\\s*'))
|
||||
|
||||
// Positions of values in regex match
|
||||
var positions = {
|
||||
years: 2,
|
||||
months: 4,
|
||||
days: 6,
|
||||
hours: 9,
|
||||
minutes: 10,
|
||||
seconds: 11,
|
||||
milliseconds: 12
|
||||
}
|
||||
// We can use negative time
|
||||
var negatives = ['hours', 'minutes', 'seconds', 'milliseconds']
|
||||
|
||||
function parseMilliseconds (fraction) {
|
||||
// add omitted zeroes
|
||||
var microseconds = fraction + '000000'.slice(fraction.length)
|
||||
return parseInt(microseconds, 10) / 1000
|
||||
}
|
||||
|
||||
function parse (interval) {
|
||||
if (!interval) return {}
|
||||
var matches = INTERVAL.exec(interval)
|
||||
var isNegative = matches[8] === '-'
|
||||
return Object.keys(positions)
|
||||
.reduce(function (parsed, property) {
|
||||
var position = positions[property]
|
||||
var value = matches[position]
|
||||
// no empty string
|
||||
if (!value) return parsed
|
||||
// milliseconds are actually microseconds (up to 6 digits)
|
||||
// with omitted trailing zeroes.
|
||||
value = property === 'milliseconds'
|
||||
? parseMilliseconds(value)
|
||||
: parseInt(value, 10)
|
||||
// no zeros
|
||||
if (!value) return parsed
|
||||
if (isNegative && ~negatives.indexOf(property)) {
|
||||
value *= -1
|
||||
}
|
||||
parsed[property] = value
|
||||
return parsed
|
||||
}, {})
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const utils_1 = require("@typescript-eslint/utils");
|
||||
const tsutils = __importStar(require("ts-api-utils"));
|
||||
const util_1 = require("../util");
|
||||
var State;
|
||||
(function (State) {
|
||||
State[State["Unsafe"] = 1] = "Unsafe";
|
||||
State[State["Safe"] = 2] = "Safe";
|
||||
State[State["Chained"] = 3] = "Chained";
|
||||
})(State || (State = {}));
|
||||
exports.default = (0, util_1.createRule)({
|
||||
name: 'no-unsafe-member-access',
|
||||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Disallow member access on a value with type `any`',
|
||||
recommended: 'recommended',
|
||||
requiresTypeChecking: true,
|
||||
},
|
||||
messages: {
|
||||
errorComputedMemberAccess: 'The type of computed name {{property}} cannot be resolved.',
|
||||
errorMemberExpression: 'Unsafe member access {{property}} on a type that cannot be resolved.',
|
||||
errorThisMemberExpression: [
|
||||
'Unsafe member access {{property}}. The type of `this` cannot be resolved.',
|
||||
'You can try to fix this by turning on the `noImplicitThis` compiler option, or adding a `this` parameter to the function.',
|
||||
].join('\n'),
|
||||
unsafeComputedMemberAccess: 'Computed name {{property}} resolves to an `any` value.',
|
||||
unsafeMemberExpression: 'Unsafe member access {{property}} on an `any` value.',
|
||||
unsafeThisMemberExpression: [
|
||||
'Unsafe member access {{property}} on an `any` value. `this` is typed as `any`.',
|
||||
'You can try to fix this by turning on the `noImplicitThis` compiler option, or adding a `this` parameter to the function.',
|
||||
].join('\n'),
|
||||
},
|
||||
schema: [
|
||||
{
|
||||
type: 'object',
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
allowOptionalChaining: {
|
||||
type: 'boolean',
|
||||
description: 'Whether to allow `?.` optional chains on `any` values.',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
defaultOptions: [
|
||||
{
|
||||
allowOptionalChaining: false,
|
||||
},
|
||||
],
|
||||
create(context, [{ allowOptionalChaining }]) {
|
||||
const services = (0, util_1.getParserServices)(context);
|
||||
const compilerOptions = services.program.getCompilerOptions();
|
||||
const isNoImplicitThis = tsutils.isStrictCompilerOptionEnabled(compilerOptions, 'noImplicitThis');
|
||||
const stateCache = new Map();
|
||||
// Case notes:
|
||||
// value?.outer.middle.inner
|
||||
// The ChainExpression is a child of the root expression, and a parent of all the MemberExpressions.
|
||||
// But the left-most expression is what we want to report on: the inner-most expressions.
|
||||
// In fact, this is true even if the chain is on the inside!
|
||||
// value.outer.middle?.inner;
|
||||
// It was already true that every `object` (MemberExpression) has optional: boolean
|
||||
function checkMemberExpression(node) {
|
||||
if (allowOptionalChaining && node.optional) {
|
||||
stateCache.set(node, State.Chained);
|
||||
return State.Chained;
|
||||
}
|
||||
const cachedState = stateCache.get(node);
|
||||
if (cachedState) {
|
||||
return cachedState;
|
||||
}
|
||||
if (node.object.type === utils_1.AST_NODE_TYPES.MemberExpression) {
|
||||
const objectState = checkMemberExpression(node.object);
|
||||
if (objectState === State.Unsafe) {
|
||||
// if the object is unsafe, we know this will be unsafe as well
|
||||
// we don't need to report, as we have already reported on the inner member expr
|
||||
stateCache.set(node, objectState);
|
||||
return objectState;
|
||||
}
|
||||
}
|
||||
const type = services.getTypeAtLocation(node.object);
|
||||
const state = (0, util_1.isTypeAnyType)(type) ? State.Unsafe : State.Safe;
|
||||
stateCache.set(node, state);
|
||||
if (state === State.Unsafe) {
|
||||
const propertyName = context.sourceCode.getText(node.property);
|
||||
let messageId;
|
||||
if (!isNoImplicitThis) {
|
||||
// `this.foo` or `this.foo[bar]`
|
||||
const thisExpression = (0, util_1.getThisExpression)(node);
|
||||
if (thisExpression) {
|
||||
const thisType = (0, util_1.getConstrainedTypeAtLocation)(services, thisExpression);
|
||||
if ((0, util_1.isTypeAnyType)(thisType)) {
|
||||
messageId = tsutils.isIntrinsicErrorType(thisType)
|
||||
? 'errorThisMemberExpression'
|
||||
: 'unsafeThisMemberExpression';
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!messageId) {
|
||||
messageId = tsutils.isIntrinsicErrorType(type)
|
||||
? 'errorMemberExpression'
|
||||
: 'unsafeMemberExpression';
|
||||
}
|
||||
context.report({
|
||||
node: node.property,
|
||||
messageId,
|
||||
data: {
|
||||
property: node.computed ? `[${propertyName}]` : `.${propertyName}`,
|
||||
},
|
||||
});
|
||||
}
|
||||
return state;
|
||||
}
|
||||
return {
|
||||
// ignore MemberExpressions with ancestors of type `TSClassImplements` or `TSInterfaceHeritage`
|
||||
'MemberExpression:not(TSClassImplements MemberExpression, TSInterfaceHeritage MemberExpression)': checkMemberExpression,
|
||||
'MemberExpression[computed = true] > *.property'(node) {
|
||||
if (allowOptionalChaining &&
|
||||
node.parent.optional) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
// x[1]
|
||||
node.type === utils_1.AST_NODE_TYPES.Literal ||
|
||||
// x[1++] x[++x] etc
|
||||
// FUN FACT - **all** update expressions return type number, regardless of the argument's type,
|
||||
// because JS engines return NaN if there the argument is not a number.
|
||||
node.type === utils_1.AST_NODE_TYPES.UpdateExpression) {
|
||||
// perf optimizations - literals can obviously never be `any`
|
||||
return;
|
||||
}
|
||||
const type = services.getTypeAtLocation(node);
|
||||
if ((0, util_1.isTypeAnyType)(type)) {
|
||||
const propertyName = context.sourceCode.getText(node);
|
||||
context.report({
|
||||
node,
|
||||
messageId: tsutils.isIntrinsicErrorType(type)
|
||||
? 'errorComputedMemberAccess'
|
||||
: 'unsafeComputedMemberAccess',
|
||||
data: {
|
||||
property: `[${propertyName}]`,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,867 @@
|
||||
/**
|
||||
* Towered extension fields.
|
||||
* Rather than implementing a massive 12th-degree extension directly, it is more efficient
|
||||
* to build it up from smaller extensions: a tower of extensions.
|
||||
*
|
||||
* For BLS12-381, the Fp12 field is implemented as a quadratic (degree two) extension,
|
||||
* on top of a cubic (degree three) extension, on top of a quadratic extension of Fp.
|
||||
*
|
||||
* For more info: "Pairings for beginners" by Costello, section 7.3.
|
||||
* @module
|
||||
*/
|
||||
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
||||
import { bitGet, bitLen, concatBytes, notImplemented } from '../utils.ts';
|
||||
import * as mod from './modular.ts';
|
||||
import type { WeierstrassPoint, WeierstrassPointCons } from './weierstrass.ts';
|
||||
|
||||
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
||||
// prettier-ignore
|
||||
const _0n = BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = BigInt(3);
|
||||
|
||||
// Fp₂ over complex plane
|
||||
export type BigintTuple = [bigint, bigint];
|
||||
export type Fp = bigint;
|
||||
// Finite extension field over irreducible polynominal.
|
||||
// Fp(u) / (u² - β) where β = -1
|
||||
export type Fp2 = { c0: bigint; c1: bigint };
|
||||
export type BigintSix = [bigint, bigint, bigint, bigint, bigint, bigint];
|
||||
export type Fp6 = { c0: Fp2; c1: Fp2; c2: Fp2 };
|
||||
export type Fp12 = { c0: Fp6; c1: Fp6 }; // Fp₁₂ = Fp₆² => Fp₂³, Fp₆(w) / (w² - γ) where γ = v
|
||||
// prettier-ignore
|
||||
export type BigintTwelve = [
|
||||
bigint, bigint, bigint, bigint, bigint, bigint,
|
||||
bigint, bigint, bigint, bigint, bigint, bigint
|
||||
];
|
||||
|
||||
export type Fp2Bls = mod.IField<Fp2> & {
|
||||
Fp: mod.IField<Fp>;
|
||||
frobeniusMap(num: Fp2, power: number): Fp2;
|
||||
fromBigTuple(num: BigintTuple): Fp2;
|
||||
mulByB: (num: Fp2) => Fp2;
|
||||
mulByNonresidue: (num: Fp2) => Fp2;
|
||||
reim: (num: Fp2) => { re: Fp; im: Fp };
|
||||
Fp4Square: (a: Fp2, b: Fp2) => { first: Fp2; second: Fp2 };
|
||||
NONRESIDUE: Fp2;
|
||||
};
|
||||
|
||||
export type Fp6Bls = mod.IField<Fp6> & {
|
||||
Fp2: Fp2Bls;
|
||||
frobeniusMap(num: Fp6, power: number): Fp6;
|
||||
fromBigSix: (tuple: BigintSix) => Fp6;
|
||||
mul1(num: Fp6, b1: Fp2): Fp6;
|
||||
mul01(num: Fp6, b0: Fp2, b1: Fp2): Fp6;
|
||||
mulByFp2(lhs: Fp6, rhs: Fp2): Fp6;
|
||||
mulByNonresidue: (num: Fp6) => Fp6;
|
||||
};
|
||||
|
||||
export type Fp12Bls = mod.IField<Fp12> & {
|
||||
Fp6: Fp6Bls;
|
||||
frobeniusMap(num: Fp12, power: number): Fp12;
|
||||
fromBigTwelve: (t: BigintTwelve) => Fp12;
|
||||
mul014(num: Fp12, o0: Fp2, o1: Fp2, o4: Fp2): Fp12;
|
||||
mul034(num: Fp12, o0: Fp2, o3: Fp2, o4: Fp2): Fp12;
|
||||
mulByFp2(lhs: Fp12, rhs: Fp2): Fp12;
|
||||
conjugate(num: Fp12): Fp12;
|
||||
finalExponentiate(num: Fp12): Fp12;
|
||||
_cyclotomicSquare(num: Fp12): Fp12;
|
||||
_cyclotomicExp(num: Fp12, n: bigint): Fp12;
|
||||
};
|
||||
|
||||
function calcFrobeniusCoefficients<T>(
|
||||
Fp: mod.IField<T>,
|
||||
nonResidue: T,
|
||||
modulus: bigint,
|
||||
degree: number,
|
||||
num: number = 1,
|
||||
divisor?: number
|
||||
) {
|
||||
const _divisor = BigInt(divisor === undefined ? degree : divisor);
|
||||
const towerModulus: any = modulus ** BigInt(degree);
|
||||
const res: T[][] = [];
|
||||
for (let i = 0; i < num; i++) {
|
||||
const a = BigInt(i + 1);
|
||||
const powers: T[] = [];
|
||||
for (let j = 0, qPower = _1n; j < degree; j++) {
|
||||
const power = ((a * qPower - a) / _divisor) % towerModulus;
|
||||
powers.push(Fp.pow(nonResidue, power));
|
||||
qPower *= modulus;
|
||||
}
|
||||
res.push(powers);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// This works same at least for bls12-381, bn254 and bls12-377
|
||||
export function psiFrobenius(
|
||||
Fp: mod.IField<Fp>,
|
||||
Fp2: Fp2Bls,
|
||||
base: Fp2
|
||||
): {
|
||||
psi: (x: Fp2, y: Fp2) => [Fp2, Fp2];
|
||||
psi2: (x: Fp2, y: Fp2) => [Fp2, Fp2];
|
||||
G2psi: (c: WeierstrassPointCons<Fp2>, P: WeierstrassPoint<Fp2>) => WeierstrassPoint<Fp2>;
|
||||
G2psi2: (c: WeierstrassPointCons<Fp2>, P: WeierstrassPoint<Fp2>) => WeierstrassPoint<Fp2>;
|
||||
PSI_X: Fp2;
|
||||
PSI_Y: Fp2;
|
||||
PSI2_X: Fp2;
|
||||
PSI2_Y: Fp2;
|
||||
} {
|
||||
// GLV endomorphism Ψ(P)
|
||||
const PSI_X = Fp2.pow(base, (Fp.ORDER - _1n) / _3n); // u^((p-1)/3)
|
||||
const PSI_Y = Fp2.pow(base, (Fp.ORDER - _1n) / _2n); // u^((p-1)/2)
|
||||
function psi(x: Fp2, y: Fp2): [Fp2, Fp2] {
|
||||
// This x10 faster than previous version in bls12-381
|
||||
const x2 = Fp2.mul(Fp2.frobeniusMap(x, 1), PSI_X);
|
||||
const y2 = Fp2.mul(Fp2.frobeniusMap(y, 1), PSI_Y);
|
||||
return [x2, y2];
|
||||
}
|
||||
// Ψ²(P) endomorphism (psi2(x) = psi(psi(x)))
|
||||
const PSI2_X = Fp2.pow(base, (Fp.ORDER ** _2n - _1n) / _3n); // u^((p^2 - 1)/3)
|
||||
// This equals -1, which causes y to be Fp2.neg(y).
|
||||
// But not sure if there are case when this is not true?
|
||||
const PSI2_Y = Fp2.pow(base, (Fp.ORDER ** _2n - _1n) / _2n); // u^((p^2 - 1)/3)
|
||||
if (!Fp2.eql(PSI2_Y, Fp2.neg(Fp2.ONE))) throw new Error('psiFrobenius: PSI2_Y!==-1');
|
||||
function psi2(x: Fp2, y: Fp2): [Fp2, Fp2] {
|
||||
return [Fp2.mul(x, PSI2_X), Fp2.neg(y)];
|
||||
}
|
||||
// Map points
|
||||
const mapAffine =
|
||||
<T>(fn: (x: T, y: T) => [T, T]) =>
|
||||
(c: WeierstrassPointCons<T>, P: WeierstrassPoint<T>) => {
|
||||
const affine = P.toAffine();
|
||||
const p = fn(affine.x, affine.y);
|
||||
return c.fromAffine({ x: p[0], y: p[1] });
|
||||
};
|
||||
const G2psi = mapAffine(psi);
|
||||
const G2psi2 = mapAffine(psi2);
|
||||
return { psi, psi2, G2psi, G2psi2, PSI_X, PSI_Y, PSI2_X, PSI2_Y };
|
||||
}
|
||||
|
||||
export type Tower12Opts = {
|
||||
ORDER: bigint;
|
||||
X_LEN: number;
|
||||
NONRESIDUE?: Fp;
|
||||
FP2_NONRESIDUE: BigintTuple;
|
||||
Fp2sqrt?: (num: Fp2) => Fp2;
|
||||
Fp2mulByB: (num: Fp2) => Fp2;
|
||||
Fp12finalExponentiate: (num: Fp12) => Fp12;
|
||||
};
|
||||
|
||||
const Fp2fromBigTuple = (Fp: mod.IField<bigint>, tuple: BigintTuple | bigint[]) => {
|
||||
if (tuple.length !== 2) throw new Error('invalid tuple');
|
||||
const fps = tuple.map((n) => Fp.create(n)) as BigintTuple;
|
||||
return { c0: fps[0], c1: fps[1] };
|
||||
};
|
||||
|
||||
class _Field2 implements mod.IField<Fp2> {
|
||||
readonly ORDER: bigint;
|
||||
readonly BITS: number;
|
||||
readonly BYTES: number;
|
||||
readonly isLE: boolean;
|
||||
readonly MASK = _1n;
|
||||
|
||||
readonly ZERO: Fp2;
|
||||
readonly ONE: Fp2;
|
||||
readonly Fp: mod.IField<bigint>;
|
||||
|
||||
readonly NONRESIDUE: Fp2;
|
||||
readonly mulByB: Tower12Opts['Fp2mulByB'];
|
||||
readonly Fp_NONRESIDUE: bigint;
|
||||
readonly Fp_div2: bigint;
|
||||
readonly FROBENIUS_COEFFICIENTS: Fp[];
|
||||
|
||||
constructor(
|
||||
Fp: mod.IField<bigint>,
|
||||
opts: Partial<{
|
||||
NONRESIDUE: bigint;
|
||||
FP2_NONRESIDUE: BigintTuple;
|
||||
Fp2mulByB: Tower12Opts['Fp2mulByB'];
|
||||
}> = {}
|
||||
) {
|
||||
const ORDER = Fp.ORDER;
|
||||
const FP2_ORDER = ORDER * ORDER;
|
||||
this.Fp = Fp;
|
||||
this.ORDER = FP2_ORDER;
|
||||
this.BITS = bitLen(FP2_ORDER);
|
||||
this.BYTES = Math.ceil(bitLen(FP2_ORDER) / 8);
|
||||
this.isLE = Fp.isLE;
|
||||
this.ZERO = { c0: Fp.ZERO, c1: Fp.ZERO };
|
||||
this.ONE = { c0: Fp.ONE, c1: Fp.ZERO };
|
||||
|
||||
this.Fp_NONRESIDUE = Fp.create(opts.NONRESIDUE || BigInt(-1));
|
||||
this.Fp_div2 = Fp.div(Fp.ONE, _2n); // 1/2
|
||||
this.NONRESIDUE = Fp2fromBigTuple(Fp, opts.FP2_NONRESIDUE!);
|
||||
// const Fp2Nonresidue = Fp2fromBigTuple(opts.FP2_NONRESIDUE);
|
||||
this.FROBENIUS_COEFFICIENTS = calcFrobeniusCoefficients(Fp, this.Fp_NONRESIDUE, Fp.ORDER, 2)[0];
|
||||
this.mulByB = opts.Fp2mulByB!;
|
||||
Object.seal(this);
|
||||
}
|
||||
fromBigTuple(tuple: BigintTuple) {
|
||||
return Fp2fromBigTuple(this.Fp, tuple);
|
||||
}
|
||||
create(num: Fp2) {
|
||||
return num;
|
||||
}
|
||||
isValid({ c0, c1 }: Fp2) {
|
||||
function isValidC(num: bigint, ORDER: bigint) {
|
||||
return typeof num === 'bigint' && _0n <= num && num < ORDER;
|
||||
}
|
||||
return isValidC(c0, this.ORDER) && isValidC(c1, this.ORDER);
|
||||
}
|
||||
is0({ c0, c1 }: Fp2) {
|
||||
return this.Fp.is0(c0) && this.Fp.is0(c1);
|
||||
}
|
||||
isValidNot0(num: Fp2) {
|
||||
return !this.is0(num) && this.isValid(num);
|
||||
}
|
||||
eql({ c0, c1 }: Fp2, { c0: r0, c1: r1 }: Fp2) {
|
||||
return this.Fp.eql(c0, r0) && this.Fp.eql(c1, r1);
|
||||
}
|
||||
neg({ c0, c1 }: Fp2) {
|
||||
return { c0: this.Fp.neg(c0), c1: this.Fp.neg(c1) };
|
||||
}
|
||||
pow(num: Fp2, power: bigint): Fp2 {
|
||||
return mod.FpPow(this, num, power);
|
||||
}
|
||||
invertBatch(nums: Fp2[]): Fp2[] {
|
||||
return mod.FpInvertBatch(this, nums);
|
||||
}
|
||||
// Normalized
|
||||
add(f1: Fp2, f2: Fp2): Fp2 {
|
||||
const { c0, c1 } = f1;
|
||||
const { c0: r0, c1: r1 } = f2;
|
||||
return {
|
||||
c0: this.Fp.add(c0, r0),
|
||||
c1: this.Fp.add(c1, r1),
|
||||
};
|
||||
}
|
||||
sub({ c0, c1 }: Fp2, { c0: r0, c1: r1 }: Fp2) {
|
||||
return {
|
||||
c0: this.Fp.sub(c0, r0),
|
||||
c1: this.Fp.sub(c1, r1),
|
||||
};
|
||||
}
|
||||
mul({ c0, c1 }: Fp2, rhs: Fp2) {
|
||||
const { Fp } = this;
|
||||
if (typeof rhs === 'bigint') return { c0: Fp.mul(c0, rhs), c1: Fp.mul(c1, rhs) };
|
||||
// (a+bi)(c+di) = (ac−bd) + (ad+bc)i
|
||||
const { c0: r0, c1: r1 } = rhs;
|
||||
let t1 = Fp.mul(c0, r0); // c0 * o0
|
||||
let t2 = Fp.mul(c1, r1); // c1 * o1
|
||||
// (T1 - T2) + ((c0 + c1) * (r0 + r1) - (T1 + T2))*i
|
||||
const o0 = Fp.sub(t1, t2);
|
||||
const o1 = Fp.sub(Fp.mul(Fp.add(c0, c1), Fp.add(r0, r1)), Fp.add(t1, t2));
|
||||
return { c0: o0, c1: o1 };
|
||||
}
|
||||
sqr({ c0, c1 }: Fp2) {
|
||||
const { Fp } = this;
|
||||
const a = Fp.add(c0, c1);
|
||||
const b = Fp.sub(c0, c1);
|
||||
const c = Fp.add(c0, c0);
|
||||
return { c0: Fp.mul(a, b), c1: Fp.mul(c, c1) };
|
||||
}
|
||||
// NonNormalized stuff
|
||||
addN(a: Fp2, b: Fp2): Fp2 {
|
||||
return this.add(a, b);
|
||||
}
|
||||
subN(a: Fp2, b: Fp2): Fp2 {
|
||||
return this.sub(a, b);
|
||||
}
|
||||
mulN(a: Fp2, b: Fp2): Fp2 {
|
||||
return this.mul(a, b);
|
||||
}
|
||||
sqrN(a: Fp2): Fp2 {
|
||||
return this.sqr(a);
|
||||
}
|
||||
// Why inversion for bigint inside Fp instead of Fp2? it is even used in that context?
|
||||
div(lhs: Fp2, rhs: Fp2): Fp2 {
|
||||
const { Fp } = this;
|
||||
// @ts-ignore
|
||||
return this.mul(lhs, typeof rhs === 'bigint' ? Fp.inv(Fp.create(rhs)) : this.inv(rhs));
|
||||
}
|
||||
inv({ c0: a, c1: b }: Fp2): Fp2 {
|
||||
// We wish to find the multiplicative inverse of a nonzero
|
||||
// element a + bu in Fp2. We leverage an identity
|
||||
//
|
||||
// (a + bu)(a - bu) = a² + b²
|
||||
//
|
||||
// which holds because u² = -1. This can be rewritten as
|
||||
//
|
||||
// (a + bu)(a - bu)/(a² + b²) = 1
|
||||
//
|
||||
// because a² + b² = 0 has no nonzero solutions for (a, b).
|
||||
// This gives that (a - bu)/(a² + b²) is the inverse
|
||||
// of (a + bu). Importantly, this can be computing using
|
||||
// only a single inversion in Fp.
|
||||
const { Fp } = this;
|
||||
const factor = Fp.inv(Fp.create(a * a + b * b));
|
||||
return { c0: Fp.mul(factor, Fp.create(a)), c1: Fp.mul(factor, Fp.create(-b)) };
|
||||
}
|
||||
sqrt(num: Fp2) {
|
||||
// This is generic for all quadratic extensions (Fp2)
|
||||
const { Fp } = this;
|
||||
const Fp2 = this;
|
||||
const { c0, c1 } = num;
|
||||
if (Fp.is0(c1)) {
|
||||
// if c0 is quadratic residue
|
||||
if (mod.FpLegendre(Fp, c0) === 1) return Fp2.create({ c0: Fp.sqrt(c0), c1: Fp.ZERO });
|
||||
else return Fp2.create({ c0: Fp.ZERO, c1: Fp.sqrt(Fp.div(c0, this.Fp_NONRESIDUE)) });
|
||||
}
|
||||
const a = Fp.sqrt(Fp.sub(Fp.sqr(c0), Fp.mul(Fp.sqr(c1), this.Fp_NONRESIDUE)));
|
||||
let d = Fp.mul(Fp.add(a, c0), this.Fp_div2);
|
||||
const legendre = mod.FpLegendre(Fp, d);
|
||||
// -1, Quadratic non residue
|
||||
if (legendre === -1) d = Fp.sub(d, a);
|
||||
const a0 = Fp.sqrt(d);
|
||||
const candidateSqrt = Fp2.create({ c0: a0, c1: Fp.div(Fp.mul(c1, this.Fp_div2), a0) });
|
||||
if (!Fp2.eql(Fp2.sqr(candidateSqrt), num)) throw new Error('Cannot find square root');
|
||||
// Normalize root: at this point candidateSqrt ** 2 = num, but also -candidateSqrt ** 2 = num
|
||||
const x1 = candidateSqrt;
|
||||
const x2 = Fp2.neg(x1);
|
||||
const { re: re1, im: im1 } = Fp2.reim(x1);
|
||||
const { re: re2, im: im2 } = Fp2.reim(x2);
|
||||
if (im1 > im2 || (im1 === im2 && re1 > re2)) return x1;
|
||||
return x2;
|
||||
}
|
||||
// Same as sgn0_m_eq_2 in RFC 9380
|
||||
isOdd(x: Fp2) {
|
||||
const { re: x0, im: x1 } = this.reim(x);
|
||||
const sign_0 = x0 % _2n;
|
||||
const zero_0 = x0 === _0n;
|
||||
const sign_1 = x1 % _2n;
|
||||
return BigInt(sign_0 || (zero_0 && sign_1)) == _1n;
|
||||
}
|
||||
// Bytes util
|
||||
fromBytes(b: Uint8Array): Fp2 {
|
||||
const { Fp } = this;
|
||||
if (b.length !== this.BYTES) throw new Error('fromBytes invalid length=' + b.length);
|
||||
return { c0: Fp.fromBytes(b.subarray(0, Fp.BYTES)), c1: Fp.fromBytes(b.subarray(Fp.BYTES)) };
|
||||
}
|
||||
toBytes({ c0, c1 }: Fp2) {
|
||||
return concatBytes(this.Fp.toBytes(c0), this.Fp.toBytes(c1));
|
||||
}
|
||||
cmov({ c0, c1 }: Fp2, { c0: r0, c1: r1 }: Fp2, c: boolean) {
|
||||
return {
|
||||
c0: this.Fp.cmov(c0, r0, c),
|
||||
c1: this.Fp.cmov(c1, r1, c),
|
||||
};
|
||||
}
|
||||
reim({ c0, c1 }: Fp2) {
|
||||
return { re: c0, im: c1 };
|
||||
}
|
||||
Fp4Square(a: Fp2, b: Fp2): { first: Fp2; second: Fp2 } {
|
||||
const Fp2 = this;
|
||||
const a2 = Fp2.sqr(a);
|
||||
const b2 = Fp2.sqr(b);
|
||||
return {
|
||||
first: Fp2.add(Fp2.mulByNonresidue(b2), a2), // b² * Nonresidue + a²
|
||||
second: Fp2.sub(Fp2.sub(Fp2.sqr(Fp2.add(a, b)), a2), b2), // (a + b)² - a² - b²
|
||||
};
|
||||
}
|
||||
// multiply by u + 1
|
||||
mulByNonresidue({ c0, c1 }: Fp2) {
|
||||
return this.mul({ c0, c1 }, this.NONRESIDUE);
|
||||
}
|
||||
frobeniusMap({ c0, c1 }: Fp2, power: number): Fp2 {
|
||||
return {
|
||||
c0,
|
||||
c1: this.Fp.mul(c1, this.FROBENIUS_COEFFICIENTS[power % 2]),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class _Field6 implements Fp6Bls {
|
||||
readonly ORDER: bigint;
|
||||
readonly BITS: number;
|
||||
readonly BYTES: number;
|
||||
readonly isLE: boolean;
|
||||
readonly MASK = _1n;
|
||||
|
||||
readonly ZERO: Fp6;
|
||||
readonly ONE: Fp6;
|
||||
readonly Fp2: Fp2Bls;
|
||||
readonly FROBENIUS_COEFFICIENTS_1: Fp2[];
|
||||
readonly FROBENIUS_COEFFICIENTS_2: Fp2[];
|
||||
|
||||
constructor(Fp2: Fp2Bls) {
|
||||
this.Fp2 = Fp2;
|
||||
this.ORDER = Fp2.ORDER; // TODO: unused, but need to verify
|
||||
this.BITS = 3 * Fp2.BITS;
|
||||
this.BYTES = 3 * Fp2.BYTES;
|
||||
this.isLE = Fp2.isLE;
|
||||
this.ZERO = { c0: Fp2.ZERO, c1: Fp2.ZERO, c2: Fp2.ZERO };
|
||||
this.ONE = { c0: Fp2.ONE, c1: Fp2.ZERO, c2: Fp2.ZERO };
|
||||
const { Fp } = Fp2;
|
||||
const frob = calcFrobeniusCoefficients(Fp2, Fp2.NONRESIDUE, Fp.ORDER, 6, 2, 3);
|
||||
this.FROBENIUS_COEFFICIENTS_1 = frob[0];
|
||||
this.FROBENIUS_COEFFICIENTS_2 = frob[1];
|
||||
Object.seal(this);
|
||||
}
|
||||
add({ c0, c1, c2 }: Fp6, { c0: r0, c1: r1, c2: r2 }: Fp6) {
|
||||
const { Fp2 } = this;
|
||||
return {
|
||||
c0: Fp2.add(c0, r0),
|
||||
c1: Fp2.add(c1, r1),
|
||||
c2: Fp2.add(c2, r2),
|
||||
};
|
||||
}
|
||||
sub({ c0, c1, c2 }: Fp6, { c0: r0, c1: r1, c2: r2 }: Fp6) {
|
||||
const { Fp2 } = this;
|
||||
return {
|
||||
c0: Fp2.sub(c0, r0),
|
||||
c1: Fp2.sub(c1, r1),
|
||||
c2: Fp2.sub(c2, r2),
|
||||
};
|
||||
}
|
||||
mul({ c0, c1, c2 }: Fp6, rhs: Fp6 | bigint) {
|
||||
const { Fp2 } = this;
|
||||
if (typeof rhs === 'bigint') {
|
||||
return {
|
||||
c0: Fp2.mul(c0, rhs),
|
||||
c1: Fp2.mul(c1, rhs),
|
||||
c2: Fp2.mul(c2, rhs),
|
||||
};
|
||||
}
|
||||
const { c0: r0, c1: r1, c2: r2 } = rhs;
|
||||
const t0 = Fp2.mul(c0, r0); // c0 * o0
|
||||
const t1 = Fp2.mul(c1, r1); // c1 * o1
|
||||
const t2 = Fp2.mul(c2, r2); // c2 * o2
|
||||
return {
|
||||
// t0 + (c1 + c2) * (r1 * r2) - (T1 + T2) * (u + 1)
|
||||
c0: Fp2.add(
|
||||
t0,
|
||||
Fp2.mulByNonresidue(Fp2.sub(Fp2.mul(Fp2.add(c1, c2), Fp2.add(r1, r2)), Fp2.add(t1, t2)))
|
||||
),
|
||||
// (c0 + c1) * (r0 + r1) - (T0 + T1) + T2 * (u + 1)
|
||||
c1: Fp2.add(
|
||||
Fp2.sub(Fp2.mul(Fp2.add(c0, c1), Fp2.add(r0, r1)), Fp2.add(t0, t1)),
|
||||
Fp2.mulByNonresidue(t2)
|
||||
),
|
||||
// T1 + (c0 + c2) * (r0 + r2) - T0 + T2
|
||||
c2: Fp2.sub(Fp2.add(t1, Fp2.mul(Fp2.add(c0, c2), Fp2.add(r0, r2))), Fp2.add(t0, t2)),
|
||||
};
|
||||
}
|
||||
sqr({ c0, c1, c2 }: Fp6) {
|
||||
const { Fp2 } = this;
|
||||
let t0 = Fp2.sqr(c0); // c0²
|
||||
let t1 = Fp2.mul(Fp2.mul(c0, c1), _2n); // 2 * c0 * c1
|
||||
let t3 = Fp2.mul(Fp2.mul(c1, c2), _2n); // 2 * c1 * c2
|
||||
let t4 = Fp2.sqr(c2); // c2²
|
||||
return {
|
||||
c0: Fp2.add(Fp2.mulByNonresidue(t3), t0), // T3 * (u + 1) + T0
|
||||
c1: Fp2.add(Fp2.mulByNonresidue(t4), t1), // T4 * (u + 1) + T1
|
||||
// T1 + (c0 - c1 + c2)² + T3 - T0 - T4
|
||||
c2: Fp2.sub(Fp2.sub(Fp2.add(Fp2.add(t1, Fp2.sqr(Fp2.add(Fp2.sub(c0, c1), c2))), t3), t0), t4),
|
||||
};
|
||||
}
|
||||
addN(a: Fp6, b: Fp6): Fp6 {
|
||||
return this.add(a, b);
|
||||
}
|
||||
subN(a: Fp6, b: Fp6): Fp6 {
|
||||
return this.sub(a, b);
|
||||
}
|
||||
mulN(a: Fp6, b: Fp6): Fp6 {
|
||||
return this.mul(a, b);
|
||||
}
|
||||
sqrN(a: Fp6): Fp6 {
|
||||
return this.sqr(a);
|
||||
}
|
||||
|
||||
create(num: Fp6) {
|
||||
return num;
|
||||
}
|
||||
|
||||
isValid({ c0, c1, c2 }: Fp6) {
|
||||
const { Fp2 } = this;
|
||||
return Fp2.isValid(c0) && Fp2.isValid(c1) && Fp2.isValid(c2);
|
||||
}
|
||||
is0({ c0, c1, c2 }: Fp6) {
|
||||
const { Fp2 } = this;
|
||||
return Fp2.is0(c0) && Fp2.is0(c1) && Fp2.is0(c2);
|
||||
}
|
||||
isValidNot0(num: Fp6) {
|
||||
return !this.is0(num) && this.isValid(num);
|
||||
}
|
||||
neg({ c0, c1, c2 }: Fp6) {
|
||||
const { Fp2 } = this;
|
||||
return { c0: Fp2.neg(c0), c1: Fp2.neg(c1), c2: Fp2.neg(c2) };
|
||||
}
|
||||
eql({ c0, c1, c2 }: Fp6, { c0: r0, c1: r1, c2: r2 }: Fp6) {
|
||||
const { Fp2 } = this;
|
||||
return Fp2.eql(c0, r0) && Fp2.eql(c1, r1) && Fp2.eql(c2, r2);
|
||||
}
|
||||
sqrt(_: Fp6) {
|
||||
return notImplemented();
|
||||
}
|
||||
// Do we need division by bigint at all? Should be done via order:
|
||||
div(lhs: Fp6, rhs: Fp6) {
|
||||
const { Fp2 } = this;
|
||||
const { Fp } = Fp2;
|
||||
return this.mul(lhs, typeof rhs === 'bigint' ? Fp.inv(Fp.create(rhs)) : this.inv(rhs));
|
||||
}
|
||||
pow(num: Fp6, power: Fp): Fp6 {
|
||||
return mod.FpPow(this, num, power);
|
||||
}
|
||||
invertBatch(nums: Fp6[]): Fp6[] {
|
||||
return mod.FpInvertBatch(this, nums);
|
||||
}
|
||||
|
||||
inv({ c0, c1, c2 }: Fp6) {
|
||||
const { Fp2 } = this;
|
||||
let t0 = Fp2.sub(Fp2.sqr(c0), Fp2.mulByNonresidue(Fp2.mul(c2, c1))); // c0² - c2 * c1 * (u + 1)
|
||||
let t1 = Fp2.sub(Fp2.mulByNonresidue(Fp2.sqr(c2)), Fp2.mul(c0, c1)); // c2² * (u + 1) - c0 * c1
|
||||
let t2 = Fp2.sub(Fp2.sqr(c1), Fp2.mul(c0, c2)); // c1² - c0 * c2
|
||||
// 1/(((c2 * T1 + c1 * T2) * v) + c0 * T0)
|
||||
let t4 = Fp2.inv(
|
||||
Fp2.add(Fp2.mulByNonresidue(Fp2.add(Fp2.mul(c2, t1), Fp2.mul(c1, t2))), Fp2.mul(c0, t0))
|
||||
);
|
||||
return { c0: Fp2.mul(t4, t0), c1: Fp2.mul(t4, t1), c2: Fp2.mul(t4, t2) };
|
||||
}
|
||||
// Bytes utils
|
||||
fromBytes(b: Uint8Array): Fp6 {
|
||||
const { Fp2 } = this;
|
||||
if (b.length !== this.BYTES) throw new Error('fromBytes invalid length=' + b.length);
|
||||
const B2 = Fp2.BYTES;
|
||||
return {
|
||||
c0: Fp2.fromBytes(b.subarray(0, B2)),
|
||||
c1: Fp2.fromBytes(b.subarray(B2, B2 * 2)),
|
||||
c2: Fp2.fromBytes(b.subarray(2 * B2)),
|
||||
};
|
||||
}
|
||||
toBytes({ c0, c1, c2 }: Fp6): Uint8Array {
|
||||
const { Fp2 } = this;
|
||||
return concatBytes(Fp2.toBytes(c0), Fp2.toBytes(c1), Fp2.toBytes(c2));
|
||||
}
|
||||
cmov({ c0, c1, c2 }: Fp6, { c0: r0, c1: r1, c2: r2 }: Fp6, c: boolean) {
|
||||
const { Fp2 } = this;
|
||||
return {
|
||||
c0: Fp2.cmov(c0, r0, c),
|
||||
c1: Fp2.cmov(c1, r1, c),
|
||||
c2: Fp2.cmov(c2, r2, c),
|
||||
};
|
||||
}
|
||||
fromBigSix(t: BigintSix): Fp6 {
|
||||
const { Fp2 } = this;
|
||||
if (!Array.isArray(t) || t.length !== 6) throw new Error('invalid Fp6 usage');
|
||||
return {
|
||||
c0: Fp2.fromBigTuple(t.slice(0, 2) as BigintTuple),
|
||||
c1: Fp2.fromBigTuple(t.slice(2, 4) as BigintTuple),
|
||||
c2: Fp2.fromBigTuple(t.slice(4, 6) as BigintTuple),
|
||||
};
|
||||
}
|
||||
frobeniusMap({ c0, c1, c2 }: Fp6, power: number) {
|
||||
const { Fp2 } = this;
|
||||
return {
|
||||
c0: Fp2.frobeniusMap(c0, power),
|
||||
c1: Fp2.mul(Fp2.frobeniusMap(c1, power), this.FROBENIUS_COEFFICIENTS_1[power % 6]),
|
||||
c2: Fp2.mul(Fp2.frobeniusMap(c2, power), this.FROBENIUS_COEFFICIENTS_2[power % 6]),
|
||||
};
|
||||
}
|
||||
mulByFp2({ c0, c1, c2 }: Fp6, rhs: Fp2): Fp6 {
|
||||
const { Fp2 } = this;
|
||||
return {
|
||||
c0: Fp2.mul(c0, rhs),
|
||||
c1: Fp2.mul(c1, rhs),
|
||||
c2: Fp2.mul(c2, rhs),
|
||||
};
|
||||
}
|
||||
mulByNonresidue({ c0, c1, c2 }: Fp6) {
|
||||
const { Fp2 } = this;
|
||||
return { c0: Fp2.mulByNonresidue(c2), c1: c0, c2: c1 };
|
||||
}
|
||||
// Sparse multiplication
|
||||
mul1({ c0, c1, c2 }: Fp6, b1: Fp2): Fp6 {
|
||||
const { Fp2 } = this;
|
||||
return {
|
||||
c0: Fp2.mulByNonresidue(Fp2.mul(c2, b1)),
|
||||
c1: Fp2.mul(c0, b1),
|
||||
c2: Fp2.mul(c1, b1),
|
||||
};
|
||||
}
|
||||
// Sparse multiplication
|
||||
mul01({ c0, c1, c2 }: Fp6, b0: Fp2, b1: Fp2): Fp6 {
|
||||
const { Fp2 } = this;
|
||||
let t0 = Fp2.mul(c0, b0); // c0 * b0
|
||||
let t1 = Fp2.mul(c1, b1); // c1 * b1
|
||||
return {
|
||||
// ((c1 + c2) * b1 - T1) * (u + 1) + T0
|
||||
c0: Fp2.add(Fp2.mulByNonresidue(Fp2.sub(Fp2.mul(Fp2.add(c1, c2), b1), t1)), t0),
|
||||
// (b0 + b1) * (c0 + c1) - T0 - T1
|
||||
c1: Fp2.sub(Fp2.sub(Fp2.mul(Fp2.add(b0, b1), Fp2.add(c0, c1)), t0), t1),
|
||||
// (c0 + c2) * b0 - T0 + T1
|
||||
c2: Fp2.add(Fp2.sub(Fp2.mul(Fp2.add(c0, c2), b0), t0), t1),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class _Field12 implements Fp12Bls {
|
||||
readonly ORDER: bigint;
|
||||
readonly BITS: number;
|
||||
readonly BYTES: number;
|
||||
readonly isLE: boolean;
|
||||
readonly MASK = _1n;
|
||||
|
||||
readonly ZERO: Fp12;
|
||||
readonly ONE: Fp12;
|
||||
|
||||
readonly Fp6: Fp6Bls;
|
||||
readonly FROBENIUS_COEFFICIENTS: Fp2[];
|
||||
readonly X_LEN: number;
|
||||
readonly finalExponentiate: Tower12Opts['Fp12finalExponentiate'];
|
||||
|
||||
constructor(Fp6: Fp6Bls, opts: Tower12Opts) {
|
||||
const { Fp2 } = Fp6;
|
||||
const { Fp } = Fp2;
|
||||
this.Fp6 = Fp6;
|
||||
|
||||
this.ORDER = Fp2.ORDER; // TODO: verify if it's unuesd
|
||||
this.BITS = 2 * Fp6.BITS;
|
||||
this.BYTES = 2 * Fp6.BYTES;
|
||||
this.isLE = Fp6.isLE;
|
||||
this.ZERO = { c0: Fp6.ZERO, c1: Fp6.ZERO };
|
||||
this.ONE = { c0: Fp6.ONE, c1: Fp6.ZERO };
|
||||
|
||||
this.FROBENIUS_COEFFICIENTS = calcFrobeniusCoefficients(
|
||||
Fp2,
|
||||
Fp2.NONRESIDUE,
|
||||
Fp.ORDER,
|
||||
12,
|
||||
1,
|
||||
6
|
||||
)[0];
|
||||
this.X_LEN = opts.X_LEN;
|
||||
this.finalExponentiate = opts.Fp12finalExponentiate;
|
||||
}
|
||||
create(num: Fp12) {
|
||||
return num;
|
||||
}
|
||||
isValid({ c0, c1 }: Fp12) {
|
||||
const { Fp6 } = this;
|
||||
return Fp6.isValid(c0) && Fp6.isValid(c1);
|
||||
}
|
||||
is0({ c0, c1 }: Fp12) {
|
||||
const { Fp6 } = this;
|
||||
return Fp6.is0(c0) && Fp6.is0(c1);
|
||||
}
|
||||
isValidNot0(num: Fp12) {
|
||||
return !this.is0(num) && this.isValid(num);
|
||||
}
|
||||
neg({ c0, c1 }: Fp12) {
|
||||
const { Fp6 } = this;
|
||||
return { c0: Fp6.neg(c0), c1: Fp6.neg(c1) };
|
||||
}
|
||||
eql({ c0, c1 }: Fp12, { c0: r0, c1: r1 }: Fp12) {
|
||||
const { Fp6 } = this;
|
||||
return Fp6.eql(c0, r0) && Fp6.eql(c1, r1);
|
||||
}
|
||||
sqrt(_: any): any {
|
||||
notImplemented();
|
||||
}
|
||||
inv({ c0, c1 }: Fp12) {
|
||||
const { Fp6 } = this;
|
||||
let t = Fp6.inv(Fp6.sub(Fp6.sqr(c0), Fp6.mulByNonresidue(Fp6.sqr(c1)))); // 1 / (c0² - c1² * v)
|
||||
return { c0: Fp6.mul(c0, t), c1: Fp6.neg(Fp6.mul(c1, t)) }; // ((C0 * T) * T) + (-C1 * T) * w
|
||||
}
|
||||
div(lhs: Fp12, rhs: Fp12) {
|
||||
const { Fp6 } = this;
|
||||
const { Fp2 } = Fp6;
|
||||
const { Fp } = Fp2;
|
||||
return this.mul(lhs, typeof rhs === 'bigint' ? Fp.inv(Fp.create(rhs)) : this.inv(rhs));
|
||||
}
|
||||
pow(num: Fp12, power: bigint): Fp12 {
|
||||
return mod.FpPow(this, num, power);
|
||||
}
|
||||
invertBatch(nums: Fp12[]): Fp12[] {
|
||||
return mod.FpInvertBatch(this, nums);
|
||||
}
|
||||
|
||||
// Normalized
|
||||
add({ c0, c1 }: Fp12, { c0: r0, c1: r1 }: Fp12) {
|
||||
const { Fp6 } = this;
|
||||
return {
|
||||
c0: Fp6.add(c0, r0),
|
||||
c1: Fp6.add(c1, r1),
|
||||
};
|
||||
}
|
||||
sub({ c0, c1 }: Fp12, { c0: r0, c1: r1 }: Fp12) {
|
||||
const { Fp6 } = this;
|
||||
return {
|
||||
c0: Fp6.sub(c0, r0),
|
||||
c1: Fp6.sub(c1, r1),
|
||||
};
|
||||
}
|
||||
mul({ c0, c1 }: Fp12, rhs: Fp12 | bigint) {
|
||||
const { Fp6 } = this;
|
||||
if (typeof rhs === 'bigint') return { c0: Fp6.mul(c0, rhs), c1: Fp6.mul(c1, rhs) };
|
||||
let { c0: r0, c1: r1 } = rhs;
|
||||
let t1 = Fp6.mul(c0, r0); // c0 * r0
|
||||
let t2 = Fp6.mul(c1, r1); // c1 * r1
|
||||
return {
|
||||
c0: Fp6.add(t1, Fp6.mulByNonresidue(t2)), // T1 + T2 * v
|
||||
// (c0 + c1) * (r0 + r1) - (T1 + T2)
|
||||
c1: Fp6.sub(Fp6.mul(Fp6.add(c0, c1), Fp6.add(r0, r1)), Fp6.add(t1, t2)),
|
||||
};
|
||||
}
|
||||
sqr({ c0, c1 }: Fp12) {
|
||||
const { Fp6 } = this;
|
||||
let ab = Fp6.mul(c0, c1); // c0 * c1
|
||||
return {
|
||||
// (c1 * v + c0) * (c0 + c1) - AB - AB * v
|
||||
c0: Fp6.sub(
|
||||
Fp6.sub(Fp6.mul(Fp6.add(Fp6.mulByNonresidue(c1), c0), Fp6.add(c0, c1)), ab),
|
||||
Fp6.mulByNonresidue(ab)
|
||||
),
|
||||
c1: Fp6.add(ab, ab),
|
||||
}; // AB + AB
|
||||
}
|
||||
// NonNormalized stuff
|
||||
addN(a: Fp12, b: Fp12): Fp12 {
|
||||
return this.add(a, b);
|
||||
}
|
||||
subN(a: Fp12, b: Fp12): Fp12 {
|
||||
return this.sub(a, b);
|
||||
}
|
||||
mulN(a: Fp12, b: Fp12): Fp12 {
|
||||
return this.mul(a, b);
|
||||
}
|
||||
sqrN(a: Fp12): Fp12 {
|
||||
return this.sqr(a);
|
||||
}
|
||||
|
||||
// Bytes utils
|
||||
fromBytes(b: Uint8Array): Fp12 {
|
||||
const { Fp6 } = this;
|
||||
if (b.length !== this.BYTES) throw new Error('fromBytes invalid length=' + b.length);
|
||||
return {
|
||||
c0: Fp6.fromBytes(b.subarray(0, Fp6.BYTES)),
|
||||
c1: Fp6.fromBytes(b.subarray(Fp6.BYTES)),
|
||||
};
|
||||
}
|
||||
toBytes({ c0, c1 }: Fp12): Uint8Array {
|
||||
const { Fp6 } = this;
|
||||
return concatBytes(Fp6.toBytes(c0), Fp6.toBytes(c1));
|
||||
}
|
||||
cmov({ c0, c1 }: Fp12, { c0: r0, c1: r1 }: Fp12, c: boolean) {
|
||||
const { Fp6 } = this;
|
||||
return {
|
||||
c0: Fp6.cmov(c0, r0, c),
|
||||
c1: Fp6.cmov(c1, r1, c),
|
||||
};
|
||||
}
|
||||
// Utils
|
||||
// toString() {
|
||||
// return '' + 'Fp12(' + this.c0 + this.c1 + '* w');
|
||||
// },
|
||||
// fromTuple(c: [Fp6, Fp6]) {
|
||||
// return new Fp12(...c);
|
||||
// }
|
||||
fromBigTwelve(t: BigintTwelve): Fp12 {
|
||||
const { Fp6 } = this;
|
||||
return {
|
||||
c0: Fp6.fromBigSix(t.slice(0, 6) as BigintSix),
|
||||
c1: Fp6.fromBigSix(t.slice(6, 12) as BigintSix),
|
||||
};
|
||||
}
|
||||
// Raises to q**i -th power
|
||||
frobeniusMap(lhs: Fp12, power: number) {
|
||||
const { Fp6 } = this;
|
||||
const { Fp2 } = Fp6;
|
||||
const { c0, c1, c2 } = Fp6.frobeniusMap(lhs.c1, power);
|
||||
const coeff = this.FROBENIUS_COEFFICIENTS[power % 12];
|
||||
return {
|
||||
c0: Fp6.frobeniusMap(lhs.c0, power),
|
||||
c1: Fp6.create({
|
||||
c0: Fp2.mul(c0, coeff),
|
||||
c1: Fp2.mul(c1, coeff),
|
||||
c2: Fp2.mul(c2, coeff),
|
||||
}),
|
||||
};
|
||||
}
|
||||
mulByFp2({ c0, c1 }: Fp12, rhs: Fp2): Fp12 {
|
||||
const { Fp6 } = this;
|
||||
return {
|
||||
c0: Fp6.mulByFp2(c0, rhs),
|
||||
c1: Fp6.mulByFp2(c1, rhs),
|
||||
};
|
||||
}
|
||||
conjugate({ c0, c1 }: Fp12): Fp12 {
|
||||
return { c0, c1: this.Fp6.neg(c1) };
|
||||
}
|
||||
// Sparse multiplication
|
||||
mul014({ c0, c1 }: Fp12, o0: Fp2, o1: Fp2, o4: Fp2) {
|
||||
const { Fp6 } = this;
|
||||
const { Fp2 } = Fp6;
|
||||
let t0 = Fp6.mul01(c0, o0, o1);
|
||||
let t1 = Fp6.mul1(c1, o4);
|
||||
return {
|
||||
c0: Fp6.add(Fp6.mulByNonresidue(t1), t0), // T1 * v + T0
|
||||
// (c1 + c0) * [o0, o1+o4] - T0 - T1
|
||||
c1: Fp6.sub(Fp6.sub(Fp6.mul01(Fp6.add(c1, c0), o0, Fp2.add(o1, o4)), t0), t1),
|
||||
};
|
||||
}
|
||||
mul034({ c0, c1 }: Fp12, o0: Fp2, o3: Fp2, o4: Fp2) {
|
||||
const { Fp6 } = this;
|
||||
const { Fp2 } = Fp6;
|
||||
const a = Fp6.create({
|
||||
c0: Fp2.mul(c0.c0, o0),
|
||||
c1: Fp2.mul(c0.c1, o0),
|
||||
c2: Fp2.mul(c0.c2, o0),
|
||||
});
|
||||
const b = Fp6.mul01(c1, o3, o4);
|
||||
const e = Fp6.mul01(Fp6.add(c0, c1), Fp2.add(o0, o3), o4);
|
||||
return {
|
||||
c0: Fp6.add(Fp6.mulByNonresidue(b), a),
|
||||
c1: Fp6.sub(e, Fp6.add(a, b)),
|
||||
};
|
||||
}
|
||||
|
||||
// A cyclotomic group is a subgroup of Fp^n defined by
|
||||
// GΦₙ(p) = {α ∈ Fpⁿ : α^Φₙ(p) = 1}
|
||||
// The result of any pairing is in a cyclotomic subgroup
|
||||
// https://eprint.iacr.org/2009/565.pdf
|
||||
// https://eprint.iacr.org/2010/354.pdf
|
||||
_cyclotomicSquare({ c0, c1 }: Fp12): Fp12 {
|
||||
const { Fp6 } = this;
|
||||
const { Fp2 } = Fp6;
|
||||
const { c0: c0c0, c1: c0c1, c2: c0c2 } = c0;
|
||||
const { c0: c1c0, c1: c1c1, c2: c1c2 } = c1;
|
||||
const { first: t3, second: t4 } = Fp2.Fp4Square(c0c0, c1c1);
|
||||
const { first: t5, second: t6 } = Fp2.Fp4Square(c1c0, c0c2);
|
||||
const { first: t7, second: t8 } = Fp2.Fp4Square(c0c1, c1c2);
|
||||
const t9 = Fp2.mulByNonresidue(t8); // T8 * (u + 1)
|
||||
return {
|
||||
c0: Fp6.create({
|
||||
c0: Fp2.add(Fp2.mul(Fp2.sub(t3, c0c0), _2n), t3), // 2 * (T3 - c0c0) + T3
|
||||
c1: Fp2.add(Fp2.mul(Fp2.sub(t5, c0c1), _2n), t5), // 2 * (T5 - c0c1) + T5
|
||||
c2: Fp2.add(Fp2.mul(Fp2.sub(t7, c0c2), _2n), t7),
|
||||
}), // 2 * (T7 - c0c2) + T7
|
||||
c1: Fp6.create({
|
||||
c0: Fp2.add(Fp2.mul(Fp2.add(t9, c1c0), _2n), t9), // 2 * (T9 + c1c0) + T9
|
||||
c1: Fp2.add(Fp2.mul(Fp2.add(t4, c1c1), _2n), t4), // 2 * (T4 + c1c1) + T4
|
||||
c2: Fp2.add(Fp2.mul(Fp2.add(t6, c1c2), _2n), t6),
|
||||
}),
|
||||
}; // 2 * (T6 + c1c2) + T6
|
||||
}
|
||||
// https://eprint.iacr.org/2009/565.pdf
|
||||
_cyclotomicExp(num: Fp12, n: bigint): Fp12 {
|
||||
let z = this.ONE;
|
||||
for (let i = this.X_LEN - 1; i >= 0; i--) {
|
||||
z = this._cyclotomicSquare(z);
|
||||
if (bitGet(n, i)) z = this.mul(z, num);
|
||||
}
|
||||
return z;
|
||||
}
|
||||
}
|
||||
|
||||
export function tower12(opts: Tower12Opts): {
|
||||
Fp: Readonly<mod.IField<bigint> & Required<Pick<mod.IField<bigint>, 'isOdd'>>>;
|
||||
Fp2: Fp2Bls;
|
||||
Fp6: Fp6Bls;
|
||||
Fp12: Fp12Bls;
|
||||
} {
|
||||
const Fp = mod.Field(opts.ORDER);
|
||||
const Fp2 = new _Field2(Fp, opts);
|
||||
const Fp6 = new _Field6(Fp2);
|
||||
const Fp12 = new _Field12(Fp6, opts);
|
||||
return { Fp, Fp2, Fp6, Fp12 };
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
import * as util from "../core/util.js";
|
||||
const error = () => {
|
||||
const Sizable = {
|
||||
string: { unit: "tegn", verb: "å ha" },
|
||||
file: { unit: "bytes", verb: "å ha" },
|
||||
array: { unit: "elementer", verb: "å inneholde" },
|
||||
set: { unit: "elementer", verb: "å inneholde" },
|
||||
};
|
||||
function getSizing(origin) {
|
||||
return Sizable[origin] ?? null;
|
||||
}
|
||||
const FormatDictionary = {
|
||||
regex: "input",
|
||||
email: "e-postadresse",
|
||||
url: "URL",
|
||||
emoji: "emoji",
|
||||
uuid: "UUID",
|
||||
uuidv4: "UUIDv4",
|
||||
uuidv6: "UUIDv6",
|
||||
nanoid: "nanoid",
|
||||
guid: "GUID",
|
||||
cuid: "cuid",
|
||||
cuid2: "cuid2",
|
||||
ulid: "ULID",
|
||||
xid: "XID",
|
||||
ksuid: "KSUID",
|
||||
datetime: "ISO dato- og klokkeslett",
|
||||
date: "ISO-dato",
|
||||
time: "ISO-klokkeslett",
|
||||
duration: "ISO-varighet",
|
||||
ipv4: "IPv4-område",
|
||||
ipv6: "IPv6-område",
|
||||
cidrv4: "IPv4-spekter",
|
||||
cidrv6: "IPv6-spekter",
|
||||
base64: "base64-enkodet streng",
|
||||
base64url: "base64url-enkodet streng",
|
||||
json_string: "JSON-streng",
|
||||
e164: "E.164-nummer",
|
||||
jwt: "JWT",
|
||||
template_literal: "input",
|
||||
};
|
||||
const TypeDictionary = {
|
||||
nan: "NaN",
|
||||
number: "tall",
|
||||
array: "liste",
|
||||
};
|
||||
return (issue) => {
|
||||
switch (issue.code) {
|
||||
case "invalid_type": {
|
||||
const expected = TypeDictionary[issue.expected] ?? issue.expected;
|
||||
const receivedType = util.parsedType(issue.input);
|
||||
const received = TypeDictionary[receivedType] ?? receivedType;
|
||||
if (/^[A-Z]/.test(issue.expected)) {
|
||||
return `Ugyldig input: forventet instanceof ${issue.expected}, fikk ${received}`;
|
||||
}
|
||||
return `Ugyldig input: forventet ${expected}, fikk ${received}`;
|
||||
}
|
||||
case "invalid_value":
|
||||
if (issue.values.length === 1)
|
||||
return `Ugyldig verdi: forventet ${util.stringifyPrimitive(issue.values[0])}`;
|
||||
return `Ugyldig valg: forventet en av ${util.joinValues(issue.values, "|")}`;
|
||||
case "too_big": {
|
||||
const adj = issue.inclusive ? "<=" : "<";
|
||||
const sizing = getSizing(issue.origin);
|
||||
if (sizing)
|
||||
return `For stor(t): forventet ${issue.origin ?? "value"} til å ha ${adj}${issue.maximum.toString()} ${sizing.unit ?? "elementer"}`;
|
||||
return `For stor(t): forventet ${issue.origin ?? "value"} til å ha ${adj}${issue.maximum.toString()}`;
|
||||
}
|
||||
case "too_small": {
|
||||
const adj = issue.inclusive ? ">=" : ">";
|
||||
const sizing = getSizing(issue.origin);
|
||||
if (sizing) {
|
||||
return `For lite(n): forventet ${issue.origin} til å ha ${adj}${issue.minimum.toString()} ${sizing.unit}`;
|
||||
}
|
||||
return `For lite(n): forventet ${issue.origin} til å ha ${adj}${issue.minimum.toString()}`;
|
||||
}
|
||||
case "invalid_format": {
|
||||
const _issue = issue;
|
||||
if (_issue.format === "starts_with")
|
||||
return `Ugyldig streng: må starte med "${_issue.prefix}"`;
|
||||
if (_issue.format === "ends_with")
|
||||
return `Ugyldig streng: må ende med "${_issue.suffix}"`;
|
||||
if (_issue.format === "includes")
|
||||
return `Ugyldig streng: må inneholde "${_issue.includes}"`;
|
||||
if (_issue.format === "regex")
|
||||
return `Ugyldig streng: må matche mønsteret ${_issue.pattern}`;
|
||||
return `Ugyldig ${FormatDictionary[_issue.format] ?? issue.format}`;
|
||||
}
|
||||
case "not_multiple_of":
|
||||
return `Ugyldig tall: må være et multiplum av ${issue.divisor}`;
|
||||
case "unrecognized_keys":
|
||||
return `${issue.keys.length > 1 ? "Ukjente nøkler" : "Ukjent nøkkel"}: ${util.joinValues(issue.keys, ", ")}`;
|
||||
case "invalid_key":
|
||||
return `Ugyldig nøkkel i ${issue.origin}`;
|
||||
case "invalid_union":
|
||||
return "Ugyldig input";
|
||||
case "invalid_element":
|
||||
return `Ugyldig verdi i ${issue.origin}`;
|
||||
default:
|
||||
return `Ugyldig input`;
|
||||
}
|
||||
};
|
||||
};
|
||||
export default function () {
|
||||
return {
|
||||
localeError: error(),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
'use strict';
|
||||
|
||||
const {Transform} = require('stream');
|
||||
|
||||
class Skip extends Transform {
|
||||
constructor(options) {
|
||||
super(Object.assign({}, options, {writableObjectMode: true, readableObjectMode: true}));
|
||||
this._n = 0;
|
||||
if (options) {
|
||||
'n' in options && (this._n = options.n);
|
||||
}
|
||||
if (this._n <= 0) {
|
||||
this._transform = this._passThrough;
|
||||
}
|
||||
}
|
||||
_transform(chunk, encoding, callback) {
|
||||
if (--this._n <= 0) {
|
||||
this._transform = this._passThrough;
|
||||
}
|
||||
callback(null);
|
||||
}
|
||||
_passThrough(chunk, encoding, callback) {
|
||||
this.push(chunk);
|
||||
callback(null);
|
||||
}
|
||||
static make(n) {
|
||||
return new Skip(typeof n == 'object' ? n : {n});
|
||||
}
|
||||
}
|
||||
Skip.make.Constructor = Skip;
|
||||
|
||||
module.exports = Skip.make;
|
||||
@@ -0,0 +1,18 @@
|
||||
'use strict'
|
||||
|
||||
const { parentPort } = require('worker_threads')
|
||||
const { Writable } = require('stream')
|
||||
|
||||
function run () {
|
||||
parentPort.once('message', function ({ text, takeThisPortPlease }) {
|
||||
takeThisPortPlease.postMessage(`received: ${text}`)
|
||||
})
|
||||
return new Writable({
|
||||
autoDestroy: true,
|
||||
write (chunk, enc, cb) {
|
||||
cb()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = run
|
||||
@@ -0,0 +1,13 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.TSEnumMemberDefinition = void 0;
|
||||
const DefinitionBase_1 = require("./DefinitionBase");
|
||||
const DefinitionType_1 = require("./DefinitionType");
|
||||
class TSEnumMemberDefinition extends DefinitionBase_1.DefinitionBase {
|
||||
isTypeDefinition = true;
|
||||
isVariableDefinition = true;
|
||||
constructor(name, node) {
|
||||
super(DefinitionType_1.DefinitionType.TSEnumMember, name, node, null);
|
||||
}
|
||||
}
|
||||
exports.TSEnumMemberDefinition = TSEnumMemberDefinition;
|
||||
@@ -0,0 +1,24 @@
|
||||
/* global test, expect */
|
||||
'use strict'
|
||||
|
||||
const { createWarning } = require('..')
|
||||
|
||||
if (globalThis.test) {
|
||||
test('works with jest', done => {
|
||||
const code = createWarning({
|
||||
name: 'TestDeprecation',
|
||||
code: 'CODE',
|
||||
message: 'Hello world'
|
||||
})
|
||||
code('world')
|
||||
|
||||
// we cannot actually listen to process warning event
|
||||
// because jest messes with it (that's the point of this test)
|
||||
// we can only test it was emitted indirectly
|
||||
// and test no exception is raised
|
||||
setImmediate(() => {
|
||||
expect(code.emitted).toBeTruthy()
|
||||
done()
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
export namespace enumUtil {
|
||||
type UnionToIntersectionFn<T> = (T extends unknown ? (k: () => T) => void : never) extends (
|
||||
k: infer Intersection
|
||||
) => void
|
||||
? Intersection
|
||||
: never;
|
||||
|
||||
type GetUnionLast<T> = UnionToIntersectionFn<T> extends () => infer Last ? Last : never;
|
||||
|
||||
type UnionToTuple<T, Tuple extends unknown[] = []> = [T] extends [never]
|
||||
? Tuple
|
||||
: UnionToTuple<Exclude<T, GetUnionLast<T>>, [GetUnionLast<T>, ...Tuple]>;
|
||||
|
||||
type CastToStringTuple<T> = T extends [string, ...string[]] ? T : never;
|
||||
|
||||
export type UnionToTupleString<T> = CastToStringTuple<UnionToTuple<T>>;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
"use strict";
|
||||
// THIS CODE WAS AUTOMATICALLY GENERATED
|
||||
// DO NOT EDIT THIS CODE BY HAND
|
||||
// RUN THE FOLLOWING COMMAND FROM THE WORKSPACE ROOT TO REGENERATE:
|
||||
// npx nx generate-lib repo
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.es2020_intl = void 0;
|
||||
const base_config_1 = require("./base-config");
|
||||
const es2018_intl_1 = require("./es2018.intl");
|
||||
exports.es2020_intl = {
|
||||
libs: [es2018_intl_1.es2018_intl],
|
||||
variables: [['Intl', base_config_1.TYPE_VALUE]],
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
"use strict";
|
||||
|
||||
var _class_apply_descriptor_get = require("./_class_apply_descriptor_get.cjs");
|
||||
var _class_check_private_static_access = require("./_class_check_private_static_access.cjs");
|
||||
var _class_check_private_static_field_descriptor = require("./_class_check_private_static_field_descriptor.cjs");
|
||||
|
||||
function _class_static_private_field_spec_get(receiver, classConstructor, descriptor) {
|
||||
_class_check_private_static_access._(receiver, classConstructor);
|
||||
_class_check_private_static_field_descriptor._(descriptor, "get");
|
||||
|
||||
return _class_apply_descriptor_get._(receiver, descriptor);
|
||||
}
|
||||
exports._ = _class_static_private_field_spec_get;
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"main": "../../cjs/_class_static_private_field_spec_set.cjs",
|
||||
"module": "../../esm/_class_static_private_field_spec_set.js"
|
||||
}
|
||||
Reference in New Issue
Block a user