Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 0 additions & 31 deletions .pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions .yarn/cache/@types-bn.js-npm-5.1.0-4a0335ff4f-04c6705445.zip

This file was deleted.

3 changes: 0 additions & 3 deletions .yarn/cache/bn.js-npm-5.2.0-11748c0b07-67e17b1934.zip

This file was deleted.

2 changes: 0 additions & 2 deletions packages/crypto/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,10 @@
"@cosmjs/utils": "workspace:^",
"@noble/curves": "^1.9.2",
"@noble/hashes": "^1",
"bn.js": "^5.2.0",
"libsodium-wrappers-sumo": "^0.7.11"
},
"devDependencies": {
"@istanbuljs/nyc-config-typescript": "^1.0.1",
"@types/bn.js": "^5",
"@types/jasmine": "^4",
"@types/karma-firefox-launcher": "^2",
"@types/karma-jasmine": "^4",
Expand Down
25 changes: 16 additions & 9 deletions packages/crypto/src/slip10.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { toAscii, toHex } from "@cosmjs/encoding";
import { fromHex, toAscii, toHex } from "@cosmjs/encoding";
import { Uint32, Uint53 } from "@cosmjs/math";
import { assert } from "@cosmjs/utils";
import { secp256k1 } from "@noble/curves/secp256k1";
// eslint-disable-next-line @typescript-eslint/naming-convention
import BN from "bn.js";

import { Hmac } from "./hmac";
import { Sha512 } from "./sha";
Expand All @@ -26,6 +25,14 @@ function bytesToUnsignedBigInt(a: Uint8Array): bigint {
return BigInt("0x" + toHex(a));
}

function intTo32be(n: bigint): Uint8Array {
assert(n >= 0n);
assert(n < 2n ** (32n * 8n));
// 32 bytes is 64 hexadecimal characters
const hex = n.toString(16).padStart(64, "0");
return fromHex(hex);
}

/**
* Reverse mapping of Slip10Curve
*/
Expand Down Expand Up @@ -175,8 +182,8 @@ export class Slip10 {

// step 5
const n = this.n(curve);
const returnChildKeyAsNumber = new BN(il).add(new BN(parentPrivkey)).mod(n);
const returnChildKey = Uint8Array.from(returnChildKeyAsNumber.toArray("be", 32));
const returnChildKeyAsNumber = (bytesToUnsignedBigInt(il) + bytesToUnsignedBigInt(parentPrivkey)) % n;
const returnChildKey = intTo32be(returnChildKeyAsNumber);

// step 6
if (this.isGteN(curve, il) || this.isZero(returnChildKey)) {
Expand All @@ -198,14 +205,14 @@ export class Slip10 {
}

private static isGteN(curve: Slip10Curve, privkey: Uint8Array): boolean {
const keyAsNumber = new BN(privkey);
return keyAsNumber.gte(this.n(curve));
const keyAsNumber = bytesToUnsignedBigInt(privkey);
return keyAsNumber >= this.n(curve);
}

private static n(curve: Slip10Curve): BN {
private static n(curve: Slip10Curve): bigint {
switch (curve) {
case Slip10Curve.Secp256k1:
return new BN("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16);
return 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141n;
default:
throw new Error("curve not supported");
}
Expand Down
4 changes: 0 additions & 4 deletions packages/math/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,8 @@
"build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build",
"pack-web": "yarn build-or-skip && webpack --mode development --config webpack.web.config.js"
},
"dependencies": {
"bn.js": "^5.2.0"
},
"devDependencies": {
"@istanbuljs/nyc-config-typescript": "^1.0.1",
"@types/bn.js": "^5",
"@types/jasmine": "^4",
"@types/karma-firefox-launcher": "^2",
"@types/karma-jasmine": "^4",
Expand Down
48 changes: 24 additions & 24 deletions packages/math/src/decimal.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
// eslint-disable-next-line @typescript-eslint/naming-convention
import BN from "bn.js";

import { Uint32, Uint53, Uint64 } from "./integers";

// Too large values lead to massive memory usage. Limit to something sensible.
Expand Down Expand Up @@ -94,7 +91,10 @@ export class Decimal {

public static compare(a: Decimal, b: Decimal): number {
if (a.fractionalDigits !== b.fractionalDigits) throw new Error("Fractional digits do not match");
return a.data.atomics.cmp(new BN(b.atomics));
const difference = a.data.atomics - b.data.atomics;
if (difference < 0n) return -1;
if (difference > 0n) return 1;
return 0;
}

public get atomics(): string {
Expand All @@ -106,7 +106,7 @@ export class Decimal {
}

private readonly data: {
readonly atomics: BN;
readonly atomics: bigint;
readonly fractionalDigits: number;
};

Expand All @@ -118,7 +118,7 @@ export class Decimal {
}

this.data = {
atomics: new BN(atomics),
atomics: BigInt(atomics),
fractionalDigits: fractionalDigits,
};
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Slightly out of scope, but we can now also change the constuctor argument to atomics: string | bigint for more efficientcy in a few places.

Expand All @@ -130,36 +130,36 @@ export class Decimal {

/** Returns the greatest decimal <= this which has no fractional part (rounding down) */
public floor(): Decimal {
const factor = new BN(10).pow(new BN(this.data.fractionalDigits));
const whole = this.data.atomics.div(factor);
const fractional = this.data.atomics.mod(factor);
const factor = 10n ** BigInt(this.data.fractionalDigits);
const whole = this.data.atomics / factor;
const fractional = this.data.atomics % factor;

if (fractional.isZero()) {
if (fractional === 0n) {
return this.clone();
} else {
return Decimal.fromAtomics(whole.mul(factor).toString(), this.fractionalDigits);
return Decimal.fromAtomics((whole * factor).toString(), this.fractionalDigits);
}
}

/** Returns the smallest decimal >= this which has no fractional part (rounding up) */
public ceil(): Decimal {
const factor = new BN(10).pow(new BN(this.data.fractionalDigits));
const whole = this.data.atomics.div(factor);
const fractional = this.data.atomics.mod(factor);
const factor = 10n ** BigInt(this.data.fractionalDigits);
const whole = this.data.atomics / factor;
const fractional = this.data.atomics % factor;

if (fractional.isZero()) {
if (fractional === 0n) {
return this.clone();
} else {
return Decimal.fromAtomics(whole.addn(1).mul(factor).toString(), this.fractionalDigits);
return Decimal.fromAtomics(((whole + 1n) * factor).toString(), this.fractionalDigits);
}
}

public toString(): string {
const factor = new BN(10).pow(new BN(this.data.fractionalDigits));
const whole = this.data.atomics.div(factor);
const fractional = this.data.atomics.mod(factor);
const factor = 10n ** BigInt(this.data.fractionalDigits);
const whole = this.data.atomics / factor;
const fractional = this.data.atomics % factor;

if (fractional.isZero()) {
if (fractional === 0n) {
return whole.toString();
} else {
const fullFractionalPart = fractional.toString().padStart(this.data.fractionalDigits, "0");
Expand All @@ -185,7 +185,7 @@ export class Decimal {
*/
public plus(b: Decimal): Decimal {
if (this.fractionalDigits !== b.fractionalDigits) throw new Error("Fractional digits do not match");
const sum = this.data.atomics.add(new BN(b.atomics));
const sum = this.data.atomics + b.data.atomics;
return new Decimal(sum.toString(), this.fractionalDigits);
}

Expand All @@ -197,8 +197,8 @@ export class Decimal {
*/
public minus(b: Decimal): Decimal {
if (this.fractionalDigits !== b.fractionalDigits) throw new Error("Fractional digits do not match");
const difference = this.data.atomics.sub(new BN(b.atomics));
if (difference.ltn(0)) throw new Error("Difference must not be negative");
const difference = this.data.atomics - b.data.atomics;
if (difference < 0n) throw new Error("Difference must not be negative");
return new Decimal(difference.toString(), this.fractionalDigits);
}

Expand All @@ -208,7 +208,7 @@ export class Decimal {
* We only allow multiplication by unsigned integers to avoid rounding errors.
*/
public multiply(b: Uint32 | Uint53 | Uint64): Decimal {
const product = this.data.atomics.mul(new BN(b.toString()));
const product = this.data.atomics * b.toBigInt();
return new Decimal(product.toString(), this.fractionalDigits);
}

Expand Down
Loading
Loading