Skip to content

Commit

Permalink
update smart contract
Browse files Browse the repository at this point in the history
  • Loading branch information
kevaundray committed Oct 11, 2023
1 parent 34cd4aa commit f710440
Showing 1 changed file with 99 additions and 63 deletions.
162 changes: 99 additions & 63 deletions tooling/bb_abstraction_leaks/src/contract.sol
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

/**
* @title Ultra Plonk proof verification contract
* @dev Top level Plonk proof verification contract, which allows Plonk proof to be verified
Expand Down Expand Up @@ -282,6 +281,9 @@ abstract contract BaseUltraVerifier {
uint256 internal constant LIMB_SIZE = 0x100000000000000000; // 2<<68
uint256 internal constant SUBLIMB_SHIFT = 0x4000; // 2<<14

// y^2 = x^3 + ax + b
// for Grumpkin, a = 0 and b = -17. We use b in a custom gate relation that evaluates elliptic curve arithmetic
uint256 internal constant GRUMPKIN_CURVE_B_PARAMETER_NEGATED = 17;
error PUBLIC_INPUT_COUNT_INVALID(uint256 expected, uint256 actual);
error PUBLIC_INPUT_INVALID_BN128_G1_POINT();
error PUBLIC_INPUT_GE_P();
Expand Down Expand Up @@ -1154,96 +1156,130 @@ abstract contract BaseUltraVerifier {
* sign_term += sign_term
* sign_term *= q_sign
*/
// q_elliptic * (x3 + x2 + x1)(x2 - x1)(x2 - x1) - y2^2 - y1^2 + 2(y2y1)*q_sign = 0
let x_diff := addmod(mload(X2_EVAL_LOC), sub(p, mload(X1_EVAL_LOC)), p)
let y2_sqr := mulmod(mload(Y2_EVAL_LOC), mload(Y2_EVAL_LOC), p)
let y1_sqr := mulmod(mload(Y1_EVAL_LOC), mload(Y1_EVAL_LOC), p)
let y1y2 := mulmod(mulmod(mload(Y1_EVAL_LOC), mload(Y2_EVAL_LOC), p), mload(QSIGN_LOC), p)

let endo_term :=
let x_add_identity :=
addmod(
mulmod(
addmod(mload(X3_EVAL_LOC), addmod(mload(X2_EVAL_LOC), mload(X1_EVAL_LOC), p), p),
mulmod(x_diff, x_diff, p),
p
),
addmod(
sub(
p,
addmod(y2_sqr, y1_sqr, p)
),
addmod(y1y2, y1y2, p),
p
),
p
)
x_add_identity :=
mulmod(
mulmod(
mulmod(sub(p, mload(X2_EVAL_LOC)), mload(X1_EVAL_LOC), p),
addmod(addmod(mload(X3_EVAL_LOC), mload(X3_EVAL_LOC), p), mload(X1_EVAL_LOC), p),
x_add_identity,
addmod(
1,
sub(p, mload(QM_EVAL_LOC)),
p
),
p
),
mload(QBETA_LOC),
mload(C_ALPHA_BASE_LOC),
p
)

let endo_sqr_term := mulmod(mload(X2_EVAL_LOC), mload(X2_EVAL_LOC), p)
endo_sqr_term := mulmod(endo_sqr_term, addmod(mload(X3_EVAL_LOC), sub(p, mload(X1_EVAL_LOC)), p), p)
endo_sqr_term := mulmod(endo_sqr_term, mload(QBETA_SQR_LOC), p)
// q_elliptic * (x3 + x2 + x1)(x2 - x1)(x2 - x1) - y2^2 - y1^2 + 2(y2y1)*q_sign = 0
let y1_plus_y3 := addmod(
mload(Y1_EVAL_LOC),
mload(Y3_EVAL_LOC),
p
)
let y_diff := addmod(mulmod(mload(Y2_EVAL_LOC), mload(QSIGN_LOC), p), sub(p, mload(Y1_EVAL_LOC)), p)
let y_add_identity :=
addmod(
mulmod(y1_plus_y3, x_diff, p),
mulmod(addmod(mload(X3_EVAL_LOC), sub(p, mload(X1_EVAL_LOC)), p), y_diff, p),
p
)
y_add_identity :=
mulmod(
mulmod(y_add_identity, addmod(1, sub(p, mload(QM_EVAL_LOC)), p), p),
mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p),
p
)

let leftovers := mulmod(mload(X2_EVAL_LOC), mload(X2_EVAL_LOC), p)
leftovers := mulmod(leftovers, mload(X2_EVAL_LOC), p)
leftovers :=
// ELLIPTIC_IDENTITY = (x_identity + y_identity) * Q_ELLIPTIC_EVAL
mstore(
ELLIPTIC_IDENTITY, mulmod(addmod(x_add_identity, y_add_identity, p), mload(QELLIPTIC_EVAL_LOC), p)
)
}
{
/**
* x_pow_4 = (y_1_sqr - curve_b) * x_1;
* y_1_sqr_mul_4 = y_1_sqr + y_1_sqr;
* y_1_sqr_mul_4 += y_1_sqr_mul_4;
* x_1_pow_4_mul_9 = x_pow_4;
* x_1_pow_4_mul_9 += x_1_pow_4_mul_9;
* x_1_pow_4_mul_9 += x_1_pow_4_mul_9;
* x_1_pow_4_mul_9 += x_1_pow_4_mul_9;
* x_1_pow_4_mul_9 += x_pow_4;
* x_1_sqr_mul_3 = x_1_sqr + x_1_sqr + x_1_sqr;
* x_double_identity = (x_3 + x_1 + x_1) * y_1_sqr_mul_4 - x_1_pow_4_mul_9;
* y_double_identity = x_1_sqr_mul_3 * (x_1 - x_3) - (y_1 + y_1) * (y_1 + y_3);
*/
// (x3 + x1 + x1) (4y1*y1) - 9 * x1 * x1 * x1 * x1 = 0
let x1_sqr := mulmod(mload(X1_EVAL_LOC), mload(X1_EVAL_LOC), p)
let y1_sqr := mulmod(mload(Y1_EVAL_LOC), mload(Y1_EVAL_LOC), p)
let x_pow_4 := mulmod(addmod(y1_sqr, GRUMPKIN_CURVE_B_PARAMETER_NEGATED, p), mload(X1_EVAL_LOC), p)
let y1_sqr_mul_4 := mulmod(y1_sqr, 4, p)
let x1_pow_4_mul_9 := mulmod(x_pow_4, 9, p)
let x1_sqr_mul_3 := mulmod(x1_sqr, 3, p)
let x_double_identity :=
addmod(
leftovers,
mulmod(
mulmod(mload(X1_EVAL_LOC), mload(X1_EVAL_LOC), p),
addmod(mload(X3_EVAL_LOC), mload(X1_EVAL_LOC), p),
addmod(mload(X3_EVAL_LOC), addmod(mload(X1_EVAL_LOC), mload(X1_EVAL_LOC), p), p),
y1_sqr_mul_4,
p
),
sub(p, x1_pow_4_mul_9),
p
)
leftovers :=
// (y1 + y1) (2y1) - (3 * x1 * x1)(x1 - x3) = 0
let y_double_identity :=
addmod(
leftovers,
mulmod(x1_sqr_mul_3, addmod(mload(X1_EVAL_LOC), sub(p, mload(X3_EVAL_LOC)), p), p),
sub(
p,
addmod(
mulmod(mload(Y2_EVAL_LOC), mload(Y2_EVAL_LOC), p),
mulmod(mload(Y1_EVAL_LOC), mload(Y1_EVAL_LOC), p),
mulmod(
addmod(mload(Y1_EVAL_LOC), mload(Y1_EVAL_LOC), p),
addmod(mload(Y1_EVAL_LOC), mload(Y3_EVAL_LOC), p),
p
)
),
p
)

let sign_term := mulmod(mload(Y2_EVAL_LOC), mload(Y1_EVAL_LOC), p)
sign_term := addmod(sign_term, sign_term, p)
sign_term := mulmod(sign_term, mload(QSIGN_LOC), p)

/**
* x_identity = endo_term + endo_sqr_term + sign_term + leftovers
* x_identity *= alpha_base
* endo_term = (x_2 * q_beta) * (y_3 + y_1)
* sign_term = -((y2 * q_sign) * (x_1 + x_3))
* leftovers = - x1 * (y_3 + y_1) + y_1 * (x_1 - x_3)
* y_identity = (endo_term + sign_term + leftovers) * (alpha_base * α)
*/

let x_identity := addmod(addmod(endo_term, endo_sqr_term, p), addmod(sign_term, leftovers, p), p)
x_identity := mulmod(x_identity, mload(C_ALPHA_BASE_LOC), p)
endo_term :=
mulmod(
mulmod(mload(X2_EVAL_LOC), mload(QBETA_LOC), p),
addmod(mload(Y3_EVAL_LOC), mload(Y1_EVAL_LOC), p),
p
)
sign_term :=
sub(
p,
mulmod(
mulmod(mload(Y2_EVAL_LOC), mload(QSIGN_LOC), p),
addmod(mload(X1_EVAL_LOC), sub(p, mload(X3_EVAL_LOC)), p),
p
)
)
leftovers :=
x_double_identity := mulmod(x_double_identity, mload(C_ALPHA_BASE_LOC), p)
y_double_identity :=
mulmod(y_double_identity, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p), p)
x_double_identity := mulmod(x_double_identity, mload(QM_EVAL_LOC), p)
y_double_identity := mulmod(y_double_identity, mload(QM_EVAL_LOC), p)
// ELLIPTIC_IDENTITY += (x_double_identity + y_double_identity) * Q_DOUBLE_EVAL
mstore(
ELLIPTIC_IDENTITY,
addmod(
sub(p, mulmod(mload(X1_EVAL_LOC), addmod(mload(Y3_EVAL_LOC), mload(Y1_EVAL_LOC), p), p)),
mulmod(mload(Y1_EVAL_LOC), addmod(mload(X1_EVAL_LOC), sub(p, mload(X3_EVAL_LOC)), p), p),
mload(ELLIPTIC_IDENTITY),
mulmod(addmod(x_double_identity, y_double_identity, p), mload(QELLIPTIC_EVAL_LOC), p),
p
)
let y_identity :=
mulmod(
addmod(addmod(endo_term, sign_term, p), leftovers, p),
mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_LOC), p),
p
)

// ELLIPTIC_IDENTITY = (x_identity + y_identity) * Q_ELLIPTIC_EVAL
mstore(ELLIPTIC_IDENTITY, mulmod(addmod(x_identity, y_identity, p), mload(QELLIPTIC_EVAL_LOC), p))
)

// update alpha
// The paper says to use ALPHA^2, we use ALPHA^4 this is a small oversight in the prover protocol
mstore(C_ALPHA_BASE_LOC, mulmod(mload(C_ALPHA_BASE_LOC), mload(C_ALPHA_QUAD_LOC), p))
}

Expand Down

0 comments on commit f710440

Please sign in to comment.