Skip to content

Commit

Permalink
revert later: temporary field fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
mitschabaude committed May 15, 2023
1 parent a71fd2a commit 59e9894
Show file tree
Hide file tree
Showing 8 changed files with 30 additions and 28 deletions.
2 changes: 1 addition & 1 deletion src/lib/account_update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ const Body = {
if (tokenId) {
body.tokenId = tokenId;
body.mayUseToken = Provable.if(
tokenId.equals(TokenId.default),
Field(tokenId).equals(TokenId.default),
AccountUpdate.MayUseToken.type,
AccountUpdate.MayUseToken.No,
AccountUpdate.MayUseToken.ParentsOwnToken
Expand Down
2 changes: 1 addition & 1 deletion src/lib/circuit_value.ts
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ function circuitValueEquals<T>(a: T, b: T): boolean {
function toConstant<T>(type: FlexibleProvable<T>, value: T): T;
function toConstant<T>(type: Provable<T>, value: T): T {
return type.fromFields(
type.toFields(value).map((x) => x.toConstant()),
type.toFields(value).map((x) => Field(x).toConstant()),
type.toAuxiliary(value)
);
}
Expand Down
6 changes: 4 additions & 2 deletions src/lib/hash.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,15 @@ const Poseidon = {
let isChecked = !input.every((x) => x.isConstant());
// this is the same:
// return Poseidon_.update(this.initialState, input, isChecked)[0];
return Poseidon_.hash(input, isChecked);
return Field(Poseidon_.hash(input, isChecked));
},

hashToGroup(input: Field[]) {
let isChecked = !input.every((x) => x.isConstant());
// y = sqrt(y^2)
let { x, y } = Poseidon_.hashToGroup(input, isChecked);
x = Field(x);
y = Field(y);

let x0 = Provable.witness(Field, () => {
// the even root of y^2 will become x0, so the APIs are uniform
Expand All @@ -71,7 +73,7 @@ const Poseidon = {
let isChecked = !(
state.every((x) => x.isConstant()) && input.every((x) => x.isConstant())
);
return Poseidon_.update(state, input, isChecked);
return Poseidon_.update(state, input, isChecked).map(Field);
},

initialState(): [Field, Field, Field] {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/merkle_tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ function maybeSwapBad(b: Bool, x: Field, y: Field): [Field, Field] {

// more efficient version of `maybeSwapBad` which reuses an intermediate variable
function maybeSwap(b: Bool, x: Field, y: Field): [Field, Field] {
let m = b.toField().mul(x.sub(y)); // b*(x - y)
let m = Field(b.toField()).mul(x.sub(y)); // b*(x - y)
const x_ = y.add(m); // y + b*(x - y)
const y_ = x.sub(m); // x - b*(x - y) = x + b*(y - x)
return [x_, y_];
Expand Down
11 changes: 4 additions & 7 deletions src/lib/primitives.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,12 @@ describe('bool', () => {

describe('inside circuit', () => {
describe('toField', () => {
it('should return a Field', async () => {
expect(true).toEqual(true);
});
it('should convert false to Field element 0', () => {
expect(() => {
Circuit.runAndCheck(() => {
const xFalse = Circuit.witness(Bool, () => new Bool(false));

xFalse.toField().assertEquals(new Field(0));
Field(xFalse.toField()).assertEquals(new Field(0));
});
}).not.toThrow();
});
Expand All @@ -38,7 +35,7 @@ describe('bool', () => {
expect(() => {
Circuit.runAndCheck(() => {
const xTrue = Circuit.witness(Bool, () => new Bool(true));
xTrue.toField().assertEquals(new Field(1));
Field(xTrue.toField()).assertEquals(new Field(1));
});
}).not.toThrow();
});
Expand All @@ -58,7 +55,7 @@ describe('bool', () => {
expect(() => {
Circuit.runAndCheck(() => {
const x = Circuit.witness(Bool, () => new Bool(false));
const fieldArr = x.toFields();
const fieldArr = x.toFields().map(Field);
const isArr = Array.isArray(fieldArr);
expect(isArr).toBe(true);
fieldArr[0].assertEquals(new Field(0));
Expand Down Expand Up @@ -139,7 +136,7 @@ describe('bool', () => {
expect(() => {
Circuit.runAndCheck(() => {
const xTrue = Circuit.witness(Bool, () => new Bool(true));
xTrue.toField().assertEquals(new Field(1));
Field(xTrue.toField()).assertEquals(new Field(1));
});
}).not.toThrow();
});
Expand Down
12 changes: 6 additions & 6 deletions src/lib/provable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ function witness<T, S extends FlexibleProvable<T> = FlexibleProvable<T>>(
let [, ...fieldVars] = Snarky.exists(type.sizeInFields(), () => {
proverValue = compute();
let fields = type.toFields(proverValue);
let fieldConstants = fields.map((x) => x.toConstant().value[1]);
let fieldConstants = fields.map((x) => Field(x).toConstant().value[1]);

// TODO: enable this check
// currently it throws for Scalar.. which seems to be flexible about what length is returned by toFields
Expand Down Expand Up @@ -243,14 +243,14 @@ function assertEqualImplicit<T extends ToFieldable>(x: T, y: T) {
let ys = y.toFields();
let n = checkLength('Provable.assertEqual', xs, ys);
for (let i = 0; i < n; i++) {
xs[i].assertEquals(ys[i]);
Field(xs[i]).assertEquals(ys[i]);
}
}
function assertEqualExplicit<T>(type: Provable<T>, x: T, y: T) {
let xs = type.toFields(x);
let ys = type.toFields(y);
for (let i = 0; i < xs.length; i++) {
xs[i].assertEquals(ys[i]);
Field(xs[i]).assertEquals(ys[i]);
}
}

Expand All @@ -270,12 +270,12 @@ function equalImplicit<T extends ToFieldable>(x: T, y: T) {
let xs = x.toFields();
let ys = y.toFields();
checkLength('Provable.equal', xs, ys);
return xs.map((x, i) => x.equals(ys[i])).reduce(Bool.and);
return xs.map((x, i) => Field(x).equals(ys[i])).reduce(Bool.and);
}
function equalExplicit<T>(type: Provable<T>, x: T, y: T) {
let xs = type.toFields(x);
let ys = type.toFields(y);
return xs.map((x, i) => x.equals(ys[i])).reduce(Bool.and);
return xs.map((x, i) => Field(x).equals(ys[i])).reduce(Bool.and);
}

function if_<T>(condition: Bool, type: FlexibleProvable<T>, x: T, y: T): T;
Expand All @@ -294,7 +294,7 @@ function ifField(b: Field, x: Field, y: Field) {
// leads to a different but equivalent layout (same # constraints)
// https://github.com/o1-labs/snarky/blob/14f8e2ff981a9c9ea48c94b2cc1d8c161301537b/src/base/utils.ml#L171
// in the case x, y are constant, the layout is the same
return b.mul(x.sub(y)).add(y).seal();
return Field(b).mul(Field(x).sub(y)).add(y).seal();
}

function ifExplicit<T>(condition: Bool, type: Provable<T>, x: T, y: T): T {
Expand Down
19 changes: 11 additions & 8 deletions src/lib/signature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,12 @@ class PublicKey extends CircuitValue {
// compute y from elliptic curve equation y^2 = x^3 + 5
// TODO: we have to improve constraint efficiency by using range checks
let { x, isOdd } = this;
let ySquared = x.mul(x).mul(x).add(5);
let ySquared = Field(x).mul(x).mul(x).add(5);
let someY = ySquared.sqrt();
let isTheRightY = isOdd.equals(someY.toBits()[0]);
let y = isTheRightY
.toField()
let y = Field(isTheRightY.toField())
.mul(someY)
.add(isTheRightY.not().toField().mul(someY.neg()));
.add(Field(isTheRightY.not().toField()).mul(someY.neg()));
return new Group(x, y);
}

Expand All @@ -109,7 +108,7 @@ class PublicKey extends CircuitValue {
* @returns a {@link PublicKey}.
*/
static fromGroup({ x, y }: Group): PublicKey {
let isOdd = y.toBits()[0];
let isOdd = Field(y).toBits()[0];
return PublicKey.fromObject({ x, isOdd });
}

Expand Down Expand Up @@ -143,7 +142,7 @@ class PublicKey extends CircuitValue {
*/
isEmpty() {
// there are no curve points with x === 0
return this.x.isZero();
return Field(this.x).isZero();
}

/**
Expand All @@ -152,6 +151,7 @@ class PublicKey extends CircuitValue {
*/
static fromBase58(publicKeyBase58: string) {
let pk = Ledger.publicKeyOfString(publicKeyBase58);
pk.x = Field(pk.x);
return PublicKey.from(pk);
}
/**
Expand Down Expand Up @@ -208,7 +208,7 @@ class Signature extends CircuitValue {
)
);
let { x: r, y: ry } = Group.generator.scale(kPrime);
const k = ry.toBits()[0].toBoolean() ? kPrime.neg() : kPrime;
const k = Field(ry).toBits()[0].toBoolean() ? kPrime.neg() : kPrime;
let h = hashWithPrefix(
prefixes.signatureTestnet,
msg.concat([publicKey.x, publicKey.y, r])
Expand All @@ -234,7 +234,10 @@ class Signature extends CircuitValue {
// therefore we have to use scaleShifted which is very inefficient
let e = Scalar.fromBits(h.toBits());
let r = scaleShifted(point, e).neg().add(Group.generator.scale(this.s));
return Bool.and(r.x.equals(this.r), r.y.toBits()[0].equals(false));
return Bool.and(
Field(r.x).equals(this.r),
Field(r.y).toBits()[0].equals(false)
);
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/lib/zkapp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -496,8 +496,8 @@ function checkPublicInput(
self: AccountUpdate
) {
let otherInput = self.toPublicInput();
accountUpdate.assertEquals(otherInput.accountUpdate);
calls.assertEquals(otherInput.calls);
Field(accountUpdate).assertEquals(otherInput.accountUpdate);
Field(calls).assertEquals(otherInput.calls);
}

/**
Expand Down

0 comments on commit 59e9894

Please sign in to comment.