// File: 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:
subq $0x32108, %rsp          # imm = 0x32108
movq %rdi, 0x10060(%rsp)
movq %rdi, 0x10068(%rsp)
movq %rsi, 0x32100(%rsp)
movq %rdx, 0x320f8(%rsp)
vmovsd %xmm0, 0x320f0(%rsp)
movl %ecx, 0x320ec(%rsp)
leaq 0x320d0(%rsp), %rdi
callq 0x72a0
callq 0x73c0
movl %eax, 0x10074(%rsp)
jmp 0x5652
movl 0x10074(%rsp), %eax
addl %eax, %eax
movl %eax, %esi
leaq 0x320d0(%rsp), %rdi
callq 0x72b0
jmp 0x566c
movq $0x0, 0x320b8(%rsp)
movq 0x320b8(%rsp), %rax
movq %rax, 0x10050(%rsp)
callq 0x73c0
movl %eax, 0x1005c(%rsp)
jmp 0x5696
movq 0x10050(%rsp), %rax
movl 0x1005c(%rsp), %ecx
shll %ecx
movl %ecx, %ecx
cmpq %rcx, %rax
jae 0x5732
movq 0x32100(%rsp), %rsi
movq 0x320f8(%rsp), %rdx
vmovsd 0x320f0(%rsp), %xmm0
leaq 0x300b8(%rsp), %rdi
callq 0x7400
jmp 0x56da
leaq 0x320d0(%rsp), %rdi
leaq 0x300b8(%rsp), %rsi
callq 0x73d0
jmp 0x56f1
jmp 0x56f3
movq 0x320b8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x320b8(%rsp)
jmp 0x5678
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x320c8(%rsp)
movl %eax, 0x320c4(%rsp)
leaq 0x320d0(%rsp), %rdi
callq 0x7da0
jmp 0x5ab3
movl $0x0, 0x300b4(%rsp)
movl 0x300b4(%rsp), %eax
movl %eax, 0x10048(%rsp)
callq 0x73c0
movl %eax, 0x1004c(%rsp)
jmp 0x5759
movl 0x10048(%rsp), %eax
movl 0x1004c(%rsp), %ecx
cmpl %ecx, %eax
jae 0x58a1
movl 0x300b4(%rsp), %eax
incl %eax
movl %eax, 0x10040(%rsp)
callq 0x7640
movl %eax, 0x10044(%rsp)
jmp 0x578d
movl 0x10044(%rsp), %ecx
movl 0x10040(%rsp), %eax
imull %ecx, %eax
negb %al
movb %al, %cl
movl $0x1, %eax
shlxl %ecx, %eax, %eax
movl %eax, 0x300b0(%rsp)
movl 0x320ec(%rsp), %eax
movl 0x300b0(%rsp), %ecx
imull %ecx, %eax
movl %eax, 0x10034(%rsp)
movl 0x300b4(%rsp), %eax
movl %eax, %esi
leaq 0x320d0(%rsp), %rdi
callq 0x7650
movq %rax, %rdi
xorl %esi, %esi
callq 0x7670
movq %rax, 0x10038(%rsp)
jmp 0x57f5
movq 0x10038(%rsp), %rax
movl 0x10034(%rsp), %edx
movl (%rax), %ecx
addl %edx, %ecx
movl %ecx, (%rax)
movl 0x320ec(%rsp), %eax
movl 0x300b0(%rsp), %ecx
imull %ecx, %eax
movl %eax, 0x10028(%rsp)
movl 0x300b4(%rsp), %eax
movl %eax, 0x1002c(%rsp)
callq 0x73c0
movl %eax, 0x10030(%rsp)
jmp 0x583e
movl 0x10030(%rsp), %ecx
movl 0x1002c(%rsp), %eax
addl %ecx, %eax
movl %eax, %esi
leaq 0x320d0(%rsp), %rdi
callq 0x7650
movq %rax, %rdi
addq $0x1000, %rdi           # imm = 0x1000
xorl %esi, %esi
callq 0x7670
movq %rax, 0x10020(%rsp)
jmp 0x5878
movq 0x10020(%rsp), %rax
movl 0x10028(%rsp), %ecx
addl (%rax), %ecx
movl %ecx, (%rax)
movl 0x300b4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x300b4(%rsp)
jmp 0x573d
movb %fs:-0x28030, %al
cmpb $0x0, %al
jne 0x58cd
movq %fs:0x0, %rax
leaq -0x30030(%rax), %rdi
callq 0x76a0
jmp 0x58c4
movb $0x1, %fs:-0x28030
movl $0x0, 0x200ac(%rsp)
movl 0x200ac(%rsp), %eax
movl %eax, 0x10018(%rsp)
callq 0x73c0
movl %eax, 0x1001c(%rsp)
jmp 0x58f4
movl 0x10018(%rsp), %eax
movl 0x1001c(%rsp), %ecx
shll %ecx
cmpl %ecx, %eax
jae 0x5a52
movq %fs:0x0, %rax
leaq -0x30030(%rax), %rax
movq %rax, 0x10010(%rsp)
movl 0x200ac(%rsp), %esi
leaq 0x200b0(%rsp), %rdi
xorl %edx, %edx
callq 0x7c80
movq %rax, 0x200a0(%rsp)
movl 0x200ac(%rsp), %eax
movl %eax, %esi
leaq 0x320d0(%rsp), %rdi
callq 0x7650
movq %rax, %rdi
callq 0x7cf0
movq %rax, 0x20090(%rsp)
movq 0x20090(%rsp), %rsi
leaq 0x20098(%rsp), %rdi
callq 0x7d50
jmp 0x597f
movq 0x10010(%rsp), %rdi
movq 0x200a0(%rsp), %rsi
movq 0x20098(%rsp), %rdx
callq 0x7b70
jmp 0x599e
movq %fs:0x0, %rax
leaq -0x30030(%rax), %rax
movq %rax, 0x10008(%rsp)
movl 0x200ac(%rsp), %esi
leaq 0x200b0(%rsp), %rdi
movl $0x1, %edx
callq 0x7c80
movq %rax, 0x20088(%rsp)
movl 0x200ac(%rsp), %eax
movl %eax, %esi
leaq 0x320d0(%rsp), %rdi
callq 0x7650
movq %rax, %rdi
addq $0x1000, %rdi           # imm = 0x1000
callq 0x7cf0
movq %rax, 0x20078(%rsp)
movq 0x20078(%rsp), %rsi
leaq 0x20080(%rsp), %rdi
callq 0x7d50
jmp 0x5a1b
movq 0x10008(%rsp), %rdi
movq 0x20088(%rsp), %rsi
movq 0x20080(%rsp), %rdx
callq 0x7b70
jmp 0x5a3a
jmp 0x5a3c
movl 0x200ac(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x200ac(%rsp)
jmp 0x58d8
leaq 0x10078(%rsp), %rdi
movq %rdi, 0x10000(%rsp)
leaq 0x200b0(%rsp), %rsi
movl $0x10000, %edx          # imm = 0x10000
callq 0x2160
movq 0x10000(%rsp), %rsi
movq %rsp, %rdi
movl $0x2000, %ecx           # imm = 0x2000
rep  movsq (%rsi), %es:(%rdi)
movq 0x10060(%rsp), %rdi
callq 0x7d80
jmp 0x5a96
leaq 0x320d0(%rsp), %rdi
callq 0x7da0
movq 0x10068(%rsp), %rax
addq $0x32108, %rsp          # imm = 0x32108
retq
movq 0x320c8(%rsp), %rdi
callq 0x2290