001 #include "ChaCha20"; 002 #include "Poly1305"; 003 #include "U8Set"; 004 CU256 *Poly1305KeyGen(CU256 *p,U8 *key,U8 *nonce) { 005 I64 counter=0; 006 U32 ass[16]; 007 ChaCha20Block2(ass,key,counter,nonce); 008 U256Copy(p,ass); 009 return p; 010 } 011 CU8Set *Pad(CU8Set *set) { 012 CU8Set *r=U8SetNew; 013 U8SetAddBytes(r,set->body,set->cnt); 014 while(r->cnt&15) 015 U8SetAdd(r,0); 016 return r; 017 } 018 U32 *ChaCha20AEADEncrypt 019 ( 020 CU256 *tag, 021 U8 *aad,I64 aad_len, 022 U8 *key,I64 key_len, 023 U8 *iv,I64 iv_len, 024 U8 *const,I64 const_len, 025 U8 *plain,I64 plain_len 026 ) { 027 I64 ctlen; 028 CU256 otk; 029 CU8Set *nonce=U8SetNew; 030 CU8Set *mac_data,*aadv,*tmp; 031 032 U8SetAddBytes(nonce,const,const_len); 033 U8SetAddBytes(nonce,iv,iv_len); 034 Poly1305KeyGen(&otk,key,nonce->body); 035 036 U8SetDel(nonce); 037 038 U8 *cipher_text=ChaCha20Enc(key,nonce->body,plain,plain_len,&ctlen); 039 aadv=U8SetNew; 040 U8SetAddBytes(aadv,aad,aad_len); 041 mac_data=Pad(aadv); 042 U8SetDel(aadv); 043 044 aadv=U8SetNew(); 045 U8SetAddBytes(aadv,cipher_text,ctlen); 046 tmp=Pad(aadv); 047 U8SetDel(aadv); 048 U8SetAddBytes(mac_data,tmp->body,tmp->cnt); 049 U8SetDel(tmp); 050 051 U8SetAddBytes(mac_data,&aad_len,8); 052 U8SetAddBytes(mac_data,&ctlen,8); 053 "%s\n",U256ToStr(&otk); 054 if(tag) 055 Poly1305(tag,mac_data->body,mac_data->cnt,&otk); 056 U8SetDel(mac_data); 057 return cipher_text; 058 } 059 #if __CMD_LINE__ 060 U0 ValidateTag(U8 *plain,U8 *key,U8 *string) { 061 CU256 r; 062 CU8Set *e=U8SetFromHex(string); 063 CU8Set *p=U8SetFromHex(plain),*k=U8SetFromHex(key); 064 Poly1305(&r,p->body,p->cnt,k->body); 065 if(!MemCmp(e->body,&r,4*4)) { 066 "PASS\n"; 067 } else { 068 "FAIL\n"; 069 "%s,%s\n",U128ToStr(e->body),U128ToStr(&r); 070 } 071 U8SetDel(e); 072 U8SetDel(p); 073 U8SetDel(k); 074 } 075 U0 Copied() { 076 //https://github.com/calvinmetcalf/chacha20poly1305/blob/master/test/poly1305.js#L34 077 CU256 ass; 078 U8 *plain,*key,*tag; 079 plain="27 54 77 61 73 20 62 72 69 6c 6c 69 67 2c 20 61'+ 080 '6e 64 20 74 68 65 20 73 6c 69 74 68 79 20 74 6f'+ 081 '76 65 73 0a 44 69 64 20 67 79 72 65 20 61 6e 64'+ 082 '20 67 69 6d 62 6c 65 20 69 6e 20 74 68 65 20 77'+ 083 '61 62 65 3a 0a 41 6c 6c 20 6d 69 6d 73 79 20 77'+ 084 '65 72 65 20 74 68 65 20 62 6f 72 6f 67 6f 76 65'+ 085 '73 2c 0a 41 6e 64 20 74 68 65 20 6d 6f 6d 65 20'+ 086 '72 61 74 68 73 20 6f 75 74 67 72 61 62 65 2e"; 087 key="1c 92 40 a5 eb 55 d3 8a f3 33 88 86 04 f6 b5 f0'+ 088 '47 39 17 c1 40 2b 80 09 9d ca 5c bc 20 70 75 c0"; 089 tag="45 41 66 9a 7e aa ee 61 e7 08 dc 7c bc c5 eb 62"; 090 ValidateTag(plain,key,tag); 091 092 093 plain="48656c6c6f20776f726c6421"; 094 key="746869732069732033322d62797465206b657920666f7220506f6c7931333035"; 095 tag=" a6f745008f81c916a20dcc74eef2b2f0"; 096 ValidateTag(plain,key,tag); 097 098 plain="416e79207375626d697373696f6e20746f20746865204945544620696e74656e6465642062792074686520436f6e7472696275746f7220666f7220""7075626c69636174696f6e20617320616c6c206f722070617274206f6620616e204945544620496e7465726e65742d4472616674206f72205246432""0616e6420616e792073746174656d656e74206d6164652077697468696e2074686520636f6e74657874206f6620616e204945544620616374697669747920697320636f6e7369646572656420616e20224945544620436f6e747269627574696f6e222e20537563682073746174656d656e747320696e636c756465206f72616c2073746174656d656e747320696e20494554462073657373696f6e732c2061732077656c6c206173207772697474656e20616e6420656c656374726f6e696320636f6d6d756e69636174696f6e73206d61646520617420616e7920746""96d65206f7220706c6163652c207768696368206172652061646472657373656420746f"; 099 key="00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'+ 100 '36 e5 f6 b5 c5 e0 60 70 f0 ef ca 96 22 7a 86 3e"; 101 tag="36 e5 f6 b5 c5 e0 60 70 f0 ef ca 96 22 7a 86 3e"; 102 ValidateTag(plain,key,tag); 103 key="'36 e5 f6 b5 c5 e0 60 70 f0 ef ca 96 22 7a 86 3e00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'"; 104 tag="'f3 47 7e 7c d9 54 17 af 89 a6 b8 79 4c 31 0c f0'"; 105 ValidateTag(plain,key,tag); 106 107 key="36 e5 f6 b5 c5 e0 60 70 f0 ef ca 96 22 7a 86 3e""00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00"; 108 tag="f3 47 7e 7c d9 54 17 af 89 a6 b8 79 4c 31 0c f0"; 109 plain=" 110 41 6e 79 20 73 75 62 6d 69 73 73 69 6f 6e 20 74 111 6f 20 74 68 65 20 49 45 54 46 20 69 6e 74 65 6e 112 64 65 64 20 62 79 20 74 68 65 20 43 6f 6e 74 72 113 69 62 75 74 6f 72 20 66 6f 72 20 70 75 62 6c 69 114 63 61 74 69 6f 6e 20 61 73 20 61 6c 6c 20 6f 72 115 20 70 61 72 74 20 6f 66 20 61 6e 20 49 45 54 46 116 20 49 6e 74 65 72 6e 65 74 2d 44 72 61 66 74 20 117 6f 72 20 52 46 43 20 61 6e 64 20 61 6e 79 20 73 118 74 61 74 65 6d 65 6e 74 20 6d 61 64 65 20 77 69 119 74 68 69 6e 20 74 68 65 20 63 6f 6e 74 65 78 74 120 20 6f 66 20 61 6e 20 49 45 54 46 20 61 63 74 69 121 76 69 74 79 20 69 73 20 63 6f 6e 73 69 64 65 72 122 65 64 20 61 6e 20 22 49 45 54 46 20 43 6f 6e 74 123 72 69 62 75 74 69 6f 6e 22 2e 20 53 75 63 68 20 124 73 74 61 74 65 6d 65 6e 74 73 20 69 6e 63 6c 75 125 64 65 20 6f 72 61 6c 20 73 74 61 74 65 6d 65 6e 126 74 73 20 69 6e 20 49 45 54 46 20 73 65 73 73 69 127 6f 6e 73 2c 20 61 73 20 77 65 6c 6c 20 61 73 20 128 77 72 69 74 74 65 6e 20 61 6e 64 20 65 6c 65 63 129 74 72 6f 6e 69 63 20 63 6f 6d 6d 75 6e 69 63 61 130 74 69 6f 6e 73 20 6d 61 64 65 20 61 74 20 61 6e 131 79 20 74 69 6d 65 20 6f 72 20 70 6c 61 63 65 2c 132 20 77 68 69 63 68 20 61 72 65 20 61 64 64 72 65 133 73 73 65 64 20 74 6f 134 "; 135 ValidateTag(plain,key,tag); 136 137 "$RED$BELOW IS BORKED(Not my fault)?$FD$\n"; 138 plain="50 51 52 53 c0 c1 c2 c3 c4 c5 c6 c7 00 00 00 00 d3 1a 8d 34 64 8e 60 db 7b 86 af bc 53 ef 7e c2 a4 ad ed 51 29 6e 08 fe a9 e2 b5 a7 36 ee 62 d6 " 139 "3d be a4 5e 8c a9 67 12 82 fa fb 69 da 92 72 8b1a 71 de 0a 9e 06 0b 29 05 d6 a5 b6 7e cd 3b 3692 dd bd 7f 2d 77 8b 8c 98 03 ae e3 28 09 1b 58fa b3 24 e4 fa d6 75 94 55 85 80 8b 48 31 d7 bc3f f4 de f0 8e 4b 7a 9d e5 76 d2 65 86 ce c6 4b" 140 "61 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00""0c 00 00 00 00 00 00 00 72 00 00 00 00 00 00 00"; 141 key="7b ac 2b 25 2d b4 47 af 09 b6 7a 55 a4 e9 55 84 7b ac 2b 25 2d b4 47 af 09 b6 7a 55 a4 e9 55 84"; 142 tag="1a:e1:0b:59:4f:09:e2:6a:7e:90:2e:cb:d0:60:06:91"; 143 ValidateTag(plain,key,tag); 144 145 146 } 147 148 Copied; 149 #endif