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

454 lines
15 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"
const static unsigned char p2 []={0,8,1,1,1,1,1,0,0,0};
const static unsigned char p4 []={0,8,1,1,1,4,1,0,0,0};
const static unsigned char p16[]={0,8,1,1,1,16,1,0,0,0};
/* The following defines allow for redefinition of the window size
* of the exponent string at compile time, this affects the size
* of temporary data required in montgomery operations.
* Larger window sizes have more memory and are slightly faster
*/
#ifndef MAX_WIN_SIZE
#define MAX_WIN_SIZE 5
#endif
#if (MAX_WIN_SIZE == 6)
#define MAX_NUM_SIZE 16
#endif
#if (MAX_WIN_SIZE == 5)
#define MAX_NUM_SIZE 16
#endif
#if (MAX_WIN_SIZE == 4)
#define MAX_NUM_SIZE 8
#endif
#if (MAX_WIN_SIZE == 3)
#define MAX_NUM_SIZE 4
#endif
#ifndef MAX_NUM_SIZE
#define MAX_NUM_SIZE 16
#endif
/* This table is used to calculate how far to shift a window to find
* the next 1 bit within the window, for a given window size
* Comment next to each value represents window size, value of the window
* and the number of shifts to find the next 1 bit.
* where the value of the window is 0, the shift is the size of the window
* and thus may not necessary yield a 1 bit, but refreshes the window
*/
const static unsigned char shift[64]=
{6, /* window 6, bits 000000, shift 6 */
0, /* 6, bits 000001, shift 0 */
1, /* 6, bits 000010, shift 1 */
0, /* 6, bits 000011, shift 0 */
2, /* 6, bits 000100, shift 2 */
0, /* 6, bits 000101, shift 0 */
1, /* 6, bits 000110, shift 1 */
0, /* 6, bits 000111, shift 0 */
3, /* 6, bits 001000, shift 3 */
0, /* 6, bits 001001, shift 0 */
1, /* 6, bits 001010, shift 1 */
0, /* 6, bits 001011, shift 0 */
2, /* 6, bits 001100, shift 2 */
0, /* 6, bits 001101, shift 0 */
1, /* 6, bits 001110, shift 1 */
0, /* 6, bits 001111, shift 0 */
4, /* 6, bits 010000, shift 4 */
0, /* 6, bits 010001, shift 0 */
1, /* 6, bits 010010, shift 1 */
0, /* 6, bits 010011, shift 0 */
2, /* 6, bits 010100, shift 2 */
0, /* 6, bits 010101, shift 0 */
1, /* 6, bits 010110, shift 1 */
0, /* 6, bits 010111, shift 0 */
3, /* 6, bits 011000, shift 3 */
0, /* 6, bits 011001, shift 0 */
1, /* 6, bits 011010, shift 1 */
0, /* 6, bits 011011, shift 0 */
2, /* 6, bits 011100, shift 2 */
0, /* 6, bits 011101, shift 0 */
1, /* 6, bits 011110, shift 1 */
0, /* 6, bits 011111, shift 0 */
5, /* 6, bits 100000, shift 5 */
/* also window 5, bits 00000, shift 5 */
0, /* 5 ,bits 00001, shift 0 */
1, /* 5 ,bits 00010, shift 1 */
0, /* 5 ,bits 00011, shift 0 */
2, /* 5 ,bits 00100, shift 2 */
0, /* 5 ,bits 00101, shift 0 */
1, /* 5 ,bits 00110, shift 1 */
0, /* 5 ,bits 00111, shift 0 */
3, /* 5 ,bits 01000, shift 3 */
0, /* 5 ,bits 01001, shift 0 */
1, /* 5 ,bits 01010, shift 1 */
0, /* 5 ,bits 01011, shift 0 */
2, /* 5 ,bits 01100, shift 2 */
0, /* 5 ,bits 01101, shift 0 */
1, /* 5 ,bits 01110, shift 1 */
0, /* 5 ,bits 01111, shift 0 */
4, /* 5 ,bits 10000, shift 1 */
/* also window 4, bits 0000, shift 4 */
0, /* 4 ,bits 0001, shift 0 */
1, /* 4 ,bits 0010, shift 1 */
0, /* 4 ,bits 0011, shift 0 */
2, /* 4 ,bits 0100, shift 2 */
0, /* 4 ,bits 0101, shift 0 */
1, /* 4 ,bits 0110, shift 1 */
0, /* 4 ,bits 0111, shift 0 */
3, /* 4 ,bits 1000, shift 3 */
/* also window 3, bits 000, shift 3 */
0, /* 3 ,bits 001, shift 0 */
1, /* 3 ,bits 010, shift 1 */
0, /* 3 ,bits 011, shift 0 */
2, /* 3 ,bits 100, shift 2 */
0, /* 3 ,bits 101, shift 0 */
1, /* 3 ,bits 110, shift 1 */
0 /* 3 ,bits 111, shift 0 */
};
/* This table defines the starting point in the shift table for
* a particular window size
*/
const static unsigned char *shift_val[7]=
{
&(shift[63]), /* window 0 - unused */
&(shift[62]), /* window 1 */
&(shift[60]), /* window 2 - unused */
&(shift[56]), /* window 3 */
&(shift[48]), /* window 4 */
&(shift[32]), /* window 5 */
&(shift[ 0]), /* window 6 - unused */
};
/**
* Calculates a Montgomery exponent string.
*
* For a supplied exponent p, generate an exponent string strp, which
* defines in pairs the number of multiplies and square operations
* required by a particular bit pattern, commonly used exponents
* 3, 11 and F4 have predefined constant string values, the rest
* are calculated into a cast unsigned char * array via the data
* pointer of a BIGNUM taken from the BN_CTX stack of BIGNUMs
*
* @param p [In] Exponent
* @param strp [Out] Exponent string result
* @param flags [In] Unused
* @param ctx [In] Temporary data storage
*
* @pre p, and ctx are initialised and valid
* @post strp points to required exponent string
*
* @notes String length value in strp[2] is invalid for strings
* greater than length 255
* string terminates with pattern, 0, 0 this should be
* used in accurately determining the length of a returned
* string strp.
*
* @note strings with value sqr = 255, mul = 0, sqr value should be
* treated as value 256, and added to the next sqr value, this
* is used by exponent strings where more then 256 contiguous
* zero bits are in the exponent bit representation.
*
* @note code contains conditional compilation of code dependent on
* the OS int/long sizes
*/
int BN_gen_exp_bits(p,strp,flags,ctx)
BIGNUM *p;
unsigned char **strp;
int flags;
BN_CTX *ctx;
{
int bits,i,j,window,num;
unsigned char *str=NULL;
BIGNUM *tmp;
flags=flags;
bits=p->top*BN_BITS2;
tmp=&(ctx->bn[ctx->tos]);
if (p->top == 0)
return(0);
#if (BN_BITS2 > 17)
if (p->top == 1)
#else
if (bits <= 32)
#endif
{
#if (BN_BITS2 > 17)
if ((p->top == 1) && (p->d[0] == 0x10001))
str=(unsigned char *)p16;
#endif
#if (16 >= BN_BITS2) && (BN_BITS > 8)
if ( (p->top == 2) &&
(p->d[0] == 0x0001) &&
(p->d[1] == 0x0001))
str=(unsigned char *)p16;
#endif
#if (8 >= BN_BITS)
if ( (p->top == 3) &&
(p->d[0] == 0x01) &&
(p->d[1] == 0x00) &&
(p->d[2] == 0x01))
str=(unsigned char *)p16;
#endif
else if ((p->d[0] == 0x11) && (p->top == 1))
str=(unsigned char *)p4;
else if ((p->d[0] == 0x3) && (p->top == 1))
str=(unsigned char *)p2;
window=1;
num=1;
i=BN_BITS2;
}
else if (bits >= 256)
{
window=MAX_WIN_SIZE; /* max size of window */
num=MAX_NUM_SIZE;
i=(BN_BITS2+(MAX_WIN_SIZE -1))/MAX_WIN_SIZE;
}
else if (bits >= 128)
{
window=4;
num=8;
i=(BN_BITS2+3)/4;
}
else /* 128 to 33 */
{
window=3;
num=4;
i=(BN_BITS2+2)/3;
}
/* Number of tmp words */
j=(p->top*i*2+BN_BYTES-1+4)/BN_BYTES;
if (str == NULL)
{
if (!bn_wexpand(tmp,j))
return(0);
str=(unsigned char *)tmp->d;
i=BN_gen_exp_string(&(str[4]),p,window);
i+=2;
str[0]=(unsigned char)((i>>8)&0xff);
str[1]=(unsigned char)((i )&0xff);
str[2]=(unsigned char)window;
str[3]=(unsigned char)num;
}
else
{
i=8;
}
*strp=str;
return(i+2);
}
/**
* Generates the Montgomery exponent string.
*
* This function is used to generate an 'exponent string'
* which is an array of bytes that encode how to perform the steps in
* the a^p%m operation.
*
* @param str [Out] Containing the generated string
* @param p [In] Exponent to generate the string for
* @param bits [In] Size of the window for shifting the values of the BIGNUM
*
* @pre p is initialised and value BIGNUM, bits is not 0
* @post str points to generated exponent string
*
* @note str is cast assigned the data of a BIGNUM allocated and
* expanded from the BN_CTX of the calling function BN_gen_exp_bits
* it does not need to be de-allocated
*
* @note string consisted of unsigned char pairs and 4 byte init
* pairs are sqr count and multiply, where strings are greater
* than 256 bit, length in position str[2] is invalid
*
* @note strings with value sqr = 255, mul = 0, sqr value should be
* treated as value 256, and added to the next sqr value, this
* is used by exponent strings where more then 256 contiguous
* zero bits are in the exponent bit representation.
*
*/
int BN_gen_exp_string(str,p,bits)
unsigned char *str;
BIGNUM *p;
int bits;
{
unsigned char *sp;
unsigned int mask;
const unsigned char *shift;
BN_ULONG w,wh,wl,*d;
unsigned int i,mul,sqr,t,s,ss;
int top;
if (bits > 6) bits=6;
shift= shift_val[bits];
/* This is the mask for the bits we wish to operate on */
mask=(unsigned int)( (1<<bits)-1 );
ss=0;
sp= &(str[((p->top*BN_BITS2+bits-1)/bits)*2+2]);
*sp-- = 0;
*sp-- = 0;
top=p->top; /* Total words we will shift in */
d=p->d;
w=wl= *d++;
if (top <= 1)
wh=0;
else
wh= *d++;
sqr=0;
i=0;
for (;;)
{
/* t will contain how far we need to shift to set a 1
* in the bottom bit. */
for (;;)
{
t=w&mask; /* retrieve our window */
s=shift[t]; /* get the shift value for the window */
if (s == 0) break; /* no shift write out the vals */
sqr+=s; /* add the shifted zero count to sqr */
ss+=s; /* ss is total shift for wl */
if (ss >= BN_BITS2) /* we have shifted > word len */
{
if (top <= 1) break; /* no more to do */
top--; /* dec the count */
wl=wh; /* copy the next word */
/* load the word after or 0 if no more */
wh=(top <= 1)?0:(*d++);
/* adjust our shift by len of word */
ss-=BN_BITS2;
}
/* reset our window word w */
if (ss == 0)
w=wl;
else
w=(wl>>ss)|(wh<<(BN_BITS2-ss));
}
/* At this point we have the 0th bit set */
mul=t;
if (t == 0) break; /* we have reached the end of p */
/* write out sqr/mul pair */
*sp-- = (unsigned char)(sqr & 0xff);
*sp-- = (unsigned char)(mul & 0xff);
if(sqr >= 256) /* check whether sqr exceeds max uchar */
{
/* output the expanded list of to allow for this
* and numbers will require to be added together
* at interpret time
*/
while(sqr >= 256)
{
*sp-- = 255;
*sp-- = 0; /* mul is never zero normally */
sqr-= 256;
}
}
sqr=(unsigned int)bits; /* set sqr to be the window size */
ss+=bits; /* ss is total shift for wl */
if (ss >= BN_BITS2) /* adjust window words w,wl, wh again */
{
if (top <= 1) break;
top--;
wl=wh;
wh=(top <= 1)?0:(*(d++));
ss-=BN_BITS2;
}
if (ss == 0)
w=wl;
else
w=(wl>>ss)|(wh<<(BN_BITS2-ss));
}
sp++;
i=2;
/* reverse the string from the top of the exponent string
* and copy to the bottom, allocated exponent string is 2 * max length
* expected for exponent string
*/
while (sp[0] != 0 || sp[1] != 0)
{
str[0]=sp[0];
str[1]=sp[1];
str+=2;
sp+=2;
i+=2;
}
str[0]=0;
str[1]=0;
return( (int)i );
}
#ifdef MAIN
main()
{
BIGNUM p;
unsigned char buf[512],*pp;
int i;
BN_init(&p);
BN_rand(&p,33,1,0);
#ifndef NO_FP_API
BN_print_fp(stdout,&p); fprintf(stdout,"\n");
#endif
BN_rand(&p,512,1,1);
#ifndef NO_FP_API
BN_print_fp(stdout,&p); fprintf(stdout,"\n");
#endif
for (i=0; i<10000; i++)
BN_gen_exp_string(buf,&p,5);
#if 0
BN_gen_exp_string(buf,&p,3);
pp=buf;
for (;;)
{
printf("mul %d sqr %d\n",pp[0],pp[1]);
if (pp[1] == 0) break;
pp+=2;
}
#endif
}
#endif