/*---------------------------------------------------------------------------* 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. * */ #ifndef OPT_BN_ASM #define BN_MUL_ADD_WORDS #ifndef BN_MUL_WORDS #define BN_MUL_WORDS #endif #ifndef BN_SQR_WORDS #define BN_SQR_WORDS #endif #ifndef BN_ADD_WORDS #define BN_ADD_WORDS #endif #ifndef BN_SUB_WORDS #define BN_SUB_WORDS #endif #endif #include "bn_lcl.h" #ifdef BN_LLONG /* * bn_mul_add_words * * for(i=0;i=0; i--) fprintf(stderr,BN_HEX_FMT,ap[i]); fprintf(stderr,"*"); fprintf(stderr,BN_HEX_FMT,w); fprintf(stderr,"+"); for (i=num-1; i>=0; i--) fprintf(stderr,BN_HEX_FMT,rp[i]); #endif for (;;) { mul_add(rp[0],ap[0],w,c1); if (--num == 0) break; mul_add(rp[1],ap[1],w,c1); if (--num == 0) break; mul_add(rp[2],ap[2],w,c1); if (--num == 0) break; mul_add(rp[3],ap[3],w,c1); if (--num == 0) break; ap+=4; rp+=4; } #if defined(BN_ASM_DEBUG) && !defined(NO_FP_API) fprintf(stderr,"-"); fprintf(stderr,BN_HEX_FMT,c1); for (i=nn-1; i>=0; i--) fprintf(stderr,BN_HEX_FMT,rp[i]); fprintf(stderr,"\n"); } #endif return(c1); } #endif #ifdef BN_MUL_WORDS BN_ULONG bn_mul_words(rp,ap,num,w) BN_ULONG *rp,*ap; int num; BN_ULONG w; { BN_ULONG c1=0; bn_check_num(num); if (num <= 0) return(c1); #if defined(BN_ASM_DEBUG) && !defined(NO_FP_API) { int i,nn=num; for (i=num-1; i>=0; i--) fprintf(stderr,BN_HEX_FMT,ap[i]); fprintf(stderr,"*"); fprintf(stderr,BN_HEX_FMT,w); #endif for (;;) { mul(rp[0],ap[0],w,c1); if (--num == 0) break; mul(rp[1],ap[1],w,c1); if (--num == 0) break; mul(rp[2],ap[2],w,c1); if (--num == 0) break; mul(rp[3],ap[3],w,c1); if (--num == 0) break; ap+=4; rp+=4; } #if defined(BN_ASM_DEBUG) && !defined(NO_FP_API) fprintf(stderr,"-"); fprintf(stderr,BN_HEX_FMT,c1); for (i=nn-1; i>=0; i--) fprintf(stderr,BN_HEX_FMT,rp[i]); fprintf(stderr,"\n"); } #endif return(c1); } #endif #ifdef BN_SQR_WORDS void bn_sqr_words(r,a,n) BN_ULONG *r,*a; int n; { bn_check_num(n); if (n <= 0) return; #if defined(BN_ASM_DEBUG) && !defined(NO_FP_API) { int i,nn=n; for (i=n-1; i>=0; i--) { fprintf(stderr,BN_HEX_FMT,a[i]); if (i != 0) fprintf(stderr,"^2*2^%X+",i*2*BN_BITS2); else fprintf(stderr,"^2"); } #endif for (;;) { BN_ULLONG t; t=(BN_ULLONG)(a[0])*(a[0]); r[0]=Lw(t); r[1]=Hw(t); if (--n == 0) break; t=(BN_ULLONG)(a[1])*(a[1]); r[2]=Lw(t); r[3]=Hw(t); if (--n == 0) break; t=(BN_ULLONG)(a[2])*(a[2]); r[4]=Lw(t); r[5]=Hw(t); if (--n == 0) break; t=(BN_ULLONG)(a[3])*(a[3]); r[6]=Lw(t); r[7]=Hw(t); if (--n == 0) break; a+=4; r+=8; } #if defined(BN_ASM_DEBUG) && !defined(NO_FP_API) fprintf(stderr,"-"); for (i=nn+nn-1; i>=0; i--) fprintf(stderr,BN_HEX_FMT,r[i]); fprintf(stderr,"\n"); } #endif } #endif #else #ifdef BN_MUL_ADD_WORDS BN_ULONG bn_mul_add_words(rp,ap,num,w) BN_ULONG *rp,*ap; int num; BN_ULONG w; { BN_ULONG c=0; BN_ULONG bl,bh,b_hl; bn_check_num(num); if (num <= 0) return((BN_ULONG)0); bl=LBITS(w); bh=HBITS(w); b_hl=bh-bl; /* { int i,nnum=num; BN_ULONG *rrp=rp; for (i=num-1; i>=0; i--) printf("%02X",rp[i]); printf("+"); for (i=num-1; i>=0; i--) printf("%02X",ap[i]); printf("*%02X - ",w); */ for (;;) { mul_add(rp[0],ap[0],bl,bh,b_hl,c); if (--num == 0) break; mul_add(rp[1],ap[1],bl,bh,b_hl,c); if (--num == 0) break; mul_add(rp[2],ap[2],bl,bh,b_hl,c); if (--num == 0) break; mul_add(rp[3],ap[3],bl,bh,b_hl,c); if (--num == 0) break; ap+=4; rp+=4; } /* printf("%02X",c); for (i=nnum-1; i>=0; i--) printf("%02X",rrp[i]); printf("\n"); } */ return(c); } #endif #ifdef BN_MUL_WORDS BN_ULONG bn_mul_words(rp,ap,num,w) BN_ULONG *rp,*ap; int num; BN_ULONG w; { BN_ULONG carry=0; BN_ULONG bl,bh; bn_check_num(num); if (num <= 0) return((BN_ULONG)0); bl=LBITS(w); bh=HBITS(w); for (;;) { mul(rp[0],ap[0],bl,bh,carry); if (--num == 0) break; mul(rp[1],ap[1],bl,bh,carry); if (--num == 0) break; mul(rp[2],ap[2],bl,bh,carry); if (--num == 0) break; mul(rp[3],ap[3],bl,bh,carry); if (--num == 0) break; ap+=4; rp+=4; } return(carry); } #endif #ifdef BN_SQR_WORDS void bn_sqr_words(r,a,n) BN_ULONG *r,*a; int n; { bn_check_num(n); if (n <= 0) return; for (;;) { sqr64(r[0],r[1],a[0]); if (--n == 0) break; sqr64(r[2],r[3],a[1]); if (--n == 0) break; sqr64(r[4],r[5],a[2]); if (--n == 0) break; sqr64(r[6],r[7],a[3]); if (--n == 0) break; a+=4; r+=8; } } #endif #endif #ifdef BN_ADD_WORDS #ifdef BN_LLONG BN_ULONG bn_add_words(r,a,b,n) BN_ULONG *r,*a,*b; int n; { BN_ULLONG ll=0; bn_check_num(n); if (n <= 0) return((BN_ULONG)0); #if defined(BN_ASM_DEBUG) && !defined(NO_FP_API) { int i,nn=n; for (i=n-1; i>=0; i--) fprintf(stderr,BN_HEX_FMT,a[i]); fprintf(stderr,"+"); for (i=n-1; i>=0; i--) fprintf(stderr,BN_HEX_FMT,b[i]); #endif for (;;) { ll+=(BN_ULLONG)a[0]+b[0]; r[0]=(BN_ULONG)ll&BN_MASK2; ll>>=BN_BITS2; if (--n <= 0) break; ll+=(BN_ULLONG)a[1]+b[1]; r[1]=(BN_ULONG)ll&BN_MASK2; ll>>=BN_BITS2; if (--n <= 0) break; ll+=(BN_ULLONG)a[2]+b[2]; r[2]=(BN_ULONG)ll&BN_MASK2; ll>>=BN_BITS2; if (--n <= 0) break; ll+=(BN_ULLONG)a[3]+b[3]; r[3]=(BN_ULONG)ll&BN_MASK2; ll>>=BN_BITS2; if (--n <= 0) break; a+=4; b+=4; r+=4; } #if defined(BN_ASM_DEBUG) && !defined(NO_FP_API) fprintf(stderr,"-"); fprintf(stderr,BN_HEX_FMT,(BN_ULONG)ll); for (i=nn-1; i>=0; i--) fprintf(stderr,BN_HEX_FMT,r[i]); fprintf(stderr,"\n"); } #endif return((BN_ULONG)ll); } #else BN_ULONG bn_add_words(r,a,b,n) BN_ULONG *r,*a,*b; int n; { BN_ULONG c,l,t; bn_check_num(n); if (n <= 0) return((BN_ULONG)0); c=0; for (;;) { t=a[0]; t=(t+c)&BN_MASK2; c=(t < c); l=(t+b[0])&BN_MASK2; c+=(l < t); r[0]=l; if (--n <= 0) break; t=a[1]; t=(t+c)&BN_MASK2; c=(t < c); l=(t+b[1])&BN_MASK2; c+=(l < t); r[1]=l; if (--n <= 0) break; t=a[2]; t=(t+c)&BN_MASK2; c=(t < c); l=(t+b[2])&BN_MASK2; c+=(l < t); r[2]=l; if (--n <= 0) break; t=a[3]; t=(t+c)&BN_MASK2; c=(t < c); l=(t+b[3])&BN_MASK2; c+=(l < t); r[3]=l; if (--n <= 0) break; a+=4; b+=4; r+=4; } return((BN_ULONG)c); } #endif #endif #ifdef BN_SUB_WORDS BN_ULONG bn_sub_words(r,a,b,n) BN_ULONG *r,*a,*b; int n; { BN_ULONG c,t1,t2; bn_check_num(n); if (n <= 0) return((BN_ULONG)0); #if defined(BN_ASM_DEBUG) && !defined(NO_FP_API) { int i,nn=n; for (i=n-1; i>=0; i--) fprintf(stderr,BN_HEX_FMT,a[i]); fprintf(stderr,"-"); for (i=n-1; i>=0; i--) fprintf(stderr,BN_HEX_FMT,b[i]); #endif c=0; for (;;) { t1=a[0]; t2=b[0]; r[0]=(t1-t2-c)&BN_MASK2; if (t1 != t2) c=(t1 < t2); if (--n <= 0) break; t1=a[1]; t2=b[1]; r[1]=(t1-t2-c)&BN_MASK2; if (t1 != t2) c=(t1 < t2); if (--n <= 0) break; t1=a[2]; t2=b[2]; r[2]=(t1-t2-c)&BN_MASK2; if (t1 != t2) c=(t1 < t2); if (--n <= 0) break; t1=a[3]; t2=b[3]; r[3]=(t1-t2-c)&BN_MASK2; if (t1 != t2) c=(t1 < t2); if (--n <= 0) break; a+=4; b+=4; r+=4; } #if defined(BN_ASM_DEBUG) && !defined(NO_FP_API) fprintf(stderr,"- "); if (c) fprintf(stderr,"-"); for (i=nn-1; i>=0; i--) fprintf(stderr,BN_HEX_FMT,r[i]); fprintf(stderr,"\n"); } #endif return(c); } #endif