// File: msotoodeh[P]asymmetric-passwords/common/curve25519/curve25519_mehdi.c
// Function: ecp_Inverse
void ecp_Inverse(U32 *out, const U32 *z) 
{
  int i;
  U32 t0[8],t1[8],z2[8],z9[8],z11[8];
  U32 z2_5_0[8],z2_10_0[8],z2_20_0[8],z2_50_0[8],z2_100_0[8];

  /* 2 */               ecp_SqrReduce(z2,z);
  /* 4 */               ecp_SqrReduce(t1,z2);
  /* 8 */               ecp_SqrReduce(t0,t1);
  /* 9 */               ecp_MulReduce(z9,t0,z);
  /* 11 */              ecp_MulReduce(z11,z9,z2);
  /* 22 */              ecp_SqrReduce(t0,z11);
  /* 2^5 - 2^0 = 31 */  ecp_MulReduce(z2_5_0,t0,z9);

  /* 2^6 - 2^1 */       ecp_SqrReduce(t0,z2_5_0);
  /* 2^7 - 2^2 */       ecp_SqrReduce(t1,t0);
  /* 2^8 - 2^3 */       ecp_SqrReduce(t0,t1);
  /* 2^9 - 2^4 */       ecp_SqrReduce(t1,t0);
  /* 2^10 - 2^5 */      ecp_SqrReduce(t0,t1);
  /* 2^10 - 2^0 */      ecp_MulReduce(z2_10_0,t0,z2_5_0);

  /* 2^11 - 2^1 */      ecp_SqrReduce(t0,z2_10_0);
  /* 2^12 - 2^2 */      ecp_SqrReduce(t1,t0);
  /* 2^20 - 2^10 */     for (i = 2;i < 10;i += 2) { 
                            ecp_SqrReduce(t0,t1); 
                            ecp_SqrReduce(t1,t0); }
  /* 2^20 - 2^0 */      ecp_MulReduce(z2_20_0,t1,z2_10_0);

  /* 2^21 - 2^1 */      ecp_SqrReduce(t0,z2_20_0);
  /* 2^22 - 2^2 */      ecp_SqrReduce(t1,t0);
  /* 2^40 - 2^20 */     for (i = 2;i < 20;i += 2) { 
                            ecp_SqrReduce(t0,t1); 
                            ecp_SqrReduce(t1,t0); }
  /* 2^40 - 2^0 */      ecp_MulReduce(t0,t1,z2_20_0);

  /* 2^41 - 2^1 */      ecp_SqrReduce(t1,t0);
  /* 2^42 - 2^2 */      ecp_SqrReduce(t0,t1);
  /* 2^50 - 2^10 */     for (i = 2;i < 10;i += 2) { 
                            ecp_SqrReduce(t1,t0); 
                            ecp_SqrReduce(t0,t1); }
  /* 2^50 - 2^0 */      ecp_MulReduce(z2_50_0,t0,z2_10_0);

  /* 2^51 - 2^1 */      ecp_SqrReduce(t0,z2_50_0);
  /* 2^52 - 2^2 */      ecp_SqrReduce(t1,t0);
  /* 2^100 - 2^50 */    for (i = 2;i < 50;i += 2) { 
                            ecp_SqrReduce(t0,t1); 
                            ecp_SqrReduce(t1,t0); }
  /* 2^100 - 2^0 */     ecp_MulReduce(z2_100_0,t1,z2_50_0);

  /* 2^101 - 2^1 */     ecp_SqrReduce(t1,z2_100_0);
  /* 2^102 - 2^2 */     ecp_SqrReduce(t0,t1);
  /* 2^200 - 2^100 */   for (i = 2;i < 100;i += 2) { 
                            ecp_SqrReduce(t1,t0); 
                            ecp_SqrReduce(t0,t1); }
  /* 2^200 - 2^0 */     ecp_MulReduce(t1,t0,z2_100_0);

  /* 2^201 - 2^1 */     ecp_SqrReduce(t0,t1);
  /* 2^202 - 2^2 */     ecp_SqrReduce(t1,t0);
  /* 2^250 - 2^50 */    for (i = 2;i < 50;i += 2) { 
                            ecp_SqrReduce(t0,t1); 
                            ecp_SqrReduce(t1,t0); }
  /* 2^250 - 2^0 */     ecp_MulReduce(t0,t1,z2_50_0);

  /* 2^251 - 2^1 */     ecp_SqrReduce(t1,t0);
  /* 2^252 - 2^2 */     ecp_SqrReduce(t0,t1);
  /* 2^253 - 2^3 */     ecp_SqrReduce(t1,t0);
  /* 2^254 - 2^4 */     ecp_SqrReduce(t0,t1);
  /* 2^255 - 2^5 */     ecp_SqrReduce(t1,t0);
  /* 2^255 - 21 */      ecp_MulReduce(out,t1,z11);
}

// Assembly:
subq $0x158, %rsp            # imm = 0x158
movq %rdi, 0x150(%rsp)
movq %rsi, 0x148(%rsp)
leaq 0xe0(%rsp), %rdi
movq 0x148(%rsp), %rsi
callq 0x410e10
leaq 0x100(%rsp), %rdi
leaq 0xe0(%rsp), %rsi
callq 0x410e10
leaq 0x120(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x410e10
leaq 0xc0(%rsp), %rdi
leaq 0x120(%rsp), %rsi
movq 0x148(%rsp), %rdx
callq 0x410910
leaq 0xa0(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
leaq 0xe0(%rsp), %rdx
callq 0x410910
leaq 0x120(%rsp), %rdi
leaq 0xa0(%rsp), %rsi
callq 0x410e10
leaq 0x80(%rsp), %rdi
leaq 0x120(%rsp), %rsi
leaq 0xc0(%rsp), %rdx
callq 0x410910
leaq 0x120(%rsp), %rdi
leaq 0x80(%rsp), %rsi
callq 0x410e10
leaq 0x100(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x410e10
leaq 0x120(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x410e10
leaq 0x100(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x410e10
leaq 0x120(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x410e10
leaq 0x60(%rsp), %rdi
leaq 0x120(%rsp), %rsi
leaq 0x80(%rsp), %rdx
callq 0x410910
leaq 0x120(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x410e10
leaq 0x100(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x410e10
movl $0x2, 0x144(%rsp)
cmpl $0xa, 0x144(%rsp)
jge 0x4110fe
leaq 0x120(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x410e10
leaq 0x100(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x410e10
movl 0x144(%rsp), %eax
addl $0x2, %eax
movl %eax, 0x144(%rsp)
jmp 0x4110b7
leaq 0x40(%rsp), %rdi
leaq 0x100(%rsp), %rsi
leaq 0x60(%rsp), %rdx
callq 0x410910
leaq 0x120(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x410e10
leaq 0x100(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x410e10
movl $0x2, 0x144(%rsp)
cmpl $0x14, 0x144(%rsp)
jge 0x41118e
leaq 0x120(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x410e10
leaq 0x100(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x410e10
movl 0x144(%rsp), %eax
addl $0x2, %eax
movl %eax, 0x144(%rsp)
jmp 0x411147
leaq 0x120(%rsp), %rdi
leaq 0x100(%rsp), %rsi
leaq 0x40(%rsp), %rdx
callq 0x410910
leaq 0x100(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x410e10
leaq 0x120(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x410e10
movl $0x2, 0x144(%rsp)
cmpl $0xa, 0x144(%rsp)
jge 0x411224
leaq 0x100(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x410e10
leaq 0x120(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x410e10
movl 0x144(%rsp), %eax
addl $0x2, %eax
movl %eax, 0x144(%rsp)
jmp 0x4111dd
leaq 0x20(%rsp), %rdi
leaq 0x120(%rsp), %rsi
leaq 0x60(%rsp), %rdx
callq 0x410910
leaq 0x120(%rsp), %rdi
leaq 0x20(%rsp), %rsi
callq 0x410e10
leaq 0x100(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x410e10
movl $0x2, 0x144(%rsp)
cmpl $0x32, 0x144(%rsp)
jge 0x4112b4
leaq 0x120(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x410e10
leaq 0x100(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x410e10
movl 0x144(%rsp), %eax
addl $0x2, %eax
movl %eax, 0x144(%rsp)
jmp 0x41126d
movq %rsp, %rdi
leaq 0x100(%rsp), %rsi
leaq 0x20(%rsp), %rdx
callq 0x410910
leaq 0x100(%rsp), %rdi
movq %rsp, %rsi
callq 0x410e10
leaq 0x120(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x410e10
movl $0x2, 0x144(%rsp)
cmpl $0x64, 0x144(%rsp)
jge 0x411340
leaq 0x100(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x410e10
leaq 0x120(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x410e10
movl 0x144(%rsp), %eax
addl $0x2, %eax
movl %eax, 0x144(%rsp)
jmp 0x4112f9
leaq 0x100(%rsp), %rdi
leaq 0x120(%rsp), %rsi
movq %rsp, %rdx
callq 0x410910
leaq 0x120(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x410e10
leaq 0x100(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x410e10
movl $0x2, 0x144(%rsp)
cmpl $0x32, 0x144(%rsp)
jge 0x4113d4
leaq 0x120(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x410e10
leaq 0x100(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x410e10
movl 0x144(%rsp), %eax
addl $0x2, %eax
movl %eax, 0x144(%rsp)
jmp 0x41138d
leaq 0x120(%rsp), %rdi
leaq 0x100(%rsp), %rsi
leaq 0x20(%rsp), %rdx
callq 0x410910
leaq 0x100(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x410e10
leaq 0x120(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x410e10
leaq 0x100(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x410e10
leaq 0x120(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x410e10
leaq 0x100(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x410e10
movq 0x150(%rsp), %rdi
leaq 0x100(%rsp), %rsi
leaq 0xa0(%rsp), %rdx
callq 0x410910
addq $0x158, %rsp            # imm = 0x158
retq
nopl (%rax)