Skip to content

Commit

Permalink
Merge branch 'main' into fix/pickles-custom-gate-soundness
Browse files Browse the repository at this point in the history
  • Loading branch information
mitschabaude committed Mar 5, 2024
2 parents b0748da + fcf3080 commit 550408b
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 14 deletions.
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ jobs:
- name: Check if it's an even week
run: |
WEEK_NUM=$(date +'%V')
WEEK_NUM=$((10#$WEEK_NUM))
if [ $((WEEK_NUM % 2)) -ne 0 ]; then
echo "Odd week number ($WEEK_NUM), terminating job."
exit 1
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
### Fixed

- Mitigate security hazard of deploying token contracts https://github.com/o1-labs/o1js/issues/1439
- Make `Circuit` handle types with a `.provable` property (like those used in ECDSA) https://github.com/o1-labs/o1js/pull/1471
- To support offchain, non-Pickles proofs of ECDSA signatures

## [0.16.1](https://github.com/o1-labs/o1js/compare/834a44002...3b5f7c7)

Expand Down
2 changes: 2 additions & 0 deletions README-dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ o1js is a TypeScript framework designed for zk-SNARKs and zkApps on the Mina blo

For more information on our development process and how to contribute, see [CONTRIBUTING.md](https://github.com/o1-labs/o1js/blob/main/CONTRIBUTING.md). This document is meant to guide you through building o1js from source and understanding the development workflow.

It is a manual step to build the [o1js Reference docs](https://docs.minaprotocol.com/zkapps/o1js-reference). See [o1js Reference](https://github.com/o1-labs/docs2/wiki/o1js-Reference) in the docs wiki style guide.

## Prerequisites

Before starting, ensure you have the following tools installed:
Expand Down
45 changes: 45 additions & 0 deletions src/examples/circuit/ecdsa.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {
Circuit,
circuitMain,
public_,
Crypto,
createEcdsa,
createForeignCurve,
Bytes,
assert,
} from 'o1js';

export { Secp256k1, Ecdsa, Bytes32, Reserves };

class Secp256k1 extends createForeignCurve(Crypto.CurveParams.Secp256k1) {}
class Ecdsa extends createEcdsa(Secp256k1) {}
class Bytes32 extends Bytes(32) {}

class Reserves extends Circuit {
@circuitMain
static main(
@public_ message: Bytes32,
signature: Ecdsa,
publicKey: Secp256k1
) {
assert(signature.verify(message, publicKey));
}
}

console.time('generateKeypair');
let kp = await Reserves.generateKeypair();
console.timeEnd('generateKeypair');

let message = Bytes32.random();
let privateKey = Secp256k1.Scalar.random();
let publicKey = Secp256k1.generator.scale(privateKey);
let signature = Ecdsa.sign(message.toBytes(), privateKey.toBigInt());

console.time('prove');
let proof = await Reserves.prove([signature, publicKey], [message], kp);
console.timeEnd('prove');

console.time('verify');
let isValid = await Reserves.verify([message], kp.verificationKey(), proof);
assert(isValid, 'verifies');
console.timeEnd('verify');
21 changes: 14 additions & 7 deletions src/lib/circuit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,20 +266,27 @@ function circuitMain(
};
}

type ProvableInputPure<T> = ProvablePure<T> | { provable: ProvablePure<T> };

// TODO support auxiliary data
function provableFromTuple(typs: ProvablePure<any>[]): ProvablePure<any> {
function provableFromTuple(
inputTypes: ProvableInputPure<any>[]
): ProvablePure<any> {
let types = inputTypes.map((t) => ('provable' in t ? t.provable : t));
return {
sizeInFields: () => {
return typs.reduce((acc, typ) => acc + typ.sizeInFields(), 0);
return types.reduce((acc, type) => acc + type.sizeInFields(), 0);
},

toFields: (t: Array<any>) => {
if (t.length !== typs.length) {
throw new Error(`typOfArray: Expected ${typs.length}, got ${t.length}`);
if (t.length !== types.length) {
throw new Error(
`typOfArray: Expected ${types.length}, got ${t.length}`
);
}
let res = [];
for (let i = 0; i < t.length; ++i) {
res.push(...typs[i].toFields(t[i]));
res.push(...types[i].toFields(t[i]));
}
return res;
},
Expand All @@ -291,7 +298,7 @@ function provableFromTuple(typs: ProvablePure<any>[]): ProvablePure<any> {
fromFields: (xs: Array<any>) => {
let offset = 0;
let res: Array<any> = [];
typs.forEach((typ) => {
types.forEach((typ) => {
const n = typ.sizeInFields();
res.push(typ.fromFields(xs.slice(offset, offset + n)));
offset += n;
Expand All @@ -300,7 +307,7 @@ function provableFromTuple(typs: ProvablePure<any>[]): ProvablePure<any> {
},

check(xs: Array<any>) {
typs.forEach((typ, i) => (typ as any).check(xs[i]));
types.forEach((typ, i) => (typ as any).check(xs[i]));
},
};
}
14 changes: 7 additions & 7 deletions src/tests/transaction-flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ await testLocalAndRemote(async () => {
console.log('');

console.log(
"Test calling successful 'update' method does not throw with throwOnFail is false"
"Test calling successful 'update' method does not throw with throwOnFail is true"
);
await testLocalAndRemote(async () => {
await assert.doesNotReject(async () => {
Expand All @@ -199,15 +199,18 @@ await testLocalAndRemote(async () => {
}
);
transaction.sign([senderKey, zkAppKey]);
const includedTransaction = await sendAndVerifyTransaction(transaction);
const includedTransaction = await sendAndVerifyTransaction(
transaction,
true
);
assert(includedTransaction.status === 'included');
await Mina.fetchEvents(zkAppAddress, TokenId.default);
});
});
console.log('');

console.log(
"Test calling successful 'update' method does not throw with throwOnFail is true"
"Test calling successful 'update' method does not throw with throwOnFail is false"
);
await testLocalAndRemote(async () => {
await assert.doesNotReject(async () => {
Expand All @@ -218,10 +221,7 @@ await testLocalAndRemote(async () => {
}
);
transaction.sign([senderKey, zkAppKey]);
const includedTransaction = await sendAndVerifyTransaction(
transaction,
true
);
const includedTransaction = await sendAndVerifyTransaction(transaction);
assert(includedTransaction.status === 'included');
await Mina.fetchEvents(zkAppAddress, TokenId.default);
});
Expand Down

0 comments on commit 550408b

Please sign in to comment.