Skip to content

Commit

Permalink
move increments and decrements into statements in circuits
Browse files Browse the repository at this point in the history
  • Loading branch information
lydiagarms committed Jul 4, 2024
1 parent ac8f782 commit d9369a5
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 32 deletions.
10 changes: 8 additions & 2 deletions src/boilerplate/circuit/zokrates/nodes/BoilerplateGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -376,18 +376,24 @@ class BoilerplateGenerator {
});

/** Partitioned states need boilerplate for an incrementation/decrementation, because it's so weird and different from `a = a - b`. Whole states inherit directly from the AST, so don't need boilerplate here. */
incrementation = () => {
incrementation = (extraParams) => {
//const startIndex = this.getIndex({ addendId });
return {
// startIndex,
newCommitmentValue: this.newCommitmentValue,
structProperties: (this.isStruct && { structProperties: this.structProperties}),
memberName: extraParams.memberName,
addend: {},
};
};

decrementation = () => {
decrementation = (extraParams) => {
//const startIndex = this.getIndex({ subtrahendId });
return {
// startIndex,
newCommitmentValue: this.newCommitmentValue,
structProperties: (this.isStruct && { structProperties: this.structProperties}),
memberName: extraParams.memberName,
subtrahend: {},
};
};
Expand Down
65 changes: 38 additions & 27 deletions src/boilerplate/circuit/zokrates/raw/BoilerplateGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,10 +310,20 @@ class BoilerplateGenerator {
];
},

preStatements({ name: x, id, isMapping }): string[] {
preStatements({ name: x, id, isMapping, isWhole, isNullified, typeName, structProperties }): string[] {
if (isMapping) return [];
let decLine = '';
if (!isWhole && isNullified) {
const i = parseInt(x.slice(-1), 10);
const x0 = x.slice(0, -1) + `${i-2}`;
const x1 = x.slice(0, -1) + `${i-1}`;
const x_name = x.slice(0, -2);
let type = typeName ? typeName : 'field';
decLine = `${type} ${x_name} = ${structProperties ? `${type} {${structProperties.map(p => ` ${p}: ${x0}.${p} + ${x1}.${p}`)}}` :`${x0} + ${x1}`} `;
}
return [
`
`${decLine}
\n
// We need to hard-code each stateVarId into the circuit:
field ${x}_stateVarId_field = ${id}`,
// TODO: this results in unnecessary unpacking constraints, but simplifies transpilation effort, for now.
Expand All @@ -322,30 +332,32 @@ class BoilerplateGenerator {

postStatements({ name: x, isWhole, isNullified, newCommitmentValue, structProperties, structPropertiesTypes, typeName }): string[] {
// if (!isWhole && !newCommitmentValue) throw new Error('PATH');
const y = isWhole ? x : newCommitmentValue;
let y = isWhole ? x : newCommitmentValue;
const lines: string[] = [];
if (!isWhole && isNullified) {
// decrement
const i = parseInt(x.slice(-1), 10);
const x0 = x.slice(0, -1) + `${i-2}`;
const x1 = x.slice(0, -1) + `${i-1}`;
const x_name = x.slice(0, -2);
if (!structProperties) {
lines.push(
`assert(${x0} + ${x1} > ${y})
`assert(${x_name} >0)
// TODO: assert no under/overflows
field ${x}_newCommitment_value_field = (${x0} + ${x1}) - (${y})`
field ${x}_newCommitment_value_field = ${x_name}`
);
} else {
// TODO types for each structProperty
lines.push(
`${structProperties.map(p => newCommitmentValue[p] === '0' ? '' : `assert(${x0}.${p} + ${x1}.${p} >= ${y[p]})`).join('\n')}
`${structProperties.map(p => newCommitmentValue[p] === '0' ? '' : `assert(${x_name}.${p} > 0)`).join('\n')}
// TODO: assert no under/overflows
${typeName} ${x}_newCommitment_value = ${typeName} { ${structProperties.map(p => ` ${p}: (${x0}.${p} + ${x1}.${p}) - (${y[p]})`)} }`
${typeName} ${x}_newCommitment_value = ${typeName} { ${structProperties.map(p => ` ${p}: ${x_name}.${p}`)} }`
);
}
} else {
y = isWhole ? x : x.slice(0, -2);
if (!structProperties ) {
if (typeName === 'bool'){
lines.push(`field ${x}_newCommitment_value_field = if ${y} then 1 else 0 fi`);
Expand All @@ -355,7 +367,7 @@ class BoilerplateGenerator {

}
else {
lines.push(`${typeName} ${x}_newCommitment_value = ${typeName} { ${structProperties.map(p => ` ${p}: ${isWhole ? `${y}.${p}` : `${y[p]}`}`)} }\n`);
lines.push(`${typeName} ${x}_newCommitment_value = ${typeName} { ${structProperties.map(p => ` ${p}: ${isWhole ? `${y}.${p}` : `${y}_${p}`}`)} }\n`);
if (structPropertiesTypes) {
structPropertiesTypes.forEach(property => {
if (property.typeName === 'bool'){
Expand Down Expand Up @@ -509,22 +521,17 @@ class BoilerplateGenerator {
return []; // TODO: we might eventually import some underflow/overflow functions.
},

statements({ name: x}): string[] {
// let y = codeGenerator(addends[0]);
//
// for (const addend of addends) {
// if (addend !== addend[0])
// y += `${addend.precedingOperator} ${codeGenerator(addend)}`;
// }


return [
`// Skipping incrementation of ${x}`
statements({ name: x, addend, newCommitmentValue, structProperties, memberName}): string[] {
let typeName = 'field';
if (addend.typeName?.name === 'bool' || addend.leftExpression?.typeName?.name === 'bool') typeName = 'bool';
if (structProperties) {
return [`${typeName} ${x}_${memberName} = ${x}_${memberName} + ${newCommitmentValue[memberName]}`]
}
return [`${typeName} ${x} = ${x} + ${newCommitmentValue}`];
//return [
// `// Skipping incrementation of ${x}`
// `
// // The below represents the incrementation '${x} = ${x} + ${y}':
//
// field ${x}_${i} = ${y}`,
];
//];
},
};

Expand All @@ -534,23 +541,27 @@ class BoilerplateGenerator {
return []; // TODO: we might eventually import some underflow/overflow functions.
},

statements({ name: x }): string[] {
statements({ name: x, subtrahend, newCommitmentValue, structProperties, memberName}): string[] {
if (structProperties) {
return [`${x}.${memberName} = ${newCommitmentValue[memberName]}`]
}
return [`${x} = ${x} - (${newCommitmentValue})`];
// const y = codeGenerator(subtrahend);
// let i = startIndex;
// const x0 = `${x}_${i++}`;
// const x1 = `${x}_${i++}`;
// const x2 = `${x}_${i}`;

return [
`// Moved decrementation of ${x}`
//return [
//`// Moved decrementation of ${x}`
// `
// // The below represents the decrementation '${x} = ${x} - ${y}':
//
// assert(${x0} + ${x1} > ${y})
// // TODO: assert no under/overflows
//
// field ${x2} = (${x0} + ${x1}) - ${y}`,
];
//];
},
};
internalFunctionCall = {
Expand Down
6 changes: 6 additions & 0 deletions src/transformers/visitors/toCircuitVisitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,9 @@ let childOfSecret = path.getAncestorOfType('ForStatement')?.containsSecret;
lhs.indexExpression?.name ||
lhs.indexExpression.expression.name,
}), // TODO: tidy this
...(lhsIndicator.isStruct && {
memberName: lhs.memberName
}),
});
tempRHSPath.containerName = 'subtrahend'; // a dangerous bodge that works
node._newASTPointer = newNode.subtrahend;
Expand All @@ -868,6 +871,9 @@ let childOfSecret = path.getAncestorOfType('ForStatement')?.containsSecret;
lhs.indexExpression?.name ||
lhs.indexExpression.expression.name,
}), // TODO: tidy this
...(lhsIndicator.isStruct && {
memberName: lhs.memberName
}),
});
tempRHSPath.containerName = 'addend'; // a dangerous bodge that works
node._newASTPointer = newNode.addend;
Expand Down
5 changes: 2 additions & 3 deletions test/contracts/KnownUnknown.zol
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,15 @@ contract Assign {
function add( uint256 value ) public {
unknown b += value +a;
unknown x.prop1 += value + a;
unknown x.prop2 += value + a;
unknown x.prop2 += value;
a+= value;
}

function remove( uint256 value ) public {
unknown b -= value +a;
unknown x.prop1 -= value + a;
unknown x.prop2 -= value + a;
unknown x.prop2 -= value;
a+= value;
}


}

0 comments on commit d9369a5

Please sign in to comment.