// File: /workspace/github_cpp_makefile_star2_O2/DiplIngFrankGerlach[P]MST/UnitTest.cpp
// Function: encryptedCommunicationExampleComplex()
void encryptedCommunicationExampleComplex()
{
   uint8_t sharedKey[16] = {11,55,11,33,67,89,91,11,55,11,33,67,89,91,0,0};

   MST_Endpoint endpointA(sharedKey);
   MST_Endpoint endpointB(sharedKey);

   uint8_t mcA[16];
   endpointA.generateMaskCounterExchange(mcA);

   uint8_t mcB[16];
   endpointB.generateMaskCounterExchange(mcB);

   //exchange of masking counters
   endpointA.decryptMaskCounterExchange(mcB);
   endpointB.decryptMaskCounterExchange(mcA);
 
   
   //now we can securely encrypt with all assurances of the protocol

   for(uint32_t i=0; i < 10000; i++)
   {
	   string plaintext = "Schiller, Goethe, Von der Vogelweide";

           uint8_t n= rand() & 0xF;
           for(uint8_t j=0; j < n; j++)
           {
              plaintext += " three more words";
           }
	   uint8_t* secureMessage;
	   uint32_t lengthSM;
	   assert( endpointA.encryptToSecureMessage((uint8_t*)plaintext.c_str(),
		                                    plaintext.length()+1,
		                                    &secureMessage,
		                                    &lengthSM) );
	   
	   uint8_t* plaintextDec;
	   uint32_t lengthPT;
	   assert( endpointB.decryptSecureMessage(secureMessage,lengthSM,&plaintextDec,&lengthPT) );

	   assert( plaintext.compare( (const char*)plaintextDec) == 0 );


           if( (rand() & 0xF) < 5 )
           {
		   string plaintext2 = "Buy 100 shares of Apple and 200 shares of Deutsche Bank";

		   n= rand() & 0xF;
		   for(uint8_t j=0; j < n; j++)
		   {
		      plaintext2 += " three more words";
		   }
		   assert( endpointB.encryptToSecureMessage((uint8_t*)plaintext2.c_str(),
				                            plaintext2.length()+1,
				                            &secureMessage,
				                            &lengthSM) );
	   
		   assert( endpointA.decryptSecureMessage(secureMessage,lengthSM,&plaintextDec,&lengthPT) );

		   assert( plaintext2.compare((const char*)plaintextDec) == 0 );
           }
   }
   
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x328, %rsp            # imm = 0x328
movaps 0x2077(%rip), %xmm0     # 0x58f0
leaq -0xc0(%rbp), %rbx
movaps %xmm0, (%rbx)
leaq -0x350(%rbp), %rdi
movq %rbx, %rsi
callq 0x4222
leaq -0x208(%rbp), %rdi
movq %rbx, %rsi
callq 0x4222
leaq -0x350(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x4286
leaq -0x208(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x4286
leaq -0x350(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x42d0
leaq -0x208(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x42d0
xorl %eax, %eax
leaq -0xb0(%rbp), %r14
leaq -0x90(%rbp), %r15
leaq 0x2229(%rip), %r12      # 0x5b21
movl %eax, -0x44(%rbp)
cmpl $0x2710, %eax           # imm = 0x2710
je 0x3a5e
movq %r14, %rdi
leaq 0x2126(%rip), %rsi      # 0x5a36
movq %r15, %rdx
callq 0x44fc
callq 0x1040
movl %eax, %r13d
andb $0xf, %r13b
xorl %ebx, %ebx
cmpb %bl, %r13b
jbe 0x393a
movq %r14, %rdi
movq %r12, %rsi
callq 0x11a0
incb %bl
jmp 0x3926
movq -0xb0(%rbp), %rsi
movl -0xa8(%rbp), %edx
incl %edx
leaq -0x350(%rbp), %rdi
leaq -0x40(%rbp), %rcx
leaq -0x2c(%rbp), %r8
callq 0x4300
testb %al, %al
je 0x3a88
movq -0x40(%rbp), %rsi
movl -0x2c(%rbp), %edx
leaq -0x208(%rbp), %rdi
leaq -0x38(%rbp), %rcx
leaq -0x48(%rbp), %r8
callq 0x43b8
testb %al, %al
je 0x3aba
movq -0x38(%rbp), %rsi
movq %r14, %rdi
callq 0x1050
testl %eax, %eax
jne 0x3aa1
callq 0x1040
andl $0xf, %eax
cmpl $0x4, %eax
ja 0x3a4c
movq %r15, %rdi
leaq 0x224a(%rip), %rsi      # 0x5c01
leaq -0x2d(%rbp), %rdx
callq 0x44fc
callq 0x1040
movl %eax, %r13d
andb $0xf, %r13b
xorl %ebx, %ebx
cmpb %bl, %r13b
jbe 0x39e2
movq %r15, %rdi
movq %r12, %rsi
callq 0x11a0
incb %bl
jmp 0x39ce
movq -0x90(%rbp), %rsi
movl -0x88(%rbp), %edx
incl %edx
leaq -0x208(%rbp), %rdi
leaq -0x40(%rbp), %rcx
leaq -0x2c(%rbp), %r8
callq 0x4300
testb %al, %al
je 0x3af6
movq -0x40(%rbp), %rsi
movl -0x2c(%rbp), %edx
leaq -0x350(%rbp), %rdi
leaq -0x38(%rbp), %rcx
leaq -0x48(%rbp), %r8
callq 0x43b8
testb %al, %al
je 0x3b15
movq -0x38(%rbp), %rsi
movq %r15, %rdi
callq 0x1050
testl %eax, %eax
jne 0x3ad7
movq %r15, %rdi
callq 0x1070
movq %r14, %rdi
callq 0x1070
movl -0x44(%rbp), %eax
incl %eax
jmp 0x38f8
leaq -0x208(%rbp), %rdi
callq 0x44ae
leaq -0x350(%rbp), %rdi
callq 0x44ae
addq $0x328, %rsp            # imm = 0x328
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x20a4(%rip), %rdi      # 0x5b33
leaq 0x1ee4(%rip), %rsi      # 0x597a
leaq 0x2105(%rip), %rcx      # 0x5ba2
pushq $0x76
jmp 0x3ad1
leaq 0x2126(%rip), %rdi      # 0x5bce
leaq 0x1ecb(%rip), %rsi      # 0x597a
leaq 0x20ec(%rip), %rcx      # 0x5ba2
pushq $0x7c
jmp 0x3ad1
leaq 0x2011(%rip), %rdi      # 0x5ad2
leaq 0x1eb2(%rip), %rsi      # 0x597a
leaq 0x20d3(%rip), %rcx      # 0x5ba2
pushq $0x7a
popq %rdx
callq 0x10a0
leaq 0x221b(%rip), %rdi      # 0x5cf9
leaq 0x1e95(%rip), %rsi      # 0x597a
leaq 0x20b6(%rip), %rcx      # 0x5ba2
movl $0x8f, %edx
callq 0x10a0
leaq 0x213c(%rip), %rdi      # 0x5c39
leaq 0x1e76(%rip), %rsi      # 0x597a
leaq 0x2097(%rip), %rcx      # 0x5ba2
movl $0x8b, %edx
callq 0x10a0
leaq 0x218e(%rip), %rdi      # 0x5caa
leaq 0x1e57(%rip), %rsi      # 0x597a
leaq 0x2078(%rip), %rcx      # 0x5ba2
movl $0x8d, %edx
callq 0x10a0
jmp 0x3b45
movq %rax, %rbx
jmp 0x3b76
jmp 0x3b45
jmp 0x3b5b
jmp 0x3b4a
jmp 0x3b5b
jmp 0x3b5b
movq %rax, %rbx
jmp 0x3b6a
movq %rax, %rbx
leaq -0x90(%rbp), %rdi
callq 0x1070
jmp 0x3b5e
movq %rax, %rbx
leaq -0xb0(%rbp), %rdi
callq 0x1070
leaq -0x208(%rbp), %rdi
callq 0x44ae
leaq -0x350(%rbp), %rdi
callq 0x44ae
movq %rbx, %rdi
callq 0x1180