TwlIPL/build/libraries_sysmenu/acsign/ARM9/src/bn_r_exp.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

151 lines
4.1 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 RECP_MUL_MOD */
int BN_mod_exp_recp(r,a,p,m,ctx)
BIGNUM *r;
BIGNUM *a;
BIGNUM *p;
BIGNUM *m;
BN_CTX *ctx;
{
int i,j,bits,ret=0,wstart,wend,window,wvalue;
int start=1,ts=0;
BIGNUM *aa;
BIGNUM val[BN_EXP_TABLE_SIZE];
BN_RECP_CTX recp;
bits=BN_num_bits(p);
if (BN_is_zero(a))
{ (void)BN_zero(r); return(1); }
if (BN_is_zero(p))
{ (void)BN_one(r); return(1); }
if (BN_is_one(p))
{ (void)BN_copy(r,a); return(1); }
BN_RECP_CTX_init(&recp);
if (BN_RECP_CTX_set(&recp,m,ctx) <= 0) goto err;
BN_init(&(val[0]));
ts=1;
aa= &(ctx->bn[ctx->tos++]);
if (!BN_mod(&(val[0]),a,m,ctx)) goto err; /* 1 */
if (!BN_mod_mul_reciprocal(aa,&(val[0]),&(val[0]),&recp,ctx))
goto err; /* 2 */
if (bits <= 17) /* This is probably 3 or 0x10001, so just do singles */
window=1;
else if (bits >= 256)
window=5; /* max size of window */
else if (bits >= 128)
window=4;
else
window=3;
j=1<<(window-1);
for (i=1; i<j; i++)
{
BN_init(&val[i]);
if (!BN_mod_mul_reciprocal(&(val[i]),&(val[i-1]),aa,&recp,ctx))
goto err;
}
ts=i;
start=1; /* This is used to avoid multiplication etc
* when there is only the value '1' in the
* buffer. */
wvalue=0; /* The 'value' of the window */
wstart=bits-1; /* The top bit of the window */
wend=0; /* The bottom bit of the window */
if (!BN_one(r)) goto err;
for (;;)
{
if (BN_is_bit_set(p,wstart) == 0)
{
if (!start)
if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
goto err;
if (wstart == 0) break;
wstart--;
continue;
}
/* We now have wstart on a 'set' bit, we now need to work out
* how bit a window to do. To do this we need to scan
* forward until the last set bit before the end of the
* window */
j=wstart;
wvalue=1;
wend=0;
for (i=1; i<window; i++)
{
if (wstart-i < 0) break;
if (BN_is_bit_set(p,wstart-i))
{
wvalue<<=(i-wend);
wvalue|=1;
wend=i;
}
}
/* wend is the size of the current window */
j=wend+1;
/* add the 'bytes above' */
if (!start)
for (i=0; i<j; i++)
{
if (!BN_mod_mul_reciprocal(r,r,r,&recp,ctx))
goto err;
}
/* wvalue will be an odd number < 2^window */
if (!BN_mod_mul_reciprocal(r,r,&(val[wvalue>>1]),&recp,ctx))
goto err;
/* move the 'window' down further */
wstart-=wend+1;
wvalue=0;
start=0;
if (wstart < 0) break;
}
ret=1;
err:
ctx->tos--;
for (i=0; i<ts; i++)
BN_clear_free(&(val[i]));
BN_RECP_CTX_free(&recp);
return(ret);
}
/* #endif */