<% function signL(reg, label_pos, label_neg) { %>
|
|
<% for (let i=n64-1; i>=0; i--) { %>
|
|
mov rax, [<%=reg%> + <%= 8+(i*8) %>]
|
|
cmp [half + <%= (i*8) %>], rax ; comare with (q-1)/2
|
|
jc <%=label_neg%> ; half<rax => e1-e2 is neg => e1 < e2
|
|
<% if (i>0) { %>
|
|
jnz <%=label_pos%> ; half>rax => e1 -e2 is pos => e1 > e2
|
|
<% } else { %>
|
|
jmp <%=label_pos%>
|
|
<% } %>
|
|
<% } %>
|
|
<% } %>
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; rgt - Raw Greater Than
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; returns in ax 1 id *rsi > *rdx
|
|
; Params:
|
|
; rsi <= Pointer to element 1
|
|
; rdx <= Pointer to element 2
|
|
; rax <= Return 1 or 0
|
|
; Modified Registers:
|
|
; r8, r9, rax
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
<%=name%>_rgt:
|
|
mov r8, [rsi]
|
|
mov r9, [rdx]
|
|
bt r8, 63 ; Check if is short first operand
|
|
jc rgt_l1
|
|
bt r9, 63 ; Check if is short second operand
|
|
jc rgt_s1l2
|
|
|
|
rgt_s1s2: ; Both operands are short
|
|
cmp r8d, r9d
|
|
jg rgt_ret1
|
|
jmp rgt_ret0
|
|
|
|
|
|
rgt_l1:
|
|
bt r9, 63 ; Check if is short second operand
|
|
jc rgt_l1l2
|
|
|
|
;;;;;;;;
|
|
rgt_l1s2:
|
|
bt r8, 62 ; check if montgomery first
|
|
jc rgt_l1ms2
|
|
rgt_l1ns2:
|
|
<%= global.toLong_b() %>
|
|
jmp rgtL1L2
|
|
|
|
rgt_l1ms2:
|
|
<%= global.toLong_b() %>
|
|
<%= global.fromMont_a() %>
|
|
jmp rgtL1L2
|
|
|
|
|
|
;;;;;;;;
|
|
rgt_s1l2:
|
|
bt r9, 62 ; check if montgomery second
|
|
jc rgt_s1l2m
|
|
rgt_s1l2n:
|
|
<%= global.toLong_a() %>
|
|
jmp rgtL1L2
|
|
|
|
rgt_s1l2m:
|
|
<%= global.toLong_a() %>
|
|
<%= global.fromMont_b() %>
|
|
jmp rgtL1L2
|
|
|
|
;;;;
|
|
rgt_l1l2:
|
|
bt r8, 62 ; check if montgomery first
|
|
jc rgt_l1ml2
|
|
rgt_l1nl2:
|
|
bt r9, 62 ; check if montgomery second
|
|
jc rgt_l1nl2m
|
|
rgt_l1nl2n:
|
|
jmp rgtL1L2
|
|
|
|
rgt_l1nl2m:
|
|
<%= global.fromMont_b() %>
|
|
jmp rgtL1L2
|
|
|
|
rgt_l1ml2:
|
|
bt r9, 62 ; check if montgomery second
|
|
jc rgt_l1ml2m
|
|
rgt_l1ml2n:
|
|
<%= global.fromMont_a() %>
|
|
jmp rgtL1L2
|
|
|
|
rgt_l1ml2m:
|
|
<%= global.fromMont_a() %>
|
|
<%= global.fromMont_b() %>
|
|
jmp rgtL1L2
|
|
|
|
|
|
;;;;;;
|
|
; rgtL1L2
|
|
;;;;;;
|
|
|
|
rgtL1L2:
|
|
<%= signL("rsi", "rgtl1l2_p1", "rgtl1l2_n1") %>
|
|
rgtl1l2_p1:
|
|
<%= signL("rdx", "rgtRawL1L2", "rgt_ret1") %>
|
|
|
|
rgtl1l2_n1:
|
|
<%= signL("rdx", "rgt_ret0", "rgtRawL1L2") %>
|
|
|
|
|
|
rgtRawL1L2:
|
|
<% for (let i=n64-1; i>=0; i--) { %>
|
|
mov rax, [rsi + <%= 8+(i*8) %>]
|
|
cmp [rdx + <%= 8+(i*8) %>], rax ; comare with (q-1)/2
|
|
jc rgt_ret1 ; rsi<rdx => 1st > 2nd
|
|
<% if (i>0) { %>
|
|
jnz rgt_ret0
|
|
<% } %>
|
|
<% } %>
|
|
|
|
rgt_ret0:
|
|
xor rax, rax
|
|
ret
|
|
rgt_ret1:
|
|
mov rax, 1
|
|
ret
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; rlt - Raw Less Than
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; returns in ax 1 id *rsi > *rdx
|
|
; Params:
|
|
; rsi <= Pointer to element 1
|
|
; rdx <= Pointer to element 2
|
|
; rax <= Return 1 or 0
|
|
; Modified Registers:
|
|
; r8, r9, rax
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
<%=name%>_rlt:
|
|
mov r8, [rsi]
|
|
mov r9, [rdx]
|
|
bt r8, 63 ; Check if is short first operand
|
|
jc rlt_l1
|
|
bt r9, 63 ; Check if is short second operand
|
|
jc rlt_s1l2
|
|
|
|
rlt_s1s2: ; Both operands are short
|
|
cmp r8d, r9d
|
|
jl rlt_ret1
|
|
jmp rlt_ret0
|
|
|
|
|
|
rlt_l1:
|
|
bt r9, 63 ; Check if is short second operand
|
|
jc rlt_l1l2
|
|
|
|
;;;;;;;;
|
|
rlt_l1s2:
|
|
bt r8, 62 ; check if montgomery first
|
|
jc rlt_l1ms2
|
|
rlt_l1ns2:
|
|
<%= global.toLong_b() %>
|
|
jmp rltL1L2
|
|
|
|
rlt_l1ms2:
|
|
<%= global.toLong_b() %>
|
|
<%= global.fromMont_a() %>
|
|
jmp rltL1L2
|
|
|
|
|
|
;;;;;;;;
|
|
rlt_s1l2:
|
|
bt r9, 62 ; check if montgomery second
|
|
jc rlt_s1l2m
|
|
rlt_s1l2n:
|
|
<%= global.toLong_a() %>
|
|
jmp rltL1L2
|
|
|
|
rlt_s1l2m:
|
|
<%= global.toLong_a() %>
|
|
<%= global.fromMont_b() %>
|
|
jmp rltL1L2
|
|
|
|
;;;;
|
|
rlt_l1l2:
|
|
bt r8, 62 ; check if montgomery first
|
|
jc rlt_l1ml2
|
|
rlt_l1nl2:
|
|
bt r9, 62 ; check if montgomery second
|
|
jc rlt_l1nl2m
|
|
rlt_l1nl2n:
|
|
jmp rltL1L2
|
|
|
|
rlt_l1nl2m:
|
|
<%= global.fromMont_b() %>
|
|
jmp rltL1L2
|
|
|
|
rlt_l1ml2:
|
|
bt r9, 62 ; check if montgomery second
|
|
jc rlt_l1ml2m
|
|
rlt_l1ml2n:
|
|
<%= global.fromMont_a() %>
|
|
jmp rltL1L2
|
|
|
|
rlt_l1ml2m:
|
|
<%= global.fromMont_a() %>
|
|
<%= global.fromMont_b() %>
|
|
jmp rltL1L2
|
|
|
|
|
|
;;;;;;
|
|
; rltL1L2
|
|
;;;;;;
|
|
|
|
rltL1L2:
|
|
<%= signL("rsi", "rltl1l2_p1", "rltl1l2_n1") %>
|
|
rltl1l2_p1:
|
|
<%= signL("rdx", "rltRawL1L2", "rlt_ret0") %>
|
|
|
|
rltl1l2_n1:
|
|
<%= signL("rdx", "rlt_ret1", "rltRawL1L2") %>
|
|
|
|
|
|
rltRawL1L2:
|
|
<% for (let i=n64-1; i>=0; i--) { %>
|
|
mov rax, [rsi + <%= 8+(i*8) %>]
|
|
cmp [rdx + <%= 8+(i*8) %>], rax ; comare with (q-1)/2
|
|
jc rlt_ret0 ; rsi<rdx => 1st > 2nd
|
|
jnz rlt_ret1
|
|
<% } %>
|
|
|
|
rlt_ret0:
|
|
xor rax, rax
|
|
ret
|
|
rlt_ret1:
|
|
mov rax, 1
|
|
ret
|
|
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; req - Raw Eq
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; returns in ax 1 id *rsi == *rdx
|
|
; Params:
|
|
; rsi <= Pointer to element 1
|
|
; rdx <= Pointer to element 2
|
|
; rax <= Return 1 or 0
|
|
; Modified Registers:
|
|
; r8, r9, rax
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
<%=name%>_req:
|
|
mov r8, [rsi]
|
|
mov r9, [rdx]
|
|
bt r8, 63 ; Check if is short first operand
|
|
jc req_l1
|
|
bt r9, 63 ; Check if is short second operand
|
|
jc req_s1l2
|
|
|
|
req_s1s2: ; Both operands are short
|
|
cmp r8d, r9d
|
|
je req_ret1
|
|
jmp req_ret0
|
|
|
|
|
|
req_l1:
|
|
bt r9, 63 ; Check if is short second operand
|
|
jc req_l1l2
|
|
|
|
;;;;;;;;
|
|
req_l1s2:
|
|
bt r8, 62 ; check if montgomery first
|
|
jc req_l1ms2
|
|
req_l1ns2:
|
|
<%= global.toLong_b() %>
|
|
jmp reqL1L2
|
|
|
|
req_l1ms2:
|
|
<%= global.toMont_b() %>
|
|
jmp reqL1L2
|
|
|
|
|
|
;;;;;;;;
|
|
req_s1l2:
|
|
bt r9, 62 ; check if montgomery second
|
|
jc req_s1l2m
|
|
req_s1l2n:
|
|
<%= global.toLong_a() %>
|
|
jmp reqL1L2
|
|
|
|
req_s1l2m:
|
|
<%= global.toMont_a() %>
|
|
jmp reqL1L2
|
|
|
|
;;;;
|
|
req_l1l2:
|
|
bt r8, 62 ; check if montgomery first
|
|
jc req_l1ml2
|
|
req_l1nl2:
|
|
bt r9, 62 ; check if montgomery second
|
|
jc req_l1nl2m
|
|
req_l1nl2n:
|
|
jmp reqL1L2
|
|
|
|
req_l1nl2m:
|
|
<%= global.toMont_a() %>
|
|
jmp reqL1L2
|
|
|
|
req_l1ml2:
|
|
bt r9, 62 ; check if montgomery second
|
|
jc req_l1ml2m
|
|
req_l1ml2n:
|
|
<%= global.toMont_b() %>
|
|
jmp reqL1L2
|
|
|
|
req_l1ml2m:
|
|
jmp reqL1L2
|
|
|
|
|
|
;;;;;;
|
|
; eqL1L2
|
|
;;;;;;
|
|
|
|
reqL1L2:
|
|
<% for (let i=0; i<n64; i++) { %>
|
|
mov rax, [rsi + <%= 8+(i*8) %>]
|
|
cmp [rdx + <%= 8+(i*8) %>], rax
|
|
jne req_ret0 ; rsi<rdi => 1st > 2nd
|
|
<% } %>
|
|
|
|
req_ret1:
|
|
mov rax, 1
|
|
ret
|
|
|
|
req_ret0:
|
|
xor rax, rax
|
|
ret
|
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; gt
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; Compares two elements of any kind
|
|
; Params:
|
|
; rsi <= Pointer to element 1
|
|
; rdx <= Pointer to element 2
|
|
; rdi <= Pointer to result can be zero or one.
|
|
; Modified Registers:
|
|
; rax, rcx
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
<%=name%>_gt:
|
|
call <%=name%>_rgt
|
|
mov [rdi], rax
|
|
ret
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; lt
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; Compares two elements of any kind
|
|
; Params:
|
|
; rsi <= Pointer to element 1
|
|
; rdx <= Pointer to element 2
|
|
; rdi <= Pointer to result can be zero or one.
|
|
; Modified Registers:
|
|
; rax, rcx
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
<%=name%>_lt:
|
|
call <%=name%>_rlt
|
|
mov [rdi], rax
|
|
ret
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; eq
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; Compares two elements of any kind
|
|
; Params:
|
|
; rsi <= Pointer to element 1
|
|
; rdx <= Pointer to element 2
|
|
; rdi <= Pointer to result can be zero or one.
|
|
; Modified Registers:
|
|
; rax, rcx
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
<%=name%>_eq:
|
|
call <%=name%>_req
|
|
mov [rdi], rax
|
|
ret
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; neq
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; Compares two elements of any kind
|
|
; Params:
|
|
; rsi <= Pointer to element 1
|
|
; rdx <= Pointer to element 2
|
|
; rdi <= Pointer to result can be zero or one.
|
|
; Modified Registers:
|
|
; rax, rcx
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
<%=name%>_neq:
|
|
call <%=name%>_req
|
|
xor rax, 1
|
|
mov [rdi], rax
|
|
ret
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; geq
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; Compares two elements of any kind
|
|
; Params:
|
|
; rsi <= Pointer to element 1
|
|
; rdx <= Pointer to element 2
|
|
; rdi <= Pointer to result can be zero or one.
|
|
; Modified Registers:
|
|
; rax, rcx
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
<%=name%>_geq:
|
|
call <%=name%>_rlt
|
|
xor rax, 1
|
|
mov [rdi], rax
|
|
ret
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; leq
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
; Compares two elements of any kind
|
|
; Params:
|
|
; rsi <= Pointer to element 1
|
|
; rdx <= Pointer to element 2
|
|
; rdi <= Pointer to result can be zero or one.
|
|
; Modified Registers:
|
|
; rax, rcx
|
|
;;;;;;;;;;;;;;;;;;;;;;
|
|
<%=name%>_leq:
|
|
call <%=name%>_rgt
|
|
xor rax, 1
|
|
mov [rdi], rax
|
|
ret
|