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