Skip to content

Commit

Permalink
import foreign files from lambda repo
Browse files Browse the repository at this point in the history
  • Loading branch information
mohammed7s committed Nov 11, 2023
1 parent 81dec02 commit 982e9af
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 1 deletion.
1 change: 0 additions & 1 deletion src/Verifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,4 @@ export class Verifier extends SmartContract {
}



}
3 changes: 3 additions & 0 deletions src/foreign_field.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { Field, createForeignField } from "o1js";

Check failure on line 1 in src/foreign_field.ts

View workflow job for this annotation

GitHub Actions / test

Module '"o1js"' has no exported member 'createForeignField'.

export class ForeignField extends createForeignField(Field.ORDER) { }
135 changes: 135 additions & 0 deletions src/foreign_group.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { Bool, Field, Provable } from "o1js";
import { ForeignField } from "./foreign_field.js";
import { ForeignScalar } from "./foreign_scalar.js";

export class ForeignGroup {
x: ForeignField;
y: ForeignField;

constructor(x: ForeignField, y: ForeignField) {
this.x = x;
this.y = y;
}

static zero() {
return new ForeignGroup(ForeignField.from(0), ForeignField.from(0));

Check failure on line 15 in src/foreign_group.ts

View workflow job for this annotation

GitHub Actions / test

Property 'from' does not exist on type 'typeof ForeignField'.

Check failure on line 15 in src/foreign_group.ts

View workflow job for this annotation

GitHub Actions / test

Property 'from' does not exist on type 'typeof ForeignField'.
}

isZero() {
// only the zero element can have x = 0, there are no other (valid) group elements with x = 0
return this.x.equals(ForeignField.from(0));

Check failure on line 20 in src/foreign_group.ts

View workflow job for this annotation

GitHub Actions / test

Property 'equals' does not exist on type 'ForeignField'.

Check failure on line 20 in src/foreign_group.ts

View workflow job for this annotation

GitHub Actions / test

Property 'from' does not exist on type 'typeof ForeignField'.
}

assertEquals(g: ForeignGroup, message?: string) {
let { x: x1, y: y1 } = this;
let { x: x2, y: y2 } = g;

x1.assertEquals(x2, message);

Check failure on line 27 in src/foreign_group.ts

View workflow job for this annotation

GitHub Actions / test

Property 'assertEquals' does not exist on type 'ForeignField'.
y1.assertEquals(y2, message);

Check failure on line 28 in src/foreign_group.ts

View workflow job for this annotation

GitHub Actions / test

Property 'assertEquals' does not exist on type 'ForeignField'.
}

equals(g: ForeignGroup) {
let { x: x1, y: y1 } = this;
let { x: x2, y: y2 } = g;

let x_are_equal = x1.equals(x2);

Check failure on line 35 in src/foreign_group.ts

View workflow job for this annotation

GitHub Actions / test

Property 'equals' does not exist on type 'ForeignField'.
let y_are_equal = y1.equals(y2);

Check failure on line 36 in src/foreign_group.ts

View workflow job for this annotation

GitHub Actions / test

Property 'equals' does not exist on type 'ForeignField'.

return x_are_equal.and(y_are_equal);
}

add(g: ForeignGroup) {
// TODO: Make provable and use foreign EC constraints

const { x: x1, y: y1 } = this;
const { x: x2, y: y2 } = g;

let inf = Provable.witness(Bool, () =>
x1.equals(x2).and(y1.equals(y2).not())

Check failure on line 48 in src/foreign_group.ts

View workflow job for this annotation

GitHub Actions / test

Property 'equals' does not exist on type 'ForeignField'.
);

let s = Provable.witness(ForeignField, () => {
if (x1.equals(x2).toBoolean()) {
let x1_squared = x1.mul(x1);
return x1_squared.add(x1_squared).add(x1_squared).mul(y1.add(y1).inv());
} else return y2.sub(y1).mul(x2.sub(x1).inv());
});

let x3 = Provable.witness(ForeignField, () => {
return s.mul(s).sub(x1.add(x2));
});

let y3 = Provable.witness(ForeignField, () => {
return s.mul(x1.sub(x3)).sub(y1);
});

// similarly to the constant implementation, we check if either operand is zero
// and the implementation above (original OCaml implementation) returns something wild -> g + 0 != g where it should be g + 0 = g
let gIsZero = g.isZero();
let thisIsZero = this.isZero();

let bothZero = gIsZero.and(thisIsZero);

let onlyGisZero = gIsZero.and(thisIsZero.not());
let onlyThisIsZero = thisIsZero.and(gIsZero.not());

let isNegation = inf;

let isNewElement = bothZero
.not()
.and(isNegation.not())
.and(onlyThisIsZero.not())
.and(onlyGisZero.not());

const zero_g = ForeignGroup.zero();

return Provable.switch(
[bothZero, onlyGisZero, onlyThisIsZero, isNegation, isNewElement],
ForeignGroup,
[zero_g, this, g, zero_g, new ForeignGroup(x3, y3)]
);
}

static sizeInFields() {
return ForeignField.sizeInFields() * 2;
}

static fromFields(fields: Field[]) {
let x = fields.slice(0, 3);
let y = fields.slice(3);

return new ForeignGroup(ForeignField.fromFields(x), ForeignField.fromFields(y));
}

toFields() {
return [...this.x.toFields(), ...this.y.toFields()];
}

static toFields(g: ForeignGroup) {
return g.toFields();
}

static toAuxiliary() {
return [];
}

static check(g: ForeignGroup) {
try {
const a = 0n;
const b = 5n;
const { x, y } = g;

let x2 = x.mul(x);
let x3 = x2.mul(x);
let ax = x.mul(a); // this will obviously be 0, but just for the sake of correctness

// we also check the zero element (0, 0) here
let isZero = x.equals(0).and(y.equals(0));

isZero.or(x3.add(ax).add(b).equals(y.mul(y))).assertTrue();
} catch (error) {
if (!(error instanceof Error)) return error;
throw `${`Element (x: ${g.x}, y: ${g.y}) is not an element of the group.`}\n${error.message}`;
}
}
}
3 changes: 3 additions & 0 deletions src/foreign_scalar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { Scalar, createForeignField } from "o1js";

export class ForeignScalar extends createForeignField(Scalar.ORDER) { }

0 comments on commit 982e9af

Please sign in to comment.