📄 mredn2.c
字号:
/*
* MIRACL E(F_p^2) support functions
* mredn2.c
* Inverted Edwards Form
*
* Copyright (c) 2009 Shamus Software Ltd.
*/
#include <stdlib.h>
#include "miracl.h"
#ifdef MR_STATIC
#include <string.h>
#endif
BOOL ecn2_iszero(ecn2 *a)
{
if (a->marker==MR_EPOINT_INFINITY) return TRUE;
return FALSE;
}
void ecn2_copy(ecn2 *a,ecn2 *b)
{
zzn2_copy(&(a->x),&(b->x));
zzn2_copy(&(a->y),&(b->y));
if (a->marker==MR_EPOINT_GENERAL) zzn2_copy(&(a->z),&(b->z));
b->marker=a->marker;
}
void ecn2_zero(ecn2 *a)
{
zzn2_from_zzn(mr_mip->one,&(a->x));
zzn2_zero(&(a->y));
if (a->marker==MR_EPOINT_GENERAL) zzn2_zero(&(a->z));
a->marker=MR_EPOINT_INFINITY;
}
BOOL ecn2_compare(_MIPD_ ecn2 *a,ecn2 *b)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (mr_mip->ERNUM) return FALSE;
MR_IN(193)
ecn2_norm(_MIPP_ a);
ecn2_norm(_MIPP_ b);
MR_OUT
if (zzn2_compare(&(a->x),&(b->x)) && zzn2_compare(&(a->y),&(b->y)) && a->marker==b->marker) return TRUE;
return FALSE;
}
void ecn2_norm(_MIPD_ ecn2 *a)
{
zzn2 t;
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (mr_mip->ERNUM) return;
if (a->marker!=MR_EPOINT_GENERAL) return;
MR_IN(194)
zzn2_inv(_MIPP_ &(a->z));
zzn2_mul(_MIPP_ &(a->x),&(a->z),&(a->x));
zzn2_mul(_MIPP_ &(a->y),&(a->z),&(a->y));
zzn2_from_zzn(mr_mip->one,&(a->z));
a->marker=MR_EPOINT_NORMALIZED;
MR_OUT
}
void ecn2_get(_MIPD_ ecn2 *e,zzn2 *x,zzn2 *y,zzn2 *z)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
zzn2_copy(&(e->x),x);
zzn2_copy(&(e->y),y);
if (e->marker==MR_EPOINT_GENERAL) zzn2_copy(&(e->z),z);
else zzn2_from_zzn(mr_mip->one,z);
}
void ecn2_getxy(ecn2 *e,zzn2 *x,zzn2 *y)
{
zzn2_copy(&(e->x),x);
zzn2_copy(&(e->y),y);
}
void ecn2_getx(ecn2 *e,zzn2 *x)
{
zzn2_copy(&(e->x),x);
}
void ecn2_getz(_MIPD_ ecn2 *e,zzn2 *z)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (e->marker==MR_EPOINT_GENERAL) zzn2_copy(&(e->z),z);
else zzn2_from_zzn(mr_mip->one,z);
}
void ecn2_psi(_MIPD_ zzn2 *psi,ecn2 *P)
{ /* apply GLS morphism to P */
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
MR_IN(212)
zzn2_conj(_MIPP_ &(P->x),&(P->x));
zzn2_conj(_MIPP_ &(P->y),&(P->y));
zzn2_conj(_MIPP_ &(P->z),&(P->z));
zzn2_mul(_MIPP_ &(P->x),&psi[0],&(P->x));
zzn2_mul(_MIPP_ &(P->y),&psi[1],&(P->y));
MR_OUT
}
/* find RHS=(x^2-B)/(x^2-A) */
void ecn2_rhs(_MIPD_ zzn2 *x,zzn2 *rhs)
{ /* calculate RHS of elliptic curve equation */
BOOL twist;
zzn2 A,B;
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (mr_mip->ERNUM) return;
twist=mr_mip->TWIST;
MR_IN(202)
A.a=mr_mip->w8;
A.b=mr_mip->w9;
B.a=mr_mip->w10;
B.b=mr_mip->w11;
zzn2_from_zzn(mr_mip->A,&A);
zzn2_from_zzn(mr_mip->B,&B);
if (twist)
{
zzn2_txx(_MIPP_ &A);
zzn2_txx(_MIPP_ &B);
}
zzn2_sqr(_MIPP_ x,rhs);
zzn2_sub(_MIPP_ rhs,&B,&B);
zzn2_sub(_MIPP_ rhs,&A,&A);
zzn2_inv(_MIPP_ &A);
zzn2_mul(_MIPP_ &A,&B,rhs);
MR_OUT
}
BOOL ecn2_set(_MIPD_ zzn2 *x,zzn2 *y,ecn2 *e)
{
zzn2 lhs,rhs;
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (mr_mip->ERNUM) return FALSE;
MR_IN(195)
lhs.a=mr_mip->w12;
lhs.b=mr_mip->w13;
rhs.a=mr_mip->w14;
rhs.b=mr_mip->w15;
ecn2_rhs(_MIPP_ x,&rhs);
zzn2_sqr(_MIPP_ y,&lhs);
if (!zzn2_compare(&lhs,&rhs))
{
MR_OUT
return FALSE;
}
zzn2_copy(x,&(e->x));
zzn2_copy(y,&(e->y));
e->marker=MR_EPOINT_NORMALIZED;
MR_OUT
return TRUE;
}
#ifndef MR_NOSUPPORT_COMPRESSION
BOOL ecn2_setx(_MIPD_ zzn2 *x,ecn2 *e)
{
zzn2 rhs;
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (mr_mip->ERNUM) return FALSE;
MR_IN(201)
rhs.a=mr_mip->w12;
rhs.b=mr_mip->w13;
ecn2_rhs(_MIPP_ x,&rhs);
if (!zzn2_iszero(&rhs))
{
if (!zzn2_sqrt(_MIPP_ &rhs,&rhs))
{
MR_OUT
return FALSE;
}
}
zzn2_copy(x,&(e->x));
zzn2_copy(&rhs,&(e->y));
e->marker=MR_EPOINT_NORMALIZED;
MR_OUT
return TRUE;
}
#endif
void ecn2_setxyz(zzn2 *x,zzn2 *y,zzn2 *z,ecn2 *e)
{
zzn2_copy(x,&(e->x));
zzn2_copy(y,&(e->y));
zzn2_copy(z,&(e->z));
e->marker=MR_EPOINT_GENERAL;
}
BOOL ecn2_add(_MIPD_ ecn2 *Q,ecn2 *P)
{ /* P+=Q */
BOOL Doubling=FALSE;
BOOL twist;
int iA;
zzn2 t2,t3,t4;
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
t2.a = mr_mip->w8;
t2.b = mr_mip->w9;
t3.a = mr_mip->w10;
t3.b = mr_mip->w11;
t4.a = mr_mip->w12;
t4.b = mr_mip->w13;
twist=mr_mip->TWIST;
if (mr_mip->ERNUM) return FALSE;
if (P->marker==MR_EPOINT_INFINITY)
{
ecn2_copy(Q,P);
return Doubling;
}
if (Q->marker==MR_EPOINT_INFINITY) return Doubling;
if (Q==P)
{
Doubling=TRUE;
if (P->marker==MR_EPOINT_INFINITY)
{ /* 2 times infinity == infinity ! */
return Doubling;
}
}
MR_IN(205)
if (!Doubling)
{ /* Addition */
zzn2_add(_MIPP_ &(Q->x),&(Q->y),&t2);
zzn2_add(_MIPP_ &(P->x),&(P->y),&t4);
zzn2_mul(_MIPP_ &t4,&t2,&t4); /* I = t4 = (x1+y1)(x2+y2) */
if (Q->marker!=MR_EPOINT_NORMALIZED)
{
if (P->marker==MR_EPOINT_NORMALIZED)
zzn2_copy(&(Q->z),&(P->z));
else
zzn2_mul(_MIPP_ &(Q->z),&(P->z),&(P->z)); /* Z = z1*z2 */
}
else
{
if (P->marker==MR_EPOINT_NORMALIZED)
zzn2_from_zzn(_MIPP_ mr_mip->one,&(P->z));
}
zzn2_mul(_MIPP_ &(P->z),&(P->z),&t2); /* P->z = z1.z2 */
if (mr_abs(mr_mip->Bsize)==MR_TOOBIG)
zzn2_smul(_MIPP_ &t2,mr_mip->B,&t2);
else
zzn2_imul(_MIPP_ &t2,mr_mip->Bsize,&t2);
if (twist) zzn2_txx(_MIPP_ &t2); /* B = t2 = d*A^2 */
zzn2_mul(_MIPP_ &(P->x),&(Q->x),&(P->x)); /* X = x1*x2 */
zzn2_mul(_MIPP_ &(P->y),&(Q->y),&(P->y)); /* Y = y1*y2 */
zzn2_sub(_MIPP_ &t4,&(P->x),&t4);
zzn2_sub(_MIPP_ &t4,&(P->y),&t4); /* I = (x1+y1)(x2+y2)-X-Y */
zzn2_mul(_MIPP_ &(P->x),&(P->y),&t3); /* E = t3 = X*Y */
if (mr_abs(mr_mip->Asize)==MR_TOOBIG)
zzn2_smul(_MIPP_ &(P->y),mr_mip->A,&(P->y));
else
zzn2_imul(_MIPP_ &(P->y),mr_mip->Asize,&(P->y));
if (twist) zzn2_txx(_MIPP_ &(P->y)); /* Y=aY */
zzn2_sub(_MIPP_ &(P->x),&(P->y),&(P->x)); /* X=X-aY */
zzn2_mul(_MIPP_ &(P->z),&(P->x),&(P->z));
zzn2_mul(_MIPP_ &(P->z),&t4,&(P->z));
zzn2_sub(_MIPP_ &t3,&t2,&(P->y));
zzn2_mul(_MIPP_ &(P->y),&t4,&(P->y));
zzn2_add(_MIPP_ &t3,&t2,&t4);
zzn2_mul(_MIPP_ &(P->x),&t4,&(P->x));
}
else
{ /* doubling */
zzn2_add(_MIPP_ &(P->x),&(P->y),&t2);
zzn2_mul(_MIPP_ &t2,&t2,&t2);
zzn2_sqr(_MIPP_ &(P->x),&(P->x));
zzn2_sqr(_MIPP_ &(P->y),&(P->y));
zzn2_sub(_MIPP_ &t2,&(P->x),&t2);
zzn2_sub(_MIPP_ &t2,&(P->y),&t2); /* E=(X+Y)^2-X^2-Y^2 */
if (P->marker!=MR_EPOINT_NORMALIZED)
zzn2_sqr(_MIPP_ &(P->z),&(P->z));
else
zzn2_from_zzn(_MIPP_ mr_mip->one,&(P->z));
zzn2_add(_MIPP_ &(P->z),&(P->z),&(P->z));
if (mr_abs(mr_mip->Bsize)==MR_TOOBIG)
zzn2_smul(_MIPP_ &(P->z),mr_mip->B,&(P->z));
else
zzn2_imul(_MIPP_ &(P->z),mr_mip->Bsize,&(P->z));
if (twist) zzn2_txx(_MIPP_ &(P->z));
if (mr_abs(mr_mip->Asize)==MR_TOOBIG)
zzn2_smul(_MIPP_ &(P->y),mr_mip->A,&(P->y));
else
zzn2_imul(_MIPP_ &(P->y),mr_mip->Asize,&(P->y));
if (twist) zzn2_txx(_MIPP_ &(P->y));
zzn2_add(_MIPP_ &(P->x),&(P->y),&t3);
zzn2_sub(_MIPP_ &(P->x),&(P->y),&t4);
zzn2_mul(_MIPP_ &t3,&t4,&(P->x));
zzn2_sub(_MIPP_ &t3,&(P->z),&t3);
zzn2_mul(_MIPP_ &t2,&t3,&(P->y));
zzn2_mul(_MIPP_ &t2,&t4,&(P->z));
}
if (zzn2_iszero(&(P->z)))
{
zzn2_from_zzn(mr_mip->one,&(P->x));
zzn2_zero(&(P->y));
P->marker=MR_EPOINT_INFINITY;
}
else P->marker=MR_EPOINT_GENERAL;
MR_OUT
return Doubling;
}
void ecn2_negate(_MIPD_ ecn2 *u,ecn2 *w)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
ecn2_copy(u,w);
if (w->marker!=MR_EPOINT_INFINITY)
zzn2_negate(_MIPP_ &(w->x),&(w->x));
}
BOOL ecn2_sub(_MIPD_ ecn2 *Q,ecn2 *P)
{
BOOL Doubling;
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
zzn2 lam;
lam.a = mr_mip->w14;
lam.b = mr_mip->w15;
ecn2_negate(_MIPP_ Q,Q);
Doubling=ecn2_add(_MIPP_ Q,P);
ecn2_negate(_MIPP_ Q,Q);
return Doubling;
}
/*
BOOL ecn2_add_sub(_MIPD_ ecn2 *P,ecn2 *Q,ecn2 *PP,ecn2 *PM)
{ PP=P+Q, PM=P-Q. Assumes P and Q are both normalized, and P!=Q
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
zzn2 t1,t2,lam;
if (mr_mip->ERNUM) return FALSE;
PP->marker=MR_EPOINT_NORMALIZED;
PM->marker=MR_EPOINT_NORMALIZED;
return TRUE;
}
*/
/* Precomputation of 3P, 5P, 7P etc. into PT. Assume PT[0] contains P */
static void ecn2_pre(_MIPD_ int sz,ecn2 *PT)
{
int i,j;
ecn2 P2;
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
#ifndef MR_STATIC
char *mem = memalloc(_MIPP_ 6);
#else
char mem[MR_BIG_RESERVE(6)];
memset(mem, 0, MR_BIG_RESERVE(6));
#endif
j=0;
P2.x.a=mirvar_mem(_MIPP_ mem, j++);
P2.x.b=mirvar_mem(_MIPP_ mem, j++);
P2.y.a=mirvar_mem(_MIPP_ mem, j++);
P2.y.b=mirvar_mem(_MIPP_ mem, j++);
P2.z.a=mirvar_mem(_MIPP_ mem, j++);
P2.z.b=mirvar_mem(_MIPP_ mem, j++);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -