01 #include "I128.HC";
02 #include "I256";
03 //https://www.rfc-editor.org/rfc/rfc8439#section-2.1
04 //
05 U0 Poly1305AESTestClamp(U8 *r) {
06   r[3]&=15;
07   r[7]&=15;
08   r[11]&=15;
09   r[15]&=15;
10   r[4]&=252;
11   r[8]&=252;
12   r[12]&=252;
13 }
14 CU128 clamp_const;
15 Str2U128(&clamp_const,"0ffffffc0ffffffc0ffffffc0fffffff");
16 U8 *Pad(U8 *str,I64 l) {
17   U8 *r=CAlloc(CeilI64(l,16));
18   MemCpy(r,str,l);
19   return r;
20 }
21 CU128 *Poly1305(CU256 *dst,U8 *msg,I64 len,U8 *key) {
22   msg=Pad(msg,len);
23   I64 i;
24   CU256 r,a,p,tmp,n,ul,s;
25 //   r = le_bytes_to_num(key[0..15])
26 //   clamp(r)
27   ToU256(&r,0);
28   U128Copy(&r,key);
29   r._u64[0]&=clamp_const._u64[0];
30   r._u64[1]&=clamp_const._u64[1];
31 //a=0
32   ToU256(&a,0);
33   ToU256(&p,0);
34   Bts(&p,130);
35 //         p = (1<<130)-5
36   ToU256(&tmp,5);
37   SubU256(&p,&p,&tmp);
38 //    s = le_bytes_to_num(key[16..31])
39   ToU256(&s,0);
40   U128Copy(&s,key+16);
41   for(i=1;i<=CeilI64(len,16)/16;i++) {
42 //           n = le_bytes_to_num(msg[((i-1)*16)..(i*16)] | [0x01])
43      ToU256(&n,1);
44      U128Copy(&n,msg+(i-1)*16);
45      if(i==CeilI64(len,16)/16) {
46         Bts(&n,(len&15)*8);
47       } else {
48         Bts(&n,128);
49      }
50 //     "BLK:\t%s\n",U256ToStr(&n);
51 //           a+=n
52      AddU256(&a,&a,&n);
53 //     "ACC+BLK:\t%s\n",U256ToStr(&a);
54      MulU256(&tmp,&r,&a);
55 //     "%s\n",U256ToStr(&tmp);
56      DivU256(&ul,&tmp,&p,&a);
57 //     "%%:\t%s\n",U256ToStr(&a);
58   }
59 //         a += s
60 //     "%%:\t%s\n",U256ToStr(&a);
61   AddU256(dst,&a,&s);
62   Free(msg);
63 //"Final\t%s\n",U256ToStr(dst);
64   return dst;
65 }
66 
67 #if __CMD_LINE__
68 U8 *test="Cryptographic Forum Research Group";
69 U8 *key="\x85\xd6\xbe\x78\x57\x55\x6d\x33\x7f\x44\x52\xfe\x42\xd5\x06\xa8\x01\x03\x80\x8a\xfb\x0d\xb2\xfd\x4a\xbf\xf6\xaf\x41\x49\xf5\x1b";
70 CU128 the_finale;
71 Poly1305(&the_finale,test,StrLen(test),key);
72 "%s\n",U128ToStr(&the_finale);
73 #endif