forked from tornado-packages/noble-curves
stark: refactor
This commit is contained in:
parent
8c77331ef2
commit
285aa6375d
228
src/stark.ts
228
src/stark.ts
@ -1,164 +1,126 @@
|
|||||||
/*! 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 { weierstrass, ProjPointType } from './abstract/weierstrass.js';
|
|
||||||
import * as cutils from './abstract/utils.js';
|
|
||||||
import { Fp, mod, Field, validateField } from './abstract/modular.js';
|
|
||||||
import { getHash } from './_shortw_utils.js';
|
|
||||||
import * as poseidon from './abstract/poseidon.js';
|
|
||||||
import { utf8ToBytes } from '@noble/hashes/utils';
|
import { utf8ToBytes } from '@noble/hashes/utils';
|
||||||
|
import { Fp, mod, Field, validateField } from './abstract/modular.js';
|
||||||
|
import { poseidon } from './abstract/poseidon.js';
|
||||||
|
import { weierstrass, ProjPointType, SignatureType } from './abstract/weierstrass.js';
|
||||||
|
import {
|
||||||
|
Hex,
|
||||||
|
bitMask,
|
||||||
|
bytesToHex,
|
||||||
|
bytesToNumberBE,
|
||||||
|
concatBytes,
|
||||||
|
ensureBytes as ensureBytesOrig,
|
||||||
|
hexToBytes,
|
||||||
|
hexToNumber,
|
||||||
|
numberToVarBytesBE,
|
||||||
|
} from './abstract/utils.js';
|
||||||
|
import { getHash } from './_shortw_utils.js';
|
||||||
|
|
||||||
type ProjectivePoint = ProjPointType<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
|
||||||
|
|
||||||
const CURVE_N = BigInt(
|
type ProjectivePoint = ProjPointType<bigint>;
|
||||||
|
const CURVE_ORDER = BigInt(
|
||||||
'3618502788666131213697322783095070105526743751716087489154079457884512865583'
|
'3618502788666131213697322783095070105526743751716087489154079457884512865583'
|
||||||
);
|
);
|
||||||
const nBitLength = 252;
|
const nBitLength = 252;
|
||||||
// Copy-pasted from weierstrass.ts
|
|
||||||
function bits2int(bytes: Uint8Array): bigint {
|
function bits2int(bytes: Uint8Array): bigint {
|
||||||
|
while (bytes[0] === 0) bytes = bytes.subarray(1); // strip leading 0s
|
||||||
|
// Copy-pasted from weierstrass.ts
|
||||||
const delta = bytes.length * 8 - nBitLength;
|
const delta = bytes.length * 8 - nBitLength;
|
||||||
const num = cutils.bytesToNumberBE(bytes);
|
const num = bytesToNumberBE(bytes);
|
||||||
return delta > 0 ? num >> BigInt(delta) : num;
|
return delta > 0 ? num >> BigInt(delta) : num;
|
||||||
}
|
}
|
||||||
function bits2int_modN(bytes: Uint8Array): bigint {
|
function hex0xToBytes(hex: string): Uint8Array {
|
||||||
return mod(bits2int(bytes), CURVE_N);
|
if (typeof hex === 'string') {
|
||||||
|
hex = strip0x(hex); // allow 0x prefix
|
||||||
|
if (hex.length & 1) hex = '0' + hex; // allow unpadded hex
|
||||||
}
|
}
|
||||||
export const starkCurve = weierstrass({
|
return hexToBytes(hex);
|
||||||
// Params: a, b
|
}
|
||||||
a: BigInt(1),
|
const curve = weierstrass({
|
||||||
|
a: BigInt(1), // Params: a, b
|
||||||
b: BigInt('3141592653589793238462643383279502884197169399375105820974944592307816406665'),
|
b: BigInt('3141592653589793238462643383279502884197169399375105820974944592307816406665'),
|
||||||
// Field over which we'll do calculations; 2n**251n + 17n * 2n**192n + 1n
|
// Field over which we'll do calculations; 2n**251n + 17n * 2n**192n + 1n
|
||||||
// There is no efficient sqrt for field (P%4==1)
|
// There is no efficient sqrt for field (P%4==1)
|
||||||
Fp: Fp(BigInt('0x800000000000011000000000000000000000000000000000000000000000001')),
|
Fp: Fp(BigInt('0x800000000000011000000000000000000000000000000000000000000000001')),
|
||||||
// Curve order, total count of valid points in the field.
|
n: CURVE_ORDER, // Curve order, total count of valid points in the field.
|
||||||
n: CURVE_N,
|
nBitLength, // len(bin(N).replace('0b',''))
|
||||||
nBitLength: nBitLength, // len(bin(N).replace('0b',''))
|
|
||||||
// Base point (x, y) aka generator point
|
// Base point (x, y) aka generator point
|
||||||
Gx: BigInt('874739451078007766457464989774322083649278607533249481151382481072868806602'),
|
Gx: BigInt('874739451078007766457464989774322083649278607533249481151382481072868806602'),
|
||||||
Gy: BigInt('152666792071518830868575557812948353041420400780739481342941381225525861407'),
|
Gy: BigInt('152666792071518830868575557812948353041420400780739481342941381225525861407'),
|
||||||
h: BigInt(1),
|
h: BigInt(1), // cofactor
|
||||||
// Default options
|
lowS: false, // Allow high-s signatures
|
||||||
lowS: false,
|
|
||||||
...getHash(sha256),
|
...getHash(sha256),
|
||||||
// Custom truncation routines for stark curve
|
// Custom truncation routines for stark curve
|
||||||
bits2int: (bytes: Uint8Array): bigint => {
|
bits2int,
|
||||||
while (bytes[0] === 0) bytes = bytes.subarray(1);
|
|
||||||
return bits2int(bytes);
|
|
||||||
},
|
|
||||||
bits2int_modN: (bytes: Uint8Array): bigint => {
|
bits2int_modN: (bytes: Uint8Array): bigint => {
|
||||||
let hashS = cutils.bytesToNumberBE(bytes).toString(16);
|
// 2102820b232636d200cb21f1d330f20d096cae09d1bf3edb1cc333ddee11318 =>
|
||||||
if (hashS.length === 63) {
|
// 2102820b232636d200cb21f1d330f20d096cae09d1bf3edb1cc333ddee113180
|
||||||
hashS += '0';
|
const hex = bytesToNumberBE(bytes).toString(16); // toHex unpadded
|
||||||
bytes = hexToBytes0x(hashS);
|
if (hex.length === 63) bytes = hex0xToBytes(hex + '0'); // append trailing 0
|
||||||
}
|
return mod(bits2int(bytes), CURVE_ORDER);
|
||||||
// Truncate zero bytes on left (compat with elliptic)
|
|
||||||
while (bytes[0] === 0) bytes = bytes.subarray(1);
|
|
||||||
return bits2int_modN(bytes);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
export const _starkCurve = curve;
|
||||||
|
|
||||||
// Custom Starknet type conversion functions that can handle 0x and unpadded hex
|
function ensureBytes(hex: Hex): Uint8Array {
|
||||||
function hexToBytes0x(hex: string): Uint8Array {
|
return ensureBytesOrig('', typeof hex === 'string' ? hex0xToBytes(hex) : hex);
|
||||||
if (typeof hex !== 'string') {
|
|
||||||
throw new Error('hexToBytes: expected string, got ' + typeof hex);
|
|
||||||
}
|
|
||||||
hex = strip0x(hex);
|
|
||||||
if (hex.length & 1) hex = '0' + hex; // padding
|
|
||||||
if (hex.length % 2) throw new Error('hexToBytes: received invalid unpadded hex ' + hex.length);
|
|
||||||
const array = new Uint8Array(hex.length / 2);
|
|
||||||
for (let i = 0; i < array.length; i++) {
|
|
||||||
const j = i * 2;
|
|
||||||
const hexByte = hex.slice(j, j + 2);
|
|
||||||
const byte = Number.parseInt(hexByte, 16);
|
|
||||||
if (Number.isNaN(byte) || byte < 0) throw new Error('Invalid byte sequence');
|
|
||||||
array[i] = byte;
|
|
||||||
}
|
|
||||||
return array;
|
|
||||||
}
|
|
||||||
function hexToNumber0x(hex: string): bigint {
|
|
||||||
if (typeof hex !== 'string') {
|
|
||||||
throw new Error('hexToNumber: expected string, got ' + typeof hex);
|
|
||||||
}
|
|
||||||
// Big Endian
|
|
||||||
// TODO: strip vs no strip?
|
|
||||||
return BigInt(`0x${strip0x(hex)}`);
|
|
||||||
}
|
|
||||||
function bytesToNumber0x(bytes: Uint8Array): bigint {
|
|
||||||
return hexToNumber0x(cutils.bytesToHex(bytes));
|
|
||||||
}
|
|
||||||
function ensureBytes0x(hex: Hex): Uint8Array {
|
|
||||||
// Uint8Array.from() instead of hash.slice() because node.js Buffer
|
|
||||||
// is instance of Uint8Array, and its slice() creates **mutable** copy
|
|
||||||
return hex instanceof Uint8Array ? Uint8Array.from(hex) : hexToBytes0x(hex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function normPrivKey(privKey: Hex) {
|
function normPrivKey(privKey: Hex): string {
|
||||||
return cutils.bytesToHex(ensureBytes0x(privKey)).padStart(64, '0');
|
return bytesToHex(ensureBytes(privKey)).padStart(64, '0');
|
||||||
}
|
}
|
||||||
function getPublicKey0x(privKey: Hex, isCompressed = false) {
|
export function getPublicKey(privKey: Hex, isCompressed = false): Uint8Array {
|
||||||
return starkCurve.getPublicKey(normPrivKey(privKey), isCompressed);
|
return curve.getPublicKey(normPrivKey(privKey), isCompressed);
|
||||||
}
|
}
|
||||||
function getSharedSecret0x(privKeyA: Hex, pubKeyB: Hex) {
|
export function getSharedSecret(privKeyA: Hex, pubKeyB: Hex): Uint8Array {
|
||||||
return starkCurve.getSharedSecret(normPrivKey(privKeyA), pubKeyB);
|
return curve.getSharedSecret(normPrivKey(privKeyA), pubKeyB);
|
||||||
|
}
|
||||||
|
export function sign(msgHash: Hex, privKey: Hex, opts?: any): SignatureType {
|
||||||
|
return curve.sign(ensureBytes(msgHash), normPrivKey(privKey), opts);
|
||||||
|
}
|
||||||
|
export function verify(signature: SignatureType | Hex, msgHash: Hex, pubKey: Hex) {
|
||||||
|
const sig = signature instanceof Signature ? signature : ensureBytes(signature);
|
||||||
|
return curve.verify(sig, ensureBytes(msgHash), ensureBytes(pubKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
function sign0x(msgHash: Hex, privKey: Hex, opts?: any) {
|
const { CURVE, ProjectivePoint, Signature, utils } = curve;
|
||||||
if (typeof privKey === 'string') privKey = strip0x(privKey).padStart(64, '0');
|
export { CURVE, ProjectivePoint, Signature, utils };
|
||||||
return starkCurve.sign(ensureBytes0x(msgHash), normPrivKey(privKey), opts);
|
|
||||||
|
function extractX(bytes: Uint8Array): string {
|
||||||
|
const hex = bytesToHex(bytes.subarray(1));
|
||||||
|
const stripped = hex.replace(/^0+/gm, ''); // strip leading 0s
|
||||||
|
return `0x${stripped}`;
|
||||||
}
|
}
|
||||||
function verify0x(signature: Hex, msgHash: Hex, pubKey: Hex) {
|
function strip0x(hex: string) {
|
||||||
const sig = signature instanceof Signature ? signature : ensureBytes0x(signature);
|
return hex.replace(/^0x/i, '');
|
||||||
return starkCurve.verify(sig, ensureBytes0x(msgHash), ensureBytes0x(pubKey));
|
}
|
||||||
}
|
function numberTo0x16(num: bigint) {
|
||||||
|
// can't use utils.numberToHexUnpadded: adds leading 0 for even byte length
|
||||||
const { CURVE, ProjectivePoint, Signature } = starkCurve;
|
return `0x${num.toString(16)}`;
|
||||||
export const utils = starkCurve.utils;
|
|
||||||
export {
|
|
||||||
CURVE,
|
|
||||||
Signature,
|
|
||||||
ProjectivePoint,
|
|
||||||
getPublicKey0x as getPublicKey,
|
|
||||||
getSharedSecret0x as getSharedSecret,
|
|
||||||
sign0x as sign,
|
|
||||||
verify0x as verify,
|
|
||||||
};
|
|
||||||
|
|
||||||
const stripLeadingZeros = (s: string) => s.replace(/^0+/gm, '');
|
|
||||||
export const bytesToHexEth = (uint8a: Uint8Array): string =>
|
|
||||||
`0x${stripLeadingZeros(cutils.bytesToHex(uint8a))}`;
|
|
||||||
export const strip0x = (hex: string) => hex.replace(/^0x/i, '');
|
|
||||||
export const numberToHexEth = (num: bigint | number) => `0x${num.toString(16)}`;
|
|
||||||
|
|
||||||
// We accept hex strings besides Uint8Array for simplicity
|
|
||||||
type Hex = Uint8Array | string;
|
|
||||||
|
|
||||||
// 1. seed generation
|
|
||||||
function hashKeyWithIndex(key: Uint8Array, index: number) {
|
|
||||||
let indexHex = cutils.numberToHexUnpadded(index);
|
|
||||||
if (indexHex.length & 1) indexHex = '0' + indexHex;
|
|
||||||
return sha256Num(cutils.concatBytes(key, hexToBytes0x(indexHex)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// seed generation
|
||||||
export function grindKey(seed: Hex) {
|
export function grindKey(seed: Hex) {
|
||||||
const _seed = ensureBytes0x(seed);
|
const _seed = ensureBytes(seed);
|
||||||
const sha256mask = 2n ** 256n;
|
const sha256mask = 2n ** 256n;
|
||||||
|
const limit = sha256mask - mod(sha256mask, CURVE_ORDER);
|
||||||
const limit = sha256mask - mod(sha256mask, CURVE_N);
|
|
||||||
for (let i = 0; ; i++) {
|
for (let i = 0; ; i++) {
|
||||||
const key = hashKeyWithIndex(_seed, i);
|
const key = sha256Num(concatBytes(_seed, numberToVarBytesBE(BigInt(i))));
|
||||||
// key should be in [0, limit)
|
if (key < limit) return mod(key, CURVE_ORDER).toString(16); // key should be in [0, limit)
|
||||||
if (key < limit) return mod(key, CURVE_N).toString(16);
|
if (i === 100000) throw new Error('grindKey is broken: tried 100k vals'); // prevent dos
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getStarkKey(privateKey: Hex) {
|
export function getStarkKey(privateKey: Hex): string {
|
||||||
return bytesToHexEth(getPublicKey0x(privateKey, true).slice(1));
|
return extractX(getPublicKey(privateKey, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ethSigToPrivate(signature: string) {
|
export function ethSigToPrivate(signature: string): string {
|
||||||
signature = strip0x(signature.replace(/^0x/, ''));
|
signature = strip0x(signature);
|
||||||
if (signature.length !== 130) throw new Error('Wrong ethereum signature');
|
if (signature.length !== 130) throw new Error('Wrong ethereum signature');
|
||||||
return grindKey(signature.substring(0, 64));
|
return grindKey(signature.substring(0, 64));
|
||||||
}
|
}
|
||||||
@ -170,15 +132,15 @@ export function getAccountPath(
|
|||||||
application: string,
|
application: string,
|
||||||
ethereumAddress: string,
|
ethereumAddress: string,
|
||||||
index: number
|
index: number
|
||||||
) {
|
): string {
|
||||||
const layerNum = int31(sha256Num(layer));
|
const layerNum = int31(sha256Num(layer));
|
||||||
const applicationNum = int31(sha256Num(application));
|
const applicationNum = int31(sha256Num(application));
|
||||||
const eth = hexToNumber0x(ethereumAddress);
|
const eth = hexToNumber(strip0x(ethereumAddress));
|
||||||
return `m/2645'/${layerNum}'/${applicationNum}'/${int31(eth)}'/${int31(eth >> 31n)}'/${index}`;
|
return `m/2645'/${layerNum}'/${applicationNum}'/${int31(eth)}'/${int31(eth >> 31n)}'/${index}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://docs.starkware.co/starkex/pedersen-hash-function.html
|
// https://docs.starkware.co/starkex/pedersen-hash-function.html
|
||||||
const PEDERSEN_POINTS_AFFINE = [
|
const PEDERSEN_POINTS = [
|
||||||
new ProjectivePoint(
|
new ProjectivePoint(
|
||||||
2089986280348253421170679821480865132823066470938446095505822317253594081284n,
|
2089986280348253421170679821480865132823066470938446095505822317253594081284n,
|
||||||
1713931329540660377023406109199410414810705867260802078187082345529207694986n,
|
1713931329540660377023406109199410414810705867260802078187082345529207694986n,
|
||||||
@ -205,8 +167,6 @@ const PEDERSEN_POINTS_AFFINE = [
|
|||||||
1n
|
1n
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
// for (const p of PEDERSEN_POINTS) p._setWindowSize(8);
|
|
||||||
const PEDERSEN_POINTS = PEDERSEN_POINTS_AFFINE;
|
|
||||||
|
|
||||||
function pedersenPrecompute(p1: ProjectivePoint, p2: ProjectivePoint): ProjectivePoint[] {
|
function pedersenPrecompute(p1: ProjectivePoint, p2: ProjectivePoint): ProjectivePoint[] {
|
||||||
const out: ProjectivePoint[] = [];
|
const out: ProjectivePoint[] = [];
|
||||||
@ -230,14 +190,16 @@ const PEDERSEN_POINTS2 = pedersenPrecompute(PEDERSEN_POINTS[3], PEDERSEN_POINTS[
|
|||||||
type PedersenArg = Hex | bigint | number;
|
type PedersenArg = Hex | bigint | number;
|
||||||
function pedersenArg(arg: PedersenArg): bigint {
|
function pedersenArg(arg: PedersenArg): bigint {
|
||||||
let value: bigint;
|
let value: bigint;
|
||||||
if (typeof arg === 'bigint') value = arg;
|
if (typeof arg === 'bigint') {
|
||||||
else if (typeof arg === 'number') {
|
value = arg;
|
||||||
|
} else if (typeof arg === 'number') {
|
||||||
if (!Number.isSafeInteger(arg)) throw new Error(`Invalid pedersenArg: ${arg}`);
|
if (!Number.isSafeInteger(arg)) throw new Error(`Invalid pedersenArg: ${arg}`);
|
||||||
value = BigInt(arg);
|
value = BigInt(arg);
|
||||||
} else value = bytesToNumber0x(ensureBytes0x(arg));
|
} else {
|
||||||
// [0..Fp)
|
value = bytesToNumberBE(ensureBytes(arg));
|
||||||
if (!(0n <= value && value < starkCurve.CURVE.Fp.ORDER))
|
}
|
||||||
throw new Error(`PedersenArg should be 0 <= value < CURVE.P: ${value}`);
|
if (!(0n <= value && value < curve.CURVE.Fp.ORDER))
|
||||||
|
throw new Error(`PedersenArg should be 0 <= value < CURVE.P: ${value}`); // [0..Fp)
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,17 +215,17 @@ function pedersenSingle(point: ProjectivePoint, value: PedersenArg, constants: P
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 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): string {
|
||||||
let point: ProjectivePoint = PEDERSEN_POINTS[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.toRawBytes(true).slice(1));
|
return extractX(point.toRawBytes(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hashChain(data: PedersenArg[], fn = pedersen) {
|
export function hashChain(data: PedersenArg[], fn = pedersen) {
|
||||||
if (!Array.isArray(data) || data.length < 1)
|
if (!Array.isArray(data) || data.length < 1)
|
||||||
throw new Error('data should be array of at least 1 element');
|
throw new Error('data should be array of at least 1 element');
|
||||||
if (data.length === 1) return numberToHexEth(pedersenArg(data[0]));
|
if (data.length === 1) return numberTo0x16(pedersenArg(data[0]));
|
||||||
return Array.from(data)
|
return Array.from(data)
|
||||||
.reverse()
|
.reverse()
|
||||||
.reduce((acc, i) => fn(i, acc));
|
.reduce((acc, i) => fn(i, acc));
|
||||||
@ -272,9 +234,9 @@ export function hashChain(data: PedersenArg[], fn = pedersen) {
|
|||||||
export const computeHashOnElements = (data: PedersenArg[], fn = pedersen) =>
|
export const computeHashOnElements = (data: PedersenArg[], fn = pedersen) =>
|
||||||
[0, ...data, data.length].reduce((x, y) => fn(x, y));
|
[0, ...data, data.length].reduce((x, y) => fn(x, y));
|
||||||
|
|
||||||
const MASK_250 = cutils.bitMask(250);
|
const MASK_250 = bitMask(250);
|
||||||
export const keccak = (data: Uint8Array): bigint => bytesToNumber0x(keccak_256(data)) & MASK_250;
|
export const keccak = (data: Uint8Array): bigint => bytesToNumberBE(keccak_256(data)) & MASK_250;
|
||||||
const sha256Num = (data: Uint8Array | string): bigint => cutils.bytesToNumberBE(sha256(data));
|
const sha256Num = (data: Uint8Array | string): bigint => bytesToNumberBE(sha256(data));
|
||||||
|
|
||||||
// Poseidon hash
|
// Poseidon hash
|
||||||
export const Fp253 = Fp(
|
export const Fp253 = Fp(
|
||||||
@ -330,7 +292,7 @@ export function poseidonBasic(opts: PoseidonOpts, mds: bigint[][]) {
|
|||||||
for (let j = 0; j < m; j++) row.push(poseidonRoundConstant(opts.Fp, 'Hades', m * i + j));
|
for (let j = 0; j < m; j++) row.push(poseidonRoundConstant(opts.Fp, 'Hades', m * i + j));
|
||||||
roundConstants.push(row);
|
roundConstants.push(row);
|
||||||
}
|
}
|
||||||
return poseidon.poseidon({
|
return poseidon({
|
||||||
...opts,
|
...opts,
|
||||||
t: m,
|
t: m,
|
||||||
sboxPower: 3,
|
sboxPower: 3,
|
||||||
|
@ -12,7 +12,7 @@ import { secp521r1 } from '../esm/p521.js';
|
|||||||
import { secp256k1 } from '../esm/secp256k1.js';
|
import { secp256k1 } from '../esm/secp256k1.js';
|
||||||
import { ed25519, ed25519ctx, ed25519ph, x25519 } from '../esm/ed25519.js';
|
import { ed25519, ed25519ctx, ed25519ph, x25519 } from '../esm/ed25519.js';
|
||||||
import { ed448, ed448ph } from '../esm/ed448.js';
|
import { ed448, ed448ph } from '../esm/ed448.js';
|
||||||
import { starkCurve } from '../esm/stark.js';
|
import { _starkCurve as starkCurve } from '../esm/stark.js';
|
||||||
import { pallas, vesta } from '../esm/pasta.js';
|
import { pallas, vesta } from '../esm/pasta.js';
|
||||||
import { bn254 } from '../esm/bn.js';
|
import { bn254 } from '../esm/bn.js';
|
||||||
import { jubjub } from '../esm/jubjub.js';
|
import { jubjub } from '../esm/jubjub.js';
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
|
import { describe, should } from 'micro-should';
|
||||||
import './basic.test.js';
|
import './basic.test.js';
|
||||||
import './stark.test.js';
|
import './stark.test.js';
|
||||||
import './property.test.js';
|
import './property.test.js';
|
||||||
import './poseidon.test.js';
|
import './poseidon.test.js';
|
||||||
|
|
||||||
|
// ESM is broken.
|
||||||
|
import url from 'url';
|
||||||
|
if (import.meta.url === url.pathToFileURL(process.argv[1]).href) {
|
||||||
|
should.run();
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user