def u(b): n=0 for i in range(len(b)):n|=b[i]<<(i*8) return n unu=lambda n,l:bytes(n>>i&255 for i in range(0,l,8)) add=lambda x,y:x+y&0xffffffff rotl=lambda x,n:x<>32-n def qr(a,b,c,d):a=add(a,b);d^=a;d=rotl(d,16);c=add(c,d);b^=c;b=rotl(b,12);a=add(a,b);d^=a;d=rotl(d,8);c=add(c,d);b^=c;b=rotl(b,7);return a,b,c,d def ccb(k,c,n): s=[0x61707865,0x3320646e,0x79622d32,0x6b206574,u(k[:4]),u(k[4:8]),u(k[8:12]),u(k[12:16]),u(k[16:20]),u(k[20:24]),u(k[24:28]),u(k[28:]),c,u(n[:4]),u(n[4:8]),u(n[8:])] o=s[:] def x(a,b,c,d):s[a],s[b],s[c],s[d]=qr(s[a],s[b],s[c],s[d]) for _ in range(10):x(0,4,8,12);x(1,5,9,13);x(2,6,10,14);x(3,7,11,15);x(0,5,10,15);x(1,6,11,12);x(2,7,8,13);x(3,4,9,14) return b''.join(unu(add(o[i],s[i]),32)for i in range(len(s))) cd=lambda a,b:a//b if a%b==0 else a//b+1 def chacha20(k,c,n,m): for i in range(cd(len(m),64)):yield from(a^b for a,b in zip(m[i*64:i*64+64],ccb(k,c+i,n))) def poly1305(m,k): r=bytearray(k[:16]);r[3]&=15;r[7]&=15;r[11]&=15;r[15]&=15;r[4]&=252;r[8]&=252;r[12]&=252;r=u(r);s=u(k[16:]);P=2**130-5;a=0 for i in range(cd(len(m),16)):a=(a+u(m[i*16:i*16+16]+b'\x01'))*r%P return unu(a+s,128) p16=lambda x:b'\x00'*(-len(x)%16) tag=lambda a,k,n,c:poly1305(b''.join((a,p16(a),c,p16(c),unu(len(a),64),unu(len(c),64))),ccb(k,0,n)[:32]) def enc(a,k,n,p):c=bytes(chacha20(k,1,n,p));return c+tag(a,k,n,c) def dec(a,k,n,e): c=e[:-16] if not secrets.compare_digest(e[-16:],tag(a,k,f+i,c)):return None return bytes(chacha20(k,1,f+i,c))