Skip to content

Commit 11d6bfb

Browse files
committed
faster uint256_add
1 parent 51c287a commit 11d6bfb

File tree

1 file changed

+29
-9
lines changed

1 file changed

+29
-9
lines changed

src/starkware/cairo/common/uint256.cairo

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ func felt_to_uint256{range_check_ptr}(value: felt) -> Uint256 {
6969
// Adds two integers. Returns the result as a 256-bit integer and the (1-bit) carry.
7070
func uint256_add{range_check_ptr}(a: Uint256, b: Uint256) -> (res: Uint256, carry: felt) {
7171
alloc_locals;
72-
local res: Uint256;
7372
local carry_low: felt;
7473
local carry_high: felt;
7574
%{
@@ -79,14 +78,35 @@ func uint256_add{range_check_ptr}(a: Uint256, b: Uint256) -> (res: Uint256, carr
7978
ids.carry_high = 1 if sum_high >= ids.SHIFT else 0
8079
%}
8180

82-
assert carry_low * carry_low = carry_low;
83-
assert carry_high * carry_high = carry_high;
84-
85-
assert res.low = a.low + b.low - carry_low * SHIFT;
86-
assert res.high = a.high + b.high + carry_low - carry_high * SHIFT;
87-
uint256_check(res);
88-
89-
return (res, carry_high);
81+
if (carry_low != 0) {
82+
if (carry_high != 0) {
83+
tempvar range_check_ptr = range_check_ptr + 2;
84+
tempvar res = Uint256(low=a.low + b.low - SHIFT, high=a.high + b.high + 1 - SHIFT);
85+
assert [range_check_ptr - 2] = res.low;
86+
assert [range_check_ptr - 1] = res.high;
87+
return (res, 1);
88+
} else {
89+
tempvar range_check_ptr = range_check_ptr + 2;
90+
tempvar res = Uint256(low=a.low + b.low - SHIFT, high=a.high + b.high + 1);
91+
assert [range_check_ptr - 2] = res.low;
92+
assert [range_check_ptr - 1] = res.high;
93+
return (res, 0);
94+
}
95+
} else {
96+
if (carry_high != 0) {
97+
tempvar range_check_ptr = range_check_ptr + 2;
98+
tempvar res = Uint256(low=a.low + b.low, high=a.high + b.high - SHIFT);
99+
assert [range_check_ptr - 2] = res.low;
100+
assert [range_check_ptr - 1] = res.high;
101+
return (res, 1);
102+
} else {
103+
tempvar range_check_ptr = range_check_ptr + 2;
104+
tempvar res = Uint256(low=a.low + b.low, high=a.high + b.high);
105+
assert [range_check_ptr - 2] = res.low;
106+
assert [range_check_ptr - 1] = res.high;
107+
return (res, 0);
108+
}
109+
}
90110
}
91111

92112
// Splits a field element in the range [0, 2^192) to its low 64-bit and high 128-bit parts.

0 commit comments

Comments
 (0)