void test3()
{
static bits256 G,x,y,a,b,xG,yG,e,s;
uint64_t buf[2][5];
int i;
limb bp[5],xbp[5],ybp[5],e_xGx[5],e_xGz[5],e_yGx[5],e_yGz[5],sGx[5],sGz[5],aGx[5],aGz[5],bGx[5],bGz[5];
limb Q2x[5],Q2z[5],Rx[5],Rz[5],xpoly[5],ypoly[5],epoly[5],apoly[5],bpoly[5],xe[5],ye[5],spoly[5],xsumx[5],xsumz[5],ysumx[5],ysumz[5];
G.bytes[0] = 9, fexpand(bp,G.bytes);
// A
randombytes(x.bytes,sizeof(x)), x = mask_key(x), fexpand(xpoly,x.bytes);
randombytes(a.bytes,sizeof(a)), a = mask_key(a), fexpand(apoly,a.bytes);
xG = curve25519(x,G);
cmult(aGx,aGz,a.bytes,bp);
// B
randombytes(y.bytes,sizeof(y)), y = mask_key(y), fexpand(ypoly,y.bytes);
randombytes(b.bytes,sizeof(b)), b = mask_key(b), fexpand(bpoly,b.bytes);
yG = curve25519(y,G);
cmult(bGx,bGz,b.bytes,bp);
// Both
fmonty(Q2x,Q2z,Rx,Rz,aGx,aGz,bGx,bGz,bp); // A and B exchange (aGx,aGz) and (bGx,bGz) so both can compute e
memcpy(buf[0],Rx,sizeof(buf[0]));
memcpy(buf[1],Rz,sizeof(buf[1]));
char *src = "hello world";
calc_sha256cat(e.bytes,(unsigned char *)src,(int32_t)strlen(src),(unsigned char *)buf,sizeof(buf));
// A
fmul(xe,xpoly,epoly); // xe = x * e
fdifference_backwards(xe,apoly); // (α - xe) = s'
// B
fmul(ye,ypoly,epoly); // ye = y * e
fdifference_backwards(ye,bpoly); // (β - ye) = s''
// finally A and B share s' and s''
for (i=0; i<5; i++) // s = s' + s''
spoly[i] = (xe[i] + ye[i]);
disp_limb("spoly",spoly);
fcontract(s.bytes,spoly), disp_bits256(" s\n",s);
cmult(sGx,sGz,s.bytes,bp); // sG
disp_xz("sG xz\n",sGx,sGz);
// R = eP + sG -> (e*xG + s*G) should equal (e*yG + s*G)
fexpand(xbp,xG.bytes);
cmult(e_xGx,e_xGz,e.bytes,xbp); // eP for x
fmonty(Q2x,Q2z,xsumx,xsumz,e_xGx,e_xGz,sGx,sGz,bp); // (eP + sG)
disp_xz("xsum xz\n",xsumx,xsumz);
fexpand(ybp,yG.bytes);
cmult(e_yGx,e_yGz,e.bytes,ybp); // eP for y
fmonty(Q2x,Q2z,ysumx,ysumz,e_yGx,e_yGz,sGx,sGz,bp); // (eP + sG)
disp_xz("ysum xz\n",ysumx,ysumz);
}
I noticed in polynomial form it can vary, but when compressed to 256 bit number it is always the same, so I display both the x and z vals.
8e0539c79e4c30 8926b81faef662 811fdcd5840e1d 86c88ac5c0c565 829f821a0b73fa spoly
604d9ec739059eb377fdc035898b036135f747ea8a818b1591ad40b7a021f829 s
2c7332292b79212c31ae926c6cf62ea339c80452761a7d3f53eced415368c430 sGx
2dfd7e0f309e76ec163b674dfffdf8b4b07156abbcc8d282456f1c7494838637 sGz
4d8a4ccda4b4c3959c7040478fe6ac3830aafc28d6432da97d4c834224888412 xsumx (eP + sG)
28768f66cef5f334af3746d27b427f52d5b91f1e1338b73af6e625b870f5d275 xsumz
908c0ac5a707594261b3df6fc64896033f61166afd6b98b7f0e32f615a514259 ysumx (eP + sG)
9422a680f5a74e05d561458d8ad25945ab64b5fc73aeb8b070e166a2eb34b93e ysumz
Not 100% sure that the (eP + sG) checks are even right, and maybe s or e are messed up. Without anyway to have known values part way, it seems it cant have any bugs through the entire process. Hopefully, I am at least close.
James