summaryrefslogtreecommitdiff
path: root/ext/ed25519-amd64-asm/fe25519_invert.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/ed25519-amd64-asm/fe25519_invert.c')
-rw-r--r--ext/ed25519-amd64-asm/fe25519_invert.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/ext/ed25519-amd64-asm/fe25519_invert.c b/ext/ed25519-amd64-asm/fe25519_invert.c
new file mode 100644
index 00000000..a46d141f
--- /dev/null
+++ b/ext/ed25519-amd64-asm/fe25519_invert.c
@@ -0,0 +1,60 @@
+#include "fe25519.h"
+
+void fe25519_invert(fe25519 *r, const fe25519 *x)
+{
+ fe25519 z2;
+ fe25519 z9;
+ fe25519 z11;
+ fe25519 z2_5_0;
+ fe25519 z2_10_0;
+ fe25519 z2_20_0;
+ fe25519 z2_50_0;
+ fe25519 z2_100_0;
+ fe25519 t;
+ int i;
+
+ /* 2 */ fe25519_square(&z2,x);
+ /* 4 */ fe25519_square(&t,&z2);
+ /* 8 */ fe25519_square(&t,&t);
+ /* 9 */ fe25519_mul(&z9,&t,x);
+ /* 11 */ fe25519_mul(&z11,&z9,&z2);
+ /* 22 */ fe25519_square(&t,&z11);
+ /* 2^5 - 2^0 = 31 */ fe25519_mul(&z2_5_0,&t,&z9);
+
+ /* 2^6 - 2^1 */ fe25519_square(&t,&z2_5_0);
+ /* 2^20 - 2^10 */ for (i = 1;i < 5;i++) { fe25519_square(&t,&t); }
+ /* 2^10 - 2^0 */ fe25519_mul(&z2_10_0,&t,&z2_5_0);
+
+ /* 2^11 - 2^1 */ fe25519_square(&t,&z2_10_0);
+ /* 2^20 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); }
+ /* 2^20 - 2^0 */ fe25519_mul(&z2_20_0,&t,&z2_10_0);
+
+ /* 2^21 - 2^1 */ fe25519_square(&t,&z2_20_0);
+ /* 2^40 - 2^20 */ for (i = 1;i < 20;i++) { fe25519_square(&t,&t); }
+ /* 2^40 - 2^0 */ fe25519_mul(&t,&t,&z2_20_0);
+
+ /* 2^41 - 2^1 */ fe25519_square(&t,&t);
+ /* 2^50 - 2^10 */ for (i = 1;i < 10;i++) { fe25519_square(&t,&t); }
+ /* 2^50 - 2^0 */ fe25519_mul(&z2_50_0,&t,&z2_10_0);
+
+ /* 2^51 - 2^1 */ fe25519_square(&t,&z2_50_0);
+ /* 2^100 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); }
+ /* 2^100 - 2^0 */ fe25519_mul(&z2_100_0,&t,&z2_50_0);
+
+ /* 2^101 - 2^1 */ fe25519_square(&t,&z2_100_0);
+ /* 2^200 - 2^100 */ for (i = 1;i < 100;i++) { fe25519_square(&t,&t); }
+ /* 2^200 - 2^0 */ fe25519_mul(&t,&t,&z2_100_0);
+
+ /* 2^201 - 2^1 */ fe25519_square(&t,&t);
+ /* 2^250 - 2^50 */ for (i = 1;i < 50;i++) { fe25519_square(&t,&t); }
+ /* 2^250 - 2^0 */ fe25519_mul(&t,&t,&z2_50_0);
+
+ /* 2^251 - 2^1 */ fe25519_square(&t,&t);
+ /* 2^252 - 2^2 */ fe25519_square(&t,&t);
+ /* 2^253 - 2^3 */ fe25519_square(&t,&t);
+
+ /* 2^254 - 2^4 */ fe25519_square(&t,&t);
+
+ /* 2^255 - 2^5 */ fe25519_square(&t,&t);
+ /* 2^255 - 21 */ fe25519_mul(r,&t,&z11);
+}