TwlIPL/build/libraries_sysmenu/acsign/ARM9/src/bn_sqr.c
yosiokat 1952c74fb3 systemMenu_REDの追加。(まだまともに動かない。)
git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@72 b08762b0-b915-fc4b-9d8c-17b2551a87ff
2007-10-29 11:02:25 +00:00

290 lines
6.5 KiB
C

/*---------------------------------------------------------------------------*
Project: TwlIPL
File:
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
/*
* Copyright (C) 1998-2002 RSA Security Inc. All rights reserved.
*
* This work contains proprietary information of RSA Security.
* Distribution is limited to authorized licensees of RSA
* Security. Any unauthorized reproduction, distribution or
* modification of this work is strictly prohibited.
*
*/
#include "bn_lcl.h"
#ifdef SMALL_CODE_SIZE
#undef BN_RECURSION_SQR
#endif
#if !(defined(NO_SPLIT) && defined(SPLIT_FILE))
#ifdef NO_SPLIT
#define SPLIT_BN_SQR
#define SPLIT_BN_SQR_NORMAL
#define SPLIT_BN_RECURSION_SQR
#endif /* NO_SPLIT */
#ifdef SPLIT_BN_SQR
/* r must not be a */
int BN_sqr(r, a, ctx)
BIGNUM *r;
BIGNUM *a;
BN_CTX *ctx;
{
int max,al;
BIGNUM *tmp,*rr;
#ifdef BN_COUNT
printf("BN_sqr %d * %d\n",a->top,a->top);
#endif
bn_check_top(a);
tmp= &(ctx->bn[ctx->tos]);
rr=(a != r)?r: (&ctx->bn[ctx->tos+1]);
al=a->top;
if (al <= 0)
{
r->top=0;
return(1);
}
max=(al+al);
if (bn_wexpand(rr,max) == NULL) return(0);
rr->top=max;
rr->neg=0;
if (al == 4)
{
#ifndef BN_SQR_COMBA
BN_ULONG t[8];
bn_sqr_normal(rr->d,a->d,4,t);
#else
bn_sqr_comba4(rr->d,a->d);
#endif
}
else if (al == 8)
{
#ifndef BN_SQR_COMBA
BN_ULONG t[16];
bn_sqr_normal(rr->d,a->d,8,t);
#else
bn_sqr_comba8(rr->d,a->d);
#endif
}
else
{
#if 1 && defined(BN_RECURSION_SQR)
if (al < BN_SQR_RECURSIVE_SIZE_NORMAL)
{
BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL*2];
bn_sqr_normal(rr->d,a->d,al,t);
}
else
{
int j,l,k;
l=BN_num_bits_word((BN_ULONG)al);
j=1<<(l-1);
k=j+j;
if ((al == j) && !BN_get_flags(a,BN_FLG_STATIC_DATA))
{
BN_REC rec;
if (bn_wexpand(tmp,k*2) == NULL) return(0);
rec.depth=l-5;
rec.n=j;
rec.mul=bn_mul_comba8;
rec.sqr=bn_sqr_comba8;
bn_sqr_rec_words(rr->d,a->d,tmp->d,&rec);
}
else
{
if (bn_wexpand(tmp,max) == NULL) return(0);
bn_assert(al*2 <= max);
bn_sqr_normal(rr->d,a->d,al,tmp->d);
}
}
#else
if (bn_wexpand(tmp,max) == NULL) return(0);
bn_assert(al*2 <= max);
bn_sqr_normal(rr->d,a->d,al,tmp->d);
#endif
#ifdef BN_DEBUG
tmp->top=0;
#endif
}
if ((max > 0) && (rr->d[max-1] == 0)) rr->top--;
if (rr != r) (void)BN_copy(r,rr);
return(1);
}
#endif
#ifdef SPLIT_BN_SQR_NORMAL
/* tmp must have 2*n words */
void bn_sqr_normal(r, a, n, tmp)
BN_ULONG *r;
BN_ULONG *a;
int n;
BN_ULONG *tmp;
{
int i,j,max;
BN_ULONG *ap,*rp,m;
max=n*2;
ap=a;
rp=r;
rp[0]=rp[max-1]=0;
rp++;
j=n;
if (--j > 0)
{
m= (*ap++);
rp[j]=bn_mul_words(rp,ap,j,m);
rp+=2;
}
for (i=n-2; i>0; i--)
{
j--;
m= *(ap++);
rp[j]=bn_mul_add_words(rp,ap,j,m);
rp+=2;
}
(void)bn_add_words(r,r,r,max);
/* There will not be a carry */
bn_sqr_words(tmp,a,n);
(void)bn_add_words(r,r,tmp,max);
}
#endif
#if 0 /* replaced by bn_sqr_rec_words() AND this has bugs */
#ifdef SPLIT_BN_RECURSION_SQR
#ifdef BN_RECURSION_SQR
/* r is 2*n words in size,
* a and b are both n words in size.
* n must be a power of 2.
* We multiply and return the result.
* t must be 2*n words in size
* We calulate
* a[0]*b[0]
* a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
* a[1]*b[1]
*/
void bn_sqr_recursive(r,a,n2,t)
BN_ULONG *r,*a;
int n2;
BN_ULONG *t;
{
int n=n2/2;
int zero,c1;
BN_ULONG ln,lo,*p;
#ifdef BN_COUNT
printf(" bn_sqr_recursive %d * %d\n",n2,n2);
#endif
if (n2 == 4)
{
#ifndef BN_SQR_COMBA
bn_sqr_normal(r,a,4,t);
#else
bn_sqr_comba4(r,a);
#endif
return;
}
else if (n2 == 8)
{
#ifndef BN_SQR_COMBA
bn_sqr_normal(r,a,8,t);
#else
bn_sqr_comba8(r,a);
#endif
return;
}
if (n2 < BN_SQR_RECURSIVE_SIZE_NORMAL)
{
bn_sqr_normal(r,a,n2,t);
return;
}
/* r=(a[0]-a[1])*(a[1]-a[0]) */
c1=bn_cmp_words(a,&(a[n]),n);
zero=0;
if (c1 > 0)
bn_sub_words(t,a,&(a[n]),n);
else if (c1 < 0)
bn_sub_words(t,&(a[n]),a,n);
else
zero=1;
/* The result will always be negative unless it is zero */
p= &(t[n2*2]);
if (!zero)
bn_sqr_recursive(&(t[n2]),t,n,p);
else
Memset(&(t[n2]),0,n*sizeof(BN_ULONG));
bn_sqr_recursive(r,a,n,p);
bn_sqr_recursive(&(r[n2]),&(a[n]),n,p);
/* t[32] holds (a[0]-a[1])*(a[1]-a[0]), it is negative or zero
* r[10] holds (a[0]*b[0])
* r[32] holds (b[1]*b[1])
*/
c1=(int)(bn_add_words(t,r,&(r[n2]),n2));
/* t[32] is negative */
c1-=(int)(bn_sub_words(&(t[n2]),t,&(t[n2]),n2));
/* t[32] holds (a[0]-a[1])*(a[1]-a[0])+(a[0]*a[0])+(a[1]*a[1])
* r[10] holds (a[0]*a[0])
* r[32] holds (a[1]*a[1])
* c1 holds the carry bits
*/
c1+=(int)(bn_add_words(&(r[n]),&(r[n]),&(t[n2]),n2));
if (c1)
{
p= &(r[n+n2]);
lo= *p;
ln=(lo+c1)&BN_MASK2;
*p=ln;
/* The overflow will stop before we over write
* words we should not overwrite */
if (ln < (BN_ULONG)c1)
{
do {
p++;
lo= *p;
ln=(lo+1)&BN_MASK2;
*p=ln;
} while (ln == 0);
}
}
}
#endif
#endif
#endif
#endif