LLM4Binary/decompile-bench-makefile huggingface dataset:
// File: occivink[P]pyct/monocypher.cpp
// Function: extended_hash(unsigned char*, unsigned int, unsigned char const*, unsigned int)
static void extended_hash(u8       *digest, u32 digest_size,
                          const u8 *input , u32 input_size)
{
    crypto_blake2b_ctx ctx;
    crypto_blake2b_general_init(&ctx, MIN(digest_size, 64), 0, 0);
    blake_update_32            (&ctx, digest_size);
    crypto_blake2b_update      (&ctx, input, input_size);
    crypto_blake2b_final       (&ctx, digest);

    if (digest_size > 64) {
        // the conversion to u64 avoids integer overflow on
        // ludicrously big hash sizes.
        u32 r   = (u32)(((u64)digest_size + 31) >> 5) - 2;
        u32 i   =  1;
        u32 in  =  0;
        u32 out = 32;
        while (i < r) {
            // Input and output overlap. This is intentional
            crypto_blake2b(digest + out, digest + in, 64);
            i   +=  1;
            in  += 32;
            out += 32;
        }
        crypto_blake2b_general(digest + out, digest_size - (32 * r),
                               0, 0, // no key
                               digest + in , 64);
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x120, %rsp            # imm = 0x120
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq %rdx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
cmpl $0x40, -0xc(%rbp)
ja 0xa25a
movl -0xc(%rbp), %eax
movl %eax, -0x114(%rbp)
jmp 0xa267
movl $0x40, %eax
movl %eax, -0x114(%rbp)
jmp 0xa267
movl -0x114(%rbp), %eax
movl %eax, %eax
movl %eax, %esi
leaq -0x100(%rbp), %rdi
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rdx
callq 0x4ca0
movl -0xc(%rbp), %esi
leaq -0x100(%rbp), %rdi
callq 0xa1e0
movq -0x18(%rbp), %rsi
movl -0x1c(%rbp), %eax
movl %eax, %edx
leaq -0x100(%rbp), %rdi
callq 0x4e70
movq -0x8(%rbp), %rsi
leaq -0x100(%rbp), %rdi
callq 0x9a20
cmpl $0x40, -0xc(%rbp)
jbe 0xa393
movl -0xc(%rbp), %eax
addq $0x1f, %rax
shrq $0x5, %rax
subl $0x2, %eax
movl %eax, -0x104(%rbp)
movl $0x1, -0x108(%rbp)
movl $0x0, -0x10c(%rbp)
movl $0x20, -0x110(%rbp)
movl -0x108(%rbp), %eax
cmpl -0x104(%rbp), %eax
jae 0xa355
movq -0x8(%rbp), %rdi
movl -0x110(%rbp), %eax
addq %rax, %rdi
movq -0x8(%rbp), %rsi
movl -0x10c(%rbp), %eax
addq %rax, %rsi
movl $0x40, %edx
callq 0x9be0
movl -0x108(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x108(%rbp)
movl -0x10c(%rbp), %eax
addl $0x20, %eax
movl %eax, -0x10c(%rbp)
movl -0x110(%rbp), %eax
addl $0x20, %eax
movl %eax, -0x110(%rbp)
jmp 0xa2f4
movq -0x8(%rbp), %rdi
movl -0x110(%rbp), %eax
addq %rax, %rdi
movl -0xc(%rbp), %eax
movl -0x104(%rbp), %ecx
shll $0x5, %ecx
subl %ecx, %eax
movl %eax, %eax
movl %eax, %esi
movq -0x8(%rbp), %r8
movl -0x10c(%rbp), %eax
addq %rax, %r8
xorl %eax, %eax
movl %eax, %ecx
movl $0x40, %r9d
movq %rcx, %rdx
callq 0x9b70
addq $0x120, %rsp            # imm = 0x120
popq %rbp
retq
nopl (%rax)
// File: occivink[P]pyct/monocypher.cpp
// Function: gidx_init(gidx_ctx*, unsigned int, unsigned int, unsigned int, unsigned int)
static void gidx_init(gidx_ctx *ctx,
                      u32 pass_number, u32 slice_number,
                      u32 nb_blocks,   u32 nb_iterations)
{
    ctx->pass_number   = pass_number;
    ctx->slice_number  = slice_number;
    ctx->nb_blocks     = nb_blocks;
    ctx->nb_iterations = nb_iterations;
    ctx->ctr           = 0;

    // Offset from the beginning of the segment.  For the first slice
    // of the first pass, we start at the *third* block, so the offset
    // starts at 2, not 0.
    if (pass_number != 0 || slice_number != 0) {
        ctx->offset = 0;
    } else {
        ctx->offset = 2;
        ctx->ctr++;         // Compensates for missed lazy creation
        gidx_refresh(ctx);  // at the start of gidx_next()
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movl %edx, -0x10(%rbp)
movl %ecx, -0x14(%rbp)
movl %r8d, -0x18(%rbp)
movl -0xc(%rbp), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x400(%rax)
movl -0x10(%rbp), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x404(%rax)
movl -0x14(%rbp), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x408(%rax)
movl -0x18(%rbp), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x40c(%rax)
movq -0x8(%rbp), %rax
movl $0x0, 0x410(%rax)
cmpl $0x0, -0xc(%rbp)
jne 0xa437
cmpl $0x0, -0x10(%rbp)
je 0xa447
movq -0x8(%rbp), %rax
movl $0x0, 0x414(%rax)
jmp 0xa471
movq -0x8(%rbp), %rax
movl $0x2, 0x414(%rax)
movq -0x8(%rbp), %rax
movl 0x410(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x410(%rax)
movq -0x8(%rbp), %rdi
callq 0x12750
addq $0x20, %rsp
popq %rbp
retq
nopw (%rax,%rax)
// File: occivink[P]pyct/monocypher.cpp
// Function: crypto_x25519
void crypto_x25519(u8       raw_shared_secret[32],
                   const u8 your_secret_key  [32],
                   const u8 their_public_key [32])
{
    // restrict the possible scalar values
    u8 e[32];
    COPY(e, your_secret_key, 32);
    trim_scalar(e);
    scalarmult(raw_shared_secret, e, their_public_key, 255);
    WIPE_BUFFER(e);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq $0x0, -0x48(%rbp)
cmpq $0x20, -0x48(%rbp)
jae 0xd6a4
movq -0x10(%rbp), %rax
movq -0x48(%rbp), %rcx
movb (%rax,%rcx), %cl
movq -0x48(%rbp), %rax
movb %cl, -0x40(%rbp,%rax)
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0xd67c
leaq -0x40(%rbp), %rdi
callq 0xd6e0
movq -0x8(%rbp), %rdi
leaq -0x40(%rbp), %rsi
movq -0x18(%rbp), %rdx
movl $0xff, %ecx
callq 0xd720
leaq -0x40(%rbp), %rdi
movl $0x20, %esi
callq 0x3890
addq $0x50, %rsp
popq %rbp
retq
nopw (%rax,%rax)
// File: occivink[P]pyct/monocypher.cpp
// Function: crypto_sign_public_key_custom_hash
void crypto_sign_public_key_custom_hash(u8       public_key[32],
                                        const u8 secret_key[32],
                                        const crypto_sign_vtable *hash)
{
    u8 a[64];
    hash->hash(a, secret_key, 32);
    trim_scalar(a);
    ge A;
    ge_scalarmult_base(&A, a);
    ge_tobytes(public_key, &A);
    WIPE_BUFFER(a);
    WIPE_CTX(&A);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x100, %rsp            # imm = 0x100
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rax
leaq -0x60(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl $0x20, %edx
callq *%rax
leaq -0x60(%rbp), %rdi
callq 0xd6e0
leaq -0x60(%rbp), %rsi
leaq -0x100(%rbp), %rdi
callq 0xdb40
movq -0x8(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0xdd00
leaq -0x60(%rbp), %rdi
movl $0x40, %esi
callq 0x3890
leaq -0x100(%rbp), %rdi
movl $0xa0, %esi
callq 0x3890
addq $0x100, %rsp            # imm = 0x100
popq %rbp
retq
nop
// File: occivink[P]pyct/monocypher.cpp
// Function: ge_tobytes(unsigned char*, ge const*)
static void ge_tobytes(u8 s[32], const ge *h)
{
    fe recip, x, y;
    fe_invert(recip, h->Z);
    fe_mul(x, h->X, recip);
    fe_mul(y, h->Y, recip);
    fe_tobytes(s, y);
    s[31] ^= fe_isodd(x) << 7;

    WIPE_BUFFER(recip);
    WIPE_BUFFER(x);
    WIPE_BUFFER(y);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x40(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x50, %rsi
callq 0xeba0
leaq -0x70(%rbp), %rdi
movq -0x10(%rbp), %rsi
leaq -0x40(%rbp), %rdx
callq 0xec00
leaq -0xa0(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x28, %rsi
leaq -0x40(%rbp), %rdx
callq 0xec00
movq -0x8(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0xf800
leaq -0x70(%rbp), %rdi
callq 0x11810
movl %eax, %edx
shll $0x7, %edx
movq -0x8(%rbp), %rax
movzbl 0x1f(%rax), %ecx
xorl %edx, %ecx
movb %cl, 0x1f(%rax)
leaq -0x40(%rbp), %rdi
movl $0x28, %esi
callq 0x3890
leaq -0x70(%rbp), %rdi
movl $0x28, %esi
callq 0x3890
leaq -0xa0(%rbp), %rdi
movl $0x28, %esi
callq 0x3890
addq $0xa0, %rsp
popq %rbp
retq
nop
// File: occivink[P]pyct/monocypher.cpp
// Function: crypto_sign_init_first_pass_custom_hash
void crypto_sign_init_first_pass_custom_hash(crypto_sign_ctx_abstract *ctx,
                                             const u8 secret_key[32],
                                             const u8 public_key[32],
                                             const crypto_sign_vtable *hash)
{
    ctx->hash  = hash; // set vtable
    u8 *a      = ctx->buf;
    u8 *prefix = ctx->buf + 32;
    ctx->hash->hash(a, secret_key, 32);
    trim_scalar(a);

    if (public_key == 0) {
        crypto_sign_public_key_custom_hash(ctx->pk, secret_key, ctx->hash);
    } else {
        COPY(ctx->pk, public_key, 32);
    }

    // Deterministic part of EdDSA: Construct a nonce by hashing the message
    // instead of generating a random number.
    // An actual random number would work just fine, and would save us
    // the trouble of hashing the message twice.  If we did that
    // however, the user could fuck it up and reuse the nonce.
    ctx->hash->init  (ctx);
    ctx->hash->update(ctx, prefix , 32);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x20(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, (%rax)
movq -0x8(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x28(%rbp)
movq -0x8(%rbp), %rax
addq $0x8, %rax
addq $0x20, %rax
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq -0x28(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl $0x20, %edx
callq *%rax
movq -0x28(%rbp), %rdi
callq 0xd6e0
cmpq $0x0, -0x18(%rbp)
jne 0xde62
movq -0x8(%rbp), %rdi
addq $0x68, %rdi
movq -0x10(%rbp), %rsi
movq -0x8(%rbp), %rax
movq (%rax), %rdx
callq 0xdac0
jmp 0xde98
movq $0x0, -0x38(%rbp)
cmpq $0x20, -0x38(%rbp)
jae 0xde96
movq -0x18(%rbp), %rax
movq -0x38(%rbp), %rcx
movb (%rax,%rcx), %dl
movq -0x8(%rbp), %rax
movq -0x38(%rbp), %rcx
movb %dl, 0x68(%rax,%rcx)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0xde6a
jmp 0xde98
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq 0x8(%rax), %rax
movq -0x8(%rbp), %rdi
callq *%rax
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq 0x10(%rax), %rax
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rsi
movl $0x20, %edx
callq *%rax
addq $0x40, %rsp
popq %rbp
retq
nopl (%rax)
// File: occivink[P]pyct/monocypher.cpp
// Function: crypto_sign_init_second_pass
void crypto_sign_init_second_pass(crypto_sign_ctx_abstract *ctx)
{
    u8 *r        = ctx->buf + 32;
    u8 *half_sig = ctx->buf + 64;
    ctx->hash->final(ctx, r);
    reduce(r);

    // first half of the signature = "random" nonce times the base point
    ge R;
    ge_scalarmult_base(&R, r);
    ge_tobytes(half_sig, &R);
    WIPE_CTX(&R);

    // Hash R, the public key, and the message together.
    // It cannot be done in parallel with the first hash.
    ctx->hash->init  (ctx);
    ctx->hash->update(ctx, half_sig, 32);
    ctx->hash->update(ctx, ctx->pk , 32);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x8, %rax
addq $0x20, %rax
movq %rax, -0x10(%rbp)
movq -0x8(%rbp), %rax
addq $0x8, %rax
addq $0x40, %rax
movq %rax, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq 0x18(%rax), %rax
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq *%rax
movq -0x10(%rbp), %rdi
callq 0xe020
movq -0x10(%rbp), %rsi
leaq -0xb8(%rbp), %rdi
callq 0xdb40
movq -0x18(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
callq 0xdd00
leaq -0xb8(%rbp), %rdi
movl $0xa0, %esi
callq 0x3890
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq 0x8(%rax), %rax
movq -0x8(%rbp), %rdi
callq *%rax
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq 0x10(%rax), %rax
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
movl $0x20, %edx
callq *%rax
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq 0x10(%rax), %rax
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rsi
addq $0x68, %rsi
movl $0x20, %edx
callq *%rax
addq $0xc0, %rsp
popq %rbp
retq
// File: occivink[P]pyct/monocypher.cpp
// Function: crypto_sign_final
void crypto_sign_final(crypto_sign_ctx_abstract *ctx, u8 signature[64])
{
    u8 *a        = ctx->buf;
    u8 *r        = ctx->buf + 32;
    u8 *half_sig = ctx->buf + 64;
    u8  h_ram[64];
    ctx->hash->final(ctx, h_ram);
    reduce(h_ram);
    COPY(signature, half_sig, 32);
    mul_add(signature + 32, h_ram, a, r); // s = h_ram * a + r
    WIPE_BUFFER(h_ram);
    crypto_wipe(ctx, ctx->hash->ctx_size);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x18(%rbp)
movq -0x8(%rbp), %rax
addq $0x8, %rax
addq $0x20, %rax
movq %rax, -0x20(%rbp)
movq -0x8(%rbp), %rax
addq $0x8, %rax
addq $0x40, %rax
movq %rax, -0x28(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq 0x18(%rax), %rax
movq -0x8(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq *%rax
leaq -0x70(%rbp), %rdi
callq 0xe020
movq $0x0, -0x78(%rbp)
cmpq $0x20, -0x78(%rbp)
jae 0xe0f0
movq -0x28(%rbp), %rax
movq -0x78(%rbp), %rcx
movb (%rax,%rcx), %dl
movq -0x10(%rbp), %rax
movq -0x78(%rbp), %rcx
movb %dl, (%rax,%rcx)
movq -0x78(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x78(%rbp)
jmp 0xe0c5
movq -0x10(%rbp), %rdi
addq $0x20, %rdi
leaq -0x70(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
callq 0xe140
leaq -0x70(%rbp), %rdi
movl $0x40, %esi
callq 0x3890
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq 0x20(%rax), %rsi
callq 0x3890
addq $0x80, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
// File: occivink[P]pyct/monocypher.cpp
// Function: mul_add(unsigned char*, unsigned char const*, unsigned char const*, unsigned char const*)
static void mul_add(u8 r[32], const u8 a[32], const u8 b[32], const u8 c[32])
{
    u32 A[8];  load32_le_buf(A, a, 8);
    u32 B[8];  load32_le_buf(B, b, 8);
    u32 p[16]; load32_le_buf(p, c, 8);  ZERO(p + 8, 8);
    multiply(p, A, B);
    mod_l(r, p);
    WIPE_BUFFER(p);
    WIPE_BUFFER(A);
    WIPE_BUFFER(B);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
leaq -0x40(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl $0x8, %edx
callq 0x3990
leaq -0x60(%rbp), %rdi
movq -0x18(%rbp), %rsi
movl $0x8, %edx
callq 0x3990
leaq -0xa0(%rbp), %rdi
movq -0x20(%rbp), %rsi
movl $0x8, %edx
callq 0x3990
movq $0x0, -0xa8(%rbp)
cmpq $0x8, -0xa8(%rbp)
jae 0xe1cc
movq -0xa8(%rbp), %rax
movl $0x0, -0x80(%rbp,%rax,4)
movq -0xa8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xa8(%rbp)
jmp 0xe19f
leaq -0xa0(%rbp), %rdi
leaq -0x40(%rbp), %rsi
leaq -0x60(%rbp), %rdx
callq 0x12010
movq -0x8(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x11d10
leaq -0xa0(%rbp), %rdi
movl $0x40, %esi
callq 0x3890
leaq -0x40(%rbp), %rdi
movl $0x20, %esi
callq 0x3890
leaq -0x60(%rbp), %rdi
movl $0x20, %esi
callq 0x3890
addq $0xb0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
// File: occivink[P]pyct/monocypher.cpp
// Function: crypto_sign
void crypto_sign(u8        signature[64],
                 const u8  secret_key[32],
                 const u8  public_key[32],
                 const u8 *message, size_t message_size)
{
    crypto_sign_ctx ctx;
    crypto_sign_ctx_abstract *actx = (crypto_sign_ctx_abstract*)&ctx;
    crypto_sign_init_first_pass (actx, secret_key, public_key);
    crypto_sign_update          (actx, message, message_size);
    crypto_sign_init_second_pass(actx);
    crypto_sign_update          (actx, message, message_size);
    crypto_sign_final           (actx, signature);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1a0, %rsp            # imm = 0x1A0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
leaq -0x190(%rbp), %rax
movq %rax, -0x198(%rbp)
movq -0x198(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
callq 0xded0
movq -0x198(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0xdf10
movq -0x198(%rbp), %rdi
callq 0xdf50
movq -0x198(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0xdf10
movq -0x198(%rbp), %rdi
movq -0x8(%rbp), %rsi
callq 0xe060
addq $0x1a0, %rsp            # imm = 0x1A0
popq %rbp
retq
nop
// File: occivink[P]pyct/monocypher.cpp
// Function: crypto_check_init_custom_hash
void crypto_check_init_custom_hash(crypto_check_ctx_abstract *ctx,
                                   const u8 signature[64],
                                   const u8 public_key[32],
                                   const crypto_sign_vtable *hash)
{
    ctx->hash = hash; // set vtable
    COPY(ctx->buf, signature , 64);
    COPY(ctx->pk , public_key, 32);
    ctx->hash->init  (ctx);
    ctx->hash->update(ctx, signature , 32);
    ctx->hash->update(ctx, public_key, 32);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x20(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, (%rax)
movq $0x0, -0x28(%rbp)
cmpq $0x40, -0x28(%rbp)
jae 0xe317
movq -0x10(%rbp), %rax
movq -0x28(%rbp), %rcx
movb (%rax,%rcx), %dl
movq -0x8(%rbp), %rax
movq -0x28(%rbp), %rcx
movb %dl, 0x8(%rax,%rcx)
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0xe2eb
movq $0x0, -0x30(%rbp)
cmpq $0x20, -0x30(%rbp)
jae 0xe34b
movq -0x18(%rbp), %rax
movq -0x30(%rbp), %rcx
movb (%rax,%rcx), %dl
movq -0x8(%rbp), %rax
movq -0x30(%rbp), %rcx
movb %dl, 0x68(%rax,%rcx)
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0xe31f
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq 0x8(%rax), %rax
movq -0x8(%rbp), %rdi
callq *%rax
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq 0x10(%rax), %rax
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl $0x20, %edx
callq *%rax
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq 0x10(%rax), %rax
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
movl $0x20, %edx
callq *%rax
addq $0x30, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
// File: occivink[P]pyct/monocypher.cpp
// Function: crypto_check_final
int crypto_check_final(crypto_check_ctx_abstract *ctx)
{
    u8 *s = ctx->buf + 32; // s
    u8  h_ram[64];
    u32 s32[8];            // s (different encoding)
    ge  A;

    ctx->hash->final(ctx, h_ram);
    reduce(h_ram);
    load32_le_buf(s32, s, 8);
    if (ge_frombytes_neg_vartime(&A, ctx->pk) ||  // A = -pk
        is_above_l(s32)) {                        // prevent s malleability
        return -1;
    }
    ge_double_scalarmult_vartime(&A, h_ram, s);   // A = [s]B - [h_ram]pk
    ge_tobytes(ctx->pk, &A);                      // R_check = A
    return crypto_verify32(ctx->buf, ctx->pk);    // R == R_check ? OK : fail
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x120, %rsp            # imm = 0x120
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
addq $0x8, %rax
addq $0x20, %rax
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq 0x18(%rax), %rax
movq -0x10(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq *%rax
leaq -0x60(%rbp), %rdi
callq 0xe020
leaq -0x80(%rbp), %rdi
movq -0x18(%rbp), %rsi
movl $0x8, %edx
callq 0x3990
movq -0x10(%rbp), %rsi
addq $0x68, %rsi
leaq -0x120(%rbp), %rdi
callq 0xe4f0
cmpl $0x0, %eax
jne 0xe496
leaq -0x80(%rbp), %rdi
callq 0xe620
cmpl $0x0, %eax
je 0xe49f
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xe4df
leaq -0x60(%rbp), %rsi
movq -0x18(%rbp), %rdx
leaq -0x120(%rbp), %rdi
callq 0xe690
movq -0x10(%rbp), %rdi
addq $0x68, %rdi
leaq -0x120(%rbp), %rsi
callq 0xdd00
movq -0x10(%rbp), %rdi
addq $0x8, %rdi
movq -0x10(%rbp), %rsi
addq $0x68, %rsi
callq 0x3790
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x120, %rsp            # imm = 0x120
popq %rbp
retq
nopl (%rax,%rax)
// File: occivink[P]pyct/monocypher.cpp
// Function: ge_frombytes_neg_vartime(ge*, unsigned char const*)
static int ge_frombytes_neg_vartime(ge *h, const u8 s[32])
{
    fe_frombytes(h->Y, s);
    fe_1(h->Z);
    fe_sq (h->T, h->Y);        // t =   y^2
    fe_mul(h->X, h->T, d   );  // x = d*y^2
    fe_sub(h->T, h->T, h->Z);  // t =   y^2 - 1
    fe_add(h->X, h->X, h->Z);  // x = d*y^2 + 1
    fe_mul(h->X, h->T, h->X);  // x = (y^2 - 1) * (d*y^2 + 1)
    int is_square = invsqrt(h->X, h->X);
    if (!is_square) {
        return -1;             // Not on the curve, abort
    }
    fe_mul(h->X, h->T, h->X);  // x = sqrt((y^2 - 1) / (d*y^2 + 1))
    if (fe_isodd(h->X) == (s[31] >> 7)) {
        fe_neg(h->X, h->X);
    }
    fe_mul(h->T, h->X, h->Y);
    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rdi
addq $0x28, %rdi
movq -0x18(%rbp), %rsi
callq 0xead0
movq -0x10(%rbp), %rdi
addq $0x50, %rdi
callq 0x12870
movq -0x10(%rbp), %rdi
addq $0x78, %rdi
movq -0x10(%rbp), %rsi
addq $0x28, %rsi
callq 0x10580
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x78, %rsi
leaq 0xe56a(%rip), %rdx      # 0x1cab0
callq 0xec00
movq -0x10(%rbp), %rdi
addq $0x78, %rdi
movq -0x10(%rbp), %rsi
addq $0x78, %rsi
movq -0x10(%rbp), %rdx
addq $0x50, %rdx
callq 0xeb50
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x10(%rbp), %rdx
addq $0x50, %rdx
callq 0xeb00
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x78, %rsi
movq -0x10(%rbp), %rdx
callq 0xec00
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x10d90
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
jne 0xe5b1
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xe60b
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x78, %rsi
movq -0x10(%rbp), %rdx
callq 0xec00
movq -0x10(%rbp), %rdi
callq 0x11810
movq -0x18(%rbp), %rcx
movzbl 0x1f(%rcx), %ecx
sarl $0x7, %ecx
cmpl %ecx, %eax
jne 0xe5eb
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x11290
movq -0x10(%rbp), %rdi
addq $0x78, %rdi
movq -0x10(%rbp), %rsi
movq -0x10(%rbp), %rdx
addq $0x28, %rdx
callq 0xec00
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x20, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
// File: occivink[P]pyct/monocypher.cpp
// Function: is_above_l(unsigned int const*)
static int is_above_l(const u32 x[8])
{
    // We work with L directly, in a 2's complement encoding
    // (-L == ~L + 1)
    u64 carry = 1;
    FOR (i, 0, 8) {
        carry  += (u64)x[i] + (~L[i] & 0xffffffff);
        carry >>= 32;
    }
    return (int)carry; // carry is either 0 or 1
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
movq %rdi, -0x8(%rbp)
movq $0x1, -0x10(%rbp)
movq $0x0, -0x18(%rbp)
cmpq $0x8, -0x18(%rbp)
jae 0xe685
movq -0x8(%rbp), %rax
movq -0x18(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movq -0x18(%rbp), %rdx
leaq 0xe48b(%rip), %rcx      # 0x1cae0
movl (%rcx,%rdx,4), %ecx
xorl $-0x1, %ecx
andl $-0x1, %ecx
movl %ecx, %ecx
addq %rcx, %rax
addq -0x10(%rbp), %rax
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
shrq $0x20, %rax
movq %rax, -0x10(%rbp)
movq -0x18(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x18(%rbp)
jmp 0xe638
movq -0x10(%rbp), %rax
popq %rbp
retq
nopl (%rax,%rax)
// File: occivink[P]pyct/monocypher.cpp
// Function: crypto_check
int crypto_check(const u8  signature[64], const u8 public_key[32],
                 const u8 *message, size_t message_size)
{
    crypto_check_ctx ctx;
    crypto_check_ctx_abstract *actx = (crypto_check_ctx_abstract*)&ctx;
    crypto_check_init  (actx, signature, public_key);
    crypto_check_update(actx, message, message_size);
    return crypto_check_final(actx);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x190, %rsp            # imm = 0x190
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
leaq -0x188(%rbp), %rax
movq %rax, -0x190(%rbp)
movq -0x190(%rbp), %rdi
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rdx
callq 0xe3a0
movq -0x190(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0xe3e0
movq -0x190(%rbp), %rdi
callq 0xe420
addq $0x190, %rsp            # imm = 0x190
popq %rbp
retq
nopw %cs:(%rax,%rax)
// File: occivink[P]pyct/monocypher.cpp
// Function: crypto_from_eddsa_public
void crypto_from_eddsa_public(u8 x25519[32], const u8 eddsa[32])
{
    fe t1, t2;
    fe_frombytes(t2, eddsa);
    fe_add(t1, fe_one, t2);
    fe_sub(t2, fe_one, t2);
    fe_invert(t2, t2);
    fe_mul(t1, t1, t2);
    fe_tobytes(x25519, t1);
    WIPE_BUFFER(t1);
    WIPE_BUFFER(t2);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x70(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0xead0
leaq -0x40(%rbp), %rdi
leaq -0x70(%rbp), %rdx
leaq 0xe464(%rip), %rsi      # 0x1cec0
callq 0xeb00
leaq -0x70(%rbp), %rdi
leaq -0x70(%rbp), %rdx
leaq 0xe450(%rip), %rsi      # 0x1cec0
callq 0xeb50
leaq -0x70(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0xeba0
leaq -0x40(%rbp), %rdi
leaq -0x40(%rbp), %rsi
leaq -0x70(%rbp), %rdx
callq 0xec00
movq -0x8(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0xf800
leaq -0x40(%rbp), %rdi
movl $0x28, %esi
callq 0x3890
leaq -0x70(%rbp), %rdi
movl $0x28, %esi
callq 0x3890
addq $0x70, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
// File: occivink[P]pyct/monocypher.cpp
// Function: fe_invert(int*, int const*)
static void fe_invert(fe out, const fe x)
{
    fe tmp;
    fe_sq(tmp, x);
    invsqrt(tmp, tmp);
    fe_sq(tmp, tmp);
    fe_mul(out, tmp, x);
    WIPE_BUFFER(tmp);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x40(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x10580
leaq -0x40(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x10d90
leaq -0x40(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x10580
movq -0x8(%rbp), %rdi
leaq -0x40(%rbp), %rsi
movq -0x10(%rbp), %rdx
callq 0xec00
leaq -0x40(%rbp), %rdi
movl $0x28, %esi
callq 0x3890
addq $0x40, %rsp
popq %rbp
retq
nopl (%rax)
// File: occivink[P]pyct/monocypher.cpp
// Function: crypto_x25519_dirty_small
void crypto_x25519_dirty_small(u8 public_key[32], const u8 secret_key[32])
{
    // Base point of order 8*L
    // Raw scalar multiplication with it does not clear the cofactor,
    // and the resulting public key will reveal 3 bits of the scalar.
    //
    // The low order component of this base point  has been chosen
    // to yield the same results as crypto_x25519_dirty_fast().
    static const u8 dirty_base_point[32] = {
        0xd8, 0x86, 0x1a, 0xa2, 0x78, 0x7a, 0xd9, 0x26, 0x8b, 0x74, 0x74, 0xb6,
        0x82, 0xe3, 0xbe, 0xc3, 0xce, 0x36, 0x9a, 0x1e, 0x5e, 0x31, 0x47, 0xa2,
        0x6d, 0x37, 0x7c, 0xfd, 0x20, 0xb5, 0xdf, 0x75,
    };
    // separate the main factor & the cofactor of the scalar
    u8 scalar[32];
    COPY(scalar, secret_key, 32);
    trim_scalar(scalar);

    // Separate the main factor and the cofactor
    //
    // The scalar is trimmed, so its cofactor is cleared.  The three
    // least significant bits however still have a main factor.  We must
    // remove it for X25519 compatibility.
    //
    //   cofactor = lsb * L            (modulo 8*L)
    //   combined = scalar + cofactor  (modulo 8*L)
    add_xl(scalar, secret_key[0]);
    scalarmult(public_key, scalar, dirty_base_point, 256);
    WIPE_BUFFER(scalar);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq $0x0, -0x38(%rbp)
cmpq $0x20, -0x38(%rbp)
jae 0xfa70
movq -0x10(%rbp), %rax
movq -0x38(%rbp), %rcx
movb (%rax,%rcx), %cl
movq -0x38(%rbp), %rax
movb %cl, -0x30(%rbp,%rax)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0xfa48
leaq -0x30(%rbp), %rdi
callq 0xd6e0
leaq -0x30(%rbp), %rdi
movq -0x10(%rbp), %rax
movzbl (%rax), %esi
callq 0xfac0
movq -0x8(%rbp), %rdi
leaq -0x30(%rbp), %rsi
leaq 0xc668(%rip), %rdx      # 0x1c100
movl $0x100, %ecx            # imm = 0x100
callq 0xd720
leaq -0x30(%rbp), %rdi
movl $0x20, %esi
callq 0x3890
addq $0x40, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
// File: occivink[P]pyct/monocypher.cpp
// Function: add_xl(unsigned char*, unsigned char)
static void add_xl(u8 s[32], u8 x)
{
    u64 mod8  = x & 7;
    u64 carry = 0;
    FOR (i , 0, 8) {
        carry = carry + load32_le(s + 4*i) + L[i] * mod8;
        store32_le(s + 4*i, (u32)carry);
        carry >>= 32;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movb %sil, %al
movq %rdi, -0x8(%rbp)
movb %al, -0x9(%rbp)
movzbl -0x9(%rbp), %eax
andl $0x7, %eax
cltq
movq %rax, -0x18(%rbp)
movq $0x0, -0x20(%rbp)
movq $0x0, -0x28(%rbp)
cmpq $0x8, -0x28(%rbp)
jae 0xfb6b
movq -0x20(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rdi
movq -0x28(%rbp), %rax
shlq $0x2, %rax
addq %rax, %rdi
callq 0x4300
movl %eax, %ecx
movq -0x30(%rbp), %rax
movl %ecx, %ecx
addq %rcx, %rax
movq -0x28(%rbp), %rdx
leaq 0xcfb8(%rip), %rcx      # 0x1cae0
movl (%rcx,%rdx,4), %ecx
imulq -0x18(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x20(%rbp)
movq -0x8(%rbp), %rdi
movq -0x28(%rbp), %rax
shlq $0x2, %rax
addq %rax, %rdi
movq -0x20(%rbp), %rax
movl %eax, %esi
callq 0x42a0
movq -0x20(%rbp), %rax
shrq $0x20, %rax
movq %rax, -0x20(%rbp)
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0xfaef
addq $0x30, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
// File: occivink[P]pyct/monocypher.cpp
// Function: select_lop(int*, int const*, int const*, unsigned char)
static void select_lop(fe out, const fe x, const fe k, u8 cofactor)
{
    fe tmp;
    fe_0(out);
    fe_ccopy(out, k  , (cofactor >> 1) & 1); // bit 1
    fe_ccopy(out, x  , (cofactor >> 0) & 1); // bit 0
    fe_neg  (tmp, out);
    fe_ccopy(out, tmp, (cofactor >> 2) & 1); // bit 2
    WIPE_BUFFER(tmp);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movb %cl, %al
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movb %al, -0x19(%rbp)
movq -0x8(%rbp), %rdi
callq 0x128c0
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
movzbl -0x19(%rbp), %edx
sarl %edx
andl $0x1, %edx
callq 0x11220
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movzbl -0x19(%rbp), %edx
sarl $0x0, %edx
andl $0x1, %edx
callq 0x11220
leaq -0x50(%rbp), %rdi
movq -0x8(%rbp), %rsi
callq 0x11290
movq -0x8(%rbp), %rdi
leaq -0x50(%rbp), %rsi
movzbl -0x19(%rbp), %edx
sarl $0x2, %edx
andl $0x1, %edx
callq 0x11220
leaq -0x50(%rbp), %rdi
movl $0x28, %esi
callq 0x3890
addq $0x50, %rsp
popq %rbp
retq
nopw (%rax,%rax)
// File: occivink[P]pyct/monocypher.cpp
// Function: ge_madd(ge*, ge const*, ge_precomp const*, int*, int*)
static void ge_madd(ge *s, const ge *p, const ge_precomp *q, fe a, fe b)
{
    fe_add(a   , p->Y, p->X );
    fe_sub(b   , p->Y, p->X );
    fe_mul(a   , a   , q->Yp);
    fe_mul(b   , b   , q->Ym);
    fe_add(s->Y, a   , b    );
    fe_sub(s->X, a   , b    );

    fe_add(s->Z, p->Z, p->Z );
    fe_mul(s->T, p->T, q->T2);
    fe_add(a   , s->Z, s->T );
    fe_sub(b   , s->Z, s->T );

    fe_mul(s->T, s->X, s->Y);
    fe_mul(s->X, s->X, b   );
    fe_mul(s->Y, s->Y, a   );
    fe_mul(s->Z, a   , b   );
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq -0x20(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x28, %rsi
movq -0x10(%rbp), %rdx
callq 0xeb00
movq -0x28(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x28, %rsi
movq -0x10(%rbp), %rdx
callq 0xeb50
movq -0x20(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x18(%rbp), %rdx
callq 0xec00
movq -0x28(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x18(%rbp), %rdx
addq $0x28, %rdx
callq 0xec00
movq -0x8(%rbp), %rdi
addq $0x28, %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0xeb00
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0xeb50
movq -0x8(%rbp), %rdi
addq $0x50, %rdi
movq -0x10(%rbp), %rsi
addq $0x50, %rsi
movq -0x10(%rbp), %rdx
addq $0x50, %rdx
callq 0xeb00
movq -0x8(%rbp), %rdi
addq $0x78, %rdi
movq -0x10(%rbp), %rsi
addq $0x78, %rsi
movq -0x18(%rbp), %rdx
addq $0x50, %rdx
callq 0xec00
movq -0x20(%rbp), %rdi
movq -0x8(%rbp), %rsi
addq $0x50, %rsi
movq -0x8(%rbp), %rdx
addq $0x78, %rdx
callq 0xeb00
movq -0x28(%rbp), %rdi
movq -0x8(%rbp), %rsi
addq $0x50, %rsi
movq -0x8(%rbp), %rdx
addq $0x78, %rdx
callq 0xeb50
movq -0x8(%rbp), %rdi
addq $0x78, %rdi
movq -0x8(%rbp), %rsi
movq -0x8(%rbp), %rdx
addq $0x28, %rdx
callq 0xec00
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0xec00
movq -0x8(%rbp), %rdi
addq $0x28, %rdi
movq -0x8(%rbp), %rsi
addq $0x28, %rsi
movq -0x20(%rbp), %rdx
callq 0xec00
movq -0x8(%rbp), %rdi
addq $0x50, %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0xec00
addq $0x30, %rsp
popq %rbp
retq
nopl (%rax)
// File: occivink[P]pyct/monocypher.cpp
// Function: crypto_hidden_to_curve
void crypto_hidden_to_curve(uint8_t curve[32], const uint8_t hidden[32])
{
    fe r, u, t1, t2, t3;
    fe_frombytes_mask(r, hidden, 2); // r is encoded in 254 bits.
    fe_sq(r, r);
    fe_add(t1, r, r);
    fe_add(u, t1, fe_one);
    fe_sq (t2, u);
    fe_mul(t3, A2, t1);
    fe_sub(t3, t3, t2);
    fe_mul(t3, t3, A);
    fe_mul(t1, t2, u);
    fe_mul(t1, t3, t1);
    int is_square = invsqrt(t1, t1);
    fe_mul(u, r, ufactor);
    fe_ccopy(u, fe_one, is_square);
    fe_sq (t1, t1);
    fe_mul(u, u, A);
    fe_mul(u, u, t3);
    fe_mul(u, u, t2);
    fe_mul(u, u, t1);
    fe_neg(u, u);
    fe_tobytes(curve, u);

    WIPE_BUFFER(t1);  WIPE_BUFFER(r);
    WIPE_BUFFER(t2);  WIPE_BUFFER(u);
    WIPE_BUFFER(t3);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x110, %rsp            # imm = 0x110
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x40(%rbp), %rdi
movq -0x10(%rbp), %rsi
movl $0x2, %edx
callq 0x101b0
leaq -0x40(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x10580
leaq -0xa0(%rbp), %rdi
leaq -0x40(%rbp), %rsi
leaq -0x40(%rbp), %rdx
callq 0xeb00
leaq -0x70(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
leaq 0xcec8(%rip), %rdx      # 0x1cec0
callq 0xeb00
leaq -0xd0(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x10580
leaq -0x100(%rbp), %rdi
leaq -0xa0(%rbp), %rdx
leaq 0xcece(%rip), %rsi      # 0x1cef0
callq 0xec00
leaq -0x100(%rbp), %rdi
leaq -0x100(%rbp), %rsi
leaq -0xd0(%rbp), %rdx
callq 0xeb50
leaq -0x100(%rbp), %rdi
leaq -0x100(%rbp), %rsi
leaq 0xceca(%rip), %rdx      # 0x1cf20
callq 0xec00
leaq -0xa0(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
leaq -0x70(%rbp), %rdx
callq 0xec00
leaq -0xa0(%rbp), %rdi
leaq -0x100(%rbp), %rsi
leaq -0xa0(%rbp), %rdx
callq 0xec00
leaq -0xa0(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x10d90
movl %eax, -0x104(%rbp)
leaq -0x70(%rbp), %rdi
leaq -0x40(%rbp), %rsi
leaq 0xc12c(%rip), %rdx      # 0x1c1e0
callq 0xec00
leaq -0x70(%rbp), %rdi
movl -0x104(%rbp), %edx
leaq 0xcdf6(%rip), %rsi      # 0x1cec0
callq 0x11220
leaq -0xa0(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x10580
leaq -0x70(%rbp), %rdi
leaq -0x70(%rbp), %rsi
leaq 0xce2f(%rip), %rdx      # 0x1cf20
callq 0xec00
leaq -0x70(%rbp), %rdi
leaq -0x70(%rbp), %rsi
leaq -0x100(%rbp), %rdx
callq 0xec00
leaq -0x70(%rbp), %rdi
leaq -0x70(%rbp), %rsi
leaq -0xd0(%rbp), %rdx
callq 0xec00
leaq -0x70(%rbp), %rdi
leaq -0x70(%rbp), %rsi
leaq -0xa0(%rbp), %rdx
callq 0xec00
leaq -0x70(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x11290
movq -0x8(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0xf800
leaq -0xa0(%rbp), %rdi
movl $0x28, %esi
callq 0x3890
leaq -0x40(%rbp), %rdi
movl $0x28, %esi
callq 0x3890
leaq -0xd0(%rbp), %rdi
movl $0x28, %esi
callq 0x3890
leaq -0x70(%rbp), %rdi
movl $0x28, %esi
callq 0x3890
leaq -0x100(%rbp), %rdi
movl $0x28, %esi
callq 0x3890
addq $0x110, %rsp            # imm = 0x110
popq %rbp
retq
nopw %cs:(%rax,%rax)
// File: occivink[P]pyct/monocypher.cpp
// Function: fe_ccopy(int*, int const*, int)
static void fe_ccopy(fe f, const fe g, int b)
{
    i32 mask = -b; // -1 = 0xffffffff
    FOR (i, 0, 10) {
        i32 x = (f[i] ^ g[i]) & mask;
        f[i] = f[i] ^ x;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
xorl %eax, %eax
subl -0x14(%rbp), %eax
movl %eax, -0x18(%rbp)
movq $0x0, -0x20(%rbp)
cmpq $0xa, -0x20(%rbp)
jae 0x11289
movq -0x8(%rbp), %rax
movq -0x20(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movq -0x10(%rbp), %rcx
movq -0x20(%rbp), %rdx
xorl (%rcx,%rdx,4), %eax
andl -0x18(%rbp), %eax
movl %eax, -0x24(%rbp)
movq -0x8(%rbp), %rax
movq -0x20(%rbp), %rcx
movl (%rax,%rcx,4), %edx
xorl -0x24(%rbp), %edx
movq -0x8(%rbp), %rax
movq -0x20(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0x1123f
popq %rbp
retq
nopl (%rax,%rax)
// File: occivink[P]pyct/monocypher.cpp
// Function: crypto_curve_to_hidden
int crypto_curve_to_hidden(u8 hidden[32], const u8 public_key[32], u8 tweak)
{
    fe t1, t2, t3;
    fe_frombytes(t1, public_key);    // t1 = u

    fe_add(t2, t1, A);               // t2 = u + A
    fe_mul(t3, t1, t2);
    fe_mul_small(t3, t3, -2);
    int is_square = invsqrt(t3, t3); // t3 = sqrt(-1 / non_square * u * (u+A))
    if (is_square) {
        // The only variable time bit.  This ultimately reveals how many
        // tries it took us to find a representable key.
        // This does not affect security as long as we try keys at random.

        fe_ccopy    (t1, t2, tweak & 1); // multiply by u if v is positive,
        fe_mul      (t3, t1, t3);        // multiply by u+A otherwise
        fe_mul_small(t1, t3, 2);
        fe_neg      (t2, t3);
        fe_ccopy    (t3, t2, fe_isodd(t1));
        fe_tobytes(hidden, t3);

        // Pad with two random bits
        hidden[31] |= tweak & 0xc0;
    }

    WIPE_BUFFER(t1);
    WIPE_BUFFER(t2);
    WIPE_BUFFER(t3);
    return is_square - 1;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movb %dl, %al
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movb %al, -0x11(%rbp)
leaq -0x40(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0xead0
leaq -0x70(%rbp), %rdi
leaq -0x40(%rbp), %rsi
leaq 0xbc0c(%rip), %rdx      # 0x1cf20
callq 0xeb00
leaq -0xa0(%rbp), %rdi
leaq -0x40(%rbp), %rsi
leaq -0x70(%rbp), %rdx
callq 0xec00
leaq -0xa0(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
movl $0xfffffffe, %edx       # imm = 0xFFFFFFFE
callq 0x11460
leaq -0xa0(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x10d90
movl %eax, -0xa4(%rbp)
cmpl $0x0, -0xa4(%rbp)
je 0x11419
leaq -0x40(%rbp), %rdi
leaq -0x70(%rbp), %rsi
movzbl -0x11(%rbp), %edx
andl $0x1, %edx
callq 0x11220
leaq -0xa0(%rbp), %rdi
leaq -0x40(%rbp), %rsi
leaq -0xa0(%rbp), %rdx
callq 0xec00
leaq -0x40(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
movl $0x2, %edx
callq 0x11460
leaq -0x70(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x11290
leaq -0xa0(%rbp), %rax
movq %rax, -0xb8(%rbp)
leaq -0x70(%rbp), %rax
movq %rax, -0xb0(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x11810
movq -0xb8(%rbp), %rdi
movq -0xb0(%rbp), %rsi
movl %eax, %edx
callq 0x11220
movq -0x8(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0xf800
movzbl -0x11(%rbp), %edx
andl $0xc0, %edx
movq -0x8(%rbp), %rax
movzbl 0x1f(%rax), %ecx
orl %edx, %ecx
movb %cl, 0x1f(%rax)
leaq -0x40(%rbp), %rdi
movl $0x28, %esi
callq 0x3890
leaq -0x70(%rbp), %rdi
movl $0x28, %esi
callq 0x3890
leaq -0xa0(%rbp), %rdi
movl $0x28, %esi
callq 0x3890
movl -0xa4(%rbp), %eax
subl $0x1, %eax
addq $0xc0, %rsp
popq %rbp
retq
nopl (%rax,%rax)
// File: occivink[P]pyct/monocypher.cpp
// Function: fe_isodd(int const*)
static int fe_isodd(const fe f)
{
    u8 s[32];
    fe_tobytes(s, f);
    u8 isodd = s[0] & 1;
    WIPE_BUFFER(s);
    return isodd;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
leaq -0x30(%rbp), %rdi
movq -0x8(%rbp), %rsi
callq 0xf800
movzbl -0x30(%rbp), %eax
andl $0x1, %eax
movb %al, -0x31(%rbp)
leaq -0x30(%rbp), %rdi
movl $0x20, %esi
callq 0x3890
movzbl -0x31(%rbp), %eax
addq $0x40, %rsp
popq %rbp
retq
nopl (%rax,%rax)
// File: occivink[P]pyct/monocypher.cpp
// Function: crypto_hidden_key_pair
void crypto_hidden_key_pair(u8 hidden[32], u8 secret_key[32], u8 seed[32])
{
    u8 pk [32]; // public key
    u8 buf[64]; // seed + representative
    COPY(buf + 32, seed, 32);
    do {
        crypto_chacha20(buf, 0, 64, buf+32, zero);
        crypto_x25519_dirty_fast(pk, buf); // or the "small" version
    } while(crypto_curve_to_hidden(buf+32, pk, buf[32]));
    // Note that the return value of crypto_curve_to_hidden() is
    // independent from its tweak parameter.
    // Therefore, buf[32] is not actually reused.  Either we loop one
    // more time and buf[32] is used for the new seed, or we succeeded,
    // and buf[32] becomes the tweak parameter.

    crypto_wipe(seed, 32);
    COPY(hidden    , buf + 32, 32);
    COPY(secret_key, buf     , 32);
    WIPE_BUFFER(buf);
    WIPE_BUFFER(pk);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq $0x0, -0x88(%rbp)
cmpq $0x20, -0x88(%rbp)
jae 0x118a9
movq -0x18(%rbp), %rax
movq -0x88(%rbp), %rcx
movb (%rax,%rcx), %cl
movq -0x88(%rbp), %rax
movb %cl, -0x60(%rbp,%rax)
movq -0x88(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x88(%rbp)
jmp 0x11872
jmp 0x118ab
leaq -0x80(%rbp), %rdi
leaq -0x80(%rbp), %rcx
addq $0x20, %rcx
xorl %eax, %eax
movl %eax, %esi
movl $0x40, %edx
leaq 0xa759(%rip), %r8       # 0x1c020
callq 0x4420
leaq -0x40(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0xfb80
leaq -0x80(%rbp), %rdi
addq $0x20, %rdi
leaq -0x40(%rbp), %rsi
movzbl -0x60(%rbp), %edx
callq 0x112e0
cmpl $0x0, %eax
jne 0x118ab
movq -0x18(%rbp), %rdi
movl $0x20, %esi
callq 0x3890
movq $0x0, -0x90(%rbp)
cmpq $0x20, -0x90(%rbp)
jae 0x11943
movq -0x90(%rbp), %rax
movb -0x60(%rbp,%rax), %dl
movq -0x8(%rbp), %rax
movq -0x90(%rbp), %rcx
movb %dl, (%rax,%rcx)
movq -0x90(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x90(%rbp)
jmp 0x1190c
movq $0x0, -0x98(%rbp)
cmpq $0x20, -0x98(%rbp)
jae 0x11985
movq -0x98(%rbp), %rax
movb -0x80(%rbp,%rax), %dl
movq -0x10(%rbp), %rax
movq -0x98(%rbp), %rcx
movb %dl, (%rax,%rcx)
movq -0x98(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x98(%rbp)
jmp 0x1194e
leaq -0x80(%rbp), %rdi
movl $0x40, %esi
callq 0x3890
leaq -0x40(%rbp), %rdi
movl $0x20, %esi
callq 0x3890
addq $0xa0, %rsp
popq %rbp
retq
nopw (%rax,%rax)
// File: occivink[P]pyct/monocypher.cpp
// Function: multiply(unsigned int*, unsigned int const*, unsigned int const*)
static void multiply(u32 p[16], const u32 a[8], const u32 b[8])
{
    FOR (i, 0, 8) {
        u64 carry = 0;
        FOR (j, 0, 8) {
            carry  += p[i+j] + (u64)a[i] * b[j];
            p[i+j]  = (u32)carry;
            carry >>= 32;
        }
        p[i+8] = (u32)carry;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq $0x0, -0x20(%rbp)
cmpq $0x8, -0x20(%rbp)
jae 0x120d0
movq $0x0, -0x28(%rbp)
movq $0x0, -0x30(%rbp)
cmpq $0x8, -0x30(%rbp)
jae 0x120ad
movq -0x8(%rbp), %rax
movq -0x20(%rbp), %rcx
addq -0x30(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movq -0x10(%rbp), %rcx
movq -0x20(%rbp), %rdx
movl (%rcx,%rdx,4), %ecx
movq -0x18(%rbp), %rdx
movq -0x30(%rbp), %rsi
movl (%rdx,%rsi,4), %edx
imulq %rdx, %rcx
addq %rcx, %rax
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movl %eax, %edx
movq -0x8(%rbp), %rax
movq -0x20(%rbp), %rcx
addq -0x30(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movq -0x28(%rbp), %rax
shrq $0x20, %rax
movq %rax, -0x28(%rbp)
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0x12043
movq -0x28(%rbp), %rax
movl %eax, %edx
movq -0x8(%rbp), %rax
movq -0x20(%rbp), %rcx
movl %edx, 0x20(%rax,%rcx,4)
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0x12028
popq %rbp
retq
nopw %cs:(%rax,%rax)
// File: occivink[P]pyct/monocypher.cpp
// Function: redc(unsigned int*, unsigned int*)
static void redc(u32 u[8], u32 x[16])
{
    static const u32 k[8] = { 0x12547e1b, 0xd2b51da3, 0xfdba84ff, 0xb1a206f2,
                              0xffa36bea, 0x14e75438, 0x6fe91836, 0x9db6c6f2, };

    // s = x * k (modulo 2^256)
    // This is cheaper than the full multiplication.
    u32 s[8] = {0};
    FOR (i, 0, 8) {
        u64 carry = 0;
        FOR (j, 0, 8-i) {
            carry  += s[i+j] + (u64)x[i] * k[j];
            s[i+j]  = (u32)carry;
            carry >>= 32;
        }
    }
    u32 t[16] = {0};
    multiply(t, s, L);

    // t = t + x
    u64 carry = 0;
    FOR (i, 0, 16) {
        carry  += (u64)t[i] + x[i];
        t[i]    = (u32)carry;
        carry >>= 32;
    }

    // u = (t / 2^256) % L
    // Note that t / 2^256 is always below 2*L,
    // So a constant time conditional subtraction is enough
    remove_l(u, t+8);

    WIPE_BUFFER(s);
    WIPE_BUFFER(t);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x30(%rbp), %rdi
xorl %esi, %esi
movl $0x20, %edx
callq 0x3160
movq $0x0, -0x38(%rbp)
cmpq $0x8, -0x38(%rbp)
jae 0x121ab
movq $0x0, -0x40(%rbp)
movq $0x0, -0x48(%rbp)
movq -0x48(%rbp), %rax
movl $0x8, %ecx
subq -0x38(%rbp), %rcx
cmpq %rcx, %rax
jae 0x12198
movq -0x38(%rbp), %rax
addq -0x48(%rbp), %rax
movl -0x30(%rbp,%rax,4), %eax
movq -0x10(%rbp), %rcx
movq -0x38(%rbp), %rdx
movl (%rcx,%rdx,4), %ecx
movq -0x48(%rbp), %rsi
leaq 0xae26(%rip), %rdx      # 0x1cf80
movl (%rdx,%rsi,4), %edx
imulq %rdx, %rcx
addq %rcx, %rax
addq -0x40(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movl %eax, %ecx
movq -0x38(%rbp), %rax
addq -0x48(%rbp), %rax
movl %ecx, -0x30(%rbp,%rax,4)
movq -0x40(%rbp), %rax
shrq $0x20, %rax
movq %rax, -0x40(%rbp)
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0x12126
jmp 0x1219a
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x1210b
leaq -0x90(%rbp), %rdi
xorl %esi, %esi
movl $0x40, %edx
callq 0x3160
leaq -0x90(%rbp), %rdi
leaq -0x30(%rbp), %rsi
leaq 0xa910(%rip), %rdx      # 0x1cae0
callq 0x12010
movq $0x0, -0x98(%rbp)
movq $0x0, -0xa0(%rbp)
cmpq $0x10, -0xa0(%rbp)
jae 0x1225f
movq -0xa0(%rbp), %rax
movl -0x90(%rbp,%rax,4), %eax
movq -0x10(%rbp), %rcx
movq -0xa0(%rbp), %rdx
movl (%rcx,%rdx,4), %ecx
addq %rcx, %rax
addq -0x98(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x98(%rbp), %rax
movl %eax, %ecx
movq -0xa0(%rbp), %rax
movl %ecx, -0x90(%rbp,%rax,4)
movq -0x98(%rbp), %rax
shrq $0x20, %rax
movq %rax, -0x98(%rbp)
movq -0xa0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xa0(%rbp)
jmp 0x121eb
movq -0x8(%rbp), %rdi
leaq -0x90(%rbp), %rsi
addq $0x20, %rsi
callq 0x13340
leaq -0x30(%rbp), %rdi
movl $0x20, %esi
callq 0x3890
leaq -0x90(%rbp), %rdi
movl $0x40, %esi
callq 0x3890
addq $0xa0, %rsp
popq %rbp
retq
nopl (%rax,%rax)
// File: occivink[P]pyct/monocypher.cpp
// Function: crypto_lock_aead
void crypto_lock_aead(u8 mac[16], u8 *cipher_text,
                      const u8  key[32], const u8  nonce[24],
                      const u8 *ad        , size_t ad_size,
                      const u8 *plain_text, size_t text_size)
{
    u8 sub_key[32];
    u8 auth_key[64]; // "Wasting" the whole Chacha block is faster
    crypto_hchacha20(sub_key, key, nonce);
    crypto_chacha20(auth_key, 0, 64, sub_key, nonce + 16);
    crypto_chacha20_ctr(cipher_text, plain_text, text_size,
                        sub_key, nonce + 16, 1);
    lock_auth(mac, auth_key, ad, ad_size, cipher_text, text_size);
    WIPE_BUFFER(sub_key);
    WIPE_BUFFER(auth_key);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq 0x18(%rbp), %rax
movq 0x10(%rbp), %rax
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq %r9, -0x30(%rbp)
leaq -0x50(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x38e0
leaq -0x90(%rbp), %rdi
leaq -0x50(%rbp), %rcx
movq -0x20(%rbp), %r8
addq $0x10, %r8
xorl %eax, %eax
movl %eax, %esi
movl $0x40, %edx
callq 0x4420
movq -0x10(%rbp), %rdi
movq 0x10(%rbp), %rsi
movq 0x18(%rbp), %rdx
leaq -0x50(%rbp), %rcx
movq -0x20(%rbp), %r8
addq $0x10, %r8
movl $0x1, %r9d
callq 0x3f50
movq -0x8(%rbp), %rdi
leaq -0x90(%rbp), %rsi
movq -0x28(%rbp), %rdx
movq -0x30(%rbp), %rcx
movq -0x10(%rbp), %r8
movq 0x18(%rbp), %r9
callq 0x123b0
leaq -0x50(%rbp), %rdi
movl $0x20, %esi
callq 0x3890
leaq -0x90(%rbp), %rdi
movl $0x40, %esi
callq 0x3890
addq $0x90, %rsp
popq %rbp
retq
nopl (%rax,%rax)