// File: rupc[P]xor-secret-sharing-scheme/main.cpp
// Function: main
int main(int argc, char *argv[])
{
    srand (time(NULL));
    XORSecretShares xss(128);
    std::cout << "original secret" << "\n";
    std::string orig_secret = xss.generate_random_secret();
    std::cout << orig_secret << "\n\n";
    std::cout << "shadows" << "\n";
    auto shadows = xss.split(14);

    for (const auto &p : shadows) {
        std::cout << p << "\n";
    }

    std::cout << "\n";
    std::cout << "All shadows are XOR-ed" << "\n";

    auto key_size = xss.get_key_size();
    std::string xored_share = shadows[0];

    for (int i = 1; i < shadows.size(); i++) {
        switch (key_size) {
            case 64: {
                std::bitset<64> xored_share_64(xored_share);
                std::bitset<64> share_64(shadows[i]);
                xored_share = (xored_share_64^=share_64).to_string();
            }
                break;
            case 128: {
                std::bitset<128> xored_share_128(xored_share);
                std::bitset<128> share_128(shadows[i]);
                xored_share = (xored_share_128^=share_128).to_string();
            }
                break;
            case 256: {
                std::bitset<256> xored_share_256(xored_share);
                std::bitset<256> _share_256(shadows[i]);
                xored_share = (xored_share_256^=_share_256).to_string();
            }
                break;
            default: {
                std::bitset<64> xored_share_64(xored_share);
                std::bitset<64> _share_64(shadows[i]);
                xored_share = (xored_share_64^=_share_64).to_string();
            }
                break;
        }
        
    }

    std::cout << "Retrived Secret" << "\n";
    std::cout << xored_share << "\n";

    std::cout << "Original Secret" << "\n";
    std::cout << orig_secret << "\n";

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x270, %rsp            # imm = 0x270
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
xorl %eax, %eax
movl %eax, %edi
callq 0x2120
movl %eax, %edi
callq 0x2140
leaq -0x70(%rbp), %rdi
movl $0x80, %esi
callq 0x3890
movq 0x6292(%rip), %rdi      # 0x8fd0
leaq 0x32c5(%rip), %rsi      # 0x600a
callq 0x2150
movq %rax, -0x210(%rbp)
jmp 0x2d53
movq -0x210(%rbp), %rdi
leaq 0x32ba(%rip), %rsi      # 0x601b
callq 0x2150
jmp 0x2d68
leaq -0xa0(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x2390
jmp 0x2d7a
movq 0x624f(%rip), %rdi      # 0x8fd0
leaq -0xa0(%rbp), %rsi
callq 0x2110
movq %rax, -0x218(%rbp)
jmp 0x2d96
movq -0x218(%rbp), %rdi
leaq 0x3276(%rip), %rsi      # 0x601a
callq 0x2150
jmp 0x2dab
movq 0x621e(%rip), %rdi      # 0x8fd0
leaq 0x3264(%rip), %rsi      # 0x601d
callq 0x2150
movq %rax, -0x220(%rbp)
jmp 0x2dc7
movq -0x220(%rbp), %rdi
leaq 0x3246(%rip), %rsi      # 0x601b
callq 0x2150
jmp 0x2ddc
leaq -0xb8(%rbp), %rdi
leaq -0x70(%rbp), %rsi
movl $0xe, %edx
callq 0x2740
jmp 0x2df3
leaq -0xb8(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0xc0(%rbp), %rdi
callq 0x3960
movq %rax, -0xc8(%rbp)
movq -0xc0(%rbp), %rdi
callq 0x3990
movq %rax, -0xd0(%rbp)
leaq -0xc8(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
callq 0x39c0
testb $0x1, %al
jne 0x2e43
jmp 0x2eca
leaq -0xc8(%rbp), %rdi
callq 0x3a00
movq %rax, -0xd8(%rbp)
movq -0xd8(%rbp), %rsi
movq 0x616c(%rip), %rdi      # 0x8fd0
callq 0x2110
movq %rax, -0x228(%rbp)
jmp 0x2e72
movq -0x228(%rbp), %rdi
leaq 0x319b(%rip), %rsi      # 0x601b
callq 0x2150
jmp 0x2e87
jmp 0x2e89
leaq -0xc8(%rbp), %rdi
callq 0x3a20
jmp 0x2e27
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x332f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x3323
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x3317
movq 0x60ff(%rip), %rdi      # 0x8fd0
leaq 0x3143(%rip), %rsi      # 0x601b
callq 0x2150
jmp 0x2edf
movq 0x60ea(%rip), %rdi      # 0x8fd0
leaq 0x3138(%rip), %rsi      # 0x6025
callq 0x2150
movq %rax, -0x230(%rbp)
jmp 0x2efb
movq -0x230(%rbp), %rdi
leaq 0x3112(%rip), %rsi      # 0x601b
callq 0x2150
jmp 0x2f10
leaq -0x70(%rbp), %rdi
callq 0x3a40
movl %eax, -0x234(%rbp)
jmp 0x2f21
movl -0x234(%rbp), %eax
movl %eax, -0xdc(%rbp)
xorl %eax, %eax
movl %eax, %esi
leaq -0xb8(%rbp), %rdi
callq 0x3760
movq %rax, %rsi
leaq -0x100(%rbp), %rdi
callq 0x2080
jmp 0x2f4e
movl $0x1, -0x104(%rbp)
movslq -0x104(%rbp), %rax
movq %rax, -0x240(%rbp)
leaq -0xb8(%rbp), %rdi
callq 0x3810
movq %rax, %rcx
movq -0x240(%rbp), %rax
cmpq %rcx, %rax
jae 0x3213
movl -0xdc(%rbp), %eax
movl %eax, -0x244(%rbp)
subl $0x40, %eax
je 0x2fc1
jmp 0x2f98
movl -0x244(%rbp), %eax
subl $0x80, %eax
je 0x3067
jmp 0x2fab
movl -0x244(%rbp), %eax
subl $0x100, %eax            # imm = 0x100
je 0x30f0
jmp 0x3179
xorl %eax, %eax
movl %eax, %edx
leaq -0x110(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0x3470
jmp 0x2fda
movslq -0x104(%rbp), %rsi
leaq -0xb8(%rbp), %rdi
callq 0x3760
movq %rax, %rsi
xorl %eax, %eax
movl %eax, %edx
leaq -0x118(%rbp), %rdi
callq 0x3470
jmp 0x3002
leaq -0x110(%rbp), %rdi
leaq -0x118(%rbp), %rsi
callq 0x3780
movq %rax, %rsi
leaq -0x138(%rbp), %rdi
callq 0x34d0
jmp 0x3026
leaq -0x100(%rbp), %rdi
leaq -0x138(%rbp), %rsi
callq 0x2190
leaq -0x138(%rbp), %rdi
callq 0x20c0
jmp 0x31fd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x100(%rbp), %rdi
callq 0x20c0
jmp 0x3317
xorl %eax, %eax
movl %eax, %edx
leaq -0x148(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0x3500
jmp 0x3080
movslq -0x104(%rbp), %rsi
leaq -0xb8(%rbp), %rdi
callq 0x3760
movq %rax, %rsi
xorl %eax, %eax
movl %eax, %edx
leaq -0x158(%rbp), %rdi
callq 0x3500
jmp 0x30a8
leaq -0x148(%rbp), %rdi
leaq -0x158(%rbp), %rsi
callq 0x37b0
movq %rax, %rsi
leaq -0x178(%rbp), %rdi
callq 0x3560
jmp 0x30cc
leaq -0x100(%rbp), %rdi
leaq -0x178(%rbp), %rsi
callq 0x2190
leaq -0x178(%rbp), %rdi
callq 0x20c0
jmp 0x31fd
xorl %eax, %eax
movl %eax, %edx
leaq -0x198(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0x3590
jmp 0x3109
movslq -0x104(%rbp), %rsi
leaq -0xb8(%rbp), %rdi
callq 0x3760
movq %rax, %rsi
xorl %eax, %eax
movl %eax, %edx
leaq -0x1b8(%rbp), %rdi
callq 0x3590
jmp 0x3131
leaq -0x198(%rbp), %rdi
leaq -0x1b8(%rbp), %rsi
callq 0x37e0
movq %rax, %rsi
leaq -0x1d8(%rbp), %rdi
callq 0x35f0
jmp 0x3155
leaq -0x100(%rbp), %rdi
leaq -0x1d8(%rbp), %rsi
callq 0x2190
leaq -0x1d8(%rbp), %rdi
callq 0x20c0
jmp 0x31fd
xorl %eax, %eax
movl %eax, %edx
leaq -0x1e0(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0x3470
jmp 0x3192
movslq -0x104(%rbp), %rsi
leaq -0xb8(%rbp), %rdi
callq 0x3760
movq %rax, %rsi
xorl %eax, %eax
movl %eax, %edx
leaq -0x1e8(%rbp), %rdi
callq 0x3470
jmp 0x31ba
leaq -0x1e0(%rbp), %rdi
leaq -0x1e8(%rbp), %rsi
callq 0x3780
movq %rax, %rsi
leaq -0x208(%rbp), %rdi
callq 0x34d0
jmp 0x31de
leaq -0x100(%rbp), %rdi
leaq -0x208(%rbp), %rsi
callq 0x2190
leaq -0x208(%rbp), %rdi
callq 0x20c0
jmp 0x31ff
movl -0x104(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x104(%rbp)
jmp 0x2f58
movq 0x5db6(%rip), %rdi      # 0x8fd0
leaq 0x2e1b(%rip), %rsi      # 0x603c
callq 0x2150
movq %rax, -0x250(%rbp)
jmp 0x322f
movq -0x250(%rbp), %rdi
leaq 0x2dde(%rip), %rsi      # 0x601b
callq 0x2150
jmp 0x3244
movq 0x5d85(%rip), %rdi      # 0x8fd0
leaq -0x100(%rbp), %rsi
callq 0x2110
movq %rax, -0x258(%rbp)
jmp 0x3260
movq -0x258(%rbp), %rdi
leaq 0x2dad(%rip), %rsi      # 0x601b
callq 0x2150
jmp 0x3275
movq 0x5d54(%rip), %rdi      # 0x8fd0
leaq 0x2dc9(%rip), %rsi      # 0x604c
callq 0x2150
movq %rax, -0x260(%rbp)
jmp 0x3291
movq -0x260(%rbp), %rdi
leaq 0x2d7c(%rip), %rsi      # 0x601b
callq 0x2150
jmp 0x32a6
movq 0x5d23(%rip), %rdi      # 0x8fd0
leaq -0xa0(%rbp), %rsi
callq 0x2110
movq %rax, -0x268(%rbp)
jmp 0x32c2
movq -0x268(%rbp), %rdi
leaq 0x2d4b(%rip), %rsi      # 0x601b
callq 0x2150
jmp 0x32d7
movl $0x0, -0x4(%rbp)
leaq -0x100(%rbp), %rdi
callq 0x20c0
leaq -0xb8(%rbp), %rdi
callq 0x3830
leaq -0xa0(%rbp), %rdi
callq 0x20c0
leaq -0x70(%rbp), %rdi
callq 0x3a50
movl -0x4(%rbp), %eax
addq $0x270, %rsp            # imm = 0x270
popq %rbp
retq
leaq -0xb8(%rbp), %rdi
callq 0x3830
leaq -0xa0(%rbp), %rdi
callq 0x20c0
leaq -0x70(%rbp), %rdi
callq 0x3a50
movq -0x78(%rbp), %rdi
callq 0x2220
nopw %cs:(%rax,%rax)
nopl (%rax,%rax)