From 5b30e080615058f7032c1de7166ed007afa70c16 Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Thu, 27 Apr 2023 10:57:26 -0300
Subject: [PATCH 1/4] Add alternative string for hint EC_DOUBLE_ASSIGN_NEW_X

---
 src/hint_processor/builtin_hint_processor/hint_code.rs | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/src/hint_processor/builtin_hint_processor/hint_code.rs b/src/hint_processor/builtin_hint_processor/hint_code.rs
index cdb44bc186..06927d82ff 100644
--- a/src/hint_processor/builtin_hint_processor/hint_code.rs
+++ b/src/hint_processor/builtin_hint_processor/hint_code.rs
@@ -708,6 +708,14 @@ y = pack(ids.point.y, PRIME)
 
 value = new_x = (pow(slope, 2, SECP_P) - 2 * x) % SECP_P"#;
 
+pub const EC_DOUBLE_ASSIGN_NEW_X_V4: &str = r#"from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack
+
+slope = pack(ids.slope, PRIME)
+x = pack(ids.pt.x, PRIME)
+y = pack(ids.pt.y, PRIME)
+
+value = new_x = (pow(slope, 2, SECP_P) - 2 * x) % SECP_P"#;
+
 pub const EC_DOUBLE_ASSIGN_NEW_Y: &str = r#"value = new_y = (slope * (x - new_x) - y) % SECP_P"#;
 
 pub const SHA256_INPUT: &str = r#"ids.full_word = int(ids.n_bytes >= 4)"#;

From 8f71c7d66fbdbbf6858c18ef560b9e53c8f61c15 Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Thu, 27 Apr 2023 11:16:52 -0300
Subject: [PATCH 2/4] Expand hitn func with point_alias arg

---
 .../builtin_hint_processor_definition.rs               | 10 ++++++++++
 .../builtin_hint_processor/secp/ec_utils.rs            |  3 ++-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs b/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs
index ba666d33c2..baec3a2499 100644
--- a/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs
+++ b/src/hint_processor/builtin_hint_processor/builtin_hint_processor_definition.rs
@@ -525,6 +525,7 @@ impl HintProcessor for BuiltinHintProcessor {
                     &hint_data.ids_data,
                     &hint_data.ap_tracking,
                     &SECP_P,
+                    "point",
                 )
             }
             hint_code::EC_DOUBLE_ASSIGN_NEW_X_V3 => ec_double_assign_new_x(
@@ -533,6 +534,15 @@ impl HintProcessor for BuiltinHintProcessor {
                 &hint_data.ids_data,
                 &hint_data.ap_tracking,
                 &SECP_P_V2,
+                "point",
+            ),
+            hint_code::EC_DOUBLE_ASSIGN_NEW_X_V4 => ec_double_assign_new_x(
+                vm,
+                exec_scopes,
+                &hint_data.ids_data,
+                &hint_data.ap_tracking,
+                &SECP_P,
+                "pt",
             ),
             hint_code::EC_DOUBLE_ASSIGN_NEW_Y => ec_double_assign_new_y(exec_scopes),
             hint_code::KECCAK_WRITE_ARGS => {
diff --git a/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs b/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs
index f80fe6caf1..30513dee70 100644
--- a/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs
+++ b/src/hint_processor/builtin_hint_processor/secp/ec_utils.rs
@@ -215,12 +215,13 @@ pub fn ec_double_assign_new_x(
     ids_data: &HashMap<String, HintReference>,
     ap_tracking: &ApTracking,
     secp_p: &BigInt,
+    point_alias: &str,
 ) -> Result<(), HintError> {
     exec_scopes.insert_value("SECP_P", secp_p.clone());
     //ids.slope
     let slope = BigInt3::from_var_name("slope", vm, ids_data, ap_tracking)?;
     //ids.point
-    let point = EcPoint::from_var_name("point", vm, ids_data, ap_tracking)?;
+    let point = EcPoint::from_var_name(point_alias, vm, ids_data, ap_tracking)?;
 
     let slope = slope.pack86().mod_floor(secp_p);
     let x = point.x.pack86().mod_floor(secp_p);

From 5ffbf5c592b9ccabcdaa17c05ac871d153dd39e8 Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Thu, 27 Apr 2023 11:28:24 -0300
Subject: [PATCH 3/4] Add integration test

---
 cairo_programs/ec_double_v4.cairo | 84 +++++++++++++++++++++++++++++++
 src/tests/cairo_run_test.rs       |  7 +++
 2 files changed, 91 insertions(+)
 create mode 100644 cairo_programs/ec_double_v4.cairo

diff --git a/cairo_programs/ec_double_v4.cairo b/cairo_programs/ec_double_v4.cairo
new file mode 100644
index 0000000000..8455b22678
--- /dev/null
+++ b/cairo_programs/ec_double_v4.cairo
@@ -0,0 +1,84 @@
+%builtins range_check
+
+from starkware.cairo.common.cairo_secp.bigint import BigInt3, UnreducedBigInt3, nondet_bigint3
+from starkware.cairo.common.cairo_secp.ec import compute_doubling_slope, EcPoint
+from starkware.cairo.common.cairo_secp.field import (
+    is_zero,
+    unreduced_mul,
+    unreduced_sqr,
+    verify_zero,
+)
+
+// Computes the addition of a given point to itself.
+//
+// Arguments:
+//   point - the point to operate on.
+//
+// Returns:
+//   res - a point representing point + point.
+func ec_double{range_check_ptr}(pt: EcPoint) -> (res: EcPoint) {
+    // The zero point.
+    if (pt.x.d0 == 0) {
+        if (pt.x.d1 == 0) {
+            if (pt.x.d2 == 0) {
+                return (res=pt);
+            }
+        }
+    }
+
+    let (slope: BigInt3) = compute_doubling_slope(pt);
+    let (slope_sqr: UnreducedBigInt3) = unreduced_sqr(slope);
+
+    %{
+        from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack
+
+        slope = pack(ids.slope, PRIME)
+        x = pack(ids.pt.x, PRIME)
+        y = pack(ids.pt.y, PRIME)
+
+        value = new_x = (pow(slope, 2, SECP_P) - 2 * x) % SECP_P
+    %}
+    let (new_x: BigInt3) = nondet_bigint3();
+
+    %{ value = new_y = (slope * (x - new_x) - y) % SECP_P %}
+    let (new_y: BigInt3) = nondet_bigint3();
+
+    verify_zero(
+        UnreducedBigInt3(
+            d0=slope_sqr.d0 - new_x.d0 - 2 * pt.x.d0,
+            d1=slope_sqr.d1 - new_x.d1 - 2 * pt.x.d1,
+            d2=slope_sqr.d2 - new_x.d2 - 2 * pt.x.d2,
+        ),
+    );
+
+    let (x_diff_slope: UnreducedBigInt3) = unreduced_mul(
+        BigInt3(d0=pt.x.d0 - new_x.d0, d1=pt.x.d1 - new_x.d1, d2=pt.x.d2 - new_x.d2), slope
+    );
+
+    verify_zero(
+        UnreducedBigInt3(
+            d0=x_diff_slope.d0 - pt.y.d0 - new_y.d0,
+            d1=x_diff_slope.d1 - pt.y.d1 - new_y.d1,
+            d2=x_diff_slope.d2 - pt.y.d2 - new_y.d2,
+        ),
+    );
+
+    return (res=EcPoint(new_x, new_y));
+}
+
+func main{range_check_ptr}() {
+    let x = BigInt3(7,8,9);
+    let y = BigInt3(19,29,30);
+    let p = EcPoint(x, y);
+    let (r) = ec_double(p);
+
+    assert r.x.d0 = 51257743837507631919880152;
+    assert r.x.d1 = 64460046105241149334147278;
+    assert r.x.d2 = 12582041431145599112140654;
+
+    assert r.y.d0 = 19321524266852839048503535;
+    assert r.y.d1 = 35591956483215965716767025;
+    assert r.y.d2 = 12630971731313051616919773;
+
+    return();
+}
diff --git a/src/tests/cairo_run_test.rs b/src/tests/cairo_run_test.rs
index ef3903621b..403e001ca4 100644
--- a/src/tests/cairo_run_test.rs
+++ b/src/tests/cairo_run_test.rs
@@ -911,3 +911,10 @@ fn nondet_bigint3_v2() {
     let program_data = include_bytes!("../../cairo_programs/nondet_bigint3_v2.json");
     run_program_simple(program_data.as_slice());
 }
+
+#[test]
+#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
+fn ec_double_v4() {
+    let program_data = include_bytes!("../../cairo_programs/ec_double_v4.json");
+    run_program_simple(program_data.as_slice());
+}

From f42a9f7300127890b9ecdfc4ca2145f18534811c Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Thu, 27 Apr 2023 11:29:41 -0300
Subject: [PATCH 4/4] Add changelog entry

---
 CHANGELOG.md | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2c605e7234..b48840b6c4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,22 @@
 
 #### Upcoming Changes
 
+* Add alternative hint code for ec_double hint [#1083](https://github.com/lambdaclass/cairo-rs/pull/1083)
+
+    `BuiltinHintProcessor` now supports the following hint:
+
+    ```python
+        %{
+        from starkware.cairo.common.cairo_secp.secp_utils import SECP_P, pack
+
+        slope = pack(ids.slope, PRIME)
+        x = pack(ids.pt.x, PRIME)
+        y = pack(ids.pt.y, PRIME)
+
+        value = new_x = (pow(slope, 2, SECP_P) - 2 * x) % SECP_P
+    %}
+    ```
+
 * Add alternative hint code for nondet_bigint3 hint [#1071](https://github.com/lambdaclass/cairo-rs/pull/1071)
 
     `BuiltinHintProcessor` now supports the following hint: