Skip to content

Commit

Permalink
fix: ecadd/mul (#961)
Browse files Browse the repository at this point in the history
* fix: ec_add

* fix: ec_mul

* fmt
  • Loading branch information
enitrat authored Sep 23, 2024
1 parent a4442a6 commit 23d3b18
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 32 deletions.
51 changes: 31 additions & 20 deletions crates/evm/src/precompiles/ec_add.cairo
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use core::circuit::CircuitElement as CE;
use core::circuit::CircuitInput as CI;
use core::circuit::u96;

use core::circuit::{
u384, CircuitElement, CircuitInput, circuit_add, circuit_sub, circuit_mul, circuit_inverse,
Expand All @@ -17,6 +18,11 @@ use utils::helpers::{load_word, U8SpanExTrait};

const BASE_COST: u64 = 150;
const U256_BYTES_LEN: usize = 32;
const PRIME: [
u96
; 4] = [
0x6871ca8d3c208c16d87cfd47, 0xb85045b68181585d97816a91, 0x30644e72e131a029, 0x0
];

pub impl EcAdd of Precompile {
#[inline(always)]
Expand Down Expand Up @@ -145,16 +151,14 @@ pub fn ec_safe_add(x1: u384, y1: u384, x2: u384, y2: u384) -> Option<(u384, u384
pub fn is_on_curve(x: u384, y: u384) -> bool {
let (b, _x, _y) = (CE::<CI<0>> {}, CE::<CI<1>> {}, CE::<CI<2>> {});

// Compute (y^2 - (x^2 + b)) % p_bn254
// Compute (y^2 - (x^3 + b)) % p_bn254
let x2 = circuit_mul(_x, _x);
let x3 = circuit_mul(x2, _x);
let y2 = circuit_mul(_y, _y);
let y3 = circuit_mul(_y, y2);
let rhs = circuit_add(x2, b);
let check = circuit_sub(y3, rhs);
let rhs = circuit_add(x3, b);
let check = circuit_sub(y2, rhs);

let modulus = TryInto::<
_, CircuitModulus
>::try_into([0x6871ca8d3c208c16d87cfd47, 0xb85045b68181585d97816a91, 0x30644e72e131a029, 0x0])
let modulus = TryInto::<_, CircuitModulus>::try_into(PRIME)
.unwrap(); // BN254 prime field modulus

let mut circuit_inputs = (check,).new_inputs();
Expand Down Expand Up @@ -187,9 +191,7 @@ fn add_ec_point_unchecked(xP: u384, yP: u384, xQ: u384, yQ: u384) -> (u384, u384
let nx = circuit_sub(circuit_sub(slope_sqr, _xP), _xQ);
let ny = circuit_sub(circuit_mul(slope, circuit_sub(_xP, nx)), _yP);

let modulus = TryInto::<
_, CircuitModulus
>::try_into([0x6871ca8d3c208c16d87cfd47, 0xb85045b68181585d97816a91, 0x30644e72e131a029, 0x0])
let modulus = TryInto::<_, CircuitModulus>::try_into(PRIME)
.unwrap(); // BN254 prime field modulus

let mut circuit_inputs = (nx, ny,).new_inputs();
Expand Down Expand Up @@ -219,11 +221,9 @@ pub fn double_ec_point_unchecked(x: u384, y: u384) -> (u384, u384) {
let slope_sqr = circuit_mul(slope, slope);

let nx = circuit_sub(circuit_sub(slope_sqr, _x), _x);
let ny = circuit_sub(_y, circuit_mul(slope, circuit_sub(_x, nx)));
let ny = circuit_sub(circuit_mul(slope, circuit_sub(_x, nx)), _y);

let modulus = TryInto::<
_, CircuitModulus
>::try_into([0x6871ca8d3c208c16d87cfd47, 0xb85045b68181585d97816a91, 0x30644e72e131a029, 0x0])
let modulus = TryInto::<_, CircuitModulus>::try_into(PRIME)
.unwrap(); // BN254 prime field modulus

let mut circuit_inputs = (nx, ny,).new_inputs();
Expand All @@ -243,9 +243,7 @@ fn eq_mod_p(a: u384, b: u384) -> bool {
let in2 = CircuitElement::<CircuitInput<1>> {};
let sub = circuit_sub(in1, in2);

let modulus = TryInto::<
_, CircuitModulus
>::try_into([0x6871ca8d3c208c16d87cfd47, 0xb85045b68181585d97816a91, 0x30644e72e131a029, 0x0])
let modulus = TryInto::<_, CircuitModulus>::try_into(PRIME)
.unwrap(); // BN254 prime field modulus

let outputs = (sub,).new_inputs().next_2(a).next_2(b).done_2().eval(modulus).unwrap();
Expand All @@ -259,12 +257,25 @@ fn eq_neg_mod_p(a: u384, b: u384) -> bool {
let _b = CE::<CI<1>> {};
let check = circuit_add(_a, _b);

let modulus = TryInto::<
_, CircuitModulus
>::try_into([0x6871ca8d3c208c16d87cfd47, 0xb85045b68181585d97816a91, 0x30644e72e131a029, 0x0])
let modulus = TryInto::<_, CircuitModulus>::try_into(PRIME)
.unwrap(); // BN254 prime field modulus

let outputs = (check,).new_inputs().next_2(a).next_2(b).done_2().eval(modulus).unwrap();

return outputs.get_output(check).is_zero();
}

#[cfg(test)]
mod tests {
use super::ec_add;
#[test]
fn test_ec_add() {
let x1 = 1;
let y1 = 2;
let x2 = 1;
let y2 = 2;
let (x, y) = ec_add(x1, y1, x2, y2).expect('ec_add failed');
assert_eq!(x, 0x030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd3);
assert_eq!(y, 0x15ed738c0e0a7c92e7845f96b2ae9c0a68a6a449e3538fc7ff3ebf7a5a18a2c4);
}
}
39 changes: 27 additions & 12 deletions crates/evm/src/precompiles/ec_mul.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,11 @@ fn get_bits_little(s: u256) -> Array<felt252> {
s_low = q;
};
let mut s_high = s.high;

if s_high != 0 {
while bits.len() != 128 {
bits.append(0);
}
}
while s_high != 0 {
let (q, r) = core::traits::DivRem::div_rem(s_high, 2);
bits.append(r.into());
Expand All @@ -108,21 +112,32 @@ fn get_bits_little(s: u256) -> Array<felt252> {
// Returns Option::None in case of point at infinity.
// The size of bits array must be at minimum 2 and the point must be on the curve.
fn ec_mul_inner(pt: (u384, u384), mut bits: Array<felt252>) -> Option<(u384, u384)> {
let (x_o, y_o) = pt;
let mut pt = Option::Some(pt);
let (mut temp_x, mut temp_y) = pt;
let mut result: Option<(u384, u384)> = Option::None;
while let Option::Some(bit) = bits.pop_front() {
match pt {
Option::Some((xt, yt)) => pt = Option::Some(double_ec_point_unchecked(xt, yt)),
Option::None => pt = Option::None,
}

if bit != 0 {
match pt {
Option::Some((xt, yt)) => pt = ec_safe_add(x_o, y_o, xt, yt),
Option::None => pt = Option::Some((x_o, y_o)),
match result {
Option::Some((xr, yr)) => result = ec_safe_add(temp_x, temp_y, xr, yr),
Option::None => result = Option::Some((temp_x, temp_y)),
};
};
let (_temp_x, _temp_y) = double_ec_point_unchecked(temp_x, temp_y);
temp_x = _temp_x;
temp_y = _temp_y;
};

pt
return result;
}

#[cfg(test)]
mod tests {
use super::ec_mul;

#[test]
fn test_ec_mul() {
let (x1, y1, s) = (1, 2, 2);
let (x, y) = ec_mul(x1, y1, s).expect('ec_mul failed');
assert_eq!(x, 0x030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd3);
assert_eq!(y, 0x15ed738c0e0a7c92e7845f96b2ae9c0a68a6a449e3538fc7ff3ebf7a5a18a2c4);
}
}

0 comments on commit 23d3b18

Please sign in to comment.