mirror of
https://github.com/arnaucube/circom.git
synced 2026-02-06 18:56:40 +01:00
toInt and isTrue in assembly
This commit is contained in:
@@ -79,3 +79,55 @@ u64toLong_adjust_neg:
|
|||||||
mov [rdi + <%= (i+1)*8 %>], rax
|
mov [rdi + <%= (i+1)*8 %>], rax
|
||||||
<% } %>
|
<% } %>
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
; toInt
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
; Convert a 64 bit integer to a long format field element
|
||||||
|
; Params:
|
||||||
|
; rsi <= Pointer to the element
|
||||||
|
; Returs:
|
||||||
|
; rax <= The value
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
<%=name%>_toInt:
|
||||||
|
mov rax, [rdi]
|
||||||
|
bt rax, 63
|
||||||
|
jc <%=name%>_long
|
||||||
|
movsx rax, eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
<%=name%>_long:
|
||||||
|
mov rax, [rdi + 8]
|
||||||
|
mov rcx, rax
|
||||||
|
shr rcx, 31
|
||||||
|
jnz <%=name%>_longNeg
|
||||||
|
<% for (let i=1; i< n64; i++) { %>
|
||||||
|
mov rcx, [rdi + <%= i*8+8 %>]
|
||||||
|
test rcx, rcx
|
||||||
|
jnz <%=name%>_longNeg
|
||||||
|
<% } %>
|
||||||
|
ret
|
||||||
|
|
||||||
|
<%=name%>_longNeg:
|
||||||
|
mov rax, [rdi + 8]
|
||||||
|
sub rax, [q]
|
||||||
|
jnc <%=name%>_longErr
|
||||||
|
<% for (let i=1; i<n64; i++) { %>
|
||||||
|
mov rcx, [rdi + <%= i*8+8 %>]
|
||||||
|
sbb rcx, [q + <%= i*8 %>]
|
||||||
|
jnc <%=name%>_longErr
|
||||||
|
<% } %>
|
||||||
|
mov rcx, rax
|
||||||
|
sar rcx, 31
|
||||||
|
add rcx, 1
|
||||||
|
jnz <%=name%>_longErr
|
||||||
|
ret
|
||||||
|
|
||||||
|
<%=name%>_longErr:
|
||||||
|
push rdi
|
||||||
|
mov rdi, 0
|
||||||
|
call <%=name%>_fail
|
||||||
|
pop rdi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,10 @@
|
|||||||
global Fr_toNormal
|
global Fr_toNormal
|
||||||
global Fr_toLongNormal
|
global Fr_toLongNormal
|
||||||
global Fr_toMontgomery
|
global Fr_toMontgomery
|
||||||
|
global Fr_toInt
|
||||||
|
global Fr_isTrue
|
||||||
global Fr_q
|
global Fr_q
|
||||||
|
extern Fr_fail
|
||||||
DEFAULT REL
|
DEFAULT REL
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
@@ -150,6 +153,74 @@ u64toLong_adjust_neg:
|
|||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
; toInt
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
; Convert a 64 bit integer to a long format field element
|
||||||
|
; Params:
|
||||||
|
; rsi <= Pointer to the element
|
||||||
|
; Returs:
|
||||||
|
; rax <= The value
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
Fr_toInt:
|
||||||
|
mov rax, [rdi]
|
||||||
|
bt rax, 63
|
||||||
|
jc Fr_long
|
||||||
|
movsx rax, eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
Fr_long:
|
||||||
|
mov rax, [rdi + 8]
|
||||||
|
mov rcx, rax
|
||||||
|
shr rcx, 31
|
||||||
|
jnz Fr_longNeg
|
||||||
|
|
||||||
|
mov rcx, [rdi + 16]
|
||||||
|
test rcx, rcx
|
||||||
|
jnz Fr_longNeg
|
||||||
|
|
||||||
|
mov rcx, [rdi + 24]
|
||||||
|
test rcx, rcx
|
||||||
|
jnz Fr_longNeg
|
||||||
|
|
||||||
|
mov rcx, [rdi + 32]
|
||||||
|
test rcx, rcx
|
||||||
|
jnz Fr_longNeg
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
Fr_longNeg:
|
||||||
|
mov rax, [rdi + 8]
|
||||||
|
sub rax, [q]
|
||||||
|
jnc Fr_longErr
|
||||||
|
|
||||||
|
mov rcx, [rdi + 16]
|
||||||
|
sbb rcx, [q + 8]
|
||||||
|
jnc Fr_longErr
|
||||||
|
|
||||||
|
mov rcx, [rdi + 24]
|
||||||
|
sbb rcx, [q + 16]
|
||||||
|
jnc Fr_longErr
|
||||||
|
|
||||||
|
mov rcx, [rdi + 32]
|
||||||
|
sbb rcx, [q + 24]
|
||||||
|
jnc Fr_longErr
|
||||||
|
|
||||||
|
mov rcx, rax
|
||||||
|
sar rcx, 31
|
||||||
|
add rcx, 1
|
||||||
|
jnz Fr_longErr
|
||||||
|
ret
|
||||||
|
|
||||||
|
Fr_longErr:
|
||||||
|
push rdi
|
||||||
|
mov rdi, 0
|
||||||
|
call Fr_fail
|
||||||
|
pop rdi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1432,6 +1503,7 @@ toLongNormal_fromShort:
|
|||||||
movsx rsi, eax
|
movsx rsi, eax
|
||||||
call rawCopyS2L
|
call rawCopyS2L
|
||||||
mov rsi, r8 ; recover rsi
|
mov rsi, r8 ; recover rsi
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -5699,6 +5771,62 @@ lnot_retOne:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
; isTrue
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
; Convert a 64 bit integer to a long format field element
|
||||||
|
; Params:
|
||||||
|
; rsi <= Pointer to the element
|
||||||
|
; Returs:
|
||||||
|
; rax <= 1 if true 0 if false
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
Fr_isTrue:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
mov rax, [rdi]
|
||||||
|
bt rax, 63
|
||||||
|
jc tmp_64
|
||||||
|
|
||||||
|
test eax, eax
|
||||||
|
jz retZero_66
|
||||||
|
jmp retOne_65
|
||||||
|
|
||||||
|
tmp_64:
|
||||||
|
|
||||||
|
mov rax, [rdi + 8]
|
||||||
|
test rax, rax
|
||||||
|
jnz retOne_65
|
||||||
|
|
||||||
|
mov rax, [rdi + 16]
|
||||||
|
test rax, rax
|
||||||
|
jnz retOne_65
|
||||||
|
|
||||||
|
mov rax, [rdi + 24]
|
||||||
|
test rax, rax
|
||||||
|
jnz retOne_65
|
||||||
|
|
||||||
|
mov rax, [rdi + 32]
|
||||||
|
test rax, rax
|
||||||
|
jnz retOne_65
|
||||||
|
|
||||||
|
|
||||||
|
retZero_66:
|
||||||
|
mov qword rax, 0
|
||||||
|
jmp done_67
|
||||||
|
|
||||||
|
retOne_65:
|
||||||
|
mov qword rax, 1
|
||||||
|
|
||||||
|
done_67:
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
section .data
|
section .data
|
||||||
|
|||||||
@@ -23,7 +23,10 @@
|
|||||||
global <%=name%>_toNormal
|
global <%=name%>_toNormal
|
||||||
global <%=name%>_toLongNormal
|
global <%=name%>_toLongNormal
|
||||||
global <%=name%>_toMontgomery
|
global <%=name%>_toMontgomery
|
||||||
|
global <%=name%>_toInt
|
||||||
|
global <%=name%>_isTrue
|
||||||
global <%=name%>_q
|
global <%=name%>_q
|
||||||
|
extern <%=name%>_fail
|
||||||
DEFAULT REL
|
DEFAULT REL
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
|
|||||||
@@ -179,32 +179,7 @@ void Fr_div(PFrElement r, PFrElement a, PFrElement b) {
|
|||||||
Fr_mul(r, a, &tmp);
|
Fr_mul(r, a, &tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Fr_isTrue(PFrElement pE) {
|
void Fr_fail() {
|
||||||
if (!(pE->type & Fr_LONG)) return pE->shortVal != 0;
|
assert(false);
|
||||||
for (int i=0; i< Fr_N64; i++) {
|
|
||||||
if (pE->longVal[i]) return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Fr_toInt(PFrElement pE) {
|
|
||||||
Fr_toNormal(pE);
|
|
||||||
if (!(pE->type & Fr_LONG)) {
|
|
||||||
return pE->shortVal;
|
|
||||||
} else {
|
|
||||||
mpz_t ma;
|
|
||||||
mpz_init(ma);
|
|
||||||
Fr_toMpz(ma, pE);
|
|
||||||
if (mpz_fits_sint_p(ma)) {
|
|
||||||
return mpz_get_si(ma);
|
|
||||||
}
|
|
||||||
|
|
||||||
mpz_sub(ma, ma, q);
|
|
||||||
if (mpz_fits_sint_p(ma)) {
|
|
||||||
return mpz_get_si(ma);
|
|
||||||
} else {
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -179,32 +179,7 @@ void <%=name%>_div(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b
|
|||||||
<%=name%>_mul(r, a, &tmp);
|
<%=name%>_mul(r, a, &tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
int <%=name%>_isTrue(P<%=name%>Element pE) {
|
void <%=name%>_fail() {
|
||||||
if (!(pE->type & <%=name%>_LONG)) return pE->shortVal != 0;
|
assert(false);
|
||||||
for (int i=0; i< <%=name%>_N64; i++) {
|
|
||||||
if (pE->longVal[i]) return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int <%=name%>_toInt(P<%=name%>Element pE) {
|
|
||||||
Fr_toNormal(pE);
|
|
||||||
if (!(pE->type & <%=name%>_LONG)) {
|
|
||||||
return pE->shortVal;
|
|
||||||
} else {
|
|
||||||
mpz_t ma;
|
|
||||||
mpz_init(ma);
|
|
||||||
<%=name%>_toMpz(ma, pE);
|
|
||||||
if (mpz_fits_sint_p(ma)) {
|
|
||||||
return mpz_get_si(ma);
|
|
||||||
}
|
|
||||||
|
|
||||||
mpz_sub(ma, ma, q);
|
|
||||||
if (mpz_fits_sint_p(ma)) {
|
|
||||||
return mpz_get_si(ma);
|
|
||||||
} else {
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,16 @@ extern "C" void Fr_lnot(PFrElement r, PFrElement a);
|
|||||||
extern "C" void Fr_toNormal(PFrElement pE);
|
extern "C" void Fr_toNormal(PFrElement pE);
|
||||||
extern "C" void Fr_toLongNormal(PFrElement pE);
|
extern "C" void Fr_toLongNormal(PFrElement pE);
|
||||||
extern "C" void Fr_toMontgomery(PFrElement pE);
|
extern "C" void Fr_toMontgomery(PFrElement pE);
|
||||||
|
|
||||||
|
extern "C" int Fr_isTrue(PFrElement pE);
|
||||||
|
extern "C" int Fr_toInt(PFrElement pE);
|
||||||
|
|
||||||
|
extern "C" void Fr_fail();
|
||||||
|
|
||||||
|
extern FrElement Fr_q;
|
||||||
|
|
||||||
|
// Pending functions to convert
|
||||||
|
|
||||||
void Fr_str2element(PFrElement pE, char const*s);
|
void Fr_str2element(PFrElement pE, char const*s);
|
||||||
char *Fr_element2str(PFrElement pE);
|
char *Fr_element2str(PFrElement pE);
|
||||||
void Fr_idiv(PFrElement r, PFrElement a, PFrElement b);
|
void Fr_idiv(PFrElement r, PFrElement a, PFrElement b);
|
||||||
@@ -46,12 +56,9 @@ void Fr_shl(PFrElement r, PFrElement a, PFrElement b);
|
|||||||
void Fr_shr(PFrElement r, PFrElement a, PFrElement b);
|
void Fr_shr(PFrElement r, PFrElement a, PFrElement b);
|
||||||
void Fr_pow(PFrElement r, PFrElement a, PFrElement b);
|
void Fr_pow(PFrElement r, PFrElement a, PFrElement b);
|
||||||
|
|
||||||
int Fr_isTrue(PFrElement pE);
|
|
||||||
int Fr_toInt(PFrElement pE);
|
|
||||||
|
|
||||||
void Fr_init();
|
void Fr_init();
|
||||||
|
|
||||||
extern FrElement Fr_q;
|
|
||||||
|
|
||||||
|
|
||||||
#endif // __FR_H
|
#endif // __FR_H
|
||||||
|
|||||||
@@ -36,6 +36,16 @@ extern "C" void <%=name%>_lnot(P<%=name%>Element r, P<%=name%>Element a);
|
|||||||
extern "C" void <%=name%>_toNormal(P<%=name%>Element pE);
|
extern "C" void <%=name%>_toNormal(P<%=name%>Element pE);
|
||||||
extern "C" void <%=name%>_toLongNormal(P<%=name%>Element pE);
|
extern "C" void <%=name%>_toLongNormal(P<%=name%>Element pE);
|
||||||
extern "C" void <%=name%>_toMontgomery(P<%=name%>Element pE);
|
extern "C" void <%=name%>_toMontgomery(P<%=name%>Element pE);
|
||||||
|
|
||||||
|
extern "C" int <%=name%>_isTrue(P<%=name%>Element pE);
|
||||||
|
extern "C" int <%=name%>_toInt(P<%=name%>Element pE);
|
||||||
|
|
||||||
|
extern "C" void <%=name%>_fail();
|
||||||
|
|
||||||
|
extern <%=name%>Element <%=name%>_q;
|
||||||
|
|
||||||
|
// Pending functions to convert
|
||||||
|
|
||||||
void <%=name%>_str2element(P<%=name%>Element pE, char const*s);
|
void <%=name%>_str2element(P<%=name%>Element pE, char const*s);
|
||||||
char *<%=name%>_element2str(P<%=name%>Element pE);
|
char *<%=name%>_element2str(P<%=name%>Element pE);
|
||||||
void <%=name%>_idiv(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b);
|
void <%=name%>_idiv(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b);
|
||||||
@@ -46,12 +56,9 @@ void <%=name%>_shl(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b
|
|||||||
void <%=name%>_shr(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b);
|
void <%=name%>_shr(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b);
|
||||||
void <%=name%>_pow(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b);
|
void <%=name%>_pow(P<%=name%>Element r, P<%=name%>Element a, P<%=name%>Element b);
|
||||||
|
|
||||||
int <%=name%>_isTrue(P<%=name%>Element pE);
|
|
||||||
int <%=name%>_toInt(P<%=name%>Element pE);
|
|
||||||
|
|
||||||
void <%=name%>_init();
|
void <%=name%>_init();
|
||||||
|
|
||||||
extern <%=name%>Element <%=name%>_q;
|
|
||||||
|
|
||||||
|
|
||||||
#endif // __<%=name.toUpperCase()%>_H
|
#endif // __<%=name.toUpperCase()%>_H
|
||||||
|
|||||||
BIN
c/buildasm/fr.o
BIN
c/buildasm/fr.o
Binary file not shown.
@@ -80,3 +80,18 @@ lnot_retOne:
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
; isTrue
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
; Convert a 64 bit integer to a long format field element
|
||||||
|
; Params:
|
||||||
|
; rsi <= Pointer to the element
|
||||||
|
; Returs:
|
||||||
|
; rax <= 1 if true 0 if false
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
<%=name%>_isTrue:
|
||||||
|
<%= isTrue("rax", "rdi") %>
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
#include "fr.h"
|
#include "fr.h"
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
Fr_init();
|
||||||
|
/*
|
||||||
FrElement a = { 0, Fr_LONGMONTGOMERY, {1,1,1,1}};
|
FrElement a = { 0, Fr_LONGMONTGOMERY, {1,1,1,1}};
|
||||||
FrElement b = { 0, Fr_LONGMONTGOMERY, {2,2,2,2}};
|
FrElement b = { 0, Fr_LONGMONTGOMERY, {2,2,2,2}};
|
||||||
|
|
||||||
/*
|
|
||||||
FrElement a={0x43e1f593f0000000ULL,0x2833e84879b97091ULL,0xb85045b68181585dULL,0x30644e72e131a029ULL};
|
FrElement a={0x43e1f593f0000000ULL,0x2833e84879b97091ULL,0xb85045b68181585dULL,0x30644e72e131a029ULL};
|
||||||
FrElement b = {3,0,0,0};
|
FrElement b = {3,0,0,0};
|
||||||
|
|
||||||
@@ -24,6 +26,7 @@ int main() {
|
|||||||
Fr_mul(&c,&a, &b);
|
Fr_mul(&c,&a, &b);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
FrElement a1[10];
|
FrElement a1[10];
|
||||||
FrElement a2[10];
|
FrElement a2[10];
|
||||||
for (int i=0; i<10; i++) {
|
for (int i=0; i<10; i++) {
|
||||||
@@ -43,6 +46,19 @@ int main() {
|
|||||||
free(c1);
|
free(c1);
|
||||||
free(c2);
|
free(c2);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
int tests[7] = { 0, 1, 2, -1, -2, 0x7FFFFFFF, (int)0x80000000};
|
||||||
|
for (int i=0; i<7;i++) {
|
||||||
|
FrElement a = { tests[i], Fr_SHORT, {0,0,0,0}};
|
||||||
|
Fr_toLongNormal(&a);
|
||||||
|
int b = Fr_toInt(&a);
|
||||||
|
int c = Fr_isTrue(&a);
|
||||||
|
printf("%d, %d, %d\n", tests[i], b, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
FrElement err = { 0, Fr_LONGMONTGOMERY, {1,1,1,1}};
|
||||||
|
Fr_toInt(&err);
|
||||||
|
|
||||||
// printf("%llu, %llu, %llu, %llu\n", c.longVal[0], c.longVal[1], c.longVal[2], c.longVal[3]);
|
// printf("%llu, %llu, %llu, %llu\n", c.longVal[0], c.longVal[1], c.longVal[2], c.longVal[3]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -338,4 +338,5 @@ toLongNormal_fromShort:
|
|||||||
movsx rsi, eax
|
movsx rsi, eax
|
||||||
call rawCopyS2L
|
call rawCopyS2L
|
||||||
mov rsi, r8 ; recover rsi
|
mov rsi, r8 ; recover rsi
|
||||||
|
ret
|
||||||
|
|
||||||
|
|||||||
@@ -139,6 +139,7 @@ void processLine(std::string &line) {
|
|||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
Fr_init();
|
||||||
fillMap();
|
fillMap();
|
||||||
std::string line;
|
std::string line;
|
||||||
int i=0;
|
int i=0;
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ const mnt6753r = new bigInt("418984909679189534023442147912406371281707099199539
|
|||||||
|
|
||||||
describe("field asm test", function () {
|
describe("field asm test", function () {
|
||||||
this.timeout(1000000000);
|
this.timeout(1000000000);
|
||||||
/*
|
|
||||||
it("bn128r add", async () => {
|
it("bn128r add", async () => {
|
||||||
const tv = buildTestVector2(bn128r, "add");
|
const tv = buildTestVector2(bn128r, "add");
|
||||||
await tester(bn128r, tv);
|
await tester(bn128r, tv);
|
||||||
@@ -255,7 +254,6 @@ describe("field asm test", function () {
|
|||||||
const tv = buildTestVector2(mnt6753q, "div");
|
const tv = buildTestVector2(mnt6753q, "div");
|
||||||
await tester(mnt6753q, tv);
|
await tester(mnt6753q, tv);
|
||||||
});
|
});
|
||||||
*/
|
|
||||||
it("bn128r square", async () => {
|
it("bn128r square", async () => {
|
||||||
const tv = buildTestVector1(bn128r, "square");
|
const tv = buildTestVector1(bn128r, "square");
|
||||||
await tester(bn128r, tv);
|
await tester(bn128r, tv);
|
||||||
|
|||||||
Reference in New Issue
Block a user