den4,den2);M(t,den6,num);M(t,t,den);pow2523(t,t);M(t,t,num);M(t,t,den);M(t,t,den);M(r[0],t,den);S(chk,r[0]);M(chk,chk,den);if(neq25519(chk,
if(unpackneg(q,pk))return-1;FOR(i,n)m[i]=sm[i];FOR(i,32)m[i+32]=pk[i];crypto_hash(h,m,n);reduce(h);scalarmult(p,q,h);scalarbase(q,sm+32);add
add1305(h,c);FOR(j,16)out[j]=h[j];return 0;}int crypto_onetimeauth_verify(const u8*h,const u8*m,u64 n,const u8*k){u8 x[16];
crypto_box_keypair(u8*y,u8*x){randombytes(x,32);return crypto_scalarmult_base(y,x);}int crypto_box_beforenm(u8*k,const u8*y,const u8*x){u8 s
const u8 iv[64]={0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08,0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b,0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b,
31)t[i]=0;FOR(i,16)FOR(j,16)t[i+j]+=a[i]*b[j];FOR(i,15)t[i]+=38*t[i+16];FOR(i,16)o[i]=t[i];car25519(o);car25519(o);}sv S(gf o,const gf a){M(
crypto_scalarmult(u8*q,const u8*n,const u8*p){u8 z[32];i64 x[80],r,i;gf a,b,c,d,e,f;FOR(i,31)z[i]=n[i];z[31]=(n[31]&127)|64;z[0]&=248;
scalarmult(p,q,s);}int crypto_sign_keypair(u8*pk,u8*sk){u8 d[64];gf p[4];int i;randombytes(sk,32);crypto_hash(d,sk,32);d[0]&=248;d[31]&=127;
unpack25519(x,p);FOR(i,16){b[i]=x[i];d[i]=a[i]=c[i]=0;}a[0]=d[0]=1;for(i=254;i>=0;–i){r=(z[i>>3]>>(i&7))&1;sel25519(a,b,r);sel25519(c,d,r);
car25519(t);FOR(j,2){m[0]=t[0]-0xffed;for(i=1;i<15;i++){m[i]=t[i]-0xffff-((m[i-1]>>16)&1);m[i-1]&=0xffff;}m[15]=t[15]-0x7fff-((m[14]>>16)&1)
{x[j]+=carry-16*x[i]*L[j-(i-32)];carry=(x[j]+128)>>8;x[j]-=carry<;}x[j]+=carry;x[i]=0;}carry=0;FOR(j,32){x[j]+=carry-(x
);crypto_hashblocks(h,x,n);FOR(i,64)out[i]=h[i];return 0;}sv add(gf p[4],gf q[4]){gf a,b,c,d,t,e,f,g,h;Z(a,p[1],p[0]);Z(t,q[1],q[0]);M(a,a,t
sigma);return crypto_stream_salsa20_xor(c,m,d,n+16,s);}sv add1305(u32*h,const u32*c){u32 j,u=0;FOR(j,17){u+=h[j]+c[j];h[j]=u7u>>=8;}}
Sigma1(u64 x){return R(x,14)^R(x,18)^R(x,41);}static u64 sigma0(u64 x){return R(x,1)^R(x,8)^(x>>7);}static u64 sigma1(u64 x){return R(x,19)^
,k,sigma);FOR(i,64)c[i]=(m?m[i]:0)^x[i];u=1;for(i=8;i<16;++i){u+=(u32)z[i];z[i]=u;u>>=8;}b-=64;c+=64;if(m)m+=64;}if(b){crypto_core_salsa20(x
);return 0;}int crypto_sign_open(u8*m,u64*mlen,const u8*sm,u64 n,const u8*pk){int i;u8 t[32],h[64];gf p[4],q[4];*mlen= -1;if(n<64)return-1;
{return crypto_secretbox(c,m,d,n,k);}int crypto_box_open_afternm(u8*m,const u8*c,u64 d,const u8*n,const u8*k){return crypto_secretbox_open(m
;b=(m[15]>>16)&1;m[14]&=0xffff;sel25519(t,m,1-b);}FOR(i,16){o[2*i]=t[i]ÿo[2*i+1]=t[i]>>8;}}static int neq25519(const gf a,const gf b){
]=iv[i];crypto_hashblocks(h,m,n);m+=n;n&=127;m-=n;FOR(i,256)x[i]=0;FOR(i,n)x[i]=m[i];x[n]=128;n=256-128*(n<112);x[n-9]=b>>61;ts64(x+n-8,b<<3
0xc0a4,0x53fe,0xcd6e,0x36d3,0x2169},Y={0x6658,0x6666,0x6666,0x6666,0x6666,0x6666,0x6666,0x6666,0x6666,0x6666,0x6666,0x6666,0x6666,0x6666,
,den4,den6;set25519(r[2],gf1);unpack25519(r[1],p);S(num,r[1]);M(den,num,D);Z(num,num,r[2]);A(den,r[2],den);S(den2,den);S(den4,den2);M(den6,
#define sv static void
y)^(~x&z);}static u64 Maj(u64 x,u64 y,u64 z){return(x&y)^(x&z)^(y&z);}static u64 Sigma0(u64 x){return R(x,28)^R(x,34)^R(x,39);}static u64
1);FOR(i,16){t=c&(p[i]^q[i]);p[i]^=t;q[i]^=t;}}sv pack25519(u8*o,const gf n){int i,j,b;gf m,t;FOR(i,16)t[i]=n[i];car25519(t);car25519(t);
+Ch(a[4],a[5],a[6])+K[i]+w[i%16];b[7]=t+Sigma0(a[0])+Maj(a[0],a[1],a[2]);b[3]+=t;FOR(j,8)a[(j+1)%8]=b[j];if(i%16==15)FOR(j,16)w[j]+=w[
2014-04-27T16:21:09 (j+9)%16]+sigma0(w[(j+1)%16])+sigma1(w[(j+14)%16]);}FOR(i,8){a[i]+=z[i];z[i]=a[i];}m+=128;n-=128;}FOR(i,8)ts64(x+8*i,z[i]);return n;}static
p[1],h,g);M(p[2],g,f);M(p[3],e,h);}sv cswap(gf p[4],gf q[4],u8 b){int i;FOR(i,4)sel25519(p[i],q[i],b);}sv pack(u8*r,gf p[4]){gf tx,ty,zi;
0xd130,0xeef3,0x80f2,0x198e,0xfce7,0x56df,0xd9dc,0x2406},X={0xd51a,0x8f25,0x2d60,0xc956,0xa7b2,0x9525,0xc760,0x692c,0xdc5c,0xfdd6,0xe231,
const u8*k,const u8*c){core(out,in,k,c,1);return 0;}static const u8 sigma[16]=“expand 32-byte k”;int crypto_stream_salsa20_xor(u8*c,const u8
]+t[0],9);t[3]^=L32(t[2]+t[1],13);t[0]^=L32(t[3]+t[2],18);FOR(m,4)w[4*j+(j+m)%4]=t[m];}FOR(m,16)x[m]=w[m];}if(h){FOR(i,16)x[i]+=y[i];FOR(i,4
0x4141,0x0a4d,0x0070,0xe898,0x7779,0x4079,0x8cc7,0xfe73,0x2b6f,0x6cee,0x5203},D2={0xf159,0x26b2,0x9b94,0xebd6,0xb156,0x8283,0x149a,0x00e0,
*out,const u8*in,const u8*k,const u8*c,int h){u32 w[16],x[16],y[16],t[4];int i,j,m;FOR(i,4){x[5*i]=ld32(c+4*i);x[1+i]=ld32(k+4*i);x[6+i]=
u64)r[i];FOR(i,32)FOR(j,32)x[i+j]+=h[i]*(u64)d[j];modL(sm+32,x);return 0;}static int unpackneg(gf r[4],const u8 p[32]){gf t,chk,num,den,den2
0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1,0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1,0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f,0x1f,0x83,0xd9,0xab,
while(n>0){FOR(j,17)c[j]=0;for(j=0;(j<16)&&(j>=8;}u+=h[16];h[16]=u&3;u=5*(u>>2);FOR(j,16){u+=h[j];h[j]=u7u
0xf40e35855771202aULL,0x106aa07032bbd1b8ULL,0x19a4c116b8d2d0c8ULL,0x1e376c085141ab53ULL,0x2748774cdf8eeb99ULL,0x34b0bcb5e19b48a8ULL,
;pack(t,p);n-=64;if(crypto_verify_32(sm,t)){FOR(i,n)m[i]=0;return-1;}FOR(i,n)m[i]=sm[i+64];*mlen=n;return 0;}
0x113f9804bef90daeULL,0x1b710b35131c471bULL,0x28db77f523047d84ULL,0x32caab7b40c72493ULL,0x3c9ebe0a15c9bebcULL,0x431d67c49c100d4cULL,
;add(p,p);cswap(p,q,b);}}sv scalarbase(gf p[4],const u8*s){gf q[4];set25519(q[0],X);set25519(q[1],Y);set25519(q[2],gf1);M(q[3],X,Y);
o,a,a);}sv inv25519(gf o,const gf i){gf c;int a;FOR(a,16)c[a]=i[a];for(a=253;a>=0;a–){S(c,c);if(a!=2&&a!=4)M(c,c,i);}FOR(a,16)o[a]=c[a];}sv
inv25519(zi,p[2]);M(tx,p[0],zi);M(ty,p[1],zi);pack25519(r,ty);r[31]^=par25519(tx)<;}sv scalarmult(gf p[4],gf q[4],const u8*s){int i;
+32,n+32);reduce®;scalarbase(p,r);pack(sm,p);FOR(i,32)sm[i+32]=sk[i+32];crypto_hash(h,sm,n+64);reduce(h);FOR(i,64)x[i]=0;FOR(i,32)x[i]=(