// File: /workspace/github_cpp_makefile_star2_O3/ushitora-anqou[P]aqtfhe2/./aqtfhe2.hpp
// Function: aqtfhe2::trgswfft_lvl1<aqtfhe2::params::CGGI16> aqtfhe2::trgswfft_lvl1<aqtfhe2::params::CGGI16>::sym_encrypt<std::random_device>(std::random_device&, aqtfhe2::detail::nd_array<unsigned int, 1024ul> const&, double, unsigned int)
trgswfft_lvl1<P> trgswfft_lvl1<P>::sym_encrypt(
    RandomEngine &rand,
    const typename secret_key<P>::container_key_lvl1 &key_lvl1, double alpha,
    uint32_t plain)
{
    // trgsw sym encrypt
    // FIXME: more efficient implementation?
    std::vector<trlwe_lvl1<P>> trgsw;
    trgsw.reserve(2 * P::l());
    for (size_t i = 0; i < 2 * P::l(); i++)
        trgsw.push_back(trlwe_lvl1<P>::sym_encrypt_zero(rand, key_lvl1, alpha));
    for (uint32_t i = 0; i < P::l(); i++) {
        uint32_t h = 1U << (32 - (i + 1) * P::Bgbit());
        trgsw[i].poly0_[0] += plain * h;
        trgsw[i + P::l()].poly1_[0] += plain * h;
    }

    // trgswfft sym encrypt
    thread_local detail::fft_processor<P::N()> fftproc;
    container trgswfft;
    for (uint32_t i = 0; i < 2 * P::l(); i++) {
        fftproc.twist_ifft_lvl1(trgswfft.slice(i, 0), trgsw[i].poly0_.slice());
        fftproc.twist_ifft_lvl1(trgswfft.slice(i, 1), trgsw[i].poly1_.slice());
    }

    return trgswfft_lvl1{std::move(trgswfft)};
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x12038, %rsp          # imm = 0x12038
vmovsd %xmm0, 0x8(%rsp)
movq %rdi, 0x30(%rsp)
leaq 0x10(%rsp), %rdi
vxorps %xmm0, %xmm0, %xmm0
movl %ecx, %ebp
movq %rdx, %r14
movq %rsi, %r15
vmovaps %xmm0, (%rdi)
movq $0x0, 0x10(%rdi)
movl $0x4, %esi
movl $0x4, %r13d
callq 0x420e
leaq 0x38(%rsp), %r12
vmovsd 0x8(%rsp), %xmm0
movq %r12, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x42f2
movq 0x18(%rsp), %rbx
cmpq 0x20(%rsp), %rbx
je 0x3cdc
movl $0x2000, %edx           # imm = 0x2000
movq %rbx, %rdi
movq %r12, %rsi
callq 0x2130
addq $0x2000, %rbx           # imm = 0x2000
movq %rbx, 0x18(%rsp)
jmp 0x3cec
leaq 0x10(%rsp), %rdi
movq %rbx, %rsi
movq %r12, %rdx
callq 0x49b6
decq %r13
jne 0x3c9e
movq 0x10(%rsp), %rax
movb $0x1, %cl
xorl %edx, %edx
leal (%rdx,%rdx), %esi
shlq $0xd, %rdx
leal (%rsi,%rsi,4), %esi
negl %esi
addb $0x16, %sil
shlxl %esi, %ebp, %esi
addl %esi, (%rax,%rdx)
addl %esi, 0x5000(%rax,%rdx)
movl $0x1, %edx
testb $0x1, %cl
movl $0x0, %ecx
jne 0x3cfa
cmpb $0x0, %fs:-0x28030
je 0x3e66
movq %fs:0x0, %rax
movl $0x1000, %r13d          # imm = 0x1000
leaq 0x38(%rsp), %r15
xorl %ebp, %ebp
xorl %r14d, %r14d
leaq -0x30030(%rax), %rax
movq %rax, 0x8(%rsp)
movq 0x10(%rsp), %rax
movq %r14, %r12
shlq $0xe, %r12
xorl %ecx, %ecx
addq %rbp, %rax
vcvtdq2pd (%rax,%rcx,4), %zmm0
vmovups %zmm0, 0x38(%rsp,%rcx,8)
addq $0x8, %rcx
cmpq $0x400, %rcx            # imm = 0x400
jne 0x3d6d
movq 0x8(%rsp), %rdi
movq %r15, %rsi
leaq 0x2038(%rsp,%r12), %rbx
vzeroupper
callq 0x4f1a
movl $0x2000, %edx           # imm = 0x2000
movq %rbx, %rdi
movq %r15, %rsi
callq 0x2130
movq 0x10(%rsp), %rax
xorl %ecx, %ecx
addq %r13, %rax
vcvtdq2pd (%rax,%rcx,4), %zmm0
vmovups %zmm0, 0x38(%rsp,%rcx,8)
addq $0x8, %rcx
cmpq $0x400, %rcx            # imm = 0x400
jne 0x3dbe
movq 0x8(%rsp), %rdi
leaq 0x4038(%rsp), %rax
movq %r15, %rsi
addq %rax, %r12
vzeroupper
callq 0x4f1a
movl $0x2000, %edx           # imm = 0x2000
movq %r12, %rdi
movq %r15, %rsi
callq 0x2130
movl $0x2000, %eax           # imm = 0x2000
incq %r14
addq %rax, %rbp
addq %rax, %r13
cmpq $0x4, %r14
jne 0x3d5c
movq 0x30(%rsp), %rbx
leaq 0x2038(%rsp), %rsi
movl $0x10000, %edx          # imm = 0x10000
movq %rbx, %rdi
callq 0x2130
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x3e51
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x2180
movq %rbx, %rax
addq $0x12038, %rsp          # imm = 0x12038
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %fs:0x0, %rax
leaq -0x30030(%rax), %rdi
callq 0x43f0
movb $0x1, %fs:-0x28030
jmp 0x3d37
jmp 0x3e8b
movq 0x10(%rsp), %rdi
movq %rax, %rbx
testq %rdi, %rdi
je 0x3ea5
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x2180
movq %rbx, %rdi
callq 0x21d0
nop