Skip to content

Commit

Permalink
standardise fromTuple interfaces across fields
Browse files Browse the repository at this point in the history
  • Loading branch information
kevincharm committed Jul 21, 2024
1 parent eadd5be commit b7ee7a2
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 204 deletions.
66 changes: 33 additions & 33 deletions src/ff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,57 +78,53 @@ export interface Field {
}

export class Fq implements Field {
x: bigint
value: bigint

constructor(x: bigint) {
this.x = mod(x, P)
}

static fromTuple([x]: bigint[]): Fq {
return new Fq(x)
this.value = mod(x, P)
}

static zero(): Fq {
return new Fq(0n)
}

equals(rhs: Fq): boolean {
return this.x === rhs.x
return this.value === rhs.value
}

lt(rhs: Fq): boolean {
return this.x < rhs.x
return this.value < rhs.value
}

add(rhs: Fq): Fq {
return new Fq(this.x + rhs.x)
return new Fq(this.value + rhs.value)
}

sub(rhs: Fq): Fq {
return new Fq(this.x - rhs.x)
return new Fq(this.value - rhs.value)
}

neg(): Fq {
return new Fq(-this.x)
return new Fq(-this.value)
}

mul(rhs: Fq): Fq {
return new Fq(this.x * rhs.x)
return new Fq(this.value * rhs.value)
}

mulByScalar(c: bigint): Fq {
return new Fq(this.x * c)
return new Fq(this.value * c)
}

mulByNonResidue(): Fq {
return this
}

inv() {
if (this.x === 0n) {
if (this.value === 0n) {
throw new Error(`Inversion of zero`)
}
return new Fq(gcd(this.x, P, 1n, 0n, P))
return new Fq(gcd(this.value, P, 1n, 0n, P))
}

exp(y: bigint): Fq {
Expand Down Expand Up @@ -170,12 +166,12 @@ export class Fq implements Field {
}

toString() {
return `(Fq ${this.x.toString()})`
return `(Fq ${this.value.toString()})`
}

toJSON() {
return {
x: this.x.toString(),
x: this.value.toString(),
}
}
}
Expand Down Expand Up @@ -220,11 +216,11 @@ export class Fq2 implements Field {
}

gt(rhs: Fq2): boolean {
return this.x.x > rhs.x.x && this.y.x > rhs.y.x
return this.x.value > rhs.x.value && this.y.value > rhs.y.value
}

lt(rhs: Fq2): boolean {
return this.x.x < rhs.x.x && this.y.x < rhs.y.x
return this.x.value < rhs.x.value && this.y.value < rhs.y.value
}

add(rhs: Fq2): Fq2 {
Expand Down Expand Up @@ -320,10 +316,12 @@ export class Fq2 implements Field {
}

toTuple(): [bigint, bigint] {
return [this.x.x, this.y.x]
return [this.x.value, this.y.value]
}
}

type Fq2Tuple = ReturnType<Fq2['toTuple']>

/// Cubic extension to Fq2
export class Fq6 implements Field {
x: Fq2
Expand All @@ -335,20 +333,20 @@ export class Fq6 implements Field {
this.z = z
}

static fromTuple([x, y, z]: [Fq2, Fq2, Fq2]): Fq6 {
return new Fq6(x, y, z)
static fromTuple([x, y, z]: [Fq2Tuple, Fq2Tuple, Fq2Tuple]): Fq6 {
return new Fq6(Fq2.fromTuple(x), Fq2.fromTuple(y), Fq2.fromTuple(z))
}

static fromNumber(n: bigint): Fq6 {
return Fq6.fromTuple([Fq2.fromNumber(n), Fq2.zero(), Fq2.zero()])
return new Fq6(Fq2.fromNumber(n), Fq2.zero(), Fq2.zero())
}

static zero(): Fq6 {
return Fq6.fromTuple([Fq2.zero(), Fq2.zero(), Fq2.zero()])
return new Fq6(Fq2.zero(), Fq2.zero(), Fq2.zero())
}

static one(): Fq6 {
return Fq6.fromTuple([Fq2.one(), Fq2.zero(), Fq2.zero()])
return new Fq6(Fq2.one(), Fq2.zero(), Fq2.zero())
}

equals(rhs: Fq6): boolean {
Expand Down Expand Up @@ -397,7 +395,7 @@ export class Fq6 implements Field {
}

mulByNonResidue(): Fq6 {
return Fq6.fromTuple([this.z.mulByNonResidue(), this.x, this.y])
return new Fq6(this.z.mulByNonResidue(), this.x, this.y)
}

inv(): Fq6 {
Expand All @@ -412,7 +410,7 @@ export class Fq6 implements Field {
.add(a2.mul(t1).mulByNonResidue())
.add(a1.mul(t2).mulByNonResidue())
.inv()
return Fq6.fromTuple([t0.mul(factor), t1.mul(factor), t2.mul(factor)])
return new Fq6(t0.mul(factor), t1.mul(factor), t2.mul(factor))
}

toString() {
Expand All @@ -436,6 +434,8 @@ export class Fq6 implements Field {
}
}

type Fq6Tuple = ReturnType<Fq6['toTuple']>

/// 12th degree extension to Fq
export class Fq12 implements Field {
x: Fq6
Expand All @@ -445,20 +445,20 @@ export class Fq12 implements Field {
this.y = y
}

static fromTuple([x, y]: [Fq6, Fq6]): Fq12 {
return new Fq12(x, y)
static fromTuple([x, y]: [Fq6Tuple, Fq6Tuple]): Fq12 {
return new Fq12(Fq6.fromTuple(x), Fq6.fromTuple(y))
}

static fromNumber(n: bigint): Fq12 {
return Fq12.fromTuple([Fq6.fromNumber(n), Fq6.zero()])
return new Fq12(Fq6.fromNumber(n), Fq6.zero())
}

static zero(): Fq12 {
return Fq12.fromTuple([Fq6.zero(), Fq6.zero()])
return new Fq12(Fq6.zero(), Fq6.zero())
}

static one(): Fq12 {
return Fq12.fromTuple([Fq6.one(), Fq6.zero()])
return new Fq12(Fq6.one(), Fq6.zero())
}

equals(rhs: Fq12): boolean {
Expand Down Expand Up @@ -517,7 +517,7 @@ export class Fq12 implements Field {
}
}

toTuple(): [ReturnType<Fq6['toTuple']>, ReturnType<Fq6['toTuple']>] {
toTuple(): [Fq6Tuple, Fq6Tuple] {
return [this.x.toTuple(), this.y.toTuple()]
}
}
6 changes: 3 additions & 3 deletions src/pairing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,17 @@ function lineDouble(r: PointG2, p: PointG1): Fq12 {
.mul(Fq12.fromNumber(3n))
.mul(wideR.y.mul(Fq12.fromNumber(2n)).inv())
const v = wideR.y.sub(slope.mul(wideR.x))
return Fq12.fromNumber(p.y.x).sub(Fq12.fromNumber(p.x.x).mul(slope)).sub(v)
return Fq12.fromNumber(p.y.value).sub(Fq12.fromNumber(p.x.value).mul(slope)).sub(v)
}

function lineAdd(r: PointG2, q: PointG2, p: PointG1): Fq12 {
const wideR = r.untwist()
const wideQ = q.untwist()
if (wideR.x.equals(wideQ.x) && wideR.y.equals(wideQ.y.neg())) {
return Fq12.fromNumber(p.x.x).sub(wideR.x)
return Fq12.fromNumber(p.x.value).sub(wideR.x)
} else {
const slope = wideQ.y.sub(wideR.y).mul(wideQ.x.sub(wideR.x).inv())
const v = wideQ.y.mul(wideR.x).sub(wideR.y.mul(wideQ.x)).mul(wideR.x.sub(wideQ.x).inv())
return Fq12.fromNumber(p.y.x).sub(Fq12.fromNumber(p.x.x).mul(slope)).sub(v)
return Fq12.fromNumber(p.y.value).sub(Fq12.fromNumber(p.x.value).mul(slope)).sub(v)
}
}
10 changes: 5 additions & 5 deletions src/point.ts
Original file line number Diff line number Diff line change
Expand Up @@ -323,14 +323,14 @@ export class PointG2 implements PointInstanceType<Fq2> {
untwist(): PointGT {
const x1 = this.x
const y1 = this.y
const root = Fq6.fromTuple([Fq2.zero(), Fq2.one(), Fq2.zero()])
const root = new Fq6(Fq2.zero(), Fq2.one(), Fq2.zero())
// wideX = [ Fq12 (Fq6 x1 0 0) 0 ] * inv (Fq12 root 0)
const wideX = Fq12.fromTuple([Fq6.fromTuple([x1, Fq2.zero(), Fq2.zero()]), Fq6.zero()]).mul(
Fq12.fromTuple([root, Fq6.zero()]).inv(),
const wideX = new Fq12(new Fq6(x1, Fq2.zero(), Fq2.zero()), Fq6.zero()).mul(
new Fq12(root, Fq6.zero()).inv(),
)
// wideY = [ Fq12 (Fq6 y1 0 0) 0 ] * inv (Fq12 0 root)
const wideY = Fq12.fromTuple([Fq6.fromTuple([y1, Fq2.zero(), Fq2.zero()]), Fq6.zero()]).mul(
Fq12.fromTuple([Fq6.zero(), root]).inv(),
const wideY = new Fq12(new Fq6(y1, Fq2.zero(), Fq2.zero()), Fq6.zero()).mul(
new Fq12(Fq6.zero(), root).inv(),
)
return new PointGT(wideX, wideY)
}
Expand Down
4 changes: 2 additions & 2 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Fq, Fq12, Fq2, Fq6, P } from './ff'

export function randomFq12(): Fq12 {
return Fq12.fromTuple([randomFq6(), randomFq6()])
return new Fq12(randomFq6(), randomFq6())
}

export function randomFq6(): Fq6 {
return Fq6.fromTuple([randomFq2(), randomFq2(), randomFq2()])
return new Fq6(randomFq2(), randomFq2(), randomFq2())
}

export function randomFq2(): Fq2 {
Expand Down
4 changes: 2 additions & 2 deletions test/bls.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ describe('BLS', () => {

it('hashToPoint', () => {
const p = hashToPoint(dst, messageBytes)
expect(p.x.x).to.eq(
expect(p.x.value).to.eq(
1198910066326735622577680242831393390970801051978648777282080468606313680859600948581997698323043835646099437524846n,
)
expect(p.y.x).to.eq(
expect(p.y.value).to.eq(
2057868841575584746120388979277317449872305248232397789541047611599466400564636994006407901750858857388914134998050n,
)
})
Expand Down
Loading

0 comments on commit b7ee7a2

Please sign in to comment.