Browse Source

toInt and isTrue in assembly

feature/witness_bin
Jordi Baylina 4 years ago
parent
commit
20058a38d6
No known key found for this signature in database GPG Key ID: 7480C80C1BE43112
13 changed files with 242 additions and 64 deletions
  1. +52
    -0
      c/buildasm/copy.asm.ejs
  2. +128
    -0
      c/buildasm/fr.asm
  3. +3
    -0
      c/buildasm/fr.asm.ejs
  4. +2
    -27
      c/buildasm/fr.c
  5. +2
    -27
      c/buildasm/fr.c.ejs
  6. +10
    -3
      c/buildasm/fr.h
  7. +10
    -3
      c/buildasm/fr.h.ejs
  8. BIN
      c/buildasm/fr.o
  9. +15
    -0
      c/buildasm/logicalops.asm.ejs
  10. +18
    -2
      c/buildasm/main.c
  11. +1
    -0
      c/buildasm/montgomery.asm.ejs
  12. +1
    -0
      c/buildasm/tester.cpp
  13. +0
    -2
      test/fieldasm.js

+ 52
- 0
c/buildasm/copy.asm.ejs

@ -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

+ 128
- 0
c/buildasm/fr.asm

@ -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

+ 3
- 0
c/buildasm/fr.asm.ejs

@ -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

+ 2
- 27
c/buildasm/fr.c

@ -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) {
if (!(pE->type & Fr_LONG)) return pE->shortVal != 0;
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);
}
}
void Fr_fail() {
assert(false);
} }

+ 2
- 27
c/buildasm/fr.c.ejs

@ -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) {
if (!(pE->type & <%=name%>_LONG)) return pE->shortVal != 0;
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);
}
}
void <%=name%>_fail() {
assert(false);
} }

+ 10
- 3
c/buildasm/fr.h

@ -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

+ 10
- 3
c/buildasm/fr.h.ejs

@ -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


+ 15
- 0
c/buildasm/logicalops.asm.ejs

@ -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

+ 18
- 2
c/buildasm/main.c

@ -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]);
} }

+ 1
- 0
c/buildasm/montgomery.asm.ejs

@ -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

+ 1
- 0
c/buildasm/tester.cpp

@ -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;

+ 0
- 2
test/fieldasm.js

@ -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);

Loading…
Cancel
Save