Skip to content

Commit

Permalink
Edits.
Browse files Browse the repository at this point in the history
  • Loading branch information
br0wnD3v committed Aug 5, 2024
1 parent 18b0f3f commit 7e24148
Show file tree
Hide file tree
Showing 4 changed files with 242 additions and 67 deletions.
31 changes: 21 additions & 10 deletions src/Aggregation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,34 @@ import {
method,
} from 'o1js';

export class PriceAggregationArray10 extends Struct({
pricesArray: Provable.Array(UInt64, 10),
export class PriceAggregationArray20 extends Struct({
pricesArray: Provable.Array(UInt64, 20),
count: UInt64,
}) {}
export class PriceAggregationArray100 extends Struct({
pricesArray: Provable.Array(UInt64, 100),
count: UInt64,
}) {}

export const AggregationProgram10 = ZkProgram({
export const AggregationProgram20 = ZkProgram({
name: 'doot-prices-aggregation-program',
publicInput: PriceAggregationArray10,
publicInput: PriceAggregationArray20,
publicOutput: UInt64,

methods: {
base: {
privateInputs: [],

async method(publicInput: PriceAggregationArray10) {
async method(publicInput: PriceAggregationArray20) {
return UInt64.from(0);
},
},
generateAggregationProof: {
privateInputs: [SelfProof],

async method(
publicInput: PriceAggregationArray10,
privateInput: SelfProof<PriceAggregationArray10, UInt64>
publicInput: PriceAggregationArray20,
privateInput: SelfProof<PriceAggregationArray20, UInt64>
) {
privateInput.verify();

Expand All @@ -48,7 +49,17 @@ export const AggregationProgram10 = ZkProgram({
.add(publicInput.pricesArray[7])
.add(publicInput.pricesArray[8])
.add(publicInput.pricesArray[9])
.div(10);
.add(publicInput.pricesArray[10])
.add(publicInput.pricesArray[11])
.add(publicInput.pricesArray[12])
.add(publicInput.pricesArray[13])
.add(publicInput.pricesArray[14])
.add(publicInput.pricesArray[15])
.add(publicInput.pricesArray[16])
.add(publicInput.pricesArray[17])
.add(publicInput.pricesArray[18])
.add(publicInput.pricesArray[19])
.div(publicInput.count);
},
},
},
Expand Down Expand Up @@ -182,7 +193,7 @@ export const AggregationProgram100 = ZkProgram({
},
});

export class AggregationProof10 extends ZkProgram.Proof(AggregationProgram10) {}
export class AggregationProof20 extends ZkProgram.Proof(AggregationProgram20) {}
export class AggregationProof100 extends ZkProgram.Proof(
AggregationProgram100
) {}
Expand All @@ -192,7 +203,7 @@ export class VerifyAggregationProofGenerated extends SmartContract {
super.init();
}

@method async verifyAggregationProof10(proof: AggregationProof10) {
@method async verifyAggregationProof20(proof: AggregationProof20) {
proof.verify();
}
@method async verifyAggregationProof100(proof: AggregationProof100) {
Expand Down
161 changes: 161 additions & 0 deletions src/AggregationModule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import {
UInt64,
Mina,
verify,
JsonProof,
Provable,
Struct,
ZkProgram,
SelfProof,
} from "o1js";

class PriceAggregationArray20 extends Struct({
pricesArray: Provable.Array(UInt64, 20),
count: UInt64,
}) {}

const AggregationProgram20 = ZkProgram({
name: "doot-prices-aggregation-program",
publicInput: PriceAggregationArray20,
publicOutput: UInt64,

methods: {
base: {
privateInputs: [],

async method(publicInput: PriceAggregationArray20) {
return publicInput.pricesArray[0]
.add(publicInput.pricesArray[1])
.add(publicInput.pricesArray[2])
.add(publicInput.pricesArray[3])
.add(publicInput.pricesArray[4])
.add(publicInput.pricesArray[5])
.add(publicInput.pricesArray[6])
.add(publicInput.pricesArray[7])
.add(publicInput.pricesArray[8])
.add(publicInput.pricesArray[9])
.add(publicInput.pricesArray[10])
.add(publicInput.pricesArray[11])
.add(publicInput.pricesArray[12])
.add(publicInput.pricesArray[13])
.add(publicInput.pricesArray[14])
.add(publicInput.pricesArray[15])
.add(publicInput.pricesArray[16])
.add(publicInput.pricesArray[17])
.add(publicInput.pricesArray[18])
.add(publicInput.pricesArray[19])
.div(publicInput.count);
},
},
generateAggregationProof: {
privateInputs: [SelfProof],

async method(
publicInput: PriceAggregationArray20,
privateInput: SelfProof<PriceAggregationArray20, UInt64>
) {
privateInput.verify();

return publicInput.pricesArray[0]
.add(publicInput.pricesArray[1])
.add(publicInput.pricesArray[2])
.add(publicInput.pricesArray[3])
.add(publicInput.pricesArray[4])
.add(publicInput.pricesArray[5])
.add(publicInput.pricesArray[6])
.add(publicInput.pricesArray[7])
.add(publicInput.pricesArray[8])
.add(publicInput.pricesArray[9])
.add(publicInput.pricesArray[10])
.add(publicInput.pricesArray[11])
.add(publicInput.pricesArray[12])
.add(publicInput.pricesArray[13])
.add(publicInput.pricesArray[14])
.add(publicInput.pricesArray[15])
.add(publicInput.pricesArray[16])
.add(publicInput.pricesArray[17])
.add(publicInput.pricesArray[18])
.add(publicInput.pricesArray[19])
.div(publicInput.count);
},
},
},
});

class AggregationProof20 extends ZkProgram.Proof(AggregationProgram20) {}

async function generateUInt64Array(
prices: bigint[]
): Promise<[UInt64[], UInt64]> {
let lastValidValueIndex = prices.length;
let UInt64Prices: UInt64[] = [];

for (let i = prices.length - 1; i >= 0; i--)
if (prices[i] !== 0n) {
lastValidValueIndex = i;
break;
}
const count = UInt64.from(lastValidValueIndex + 1);

UInt64Prices = prices
.slice(0, lastValidValueIndex + 1)
.map((price) => UInt64.from(price));

return [UInt64Prices, count];
}

/// AGGREGATION OF WHOLE PRICES WITHOUT PRECISION (Indirect precision of 10 by multiplying the original values by 10**10).
async function AggregationModule(
prices: bigint[],
lastAvailableProofStr: string,
isBase: boolean
): Promise<[JsonProof | null, bigint]> {
let Local = await Mina.LocalBlockchain({ proofsEnabled: false });
Mina.setActiveInstance(Local);
const { verificationKey: vk20 } = await AggregationProgram20.compile();

const lastAvailableProof: JsonProof = JSON.parse(lastAvailableProofStr);
const compatibleResults = await generateUInt64Array(prices);
const input20: PriceAggregationArray20 = new PriceAggregationArray20({
pricesArray: compatibleResults[0],
count: compatibleResults[1],
});

if (!isBase) {
const compatibleLastAvailableProof = await AggregationProof20.fromJSON(
lastAvailableProof
);
let proof20 = await AggregationProgram20.generateAggregationProof(
input20,
compatibleLastAvailableProof
);
console.log("Step Proof20 Generated.");

proof20 satisfies AggregationProof20;
console.log("Step Proof20 Sanity Check.");

const valid20 = await verify(proof20.toJSON(), vk20);
if (!valid20) {
console.log("\nERR! VALID 20 FAILED.\n");
return [null, 0n];
} else {
return [proof20.toJSON(), proof20.publicOutput.toBigInt()];
}
} else {
let proof20 = await AggregationProgram20.base(input20);
console.log("Base Proof20 Generated.");

proof20 satisfies AggregationProof20;
console.log("Base Proof20 Sanity Check.");

const valid20 = await verify(proof20.toJSON(), vk20);
if (!valid20) {
console.log("\nERR! VALID 20 FAILED.\n");
return [null, 0n];
} else {
return [proof20.toJSON(), proof20.publicOutput.toBigInt()];
}
}
}

module.exports = { AggregationModule };
Loading

0 comments on commit 7e24148

Please sign in to comment.