-rw-r--r-- 3540 lib25519-20240928/crypto_mGnP/ed25519/amd64-64/mGnP.c raw
#include "crypto_mGnP.h" #include "fe25519.h" #include "sc25519.h" #include "ge25519.h" #include "shared-data.h" #include "crypto_verify_32.h" static const fe25519 ec2d = {{0xEBD69B9426B2F146, 0x00E0149A8283B156, 0x198E80F2EEF3D130, 0xA406D9DC56DFFCE7}}; static void setneutral(ge25519 *r) { fe25519_setint(&r->x,0); fe25519_setint(&r->y,1); fe25519_setint(&r->z,1); fe25519_setint(&r->t,0); } static void ge25519_double_scalarmult_precompute(ge25519_pniels *pre1, const ge25519_p3 *p1, unsigned long long PRE1_SIZE) { ge25519_p3 d1; ge25519_p1p1 t; fe25519 d; int i; pre1[0] = *(ge25519_pniels *)p1; ge25519_dbl_p1p1(&t,(ge25519_p2 *)pre1); ge25519_p1p1_to_p3(&d1, &t); /* Convert pre[0] to projective Niels representation */ d = pre1[0].ysubx; fe25519_sub(&pre1[0].ysubx, &pre1[0].xaddy, &pre1[0].ysubx); fe25519_add(&pre1[0].xaddy, &pre1[0].xaddy, &d); fe25519_mul(&pre1[0].t2d, &pre1[0].t2d, &ec2d); for(i=0;i<PRE1_SIZE-1;i++) { ge25519_pnielsadd_p1p1(&t, &d1, &pre1[i]); ge25519_p1p1_to_p3((ge25519_p3 *)&pre1[i+1], &t); /* Convert pre1[i+1] to projective Niels representation */ d = pre1[i+1].ysubx; fe25519_sub(&pre1[i+1].ysubx, &pre1[i+1].xaddy, &pre1[i+1].ysubx); fe25519_add(&pre1[i+1].xaddy, &pre1[i+1].xaddy, &d); fe25519_mul(&pre1[i+1].t2d, &pre1[i+1].t2d, &ec2d); } } static void ge25519_double_scalarmult_process(ge25519_p3 *r, const signed char *slide1, const signed char *slide2, const ge25519_pniels *pre1, const ge25519_niels *pre2) { ge25519_pniels neg; ge25519_niels nneg; ge25519_p1p1 t; fe25519 d; int i; setneutral(r); for (i = 255;i >= 0;--i) { if (slide1[i] || slide2[i]) goto firstbit; } for(;i>=0;i--) { firstbit: ge25519_dbl_p1p1(&t, (ge25519_p2 *)r); if(slide1[i]>0) { ge25519_p1p1_to_p3(r, &t); ge25519_pnielsadd_p1p1(&t, r, &pre1[slide1[i]/2]); } else if(slide1[i]<0) { ge25519_p1p1_to_p3(r, &t); neg = pre1[-slide1[i]/2]; d = neg.ysubx; neg.ysubx = neg.xaddy; neg.xaddy = d; fe25519_neg(&neg.t2d, &neg.t2d); ge25519_pnielsadd_p1p1(&t, r, &neg); } if(slide2[i]>0) { ge25519_p1p1_to_p3(r, &t); ge25519_nielsadd_p1p1(&t, r, &pre2[slide2[i]/2]); } else if(slide2[i]<0) { ge25519_p1p1_to_p3(r, &t); nneg = pre2[-slide2[i]/2]; d = nneg.ysubx; nneg.ysubx = nneg.xaddy; nneg.xaddy = d; fe25519_neg(&nneg.t2d, &nneg.t2d); ge25519_nielsadd_p1p1(&t, r, &nneg); } ge25519_p1p1_to_p2((ge25519_p2 *)r, &t); } } void crypto_mGnP( unsigned char *Q, const unsigned char *m, const unsigned char *n, const unsigned char *P ) { sc25519 m_internal; signed char m_slide[256]; unsigned char mcheck[32]; sc25519 n_internal; signed char n_slide[256]; ge25519 P_internal; ge25519_pniels P_multiples[P_MULTIPLES]; ge25519_p3 result; int ok; sc25519_from32bytes(&m_internal,m); sc25519_from64bytes(&n_internal,n); ok = ge25519_unpackneg_vartime(&P_internal,P); sc25519_to32bytes(mcheck,&m_internal); if (crypto_verify_32(mcheck,m)) ok = 0; sc25519_slide(m_slide,&m_internal,G_WINDOWSIZE); sc25519_slide(n_slide,&n_internal,P_WINDOWSIZE); ge25519_double_scalarmult_precompute(P_multiples,&P_internal,P_MULTIPLES); ge25519_double_scalarmult_process(&result,n_slide,m_slide,P_multiples,G_multiples); ge25519_pack(Q,&result); Q[32] = ok; }