Skip to content

Commit

Permalink
Merge pull request #84 from 0xPolygonHermez/feature/array-lib-refactor
Browse files Browse the repository at this point in the history
Refactoring the array lib and minor bugs fixed
  • Loading branch information
krlosMata authored Dec 20, 2023
2 parents 7f3b956 + 2f779d5 commit 261fd15
Show file tree
Hide file tree
Showing 15 changed files with 369 additions and 460 deletions.
78 changes: 34 additions & 44 deletions main/modexp/array_lib/array_add_AGTB.zkasm
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,21 @@
;; · out = inA + inB, with len(out) <= C + 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; function array_add_AGTB(a: bigint[], b: bigint[], B: bigint): bigint[] {
; function array_add_AGTB(a: bigint[], b: bigint[], base: bigint): bigint[] {
; const alen = a.length;
; const blen = b.length;
; let result = new Array<bigint>(alen);
; let sum = 0n;
; let carry = 0n;
; for (let i = 0; i < blen; i++) {
; sum = a[i] + b[i] + carry;
; carry = sum >= B ? 1n : 0n;
; result[i] = sum - carry * B;
; carry = sum >= base ? 1n : 0n;
; out[i] = sum - carry * base;
; }
; for (let i = blen; i < alen; i++) {
; sum = a[i] + carry;
; carry = sum == B ? 1n : 0n; // the past carry is at most 1n
; result[i] = sum - carry * B;
; carry = sum == base ? 1n : 0n; // the past carry is at most 1n
; out[i] = sum - carry * base;
; }

; if (carry === 1n) {
Expand All @@ -36,7 +36,7 @@
; return result;
; }

; NOTE: It's unoptimized for the case where len(inB) = 1. Use array_add_short instead if possible.
; NOTE: It's unoptimized for the case where len(inB) = 1. Use array_add_short instead.

VAR GLOBAL array_add_AGTB_inA[%ARRAY_MAX_LEN]
VAR GLOBAL array_add_AGTB_inB[%ARRAY_MAX_LEN]
Expand All @@ -50,8 +50,8 @@ VAR GLOBAL array_add_AGTB_carry
VAR GLOBAL array_add_AGTB_RR

array_add_AGTB:
%MAX_CNT_BINARY - CNT_BINARY - 3*D - 1 - C+ D - 1 :JMPN(outOfCountersBinary)
%MAX_CNT_STEPS - STEP - 6 - 17*D - 4 - 11*C+11*D - 8 :JMPN(outOfCountersStep)
%MAX_CNT_BINARY - CNT_BINARY - 2*D - C+ D :JMPN(outOfCountersBinary)
%MAX_CNT_STEPS - STEP - 5 - 14*D - 3 - 9*C+9*D - 8 :JMPN(outOfCountersStep)

RR :MSTORE(array_add_AGTB_RR)

Expand All @@ -60,71 +60,61 @@ array_add_AGTB:

0 => E ; index in loops
0 :MSTORE(array_add_AGTB_carry)
:JMP(array_add_AGTB_loopZero2inB)

; Begin of branching
array_add_AGTB_add_carry1:
D + 1 => D :JMP(return_array_add_AGTB_add_carry1)

array_add_AGTB_add_carry2:
D + 1 => D :JMP(return_array_add_AGTB_add_carry2)

array_add_AGTB_add_carry3:
D + 1 => D :JMP(return_array_add_AGTB_add_carry3)
; End of branching

array_add_AGTB_loopZero2inB:
0 => D ; for the carry
; The result will be stored as D·base + C

0 => D ; reset the carry chunk

; a[i] + b[i]
; a[i] + b[i], where a[i],b[i] ∈ [0,base-1]: This number cannot be GT base + (base - 2), two chunks
$ => A :MLOAD(array_add_AGTB_inA + E)
$ => B :MLOAD(array_add_AGTB_inB + E)
$ => C :ADD, JMPC(array_add_AGTB_add_carry1)
return_array_add_AGTB_add_carry1:
$ => C :ADD, JMPNC(__array_add_AGTB_continue_1)
1 => D
__array_add_AGTB_continue_1:

; sum = (a[i] + b[i]) + carry
; sum = (a[i] + b[i]) + carry: This number cannot be GT base + (base - 1), two chunks
$ => A :MLOAD(array_add_AGTB_carry)
C => B
$ => C :ADD, JMPC(array_add_AGTB_add_carry2)
return_array_add_AGTB_add_carry2:
$ => C :ADD, JMPNC(__array_add_AGTB_continue_2)
1 => D
__array_add_AGTB_continue_2:

C :MSTORE(array_add_AGTB_out + E)
D :MSTORE(array_add_AGTB_carry)

E + 1 => E
E => A
E + 1 => E,A
$ => B :MLOAD(array_add_AGTB_len_inB)
$ :EQ, JMPC(array_add_AGTB_loop_index_check1, array_add_AGTB_loopZero2inB)
B - A :JMPZ(array_add_AGTB_loop_index_check, array_add_AGTB_loopZero2inB)

array_add_AGTB_loop_index_check1:
E => A
array_add_AGTB_loop_index_check:
$ => B :MLOAD(array_add_AGTB_len_inA)
$ :EQ, JMPC(array_add_AGTB_check_carry)
B - A :JMPZ(array_add_AGTB_check_carry)

0 => D
array_add_AGTB_loopInB2InA:
; sum = a[i] + carry
; sum = a[i] + carry: This number cannot be GT base, two chunks
$ => A :MLOAD(array_add_AGTB_inA + E)
$ => B :MLOAD(array_add_AGTB_carry)
$ => C :ADD, JMPC(array_add_AGTB_add_carry3)
return_array_add_AGTB_add_carry3:
$ => C :ADD, JMPNC(__array_add_AGTB_continue_3)
1 => D
__array_add_AGTB_continue_3:

C :MSTORE(array_add_AGTB_out + E)
D :MSTORE(array_add_AGTB_carry)

E + 1 => E
E => A
E + 1 => E,A
$ => B :MLOAD(array_add_AGTB_len_inA)
$ :EQ, JMPC(array_add_AGTB_check_carry, array_add_AGTB_loopInB2InA)
B - A :JMPZ(array_add_AGTB_check_carry, array_add_AGTB_loopInB2InA)

array_add_AGTB_check_carry:
$ => A :MLOAD(array_add_AGTB_carry)
1 => B
$ :EQ, JMPNC(array_add_AGTB_len_out)
D => A
A :JMPZ(__array_add_AGTB_continue_4)
; In this case, the carry = 1 and we should append it to the result
1 :MSTORE(array_add_AGTB_out + E)
E + 1 :MSTORE(array_add_AGTB_len_out)
:JMP(array_add_AGTB_end)

array_add_AGTB_len_out:
__array_add_AGTB_continue_4:
E :MSTORE(array_add_AGTB_len_out)

array_add_AGTB_end:
Expand Down
43 changes: 20 additions & 23 deletions main/modexp/array_lib/array_add_short.zkasm
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@
;; · out = inA + inB, with len(out) <= C + 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; function array_add_short(a: bigint[], b: bigint, B: bigint): bigint[] {
; function array_add_short(a: bigint[], b: bigint, base: bigint): bigint[] {
; const alen = a.length;
; let result = new Array<bigint>(alen);
; let sum = 0n;
; let carry = b;
; for (let i = 0; i < alen; i++) {
; sum = a[i] + carry;
; carry = sum >= B ? 1n : 0n;
; result[i] = sum - carry * B;
; carry = sum >= base ? 1n : 0n;
; out[i] = sum - carry * base;
; }

; if (carry === 1n) {
Expand All @@ -38,8 +38,8 @@ VAR GLOBAL array_add_short_carry
VAR GLOBAL array_add_short_RR

array_add_short:
%MAX_CNT_BINARY - CNT_BINARY - 2*C - 1 :JMPN(outOfCountersBinary)
%MAX_CNT_STEPS - STEP - 6 - 12*C - 8 :JMPN(outOfCountersStep)
%MAX_CNT_BINARY - CNT_BINARY - C :JMPN(outOfCountersBinary)
%MAX_CNT_STEPS - STEP - 5 - 10*C - 8 :JMPN(outOfCountersStep)

RR :MSTORE(array_add_short_RR)

Expand All @@ -48,40 +48,37 @@ array_add_short:
0 => E ; index in loops
$ => A :MLOAD(array_add_short_inB)
A :MSTORE(array_add_short_carry)
:JMP(array_add_short_loopZero2inA)

; Begin of branching
array_add_short_add_carry:
D + 1 => D :JMP(return_array_add_short_add_carry)
; End of branching

array_add_short_loopZero2inA:
0 => D ; for the carry
; The result will be stored as D·base + C

0 => D ; reset the carry chunk

; a[i] + carry. If i = 0, then carry = inB.
; a[i] + carry, where a[i] ∈ [0,base-1]:
; · If i = 0, then carry = inB and then the number cannot be GT base + (base - 2), two chunks
; · Otherwise, the number cannot be GT base, two chunks
$ => A :MLOAD(array_add_short_inA + E)
$ => B :MLOAD(array_add_short_carry)
$ => C :ADD, JMPC(array_add_short_add_carry)
return_array_add_short_add_carry:
$ => C :ADD, JMPNC(__array_add_short_continue_1)
1 => D
__array_add_short_continue_1:

C :MSTORE(array_add_short_out + E)
D :MSTORE(array_add_short_carry)

E + 1 => E
E => A
E + 1 => E,A
$ => B :MLOAD(array_add_short_len_inA)
$ :EQ, JMPC(array_add_short_check_carry, array_add_short_loopZero2inA)
B - A :JMPZ(array_add_short_check_carry, array_add_short_loopZero2inA)

array_add_short_check_carry:
D => A
1 => B
$ :EQ, JMPNC(array_add_short_len_out)
A :JMPZ(__array_add_short_continue_2)
; In this case, the carry = 1 and we should append it to the result
1 :MSTORE(array_add_short_out + E)
E + 1 :MSTORE(array_add_short_len_out)
:JMP(array_add_short_end)

array_add_short_len_out:
E :MSTORE(array_add_short_len_out)
__array_add_short_continue_2:
E :MSTORE(array_add_short_len_out)

array_add_short_end:
$ => RR :MLOAD(array_add_short_RR)
Expand Down
Loading

0 comments on commit 261fd15

Please sign in to comment.