KGC_TEST/KGC/miracl/source/mrzzn4.c

440 lines
11 KiB
C

/***************************************************************************
*
Copyright 2013 CertiVox UK Ltd. *
*
This file is part of CertiVox MIRACL Crypto SDK. *
*
The CertiVox MIRACL Crypto SDK provides developers with an *
extensive and efficient set of cryptographic functions. *
For further information about its features and functionalities please *
refer to http://www.certivox.com *
*
* The CertiVox MIRACL Crypto SDK is free software: you can *
redistribute it and/or modify it under the terms of the *
GNU Affero General Public License as published by the *
Free Software Foundation, either version 3 of the License, *
or (at your option) any later version. *
*
* The CertiVox MIRACL Crypto SDK is distributed in the hope *
that it will be useful, but WITHOUT ANY WARRANTY; without even the *
implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
See the GNU Affero General Public License for more details. *
*
* You should have received a copy of the GNU Affero General Public *
License along with CertiVox MIRACL Crypto SDK. *
If not, see <http://www.gnu.org/licenses/>. *
*
You can be released from the requirements of the license by purchasing *
a commercial license. Buying such a license is mandatory as soon as you *
develop commercial activities involving the CertiVox MIRACL Crypto SDK *
without disclosing the source code of your own applications, or shipping *
the CertiVox MIRACL Crypto SDK with a closed source product. *
*
***************************************************************************/
/*
* MIRACL F_p^4 support functions
* mrzzn4.c
*/
#include <stdlib.h>
#include "miracl.h"
#define FUNC_BASE 226
BOOL zzn4_iszero(zzn4 *x)
{
if (zzn2_iszero(&(x->a)) && zzn2_iszero(&(x->b))) return TRUE;
return FALSE;
}
BOOL zzn4_isunity(_MIPD_ zzn4 *x)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (mr_mip->ERNUM || !zzn2_iszero(&(x->b))) return FALSE;
if (zzn2_isunity(_MIPP_ &x->a)) return TRUE;
return FALSE;
}
BOOL zzn4_compare(zzn4 *x,zzn4 *y)
{
if (zzn2_compare(&(x->a),&(y->a)) && zzn2_compare(&(x->b),&(y->b))) return TRUE;
return FALSE;
}
void zzn4_from_int(_MIPD_ int i,zzn4 *w)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (mr_mip->ERNUM) return;
MR_IN(FUNC_BASE+0)
if (i==1)
{
copy(mr_mip->one,w->a.a);
w->unitary=TRUE;
}
else
{
convert(_MIPP_ i,mr_mip->w1);
nres(_MIPP_ mr_mip->w1,(w->a).a);
w->unitary=FALSE;
}
zero((w->a).b);
zero((w->b).a);
zero((w->b).b);
MR_OUT
}
void zzn4_copy(zzn4 *x,zzn4 *w)
{
if (x==w) return;
zzn2_copy(&(x->a),&(w->a));
zzn2_copy(&(x->b),&(w->b));
w->unitary=x->unitary;
}
void zzn4_zero(zzn4 *w)
{
zzn2_zero(&(w->a));
zzn2_zero(&(w->b));
w->unitary=FALSE;
}
void zzn4_from_zzn2s(zzn2 *x,zzn2 *y,zzn4 *w)
{
zzn2_copy(x,&(w->a));
zzn2_copy(y,&(w->b));
w->unitary=FALSE;
}
void zzn4_from_zzn2(zzn2 *x,zzn4 *w)
{
zzn2_copy(x,&(w->a));
zzn2_zero(&(w->b));
w->unitary=FALSE;
}
void zzn4_from_zzn2h(zzn2 *x,zzn4 *w)
{
zzn2_copy(x,&(w->b));
zzn2_zero(&(w->a));
w->unitary=FALSE;
}
void zzn4_from_zzn(big x,zzn4 *w)
{
zzn2_from_zzn(x,&(w->a));
zzn2_zero(&(w->b));
w->unitary=FALSE;
}
void zzn4_from_big(_MIPD_ big x, zzn4 *w)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (mr_mip->ERNUM) return;
MR_IN(FUNC_BASE+16)
zzn2_from_big(_MIPP_ x,&(w->a));
zzn2_zero(&(w->b));
MR_OUT
}
void zzn4_negate(_MIPD_ zzn4 *x,zzn4 *w)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (mr_mip->ERNUM) return;
MR_IN(FUNC_BASE+1)
zzn4_copy(x,w);
zzn2_negate(_MIPP_ &(w->a),&(w->a));
zzn2_negate(_MIPP_ &(w->b),&(w->b));
MR_OUT
}
void zzn4_conj(_MIPD_ zzn4 *x,zzn4 *w)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
MR_IN(FUNC_BASE+2)
if (mr_mip->ERNUM) return;
zzn4_copy(x,w);
zzn2_negate(_MIPP_ &(w->b),&(w->b));
MR_OUT
}
void zzn4_add(_MIPD_ zzn4 *x,zzn4 *y,zzn4 *w)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (mr_mip->ERNUM) return;
MR_IN(FUNC_BASE+3)
zzn2_add(_MIPP_ &(x->a),&(y->a),&(w->a));
zzn2_add(_MIPP_ &(x->b),&(y->b),&(w->b));
w->unitary=FALSE;
MR_OUT
}
void zzn4_sadd(_MIPD_ zzn4 *x,zzn2 *y,zzn4 *w)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (mr_mip->ERNUM) return;
MR_IN(FUNC_BASE+4)
zzn2_add(_MIPP_ &(x->a),y,&(w->a));
w->unitary=FALSE;
MR_OUT
}
void zzn4_sub(_MIPD_ zzn4 *x,zzn4 *y,zzn4 *w)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (mr_mip->ERNUM) return;
MR_IN(FUNC_BASE+5)
zzn2_sub(_MIPP_ &(x->a),&(y->a),&(w->a));
zzn2_sub(_MIPP_ &(x->b),&(y->b),&(w->b));
w->unitary=FALSE;
MR_OUT
}
void zzn4_ssub(_MIPD_ zzn4 *x,zzn2 *y,zzn4 *w)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (mr_mip->ERNUM) return;
MR_IN(FUNC_BASE+6)
zzn2_sub(_MIPP_ &(x->a),y,&(w->a));
w->unitary=FALSE;
MR_OUT
}
void zzn4_smul(_MIPD_ zzn4 *x,zzn2 *y,zzn4 *w)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (mr_mip->ERNUM) return;
MR_IN(FUNC_BASE+7)
if (!zzn2_iszero(&(x->a))) zzn2_mul(_MIPP_ &(x->a),y,&(w->a));
else zzn2_zero(&(w->a));
if (!zzn2_iszero(&(x->b))) zzn2_mul(_MIPP_ &(x->b),y,&(w->b));
else zzn2_zero(&(w->b));
w->unitary=FALSE;
MR_OUT
}
void zzn4_lmul(_MIPD_ zzn4 *x,big y,zzn4 *w)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (mr_mip->ERNUM) return;
MR_IN(FUNC_BASE+15)
if (!zzn2_iszero(&(x->a))) zzn2_smul(_MIPP_ &(x->a),y,&(w->a));
else zzn2_zero(&(w->a));
if (!zzn2_iszero(&(x->b))) zzn2_smul(_MIPP_ &(x->b),y,&(w->b));
else zzn2_zero(&(w->b));
w->unitary=FALSE;
MR_OUT
}
void zzn4_imul(_MIPD_ zzn4 *x,int y,zzn4 *w)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (mr_mip->ERNUM) return;
MR_IN(FUNC_BASE+14)
zzn2_imul(_MIPP_ &(x->a),y,&(w->a));
zzn2_imul(_MIPP_ &(x->b),y,&(w->b));
MR_OUT
}
void zzn4_sqr(_MIPD_ zzn4 *x,zzn4 *w)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
zzn2 t1,t2;
if (mr_mip->ERNUM) return;
MR_IN(FUNC_BASE+8)
t1.a=mr_mip->w10;
t1.b=mr_mip->w11;
t2.a=mr_mip->w8;
t2.b=mr_mip->w9;
zzn4_copy(x,w);
if (x->unitary)
{ /* this is a lot faster.. - see Lenstra & Stam */
zzn2_mul(_MIPP_ &(w->b),&(w->b),&t1);
zzn2_add(_MIPP_ &(w->b),&(w->a),&(w->b));
zzn2_mul(_MIPP_ &(w->b),&(w->b),&(w->b));
zzn2_sub(_MIPP_ &(w->b),&t1,&(w->b));
zzn2_txx(_MIPP_ &t1);
zzn2_copy(&t1,&(w->a));
zzn2_sub(_MIPP_ &(w->b),&(w->a),&(w->b));
zzn2_add(_MIPP_ &(w->a),&(w->a),&(w->a));
zzn2_sadd(_MIPP_ &(w->a),mr_mip->one,&(w->a));
zzn2_ssub(_MIPP_ &(w->b),mr_mip->one,&(w->b));
}
else
{
zzn2_copy(&(w->b),&t2); // t2=b;
zzn2_add(_MIPP_ &(w->a),&t2,&t1); // t1=a+b
zzn2_txx(_MIPP_ &t2);
zzn2_add(_MIPP_ &t2,&(w->a),&t2); // t2=a+txx(b)
zzn2_mul(_MIPP_ &(w->b),&(w->a),&(w->b)); // b*=a
zzn2_mul(_MIPP_ &t1,&t2,&(w->a)); // a=t1*t2
zzn2_copy(&(w->b),&t2); //t2=b
zzn2_sub(_MIPP_ &(w->a),&t2,&(w->a)); //a-=b
zzn2_txx(_MIPP_ &t2); // t2=txx(b)
zzn2_sub(_MIPP_ &(w->a),&t2,&(w->a)); // a-=txx(b);
zzn2_add(_MIPP_ &(w->b),&(w->b),&(w->b)); // b+=b;
}
MR_OUT
}
void zzn4_mul(_MIPD_ zzn4 *x,zzn4 *y,zzn4 *w)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
zzn2 t1,t2,t3;
if (mr_mip->ERNUM) return;
if (x==y) {zzn4_sqr(_MIPP_ x,w); return; }
MR_IN(FUNC_BASE+9)
t1.a=mr_mip->w12;
t1.b=mr_mip->w13;
t2.a=mr_mip->w8;
t2.b=mr_mip->w9;
t3.a=mr_mip->w10;
t3.b=mr_mip->w11;
zzn2_copy(&(x->a),&t1);
zzn2_copy(&(x->b),&t2);
zzn2_mul(_MIPP_ &t1,&(y->a),&t1); /* t1= x->a * y->a */
zzn2_mul(_MIPP_ &t2,&(y->b),&t2); /* t2 = x->b * y->b */
zzn2_copy(&(y->a),&t3);
zzn2_add(_MIPP_ &t3,&(y->b),&t3); /* y->a + y->b */
zzn2_add(_MIPP_ &(x->b),&(x->a),&(w->b)); /* x->a + x->b */
zzn2_mul(_MIPP_ &(w->b),&t3,&(w->b)); /* t3= (x->a + x->b)*(y->a + y->b) */
zzn2_sub(_MIPP_ &(w->b),&t1,&(w->b));
zzn2_sub(_MIPP_ &(w->b),&t2,&(w->b)); /* w->b = t3-(t1+t2) */
zzn2_copy(&t1,&(w->a));
zzn2_txx(_MIPP_ &t2);
zzn2_add(_MIPP_ &(w->a),&t2,&(w->a)); /* w->a = t1+tx(t2) */
if (x->unitary && y->unitary) w->unitary=TRUE;
else w->unitary=FALSE;
MR_OUT
}
void zzn4_inv(_MIPD_ zzn4 *w)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
zzn2 t1,t2;
if (mr_mip->ERNUM) return;
if (w->unitary)
{
zzn4_conj(_MIPP_ w,w);
return;
}
MR_IN(FUNC_BASE+10)
t1.a=mr_mip->w8;
t1.b=mr_mip->w9;
t2.a=mr_mip->w10;
t2.b=mr_mip->w11;
zzn2_mul(_MIPP_ &(w->a),&(w->a),&t1);
zzn2_mul(_MIPP_ &(w->b),&(w->b),&t2);
zzn2_txx(_MIPP_ &t2);
zzn2_sub(_MIPP_ &t1,&t2,&t1);
zzn2_inv(_MIPP_ &t1);
zzn2_mul(_MIPP_ &(w->a),&t1,&(w->a));
zzn2_negate(_MIPP_ &t1,&t1);
zzn2_mul(_MIPP_ &(w->b),&t1,&(w->b));
MR_OUT
}
/* divide zzn4 by 2 */
void zzn4_div2(_MIPD_ zzn4 *w)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
if (mr_mip->ERNUM) return;
MR_IN(FUNC_BASE+11)
zzn2_div2(_MIPP_ &(w->a));
zzn2_div2(_MIPP_ &(w->b));
w->unitary=FALSE;
MR_OUT
}
void zzn4_powq(_MIPD_ zzn2 *fr,zzn4 *w)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
MR_IN(FUNC_BASE+12)
zzn2_conj(_MIPP_ &(w->a),&(w->a));
zzn2_conj(_MIPP_ &(w->b),&(w->b));
zzn2_mul(_MIPP_ &(w->b),fr,&(w->b));
MR_OUT
}
void zzn4_tx(_MIPD_ zzn4* w)
{
#ifdef MR_OS_THREADS
miracl *mr_mip=get_mip();
#endif
zzn2 t;
MR_IN(FUNC_BASE+13)
t.a=mr_mip->w8;
t.b=mr_mip->w9;
zzn2_copy(&(w->b),&t);
zzn2_txx(_MIPP_ &t);
zzn2_copy(&(w->a),&(w->b));
zzn2_copy(&t,&(w->a));
MR_OUT
}